ioam: do not reuse existing vnet symbol
[vpp.git] / src / plugins / ioam / lib-vxlan-gpe / vxlan_gpe_api.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  *------------------------------------------------------------------
17  * vxlan_gpe_api.c - iOAM VxLAN-GPE related APIs to create
18  *               and maintain profiles
19  *------------------------------------------------------------------
20  */
21
22 #include <vnet/vnet.h>
23 #include <vnet/plugin/plugin.h>
24 #include <ioam/lib-vxlan-gpe/vxlan_gpe_ioam.h>
25 #include <vlibapi/api_helper_macros.h>
26 #include <vlibapi/api.h>
27 #include <vlibmemory/api.h>
28 #include <vnet/format_fns.h>
29 #include <vnet/ip/ip_types_api.h>
30
31 /* define message IDs */
32 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api_enum.h>
33 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api_types.h>
34
35 static void vl_api_vxlan_gpe_ioam_enable_t_handler
36   (vl_api_vxlan_gpe_ioam_enable_t * mp)
37 {
38   int rv = 0;
39   vl_api_vxlan_gpe_ioam_enable_reply_t *rmp;
40   clib_error_t *error;
41
42   /* Ignoring the profile id as currently a single profile
43    * is supported */
44   error =
45     vxlan_gpe_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc);
46   if (error)
47     {
48       clib_error_report (error);
49       rv = clib_error_get_code (error);
50     }
51
52   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_ENABLE_REPLY);
53 }
54
55 static void vl_api_vxlan_gpe_ioam_disable_t_handler
56   (vl_api_vxlan_gpe_ioam_disable_t * mp)
57 {
58   int rv = 0;
59   vl_api_vxlan_gpe_ioam_disable_reply_t *rmp;
60   clib_error_t *error;
61
62   /* Ignoring the profile id as currently a single profile
63    * is supported */
64   error = vxlan_gpe_ioam_disable (0, 0, 0);
65   if (error)
66     {
67       clib_error_report (error);
68       rv = clib_error_get_code (error);
69     }
70
71   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_DISABLE_REPLY);
72 }
73
74 static void vl_api_vxlan_gpe_ioam_vni_enable_t_handler
75   (vl_api_vxlan_gpe_ioam_vni_enable_t * mp)
76 {
77   int rv = 0;
78   vl_api_vxlan_gpe_ioam_vni_enable_reply_t *rmp;
79   clib_error_t *error;
80   vxlan4_gpe_tunnel_key_t key4;
81   uword *p = NULL;
82   vxlan_gpe_main_t *gm = &vxlan_gpe_main;
83   vxlan_gpe_tunnel_t *t = 0;
84   vxlan_gpe_ioam_main_t *hm = &vxlan_gpe_ioam_main;
85   u32 vni;
86
87
88   if (clib_net_to_host_u32 (mp->local.af) == ADDRESS_IP4 &&
89       clib_net_to_host_u32 (mp->remote.af) == ADDRESS_IP4)
90     {
91       clib_memcpy (&key4.local, &mp->local.un.ip4, sizeof (key4.local));
92       clib_memcpy (&key4.remote, &mp->remote.un.ip4, sizeof (key4.remote));
93       vni = clib_net_to_host_u32 (mp->vni);
94       key4.vni = clib_host_to_net_u32 (vni << 8);
95       key4.pad = 0;
96
97       p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
98     }
99   else
100     {
101       return;
102     }
103
104   if (!p)
105     return;
106
107   t = pool_elt_at_index (gm->tunnels, p[0]);
108
109   error = vxlan_gpe_ioam_set (t, hm->has_trace_option,
110                               hm->has_pot_option,
111                               hm->has_ppc_option, 0 /* is_ipv6 */ );
112
113
114   if (error)
115     {
116       clib_error_report (error);
117       rv = clib_error_get_code (error);
118     }
119
120   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_VNI_ENABLE_REPLY);
121 }
122
123
124 static void vl_api_vxlan_gpe_ioam_vni_disable_t_handler
125   (vl_api_vxlan_gpe_ioam_vni_disable_t * mp)
126 {
127   int rv = 0;
128   vl_api_vxlan_gpe_ioam_vni_enable_reply_t *rmp;
129   clib_error_t *error;
130   vxlan4_gpe_tunnel_key_t key4;
131   uword *p = NULL;
132   vxlan_gpe_main_t *gm = &vxlan_gpe_main;
133   vxlan_gpe_tunnel_t *t = 0;
134   u32 vni;
135
136
137   if (clib_net_to_host_u32 (mp->local.af) == ADDRESS_IP4 &&
138       clib_net_to_host_u32 (mp->remote.af) == ADDRESS_IP4)
139     {
140       clib_memcpy (&key4.local, &mp->local, sizeof (key4.local));
141       clib_memcpy (&key4.remote, &mp->remote, sizeof (key4.remote));
142       vni = clib_net_to_host_u32 (mp->vni);
143       key4.vni = clib_host_to_net_u32 (vni << 8);
144       key4.pad = 0;
145
146       p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
147     }
148   else
149     {
150       return;
151     }
152
153   if (!p)
154     return;
155
156   t = pool_elt_at_index (gm->tunnels, p[0]);
157
158   error = vxlan_gpe_ioam_clear (t, 0, 0, 0, 0);
159
160
161   if (error)
162     {
163       clib_error_report (error);
164       rv = clib_error_get_code (error);
165     }
166
167
168   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_VNI_DISABLE_REPLY);
169 }
170
171 static void vl_api_vxlan_gpe_ioam_transit_enable_t_handler
172   (vl_api_vxlan_gpe_ioam_transit_enable_t * mp)
173 {
174   int rv = 0;
175   vl_api_vxlan_gpe_ioam_transit_enable_reply_t *rmp;
176   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
177   ip46_address_t dst_addr;
178
179   ip_address_decode (&mp->dst_addr, &dst_addr);
180   bool is_ip6 = clib_net_to_host_u32 (mp->dst_addr.af) == ADDRESS_IP6;
181   rv = vxlan_gpe_enable_disable_ioam_for_dest (sm->vlib_main,
182                                                dst_addr,
183                                                ntohl (mp->outer_fib_index),
184                                                is_ip6, 1 /* is_add */ );
185
186   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_TRANSIT_ENABLE_REPLY);
187 }
188
189 static void vl_api_vxlan_gpe_ioam_transit_disable_t_handler
190   (vl_api_vxlan_gpe_ioam_transit_disable_t * mp)
191 {
192   int rv = 0;
193   vl_api_vxlan_gpe_ioam_transit_disable_reply_t *rmp;
194   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
195   ip46_address_t dst_addr;
196
197   ip_address_decode (&mp->dst_addr, &dst_addr);
198   bool is_ip6 = clib_net_to_host_u32 (mp->dst_addr.af) == ADDRESS_IP6;
199   rv = vxlan_gpe_ioam_disable_for_dest (sm->vlib_main,
200                                         dst_addr,
201                                         ntohl (mp->outer_fib_index), is_ip6);
202   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_TRANSIT_DISABLE_REPLY);
203 }
204
205 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api.c>
206 static clib_error_t *
207 ioam_vxlan_gpe_init (vlib_main_t * vm)
208 {
209   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
210   u32 encap_node_index = vxlan_gpe_encap_ioam_v4_node.index;
211   u32 decap_node_index = vxlan_gpe_decap_ioam_v4_node.index;
212   vlib_node_t *vxlan_gpe_encap_node = NULL;
213   vlib_node_t *vxlan_gpe_decap_node = NULL;
214   uword next_node = 0;
215
216   sm->vlib_main = vm;
217   sm->vnet_main = vnet_get_main ();
218   sm->unix_time_0 = (u32) time (0);     /* Store starting time */
219   sm->vlib_time_0 = vlib_time_now (vm);
220
221   /* Ask for a correctly-sized block of API message decode slots */
222   sm->msg_id_base = setup_message_id_table ();
223
224   /* Hook the ioam-encap node to vxlan-gpe-encap */
225   vxlan_gpe_encap_node = vlib_get_node_by_name (vm, (u8 *) "vxlan-gpe-encap");
226   sm->encap_v4_next_node =
227     vlib_node_add_next (vm, vxlan_gpe_encap_node->index, encap_node_index);
228
229   vxlan_gpe_decap_node =
230     vlib_get_node_by_name (vm, (u8 *) "vxlan4-gpe-input");
231   next_node =
232     vlib_node_add_next (vm, vxlan_gpe_decap_node->index, decap_node_index);
233   vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IOAM, next_node);
234
235   vec_new (vxlan_gpe_ioam_sw_interface_t, pool_elts (sm->sw_interfaces));
236   sm->dst_by_ip4 = hash_create_mem (0, sizeof (fib_prefix_t), sizeof (uword));
237
238   sm->dst_by_ip6 = hash_create_mem (0, sizeof (fib_prefix_t), sizeof (uword));
239
240   vxlan_gpe_ioam_interface_init ();
241
242   return 0;
243 }
244
245 VLIB_INIT_FUNCTION (ioam_vxlan_gpe_init);
246
247 /*
248  * fd.io coding-style-patch-verification: ON
249  *
250  * Local Variables:
251  * eval: (c-set-style "gnu")
252  * End:
253  */