GBP plugin
[vpp.git] / src / plugins / gbp / gbp_api.c
1 /*
2  *------------------------------------------------------------------
3  * gbp_api.c - layer 2 emulation api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vnet/vnet.h>
21 #include <vnet/plugin/plugin.h>
22
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vpp/app/version.h>
26
27 #include <gbp/gbp.h>
28
29 #include <vlibapi/api.h>
30 #include <vlibmemory/api.h>
31
32 /* define message IDs */
33 #include <gbp/gbp_msg_enum.h>
34
35 #define vl_typedefs             /* define message structures */
36 #include <gbp/gbp_all_api_h.h>
37 #undef vl_typedefs
38
39 #define vl_endianfun            /* define message structures */
40 #include <gbp/gbp_all_api_h.h>
41 #undef vl_endianfun
42
43 /* instantiate all the print functions we know about */
44 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
45 #define vl_printfun
46 #include <gbp/gbp_all_api_h.h>
47 #undef vl_printfun
48
49 /* Get the API version number */
50 #define vl_api_version(n,v) static u32 api_version=(v);
51 #include <acl/acl_all_api_h.h>
52 #undef vl_api_version
53
54 #include <vlibapi/api_helper_macros.h>
55
56 #define foreach_gbp_api_msg                                 \
57   _(GBP_ENDPOINT_ADD_DEL, gbp_endpoint_add_del)             \
58   _(GBP_ENDPOINT_DUMP, gbp_endpoint_dump)                   \
59   _(GBP_CONTRACT_ADD_DEL, gbp_contract_add_del)             \
60   _(GBP_CONTRACT_DUMP, gbp_contract_dump)
61
62 /**
63  * L2 Emulation Main
64  */
65 typedef struct gbp_main_t_
66 {
67   u16 msg_id_base;
68 } gbp_main_t;
69
70 static gbp_main_t gbp_main;
71
72 #define GBP_MSG_BASE gbp_main.msg_id_base
73
74 static void
75 vl_api_gbp_endpoint_add_del_t_handler (vl_api_gbp_endpoint_add_del_t * mp)
76 {
77   vl_api_gbp_endpoint_add_del_reply_t *rmp;
78   ip46_address_t ip = { };
79   u32 sw_if_index;
80   int rv = 0;
81
82   sw_if_index = ntohl (mp->endpoint.sw_if_index);
83   if (!vnet_sw_if_index_is_api_valid (sw_if_index))
84     goto bad_sw_if_index;
85
86   if (mp->endpoint.is_ip6)
87     {
88       clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
89     }
90   else
91     {
92       clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
93     }
94
95   if (mp->is_add)
96     {
97       gbp_endpoint_update (sw_if_index, &ip, ntohl (mp->endpoint.epg_id));
98     }
99   else
100     {
101       gbp_endpoint_delete (sw_if_index, &ip);
102     }
103
104   BAD_SW_IF_INDEX_LABEL;
105
106   REPLY_MACRO (VL_API_GBP_ENDPOINT_ADD_DEL_REPLY + GBP_MSG_BASE);
107 }
108
109 typedef struct gbp_walk_ctx_t_
110 {
111   vl_api_registration_t *reg;
112   u32 context;
113 } gbp_walk_ctx_t;
114
115 static int
116 gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
117 {
118   vl_api_gbp_endpoint_details_t *mp;
119   gbp_walk_ctx_t *ctx;
120
121   ctx = args;
122   mp = vl_msg_api_alloc (sizeof (*mp));
123   if (!mp)
124     return 1;
125
126   memset (mp, 0, sizeof (*mp));
127   mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
128   mp->context = ctx->context;
129
130   mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_sw_if_index);
131   mp->endpoint.is_ip6 = !ip46_address_is_ip4 (&gbpe->ge_key->gek_ip);
132   if (mp->endpoint.is_ip6)
133     clib_memcpy (&mp->endpoint.address,
134                  &gbpe->ge_key->gek_ip.ip6,
135                  sizeof (gbpe->ge_key->gek_ip.ip6));
136   else
137     clib_memcpy (&mp->endpoint.address,
138                  &gbpe->ge_key->gek_ip.ip4,
139                  sizeof (gbpe->ge_key->gek_ip.ip4));
140
141   mp->endpoint.epg_id = ntohl (gbpe->ge_epg_id);
142
143   vl_api_send_msg (ctx->reg, (u8 *) mp);
144
145   return (1);
146 }
147
148 static void
149 vl_api_gbp_endpoint_dump_t_handler (vl_api_gbp_endpoint_dump_t * mp)
150 {
151   vl_api_registration_t *reg;
152
153   reg = vl_api_client_index_to_registration (mp->client_index);
154   if (!reg)
155     return;
156
157   gbp_walk_ctx_t ctx = {
158     .reg = reg,
159     .context = mp->context,
160   };
161
162   gbp_endpoint_walk (gbp_endpoint_send_details, &ctx);
163 }
164
165 static void
166 vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp)
167 {
168   vl_api_gbp_contract_add_del_reply_t *rmp;
169   int rv = 0;
170
171   if (mp->is_add)
172     gbp_contract_update (ntohl (mp->contract.src_epg),
173                          ntohl (mp->contract.dst_epg),
174                          ntohl (mp->contract.acl_index));
175   else
176     gbp_contract_delete (ntohl (mp->contract.src_epg),
177                          ntohl (mp->contract.dst_epg));
178
179   REPLY_MACRO (VL_API_GBP_CONTRACT_ADD_DEL_REPLY + GBP_MSG_BASE);
180 }
181
182 static int
183 gbp_contract_send_details (gbp_contract_t * gbpc, void *args)
184 {
185   vl_api_gbp_contract_details_t *mp;
186   gbp_walk_ctx_t *ctx;
187
188   ctx = args;
189   mp = vl_msg_api_alloc (sizeof (*mp));
190   if (!mp)
191     return 1;
192
193   memset (mp, 0, sizeof (*mp));
194   mp->_vl_msg_id = ntohs (VL_API_GBP_CONTRACT_DETAILS + GBP_MSG_BASE);
195   mp->context = ctx->context;
196
197   mp->contract.src_epg = ntohl (gbpc->gc_key.gck_src);
198   mp->contract.dst_epg = ntohl (gbpc->gc_key.gck_dst);
199   mp->contract.acl_index = ntohl (gbpc->gc_acl_index);
200
201   vl_api_send_msg (ctx->reg, (u8 *) mp);
202
203   return (1);
204 }
205
206 static void
207 vl_api_gbp_contract_dump_t_handler (vl_api_gbp_contract_dump_t * mp)
208 {
209   vl_api_registration_t *reg;
210
211   reg = vl_api_client_index_to_registration (mp->client_index);
212   if (!reg)
213     return;
214
215   gbp_walk_ctx_t ctx = {
216     .reg = reg,
217     .context = mp->context,
218   };
219
220   gbp_contract_walk (gbp_contract_send_details, &ctx);
221 }
222
223 /*
224  * gbp_api_hookup
225  * Add vpe's API message handlers to the table.
226  * vlib has alread mapped shared memory and
227  * added the client registration handlers.
228  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
229  */
230 #define vl_msg_name_crc_list
231 #include <gbp/gbp_all_api_h.h>
232 #undef vl_msg_name_crc_list
233
234 static void
235 setup_message_id_table (api_main_t * am)
236 {
237 #define _(id,n,crc)                                     \
238   vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + GBP_MSG_BASE);
239   foreach_vl_msg_name_crc_gbp;
240 #undef _
241 }
242
243 static void
244 gbp_api_hookup (vlib_main_t * vm)
245 {
246 #define _(N,n)                                                  \
247     vl_msg_api_set_handlers(VL_API_##N + GBP_MSG_BASE,          \
248                             #n,                                 \
249                             vl_api_##n##_t_handler,             \
250                             vl_noop_handler,                    \
251                             vl_api_##n##_t_endian,              \
252                             vl_api_##n##_t_print,               \
253                             sizeof(vl_api_##n##_t), 1);
254   foreach_gbp_api_msg;
255 #undef _
256 }
257
258 static clib_error_t *
259 gbp_init (vlib_main_t * vm)
260 {
261   api_main_t *am = &api_main;
262   gbp_main_t *gbpm = &gbp_main;
263   u8 *name = format (0, "gbp_%08x%c", api_version, 0);
264
265   /* Ask for a correctly-sized block of API message decode slots */
266   gbpm->msg_id_base = vl_msg_api_get_msg_ids ((char *) name,
267                                               VL_MSG_FIRST_AVAILABLE);
268
269   gbp_api_hookup (vm);
270
271   /* Add our API messages to the global name_crc hash table */
272   setup_message_id_table (am);
273
274   vec_free (name);
275   return (NULL);
276 }
277
278 VLIB_API_INIT_FUNCTION (gbp_init);
279
280 /* *INDENT-OFF* */
281 VLIB_PLUGIN_REGISTER () = {
282     .version = VPP_BUILD_VER,
283     .description = "Group Based Policy",
284 };
285 /* *INDENT-ON* */
286
287
288 /*
289  * fd.io coding-style-patch-verification: ON
290  *
291  * Local Variables:
292  * eval: (c-set-style "gnu")
293  * End:
294  */