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