]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
Merge branch 'master' into type5-with-asymm
[mirror_frr.git] / zebra / zebra_vxlan.c
1 /*
2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "if.h"
26 #include "prefix.h"
27 #include "table.h"
28 #include "memory.h"
29 #include "log.h"
30 #include "linklist.h"
31 #include "stream.h"
32 #include "hash.h"
33 #include "jhash.h"
34 #include "vlan.h"
35 #include "vxlan.h"
36
37 #include "zebra/rib.h"
38 #include "zebra/rt.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
49
50 DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
51 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
54 DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
55 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
56
57 /* definitions */
58
59
60 /* static function declarations */
61 static int ip_prefix_send_to_client(vrf_id_t vrf_id,
62 struct prefix *p,
63 uint16_t cmd);
64 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
65 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
66 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
67 void **args);
68 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
69 json_object *json);
70 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
71 json_object *json);
72 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
73 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
74 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
75 static void zvni_print(zebra_vni_t *zvni, void **ctxt);
76 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
77
78 static int zvni_macip_send_msg_to_client(vni_t vni,
79 struct ethaddr *macaddr,
80 struct ipaddr *ip, u_char flags,
81 u_int16_t cmd);
82 static unsigned int neigh_hash_keymake(void *p);
83 static int neigh_cmp(const void *p1, const void *p2);
84 static void *zvni_neigh_alloc(void *p);
85 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
86 struct ethaddr *mac);
87 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
88 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg);
89 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
90 struct in_addr *r_vtep_ip);
91 static void zvni_neigh_del_all(zebra_vni_t *zvni,
92 int uninstall, int upd_client, u_int32_t flags);
93 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
94 static int zvni_neigh_send_add_to_client(vni_t vni,
95 struct ipaddr *ip,
96 struct ethaddr *macaddr, u_char flags);
97 static int zvni_neigh_send_del_to_client(vni_t vni,
98 struct ipaddr *ip,
99 struct ethaddr *macaddr, u_char flags);
100 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
101 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
102 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
103 struct interface *br_if);
104 static struct interface *zvni_map_to_svi(vlanid_t vid,
105 struct interface *br_if);
106
107 /* l3-vni next-hop neigh related APIs */
108 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
109 struct ipaddr *ip);
110 static void *zl3vni_nh_alloc(void *p);
111 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
112 struct ipaddr *vtep_ip,
113 struct ethaddr *rmac);
114 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
115 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
116 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
117
118 /* l3-vni rmac related APIs */
119 static void zl3vni_print_rmac_hash(struct hash_backet *, void *);
120 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
121 struct ethaddr *rmac);
122 static void *zl3vni_rmac_alloc(void *p);
123 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
124 struct ethaddr *rmac);
125 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
126 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
127 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
128 zebra_mac_t *zrmac);
129
130 /* l3-vni related APIs*/
131 static zebra_l3vni_t *zl3vni_lookup(vni_t vni);
132 static void *zl3vni_alloc(void *p);
133 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
134 static int zl3vni_del(zebra_l3vni_t *zl3vni);
135 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t);
136 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni);
137 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni);
138 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni);
139 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni);
140
141 static unsigned int mac_hash_keymake(void *p);
142 static int mac_cmp(const void *p1, const void *p2);
143 static void *zvni_mac_alloc(void *p);
144 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
145 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
146 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg);
147 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
148 struct in_addr *r_vtep_ip);
149 static void zvni_mac_del_all(zebra_vni_t *zvni,
150 int uninstall, int upd_client, u_int32_t flags);
151 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
152 static int zvni_mac_send_add_to_client(vni_t vni,
153 struct ethaddr *macaddr, u_char flags);
154 static int zvni_mac_send_del_to_client(vni_t vni,
155 struct ethaddr *macaddr, u_char flags);
156 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
157 struct interface *br_if, vlanid_t vid);
158 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
159 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local);
160 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
161
162 static unsigned int vni_hash_keymake(void *p);
163 static int vni_hash_cmp(const void *p1, const void *p2);
164 static void *zvni_alloc(void *p);
165 static zebra_vni_t *zvni_lookup(vni_t vni);
166 static zebra_vni_t *zvni_add(vni_t vni);
167 static int zvni_del(zebra_vni_t *zvni);
168 static int zvni_send_add_to_client(zebra_vni_t *zvni);
169 static int zvni_send_del_to_client(vni_t vni);
170 static void zvni_build_hash_table();
171 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
172 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
173 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
174 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
175 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
176 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
177 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
178 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
179 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
180 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
181 struct ethaddr *macaddr, struct ipaddr *ip);
182 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
183 struct ipaddr *ip);
184 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
185 static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
186 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
187 int uninstall);
188
189 /* Private functions */
190
191 /*
192 * Return number of valid MACs in a VNI's MAC hash table - all
193 * remote MACs and non-internal (auto) local MACs count.
194 */
195 static u_int32_t num_valid_macs(zebra_vni_t *zvni)
196 {
197 unsigned int i;
198 u_int32_t num_macs = 0;
199 struct hash *hash;
200 struct hash_backet *hb;
201 zebra_mac_t *mac;
202
203 hash = zvni->mac_table;
204 if (!hash)
205 return num_macs;
206 for (i = 0; i < hash->size; i++) {
207 for (hb = hash->index[i]; hb; hb = hb->next) {
208 mac = (zebra_mac_t *)hb->data;
209 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
210 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
211 num_macs++;
212 }
213 }
214
215 return num_macs;
216 }
217
218 static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
219 {
220 struct zebra_vrf *zvrf;
221
222 zvrf = vrf_info_lookup(VRF_DEFAULT);
223 if (zvrf && zvrf->advertise_gw_macip)
224 return 1;
225
226 if (zvni && zvni->advertise_gw_macip)
227 return 1;
228
229 return 0;
230 }
231
232 /*
233 * Helper function to determine maximum width of neighbor IP address for
234 * display - just because we're dealing with IPv6 addresses that can
235 * widely vary.
236 */
237 static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
238 {
239 zebra_neigh_t *n;
240 char buf[INET6_ADDRSTRLEN];
241 struct neigh_walk_ctx *wctx = ctxt;
242 int width;
243
244 n = (zebra_neigh_t *)backet->data;
245 if (!n)
246 return;
247
248 ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
249 if (width > wctx->addr_width)
250 wctx->addr_width = width;
251 }
252
253 /*
254 * Print a specific neighbor entry.
255 */
256 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
257 {
258 struct vty *vty;
259 char buf1[ETHER_ADDR_STRLEN];
260 char buf2[INET6_ADDRSTRLEN];
261
262 ipaddr2str(&n->ip, buf2, sizeof(buf2));
263 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
264 vty = (struct vty *)ctxt;
265 if (json == NULL) {
266 vty_out(vty, "IP: %s\n",
267 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
268 vty_out(vty, " MAC: %s",
269 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
270 } else {
271 json_object_string_add(json, "ip", buf2);
272 json_object_string_add(json, "mac", buf1);
273 }
274 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
275 if (json == NULL) {
276 vty_out(vty, " Remote VTEP: %s",
277 inet_ntoa(n->r_vtep_ip));
278 } else
279 json_object_string_add(json, "remoteVtep",
280 inet_ntoa(n->r_vtep_ip));
281 }
282 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
283 if (!json) {
284 vty_out(vty, "\n");
285 vty_out(vty, " State: %s",
286 IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active"
287 : "Inactive");
288 }
289 }
290 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
291 if (!json)
292 vty_out(vty, " Default-gateway");
293 else
294 json_object_boolean_true_add(json, "defaultGateway");
295 }
296 if (json == NULL)
297 vty_out(vty, "\n");
298 }
299
300 /*
301 * Print neighbor hash entry - called for display of all neighbors.
302 */
303 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
304 {
305 struct vty *vty;
306 json_object *json_vni = NULL, *json_row = NULL;
307 zebra_neigh_t *n;
308 char buf1[ETHER_ADDR_STRLEN];
309 char buf2[INET6_ADDRSTRLEN];
310 struct neigh_walk_ctx *wctx = ctxt;
311
312 vty = wctx->vty;
313 json_vni = wctx->json;
314 n = (zebra_neigh_t *)backet->data;
315 if (!n)
316 return;
317
318 if (json_vni)
319 json_row = json_object_new_object();
320
321 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
322 ipaddr2str(&n->ip, buf2, sizeof(buf2));
323 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
324 && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
325 if (json_vni == NULL) {
326 vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
327 buf2, "local", buf1);
328 } else {
329 json_object_string_add(json_row, "type", "local");
330 json_object_string_add(json_row, "mac", buf1);
331 }
332 wctx->count++;
333 } else {
334 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
335 if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
336 if (json_vni == NULL) {
337 if (wctx->count == 0)
338 vty_out(vty,
339 "%*s %-6s %-17s %-21s\n",
340 -wctx->addr_width,
341 "Neighbor", "Type",
342 "MAC", "Remote VTEP");
343 vty_out(vty, "%*s %-6s %-17s %-21s\n",
344 -wctx->addr_width, buf2,
345 "remote", buf1,
346 inet_ntoa(n->r_vtep_ip));
347 } else {
348 json_object_string_add(json_row, "type",
349 "remote");
350 json_object_string_add(json_row, "mac",
351 buf1);
352 json_object_string_add(
353 json_row, "remoteVtep",
354 inet_ntoa(n->r_vtep_ip));
355 }
356 wctx->count++;
357 }
358 } else {
359 if (json_vni == NULL) {
360 vty_out(vty, "%*s %-6s %-17s %-21s\n",
361 -wctx->addr_width, buf2, "remote", buf1,
362 inet_ntoa(n->r_vtep_ip));
363 } else {
364 json_object_string_add(json_row, "type",
365 "remote");
366 json_object_string_add(json_row, "mac", buf1);
367 json_object_string_add(json_row, "remoteVtep",
368 inet_ntoa(n->r_vtep_ip));
369 }
370 wctx->count++;
371 }
372 }
373
374 if (json_vni)
375 json_object_object_add(json_vni, buf2, json_row);
376 }
377
378 /*
379 * Print neighbors for all VNI.
380 */
381 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
382 void **args)
383 {
384 struct vty *vty;
385 json_object *json = NULL, *json_vni = NULL;
386 zebra_vni_t *zvni;
387 u_int32_t num_neigh;
388 struct neigh_walk_ctx wctx;
389 char vni_str[VNI_STR_LEN];
390
391 vty = (struct vty *)args[0];
392 json = (json_object *)args[1];
393
394 zvni = (zebra_vni_t *)backet->data;
395 if (!zvni) {
396 if (json)
397 vty_out(vty, "{}\n");
398 return;
399 }
400 num_neigh = hashcount(zvni->neigh_table);
401 if (json == NULL)
402 vty_out(vty,
403 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
404 zvni->vni, num_neigh);
405 else {
406 json_vni = json_object_new_object();
407 json_object_int_add(json_vni, "numArpNd", num_neigh);
408 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
409 }
410 if (!num_neigh) {
411 if (json)
412 json_object_object_add(json, vni_str, json_vni);
413 return;
414 }
415
416 /* Since we have IPv6 addresses to deal with which can vary widely in
417 * size, we try to be a bit more elegant in display by first computing
418 * the maximum width.
419 */
420 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
421 wctx.zvni = zvni;
422 wctx.vty = vty;
423 wctx.addr_width = 15;
424 wctx.json = json_vni;
425 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
426
427 if (json == NULL)
428 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
429 "Type", "MAC", "Remote VTEP");
430 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
431
432 if (json)
433 json_object_object_add(json, vni_str, json_vni);
434 }
435
436 /* print a specific next hop for an l3vni */
437 static void zl3vni_print_nh(zebra_neigh_t *n,
438 struct vty *vty,
439 json_object *json)
440 {
441 char buf1[ETHER_ADDR_STRLEN];
442 char buf2[INET6_ADDRSTRLEN];
443 struct listnode *node = NULL;
444 struct prefix *p = NULL;
445 json_object *json_hosts = NULL;
446
447 if (!json) {
448 vty_out(vty, "Ip: %s\n",
449 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
450 vty_out(vty, " RMAC: %s\n",
451 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
452 vty_out(vty, " Refcount: %d\n", listcount(n->host_list));
453 vty_out(vty, " Prefixes:\n");
454 for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
455 vty_out(vty, " %s\n",
456 prefix2str(p, buf2, sizeof(buf2)));
457 } else {
458 json_hosts = json_object_new_array();
459 json_object_string_add(json, "ip",
460 ipaddr2str(&(n->ip), buf2,
461 sizeof(buf2)));
462 json_object_string_add(json, "routerMac",
463 prefix_mac2str(&n->emac, buf2,
464 sizeof(buf2)));
465 json_object_int_add(json, "refCount", listcount(n->host_list));
466 for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
467 json_object_array_add(json_hosts,
468 json_object_new_string(
469 prefix2str(p, buf2,
470 sizeof(buf2))));
471 json_object_object_add(json, "prefixList", json_hosts);
472 }
473 }
474
475 /* Print a specific RMAC entry */
476 static void zl3vni_print_rmac(zebra_mac_t *zrmac,
477 struct vty *vty,
478 json_object *json)
479 {
480 char buf1[ETHER_ADDR_STRLEN];
481 char buf2[PREFIX_STRLEN];
482 struct listnode *node = NULL;
483 struct prefix *p = NULL;
484 json_object *json_hosts = NULL;
485
486 if (!json) {
487 vty_out(vty, "MAC: %s\n",
488 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
489 vty_out(vty, " Remote VTEP: %s\n",
490 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
491 vty_out(vty, " Refcount: %d\n", listcount(zrmac->host_list));
492 vty_out(vty, " Prefixes:\n");
493 for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
494 vty_out(vty, " %s\n",
495 prefix2str(p, buf2, sizeof(buf2)));
496 } else {
497 json_hosts = json_object_new_array();
498 json_object_string_add(json, "routerMac",
499 prefix_mac2str(&zrmac->macaddr,
500 buf1,
501 sizeof(buf1)));
502 json_object_string_add(json, "vtepIp",
503 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
504 json_object_int_add(json, "refCount",
505 listcount(zrmac->host_list));
506 for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
507 json_object_array_add(json_hosts,
508 json_object_new_string(
509 prefix2str(p, buf2,
510 sizeof(buf2))));
511 json_object_object_add(json, "prefixList", json_hosts);
512 }
513 }
514
515 /*
516 * Print a specific MAC entry.
517 */
518 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
519 {
520 struct vty *vty;
521 zebra_neigh_t *n = NULL;
522 struct listnode *node = NULL;
523 char buf1[20];
524 char buf2[INET6_ADDRSTRLEN];
525
526 vty = (struct vty *)ctxt;
527 vty_out(vty, "MAC: %s",
528 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
529 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
530 struct zebra_ns *zns;
531 struct interface *ifp;
532 ifindex_t ifindex;
533
534 ifindex = mac->fwd_info.local.ifindex;
535 zns = zebra_ns_lookup(NS_DEFAULT);
536 ifp = if_lookup_by_index_per_ns(zns, ifindex);
537 if (!ifp) // unexpected
538 return;
539 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
540 if (mac->fwd_info.local.vid)
541 vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
542 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
543 vty_out(vty, " Remote VTEP: %s",
544 inet_ntoa(mac->fwd_info.r_vtep_ip));
545 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
546 vty_out(vty, " Auto Mac ");
547 }
548
549 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
550 vty_out(vty, " Sticky Mac ");
551
552 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
553 vty_out(vty, " Default-gateway Mac ");
554
555 vty_out(vty, "\n");
556 /* print all the associated neigh */
557 vty_out(vty, " Neighbors:\n");
558 if (!listcount(mac->neigh_list))
559 vty_out(vty, " No Neighbors\n");
560 else {
561 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
562 vty_out(vty, " %s %s\n",
563 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
564 CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL)
565 ? (IS_ZEBRA_NEIGH_ACTIVE(n)
566 ? "Active"
567 : "Inactive")
568 : "");
569 }
570 }
571
572 vty_out(vty, "\n");
573 }
574
575 /*
576 * Print MAC hash entry - called for display of all MACs.
577 */
578 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
579 {
580 struct vty *vty;
581 json_object *json_mac_hdr = NULL, *json_mac = NULL;
582 zebra_mac_t *mac;
583 char buf1[20];
584 struct mac_walk_ctx *wctx = ctxt;
585
586 vty = wctx->vty;
587 json_mac_hdr = wctx->json;
588 mac = (zebra_mac_t *)backet->data;
589 if (!mac)
590 return;
591
592 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
593
594 if (json_mac_hdr)
595 json_mac = json_object_new_object();
596
597 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
598 && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
599 struct zebra_ns *zns;
600 ifindex_t ifindex;
601 struct interface *ifp;
602 vlanid_t vid;
603
604 zns = zebra_ns_lookup(NS_DEFAULT);
605 ifindex = mac->fwd_info.local.ifindex;
606 ifp = if_lookup_by_index_per_ns(zns, ifindex);
607 if (!ifp) // unexpected
608 return;
609 vid = mac->fwd_info.local.vid;
610 if (json_mac_hdr == NULL)
611 vty_out(vty, "%-17s %-6s %-21s", buf1, "local",
612 ifp->name);
613 else {
614 json_object_string_add(json_mac, "type", "local");
615 json_object_string_add(json_mac, "intf", ifp->name);
616 }
617 if (vid) {
618 if (json_mac_hdr == NULL)
619 vty_out(vty, " %-5u", vid);
620 else
621 json_object_int_add(json_mac, "vlan", vid);
622 }
623 if (json_mac_hdr == NULL)
624 vty_out(vty, "\n");
625 else
626 json_object_object_add(json_mac_hdr, buf1, json_mac);
627 wctx->count++;
628 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
629 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
630 if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
631 &wctx->r_vtep_ip)) {
632 if (wctx->count == 0) {
633 if (json_mac_hdr == NULL) {
634 vty_out(vty, "\nVNI %u\n\n",
635 wctx->zvni->vni);
636 vty_out(vty,
637 "%-17s %-6s %-21s %-5s\n",
638 "MAC", "Type",
639 "Intf/Remote VTEP",
640 "VLAN");
641 }
642 }
643 if (json_mac_hdr == NULL)
644 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
645 "remote",
646 inet_ntoa(mac->fwd_info
647 .r_vtep_ip));
648 else {
649 json_object_string_add(json_mac, "type",
650 "remote");
651 json_object_string_add(
652 json_mac, "remoteVtep",
653 inet_ntoa(mac->fwd_info
654 .r_vtep_ip));
655 json_object_object_add(json_mac_hdr,
656 buf1, json_mac);
657 }
658 wctx->count++;
659 }
660 } else {
661 if (json_mac_hdr == NULL)
662 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
663 "remote",
664 inet_ntoa(mac->fwd_info.r_vtep_ip));
665 else {
666 json_object_string_add(json_mac, "type",
667 "remote");
668 json_object_string_add(
669 json_mac, "remoteVtep",
670 inet_ntoa(mac->fwd_info.r_vtep_ip));
671 json_object_object_add(json_mac_hdr, buf1,
672 json_mac);
673 }
674 wctx->count++;
675 }
676 }
677 }
678
679 /*
680 * Print MACs for all VNI.
681 */
682 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
683 {
684 struct vty *vty;
685 json_object *json = NULL, *json_vni = NULL;
686 json_object *json_mac = NULL;
687 zebra_vni_t *zvni;
688 u_int32_t num_macs;
689 struct mac_walk_ctx *wctx = ctxt;
690 char vni_str[VNI_STR_LEN];
691
692 vty = (struct vty *)wctx->vty;
693 json = (struct json_object *)wctx->json;
694
695 zvni = (zebra_vni_t *)backet->data;
696 if (!zvni) {
697 if (json)
698 vty_out(vty, "{}\n");
699 return;
700 }
701 wctx->zvni = zvni;
702
703 /*We are iterating over a new VNI, set the count to 0*/
704 wctx->count = 0;
705
706 num_macs = num_valid_macs(zvni);
707 if (!num_macs)
708 return;
709
710 if (json) {
711 json_vni = json_object_new_object();
712 json_mac = json_object_new_object();
713 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
714 }
715
716 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
717 if (json == NULL) {
718 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
719 zvni->vni, num_macs);
720 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
721 "Intf/Remote VTEP", "VLAN");
722 } else
723 json_object_int_add(json_vni, "numMacs", num_macs);
724 }
725 /* assign per-vni to wctx->json object to fill macs
726 * under the vni. Re-assign primary json object to fill
727 * next vni information.
728 */
729 wctx->json = json_mac;
730 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
731 wctx->json = json;
732 if (json) {
733 if (wctx->count)
734 json_object_object_add(json_vni, "macs", json_mac);
735 json_object_object_add(json, vni_str, json_vni);
736 }
737 }
738
739 static void zl3vni_print_nh_hash(struct hash_backet *backet,
740 void *ctx)
741 {
742 struct nh_walk_ctx *wctx = NULL;
743 struct vty *vty = NULL;
744 struct json_object *json_vni = NULL;
745 struct json_object *json_nh = NULL;
746 zebra_neigh_t *n = NULL;
747 char buf1[ETHER_ADDR_STRLEN];
748 char buf2[INET6_ADDRSTRLEN];
749
750 wctx = (struct nh_walk_ctx *)ctx;
751 vty = wctx->vty;
752 json_vni = wctx->json;
753 if (json_vni)
754 json_nh = json_object_new_object();
755 n = (zebra_neigh_t *)backet->data;
756 if (!n)
757 return;
758
759 if (!json_vni) {
760 vty_out(vty, "%-15s %-17s\n",
761 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
762 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
763 } else {
764 json_object_string_add(json_nh, "nexthopIp",
765 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
766 json_object_string_add(json_nh, "routerMac",
767 prefix_mac2str(&n->emac, buf1,
768 sizeof(buf1)));
769 json_object_object_add(json_vni,
770 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
771 json_nh);
772 }
773 }
774
775 static void zl3vni_print_nh_hash_all_vni(struct hash_backet *backet,
776 void **args)
777 {
778 struct vty *vty = NULL;
779 json_object *json = NULL;
780 json_object *json_vni = NULL;
781 zebra_l3vni_t *zl3vni = NULL;
782 uint32_t num_nh = 0;
783 struct nh_walk_ctx wctx;
784 char vni_str[VNI_STR_LEN];
785
786 vty = (struct vty *)args[0];
787 json = (struct json_object *)args[1];
788
789 zl3vni = (zebra_l3vni_t *)backet->data;
790 if (!zl3vni) {
791 if (json)
792 vty_out(vty, "{}\n");
793 return;
794 }
795
796 num_nh = hashcount(zl3vni->nh_table);
797 if (!num_nh)
798 return;
799
800 if (json) {
801 json_vni = json_object_new_object();
802 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
803 }
804
805 if (json == NULL) {
806 vty_out(vty, "\nVNI %u #Next-Hops %u\n\n",
807 zl3vni->vni, num_nh);
808 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
809 } else
810 json_object_int_add(json_vni, "numNextHops", num_nh);
811
812 memset(&wctx, 0, sizeof(struct nh_walk_ctx));
813 wctx.vty = vty;
814 wctx.json = json_vni;
815 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
816 if (json)
817 json_object_object_add(json, vni_str, json_vni);
818 }
819
820 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet *backet,
821 void **args)
822 {
823 struct vty *vty = NULL;
824 json_object *json = NULL;
825 json_object *json_vni = NULL;
826 zebra_l3vni_t *zl3vni = NULL;
827 u_int32_t num_rmacs;
828 struct rmac_walk_ctx wctx;
829 char vni_str[VNI_STR_LEN];
830
831 vty = (struct vty *)args[0];
832 json = (struct json_object *)args[1];
833
834 zl3vni = (zebra_l3vni_t *)backet->data;
835 if (!zl3vni) {
836 if (json)
837 vty_out(vty, "{}\n");
838 return;
839 }
840
841 num_rmacs = hashcount(zl3vni->rmac_table);
842 if (!num_rmacs)
843 return;
844
845 if (json) {
846 json_vni = json_object_new_object();
847 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
848 }
849
850 if (json == NULL) {
851 vty_out(vty, "\nVNI %u #RMACs %u\n\n",
852 zl3vni->vni, num_rmacs);
853 vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
854 } else
855 json_object_int_add(json_vni, "numRmacs", num_rmacs);
856
857 /* assign per-vni to wctx->json object to fill macs
858 * under the vni. Re-assign primary json object to fill
859 * next vni information.
860 */
861 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
862 wctx.vty = vty;
863 wctx.json = json_vni;
864 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
865 if (json)
866 json_object_object_add(json, vni_str, json_vni);
867 }
868
869 static void zl3vni_print_rmac_hash(struct hash_backet *backet,
870 void *ctx)
871 {
872 zebra_mac_t *zrmac = NULL;
873 struct rmac_walk_ctx *wctx = NULL;
874 struct vty *vty = NULL;
875 struct json_object *json = NULL;
876 struct json_object *json_rmac = NULL;
877 char buf[ETHER_ADDR_STRLEN];
878
879 wctx = (struct rmac_walk_ctx *)ctx;
880 vty = wctx->vty;
881 json = wctx->json;
882 if (json)
883 json_rmac = json_object_new_object();
884 zrmac = (zebra_mac_t *)backet->data;
885 if (!zrmac)
886 return;
887
888 if (!json) {
889 vty_out(vty, "%-17s %-21s\n",
890 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
891 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
892 } else {
893 json_object_string_add(json_rmac, "routerMac",
894 prefix_mac2str(&zrmac->macaddr, buf,
895 sizeof(buf)));
896 json_object_string_add(json_rmac, "vtepIp",
897 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
898 json_object_object_add(json,
899 prefix_mac2str(&zrmac->macaddr, buf,
900 sizeof(buf)),
901 json_rmac);
902 }
903 }
904
905 /* print a specific L3 VNI entry */
906 static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
907 {
908 char buf[ETHER_ADDR_STRLEN];
909 struct vty *vty = NULL;
910 json_object *json = NULL;
911 zebra_vni_t *zvni = NULL;
912 json_object *json_vni_list = NULL;
913 struct listnode *node = NULL, *nnode = NULL;
914
915 vty = ctx[0];
916 json = ctx[1];
917
918 if (!json) {
919 vty_out(vty, "VNI: %u\n", zl3vni->vni);
920 vty_out(vty, " Type: %s\n", "L3");
921 vty_out(vty, " Tenant VRF: %s\n",
922 zl3vni_vrf_name(zl3vni));
923 vty_out(vty, " Local Vtep Ip: %s\n",
924 inet_ntoa(zl3vni->local_vtep_ip));
925 vty_out(vty, " Vxlan-Intf: %s\n",
926 zl3vni_vxlan_if_name(zl3vni));
927 vty_out(vty, " SVI-If: %s\n",
928 zl3vni_svi_if_name(zl3vni));
929 vty_out(vty, " State: %s\n",
930 zl3vni_state2str(zl3vni));
931 vty_out(vty, " VNI Filter: %s\n",
932 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ?
933 "prefix-routes-only" : "none");
934 vty_out(vty, " Router MAC: %s\n",
935 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
936 vty_out(vty, " L2 VNIs: ");
937 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni))
938 vty_out(vty, "%u ", zvni->vni);
939 vty_out(vty, "\n");
940 } else {
941 json_vni_list = json_object_new_array();
942 json_object_int_add(json, "vni", zl3vni->vni);
943 json_object_string_add(json, "type", "L3");
944 json_object_string_add(json, "localVtepIp",
945 inet_ntoa(zl3vni->local_vtep_ip));
946 json_object_string_add(json, "vxlanIntf",
947 zl3vni_vxlan_if_name(zl3vni));
948 json_object_string_add(json, "sviIntf",
949 zl3vni_svi_if_name(zl3vni));
950 json_object_string_add(json, "state",
951 zl3vni_state2str(zl3vni));
952 json_object_string_add(json, "vrf",
953 zl3vni_vrf_name(zl3vni));
954 json_object_string_add(json, "routerMac",
955 zl3vni_rmac2str(zl3vni, buf,
956 sizeof(buf)));
957 json_object_string_add(json, "vniFilter",
958 CHECK_FLAG(zl3vni->filter,
959 PREFIX_ROUTES_ONLY) ?
960 "prefix-routes-only" : "none");
961 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni)) {
962 json_object_array_add(json_vni_list,
963 json_object_new_int(zvni->vni));
964 }
965 json_object_object_add(json, "l2Vnis", json_vni_list);
966 }
967 }
968
969 /*
970 * Print a specific VNI entry.
971 */
972 static void zvni_print(zebra_vni_t *zvni, void **ctxt)
973 {
974 struct vty *vty;
975 zebra_vtep_t *zvtep;
976 u_int32_t num_macs;
977 u_int32_t num_neigh;
978 json_object *json = NULL;
979 json_object *json_vtep_list = NULL;
980 json_object *json_ip_str = NULL;
981
982 vty = ctxt[0];
983 json = ctxt[1];
984
985 if (json == NULL) {
986 vty_out(vty, "VNI: %u\n", zvni->vni);
987 vty_out(vty, " Type: %s\n", "L2");
988 vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zvni->vrf_id));
989 } else {
990 json_object_int_add(json, "vni", zvni->vni);
991 json_object_string_add(json, "type", "L2");
992 json_object_string_add(json, "vrf",
993 vrf_id_to_name(zvni->vrf_id));
994 }
995
996 if (!zvni->vxlan_if) { // unexpected
997 if (json == NULL)
998 vty_out(vty, " VxLAN interface: unknown\n");
999 return;
1000 }
1001 num_macs = num_valid_macs(zvni);
1002 num_neigh = hashcount(zvni->neigh_table);
1003 if (json == NULL) {
1004 vty_out(vty, " VxLAN interface: %s\n",
1005 zvni->vxlan_if->name);
1006 vty_out(vty, " VxLAN ifIndex: %u\n", zvni->vxlan_if->ifindex);
1007 vty_out(vty," Local VTEP IP: %s\n",
1008 inet_ntoa(zvni->local_vtep_ip));
1009 } else {
1010 json_object_string_add(json, "vxlanInterface",
1011 zvni->vxlan_if->name);
1012 json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
1013 json_object_string_add(json, "vtepIp",
1014 inet_ntoa(zvni->local_vtep_ip));
1015 json_object_string_add(json, "advertiseGatewayMacip",
1016 zvni->advertise_gw_macip ? "Yes" : "No");
1017 json_object_int_add(json, "numMacs", num_macs);
1018 json_object_int_add(json, "numArpNd", num_neigh);
1019 }
1020 if (!zvni->vteps) {
1021 if (json == NULL)
1022 vty_out(vty, " No remote VTEPs known for this VNI\n");
1023 } else {
1024 if (json == NULL)
1025 vty_out(vty, " Remote VTEPs for this VNI:\n");
1026 else
1027 json_vtep_list = json_object_new_array();
1028 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1029 if (json == NULL)
1030 vty_out(vty, " %s\n",
1031 inet_ntoa(zvtep->vtep_ip));
1032 else {
1033 json_ip_str = json_object_new_string(
1034 inet_ntoa(zvtep->vtep_ip));
1035 json_object_array_add(json_vtep_list,
1036 json_ip_str);
1037 }
1038 }
1039 if (json)
1040 json_object_object_add(json, "numRemoteVteps",
1041 json_vtep_list);
1042 }
1043 if (json == NULL) {
1044 vty_out(vty,
1045 " Number of MACs (local and remote) known for this VNI: %u\n",
1046 num_macs);
1047 vty_out(vty,
1048 " Number of ARPs (IPv4 and IPv6, local and remote) "
1049 "known for this VNI: %u\n",
1050 num_neigh);
1051 vty_out(vty, " Advertise-gw-macip: %s\n",
1052 zvni->advertise_gw_macip ? "Yes" : "No");
1053 }
1054 }
1055
1056 /* print a L3 VNI hash entry */
1057 static void zl3vni_print_hash(struct hash_backet *backet,
1058 void *ctx[])
1059 {
1060 struct vty *vty = NULL;
1061 json_object *json = NULL;
1062 json_object *json_vni = NULL;
1063 zebra_l3vni_t *zl3vni = NULL;
1064
1065 vty = (struct vty *)ctx[0];
1066 json = (json_object *)ctx[1];
1067
1068 zl3vni = (zebra_l3vni_t *)backet->data;
1069 if (!zl3vni)
1070 return;
1071
1072 if (!json) {
1073 vty_out(vty,
1074 "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1075 zl3vni->vni, "L3",
1076 zl3vni_vxlan_if_name(zl3vni),
1077 hashcount(zl3vni->rmac_table),
1078 hashcount(zl3vni->nh_table),
1079 "n/a",
1080 zl3vni_vrf_name(zl3vni));
1081 } else {
1082 char vni_str[VNI_STR_LEN];
1083
1084 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1085 json_vni = json_object_new_object();
1086 json_object_int_add(json_vni, "vni", zl3vni->vni);
1087 json_object_string_add(json_vni, "vxlanIf",
1088 zl3vni_vxlan_if_name(zl3vni));
1089 json_object_int_add(json_vni, "numMacs",
1090 hashcount(zl3vni->rmac_table));
1091 json_object_int_add(json_vni, "numArpNd",
1092 hashcount(zl3vni->nh_table));
1093 json_object_string_add(json_vni, "numRemoteVteps", "n/a");
1094 json_object_string_add(json_vni, "type", "L3");
1095 json_object_string_add(json_vni, "tenantVrf",
1096 zl3vni_vrf_name(zl3vni));
1097 json_object_object_add(json, vni_str, json_vni);
1098 }
1099
1100 }
1101
1102 /*
1103 * Print a VNI hash entry - called for display of all VNIs.
1104 */
1105 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
1106 {
1107 struct vty *vty;
1108 zebra_vni_t *zvni;
1109 zebra_vtep_t *zvtep;
1110 u_int32_t num_vteps = 0;
1111 u_int32_t num_macs = 0;
1112 u_int32_t num_neigh = 0;
1113 json_object *json = NULL;
1114 json_object *json_vni = NULL;
1115 json_object *json_ip_str = NULL;
1116 json_object *json_vtep_list = NULL;
1117
1118 vty = ctxt[0];
1119 json = ctxt[1];
1120
1121 zvni = (zebra_vni_t *)backet->data;
1122 if (!zvni)
1123 return;
1124
1125 zvtep = zvni->vteps;
1126 while (zvtep) {
1127 num_vteps++;
1128 zvtep = zvtep->next;
1129 }
1130
1131 num_macs = num_valid_macs(zvni);
1132 num_neigh = hashcount(zvni->neigh_table);
1133 if (json == NULL)
1134 vty_out(vty,
1135 "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1136 zvni->vni, "L2",
1137 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
1138 num_macs, num_neigh, num_vteps,
1139 vrf_id_to_name(zvni->vrf_id));
1140 else {
1141 char vni_str[VNI_STR_LEN];
1142 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
1143 json_vni = json_object_new_object();
1144 json_object_int_add(json_vni, "vni", zvni->vni);
1145 json_object_string_add(json_vni, "type", "L2");
1146 json_object_string_add(json_vni, "vxlanIf",
1147 zvni->vxlan_if ? zvni->vxlan_if->name
1148 : "unknown");
1149 json_object_int_add(json_vni, "numMacs", num_macs);
1150 json_object_int_add(json_vni, "numArpNd", num_neigh);
1151 json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
1152 json_object_string_add(json_vni, "tenantVrf",
1153 vrf_id_to_name(zvni->vrf_id));
1154 if (num_vteps) {
1155 json_vtep_list = json_object_new_array();
1156 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1157 json_ip_str = json_object_new_string(
1158 inet_ntoa(zvtep->vtep_ip));
1159 json_object_array_add(json_vtep_list,
1160 json_ip_str);
1161 }
1162 json_object_object_add(json_vni, "remoteVteps",
1163 json_vtep_list);
1164 }
1165 json_object_object_add(json, vni_str, json_vni);
1166 }
1167 }
1168
1169 /*
1170 * Inform BGP about local MACIP.
1171 */
1172 static int zvni_macip_send_msg_to_client(vni_t vni,
1173 struct ethaddr *macaddr,
1174 struct ipaddr *ip, u_char flags,
1175 u_int16_t cmd)
1176 {
1177 char buf[ETHER_ADDR_STRLEN];
1178 char buf2[INET6_ADDRSTRLEN];
1179 int ipa_len;
1180 struct zserv *client = NULL;
1181 struct stream *s = NULL;
1182
1183 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
1184 /* BGP may not be running. */
1185 if (!client)
1186 return 0;
1187
1188 s = client->obuf;
1189 stream_reset(s);
1190
1191 zclient_create_header(s, cmd, VRF_DEFAULT);
1192 stream_putl(s, vni);
1193 stream_put(s, macaddr->octet, ETH_ALEN);
1194 if (ip) {
1195 ipa_len = 0;
1196 if (IS_IPADDR_V4(ip))
1197 ipa_len = IPV4_MAX_BYTELEN;
1198 else if (IS_IPADDR_V6(ip))
1199 ipa_len = IPV6_MAX_BYTELEN;
1200
1201 stream_putl(s, ipa_len); /* IP address length */
1202 if (ipa_len)
1203 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
1204 } else
1205 stream_putl(s, 0); /* Just MAC. */
1206
1207 stream_putc(s, flags); /* sticky mac/gateway mac */
1208
1209
1210 /* Write packet size. */
1211 stream_putw_at(s, 0, stream_get_endp(s));
1212
1213 if (IS_ZEBRA_DEBUG_VXLAN)
1214 zlog_debug(
1215 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1216 (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
1217 flags, prefix_mac2str(macaddr, buf, sizeof(buf)),
1218 ipaddr2str(ip, buf2, sizeof(buf2)), vni,
1219 zebra_route_string(client->proto));
1220
1221 if (cmd == ZEBRA_MACIP_ADD)
1222 client->macipadd_cnt++;
1223 else
1224 client->macipdel_cnt++;
1225
1226 return zebra_server_send_message(client);
1227 }
1228
1229 /*
1230 * Make hash key for neighbors.
1231 */
1232 static unsigned int neigh_hash_keymake(void *p)
1233 {
1234 zebra_neigh_t *n = p;
1235 struct ipaddr *ip = &n->ip;
1236
1237 if (IS_IPADDR_V4(ip))
1238 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
1239
1240 return jhash2(ip->ipaddr_v6.s6_addr32,
1241 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
1242 }
1243
1244 /*
1245 * Compare two neighbor hash structures.
1246 */
1247 static int neigh_cmp(const void *p1, const void *p2)
1248 {
1249 const zebra_neigh_t *n1 = p1;
1250 const zebra_neigh_t *n2 = p2;
1251
1252 if (n1 == NULL && n2 == NULL)
1253 return 1;
1254
1255 if (n1 == NULL || n2 == NULL)
1256 return 0;
1257
1258 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
1259 }
1260
1261 /*
1262 * Callback to allocate neighbor hash entry.
1263 */
1264 static void *zvni_neigh_alloc(void *p)
1265 {
1266 const zebra_neigh_t *tmp_n = p;
1267 zebra_neigh_t *n;
1268
1269 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
1270 *n = *tmp_n;
1271
1272 return ((void *)n);
1273 }
1274
1275 /*
1276 * Add neighbor entry.
1277 */
1278 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
1279 struct ethaddr *mac)
1280 {
1281 zebra_neigh_t tmp_n;
1282 zebra_neigh_t *n = NULL;
1283 zebra_mac_t *zmac = NULL;
1284
1285 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
1286 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
1287 n = hash_get(zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
1288 assert(n);
1289
1290 memcpy(&n->emac, mac, ETH_ALEN);
1291 n->state = ZEBRA_NEIGH_INACTIVE;
1292
1293 /* Associate the neigh to mac */
1294 zmac = zvni_mac_lookup(zvni, mac);
1295 if (zmac)
1296 listnode_add_sort(zmac->neigh_list, n);
1297
1298 return n;
1299 }
1300
1301 /*
1302 * Delete neighbor entry.
1303 */
1304 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
1305 {
1306 zebra_neigh_t *tmp_n;
1307 zebra_mac_t *zmac = NULL;
1308
1309 zmac = zvni_mac_lookup(zvni, &n->emac);
1310 if (zmac)
1311 listnode_delete(zmac->neigh_list, n);
1312
1313 /* Free the VNI hash entry and allocated memory. */
1314 tmp_n = hash_release(zvni->neigh_table, n);
1315 if (tmp_n)
1316 XFREE(MTYPE_NEIGH, tmp_n);
1317
1318 return 0;
1319 }
1320
1321 /*
1322 * Free neighbor hash entry (callback)
1323 */
1324 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
1325 {
1326 struct neigh_walk_ctx *wctx = arg;
1327 zebra_neigh_t *n = backet->data;
1328
1329 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
1330 || ((wctx->flags & DEL_REMOTE_NEIGH)
1331 && (n->flags & ZEBRA_NEIGH_REMOTE))
1332 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
1333 && (n->flags & ZEBRA_NEIGH_REMOTE)
1334 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
1335 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
1336 zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip,
1337 &n->emac, 0);
1338
1339 if (wctx->uninstall)
1340 zvni_neigh_uninstall(wctx->zvni, n);
1341
1342 return zvni_neigh_del(wctx->zvni, n);
1343 }
1344
1345 return 0;
1346 }
1347
1348 /*
1349 * Delete all neighbor entries from specific VTEP for a particular VNI.
1350 */
1351 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
1352 struct in_addr *r_vtep_ip)
1353 {
1354 struct neigh_walk_ctx wctx;
1355
1356 if (!zvni->neigh_table)
1357 return;
1358
1359 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1360 wctx.zvni = zvni;
1361 wctx.uninstall = uninstall;
1362 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
1363 wctx.r_vtep_ip = *r_vtep_ip;
1364
1365 hash_iterate(zvni->neigh_table,
1366 (void (*)(struct hash_backet *,
1367 void *))zvni_neigh_del_hash_entry,
1368 &wctx);
1369 }
1370
1371 /*
1372 * Delete all neighbor entries for this VNI.
1373 */
1374 static void zvni_neigh_del_all(zebra_vni_t *zvni,
1375 int uninstall, int upd_client, u_int32_t flags)
1376 {
1377 struct neigh_walk_ctx wctx;
1378
1379 if (!zvni->neigh_table)
1380 return;
1381
1382 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1383 wctx.zvni = zvni;
1384 wctx.uninstall = uninstall;
1385 wctx.upd_client = upd_client;
1386 wctx.flags = flags;
1387
1388 hash_iterate(zvni->neigh_table,
1389 (void (*)(struct hash_backet *,
1390 void *))zvni_neigh_del_hash_entry,
1391 &wctx);
1392 }
1393
1394 /*
1395 * Look up neighbor hash entry.
1396 */
1397 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
1398 {
1399 zebra_neigh_t tmp;
1400 zebra_neigh_t *n;
1401
1402 memset(&tmp, 0, sizeof(tmp));
1403 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
1404 n = hash_lookup(zvni->neigh_table, &tmp);
1405
1406 return n;
1407 }
1408
1409 /* Process all neigh associated to a mac upon local mac add event */
1410 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni,
1411 zebra_mac_t *zmac)
1412 {
1413 zebra_neigh_t *n = NULL;
1414 struct listnode *node = NULL;
1415 char buf[ETHER_ADDR_STRLEN];
1416 char buf2[INET6_ADDRSTRLEN];
1417
1418 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1419 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1420 /* MAC is learnt locally, program all inactive neigh
1421 * pointing to this mac */
1422 if (IS_ZEBRA_NEIGH_INACTIVE(n)) {
1423 if (IS_ZEBRA_DEBUG_VXLAN)
1424 zlog_debug(
1425 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1426 ipaddr2str(&n->ip, buf2,
1427 sizeof(buf2)),
1428 prefix_mac2str(&n->emac, buf,
1429 sizeof(buf)),
1430 zvni->vni);
1431
1432 ZEBRA_NEIGH_SET_ACTIVE(n);
1433 zvni_neigh_send_add_to_client(
1434 zvni->vni, &n->ip, &n->emac, n->flags);
1435 } else {
1436 if (IS_ZEBRA_DEBUG_VXLAN)
1437 zlog_debug(
1438 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1439 ipaddr2str(&n->ip, buf2,
1440 sizeof(buf2)),
1441 prefix_mac2str(&n->emac, buf,
1442 sizeof(buf)),
1443 zvni->vni);
1444 }
1445 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1446 /* TODO: assume the neigh has moved too ?? */
1447 }
1448 }
1449 }
1450
1451 /* Process all neigh associated to a mac upon local mac del event */
1452 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
1453 zebra_mac_t *zmac)
1454 {
1455 zebra_neigh_t *n = NULL;
1456 struct listnode *node = NULL;
1457 char buf[ETHER_ADDR_STRLEN];
1458 char buf2[INET6_ADDRSTRLEN];
1459
1460 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1461 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1462 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1463 if (IS_ZEBRA_DEBUG_VXLAN)
1464 zlog_debug(
1465 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1466 ipaddr2str(&n->ip, buf2,
1467 sizeof(buf2)),
1468 prefix_mac2str(&n->emac, buf,
1469 sizeof(buf)),
1470 zvni->vni);
1471
1472 ZEBRA_NEIGH_SET_INACTIVE(n);
1473 zvni_neigh_send_del_to_client(
1474 zvni->vni, &n->ip, &n->emac, 0);
1475 }
1476 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1477 if (IS_ZEBRA_DEBUG_VXLAN)
1478 zlog_err(
1479 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1480 prefix_mac2str(&n->emac, buf,
1481 sizeof(buf)),
1482 zvni->vni,
1483 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1484 }
1485 }
1486 }
1487
1488 /* process all neigh associated to a mac entry upon remote mac add */
1489 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
1490 zebra_mac_t *zmac)
1491 {
1492 zebra_neigh_t *n = NULL;
1493 struct listnode *node = NULL;
1494 char buf[ETHER_ADDR_STRLEN];
1495 char buf2[INET6_ADDRSTRLEN];
1496
1497 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1498 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1499 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1500 if (IS_ZEBRA_DEBUG_VXLAN)
1501 zlog_debug(
1502 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1503 ipaddr2str(&n->ip, buf2,
1504 sizeof(buf2)),
1505 prefix_mac2str(&n->emac, buf,
1506 sizeof(buf)),
1507 zvni->vni);
1508
1509 ZEBRA_NEIGH_SET_INACTIVE(n);
1510 zvni_neigh_send_del_to_client(
1511 zvni->vni, &n->ip, &n->emac, 0);
1512 }
1513 }
1514 }
1515 }
1516
1517 /* process all neigh associated to mac entry upon remote mac del */
1518 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
1519 zebra_mac_t *zmac)
1520 {
1521 zebra_neigh_t *n = NULL;
1522 struct listnode *node = NULL;
1523 char buf[ETHER_ADDR_STRLEN];
1524 char buf2[INET6_ADDRSTRLEN];
1525
1526 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1527 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1528 if (IS_ZEBRA_DEBUG_VXLAN)
1529 zlog_err(
1530 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1531 prefix_mac2str(&n->emac, buf,
1532 sizeof(buf)),
1533 zvni->vni,
1534 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1535 }
1536 }
1537 }
1538
1539 /*
1540 * Inform BGP about local neighbor addition.
1541 */
1542 static int zvni_neigh_send_add_to_client(vni_t vni,
1543 struct ipaddr *ip,
1544 struct ethaddr *macaddr,
1545 u_char neigh_flags)
1546 {
1547 u_char flags = 0;
1548
1549 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
1550 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
1551
1552 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
1553 ZEBRA_MACIP_ADD);
1554 }
1555
1556 /*
1557 * Inform BGP about local neighbor deletion.
1558 */
1559 static int zvni_neigh_send_del_to_client(vni_t vni,
1560 struct ipaddr *ip,
1561 struct ethaddr *macaddr, u_char flags)
1562 {
1563 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
1564 ZEBRA_MACIP_DEL);
1565 }
1566
1567 /*
1568 * Install remote neighbor into the kernel.
1569 */
1570 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
1571 {
1572 struct zebra_if *zif;
1573 struct zebra_l2info_vxlan *vxl;
1574 struct interface *vlan_if;
1575
1576 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1577 return 0;
1578
1579 zif = zvni->vxlan_if->info;
1580 if (!zif)
1581 return -1;
1582 vxl = &zif->l2info.vxl;
1583
1584 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1585 if (!vlan_if)
1586 return -1;
1587
1588 return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
1589 }
1590
1591 /*
1592 * Uninstall remote neighbor from the kernel.
1593 */
1594 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
1595 {
1596 struct zebra_if *zif;
1597 struct zebra_l2info_vxlan *vxl;
1598 struct interface *vlan_if;
1599
1600 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1601 return 0;
1602
1603 if (!zvni->vxlan_if) {
1604 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1605 zvni->vni, zvni);
1606 return -1;
1607 }
1608
1609 zif = zvni->vxlan_if->info;
1610 if (!zif)
1611 return -1;
1612 vxl = &zif->l2info.vxl;
1613 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1614 if (!vlan_if)
1615 return -1;
1616
1617 return kernel_del_neigh(vlan_if, &n->ip);
1618 }
1619
1620 /*
1621 * Install neighbor hash entry - called upon access VLAN change.
1622 */
1623 static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
1624 {
1625 zebra_neigh_t *n;
1626 struct neigh_walk_ctx *wctx = ctxt;
1627
1628 n = (zebra_neigh_t *)backet->data;
1629 if (!n)
1630 return;
1631
1632 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
1633 zvni_neigh_install(wctx->zvni, n);
1634 }
1635
1636 /* Get the VRR interface for SVI if any */
1637 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
1638 {
1639 struct zebra_vrf *zvrf = NULL;
1640 struct interface *tmp_if = NULL;
1641 struct zebra_if *zif = NULL;
1642
1643 zvrf = vrf_info_lookup(ifp->vrf_id);
1644 assert(zvrf);
1645
1646 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
1647 zif = tmp_if->info;
1648 if (!zif)
1649 continue;
1650
1651 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
1652 continue;
1653
1654 if (zif->link == ifp)
1655 return tmp_if;
1656 }
1657
1658 return NULL;
1659 }
1660
1661 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1662 {
1663 struct listnode *cnode = NULL, *cnnode = NULL;
1664 struct connected *c = NULL;
1665 struct ethaddr macaddr;
1666
1667 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1668
1669 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1670 struct ipaddr ip;
1671
1672 memset(&ip, 0, sizeof(struct ipaddr));
1673 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1674 continue;
1675
1676 if (c->address->family == AF_INET) {
1677 ip.ipa_type = IPADDR_V4;
1678 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1679 sizeof(struct in_addr));
1680 } else if (c->address->family == AF_INET6) {
1681 ip.ipa_type = IPADDR_V6;
1682 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1683 sizeof(struct in6_addr));
1684 } else {
1685 continue;
1686 }
1687
1688 zvni_gw_macip_del(ifp, zvni, &ip);
1689 }
1690
1691 return 0;
1692 }
1693
1694 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1695 {
1696 struct listnode *cnode = NULL, *cnnode = NULL;
1697 struct connected *c = NULL;
1698 struct ethaddr macaddr;
1699
1700 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1701
1702 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1703 struct ipaddr ip;
1704
1705 memset(&ip, 0, sizeof(struct ipaddr));
1706 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1707 continue;
1708
1709 if (c->address->family == AF_INET) {
1710 ip.ipa_type = IPADDR_V4;
1711 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1712 sizeof(struct in_addr));
1713 } else if (c->address->family == AF_INET6) {
1714 ip.ipa_type = IPADDR_V6;
1715 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1716 sizeof(struct in6_addr));
1717 } else {
1718 continue;
1719 }
1720
1721 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
1722 }
1723 return 0;
1724 }
1725
1726
1727 static int zvni_advertise_subnet(zebra_vni_t *zvni,
1728 struct interface *ifp,
1729 int advertise)
1730 {
1731 struct listnode *cnode = NULL, *cnnode = NULL;
1732 struct connected *c = NULL;
1733 struct ethaddr macaddr;
1734
1735 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1736
1737 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1738 struct prefix p;
1739
1740 memcpy(&p, c->address, sizeof(struct prefix));
1741
1742 /* skip link local address */
1743 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
1744 continue;
1745
1746 apply_mask(&p);
1747 if (advertise)
1748 ip_prefix_send_to_client(ifp->vrf_id, &p,
1749 ZEBRA_IP_PREFIX_ROUTE_ADD);
1750 else
1751 ip_prefix_send_to_client(ifp->vrf_id, &p,
1752 ZEBRA_IP_PREFIX_ROUTE_DEL);
1753 }
1754 return 0;
1755 }
1756
1757 /*
1758 * zvni_gw_macip_add_to_client
1759 */
1760 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
1761 struct ethaddr *macaddr, struct ipaddr *ip)
1762 {
1763 char buf[ETHER_ADDR_STRLEN];
1764 char buf2[INET6_ADDRSTRLEN];
1765 zebra_neigh_t *n = NULL;
1766 zebra_mac_t *mac = NULL;
1767 struct zebra_if *zif = NULL;
1768 struct zebra_l2info_vxlan *vxl = NULL;
1769
1770 zif = zvni->vxlan_if->info;
1771 if (!zif)
1772 return -1;
1773
1774 vxl = &zif->l2info.vxl;
1775
1776 mac = zvni_mac_lookup(zvni, macaddr);
1777 if (!mac) {
1778 mac = zvni_mac_add(zvni, macaddr);
1779 if (!mac) {
1780 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1781 prefix_mac2str(macaddr, buf, sizeof(buf)),
1782 ifp->name, ifp->ifindex, vxl->access_vlan);
1783 return -1;
1784 }
1785 }
1786
1787 /* Set "local" forwarding info. */
1788 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
1789 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
1790 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
1791 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
1792 mac->fwd_info.local.ifindex = ifp->ifindex;
1793 mac->fwd_info.local.vid = vxl->access_vlan;
1794
1795 n = zvni_neigh_lookup(zvni, ip);
1796 if (!n) {
1797 n = zvni_neigh_add(zvni, ip, macaddr);
1798 if (!n) {
1799 zlog_err(
1800 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1801 ipaddr2str(ip, buf2, sizeof(buf2)),
1802 prefix_mac2str(macaddr, buf, sizeof(buf)),
1803 ifp->name, ifp->ifindex, zvni->vni);
1804 return -1;
1805 }
1806 }
1807
1808 /* Set "local" forwarding info. */
1809 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1810 SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
1811 memcpy(&n->emac, macaddr, ETH_ALEN);
1812 n->ifindex = ifp->ifindex;
1813
1814 /* Only advertise in BGP if the knob is enabled */
1815 if (!advertise_gw_macip_enabled(zvni))
1816 return 0;
1817
1818 if (IS_ZEBRA_DEBUG_VXLAN)
1819 zlog_debug(
1820 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1821 ifp->name, ifp->ifindex, zvni->vni,
1822 prefix_mac2str(macaddr, buf, sizeof(buf)),
1823 ipaddr2str(ip, buf2, sizeof(buf2)));
1824
1825 zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
1826 n->flags);
1827
1828 return 0;
1829 }
1830
1831 /*
1832 * zvni_gw_macip_del_from_client
1833 */
1834 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
1835 struct ipaddr *ip)
1836 {
1837 char buf1[ETHER_ADDR_STRLEN];
1838 char buf2[INET6_ADDRSTRLEN];
1839 zebra_neigh_t *n = NULL;
1840 zebra_mac_t *mac = NULL;
1841
1842 /* If the neigh entry is not present nothing to do*/
1843 n = zvni_neigh_lookup(zvni, ip);
1844 if (!n)
1845 return 0;
1846
1847 /* mac entry should be present */
1848 mac = zvni_mac_lookup(zvni, &n->emac);
1849 if (!mac) {
1850 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1851 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
1852 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
1853 return -1;
1854 }
1855
1856 /* If the entry is not local nothing to do*/
1857 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
1858 return -1;
1859
1860 /* only need to delete the entry from bgp if we sent it before */
1861 if (advertise_gw_macip_enabled(zvni)) {
1862 if (IS_ZEBRA_DEBUG_VXLAN)
1863 zlog_debug("%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1864 ifp->vrf_id, ifp->name,
1865 ifp->ifindex, zvni->vni,
1866 prefix_mac2str(&(n->emac),
1867 NULL,
1868 ETHER_ADDR_STRLEN),
1869 ipaddr2str(ip, buf2, sizeof(buf2)));
1870
1871 /* Remove neighbor from BGP. */
1872 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
1873 ZEBRA_MACIP_TYPE_GW);
1874 }
1875
1876 /* Delete this neighbor entry. */
1877 zvni_neigh_del(zvni, n);
1878
1879 /* see if the mac needs to be deleted as well*/
1880 if (mac)
1881 zvni_deref_ip2mac(zvni, mac, 0);
1882
1883 return 0;
1884 }
1885
1886 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
1887 void *ctxt)
1888 {
1889 zebra_vni_t *zvni = NULL;
1890 struct zebra_if *zif = NULL;
1891 struct zebra_l2info_vxlan zl2_info;
1892 struct interface *vlan_if = NULL;
1893 struct interface *vrr_if = NULL;
1894 struct interface *ifp;
1895
1896 /* Add primary SVI MAC*/
1897 zvni = (zebra_vni_t *)backet->data;
1898 if (!zvni)
1899 return;
1900
1901 ifp = zvni->vxlan_if;
1902 if (!ifp)
1903 return;
1904 zif = ifp->info;
1905
1906 /* If down or not mapped to a bridge, we're done. */
1907 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1908 return;
1909
1910 zl2_info = zif->l2info.vxl;
1911
1912 vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
1913 if (!vlan_if)
1914 return;
1915
1916 /* Del primary MAC-IP */
1917 zvni_del_macip_for_intf(vlan_if, zvni);
1918
1919 /* Del VRR MAC-IP - if any*/
1920 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1921 if (vrr_if)
1922 zvni_del_macip_for_intf(vrr_if, zvni);
1923
1924 return;
1925 }
1926
1927 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
1928 void *ctxt)
1929 {
1930 zebra_vni_t *zvni = NULL;
1931 struct zebra_if *zif = NULL;
1932 struct zebra_l2info_vxlan zl2_info;
1933 struct interface *vlan_if = NULL;
1934 struct interface *vrr_if = NULL;
1935 struct interface *ifp = NULL;
1936
1937 zvni = (zebra_vni_t *)backet->data;
1938 if (!zvni)
1939 return;
1940
1941 ifp = zvni->vxlan_if;
1942 if (!ifp)
1943 return;
1944 zif = ifp->info;
1945
1946 /* If down or not mapped to a bridge, we're done. */
1947 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1948 return;
1949 zl2_info = zif->l2info.vxl;
1950
1951 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
1952 zif->brslave_info.br_if);
1953 if (!vlan_if)
1954 return;
1955
1956 /* Add primary SVI MAC-IP */
1957 zvni_add_macip_for_intf(vlan_if, zvni);
1958
1959 /* Add VRR MAC-IP - if any*/
1960 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1961 if (vrr_if)
1962 zvni_add_macip_for_intf(vrr_if, zvni);
1963
1964 return;
1965 }
1966
1967 /*
1968 * Make hash key for MAC.
1969 */
1970 static unsigned int mac_hash_keymake(void *p)
1971 {
1972 zebra_mac_t *pmac = p;
1973 const void *pnt = (void *)pmac->macaddr.octet;
1974
1975 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
1976 }
1977
1978 /*
1979 * Compare two MAC addresses.
1980 */
1981 static int mac_cmp(const void *p1, const void *p2)
1982 {
1983 const zebra_mac_t *pmac1 = p1;
1984 const zebra_mac_t *pmac2 = p2;
1985
1986 if (pmac1 == NULL && pmac2 == NULL)
1987 return 1;
1988
1989 if (pmac1 == NULL || pmac2 == NULL)
1990 return 0;
1991
1992 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
1993 ETH_ALEN)
1994 == 0);
1995 }
1996
1997 /*
1998 * Callback to allocate MAC hash entry.
1999 */
2000 static void *zvni_mac_alloc(void *p)
2001 {
2002 const zebra_mac_t *tmp_mac = p;
2003 zebra_mac_t *mac;
2004
2005 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
2006 *mac = *tmp_mac;
2007
2008 return ((void *)mac);
2009 }
2010
2011 /*
2012 * Add MAC entry.
2013 */
2014 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
2015 {
2016 zebra_mac_t tmp_mac;
2017 zebra_mac_t *mac = NULL;
2018
2019 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
2020 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
2021 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
2022 assert(mac);
2023
2024 mac->neigh_list = list_new();
2025 mac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
2026
2027 return mac;
2028 }
2029
2030 /*
2031 * Delete MAC entry.
2032 */
2033 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
2034 {
2035 zebra_mac_t *tmp_mac;
2036
2037 list_delete_and_null(&mac->neigh_list);
2038
2039 /* Free the VNI hash entry and allocated memory. */
2040 tmp_mac = hash_release(zvni->mac_table, mac);
2041 if (tmp_mac)
2042 XFREE(MTYPE_MAC, tmp_mac);
2043
2044 return 0;
2045 }
2046
2047 /*
2048 * Free MAC hash entry (callback)
2049 */
2050 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
2051 {
2052 struct mac_walk_ctx *wctx = arg;
2053 zebra_mac_t *mac = backet->data;
2054
2055 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
2056 || ((wctx->flags & DEL_REMOTE_MAC)
2057 && (mac->flags & ZEBRA_MAC_REMOTE))
2058 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
2059 && (mac->flags & ZEBRA_MAC_REMOTE)
2060 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
2061 &wctx->r_vtep_ip))) {
2062 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
2063 zvni_mac_send_del_to_client(
2064 wctx->zvni->vni, &mac->macaddr,
2065 mac->flags);
2066 }
2067
2068 if (wctx->uninstall)
2069 zvni_mac_uninstall(wctx->zvni, mac, 0);
2070
2071 return zvni_mac_del(wctx->zvni, mac);
2072 }
2073
2074 return 0;
2075 }
2076
2077 /*
2078 * Delete all MAC entries from specific VTEP for a particular VNI.
2079 */
2080 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
2081 struct in_addr *r_vtep_ip)
2082 {
2083 struct mac_walk_ctx wctx;
2084
2085 if (!zvni->mac_table)
2086 return;
2087
2088 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2089 wctx.zvni = zvni;
2090 wctx.uninstall = uninstall;
2091 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
2092 wctx.r_vtep_ip = *r_vtep_ip;
2093
2094 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
2095 void *))zvni_mac_del_hash_entry,
2096 &wctx);
2097 }
2098
2099 /*
2100 * Delete all MAC entries for this VNI.
2101 */
2102 static void zvni_mac_del_all(zebra_vni_t *zvni,
2103 int uninstall, int upd_client, u_int32_t flags)
2104 {
2105 struct mac_walk_ctx wctx;
2106
2107 if (!zvni->mac_table)
2108 return;
2109
2110 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2111 wctx.zvni = zvni;
2112 wctx.uninstall = uninstall;
2113 wctx.upd_client = upd_client;
2114 wctx.flags = flags;
2115
2116 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
2117 void *))zvni_mac_del_hash_entry,
2118 &wctx);
2119 }
2120
2121 /*
2122 * Look up MAC hash entry.
2123 */
2124 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
2125 {
2126 zebra_mac_t tmp;
2127 zebra_mac_t *pmac;
2128
2129 memset(&tmp, 0, sizeof(tmp));
2130 memcpy(&tmp.macaddr, mac, ETH_ALEN);
2131 pmac = hash_lookup(zvni->mac_table, &tmp);
2132
2133 return pmac;
2134 }
2135
2136 /*
2137 * Inform BGP about local MAC addition.
2138 */
2139 static int zvni_mac_send_add_to_client(vni_t vni,
2140 struct ethaddr *macaddr,
2141 u_char mac_flags)
2142 {
2143 u_char flags = 0;
2144
2145 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
2146 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
2147 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
2148 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
2149
2150 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
2151 ZEBRA_MACIP_ADD);
2152 }
2153
2154 /*
2155 * Inform BGP about local MAC deletion.
2156 */
2157 static int zvni_mac_send_del_to_client(vni_t vni,
2158 struct ethaddr *macaddr,
2159 u_char mac_flags)
2160 {
2161 u_char flags = 0;
2162
2163 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
2164 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
2165 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
2166 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
2167
2168 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
2169 ZEBRA_MACIP_DEL);
2170 }
2171
2172 /*
2173 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2174 * notifications, to see if they are of interest.
2175 */
2176 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
2177 struct interface *br_if, vlanid_t vid)
2178 {
2179 struct zebra_ns *zns;
2180 struct route_node *rn;
2181 struct interface *tmp_if = NULL;
2182 struct zebra_if *zif;
2183 struct zebra_l2info_bridge *br;
2184 struct zebra_l2info_vxlan *vxl = NULL;
2185 u_char bridge_vlan_aware;
2186 zebra_vni_t *zvni;
2187 int found = 0;
2188
2189 /* Determine if bridge is VLAN-aware or not */
2190 zif = br_if->info;
2191 assert(zif);
2192 br = &zif->l2info.br;
2193 bridge_vlan_aware = br->vlan_aware;
2194
2195 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2196 /* TODO: Optimize with a hash. */
2197 zns = zebra_ns_lookup(NS_DEFAULT);
2198 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2199 tmp_if = (struct interface *)rn->info;
2200 if (!tmp_if)
2201 continue;
2202 zif = tmp_if->info;
2203 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2204 continue;
2205 if (!if_is_operative(tmp_if))
2206 continue;
2207 vxl = &zif->l2info.vxl;
2208
2209 if (zif->brslave_info.br_if != br_if)
2210 continue;
2211
2212 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
2213 found = 1;
2214 break;
2215 }
2216 }
2217
2218 if (!found)
2219 return NULL;
2220
2221 zvni = zvni_lookup(vxl->vni);
2222 return zvni;
2223 }
2224
2225 /*
2226 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2227 * neighbor notifications, to see if they are of interest.
2228 */
2229 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
2230 struct interface *br_if)
2231 {
2232 struct zebra_ns *zns;
2233 struct route_node *rn;
2234 struct interface *tmp_if = NULL;
2235 struct zebra_if *zif;
2236 struct zebra_l2info_bridge *br;
2237 struct zebra_l2info_vxlan *vxl = NULL;
2238 u_char bridge_vlan_aware;
2239 vlanid_t vid = 0;
2240 zebra_vni_t *zvni;
2241 int found = 0;
2242
2243 if (!br_if)
2244 return NULL;
2245
2246 /* Make sure the linked interface is a bridge. */
2247 if (!IS_ZEBRA_IF_BRIDGE(br_if))
2248 return NULL;
2249
2250 /* Determine if bridge is VLAN-aware or not */
2251 zif = br_if->info;
2252 assert(zif);
2253 br = &zif->l2info.br;
2254 bridge_vlan_aware = br->vlan_aware;
2255 if (bridge_vlan_aware) {
2256 struct zebra_l2info_vlan *vl;
2257
2258 if (!IS_ZEBRA_IF_VLAN(ifp))
2259 return NULL;
2260
2261 zif = ifp->info;
2262 assert(zif);
2263 vl = &zif->l2info.vl;
2264 vid = vl->vid;
2265 }
2266
2267 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2268 /* TODO: Optimize with a hash. */
2269 zns = zebra_ns_lookup(NS_DEFAULT);
2270 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2271 tmp_if = (struct interface *)rn->info;
2272 if (!tmp_if)
2273 continue;
2274 zif = tmp_if->info;
2275 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2276 continue;
2277 if (!if_is_operative(tmp_if))
2278 continue;
2279 vxl = &zif->l2info.vxl;
2280
2281 if (zif->brslave_info.br_if != br_if)
2282 continue;
2283
2284 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
2285 found = 1;
2286 break;
2287 }
2288 }
2289
2290 if (!found)
2291 return NULL;
2292
2293 zvni = zvni_lookup(vxl->vni);
2294 return zvni;
2295 }
2296
2297 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2298 * of two cases:
2299 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2300 * linked to the bridge
2301 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2302 * itself
2303 */
2304 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
2305 {
2306 struct zebra_ns *zns;
2307 struct route_node *rn;
2308 struct interface *tmp_if = NULL;
2309 struct zebra_if *zif;
2310 struct zebra_l2info_bridge *br;
2311 struct zebra_l2info_vlan *vl;
2312 u_char bridge_vlan_aware;
2313 int found = 0;
2314
2315 /* Defensive check, caller expected to invoke only with valid bridge. */
2316 if (!br_if)
2317 return NULL;
2318
2319 /* Determine if bridge is VLAN-aware or not */
2320 zif = br_if->info;
2321 assert(zif);
2322 br = &zif->l2info.br;
2323 bridge_vlan_aware = br->vlan_aware;
2324
2325 /* Check oper status of the SVI. */
2326 if (!bridge_vlan_aware)
2327 return if_is_operative(br_if) ? br_if : NULL;
2328
2329 /* Identify corresponding VLAN interface. */
2330 /* TODO: Optimize with a hash. */
2331 zns = zebra_ns_lookup(NS_DEFAULT);
2332 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2333 tmp_if = (struct interface *)rn->info;
2334 /* Check oper status of the SVI. */
2335 if (!tmp_if || !if_is_operative(tmp_if))
2336 continue;
2337 zif = tmp_if->info;
2338 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
2339 || zif->link != br_if)
2340 continue;
2341 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
2342
2343 if (vl->vid == vid) {
2344 found = 1;
2345 break;
2346 }
2347 }
2348
2349 return found ? tmp_if : NULL;
2350 }
2351
2352 /*
2353 * Install remote MAC into the kernel.
2354 */
2355 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
2356 {
2357 struct zebra_if *zif;
2358 struct zebra_l2info_vxlan *vxl;
2359 u_char sticky;
2360
2361 if (!(mac->flags & ZEBRA_MAC_REMOTE))
2362 return 0;
2363
2364 zif = zvni->vxlan_if->info;
2365 if (!zif)
2366 return -1;
2367 vxl = &zif->l2info.vxl;
2368
2369 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2370
2371 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
2372 mac->fwd_info.r_vtep_ip, sticky);
2373 }
2374
2375 /*
2376 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2377 * moves to remote, we have to uninstall any existing local entry first.
2378 */
2379 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
2380 {
2381 struct zebra_if *zif;
2382 struct zebra_l2info_vxlan *vxl;
2383 struct in_addr vtep_ip = {.s_addr = 0};
2384 struct zebra_ns *zns;
2385 struct interface *ifp;
2386
2387 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
2388 return 0;
2389
2390 if (!zvni->vxlan_if) {
2391 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2392 zvni->vni, zvni);
2393 return -1;
2394 }
2395
2396 zif = zvni->vxlan_if->info;
2397 if (!zif)
2398 return -1;
2399 vxl = &zif->l2info.vxl;
2400
2401 if (local) {
2402 zns = zebra_ns_lookup(NS_DEFAULT);
2403 ifp = if_lookup_by_index_per_ns(zns,
2404 mac->fwd_info.local.ifindex);
2405 if (!ifp) // unexpected
2406 return -1;
2407 } else {
2408 ifp = zvni->vxlan_if;
2409 vtep_ip = mac->fwd_info.r_vtep_ip;
2410 }
2411
2412 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
2413 local);
2414 }
2415
2416 /*
2417 * Install MAC hash entry - called upon access VLAN change.
2418 */
2419 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
2420 {
2421 zebra_mac_t *mac;
2422 struct mac_walk_ctx *wctx = ctxt;
2423
2424 mac = (zebra_mac_t *)backet->data;
2425 if (!mac)
2426 return;
2427
2428 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
2429 zvni_mac_install(wctx->zvni, mac);
2430 }
2431
2432 /*
2433 * Decrement neighbor refcount of MAC; uninstall and free it if
2434 * appropriate.
2435 */
2436 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
2437 int uninstall)
2438 {
2439 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)
2440 || !list_isempty(mac->neigh_list))
2441 return;
2442
2443 if (uninstall)
2444 zvni_mac_uninstall(zvni, mac, 0);
2445
2446 zvni_mac_del(zvni, mac);
2447 }
2448
2449 /*
2450 * Read and populate local MACs and neighbors corresponding to this VNI.
2451 */
2452 static void zvni_read_mac_neigh(zebra_vni_t *zvni,
2453 struct interface *ifp)
2454 {
2455 struct zebra_ns *zns;
2456 struct zebra_if *zif;
2457 struct interface *vlan_if;
2458 struct zebra_l2info_vxlan *vxl;
2459 struct interface *vrr_if;
2460
2461 zif = ifp->info;
2462 vxl = &zif->l2info.vxl;
2463 zns = zebra_ns_lookup(NS_DEFAULT);
2464
2465 if (IS_ZEBRA_DEBUG_VXLAN)
2466 zlog_debug(
2467 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2468 ifp->name, ifp->ifindex, zvni->vni,
2469 zif->brslave_info.bridge_ifindex);
2470
2471 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
2472 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2473 if (vlan_if) {
2474
2475 /* Add SVI MAC-IP */
2476 zvni_add_macip_for_intf(vlan_if, zvni);
2477
2478 /* Add VRR MAC-IP - if any*/
2479 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2480 if (vrr_if)
2481 zvni_add_macip_for_intf(vrr_if, zvni);
2482
2483 neigh_read_for_vlan(zns, vlan_if);
2484 }
2485 }
2486
2487 /*
2488 * Hash function for VNI.
2489 */
2490 static unsigned int vni_hash_keymake(void *p)
2491 {
2492 const zebra_vni_t *zvni = p;
2493
2494 return (jhash_1word(zvni->vni, 0));
2495 }
2496
2497 /*
2498 * Compare 2 VNI hash entries.
2499 */
2500 static int vni_hash_cmp(const void *p1, const void *p2)
2501 {
2502 const zebra_vni_t *zvni1 = p1;
2503 const zebra_vni_t *zvni2 = p2;
2504
2505 return (zvni1->vni == zvni2->vni);
2506 }
2507
2508 /*
2509 * Callback to allocate VNI hash entry.
2510 */
2511 static void *zvni_alloc(void *p)
2512 {
2513 const zebra_vni_t *tmp_vni = p;
2514 zebra_vni_t *zvni;
2515
2516 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
2517 zvni->vni = tmp_vni->vni;
2518 return ((void *)zvni);
2519 }
2520
2521 /*
2522 * Look up VNI hash entry.
2523 */
2524 static zebra_vni_t *zvni_lookup(vni_t vni)
2525 {
2526 struct zebra_vrf *zvrf;
2527 zebra_vni_t tmp_vni;
2528 zebra_vni_t *zvni = NULL;
2529
2530 zvrf = vrf_info_lookup(VRF_DEFAULT);
2531 assert(zvrf);
2532 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
2533 tmp_vni.vni = vni;
2534 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2535
2536 return zvni;
2537 }
2538
2539 /*
2540 * Add VNI hash entry.
2541 */
2542 static zebra_vni_t *zvni_add(vni_t vni)
2543 {
2544 struct zebra_vrf *zvrf;
2545 zebra_vni_t tmp_zvni;
2546 zebra_vni_t *zvni = NULL;
2547
2548 zvrf = vrf_info_lookup(VRF_DEFAULT);
2549 assert(zvrf);
2550 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
2551 tmp_zvni.vni = vni;
2552 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
2553 assert(zvni);
2554
2555 /* Create hash table for MAC */
2556 zvni->mac_table =
2557 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2558
2559 /* Create hash table for neighbors */
2560 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
2561 "Zebra VNI Neighbor Table");
2562
2563 return zvni;
2564 }
2565
2566 /*
2567 * Delete VNI hash entry.
2568 */
2569 static int zvni_del(zebra_vni_t *zvni)
2570 {
2571 struct zebra_vrf *zvrf;
2572 zebra_vni_t *tmp_zvni;
2573
2574 zvrf = vrf_info_lookup(VRF_DEFAULT);
2575 assert(zvrf);
2576
2577 zvni->vxlan_if = NULL;
2578
2579 /* Free the neighbor hash table. */
2580 hash_free(zvni->neigh_table);
2581 zvni->neigh_table = NULL;
2582
2583 /* Free the MAC hash table. */
2584 hash_free(zvni->mac_table);
2585 zvni->mac_table = NULL;
2586
2587 /* Free the VNI hash entry and allocated memory. */
2588 tmp_zvni = hash_release(zvrf->vni_table, zvni);
2589 if (tmp_zvni)
2590 XFREE(MTYPE_ZVNI, tmp_zvni);
2591
2592 return 0;
2593 }
2594
2595 /*
2596 * Inform BGP about local VNI addition.
2597 */
2598 static int zvni_send_add_to_client(zebra_vni_t *zvni)
2599 {
2600 struct zserv *client;
2601 struct stream *s;
2602
2603 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2604 /* BGP may not be running. */
2605 if (!client)
2606 return 0;
2607
2608 s = client->obuf;
2609 stream_reset(s);
2610
2611 zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
2612 stream_putl(s, zvni->vni);
2613 stream_put_in_addr(s, &zvni->local_vtep_ip);
2614 stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
2615
2616 /* Write packet size. */
2617 stream_putw_at(s, 0, stream_get_endp(s));
2618
2619 if (IS_ZEBRA_DEBUG_VXLAN)
2620 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2621 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
2622 vrf_id_to_name(zvni->vrf_id),
2623 zebra_route_string(client->proto));
2624
2625 client->vniadd_cnt++;
2626 return zebra_server_send_message(client);
2627 }
2628
2629 /*
2630 * Inform BGP about local VNI deletion.
2631 */
2632 static int zvni_send_del_to_client(vni_t vni)
2633 {
2634 struct zserv *client;
2635 struct stream *s;
2636
2637 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2638 /* BGP may not be running. */
2639 if (!client)
2640 return 0;
2641
2642 s = client->obuf;
2643 stream_reset(s);
2644
2645 zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
2646 stream_putl(s, vni);
2647
2648 /* Write packet size. */
2649 stream_putw_at(s, 0, stream_get_endp(s));
2650
2651 if (IS_ZEBRA_DEBUG_VXLAN)
2652 zlog_debug("Send VNI_DEL %u to %s", vni,
2653 zebra_route_string(client->proto));
2654
2655 client->vnidel_cnt++;
2656 return zebra_server_send_message(client);
2657 }
2658
2659 /*
2660 * Build the VNI hash table by going over the VxLAN interfaces. This
2661 * is called when EVPN (advertise-all-vni) is enabled.
2662 */
2663 static void zvni_build_hash_table()
2664 {
2665 struct zebra_ns *zns;
2666 struct route_node *rn;
2667 struct interface *ifp;
2668
2669 /* Walk VxLAN interfaces and create VNI hash. */
2670 zns = zebra_ns_lookup(NS_DEFAULT);
2671 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2672 vni_t vni;
2673 zebra_vni_t *zvni = NULL;
2674 zebra_l3vni_t *zl3vni = NULL;
2675 struct zebra_if *zif;
2676 struct zebra_l2info_vxlan *vxl;
2677
2678 ifp = (struct interface *)rn->info;
2679 if (!ifp)
2680 continue;
2681 zif = ifp->info;
2682 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2683 continue;
2684
2685 vxl = &zif->l2info.vxl;
2686 vni = vxl->vni;
2687
2688 /* L3-VNI and L2-VNI are handled seperately */
2689 zl3vni = zl3vni_lookup(vni);
2690 if (zl3vni) {
2691
2692 if (IS_ZEBRA_DEBUG_VXLAN)
2693 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2694 ifp->name, ifp->ifindex, vni);
2695
2696 /* associate with vxlan_if */
2697 zl3vni->local_vtep_ip = vxl->vtep_ip;
2698 zl3vni->vxlan_if = ifp;
2699
2700 /*
2701 * we need to associate with SVI.
2702 * we can associate with svi-if only after association
2703 * with vxlan-intf is complete
2704 */
2705 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
2706
2707 if (is_l3vni_oper_up(zl3vni))
2708 zebra_vxlan_process_l3vni_oper_up(zl3vni);
2709
2710 } else {
2711 struct interface *vlan_if = NULL;
2712
2713 if (IS_ZEBRA_DEBUG_VXLAN)
2714 zlog_debug(
2715 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2716 ifp->name, ifp->ifindex, vni,
2717 inet_ntoa(vxl->vtep_ip));
2718
2719 /* VNI hash entry is not expected to exist. */
2720 zvni = zvni_lookup(vni);
2721 if (zvni) {
2722 zlog_err(
2723 "VNI hash already present for IF %s(%u) L2-VNI %u",
2724 ifp->name, ifp->ifindex, vni);
2725 continue;
2726 }
2727
2728 zvni = zvni_add(vni);
2729 if (!zvni) {
2730 zlog_err(
2731 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2732 ifp->name, ifp->ifindex, vni);
2733 return;
2734 }
2735
2736 zvni->local_vtep_ip = vxl->vtep_ip;
2737 zvni->vxlan_if = ifp;
2738 vlan_if = zvni_map_to_svi(vxl->access_vlan,
2739 zif->brslave_info.br_if);
2740 if (vlan_if) {
2741 zvni->vrf_id = vlan_if->vrf_id;
2742 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
2743 if (zl3vni)
2744 listnode_add_sort(zl3vni->l2vnis, zvni);
2745 }
2746
2747
2748 /* Inform BGP if intf is up and mapped to bridge. */
2749 if (if_is_operative(ifp) && zif->brslave_info.br_if)
2750 zvni_send_add_to_client(zvni);
2751 }
2752 }
2753 }
2754
2755 /*
2756 * See if remote VTEP matches with prefix.
2757 */
2758 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2759 {
2760 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2761 }
2762
2763 /*
2764 * Locate remote VTEP in VNI hash table.
2765 */
2766 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2767 {
2768 zebra_vtep_t *zvtep;
2769
2770 if (!zvni)
2771 return NULL;
2772
2773 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
2774 if (zvni_vtep_match(vtep_ip, zvtep))
2775 break;
2776 }
2777
2778 return zvtep;
2779 }
2780
2781 /*
2782 * Add remote VTEP to VNI hash table.
2783 */
2784 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2785 {
2786 zebra_vtep_t *zvtep;
2787
2788 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
2789 if (!zvtep) {
2790 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
2791 return NULL;
2792 }
2793
2794 zvtep->vtep_ip = *vtep_ip;
2795
2796 if (zvni->vteps)
2797 zvni->vteps->prev = zvtep;
2798 zvtep->next = zvni->vteps;
2799 zvni->vteps = zvtep;
2800
2801 return zvtep;
2802 }
2803
2804 /*
2805 * Remove remote VTEP from VNI hash table.
2806 */
2807 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2808 {
2809 if (zvtep->next)
2810 zvtep->next->prev = zvtep->prev;
2811 if (zvtep->prev)
2812 zvtep->prev->next = zvtep->next;
2813 else
2814 zvni->vteps = zvtep->next;
2815
2816 zvtep->prev = zvtep->next = NULL;
2817 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2818
2819 return 0;
2820 }
2821
2822 /*
2823 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2824 * uninstall from kernel if asked to.
2825 */
2826 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2827 {
2828 zebra_vtep_t *zvtep, *zvtep_next;
2829
2830 if (!zvni)
2831 return -1;
2832
2833 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
2834 zvtep_next = zvtep->next;
2835 if (uninstall)
2836 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
2837 zvni_vtep_del(zvni, zvtep);
2838 }
2839
2840 return 0;
2841 }
2842
2843 /*
2844 * Install remote VTEP into the kernel.
2845 */
2846 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2847 {
2848 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2849 }
2850
2851 /*
2852 * Uninstall remote VTEP from the kernel.
2853 */
2854 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2855 {
2856 if (!zvni->vxlan_if) {
2857 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2858 zvni->vni, zvni);
2859 return -1;
2860 }
2861
2862 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2863 }
2864
2865 /*
2866 * Cleanup VNI/VTEP and update kernel
2867 */
2868 static void zvni_cleanup_all(struct hash_backet *backet, void *arg)
2869 {
2870 zebra_vni_t *zvni = NULL;
2871 zebra_l3vni_t *zl3vni = NULL;
2872 struct zebra_vrf *zvrf = (struct zebra_vrf *)arg;
2873
2874 zvni = (zebra_vni_t *)backet->data;
2875 if (!zvni)
2876 return;
2877
2878 /* remove from l3-vni list */
2879 if (zvrf->l3vni)
2880 zl3vni = zl3vni_lookup(zvrf->l3vni);
2881 if (zl3vni)
2882 listnode_delete(zl3vni->l2vnis, zvni);
2883
2884 /* Free up all neighbors and MACs, if any. */
2885 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
2886 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
2887
2888 /* Free up all remote VTEPs, if any. */
2889 zvni_vtep_del_all(zvni, 1);
2890
2891 /* Delete the hash entry. */
2892 zvni_del(zvni);
2893 }
2894
2895 /* cleanup L3VNI */
2896 static void zl3vni_cleanup_all(struct hash_backet *backet,
2897 void *args)
2898 {
2899 zebra_l3vni_t *zl3vni = NULL;
2900
2901 zl3vni = (zebra_l3vni_t *)backet->data;
2902 if (!zl3vni)
2903 return;
2904
2905 zebra_vxlan_process_l3vni_oper_down(zl3vni);
2906 }
2907
2908 static int is_host_present_in_host_list(struct list *list,
2909 struct prefix *host)
2910 {
2911 struct listnode *node = NULL;
2912 struct prefix *p = NULL;
2913
2914 for (ALL_LIST_ELEMENTS_RO(list, node, p)) {
2915 if (prefix_same(p, host))
2916 return 1;
2917 }
2918 return 0;
2919 }
2920
2921 static void host_list_add_host(struct list *list,
2922 struct prefix *host)
2923 {
2924 struct prefix *p = NULL;
2925
2926 p = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct prefix));
2927 memcpy(p, host, sizeof(struct prefix));
2928
2929 listnode_add_sort(list, p);
2930 }
2931
2932 static void host_list_delete_host(struct list *list,
2933 struct prefix *host)
2934 {
2935 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
2936 struct prefix *p = NULL;
2937
2938 for (ALL_LIST_ELEMENTS(list, node, nnode, p)) {
2939 if (prefix_same(p, host)) {
2940 XFREE(MTYPE_HOST_PREFIX, p);
2941 node_to_del = node;
2942 }
2943 }
2944
2945 if (node_to_del)
2946 list_delete_node(list, node_to_del);
2947 }
2948
2949 /*
2950 * Look up MAC hash entry.
2951 */
2952 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
2953 struct ethaddr *rmac)
2954 {
2955 zebra_mac_t tmp;
2956 zebra_mac_t *pmac;
2957
2958 memset(&tmp, 0, sizeof(tmp));
2959 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
2960 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
2961
2962 return pmac;
2963 }
2964
2965 /*
2966 * Callback to allocate RMAC hash entry.
2967 */
2968 static void *zl3vni_rmac_alloc(void *p)
2969 {
2970 const zebra_mac_t *tmp_rmac = p;
2971 zebra_mac_t *zrmac;
2972
2973 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
2974 *zrmac = *tmp_rmac;
2975
2976 return ((void *)zrmac);
2977 }
2978
2979 /*
2980 * Add RMAC entry to l3-vni
2981 */
2982 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
2983 struct ethaddr *rmac)
2984 {
2985 zebra_mac_t tmp_rmac;
2986 zebra_mac_t *zrmac = NULL;
2987
2988 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
2989 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
2990 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
2991 assert(zrmac);
2992
2993 zrmac->host_list = list_new();
2994 zrmac->host_list->cmp = (int (*)(void *, void *))prefix_cmp;
2995
2996 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
2997 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
2998
2999 return zrmac;
3000 }
3001
3002 /*
3003 * Delete MAC entry.
3004 */
3005 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni,
3006 zebra_mac_t *zrmac)
3007 {
3008 zebra_mac_t *tmp_rmac;
3009
3010 if (zrmac->host_list)
3011 list_delete_and_null(&zrmac->host_list);
3012 zrmac->host_list = NULL;
3013
3014 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
3015 if (tmp_rmac)
3016 XFREE(MTYPE_MAC, tmp_rmac);
3017
3018 return 0;
3019 }
3020
3021 /*
3022 * Install remote RMAC into the kernel.
3023 */
3024 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni,
3025 zebra_mac_t *zrmac)
3026 {
3027 struct zebra_if *zif = NULL;
3028 struct zebra_l2info_vxlan *vxl = NULL;
3029
3030 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
3031 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
3032 return 0;
3033
3034 zif = zl3vni->vxlan_if->info;
3035 if (!zif)
3036 return -1;
3037
3038 vxl = &zif->l2info.vxl;
3039
3040 return kernel_add_mac(zl3vni->vxlan_if, vxl->access_vlan,
3041 &zrmac->macaddr,
3042 zrmac->fwd_info.r_vtep_ip, 0);
3043 }
3044
3045 /*
3046 * Uninstall remote RMAC from the kernel.
3047 */
3048 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
3049 zebra_mac_t *zrmac)
3050 {
3051 char buf[ETHER_ADDR_STRLEN];
3052 struct zebra_if *zif = NULL;
3053 struct zebra_l2info_vxlan *vxl = NULL;
3054
3055 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
3056 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
3057 return 0;
3058
3059 if (!zl3vni->vxlan_if) {
3060 zlog_err(
3061 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3062 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
3063 zl3vni->vni, zl3vni);
3064 return -1;
3065 }
3066
3067 zif = zl3vni->vxlan_if->info;
3068 if (!zif)
3069 return -1;
3070
3071 vxl = &zif->l2info.vxl;
3072
3073 return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
3074 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
3075 }
3076
3077 /* handle rmac add */
3078 static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
3079 struct ethaddr *rmac,
3080 struct ipaddr *vtep_ip,
3081 struct prefix *host_prefix)
3082 {
3083 char buf[ETHER_ADDR_STRLEN];
3084 char buf1[INET6_ADDRSTRLEN];
3085 zebra_mac_t *zrmac = NULL;
3086
3087 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3088 if (!zrmac) {
3089
3090 zrmac = zl3vni_rmac_add(zl3vni, rmac);
3091 if (!zrmac) {
3092 zlog_warn(
3093 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3094 prefix_mac2str(rmac, buf,
3095 sizeof(buf)),
3096 zl3vni->vni, ipaddr2str(vtep_ip, buf1,
3097 sizeof(buf1)));
3098 return -1;
3099 }
3100 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
3101 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
3102
3103 /* install rmac in kernel */
3104 zl3vni_rmac_install(zl3vni, zrmac);
3105 }
3106
3107 if (!is_host_present_in_host_list(zrmac->host_list, host_prefix))
3108 host_list_add_host(zrmac->host_list, host_prefix);
3109 return 0;
3110 }
3111
3112
3113 /* handle rmac delete */
3114 static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni,
3115 struct ethaddr *rmac,
3116 struct prefix *host_prefix)
3117 {
3118 zebra_mac_t *zrmac = NULL;
3119
3120 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3121 if (!zrmac)
3122 return -1;
3123
3124 host_list_delete_host(zrmac->host_list, host_prefix);
3125 if (list_isempty(zrmac->host_list)) {
3126
3127 /* uninstall from kernel */
3128 zl3vni_rmac_uninstall(zl3vni, zrmac);
3129
3130 /* del the rmac entry */
3131 zl3vni_rmac_del(zl3vni, zrmac);
3132 }
3133 return 0;
3134 }
3135
3136 /*
3137 * Look up nh hash entry on a l3-vni.
3138 */
3139 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
3140 struct ipaddr *ip)
3141 {
3142 zebra_neigh_t tmp;
3143 zebra_neigh_t *n;
3144
3145 memset(&tmp, 0, sizeof(tmp));
3146 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
3147 n = hash_lookup(zl3vni->nh_table, &tmp);
3148
3149 return n;
3150 }
3151
3152
3153 /*
3154 * Callback to allocate NH hash entry on L3-VNI.
3155 */
3156 static void *zl3vni_nh_alloc(void *p)
3157 {
3158 const zebra_neigh_t *tmp_n = p;
3159 zebra_neigh_t *n;
3160
3161 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
3162 *n = *tmp_n;
3163
3164 return ((void *)n);
3165 }
3166
3167 /*
3168 * Add neighbor entry.
3169 */
3170 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
3171 struct ipaddr *ip,
3172 struct ethaddr *mac)
3173 {
3174 zebra_neigh_t tmp_n;
3175 zebra_neigh_t *n = NULL;
3176
3177 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
3178 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
3179 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
3180 assert(n);
3181
3182 n->host_list = list_new();
3183 n->host_list->cmp = (int (*)(void *, void *))prefix_cmp;
3184
3185 memcpy(&n->emac, mac, ETH_ALEN);
3186 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3187 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
3188
3189 return n;
3190 }
3191
3192 /*
3193 * Delete neighbor entry.
3194 */
3195 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni,
3196 zebra_neigh_t *n)
3197 {
3198 zebra_neigh_t *tmp_n;
3199
3200 if (n->host_list)
3201 list_delete_and_null(&n->host_list);
3202 n->host_list = NULL;
3203
3204 tmp_n = hash_release(zl3vni->nh_table, n);
3205 if (tmp_n)
3206 XFREE(MTYPE_NEIGH, tmp_n);
3207
3208 return 0;
3209 }
3210
3211 /*
3212 * Install remote nh as neigh into the kernel.
3213 */
3214 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni,
3215 zebra_neigh_t *n)
3216 {
3217 if (!is_l3vni_oper_up(zl3vni))
3218 return -1;
3219
3220 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
3221 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
3222 return 0;
3223
3224 return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
3225 }
3226
3227 /*
3228 * Uninstall remote nh from the kernel.
3229 */
3230 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni,
3231 zebra_neigh_t *n)
3232 {
3233 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
3234 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
3235 return 0;
3236
3237 if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
3238 return 0;
3239
3240 return kernel_del_neigh(zl3vni->svi_if, &n->ip);
3241 }
3242
3243 /* add remote vtep as a neigh entry */
3244 static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
3245 struct ipaddr *vtep_ip,
3246 struct ethaddr *rmac,
3247 struct prefix *host_prefix)
3248 {
3249 char buf[ETHER_ADDR_STRLEN];
3250 char buf1[INET6_ADDRSTRLEN];
3251 zebra_neigh_t *nh = NULL;
3252
3253 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
3254 if (!nh) {
3255 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
3256 if (!nh) {
3257
3258 zlog_warn(
3259 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3260 ipaddr2str(vtep_ip, buf1,
3261 sizeof(buf1)),
3262 prefix_mac2str(rmac, buf,
3263 sizeof(buf)),
3264 zl3vni->vni);
3265 return -1;
3266 }
3267
3268 /* install the nh neigh in kernel */
3269 zl3vni_nh_install(zl3vni, nh);
3270 }
3271
3272 if (!is_host_present_in_host_list(nh->host_list, host_prefix))
3273 host_list_add_host(nh->host_list, host_prefix);
3274
3275 return 0;
3276 }
3277
3278 /* handle nh neigh delete */
3279 static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni,
3280 struct ipaddr *vtep_ip,
3281 struct prefix *host_prefix)
3282 {
3283 zebra_neigh_t *nh = NULL;
3284
3285 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
3286 if (!nh)
3287 return -1;
3288
3289 host_list_delete_host(nh->host_list, host_prefix);
3290 if (list_isempty(nh->host_list)) {
3291
3292 /* uninstall from kernel */
3293 zl3vni_nh_uninstall(zl3vni, nh);
3294
3295 /* delete the nh entry */
3296 zl3vni_nh_del(zl3vni, nh);
3297 }
3298
3299 return 0;
3300 }
3301
3302 /* handle neigh update from kernel - the only thing of interest is to
3303 * readd stale entries.
3304 */
3305 static int zl3vni_local_nh_add_update(zebra_l3vni_t *zl3vni,
3306 struct ipaddr *ip, u_int16_t state)
3307 {
3308 #ifdef GNU_LINUX
3309 zebra_neigh_t *n = NULL;
3310
3311 n = zl3vni_nh_lookup(zl3vni, ip);
3312 if (!n)
3313 return 0;
3314
3315 /* all next hop neigh are remote and installed by frr.
3316 * If the kernel has aged this entry, re-install.
3317 */
3318 if (state & NUD_STALE)
3319 zl3vni_nh_install(zl3vni, n);
3320 #endif
3321 return 0;
3322 }
3323
3324 /* handle neigh delete from kernel */
3325 static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni,
3326 struct ipaddr *ip)
3327 {
3328 zebra_neigh_t *n = NULL;
3329
3330 n = zl3vni_nh_lookup(zl3vni, ip);
3331 if (!n)
3332 return 0;
3333
3334 /* all next hop neigh are remote and installed by frr.
3335 * If we get an age out notification for these neigh entries, we have to
3336 * install it back
3337 */
3338 zl3vni_nh_install(zl3vni, n);
3339
3340 return 0;
3341 }
3342
3343 /*
3344 * Hash function for L3 VNI.
3345 */
3346 static unsigned int l3vni_hash_keymake(void *p)
3347 {
3348 const zebra_l3vni_t *zl3vni = p;
3349
3350 return jhash_1word(zl3vni->vni, 0);
3351 }
3352
3353 /*
3354 * Compare 2 L3 VNI hash entries.
3355 */
3356 static int l3vni_hash_cmp(const void *p1, const void *p2)
3357 {
3358 const zebra_l3vni_t *zl3vni1 = p1;
3359 const zebra_l3vni_t *zl3vni2 = p2;
3360
3361 return (zl3vni1->vni == zl3vni2->vni);
3362 }
3363
3364 /*
3365 * Callback to allocate L3 VNI hash entry.
3366 */
3367 static void *zl3vni_alloc(void *p)
3368 {
3369 zebra_l3vni_t *zl3vni = NULL;
3370 const zebra_l3vni_t *tmp_l3vni = p;
3371
3372 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(zebra_l3vni_t));
3373 zl3vni->vni = tmp_l3vni->vni;
3374 return ((void *)zl3vni);
3375 }
3376
3377 /*
3378 * Look up L3 VNI hash entry.
3379 */
3380 static zebra_l3vni_t *zl3vni_lookup(vni_t vni)
3381 {
3382 struct zebra_ns *zns;
3383 zebra_l3vni_t tmp_l3vni;
3384 zebra_l3vni_t *zl3vni = NULL;
3385
3386 zns = zebra_ns_lookup(NS_DEFAULT);
3387 assert(zns);
3388 memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t));
3389 tmp_l3vni.vni = vni;
3390 zl3vni = hash_lookup(zns->l3vni_table, &tmp_l3vni);
3391
3392 return zl3vni;
3393 }
3394
3395 /*
3396 * Add L3 VNI hash entry.
3397 */
3398 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
3399 {
3400 zebra_l3vni_t tmp_zl3vni;
3401 struct zebra_ns *zns = NULL;
3402 zebra_l3vni_t *zl3vni = NULL;
3403
3404 zns = zebra_ns_lookup(NS_DEFAULT);
3405 assert(zns);
3406
3407 memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t));
3408 tmp_zl3vni.vni = vni;
3409
3410 zl3vni = hash_get(zns->l3vni_table, &tmp_zl3vni, zl3vni_alloc);
3411 assert(zl3vni);
3412
3413 zl3vni->vrf_id = vrf_id;
3414 zl3vni->svi_if = NULL;
3415 zl3vni->vxlan_if = NULL;
3416 zl3vni->l2vnis = list_new();
3417 zl3vni->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
3418
3419 /* Create hash table for remote RMAC */
3420 zl3vni->rmac_table =
3421 hash_create(mac_hash_keymake, mac_cmp,
3422 "Zebra L3-VNI RMAC-Table");
3423
3424 /* Create hash table for neighbors */
3425 zl3vni->nh_table = hash_create(neigh_hash_keymake, neigh_cmp,
3426 "Zebra L3-VNI next-hop table");
3427
3428 return zl3vni;
3429 }
3430
3431 /*
3432 * Delete L3 VNI hash entry.
3433 */
3434 static int zl3vni_del(zebra_l3vni_t *zl3vni)
3435 {
3436 struct zebra_ns *zns;
3437 zebra_l3vni_t *tmp_zl3vni;
3438
3439 zns = zebra_ns_lookup(NS_DEFAULT);
3440 assert(zns);
3441
3442 /* free the list of l2vnis */
3443 list_delete_and_null(&zl3vni->l2vnis);
3444 zl3vni->l2vnis = NULL;
3445
3446 /* Free the rmac table */
3447 hash_free(zl3vni->rmac_table);
3448 zl3vni->rmac_table = NULL;
3449
3450 /* Free the nh table */
3451 hash_free(zl3vni->nh_table);
3452 zl3vni->nh_table = NULL;
3453
3454 /* Free the VNI hash entry and allocated memory. */
3455 tmp_zl3vni = hash_release(zns->l3vni_table, zl3vni);
3456 if (tmp_zl3vni)
3457 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
3458
3459 return 0;
3460 }
3461
3462 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
3463 {
3464 struct zebra_ns *zns = NULL;
3465 struct route_node *rn = NULL;
3466 struct interface *ifp = NULL;
3467
3468 /* loop through all vxlan-interface */
3469 zns = zebra_ns_lookup(NS_DEFAULT);
3470 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3471
3472 struct zebra_if *zif = NULL;
3473 struct zebra_l2info_vxlan *vxl = NULL;
3474
3475 ifp = (struct interface *)rn->info;
3476 if (!ifp)
3477 continue;
3478
3479 zif = ifp->info;
3480 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3481 continue;
3482
3483 vxl = &zif->l2info.vxl;
3484 if (vxl->vni == zl3vni->vni) {
3485 zl3vni->local_vtep_ip = vxl->vtep_ip;
3486 return ifp;
3487 }
3488 }
3489
3490 return NULL;
3491 }
3492
3493 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
3494 {
3495 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
3496 struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
3497
3498 if (!zl3vni)
3499 return NULL;
3500
3501 if (!zl3vni->vxlan_if)
3502 return NULL;
3503
3504 zif = zl3vni->vxlan_if->info;
3505 if (!zif)
3506 return NULL;
3507
3508 vxl = &zif->l2info.vxl;
3509
3510 return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
3511 }
3512
3513 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id)
3514 {
3515 struct zebra_vrf *zvrf = NULL;
3516
3517 zvrf = zebra_vrf_lookup_by_id(vrf_id);
3518 if (!zvrf)
3519 return NULL;
3520
3521 return zl3vni_lookup(zvrf->l3vni);
3522 }
3523
3524 /*
3525 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3526 * neighbor notifications, to see if they are of interest.
3527 */
3528 static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp,
3529 struct interface *br_if)
3530 {
3531 int found = 0;
3532 vlanid_t vid = 0;
3533 u_char bridge_vlan_aware = 0;
3534 zebra_l3vni_t *zl3vni = NULL;
3535 struct zebra_ns *zns = NULL;
3536 struct route_node *rn = NULL;
3537 struct zebra_if *zif = NULL;
3538 struct interface *tmp_if = NULL;
3539 struct zebra_l2info_bridge *br = NULL;
3540 struct zebra_l2info_vxlan *vxl = NULL;
3541
3542 if (!br_if)
3543 return NULL;
3544
3545 /* Make sure the linked interface is a bridge. */
3546 if (!IS_ZEBRA_IF_BRIDGE(br_if))
3547 return NULL;
3548
3549 /* Determine if bridge is VLAN-aware or not */
3550 zif = br_if->info;
3551 assert(zif);
3552 br = &zif->l2info.br;
3553 bridge_vlan_aware = br->vlan_aware;
3554 if (bridge_vlan_aware) {
3555 struct zebra_l2info_vlan *vl;
3556
3557 if (!IS_ZEBRA_IF_VLAN(ifp))
3558 return NULL;
3559
3560 zif = ifp->info;
3561 assert(zif);
3562 vl = &zif->l2info.vl;
3563 vid = vl->vid;
3564 }
3565
3566 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3567 /* TODO: Optimize with a hash. */
3568 zns = zebra_ns_lookup(NS_DEFAULT);
3569 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3570 tmp_if = (struct interface *)rn->info;
3571 if (!tmp_if)
3572 continue;
3573 zif = tmp_if->info;
3574 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3575 continue;
3576 if (!if_is_operative(tmp_if))
3577 continue;
3578 vxl = &zif->l2info.vxl;
3579
3580 if (zif->brslave_info.br_if != br_if)
3581 continue;
3582
3583 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3584 found = 1;
3585 break;
3586 }
3587 }
3588
3589 if (!found)
3590 return NULL;
3591
3592 zl3vni = zl3vni_lookup(vxl->vni);
3593 return zl3vni;
3594 }
3595
3596 /*
3597 * Inform BGP about l3-vni.
3598 */
3599 static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
3600 {
3601 struct stream *s = NULL;
3602 struct zserv *client = NULL;
3603 struct ethaddr rmac;
3604 char buf[ETHER_ADDR_STRLEN];
3605
3606 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
3607 /* BGP may not be running. */
3608 if (!client)
3609 return 0;
3610
3611 /* get the rmac */
3612 memset(&rmac, 0, sizeof(struct ethaddr));
3613 zl3vni_get_rmac(zl3vni, &rmac);
3614
3615 s = client->obuf;
3616 stream_reset(s);
3617
3618 zclient_create_header(s, ZEBRA_L3VNI_ADD,
3619 zl3vni_vrf_id(zl3vni));
3620 stream_putl(s, zl3vni->vni);
3621 stream_put(s, &rmac, sizeof(struct ethaddr));
3622 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
3623 stream_put(s, &zl3vni->filter, sizeof(int));
3624
3625 /* Write packet size. */
3626 stream_putw_at(s, 0, stream_get_endp(s));
3627
3628 if (IS_ZEBRA_DEBUG_VXLAN)
3629 zlog_debug(
3630 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3631 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
3632 prefix_mac2str(&rmac, buf, sizeof(buf)),
3633 inet_ntoa(zl3vni->local_vtep_ip),
3634 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ?
3635 "prefix-routes-only" : "none",
3636 zebra_route_string(client->proto));
3637
3638 client->l3vniadd_cnt++;
3639 return zebra_server_send_message(client);
3640 }
3641
3642 /*
3643 * Inform BGP about local l3-VNI deletion.
3644 */
3645 static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
3646 {
3647 struct stream *s = NULL;
3648 struct zserv *client = NULL;
3649
3650 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
3651 /* BGP may not be running. */
3652 if (!client)
3653 return 0;
3654
3655 s = client->obuf;
3656 stream_reset(s);
3657
3658 zclient_create_header(s, ZEBRA_L3VNI_DEL,
3659 zl3vni_vrf_id(zl3vni));
3660 stream_putl(s, zl3vni->vni);
3661
3662 /* Write packet size. */
3663 stream_putw_at(s, 0, stream_get_endp(s));
3664
3665 if (IS_ZEBRA_DEBUG_VXLAN)
3666 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3667 zl3vni->vni,
3668 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
3669 zebra_route_string(client->proto));
3670
3671 client->l3vnidel_cnt++;
3672 return zebra_server_send_message(client);
3673 }
3674
3675 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
3676 {
3677 if (!zl3vni)
3678 return;
3679
3680 /* send l3vni add to BGP */
3681 zl3vni_send_add_to_client(zl3vni);
3682 }
3683
3684 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
3685 {
3686 if (!zl3vni)
3687 return;
3688
3689 /* send l3-vni del to BGP*/
3690 zl3vni_send_del_to_client(zl3vni);
3691 }
3692
3693 static void zvni_add_to_l3vni_list(struct hash_backet *backet,
3694 void *ctxt)
3695 {
3696 zebra_vni_t *zvni = (zebra_vni_t *) backet->data;
3697 zebra_l3vni_t *zl3vni = (zebra_l3vni_t *) ctxt;
3698
3699 if (zvni->vrf_id == zl3vni_vrf_id(zl3vni))
3700 listnode_add_sort(zl3vni->l2vnis, zvni);
3701 }
3702
3703 /*
3704 * handle transition of vni from l2 to l3 and vice versa
3705 */
3706 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf,
3707 vni_t vni, int add)
3708 {
3709 zebra_vni_t *zvni = NULL;
3710
3711 /* There is a possibility that VNI notification was already received
3712 * from kernel and we programmed it as L2-VNI
3713 * In such a case we need to delete this L2-VNI first, so
3714 * that it can be reprogrammed as L3-VNI in the system. It is also
3715 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3716 * interface is still present in kernel. In this case to keep it
3717 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3718 */
3719 if (add) {
3720 /* Locate hash entry */
3721 zvni = zvni_lookup(vni);
3722 if (!zvni)
3723 return 0;
3724
3725 if (IS_ZEBRA_DEBUG_VXLAN)
3726 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3727 vni);
3728
3729 /* Delete VNI from BGP. */
3730 zvni_send_del_to_client(zvni->vni);
3731
3732 /* Free up all neighbors and MAC, if any. */
3733 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
3734 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
3735
3736 /* Free up all remote VTEPs, if any. */
3737 zvni_vtep_del_all(zvni, 0);
3738
3739 /* Delete the hash entry. */
3740 if (zvni_del(zvni)) {
3741 zlog_err("Failed to del VNI hash %p, VNI %u",
3742 zvni, zvni->vni);
3743 return -1;
3744 }
3745 } else {
3746 /* TODO_MITESH: This needs to be thought through. We don't have
3747 * enough information at this point to reprogram the vni as
3748 * l2-vni. One way is to store the required info in l3-vni and
3749 * used it solely for this purpose
3750 */
3751 }
3752
3753 return 0;
3754 }
3755
3756 /* delete and uninstall rmac hash entry */
3757 static void zl3vni_del_rmac_hash_entry(struct hash_backet *backet,
3758 void *ctx)
3759 {
3760 zebra_mac_t *zrmac = NULL;
3761 zebra_l3vni_t *zl3vni = NULL;
3762
3763 zrmac = (zebra_mac_t *)backet->data;
3764 zl3vni = (zebra_l3vni_t *)ctx;
3765 zl3vni_rmac_uninstall(zl3vni, zrmac);
3766 zl3vni_rmac_del(zl3vni, zrmac);
3767 }
3768
3769 /* delete and uninstall nh hash entry */
3770 static void zl3vni_del_nh_hash_entry(struct hash_backet *backet,
3771 void *ctx)
3772 {
3773 zebra_neigh_t *n = NULL;
3774 zebra_l3vni_t *zl3vni = NULL;
3775
3776 n = (zebra_neigh_t *)backet->data;
3777 zl3vni = (zebra_l3vni_t *)ctx;
3778 zl3vni_nh_uninstall(zl3vni, n);
3779 zl3vni_nh_del(zl3vni, n);
3780 }
3781
3782 static int ip_prefix_send_to_client(vrf_id_t vrf_id,
3783 struct prefix *p,
3784 uint16_t cmd)
3785 {
3786 struct zserv *client = NULL;
3787 struct stream *s = NULL;
3788 char buf[PREFIX_STRLEN];
3789
3790 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
3791 /* BGP may not be running. */
3792 if (!client)
3793 return 0;
3794
3795 s = client->obuf;
3796 stream_reset(s);
3797
3798 zclient_create_header(s, cmd, vrf_id);
3799 stream_put(s, p, sizeof(struct prefix));
3800
3801 /* Write packet size. */
3802 stream_putw_at(s, 0, stream_get_endp(s));
3803
3804 if (IS_ZEBRA_DEBUG_VXLAN)
3805 zlog_debug(
3806 "Send ip prefix %s %s on vrf %s",
3807 prefix2str(p, buf, sizeof(buf)),
3808 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
3809 vrf_id_to_name(vrf_id));
3810
3811 if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
3812 client->prefixadd_cnt++;
3813 else
3814 client->prefixdel_cnt++;
3815
3816 return zebra_server_send_message(client);
3817 }
3818
3819 /* re-add remote rmac if needed */
3820 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
3821 struct ethaddr *rmac)
3822 {
3823 char buf[ETHER_ADDR_STRLEN];
3824 zebra_mac_t *zrmac = NULL;
3825
3826 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3827 if (!zrmac)
3828 return 0;
3829
3830 if (IS_ZEBRA_DEBUG_VXLAN)
3831 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
3832 prefix_mac2str(rmac, buf, sizeof(buf)),
3833 zl3vni->vni);
3834
3835 zl3vni_rmac_install(zl3vni, zrmac);
3836 return 0;
3837 }
3838
3839 /* Public functions */
3840
3841 int is_l3vni_for_prefix_routes_only(vni_t vni)
3842 {
3843 zebra_l3vni_t *zl3vni = NULL;
3844
3845 zl3vni = zl3vni_lookup(vni);
3846 if (!zl3vni)
3847 return 0;
3848
3849 return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
3850 }
3851
3852 /* handle evpn route in vrf table */
3853 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
3854 struct ethaddr *rmac,
3855 struct ipaddr *vtep_ip,
3856 struct prefix *host_prefix)
3857 {
3858 zebra_l3vni_t *zl3vni = NULL;
3859
3860 zl3vni = zl3vni_from_vrf(vrf_id);
3861 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
3862 return;
3863
3864 /* add the next hop neighbor */
3865 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
3866
3867 /* add the rmac */
3868 zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip, host_prefix);
3869 }
3870
3871 /* handle evpn vrf route delete */
3872 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
3873 struct ethaddr *rmac,
3874 struct ipaddr *vtep_ip,
3875 struct prefix *host_prefix)
3876 {
3877 zebra_l3vni_t *zl3vni = NULL;
3878
3879 zl3vni = zl3vni_from_vrf(vrf_id);
3880 if (!zl3vni)
3881 return;
3882
3883 /* delete the next hop entry */
3884 zl3vni_remote_nh_del(zl3vni, vtep_ip, host_prefix);
3885
3886 /* delete the rmac entry */
3887 zl3vni_remote_rmac_del(zl3vni, rmac, host_prefix);
3888 }
3889
3890 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty,
3891 vni_t l3vni,
3892 struct ethaddr *rmac,
3893 u_char use_json)
3894 {
3895 zebra_l3vni_t *zl3vni = NULL;
3896 zebra_mac_t *zrmac = NULL;
3897 json_object *json = NULL;
3898
3899 if (!is_evpn_enabled()) {
3900 if (use_json)
3901 vty_out(vty, "{}\n");
3902 return;
3903 }
3904
3905 if (use_json)
3906 json = json_object_new_object();
3907
3908 zl3vni = zl3vni_lookup(l3vni);
3909 if (!zl3vni) {
3910 if (use_json)
3911 vty_out(vty, "{}\n");
3912 else
3913 vty_out(vty, "%% L3-VNI %u doesnt exist\n",
3914 l3vni);
3915 return;
3916 }
3917
3918 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3919 if (!zrmac) {
3920 if (use_json)
3921 vty_out(vty, "{}\n");
3922 else
3923 vty_out(vty,
3924 "%% Requested RMAC doesnt exist in L3-VNI %u",
3925 l3vni);
3926 return;
3927 }
3928
3929 zl3vni_print_rmac(zrmac, vty, json);
3930
3931 if (use_json) {
3932 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3933 json, JSON_C_TO_STRING_PRETTY));
3934 json_object_free(json);
3935 }
3936 }
3937
3938 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty,
3939 vni_t l3vni,
3940 u_char use_json)
3941 {
3942 zebra_l3vni_t *zl3vni;
3943 u_int32_t num_rmacs;
3944 struct rmac_walk_ctx wctx;
3945 json_object *json = NULL;
3946
3947 if (!is_evpn_enabled())
3948 return;
3949
3950 zl3vni = zl3vni_lookup(l3vni);
3951 if (!zl3vni) {
3952 if (use_json)
3953 vty_out(vty, "{}\n");
3954 else
3955 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
3956 return;
3957 }
3958 num_rmacs = hashcount(zl3vni->rmac_table);
3959 if (!num_rmacs)
3960 return;
3961
3962 if (use_json)
3963 json = json_object_new_object();
3964
3965 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
3966 wctx.vty = vty;
3967 wctx.json = json;
3968 if (!use_json) {
3969 vty_out(vty,
3970 "Number of Remote RMACs known for this VNI: %u\n",
3971 num_rmacs);
3972 vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
3973 } else
3974 json_object_int_add(json, "numRmacs", num_rmacs);
3975
3976 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
3977
3978 if (use_json) {
3979 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3980 json, JSON_C_TO_STRING_PRETTY));
3981 json_object_free(json);
3982 }
3983 }
3984
3985 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty,
3986 u_char use_json)
3987 {
3988 struct zebra_ns *zns = NULL;
3989 json_object *json = NULL;
3990 void *args[2];
3991
3992 if (!is_evpn_enabled()) {
3993 if (use_json)
3994 vty_out(vty, "{}\n");
3995 return;
3996 }
3997
3998 zns = zebra_ns_lookup(NS_DEFAULT);
3999 if (!zns) {
4000 if (use_json)
4001 vty_out(vty, "{}\n");
4002 return;
4003 }
4004
4005 if (use_json)
4006 json = json_object_new_object();
4007
4008 args[0] = vty;
4009 args[1] = json;
4010 hash_iterate(zns->l3vni_table,
4011 (void (*)(struct hash_backet *,
4012 void *))zl3vni_print_rmac_hash_all_vni,
4013 args);
4014
4015 if (use_json) {
4016 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4017 json, JSON_C_TO_STRING_PRETTY));
4018 json_object_free(json);
4019 }
4020 }
4021
4022 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty,
4023 vni_t l3vni,
4024 struct ipaddr *ip,
4025 u_char use_json)
4026 {
4027 zebra_l3vni_t *zl3vni = NULL;
4028 zebra_neigh_t *n = NULL;
4029 json_object *json = NULL;
4030
4031 if (!is_evpn_enabled()) {
4032 if (use_json)
4033 vty_out(vty, "{}\n");
4034 return;
4035 }
4036
4037 if (use_json)
4038 json = json_object_new_object();
4039
4040 zl3vni = zl3vni_lookup(l3vni);
4041 if (!zl3vni) {
4042 if (use_json)
4043 vty_out(vty, "{}\n");
4044 else
4045 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
4046 return;
4047 }
4048
4049 n = zl3vni_nh_lookup(zl3vni, ip);
4050 if (!n) {
4051 if (use_json)
4052 vty_out(vty, "{}\n");
4053 else
4054 vty_out(vty,
4055 "%% Requested next-hop not present for L3-VNI %u",
4056 l3vni);
4057 return;
4058 }
4059
4060 zl3vni_print_nh(n, vty, json);
4061
4062 if (use_json) {
4063 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4064 json, JSON_C_TO_STRING_PRETTY));
4065 json_object_free(json);
4066 }
4067 }
4068
4069 void zebra_vxlan_print_nh_l3vni(struct vty *vty,
4070 vni_t l3vni,
4071 u_char use_json)
4072 {
4073 u_int32_t num_nh;
4074 struct nh_walk_ctx wctx;
4075 json_object *json = NULL;
4076 zebra_l3vni_t *zl3vni = NULL;
4077
4078 if (!is_evpn_enabled())
4079 return;
4080
4081 zl3vni = zl3vni_lookup(l3vni);
4082 if (!zl3vni) {
4083 if (use_json)
4084 vty_out(vty, "{}\n");
4085 else
4086 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
4087 return;
4088 }
4089
4090 num_nh = hashcount(zl3vni->nh_table);
4091 if (!num_nh)
4092 return;
4093
4094 if (use_json)
4095 json = json_object_new_object();
4096
4097 wctx.vty = vty;
4098 wctx.json = json;
4099 if (!use_json) {
4100 vty_out(vty,
4101 "Number of NH Neighbors known for this VNI: %u\n",
4102 num_nh);
4103 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
4104 } else
4105 json_object_int_add(json, "numNextHops", num_nh);
4106
4107 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
4108
4109 if (use_json) {
4110 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4111 json, JSON_C_TO_STRING_PRETTY));
4112 json_object_free(json);
4113 }
4114 }
4115
4116 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty,
4117 u_char use_json)
4118 {
4119 struct zebra_ns *zns = NULL;
4120 json_object *json = NULL;
4121 void *args[2];
4122
4123 if (!is_evpn_enabled()) {
4124 if (use_json)
4125 vty_out(vty, "{}\n");
4126 return;
4127 }
4128
4129 zns = zebra_ns_lookup(NS_DEFAULT);
4130 if (!zns)
4131 return;
4132
4133 if (use_json)
4134 json = json_object_new_object();
4135
4136 args[0] = vty;
4137 args[1] = json;
4138 hash_iterate(zns->l3vni_table,
4139 (void (*)(struct hash_backet *,
4140 void *))zl3vni_print_nh_hash_all_vni,
4141 args);
4142
4143 if (use_json) {
4144 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4145 json, JSON_C_TO_STRING_PRETTY));
4146 json_object_free(json);
4147 }
4148 return;
4149 }
4150
4151 /*
4152 * Display L3 VNI information (VTY command handler).
4153 */
4154 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, u_char use_json)
4155 {
4156 void *args[2];
4157 json_object *json = NULL;
4158 zebra_l3vni_t *zl3vni = NULL;
4159
4160 if (!is_evpn_enabled()) {
4161 if (use_json)
4162 vty_out(vty, "{}\n");
4163 return;
4164 }
4165
4166 zl3vni = zl3vni_lookup(vni);
4167 if (!zl3vni) {
4168 if (use_json)
4169 vty_out(vty, "{}\n");
4170 else
4171 vty_out(vty, "%% VNI %u does not exist\n", vni);
4172 return;
4173 }
4174
4175 if (use_json)
4176 json = json_object_new_object();
4177
4178 args[0] = vty;
4179 args[1] = json;
4180 zl3vni_print(zl3vni, (void *)args);
4181
4182 if (use_json) {
4183 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4184 json, JSON_C_TO_STRING_PRETTY));
4185 json_object_free(json);
4186 }
4187 }
4188
4189 void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
4190 json_object *json_vrfs)
4191 {
4192 char buf[ETHER_ADDR_STRLEN];
4193 zebra_l3vni_t *zl3vni = NULL;
4194
4195 zl3vni = zl3vni_lookup(zvrf->l3vni);
4196 if (!zl3vni)
4197 return;
4198
4199 if (!json_vrfs) {
4200 vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4201 zvrf_name(zvrf),
4202 zl3vni->vni,
4203 zl3vni_vxlan_if_name(zl3vni),
4204 zl3vni_svi_if_name(zl3vni),
4205 zl3vni_state2str(zl3vni),
4206 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
4207 } else {
4208 json_object *json_vrf = NULL;
4209 json_vrf = json_object_new_object();
4210 json_object_string_add(json_vrf, "vrf",
4211 zvrf_name(zvrf));
4212 json_object_int_add(json_vrf, "vni", zl3vni->vni);
4213 json_object_string_add(json_vrf, "vxlanIntf",
4214 zl3vni_vxlan_if_name(zl3vni));
4215 json_object_string_add(json_vrf, "sviIntf",
4216 zl3vni_svi_if_name(zl3vni));
4217 json_object_string_add(json_vrf, "state",
4218 zl3vni_state2str(zl3vni));
4219 json_object_string_add(json_vrf, "routerMac",
4220 zl3vni_rmac2str(zl3vni, buf,
4221 sizeof(buf)));
4222 json_object_array_add(json_vrfs, json_vrf);
4223 }
4224 }
4225
4226 /*
4227 * Display Neighbors for a VNI (VTY command handler).
4228 */
4229 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
4230 vni_t vni, u_char use_json)
4231 {
4232 zebra_vni_t *zvni;
4233 u_int32_t num_neigh;
4234 struct neigh_walk_ctx wctx;
4235 json_object *json = NULL;
4236
4237 if (!is_evpn_enabled())
4238 return;
4239 zvni = zvni_lookup(vni);
4240 if (!zvni) {
4241 if (use_json)
4242 vty_out(vty, "{}\n");
4243 else
4244 vty_out(vty, "%% VNI %u does not exist\n", vni);
4245 return;
4246 }
4247 num_neigh = hashcount(zvni->neigh_table);
4248 if (!num_neigh)
4249 return;
4250
4251 if (use_json)
4252 json = json_object_new_object();
4253
4254 /* Since we have IPv6 addresses to deal with which can vary widely in
4255 * size, we try to be a bit more elegant in display by first computing
4256 * the maximum width.
4257 */
4258 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
4259 wctx.zvni = zvni;
4260 wctx.vty = vty;
4261 wctx.addr_width = 15;
4262 wctx.json = json;
4263 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
4264
4265 if (!use_json) {
4266 vty_out(vty,
4267 "Number of ARPs (local and remote) known for this VNI: %u\n",
4268 num_neigh);
4269 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
4270 "Type", "MAC", "Remote VTEP");
4271 } else
4272 json_object_int_add(json, "numArpNd", num_neigh);
4273
4274 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
4275 if (use_json) {
4276 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4277 json, JSON_C_TO_STRING_PRETTY));
4278 json_object_free(json);
4279 }
4280 }
4281
4282 /*
4283 * Display neighbors across all VNIs (VTY command handler).
4284 */
4285 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
4286 u_char use_json)
4287 {
4288 json_object *json = NULL;
4289 void *args[2];
4290
4291 if (!is_evpn_enabled())
4292 return;
4293
4294 if (use_json)
4295 json = json_object_new_object();
4296
4297 args[0] = vty;
4298 args[1] = json;
4299 hash_iterate(zvrf->vni_table,
4300 (void (*)(struct hash_backet *,
4301 void *))zvni_print_neigh_hash_all_vni,
4302 args);
4303 if (use_json) {
4304 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4305 json, JSON_C_TO_STRING_PRETTY));
4306 json_object_free(json);
4307 }
4308 }
4309
4310 /*
4311 * Display specific neighbor for a VNI, if present (VTY command handler).
4312 */
4313 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
4314 struct zebra_vrf *zvrf, vni_t vni,
4315 struct ipaddr *ip, u_char use_json)
4316 {
4317 zebra_vni_t *zvni;
4318 zebra_neigh_t *n;
4319 json_object *json = NULL;
4320
4321 if (!is_evpn_enabled())
4322 return;
4323 zvni = zvni_lookup(vni);
4324 if (!zvni) {
4325 if (use_json)
4326 vty_out(vty, "{}\n");
4327 else
4328 vty_out(vty, "%% VNI %u does not exist\n", vni);
4329 return;
4330 }
4331 n = zvni_neigh_lookup(zvni, ip);
4332 if (!n) {
4333 if (!use_json)
4334 vty_out(vty,
4335 "%% Requested neighbor does not exist in VNI %u\n",
4336 vni);
4337 return;
4338 }
4339 if (use_json)
4340 json = json_object_new_object();
4341
4342 zvni_print_neigh(n, vty, json);
4343
4344 if (use_json) {
4345 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4346 json, JSON_C_TO_STRING_PRETTY));
4347 json_object_free(json);
4348 }
4349 }
4350
4351 /*
4352 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4353 * By definition, these are remote neighbors.
4354 */
4355 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
4356 vni_t vni, struct in_addr vtep_ip,
4357 u_char use_json)
4358 {
4359 zebra_vni_t *zvni;
4360 u_int32_t num_neigh;
4361 struct neigh_walk_ctx wctx;
4362 json_object *json = NULL;
4363
4364 if (!is_evpn_enabled())
4365 return;
4366 zvni = zvni_lookup(vni);
4367 if (!zvni) {
4368 if (use_json)
4369 vty_out(vty, "{}\n");
4370 else
4371 vty_out(vty, "%% VNI %u does not exist\n", vni);
4372 return;
4373 }
4374 num_neigh = hashcount(zvni->neigh_table);
4375 if (!num_neigh)
4376 return;
4377
4378 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
4379 wctx.zvni = zvni;
4380 wctx.vty = vty;
4381 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
4382 wctx.r_vtep_ip = vtep_ip;
4383 wctx.json = json;
4384 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
4385
4386 if (use_json) {
4387 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4388 json, JSON_C_TO_STRING_PRETTY));
4389 json_object_free(json);
4390 }
4391 }
4392
4393 /*
4394 * Display MACs for a VNI (VTY command handler).
4395 */
4396 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
4397 vni_t vni, u_char use_json)
4398 {
4399 zebra_vni_t *zvni;
4400 u_int32_t num_macs;
4401 struct mac_walk_ctx wctx;
4402 json_object *json = NULL;
4403 json_object *json_mac = NULL;
4404
4405 if (!is_evpn_enabled())
4406 return;
4407 zvni = zvni_lookup(vni);
4408 if (!zvni) {
4409 if (use_json)
4410 vty_out(vty, "{}\n");
4411 else
4412 vty_out(vty, "%% VNI %u does not exist\n", vni);
4413 return;
4414 }
4415 num_macs = num_valid_macs(zvni);
4416 if (!num_macs)
4417 return;
4418
4419 if (use_json) {
4420 json = json_object_new_object();
4421 json_mac = json_object_new_object();
4422 }
4423
4424 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4425 wctx.zvni = zvni;
4426 wctx.vty = vty;
4427 wctx.json = json_mac;
4428
4429 if (!use_json) {
4430 vty_out(vty,
4431 "Number of MACs (local and remote) known for this VNI: %u\n",
4432 num_macs);
4433 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4434 "Intf/Remote VTEP", "VLAN");
4435 } else
4436 json_object_int_add(json, "numMacs", num_macs);
4437
4438 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
4439
4440 if (use_json) {
4441 json_object_object_add(json, "macs", json_mac);
4442 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4443 json, JSON_C_TO_STRING_PRETTY));
4444 json_object_free(json);
4445 }
4446 }
4447
4448 /*
4449 * Display MACs for all VNIs (VTY command handler).
4450 */
4451 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
4452 u_char use_json)
4453 {
4454 struct mac_walk_ctx wctx;
4455 json_object *json = NULL;
4456
4457 if (!is_evpn_enabled()) {
4458 if (use_json)
4459 vty_out(vty, "{}\n");
4460 return;
4461 }
4462 if (use_json)
4463 json = json_object_new_object();
4464
4465 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4466 wctx.vty = vty;
4467 wctx.json = json;
4468 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
4469
4470 if (use_json) {
4471 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4472 json, JSON_C_TO_STRING_PRETTY));
4473 json_object_free(json);
4474 }
4475 }
4476
4477 /*
4478 * Display MACs for all VNIs (VTY command handler).
4479 */
4480 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
4481 struct zebra_vrf *zvrf,
4482 struct in_addr vtep_ip,
4483 u_char use_json)
4484 {
4485 struct mac_walk_ctx wctx;
4486 json_object *json = NULL;
4487
4488 if (!is_evpn_enabled())
4489 return;
4490
4491 if (use_json)
4492 json = json_object_new_object();
4493
4494 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4495 wctx.vty = vty;
4496 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
4497 wctx.r_vtep_ip = vtep_ip;
4498 wctx.json = json;
4499 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
4500
4501 if (use_json) {
4502 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4503 json, JSON_C_TO_STRING_PRETTY));
4504 json_object_free(json);
4505 }
4506 }
4507
4508 /*
4509 * Display specific MAC for a VNI, if present (VTY command handler).
4510 */
4511 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
4512 vni_t vni, struct ethaddr *macaddr)
4513 {
4514 zebra_vni_t *zvni;
4515 zebra_mac_t *mac;
4516
4517 if (!is_evpn_enabled())
4518 return;
4519 zvni = zvni_lookup(vni);
4520 if (!zvni) {
4521 vty_out(vty, "%% VNI %u does not exist\n", vni);
4522 return;
4523 }
4524 mac = zvni_mac_lookup(zvni, macaddr);
4525 if (!mac) {
4526 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
4527 vni);
4528 return;
4529 }
4530
4531 zvni_print_mac(mac, vty);
4532 }
4533
4534 /*
4535 * Display MACs for a VNI from specific VTEP (VTY command handler).
4536 */
4537 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
4538 vni_t vni, struct in_addr vtep_ip,
4539 u_char use_json)
4540 {
4541 zebra_vni_t *zvni;
4542 u_int32_t num_macs;
4543 struct mac_walk_ctx wctx;
4544 json_object *json = NULL;
4545 json_object *json_mac = NULL;
4546
4547 if (!is_evpn_enabled())
4548 return;
4549 zvni = zvni_lookup(vni);
4550 if (!zvni) {
4551 if (use_json)
4552 vty_out(vty, "{}\n");
4553 else
4554 vty_out(vty, "%% VNI %u does not exist\n", vni);
4555 return;
4556 }
4557 num_macs = num_valid_macs(zvni);
4558 if (!num_macs)
4559 return;
4560
4561 if (use_json) {
4562 json = json_object_new_object();
4563 json_mac = json_object_new_object();
4564 }
4565
4566 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4567 wctx.zvni = zvni;
4568 wctx.vty = vty;
4569 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
4570 wctx.r_vtep_ip = vtep_ip;
4571 wctx.json = json_mac;
4572 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
4573
4574 if (use_json) {
4575 json_object_int_add(json, "numMacs", wctx.count);
4576 if (wctx.count)
4577 json_object_object_add(json, "macs", json_mac);
4578 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4579 json, JSON_C_TO_STRING_PRETTY));
4580 json_object_free(json);
4581 }
4582 }
4583
4584
4585 /*
4586 * Display VNI information (VTY command handler).
4587 */
4588 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
4589 u_char use_json)
4590 {
4591 json_object *json = NULL;
4592 void *args[2];
4593 zebra_l3vni_t *zl3vni = NULL;
4594 zebra_vni_t *zvni = NULL;
4595
4596 if (!is_evpn_enabled())
4597 return;
4598
4599 if (use_json)
4600 json = json_object_new_object();
4601 args[0] = vty;
4602 args[1] = json;
4603
4604 zl3vni = zl3vni_lookup(vni);
4605 if (zl3vni) {
4606 zl3vni_print(zl3vni, (void *)args);
4607 } else {
4608 zvni = zvni_lookup(vni);
4609 if (!zvni) {
4610 if (use_json)
4611 vty_out(vty, "{}\n");
4612 else
4613 vty_out(vty, "%% VNI %u does not exist\n", vni);
4614 return;
4615 }
4616
4617 zvni_print(zvni, (void *)args);
4618 }
4619
4620 if (use_json) {
4621 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4622 json, JSON_C_TO_STRING_PRETTY));
4623 json_object_free(json);
4624 }
4625 }
4626
4627 /* Display all global details for EVPN */
4628 void zebra_vxlan_print_evpn(struct vty *vty, u_char uj)
4629 {
4630 int num_l2vnis = 0;
4631 int num_l3vnis = 0;
4632 int num_vnis = 0;
4633 json_object *json = NULL;
4634 struct zebra_ns *zns = NULL;
4635 struct zebra_vrf *zvrf = NULL;
4636
4637 if (!is_evpn_enabled())
4638 return;
4639
4640 zns = zebra_ns_lookup(NS_DEFAULT);
4641 if (!zns)
4642 return;
4643
4644 zvrf = vrf_info_lookup(VRF_DEFAULT);
4645 if (!zvrf)
4646 return;
4647
4648 num_l3vnis = hashcount(zns->l3vni_table);
4649 num_l2vnis = hashcount(zvrf->vni_table);
4650 num_vnis = num_l2vnis + num_l3vnis;
4651
4652 if (uj) {
4653 json = json_object_new_object();
4654 json_object_string_add(json, "advertiseGatewayMacip",
4655 zvrf->advertise_gw_macip ? "Yes" : "No");
4656 json_object_int_add(json, "numVnis", num_vnis);
4657 json_object_int_add(json, "numL2Vnis", num_l2vnis);
4658 json_object_int_add(json, "numL3Vnis", num_l3vnis);
4659 } else {
4660 vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
4661 vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
4662 vty_out(vty, "Advertise gateway mac-ip: %s\n",
4663 zvrf->advertise_gw_macip ? "Yes" : "No");
4664 }
4665
4666 if (uj) {
4667 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4668 json, JSON_C_TO_STRING_PRETTY));
4669 json_object_free(json);
4670 }
4671 }
4672
4673 /*
4674 * Display VNI hash table (VTY command handler).
4675 */
4676 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
4677 u_char use_json)
4678 {
4679 json_object *json = NULL;
4680 struct zebra_ns *zns = NULL;
4681 void *args[2];
4682
4683 if (!is_evpn_enabled())
4684 return;
4685
4686 zns = zebra_ns_lookup(NS_DEFAULT);
4687 if (!zns)
4688 return;
4689
4690
4691 if (use_json)
4692 json = json_object_new_object();
4693 else
4694 vty_out(vty,
4695 "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n",
4696 "VNI", "Type", "VxLAN IF", "# MACs",
4697 "# ARPs", "# Remote VTEPs", "Tenant VRF");
4698
4699 args[0] = vty;
4700 args[1] = json;
4701
4702 /* Display all L2-VNIs */
4703 hash_iterate(zvrf->vni_table,
4704 (void (*)(struct hash_backet *, void *))zvni_print_hash,
4705 args);
4706
4707 /* Display all L3-VNIs */
4708 hash_iterate(zns->l3vni_table,
4709 (void (*)(struct hash_backet *, void *))zl3vni_print_hash,
4710 args);
4711
4712 if (use_json) {
4713 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4714 json, JSON_C_TO_STRING_PRETTY));
4715 json_object_free(json);
4716 }
4717 }
4718
4719 /*
4720 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4721 * kernel. This may result in either the neighbor getting deleted from
4722 * our database or being re-added to the kernel (if it is a valid
4723 * remote neighbor).
4724 */
4725 int zebra_vxlan_local_neigh_del(struct interface *ifp,
4726 struct interface *link_if, struct ipaddr *ip)
4727 {
4728 char buf[INET6_ADDRSTRLEN];
4729 char buf2[ETHER_ADDR_STRLEN];
4730 zebra_neigh_t *n = NULL;
4731 zebra_vni_t *zvni = NULL;
4732 zebra_mac_t *zmac = NULL;
4733 zebra_l3vni_t *zl3vni = NULL;
4734
4735 /* check if this is a remote neigh entry corresponding to remote
4736 * next-hop
4737 */
4738 zl3vni = zl3vni_from_svi(ifp, link_if);
4739 if (zl3vni)
4740 return zl3vni_local_nh_del(zl3vni, ip);
4741
4742 /* We are only interested in neighbors on an SVI that resides on top
4743 * of a VxLAN bridge.
4744 */
4745 zvni = zvni_from_svi(ifp, link_if);
4746 if (!zvni)
4747 return 0;
4748
4749 if (!zvni->vxlan_if) {
4750 zlog_err(
4751 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4752 zvni->vni, zvni);
4753 return -1;
4754 }
4755
4756 if (IS_ZEBRA_DEBUG_VXLAN)
4757 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4758 ipaddr2str(ip, buf, sizeof(buf)),
4759 ifp->name, ifp->ifindex, zvni->vni);
4760
4761 /* If entry doesn't exist, nothing to do. */
4762 n = zvni_neigh_lookup(zvni, ip);
4763 if (!n)
4764 return 0;
4765
4766 zmac = zvni_mac_lookup(zvni, &n->emac);
4767 if (!zmac) {
4768 if (IS_ZEBRA_DEBUG_VXLAN)
4769 zlog_err(
4770 "Trying to del a neigh %s without a mac %s on VNI %u",
4771 ipaddr2str(ip, buf, sizeof(buf)),
4772 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
4773 zvni->vni);
4774
4775 return 0;
4776 }
4777
4778 /* If it is a remote entry, the kernel has aged this out or someone has
4779 * deleted it, it needs to be re-installed as Quagga is the owner.
4780 */
4781 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
4782 zvni_neigh_install(zvni, n);
4783 return 0;
4784 }
4785
4786 /* Remove neighbor from BGP. */
4787 if (IS_ZEBRA_NEIGH_ACTIVE(n))
4788 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
4789 0);
4790
4791 /* Delete this neighbor entry. */
4792 zvni_neigh_del(zvni, n);
4793
4794 /* see if the AUTO mac needs to be deleted */
4795 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
4796 && !listcount(zmac->neigh_list))
4797 zvni_mac_del(zvni, zmac);
4798
4799 return 0;
4800 }
4801
4802 /*
4803 * Handle neighbor add or update (on a VLAN device / L3 interface)
4804 * from the kernel.
4805 */
4806 int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
4807 struct interface *link_if,
4808 struct ipaddr *ip,
4809 struct ethaddr *macaddr, u_int16_t state,
4810 u_char ext_learned)
4811 {
4812 char buf[ETHER_ADDR_STRLEN];
4813 char buf2[INET6_ADDRSTRLEN];
4814 zebra_vni_t *zvni = NULL;
4815 zebra_neigh_t *n = NULL;
4816 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
4817 zebra_l3vni_t *zl3vni = NULL;
4818
4819 /* check if this is a remote neigh entry corresponding to remote
4820 * next-hop
4821 */
4822 zl3vni = zl3vni_from_svi(ifp, link_if);
4823 if (zl3vni)
4824 return zl3vni_local_nh_add_update(zl3vni, ip, state);
4825
4826 /* We are only interested in neighbors on an SVI that resides on top
4827 * of a VxLAN bridge.
4828 */
4829 zvni = zvni_from_svi(ifp, link_if);
4830 if (!zvni)
4831 return 0;
4832
4833 if (IS_ZEBRA_DEBUG_VXLAN)
4834 zlog_debug(
4835 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4836 ipaddr2str(ip, buf2, sizeof(buf2)),
4837 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
4838 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
4839 zvni->vni);
4840
4841 /* create a dummy MAC if the MAC is not already present */
4842 zmac = zvni_mac_lookup(zvni, macaddr);
4843 if (!zmac) {
4844 if (IS_ZEBRA_DEBUG_VXLAN)
4845 zlog_debug(
4846 "AUTO MAC %s created for neigh %s on VNI %u",
4847 prefix_mac2str(macaddr, buf, sizeof(buf)),
4848 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
4849
4850 zmac = zvni_mac_add(zvni, macaddr);
4851 if (!zmac) {
4852 zlog_warn("Failed to add MAC %s VNI %u",
4853 prefix_mac2str(macaddr, buf, sizeof(buf)),
4854 zvni->vni);
4855 return -1;
4856 }
4857
4858 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
4859 memset(&zmac->flags, 0, sizeof(u_int32_t));
4860 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
4861 }
4862
4863 /* If same entry already exists, it might be a change or it might be a
4864 * move from remote to local.
4865 */
4866 n = zvni_neigh_lookup(zvni, ip);
4867 if (n) {
4868 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
4869 if (memcmp(n->emac.octet, macaddr->octet,
4870 ETH_ALEN)
4871 == 0) {
4872 /* Update any params and return - client doesn't
4873 * care about a purely local change.
4874 */
4875 n->ifindex = ifp->ifindex;
4876 return 0;
4877 }
4878
4879 /* If the MAC has changed,
4880 * need to issue a delete first
4881 * as this means a different MACIP route.
4882 * Also, need to do some unlinking/relinking.
4883 */
4884 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
4885 &n->emac, 0);
4886 old_zmac = zvni_mac_lookup(zvni, &n->emac);
4887 if (old_zmac) {
4888 listnode_delete(old_zmac->neigh_list, n);
4889 zvni_deref_ip2mac(zvni, old_zmac, 0);
4890 }
4891
4892 /* Set "local" forwarding info. */
4893 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4894 n->ifindex = ifp->ifindex;
4895 memcpy(&n->emac, macaddr, ETH_ALEN);
4896
4897 /* Link to new MAC */
4898 listnode_add_sort(zmac->neigh_list, n);
4899 } else if (ext_learned)
4900 /* The neighbor is remote and that is the notification we got.
4901 */
4902 {
4903 /* TODO: Evaluate if we need to do anything here. */
4904 return 0;
4905 } else
4906 /* Neighbor has moved from remote to local. */
4907 {
4908 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
4909 n->r_vtep_ip.s_addr = 0;
4910 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4911 n->ifindex = ifp->ifindex;
4912 }
4913 } else {
4914 n = zvni_neigh_add(zvni, ip, macaddr);
4915 if (!n) {
4916 zlog_err(
4917 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4918 ipaddr2str(ip, buf2, sizeof(buf2)),
4919 prefix_mac2str(macaddr, buf, sizeof(buf)),
4920 ifp->name, ifp->ifindex, zvni->vni);
4921 return -1;
4922 }
4923 /* Set "local" forwarding info. */
4924 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4925 n->ifindex = ifp->ifindex;
4926 }
4927
4928 /* Before we program this in BGP, we need to check if MAC is locally
4929 * learnt as well */
4930 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
4931 if (IS_ZEBRA_DEBUG_VXLAN)
4932 zlog_debug(
4933 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4934 ipaddr2str(ip, buf2, sizeof(buf2)),
4935 prefix_mac2str(macaddr, buf, sizeof(buf)),
4936 zvni->vni);
4937
4938 return 0;
4939 }
4940
4941 /* Inform BGP. */
4942 if (IS_ZEBRA_DEBUG_VXLAN)
4943 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
4944 ipaddr2str(ip, buf2, sizeof(buf2)),
4945 prefix_mac2str(macaddr, buf, sizeof(buf)),
4946 zvni->vni);
4947 ZEBRA_NEIGH_SET_ACTIVE(n);
4948
4949 return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
4950 }
4951
4952
4953 /*
4954 * Handle message from client to delete a remote MACIP for a VNI.
4955 */
4956 int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
4957 struct zebra_vrf *zvrf)
4958 {
4959 struct stream *s;
4960 vni_t vni;
4961 struct ethaddr macaddr;
4962 struct ipaddr ip;
4963 struct in_addr vtep_ip;
4964 zebra_vni_t *zvni;
4965 zebra_mac_t *mac;
4966 zebra_neigh_t *n;
4967 u_short l = 0, ipa_len;
4968 char buf[ETHER_ADDR_STRLEN];
4969 char buf1[INET6_ADDRSTRLEN];
4970 struct interface *ifp = NULL;
4971 struct zebra_if *zif = NULL;
4972
4973 memset(&macaddr, 0, sizeof(struct ethaddr));
4974 memset(&ip, 0, sizeof(struct ipaddr));
4975 memset(&vtep_ip, 0, sizeof(struct in_addr));
4976
4977 s = client->ibuf;
4978
4979 while (l < length) {
4980 /* Obtain each remote MACIP and process. */
4981 /* Message contains VNI, followed by MAC followed by IP (if any)
4982 * followed by remote VTEP IP.
4983 */
4984 mac = NULL;
4985 n = NULL;
4986 memset(&ip, 0, sizeof(ip));
4987 STREAM_GETL(s, vni);
4988 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
4989 STREAM_GETL(s, ipa_len);
4990 if (ipa_len) {
4991 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
4992 : IPADDR_V6;
4993 STREAM_GET(&ip.ip.addr, s, ipa_len);
4994 }
4995 l += 4 + ETH_ALEN + 4 + ipa_len;
4996 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4997 l += IPV4_MAX_BYTELEN;
4998
4999 if (IS_ZEBRA_DEBUG_VXLAN)
5000 zlog_debug(
5001 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
5002 prefix_mac2str(&macaddr, buf, sizeof(buf)),
5003 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
5004 inet_ntoa(vtep_ip),
5005 zebra_route_string(client->proto));
5006
5007 /* Locate VNI hash entry - expected to exist. */
5008 zvni = zvni_lookup(vni);
5009 if (!zvni) {
5010 if (IS_ZEBRA_DEBUG_VXLAN)
5011 zlog_debug(
5012 "Failed to locate VNI hash upon remote MACIP DEL, "
5013 "VNI %u",
5014 vni);
5015 continue;
5016 }
5017 ifp = zvni->vxlan_if;
5018 if (!ifp) {
5019 zlog_err(
5020 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
5021 vni, zvni);
5022 continue;
5023 }
5024 zif = ifp->info;
5025
5026 /* If down or not mapped to a bridge, we're done. */
5027 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5028 continue;
5029
5030 /* The remote VTEP specified is normally expected to exist, but
5031 * it is
5032 * possible that the peer may delete the VTEP before deleting
5033 * any MACs
5034 * referring to the VTEP, in which case the handler (see
5035 * remote_vtep_del)
5036 * would have already deleted the MACs.
5037 */
5038 if (!zvni_vtep_find(zvni, &vtep_ip))
5039 continue;
5040
5041 mac = zvni_mac_lookup(zvni, &macaddr);
5042 if (ipa_len)
5043 n = zvni_neigh_lookup(zvni, &ip);
5044
5045 if (n && !mac) {
5046 zlog_err(
5047 "Failed to locate MAC %s for neigh %s VNI %u",
5048 prefix_mac2str(&macaddr, buf, sizeof(buf)),
5049 ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
5050 continue;
5051 }
5052
5053 /* If the remote mac or neighbor doesn't exist there is nothing
5054 * more
5055 * to do. Otherwise, uninstall the entry and then remove it.
5056 */
5057 if (!mac && !n)
5058 continue;
5059
5060 /* Ignore the delete if this mac is a gateway mac-ip */
5061 if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) &&
5062 CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
5063 zlog_err("%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway",
5064 zvrf_id(zvrf),
5065 prefix_mac2str(&macaddr, buf, sizeof(buf)),
5066 ipaddr2str(&ip, buf1, sizeof(buf1)),
5067 vni);
5068 continue;
5069 }
5070
5071 /* Uninstall remote neighbor or MAC. */
5072 if (n) {
5073 /* When the MAC changes for an IP, it is possible the
5074 * client may
5075 * update the new MAC before trying to delete the "old"
5076 * neighbor
5077 * (as these are two different MACIP routes). Do the
5078 * delete only
5079 * if the MAC matches.
5080 */
5081 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5082 && (memcmp(n->emac.octet, macaddr.octet,
5083 ETH_ALEN)
5084 == 0)) {
5085 zvni_neigh_uninstall(zvni, n);
5086 zvni_neigh_del(zvni, n);
5087 zvni_deref_ip2mac(zvni, mac, 1);
5088 }
5089 } else {
5090 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5091 zvni_process_neigh_on_remote_mac_del(zvni,
5092 mac);
5093
5094 if (list_isempty(mac->neigh_list)) {
5095 zvni_mac_uninstall(zvni, mac, 0);
5096 zvni_mac_del(zvni, mac);
5097 } else
5098 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5099 }
5100 }
5101 }
5102
5103 stream_failure:
5104 return 0;
5105 }
5106
5107 /*
5108 * Handle message from client to add a remote MACIP for a VNI. This
5109 * could be just the add of a MAC address or the add of a neighbor
5110 * (IP+MAC).
5111 */
5112 int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
5113 struct zebra_vrf *zvrf)
5114 {
5115 struct stream *s;
5116 vni_t vni;
5117 struct ethaddr macaddr;
5118 struct ipaddr ip;
5119 struct in_addr vtep_ip;
5120 zebra_vni_t *zvni;
5121 zebra_vtep_t *zvtep;
5122 zebra_mac_t *mac, *old_mac;
5123 zebra_neigh_t *n;
5124 u_short l = 0, ipa_len;
5125 int update_mac = 0, update_neigh = 0;
5126 char buf[ETHER_ADDR_STRLEN];
5127 char buf1[INET6_ADDRSTRLEN];
5128 u_char sticky = 0;
5129 u_char flags = 0;
5130 struct interface *ifp = NULL;
5131 struct zebra_if *zif = NULL;
5132
5133 memset(&macaddr, 0, sizeof(struct ethaddr));
5134 memset(&ip, 0, sizeof(struct ipaddr));
5135 memset(&vtep_ip, 0, sizeof(struct in_addr));
5136
5137 if (!EVPN_ENABLED(zvrf)) {
5138 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
5139 __PRETTY_FUNCTION__);
5140 return -1;
5141 }
5142
5143 s = client->ibuf;
5144
5145 while (l < length) {
5146 /* Obtain each remote MACIP and process. */
5147 /* Message contains VNI, followed by MAC followed by IP (if any)
5148 * followed by remote VTEP IP.
5149 */
5150 update_mac = update_neigh = 0;
5151 mac = NULL;
5152 n = NULL;
5153 memset(&ip, 0, sizeof(ip));
5154 STREAM_GETL(s, vni);
5155 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
5156 STREAM_GETL(s, ipa_len);
5157 if (ipa_len) {
5158 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
5159 : IPADDR_V6;
5160 STREAM_GET(&ip.ip.addr, s, ipa_len);
5161 }
5162 l += 4 + ETH_ALEN + 4 + ipa_len;
5163 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
5164 l += IPV4_MAX_BYTELEN;
5165
5166 /* Get flags - sticky mac and/or gateway mac */
5167 flags = stream_getc(s);
5168 sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
5169 l++;
5170
5171 if (IS_ZEBRA_DEBUG_VXLAN)
5172 zlog_debug(
5173 "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
5174 prefix_mac2str(&macaddr, buf, sizeof(buf)),
5175 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
5176 inet_ntoa(vtep_ip), flags,
5177 zebra_route_string(client->proto));
5178
5179 /* Locate VNI hash entry - expected to exist. */
5180 zvni = zvni_lookup(vni);
5181 if (!zvni) {
5182 zlog_err(
5183 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
5184 vni);
5185 continue;
5186 }
5187 ifp = zvni->vxlan_if;
5188 if (!ifp) {
5189 zlog_err(
5190 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5191 vni, zvni);
5192 continue;
5193 }
5194 zif = ifp->info;
5195
5196 /* If down or not mapped to a bridge, we're done. */
5197 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5198 continue;
5199
5200 /* The remote VTEP specified should normally exist, but it is
5201 * possible
5202 * that when peering comes up, peer may advertise MACIP routes
5203 * before
5204 * advertising type-3 routes.
5205 */
5206 zvtep = zvni_vtep_find(zvni, &vtep_ip);
5207 if (!zvtep) {
5208 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
5209 zlog_err(
5210 "Failed to add remote VTEP, VNI %u zvni %p",
5211 vni, zvni);
5212 continue;
5213 }
5214
5215 zvni_vtep_install(zvni, &vtep_ip);
5216 }
5217
5218 mac = zvni_mac_lookup(zvni, &macaddr);
5219
5220 /* Ignore the update if the mac is already present
5221 as a gateway mac */
5222 if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
5223 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
5224 if (IS_ZEBRA_DEBUG_VXLAN)
5225 zlog_debug("%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
5226 zvrf_id(zvrf),
5227 prefix_mac2str(&macaddr,
5228 buf, sizeof(buf)),
5229 ipaddr2str(&ip, buf1,
5230 sizeof(buf1)), vni);
5231 continue;
5232 }
5233
5234 /* check if the remote MAC is unknown or has a change.
5235 * If so, that needs to be updated first. Note that client could
5236 * install MAC and MACIP separately or just install the latter.
5237 */
5238 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
5239 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
5240 != sticky
5241 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
5242 update_mac = 1;
5243
5244 if (update_mac) {
5245 if (!mac) {
5246 mac = zvni_mac_add(zvni, &macaddr);
5247 if (!mac) {
5248 zlog_warn(
5249 "Failed to add MAC %s VNI %u Remote VTEP %s",
5250 prefix_mac2str(&macaddr, buf,
5251 sizeof(buf)),
5252 vni, inet_ntoa(vtep_ip));
5253 return -1;
5254 }
5255
5256 /* Is this MAC created for a MACIP? */
5257 if (ipa_len)
5258 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5259 }
5260
5261 /* Set "auto" and "remote" forwarding info. */
5262 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5263 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5264 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5265 mac->fwd_info.r_vtep_ip = vtep_ip;
5266
5267 if (sticky)
5268 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5269 else
5270 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5271
5272 zvni_process_neigh_on_remote_mac_add(zvni, mac);
5273
5274 /* Install the entry. */
5275 zvni_mac_install(zvni, mac);
5276 }
5277
5278 /* If there is no IP, continue - after clearing AUTO flag of
5279 * MAC. */
5280 if (!ipa_len) {
5281 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5282 continue;
5283 }
5284
5285 /* Check if the remote neighbor itself is unknown or has a
5286 * change.
5287 * If so, create or update and then install the entry.
5288 */
5289 n = zvni_neigh_lookup(zvni, &ip);
5290 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5291 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
5292 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
5293 update_neigh = 1;
5294
5295 if (update_neigh) {
5296 if (!n) {
5297 n = zvni_neigh_add(zvni, &ip, &macaddr);
5298 if (!n) {
5299 zlog_warn(
5300 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5301 ipaddr2str(&ip, buf1,
5302 sizeof(buf1)),
5303 prefix_mac2str(&macaddr, buf,
5304 sizeof(buf)),
5305 vni, inet_ntoa(vtep_ip));
5306 return -1;
5307 }
5308
5309 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
5310 != 0) {
5311 /* MAC change, update neigh list for old and new
5312 * mac */
5313 old_mac = zvni_mac_lookup(zvni, &n->emac);
5314 if (old_mac) {
5315 listnode_delete(old_mac->neigh_list, n);
5316 zvni_deref_ip2mac(zvni, old_mac, 1);
5317 }
5318 listnode_add_sort(mac->neigh_list, n);
5319 memcpy(&n->emac, &macaddr, ETH_ALEN);
5320 }
5321
5322 /* Set "remote" forwarding info. */
5323 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
5324 /* TODO: Handle MAC change. */
5325 n->r_vtep_ip = vtep_ip;
5326 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
5327
5328 /* Install the entry. */
5329 zvni_neigh_install(zvni, n);
5330 }
5331 }
5332
5333 stream_failure:
5334 return 0;
5335 }
5336
5337 /*
5338 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5339 * us, this must involve a multihoming scenario. Treat this as implicit delete
5340 * of any prior local MAC.
5341 */
5342 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
5343 struct interface *br_if,
5344 struct ethaddr *macaddr, vlanid_t vid)
5345 {
5346 struct zebra_if *zif;
5347 struct zebra_l2info_vxlan *vxl;
5348 vni_t vni;
5349 zebra_vni_t *zvni;
5350 zebra_mac_t *mac;
5351 char buf[ETHER_ADDR_STRLEN];
5352
5353 zif = ifp->info;
5354 assert(zif);
5355 vxl = &zif->l2info.vxl;
5356 vni = vxl->vni;
5357
5358 /* Check if EVPN is enabled. */
5359 if (!is_evpn_enabled())
5360 return 0;
5361
5362 /* Locate hash entry; it is expected to exist. */
5363 zvni = zvni_lookup(vni);
5364 if (!zvni)
5365 return 0;
5366
5367 /* If entry doesn't exist, nothing to do. */
5368 mac = zvni_mac_lookup(zvni, macaddr);
5369 if (!mac)
5370 return 0;
5371
5372 /* Is it a local entry? */
5373 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5374 return 0;
5375
5376 if (IS_ZEBRA_DEBUG_VXLAN)
5377 zlog_debug(
5378 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5379 prefix_mac2str(macaddr, buf, sizeof(buf)),
5380 ifp->name, ifp->ifindex, vni);
5381
5382 /* Remove MAC from BGP. */
5383 zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
5384
5385 /*
5386 * If there are no neigh associated with the mac delete the mac
5387 * else mark it as AUTO for forward reference
5388 */
5389 if (!listcount(mac->neigh_list)) {
5390 zvni_mac_del(zvni, mac);
5391 } else {
5392 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5393 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5394 }
5395
5396 return 0;
5397 }
5398
5399 /*
5400 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5401 * This can happen because the remote MAC entries are also added as "dynamic",
5402 * so the kernel can ageout the entry.
5403 */
5404 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
5405 struct interface *br_if,
5406 struct ethaddr *macaddr, vlanid_t vid)
5407 {
5408 struct zebra_if *zif = NULL;
5409 struct zebra_l2info_vxlan *vxl = NULL;
5410 vni_t vni;
5411 zebra_vni_t *zvni = NULL;
5412 zebra_l3vni_t *zl3vni = NULL;
5413 zebra_mac_t *mac = NULL;
5414 char buf[ETHER_ADDR_STRLEN];
5415
5416 zif = ifp->info;
5417 assert(zif);
5418 vxl = &zif->l2info.vxl;
5419 vni = vxl->vni;
5420
5421 /* Check if EVPN is enabled. */
5422 if (!is_evpn_enabled())
5423 return 0;
5424
5425 /* check if this is a remote RMAC and readd simillar to remote macs */
5426 zl3vni = zl3vni_lookup(vni);
5427 if (zl3vni)
5428 return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
5429
5430 /* Locate hash entry; it is expected to exist. */
5431 zvni = zvni_lookup(vni);
5432 if (!zvni)
5433 return 0;
5434
5435 /* If entry doesn't exist, nothing to do. */
5436 mac = zvni_mac_lookup(zvni, macaddr);
5437 if (!mac)
5438 return 0;
5439
5440 /* Is it a remote entry? */
5441 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
5442 return 0;
5443
5444 if (IS_ZEBRA_DEBUG_VXLAN)
5445 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5446 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5447 ifp->ifindex, vni);
5448
5449 zvni_mac_install(zvni, mac);
5450 return 0;
5451 }
5452
5453 /*
5454 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5455 */
5456 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
5457 struct ethaddr *macaddr, vlanid_t vid)
5458 {
5459 zebra_vni_t *zvni;
5460 zebra_mac_t *mac;
5461 char buf[ETHER_ADDR_STRLEN];
5462
5463 /* We are interested in MACs only on ports or (port, VLAN) that
5464 * map to a VNI.
5465 */
5466 zvni = zvni_map_vlan(ifp, br_if, vid);
5467 if (!zvni)
5468 return 0;
5469 if (!zvni->vxlan_if) {
5470 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5471 zvni->vni, zvni);
5472 return -1;
5473 }
5474
5475 if (IS_ZEBRA_DEBUG_VXLAN)
5476 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5477 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5478 ifp->ifindex, vid, zvni->vni);
5479
5480 /* If entry doesn't exist, nothing to do. */
5481 mac = zvni_mac_lookup(zvni, macaddr);
5482 if (!mac)
5483 return 0;
5484
5485 /* Is it a local entry? */
5486 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5487 return 0;
5488
5489 /* Remove MAC from BGP. */
5490 zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
5491
5492 /* Update all the neigh entries associated with this mac */
5493 zvni_process_neigh_on_local_mac_del(zvni, mac);
5494
5495 /*
5496 * If there are no neigh associated with the mac delete the mac
5497 * else mark it as AUTO for forward reference
5498 */
5499 if (!listcount(mac->neigh_list)) {
5500 zvni_mac_del(zvni, mac);
5501 } else {
5502 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5503 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5504 }
5505
5506 return 0;
5507 }
5508
5509 /*
5510 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5511 */
5512 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
5513 struct interface *br_if,
5514 struct ethaddr *macaddr, vlanid_t vid,
5515 u_char sticky)
5516 {
5517 zebra_vni_t *zvni;
5518 zebra_mac_t *mac;
5519 char buf[ETHER_ADDR_STRLEN];
5520 int add = 1;
5521 u_char mac_sticky;
5522
5523 /* We are interested in MACs only on ports or (port, VLAN) that
5524 * map to a VNI.
5525 */
5526 zvni = zvni_map_vlan(ifp, br_if, vid);
5527 if (!zvni) {
5528 if (IS_ZEBRA_DEBUG_VXLAN)
5529 zlog_debug(
5530 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5531 sticky ? "sticky " : "",
5532 prefix_mac2str(macaddr, buf, sizeof(buf)),
5533 ifp->name, ifp->ifindex, vid);
5534 return 0;
5535 }
5536
5537 if (!zvni->vxlan_if) {
5538 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5539 zvni->vni, zvni);
5540 return -1;
5541 }
5542
5543 if (IS_ZEBRA_DEBUG_VXLAN)
5544 zlog_debug(
5545 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5546 sticky ? "sticky " : "",
5547 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5548 ifp->ifindex, vid, zvni->vni);
5549
5550 /* If same entry already exists, nothing to do. */
5551 mac = zvni_mac_lookup(zvni, macaddr);
5552 if (mac) {
5553 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
5554 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
5555 ? 1
5556 : 0;
5557
5558
5559 /*
5560 * return if nothing has changed.
5561 * inform bgp if sticky flag has changed
5562 * update locally and do not inform bgp if local
5563 * parameters like interface has changed
5564 */
5565 if (mac_sticky == sticky
5566 && mac->fwd_info.local.ifindex == ifp->ifindex
5567 && mac->fwd_info.local.vid == vid) {
5568 if (IS_ZEBRA_DEBUG_VXLAN)
5569 zlog_debug(
5570 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5571 "entry exists and has not changed ",
5572 sticky ? "sticky " : "",
5573 prefix_mac2str(macaddr, buf,
5574 sizeof(buf)),
5575 ifp->name, ifp->ifindex, vid,
5576 zvni->vni);
5577 return 0;
5578 } else if (mac_sticky != sticky) {
5579 add = 1;
5580 } else {
5581 add = 0; /* This is an update of local
5582 interface. */
5583 }
5584 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5585 /*
5586 * If we have already learned the MAC as a remote sticky
5587 * MAC,
5588 * this is a operator error and we must log a warning
5589 */
5590 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
5591 zlog_warn(
5592 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5593 prefix_mac2str(macaddr, buf,
5594 sizeof(buf)),
5595 inet_ntoa(mac->fwd_info.r_vtep_ip),
5596 zvni->vni);
5597 return 0;
5598 }
5599 }
5600 }
5601
5602 if (!mac) {
5603 mac = zvni_mac_add(zvni, macaddr);
5604 if (!mac) {
5605 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5606 prefix_mac2str(macaddr, buf, sizeof(buf)),
5607 ifp->name, ifp->ifindex, vid);
5608 return -1;
5609 }
5610 }
5611
5612 /* Set "local" forwarding info. */
5613 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5614 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5615 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5616 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5617 mac->fwd_info.local.ifindex = ifp->ifindex;
5618 mac->fwd_info.local.vid = vid;
5619
5620 if (sticky)
5621 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5622 else
5623 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5624
5625 /* Inform BGP if required. */
5626 if (add) {
5627 zvni_process_neigh_on_local_mac_add(zvni, mac);
5628 return zvni_mac_send_add_to_client(zvni->vni, macaddr,
5629 mac->flags);
5630 }
5631
5632 return 0;
5633 }
5634
5635 /*
5636 * Handle message from client to delete a remote VTEP for a VNI.
5637 */
5638 int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
5639 struct zebra_vrf *zvrf)
5640 {
5641 struct stream *s;
5642 u_short l = 0;
5643 vni_t vni;
5644 struct in_addr vtep_ip;
5645 zebra_vni_t *zvni;
5646 zebra_vtep_t *zvtep;
5647 struct interface *ifp;
5648 struct zebra_if *zif;
5649
5650 if (!is_evpn_enabled()) {
5651 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5652 __PRETTY_FUNCTION__);
5653 return -1;
5654 }
5655
5656 if (zvrf_id(zvrf) != VRF_DEFAULT) {
5657 zlog_err("Recv MACIP DEL for non-default VRF %u",
5658 zvrf_id(zvrf));
5659 return -1;
5660 }
5661
5662 s = client->ibuf;
5663
5664 while (l < length) {
5665 /* Obtain each remote VTEP and process. */
5666 STREAM_GETL(s, vni);
5667 l += 4;
5668 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
5669 l += IPV4_MAX_BYTELEN;
5670
5671 if (IS_ZEBRA_DEBUG_VXLAN)
5672 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5673 inet_ntoa(vtep_ip), vni,
5674 zebra_route_string(client->proto));
5675
5676 /* Locate VNI hash entry - expected to exist. */
5677 zvni = zvni_lookup(vni);
5678 if (!zvni) {
5679 if (IS_ZEBRA_DEBUG_VXLAN)
5680 zlog_debug(
5681 "Failed to locate VNI hash upon remote VTEP DEL, "
5682 "VNI %u",
5683 vni);
5684 continue;
5685 }
5686
5687 ifp = zvni->vxlan_if;
5688 if (!ifp) {
5689 zlog_err(
5690 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5691 zvni->vni, zvni);
5692 continue;
5693 }
5694 zif = ifp->info;
5695
5696 /* If down or not mapped to a bridge, we're done. */
5697 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5698 continue;
5699
5700 /* If the remote VTEP does not exist, there's nothing more to
5701 * do.
5702 * Otherwise, uninstall any remote MACs pointing to this VTEP
5703 * and
5704 * then, the VTEP entry itself and remove it.
5705 */
5706 zvtep = zvni_vtep_find(zvni, &vtep_ip);
5707 if (!zvtep)
5708 continue;
5709
5710 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
5711 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
5712 zvni_vtep_uninstall(zvni, &vtep_ip);
5713 zvni_vtep_del(zvni, zvtep);
5714 }
5715
5716 stream_failure:
5717 return 0;
5718 }
5719
5720 /*
5721 * Handle message from client to add a remote VTEP for a VNI.
5722 */
5723 int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
5724 struct zebra_vrf *zvrf)
5725 {
5726 struct stream *s;
5727 u_short l = 0;
5728 vni_t vni;
5729 struct in_addr vtep_ip;
5730 zebra_vni_t *zvni;
5731 struct interface *ifp;
5732 struct zebra_if *zif;
5733
5734 if (!is_evpn_enabled()) {
5735 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5736 __PRETTY_FUNCTION__);
5737 return -1;
5738 }
5739
5740 if (zvrf_id(zvrf) != VRF_DEFAULT) {
5741 zlog_err("Recv MACIP ADD for non-default VRF %u",
5742 zvrf_id(zvrf));
5743 return -1;
5744 }
5745
5746 s = client->ibuf;
5747
5748 while (l < length) {
5749 /* Obtain each remote VTEP and process. */
5750 STREAM_GETL(s, vni);
5751 l += 4;
5752 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
5753 l += IPV4_MAX_BYTELEN;
5754
5755 if (IS_ZEBRA_DEBUG_VXLAN)
5756 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5757 inet_ntoa(vtep_ip), vni,
5758 zebra_route_string(client->proto));
5759
5760 /* Locate VNI hash entry - expected to exist. */
5761 zvni = zvni_lookup(vni);
5762 if (!zvni) {
5763 zlog_err(
5764 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5765 vni);
5766 continue;
5767 }
5768
5769 ifp = zvni->vxlan_if;
5770 if (!ifp) {
5771 zlog_err(
5772 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5773 zvni->vni, zvni);
5774 continue;
5775 }
5776
5777 zif = ifp->info;
5778
5779 /* If down or not mapped to a bridge, we're done. */
5780 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5781 continue;
5782
5783 /* If the remote VTEP already exists,
5784 there's nothing more to do. */
5785 if (zvni_vtep_find(zvni, &vtep_ip))
5786 continue;
5787
5788 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
5789 zlog_err(
5790 "Failed to add remote VTEP, VNI %u zvni %p",
5791 vni, zvni);
5792 continue;
5793 }
5794
5795 zvni_vtep_install(zvni, &vtep_ip);
5796 }
5797
5798 stream_failure:
5799 return 0;
5800 }
5801
5802 /*
5803 * Add/Del gateway macip to evpn
5804 * g/w can be:
5805 * 1. SVI interface on a vlan aware bridge
5806 * 2. SVI interface on a vlan unaware bridge
5807 * 3. vrr interface (MACVLAN) associated to a SVI
5808 * We advertise macip routes for an interface if it is associated to VxLan vlan
5809 */
5810 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
5811 int add)
5812 {
5813 struct ipaddr ip;
5814 struct ethaddr macaddr;
5815 zebra_vni_t *zvni = NULL;
5816
5817 memset(&ip, 0, sizeof(struct ipaddr));
5818 memset(&macaddr, 0, sizeof(struct ethaddr));
5819
5820 /* Check if EVPN is enabled. */
5821 if (!is_evpn_enabled())
5822 return 0;
5823
5824 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
5825 struct interface *svi_if =
5826 NULL; /* SVI corresponding to the MACVLAN */
5827 struct zebra_if *ifp_zif =
5828 NULL; /* Zebra daemon specific info for MACVLAN */
5829 struct zebra_if *svi_if_zif =
5830 NULL; /* Zebra daemon specific info for SVI*/
5831
5832 ifp_zif = ifp->info;
5833 if (!ifp_zif)
5834 return -1;
5835
5836 /*
5837 * for a MACVLAN interface the link represents the svi_if
5838 */
5839 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
5840 ifp_zif->link_ifindex);
5841 if (!svi_if) {
5842 zlog_err("MACVLAN %s(%u) without link information",
5843 ifp->name, ifp->ifindex);
5844 return -1;
5845 }
5846
5847 if (IS_ZEBRA_IF_VLAN(svi_if)) {
5848 /*
5849 * If it is a vlan aware bridge then the link gives the
5850 * bridge information
5851 */
5852 struct interface *svi_if_link = NULL;
5853
5854 svi_if_zif = svi_if->info;
5855 if (svi_if_zif) {
5856 svi_if_link = if_lookup_by_index_per_ns(
5857 zebra_ns_lookup(NS_DEFAULT),
5858 svi_if_zif->link_ifindex);
5859 zvni = zvni_from_svi(svi_if, svi_if_link);
5860 }
5861 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
5862 /*
5863 * If it is a vlan unaware bridge then svi is the bridge
5864 * itself
5865 */
5866 zvni = zvni_from_svi(svi_if, svi_if);
5867 }
5868 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
5869 struct zebra_if *svi_if_zif =
5870 NULL; /* Zebra daemon specific info for SVI */
5871 struct interface *svi_if_link =
5872 NULL; /* link info for the SVI = bridge info */
5873
5874 svi_if_zif = ifp->info;
5875 svi_if_link = if_lookup_by_index_per_ns(
5876 zebra_ns_lookup(NS_DEFAULT), svi_if_zif->link_ifindex);
5877 if (svi_if_zif && svi_if_link)
5878 zvni = zvni_from_svi(ifp, svi_if_link);
5879 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
5880 zvni = zvni_from_svi(ifp, ifp);
5881 }
5882
5883 if (!zvni)
5884 return 0;
5885
5886 if (!zvni->vxlan_if) {
5887 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5888 zvni->vni, zvni);
5889 return -1;
5890 }
5891
5892
5893 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
5894
5895 if (p->family == AF_INET) {
5896 ip.ipa_type = IPADDR_V4;
5897 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
5898 sizeof(struct in_addr));
5899 } else if (p->family == AF_INET6) {
5900 ip.ipa_type = IPADDR_V6;
5901 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
5902 sizeof(struct in6_addr));
5903 }
5904
5905
5906 if (add)
5907 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
5908 else
5909 zvni_gw_macip_del(ifp, zvni, &ip);
5910
5911 return 0;
5912 }
5913
5914 /*
5915 * Handle SVI interface going down.
5916 * SVI can be associated to either L3-VNI or L2-VNI.
5917 * For L2-VNI: At this point, this is a NOP since
5918 * the kernel deletes the neighbor entries on this SVI (if any).
5919 * We only need to update the vrf corresponding to zvni.
5920 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5921 * from bgp
5922 */
5923 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
5924 {
5925 zebra_l3vni_t *zl3vni = NULL;
5926
5927 zl3vni = zl3vni_from_svi(ifp, link_if);
5928 if (zl3vni) {
5929
5930 /* process l3-vni down */
5931 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5932
5933 /* remove association with svi-if */
5934 zl3vni->svi_if = NULL;
5935 } else {
5936 zebra_vni_t *zvni = NULL;
5937
5938 /* since we dont have svi corresponding to zvni, we associate it
5939 * to default vrf. Note: the corresponding neigh entries on the
5940 * SVI would have already been deleted */
5941 zvni = zvni_from_svi(ifp, link_if);
5942 if (zvni) {
5943 zvni->vrf_id = VRF_DEFAULT;
5944
5945 /* update the tenant vrf in BGP */
5946 zvni_send_add_to_client(zvni);
5947 }
5948 }
5949 return 0;
5950 }
5951
5952 /*
5953 * Handle SVI interface coming up.
5954 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5955 * vxlan intf).
5956 * For L2-VNI: we need to install any remote neighbors entried (used for
5957 * apr-suppression)
5958 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5959 */
5960 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
5961 {
5962 zebra_vni_t *zvni = NULL;
5963 zebra_l3vni_t *zl3vni = NULL;
5964
5965 zl3vni = zl3vni_from_svi(ifp, link_if);
5966 if (zl3vni) {
5967
5968 /* associate with svi */
5969 zl3vni->svi_if = ifp;
5970
5971 /* process oper-up */
5972 if (is_l3vni_oper_up(zl3vni))
5973 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5974 } else {
5975
5976 /* process SVI up for l2-vni */
5977 struct neigh_walk_ctx n_wctx;
5978
5979 zvni = zvni_from_svi(ifp, link_if);
5980 if (!zvni)
5981 return 0;
5982
5983 if (!zvni->vxlan_if) {
5984 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5985 zvni->vni, zvni);
5986 return -1;
5987 }
5988
5989 if (IS_ZEBRA_DEBUG_VXLAN)
5990 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5991 ifp->name, ifp->ifindex, zvni->vni,
5992 vrf_id_to_name(ifp->vrf_id));
5993
5994 /* update the vrf information for l2-vni and inform bgp */
5995 zvni->vrf_id = ifp->vrf_id;
5996 zvni_send_add_to_client(zvni);
5997
5998 /* Install any remote neighbors for this VNI. */
5999 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6000 n_wctx.zvni = zvni;
6001 hash_iterate(zvni->neigh_table,
6002 zvni_install_neigh_hash,
6003 &n_wctx);
6004 }
6005
6006 return 0;
6007 }
6008
6009 /*
6010 * Handle VxLAN interface down
6011 */
6012 int zebra_vxlan_if_down(struct interface *ifp)
6013 {
6014 vni_t vni;
6015 struct zebra_if *zif = NULL;
6016 struct zebra_l2info_vxlan *vxl = NULL;
6017 zebra_l3vni_t *zl3vni = NULL;
6018 zebra_vni_t *zvni;
6019
6020 /* Check if EVPN is enabled. */
6021 if (!is_evpn_enabled())
6022 return 0;
6023
6024 zif = ifp->info;
6025 assert(zif);
6026 vxl = &zif->l2info.vxl;
6027 vni = vxl->vni;
6028
6029 zl3vni = zl3vni_lookup(vni);
6030 if (zl3vni) {
6031 /* process-if-down for l3-vni */
6032 if (IS_ZEBRA_DEBUG_VXLAN)
6033 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
6034 ifp->name, ifp->ifindex, vni);
6035
6036 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6037 } else {
6038 /* process if-down for l2-vni */
6039 if (IS_ZEBRA_DEBUG_VXLAN)
6040 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
6041 ifp->name, ifp->ifindex, vni);
6042
6043 /* Locate hash entry; it is expected to exist. */
6044 zvni = zvni_lookup(vni);
6045 if (!zvni) {
6046 zlog_err(
6047 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6048 ifp->name, ifp->ifindex, vni);
6049 return -1;
6050 }
6051
6052 assert(zvni->vxlan_if == ifp);
6053
6054 /* Delete this VNI from BGP. */
6055 zvni_send_del_to_client(zvni->vni);
6056
6057 /* Free up all neighbors and MACs, if any. */
6058 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
6059 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
6060
6061 /* Free up all remote VTEPs, if any. */
6062 zvni_vtep_del_all(zvni, 1);
6063 }
6064 return 0;
6065 }
6066
6067 /*
6068 * Handle VxLAN interface up - update BGP if required.
6069 */
6070 int zebra_vxlan_if_up(struct interface *ifp)
6071 {
6072 vni_t vni;
6073 struct zebra_if *zif = NULL;
6074 struct zebra_l2info_vxlan *vxl = NULL;
6075 zebra_vni_t *zvni = NULL;
6076 zebra_l3vni_t *zl3vni = NULL;
6077
6078 /* Check if EVPN is enabled. */
6079 if (!is_evpn_enabled())
6080 return 0;
6081
6082 zif = ifp->info;
6083 assert(zif);
6084 vxl = &zif->l2info.vxl;
6085 vni = vxl->vni;
6086
6087 zl3vni = zl3vni_lookup(vni);
6088 if (zl3vni) {
6089
6090 if (IS_ZEBRA_DEBUG_VXLAN)
6091 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
6092 ifp->name, ifp->ifindex, vni);
6093
6094 /* we need to associate with SVI, if any, we can associate with
6095 * svi-if only after association with vxlan-intf is complete
6096 */
6097 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6098
6099 if (is_l3vni_oper_up(zl3vni))
6100 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6101 } else {
6102 /* Handle L2-VNI add */
6103 struct interface *vlan_if = NULL;
6104
6105 if (IS_ZEBRA_DEBUG_VXLAN)
6106 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
6107 ifp->name, ifp->ifindex, vni);
6108
6109 /* Locate hash entry; it is expected to exist. */
6110 zvni = zvni_lookup(vni);
6111 if (!zvni) {
6112 zlog_err(
6113 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6114 ifp->name, ifp->ifindex, vni);
6115 return -1;
6116 }
6117
6118 assert(zvni->vxlan_if == ifp);
6119 vlan_if = zvni_map_to_svi(vxl->access_vlan,
6120 zif->brslave_info.br_if);
6121 if (vlan_if) {
6122 zvni->vrf_id = vlan_if->vrf_id;
6123 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
6124 if (zl3vni)
6125 listnode_add_sort(zl3vni->l2vnis, zvni);
6126 }
6127
6128 /* If part of a bridge, inform BGP about this VNI. */
6129 /* Also, read and populate local MACs and neighbors. */
6130 if (zif->brslave_info.br_if) {
6131 zvni_send_add_to_client(zvni);
6132 zvni_read_mac_neigh(zvni, ifp);
6133 }
6134 }
6135
6136 return 0;
6137 }
6138
6139 /*
6140 * Handle VxLAN interface delete. Locate and remove entry in hash table
6141 * and update BGP, if required.
6142 */
6143 int zebra_vxlan_if_del(struct interface *ifp)
6144 {
6145 vni_t vni;
6146 struct zebra_if *zif = NULL;
6147 struct zebra_l2info_vxlan *vxl = NULL;
6148 zebra_vni_t *zvni = NULL;
6149 zebra_l3vni_t *zl3vni = NULL;
6150
6151 /* Check if EVPN is enabled. */
6152 if (!is_evpn_enabled())
6153 return 0;
6154
6155 zif = ifp->info;
6156 assert(zif);
6157 vxl = &zif->l2info.vxl;
6158 vni = vxl->vni;
6159
6160 zl3vni = zl3vni_lookup(vni);
6161 if (zl3vni) {
6162
6163 if (IS_ZEBRA_DEBUG_VXLAN)
6164 zlog_debug("Del L3-VNI %u intf %s(%u)",
6165 vni, ifp->name, ifp->ifindex);
6166
6167 /* process oper-down for l3-vni */
6168 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6169
6170 /* remove the association with vxlan_if */
6171 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
6172 zl3vni->vxlan_if = NULL;
6173 } else {
6174
6175 /* process if-del for l2-vni*/
6176 if (IS_ZEBRA_DEBUG_VXLAN)
6177 zlog_debug("Del L2-VNI %u intf %s(%u)",
6178 vni, ifp->name, ifp->ifindex);
6179
6180 /* Locate hash entry; it is expected to exist. */
6181 zvni = zvni_lookup(vni);
6182 if (!zvni) {
6183 zlog_err(
6184 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6185 ifp->name, ifp->ifindex, vni);
6186 return 0;
6187 }
6188
6189 /* remove from l3-vni list */
6190 zl3vni = zl3vni_from_vrf(zvni->vrf_id);
6191 if (zl3vni)
6192 listnode_delete(zl3vni->l2vnis, zvni);
6193
6194 /* Delete VNI from BGP. */
6195 zvni_send_del_to_client(zvni->vni);
6196
6197 /* Free up all neighbors and MAC, if any. */
6198 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
6199 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
6200
6201 /* Free up all remote VTEPs, if any. */
6202 zvni_vtep_del_all(zvni, 0);
6203
6204 /* Delete the hash entry. */
6205 if (zvni_del(zvni)) {
6206 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6207 zvni, ifp->name, ifp->ifindex, zvni->vni);
6208 return -1;
6209 }
6210 }
6211 return 0;
6212 }
6213
6214 /*
6215 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6216 */
6217 int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
6218 {
6219 vni_t vni;
6220 struct zebra_if *zif = NULL;
6221 struct zebra_l2info_vxlan *vxl = NULL;
6222 zebra_vni_t *zvni = NULL;
6223 zebra_l3vni_t *zl3vni = NULL;
6224
6225 /* Check if EVPN is enabled. */
6226 if (!is_evpn_enabled())
6227 return 0;
6228
6229 zif = ifp->info;
6230 assert(zif);
6231 vxl = &zif->l2info.vxl;
6232 vni = vxl->vni;
6233
6234 zl3vni = zl3vni_lookup(vni);
6235 if (zl3vni) {
6236
6237 if (IS_ZEBRA_DEBUG_VXLAN)
6238 zlog_debug(
6239 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6240 vni, ifp->name, ifp->ifindex,
6241 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6242 zif->brslave_info.bridge_ifindex, chgflags);
6243
6244 /* Removed from bridge? Cleanup and return */
6245 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6246 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
6247 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6248 return 0;
6249 }
6250
6251 /* access-vlan change - process oper down, associate with new
6252 * svi_if and then process oper up again
6253 */
6254 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6255 if (if_is_operative(ifp)) {
6256 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6257 zl3vni->svi_if = NULL;
6258 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6259 if (is_l3vni_oper_up(zl3vni))
6260 zebra_vxlan_process_l3vni_oper_up(
6261 zl3vni);
6262 }
6263 }
6264
6265 /* if we have a valid new master, process l3-vni oper up */
6266 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
6267 if (is_l3vni_oper_up(zl3vni))
6268 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6269 }
6270 } else {
6271
6272 /* Update VNI hash. */
6273 zvni = zvni_lookup(vni);
6274 if (!zvni) {
6275 zlog_err(
6276 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6277 ifp->name, ifp->ifindex, vni);
6278 return -1;
6279 }
6280
6281 if (IS_ZEBRA_DEBUG_VXLAN)
6282 zlog_debug(
6283 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6284 vni, ifp->name, ifp->ifindex,
6285 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6286 zif->brslave_info.bridge_ifindex, chgflags);
6287
6288 /* Removed from bridge? Cleanup and return */
6289 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6290 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
6291 /* Delete from client, remove all remote VTEPs */
6292 /* Also, free up all MACs and neighbors. */
6293 zvni_send_del_to_client(zvni->vni);
6294 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
6295 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
6296 zvni_vtep_del_all(zvni, 1);
6297 return 0;
6298 }
6299
6300 /* Handle other changes. */
6301 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6302 /* Remove all existing local neigh and MACs for this VNI
6303 * (including from BGP)
6304 */
6305 zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
6306 zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
6307 }
6308
6309 zvni->local_vtep_ip = vxl->vtep_ip;
6310 zvni->vxlan_if = ifp;
6311
6312 /* Take further actions needed.
6313 * Note that if we are here, there is a change of interest.
6314 */
6315 /* If down or not mapped to a bridge, we're done. */
6316 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6317 return 0;
6318
6319 /* Inform BGP, if there is a change of interest. */
6320 if (chgflags
6321 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
6322 zvni_send_add_to_client(zvni);
6323
6324 /* If there is a valid new master or a VLAN mapping change,
6325 * read and populate local MACs and neighbors.
6326 * Also, reinstall any remote MACs and neighbors
6327 * for this VNI (based on new VLAN).
6328 */
6329 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6330 zvni_read_mac_neigh(zvni, ifp);
6331 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6332 struct mac_walk_ctx m_wctx;
6333 struct neigh_walk_ctx n_wctx;
6334
6335 zvni_read_mac_neigh(zvni, ifp);
6336
6337 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6338 m_wctx.zvni = zvni;
6339 hash_iterate(zvni->mac_table,
6340 zvni_install_mac_hash,
6341 &m_wctx);
6342
6343 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6344 n_wctx.zvni = zvni;
6345 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
6346 &n_wctx);
6347 }
6348 }
6349
6350 return 0;
6351 }
6352
6353 /*
6354 * Handle VxLAN interface add.
6355 */
6356 int zebra_vxlan_if_add(struct interface *ifp)
6357 {
6358 vni_t vni;
6359 struct zebra_if *zif = NULL;
6360 struct zebra_l2info_vxlan *vxl = NULL;
6361 zebra_vni_t *zvni = NULL;
6362 zebra_l3vni_t *zl3vni = NULL;
6363
6364 /* Check if EVPN is enabled. */
6365 if (!is_evpn_enabled())
6366 return 0;
6367
6368 zif = ifp->info;
6369 assert(zif);
6370 vxl = &zif->l2info.vxl;
6371 vni = vxl->vni;
6372
6373 zl3vni = zl3vni_lookup(vni);
6374 if (zl3vni) {
6375
6376 /* process if-add for l3-vni*/
6377 if (IS_ZEBRA_DEBUG_VXLAN)
6378 zlog_debug(
6379 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6380 vni, ifp->name, ifp->ifindex,
6381 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6382 zif->brslave_info.bridge_ifindex);
6383
6384 /* associate with vxlan_if */
6385 zl3vni->local_vtep_ip = vxl->vtep_ip;
6386 zl3vni->vxlan_if = ifp;
6387
6388 /* Associate with SVI, if any. We can associate with svi-if only
6389 * after association with vxlan_if is complete */
6390 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6391
6392 if (is_l3vni_oper_up(zl3vni))
6393 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6394 } else {
6395
6396 /* process if-add for l2-vni */
6397 struct interface *vlan_if = NULL;
6398
6399 /* Create or update VNI hash. */
6400 zvni = zvni_lookup(vni);
6401 if (!zvni) {
6402 zvni = zvni_add(vni);
6403 if (!zvni) {
6404 zlog_err(
6405 "Failed to add VNI hash, IF %s(%u) VNI %u",
6406 ifp->name, ifp->ifindex, vni);
6407 return -1;
6408 }
6409 }
6410
6411 zvni->local_vtep_ip = vxl->vtep_ip;
6412 zvni->vxlan_if = ifp;
6413 vlan_if = zvni_map_to_svi(vxl->access_vlan,
6414 zif->brslave_info.br_if);
6415 if (vlan_if) {
6416 zvni->vrf_id = vlan_if->vrf_id;
6417 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
6418 if (zl3vni)
6419 listnode_add_sort(zl3vni->l2vnis, zvni);
6420 }
6421
6422 if (IS_ZEBRA_DEBUG_VXLAN)
6423 zlog_debug(
6424 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6425 vni,
6426 vlan_if ? vrf_id_to_name(vlan_if->vrf_id) :
6427 "Default",
6428 ifp->name, ifp->ifindex,
6429 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6430 zif->brslave_info.bridge_ifindex);
6431
6432 /* If down or not mapped to a bridge, we're done. */
6433 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6434 return 0;
6435
6436 /* Inform BGP */
6437 zvni_send_add_to_client(zvni);
6438
6439 /* Read and populate local MACs and neighbors */
6440 zvni_read_mac_neigh(zvni, ifp);
6441 }
6442
6443 return 0;
6444 }
6445
6446 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf,
6447 vni_t vni,
6448 char *err, int err_str_sz,
6449 int filter, int add)
6450 {
6451 zebra_l3vni_t *zl3vni = NULL;
6452 struct zebra_vrf *zvrf_default = NULL;
6453
6454 zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT);
6455 if (!zvrf_default)
6456 return -1;
6457
6458 if (IS_ZEBRA_DEBUG_VXLAN)
6459 zlog_debug("vrf %s vni %u %s",
6460 zvrf_name(zvrf),
6461 vni,
6462 add ? "ADD" : "DEL");
6463
6464 if (add) {
6465
6466 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
6467
6468 /* check if the vni is already present under zvrf */
6469 if (zvrf->l3vni) {
6470 snprintf(err, err_str_sz,
6471 "VNI is already configured under the vrf");
6472 return -1;
6473 }
6474
6475 /* check if this VNI is already present in the system */
6476 zl3vni = zl3vni_lookup(vni);
6477 if (zl3vni) {
6478 snprintf(err, err_str_sz,
6479 "VNI is already configured as L3-VNI");
6480 return -1;
6481 }
6482
6483 /* add the L3-VNI to the global table */
6484 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
6485 if (!zl3vni) {
6486 snprintf(err, err_str_sz,
6487 "Could not add L3-VNI");
6488 return -1;
6489 }
6490
6491 /* associate the vrf with vni */
6492 zvrf->l3vni = vni;
6493
6494 /* set the filter in l3vni to denote if we are using l3vni only
6495 * for prefix routes
6496 */
6497 if (filter)
6498 SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
6499
6500 /* associate with vxlan-intf;
6501 * we need to associate with the vxlan-intf first
6502 */
6503 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
6504
6505 /* associate with corresponding SVI interface, we can associate
6506 * with svi-if only after vxlan interface association is
6507 * complete
6508 */
6509 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6510
6511 /* formulate l2vni list */
6512 hash_iterate(zvrf_default->vni_table,
6513 zvni_add_to_l3vni_list, zl3vni);
6514
6515 if (is_l3vni_oper_up(zl3vni))
6516 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6517
6518 } else {
6519 zl3vni = zl3vni_lookup(vni);
6520 if (!zl3vni) {
6521 snprintf(err, err_str_sz, "VNI doesn't exist");
6522 return -1;
6523 }
6524
6525 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6526
6527 /* delete and uninstall all rmacs */
6528 hash_iterate(zl3vni->rmac_table,
6529 zl3vni_del_rmac_hash_entry,
6530 zl3vni);
6531
6532 /* delete and uninstall all next-hops */
6533 hash_iterate(zl3vni->nh_table,
6534 zl3vni_del_nh_hash_entry,
6535 zl3vni);
6536
6537 zvrf->l3vni = 0;
6538 zl3vni_del(zl3vni);
6539
6540 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
6541 }
6542 return 0;
6543 }
6544
6545 int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
6546 {
6547 zebra_l3vni_t *zl3vni = NULL;
6548
6549 if (zvrf->l3vni)
6550 zl3vni = zl3vni_lookup(zvrf->l3vni);
6551 if (!zl3vni)
6552 return 0;
6553
6554 zl3vni->vrf_id = zvrf_id(zvrf);
6555 if (is_l3vni_oper_up(zl3vni))
6556 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6557 return 0;
6558 }
6559
6560 int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
6561 {
6562 zebra_l3vni_t *zl3vni = NULL;
6563
6564 if (zvrf->l3vni)
6565 zl3vni = zl3vni_lookup(zvrf->l3vni);
6566 if (!zl3vni)
6567 return 0;
6568
6569 zl3vni->vrf_id = VRF_UNKNOWN;
6570 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6571 return 0;
6572 }
6573
6574 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
6575 {
6576 zebra_l3vni_t *zl3vni = NULL;
6577 vni_t vni;
6578
6579 if (zvrf->l3vni)
6580 zl3vni = zl3vni_lookup(zvrf->l3vni);
6581 if (!zl3vni)
6582 return 0;
6583
6584 vni = zl3vni->vni;
6585 zl3vni_del(zl3vni);
6586 zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
6587
6588 return 0;
6589 }
6590
6591 /*
6592 * Handle message from client to enable/disable advertisement of g/w macip
6593 * routes
6594 */
6595 int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
6596 struct zebra_vrf *zvrf)
6597 {
6598 struct stream *s;
6599 int advertise;
6600 vni_t vni = 0;
6601 zebra_vni_t *zvni = NULL;
6602 struct interface *ifp = NULL;
6603 struct zebra_if *zif = NULL;
6604 struct zebra_l2info_vxlan zl2_info;
6605 struct interface *vlan_if = NULL;
6606
6607 if (zvrf_id(zvrf) != VRF_DEFAULT) {
6608 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6609 zvrf_id(zvrf));
6610 return -1;
6611 }
6612
6613 s = client->ibuf;
6614 advertise = stream_getc(s);
6615 vni = stream_get3(s);
6616
6617 zvni = zvni_lookup(vni);
6618 if (!zvni)
6619 return 0;
6620
6621 if (zvni->advertise_subnet == advertise)
6622 return 0;
6623
6624 if (IS_ZEBRA_DEBUG_VXLAN)
6625 zlog_debug(
6626 "EVPN subnet Adv %s on VNI %d , currently %s",
6627 advertise ? "enabled" : "disabled", vni,
6628 zvni->advertise_subnet ? "enabled" : "disabled");
6629
6630
6631 zvni->advertise_subnet = advertise;
6632
6633 ifp = zvni->vxlan_if;
6634 if (!ifp)
6635 return 0;
6636
6637 zif = ifp->info;
6638
6639 /* If down or not mapped to a bridge, we're done. */
6640 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6641 return 0;
6642
6643 zl2_info = zif->l2info.vxl;
6644
6645 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
6646 zif->brslave_info.br_if);
6647 if (!vlan_if)
6648 return 0;
6649
6650 if (zvni->advertise_subnet)
6651 zvni_advertise_subnet(zvni, vlan_if, 1);
6652 else
6653 zvni_advertise_subnet(zvni, vlan_if, 0);
6654
6655 return 0;
6656 }
6657
6658 /*
6659 * Handle message from client to enable/disable advertisement of g/w macip
6660 * routes
6661 */
6662 int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
6663 struct zebra_vrf *zvrf)
6664 {
6665 struct stream *s;
6666 int advertise;
6667 vni_t vni = 0;
6668 zebra_vni_t *zvni = NULL;
6669 struct interface *ifp = NULL;
6670
6671 if (zvrf_id(zvrf) != VRF_DEFAULT) {
6672 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6673 zvrf_id(zvrf));
6674 return -1;
6675 }
6676
6677 s = client->ibuf;
6678 STREAM_GETC(s, advertise);
6679 STREAM_GET(&vni, s, 3);
6680
6681 if (!vni) {
6682 if (IS_ZEBRA_DEBUG_VXLAN)
6683 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6684 advertise ? "enabled" : "disabled",
6685 advertise_gw_macip_enabled(NULL)
6686 ? "enabled"
6687 : "disabled");
6688
6689 if (zvrf->advertise_gw_macip == advertise)
6690 return 0;
6691
6692 zvrf->advertise_gw_macip = advertise;
6693
6694 if (advertise_gw_macip_enabled(zvni))
6695 hash_iterate(zvrf->vni_table,
6696 zvni_gw_macip_add_for_vni_hash, NULL);
6697 else
6698 hash_iterate(zvrf->vni_table,
6699 zvni_gw_macip_del_for_vni_hash, NULL);
6700
6701 } else {
6702 struct zebra_if *zif = NULL;
6703 struct zebra_l2info_vxlan zl2_info;
6704 struct interface *vlan_if = NULL;
6705 struct interface *vrr_if = NULL;
6706
6707 if (IS_ZEBRA_DEBUG_VXLAN)
6708 zlog_debug(
6709 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6710 advertise ? "enabled" : "disabled", vni,
6711 advertise_gw_macip_enabled(zvni)
6712 ? "enabled"
6713 : "disabled");
6714
6715 zvni = zvni_lookup(vni);
6716 if (!zvni)
6717 return 0;
6718
6719 if (zvni->advertise_gw_macip == advertise)
6720 return 0;
6721
6722 zvni->advertise_gw_macip = advertise;
6723
6724 ifp = zvni->vxlan_if;
6725 if (!ifp)
6726 return 0;
6727
6728 zif = ifp->info;
6729
6730 /* If down or not mapped to a bridge, we're done. */
6731 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6732 return 0;
6733
6734 zl2_info = zif->l2info.vxl;
6735
6736 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
6737 zif->brslave_info.br_if);
6738 if (!vlan_if)
6739 return 0;
6740
6741 if (advertise_gw_macip_enabled(zvni)) {
6742 /* Add primary SVI MAC-IP */
6743 zvni_add_macip_for_intf(vlan_if, zvni);
6744
6745 /* Add VRR MAC-IP - if any*/
6746 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
6747 if (vrr_if)
6748 zvni_add_macip_for_intf(vrr_if, zvni);
6749 } else {
6750 /* Del primary MAC-IP */
6751 zvni_del_macip_for_intf(vlan_if, zvni);
6752
6753 /* Del VRR MAC-IP - if any*/
6754 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
6755 if (vrr_if)
6756 zvni_del_macip_for_intf(vrr_if, zvni);
6757 }
6758 }
6759
6760 stream_failure:
6761 return 0;
6762 }
6763
6764
6765 /*
6766 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6767 * When enabled, the VNI hash table will be built and MAC FDB table read;
6768 * when disabled, the entries should be deleted and remote VTEPs and MACs
6769 * uninstalled from the kernel.
6770 */
6771 int zebra_vxlan_advertise_all_vni(struct zserv *client,
6772 u_short length, struct zebra_vrf *zvrf)
6773 {
6774 struct stream *s = NULL;
6775 int advertise = 0;
6776 struct zebra_ns *zns = NULL;
6777
6778 if (zvrf_id(zvrf) != VRF_DEFAULT) {
6779 zlog_err("EVPN VNI Adv for non-default VRF %u",
6780 zvrf_id(zvrf));
6781 return -1;
6782 }
6783
6784 s = client->ibuf;
6785 STREAM_GETC(s, advertise);
6786
6787 if (IS_ZEBRA_DEBUG_VXLAN)
6788 zlog_debug("EVPN VNI Adv %s, currently %s",
6789 advertise ? "enabled" : "disabled",
6790 is_evpn_enabled() ? "enabled" : "disabled");
6791
6792 if (zvrf->advertise_all_vni == advertise)
6793 return 0;
6794
6795 zvrf->advertise_all_vni = advertise;
6796 if (is_evpn_enabled()) {
6797 /* Build VNI hash table and inform BGP. */
6798 zvni_build_hash_table();
6799
6800 /* Add all SVI (L3 GW) MACs to BGP*/
6801 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
6802 NULL);
6803
6804 /* Read the MAC FDB */
6805 macfdb_read(zvrf->zns);
6806
6807 /* Read neighbors */
6808 neigh_read(zvrf->zns);
6809 } else {
6810 /* Cleanup VTEPs for all VNIs - uninstall from
6811 * kernel and free entries.
6812 */
6813 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
6814
6815 /* cleanup all l3vnis */
6816 zns = zebra_ns_lookup(NS_DEFAULT);
6817 if (!zns)
6818 return -1;
6819
6820 hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL);
6821 }
6822
6823 stream_failure:
6824 return 0;
6825 }
6826
6827 /*
6828 * Allocate VNI hash table for this VRF and do other initialization.
6829 * NOTE: Currently supported only for default VRF.
6830 */
6831 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
6832 {
6833 if (!zvrf)
6834 return;
6835 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
6836 "Zebra VRF VNI Table");
6837 }
6838
6839 /* Cleanup VNI info, but don't free the table. */
6840 void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
6841 {
6842 if (!zvrf)
6843 return;
6844 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
6845 }
6846
6847 /* Close all VNI handling */
6848 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
6849 {
6850 if (!zvrf)
6851 return;
6852 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
6853 hash_free(zvrf->vni_table);
6854 }
6855
6856 /* init the l3vni table */
6857 void zebra_vxlan_ns_init(struct zebra_ns *zns)
6858 {
6859 zns->l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
6860 "Zebra VRF L3 VNI table");
6861 }
6862
6863 /* free l3vni table */
6864 void zebra_vxlan_ns_disable(struct zebra_ns *zns)
6865 {
6866 hash_free(zns->l3vni_table);
6867 }
6868
6869 /* get the l3vni svi ifindex */
6870 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
6871 {
6872 zebra_l3vni_t *zl3vni = NULL;
6873
6874 zl3vni = zl3vni_from_vrf(vrf_id);
6875 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
6876 return 0;
6877
6878 return zl3vni->svi_if->ifindex;
6879 }