ioam: remove api boilerplate
[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
29
30 /* define message IDs */
31 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api_enum.h>
32 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api_types.h>
33
34 static void vl_api_vxlan_gpe_ioam_enable_t_handler
35   (vl_api_vxlan_gpe_ioam_enable_t * mp)
36 {
37   int rv = 0;
38   vl_api_vxlan_gpe_ioam_enable_reply_t *rmp;
39   clib_error_t *error;
40
41   /* Ignoring the profile id as currently a single profile
42    * is supported */
43   error =
44     vxlan_gpe_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc);
45   if (error)
46     {
47       clib_error_report (error);
48       rv = clib_error_get_code (error);
49     }
50
51   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_ENABLE_REPLY);
52 }
53
54 static void vl_api_vxlan_gpe_ioam_disable_t_handler
55   (vl_api_vxlan_gpe_ioam_disable_t * mp)
56 {
57   int rv = 0;
58   vl_api_vxlan_gpe_ioam_disable_reply_t *rmp;
59   clib_error_t *error;
60
61   /* Ignoring the profile id as currently a single profile
62    * is supported */
63   error = vxlan_gpe_ioam_disable (0, 0, 0);
64   if (error)
65     {
66       clib_error_report (error);
67       rv = clib_error_get_code (error);
68     }
69
70   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_DISABLE_REPLY);
71 }
72
73 static void vl_api_vxlan_gpe_ioam_vni_enable_t_handler
74   (vl_api_vxlan_gpe_ioam_vni_enable_t * mp)
75 {
76   int rv = 0;
77   vl_api_vxlan_gpe_ioam_vni_enable_reply_t *rmp;
78   clib_error_t *error;
79   vxlan4_gpe_tunnel_key_t key4;
80   uword *p = NULL;
81   vxlan_gpe_main_t *gm = &vxlan_gpe_main;
82   vxlan_gpe_tunnel_t *t = 0;
83   vxlan_gpe_ioam_main_t *hm = &vxlan_gpe_ioam_main;
84   u32 vni;
85
86
87   if (!mp->is_ipv6)
88     {
89       clib_memcpy (&key4.local, &mp->local, sizeof (key4.local));
90       clib_memcpy (&key4.remote, &mp->remote, sizeof (key4.remote));
91       vni = clib_net_to_host_u32 (mp->vni);
92       key4.vni = clib_host_to_net_u32 (vni << 8);
93       key4.pad = 0;
94
95       p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
96     }
97   else
98     {
99       return;
100     }
101
102   if (!p)
103     return;
104
105   t = pool_elt_at_index (gm->tunnels, p[0]);
106
107   error = vxlan_gpe_ioam_set (t, hm->has_trace_option,
108                               hm->has_pot_option,
109                               hm->has_ppc_option, mp->is_ipv6);
110
111
112   if (error)
113     {
114       clib_error_report (error);
115       rv = clib_error_get_code (error);
116     }
117
118   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_VNI_ENABLE_REPLY);
119 }
120
121
122 static void vl_api_vxlan_gpe_ioam_vni_disable_t_handler
123   (vl_api_vxlan_gpe_ioam_vni_disable_t * mp)
124 {
125   int rv = 0;
126   vl_api_vxlan_gpe_ioam_vni_enable_reply_t *rmp;
127   clib_error_t *error;
128   vxlan4_gpe_tunnel_key_t key4;
129   uword *p = NULL;
130   vxlan_gpe_main_t *gm = &vxlan_gpe_main;
131   vxlan_gpe_tunnel_t *t = 0;
132   u32 vni;
133
134
135   if (!mp->is_ipv6)
136     {
137       clib_memcpy (&key4.local, &mp->local, sizeof (key4.local));
138       clib_memcpy (&key4.remote, &mp->remote, sizeof (key4.remote));
139       vni = clib_net_to_host_u32 (mp->vni);
140       key4.vni = clib_host_to_net_u32 (vni << 8);
141       key4.pad = 0;
142
143       p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
144     }
145   else
146     {
147       return;
148     }
149
150   if (!p)
151     return;
152
153   t = pool_elt_at_index (gm->tunnels, p[0]);
154
155   error = vxlan_gpe_ioam_clear (t, 0, 0, 0, 0);
156
157
158   if (error)
159     {
160       clib_error_report (error);
161       rv = clib_error_get_code (error);
162     }
163
164
165   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_VNI_DISABLE_REPLY);
166 }
167
168 static void vl_api_vxlan_gpe_ioam_transit_enable_t_handler
169   (vl_api_vxlan_gpe_ioam_transit_enable_t * mp)
170 {
171   int rv = 0;
172   vl_api_vxlan_gpe_ioam_transit_enable_reply_t *rmp;
173   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
174   ip46_address_t dst_addr;
175
176   clib_memset (&dst_addr.ip4, 0, sizeof (dst_addr.ip4));
177   if (!mp->is_ipv6)
178     {
179       clib_memcpy (&dst_addr.ip4, &mp->dst_addr, sizeof (dst_addr.ip4));
180     }
181   rv = vxlan_gpe_enable_disable_ioam_for_dest (sm->vlib_main,
182                                                dst_addr,
183                                                ntohl (mp->outer_fib_index),
184                                                mp->is_ipv6 ? 0 : 1,
185                                                1 /* is_add */ );
186
187   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_TRANSIT_ENABLE_REPLY);
188 }
189
190 static void vl_api_vxlan_gpe_ioam_transit_disable_t_handler
191   (vl_api_vxlan_gpe_ioam_transit_disable_t * mp)
192 {
193   int rv = 0;
194   vl_api_vxlan_gpe_ioam_transit_disable_reply_t *rmp;
195   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
196   ip46_address_t dst_addr;
197
198   clib_memset (&dst_addr.ip4, 0, sizeof (dst_addr.ip4));
199   if (!mp->is_ipv6)
200     {
201       clib_memcpy (&dst_addr.ip4, &mp->dst_addr, sizeof (dst_addr.ip4));
202     }
203
204   rv = vxlan_gpe_ioam_disable_for_dest (sm->vlib_main,
205                                         dst_addr,
206                                         ntohl (mp->outer_fib_index),
207                                         mp->is_ipv6 ? 0 : 1);
208   REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_TRANSIT_DISABLE_REPLY);
209 }
210
211 #include <ioam/lib-vxlan-gpe/ioam_vxlan_gpe.api.c>
212 static clib_error_t *
213 vxlan_gpe_init (vlib_main_t * vm)
214 {
215   vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
216   u32 encap_node_index = vxlan_gpe_encap_ioam_v4_node.index;
217   u32 decap_node_index = vxlan_gpe_decap_ioam_v4_node.index;
218   vlib_node_t *vxlan_gpe_encap_node = NULL;
219   vlib_node_t *vxlan_gpe_decap_node = NULL;
220   uword next_node = 0;
221
222   sm->vlib_main = vm;
223   sm->vnet_main = vnet_get_main ();
224   sm->unix_time_0 = (u32) time (0);     /* Store starting time */
225   sm->vlib_time_0 = vlib_time_now (vm);
226
227   /* Ask for a correctly-sized block of API message decode slots */
228   sm->msg_id_base = setup_message_id_table ();
229
230   /* Hook the ioam-encap node to vxlan-gpe-encap */
231   vxlan_gpe_encap_node = vlib_get_node_by_name (vm, (u8 *) "vxlan-gpe-encap");
232   sm->encap_v4_next_node =
233     vlib_node_add_next (vm, vxlan_gpe_encap_node->index, encap_node_index);
234
235   vxlan_gpe_decap_node =
236     vlib_get_node_by_name (vm, (u8 *) "vxlan4-gpe-input");
237   next_node =
238     vlib_node_add_next (vm, vxlan_gpe_decap_node->index, decap_node_index);
239   vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IOAM, next_node);
240
241   vec_new (vxlan_gpe_ioam_sw_interface_t, pool_elts (sm->sw_interfaces));
242   sm->dst_by_ip4 = hash_create_mem (0, sizeof (fib_prefix_t), sizeof (uword));
243
244   sm->dst_by_ip6 = hash_create_mem (0, sizeof (fib_prefix_t), sizeof (uword));
245
246   vxlan_gpe_ioam_interface_init ();
247
248   return 0;
249 }
250
251 VLIB_INIT_FUNCTION (vxlan_gpe_init);
252
253 /*
254  * fd.io coding-style-patch-verification: ON
255  *
256  * Local Variables:
257  * eval: (c-set-style "gnu")
258  * End:
259  */