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