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