2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
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
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.
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
37 #include "zebra/rib.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
51 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
54 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
55 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
60 /* static function declarations */
61 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
62 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
63 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
65 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
66 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
67 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
68 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
69 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
71 static int zvni_macip_send_msg_to_client(vni_t vni
,
72 struct ethaddr
*macaddr
,
73 struct ipaddr
*ip
, u_char flags
,
75 static unsigned int neigh_hash_keymake(void *p
);
76 static int neigh_cmp(const void *p1
, const void *p2
);
77 static void *zvni_neigh_alloc(void *p
);
78 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
80 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
81 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
82 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
83 struct in_addr
*r_vtep_ip
);
84 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
85 int uninstall
, int upd_client
, u_int32_t flags
);
86 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
87 static int zvni_neigh_send_add_to_client(vni_t vni
,
89 struct ethaddr
*macaddr
, u_char flags
);
90 static int zvni_neigh_send_del_to_client(vni_t vni
,
92 struct ethaddr
*macaddr
, u_char flags
);
93 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
94 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
95 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
96 struct interface
*br_if
);
97 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
98 struct interface
*br_if
);
100 /* l3-vni next-hop neigh related APIs */
101 /*static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
103 static void *zl3vni_nh_alloc(void *p);
104 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
105 struct ipaddr *vtep_ip,
106 struct ethaddr *rmac);
107 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
108 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
109 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);*/
111 /* l3-vni rmac related APIs */
112 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
113 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*, void *);
114 /*static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
115 struct ethaddr *rmac);
116 static void *zl3vni_rmac_alloc(void *p);
117 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
118 struct ethaddr *rmac);
119 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
120 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
121 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
122 zebra_mac_t *zrmac);*/
124 /* l3-vni related APIs*/
125 static int is_vni_l3(vni_t
);
126 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
127 static void *zl3vni_alloc(void *p
);
128 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
129 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
130 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
131 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
);
132 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
133 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
134 static void zvni_get_rmac(zebra_vni_t
*zvni
, struct ethaddr
*rmac
);
135 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
136 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
138 static unsigned int mac_hash_keymake(void *p
);
139 static int mac_cmp(const void *p1
, const void *p2
);
140 static void *zvni_mac_alloc(void *p
);
141 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
142 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
143 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
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
,
147 int uninstall
, int upd_client
, u_int32_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
,
150 struct ethaddr
*macaddr
, u_char flags
);
151 static int zvni_mac_send_del_to_client(vni_t vni
,
152 struct ethaddr
*macaddr
, u_char 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
);
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
,
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
,
186 /* Private functions */
189 * Return number of valid MACs in a VNI's MAC hash table - all
190 * remote MACs and non-internal (auto) local MACs count.
192 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
195 u_int32_t num_macs
= 0;
197 struct hash_backet
*hb
;
200 hash
= zvni
->mac_table
;
203 for (i
= 0; i
< hash
->size
; i
++) {
204 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
205 mac
= (zebra_mac_t
*)hb
->data
;
206 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
207 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
215 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
217 struct zebra_vrf
*zvrf
;
219 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
220 if (zvrf
&& zvrf
->advertise_gw_macip
)
223 if (zvni
&& zvni
->advertise_gw_macip
)
230 * Helper function to determine maximum width of neighbor IP address for
231 * display - just because we're dealing with IPv6 addresses that can
234 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
237 char buf
[INET6_ADDRSTRLEN
];
238 struct neigh_walk_ctx
*wctx
= ctxt
;
241 n
= (zebra_neigh_t
*)backet
->data
;
245 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
246 if (width
> wctx
->addr_width
)
247 wctx
->addr_width
= width
;
251 * Print a specific neighbor entry.
253 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
256 char buf1
[ETHER_ADDR_STRLEN
];
257 char buf2
[INET6_ADDRSTRLEN
];
259 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
260 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
261 vty
= (struct vty
*)ctxt
;
263 vty_out(vty
, "IP: %s\n",
264 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
265 vty_out(vty
, " MAC: %s",
266 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
268 json_object_string_add(json
, "ip", buf2
);
269 json_object_string_add(json
, "mac", buf1
);
271 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
273 vty_out(vty
, " Remote VTEP: %s",
274 inet_ntoa(n
->r_vtep_ip
));
276 json_object_string_add(json
, "remoteVtep",
277 inet_ntoa(n
->r_vtep_ip
));
279 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
282 vty_out(vty
, " State: %s",
283 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
292 * Print neighbor hash entry - called for display of all neighbors.
294 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
297 json_object
*json_vni
= NULL
, *json_row
= NULL
;
299 char buf1
[ETHER_ADDR_STRLEN
];
300 char buf2
[INET6_ADDRSTRLEN
];
301 struct neigh_walk_ctx
*wctx
= ctxt
;
304 json_vni
= wctx
->json
;
305 n
= (zebra_neigh_t
*)backet
->data
;
310 json_row
= json_object_new_object();
312 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
313 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
314 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
315 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
316 if (json_vni
== NULL
) {
317 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
318 buf2
, "local", buf1
);
320 json_object_string_add(json_row
, "type", "local");
321 json_object_string_add(json_row
, "mac", buf1
);
325 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
326 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
327 if (json_vni
== NULL
) {
328 if (wctx
->count
== 0)
330 "%*s %-6s %-17s %-21s\n",
333 "MAC", "Remote VTEP");
334 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
335 -wctx
->addr_width
, buf2
,
337 inet_ntoa(n
->r_vtep_ip
));
339 json_object_string_add(json_row
, "type",
341 json_object_string_add(json_row
, "mac",
343 json_object_string_add(
344 json_row
, "remoteVtep",
345 inet_ntoa(n
->r_vtep_ip
));
350 if (json_vni
== NULL
) {
351 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
352 -wctx
->addr_width
, buf2
, "remote", buf1
,
353 inet_ntoa(n
->r_vtep_ip
));
355 json_object_string_add(json_row
, "type",
357 json_object_string_add(json_row
, "mac", buf1
);
358 json_object_string_add(json_row
, "remoteVtep",
359 inet_ntoa(n
->r_vtep_ip
));
366 json_object_object_add(json_vni
, buf2
, json_row
);
370 * Print neighbors for all VNI.
372 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
376 json_object
*json
= NULL
, *json_vni
= NULL
;
379 struct neigh_walk_ctx wctx
;
380 char vni_str
[VNI_STR_LEN
];
382 vty
= (struct vty
*)args
[0];
383 json
= (json_object
*)args
[1];
385 zvni
= (zebra_vni_t
*)backet
->data
;
388 vty_out(vty
, "{}\n");
391 num_neigh
= hashcount(zvni
->neigh_table
);
394 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
395 zvni
->vni
, num_neigh
);
397 json_vni
= json_object_new_object();
398 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
399 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
403 json_object_object_add(json
, vni_str
, json_vni
);
407 /* Since we have IPv6 addresses to deal with which can vary widely in
408 * size, we try to be a bit more elegant in display by first computing
411 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
414 wctx
.addr_width
= 15;
415 wctx
.json
= json_vni
;
416 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
419 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
420 "Type", "MAC", "Remote VTEP");
421 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
424 json_object_object_add(json
, vni_str
, json_vni
);
428 * Print a specific MAC entry.
430 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
433 zebra_neigh_t
*n
= NULL
;
434 struct listnode
*node
= NULL
;
436 char buf2
[INET6_ADDRSTRLEN
];
438 vty
= (struct vty
*)ctxt
;
439 vty_out(vty
, "MAC: %s",
440 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
441 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
442 struct zebra_ns
*zns
;
443 struct interface
*ifp
;
446 ifindex
= mac
->fwd_info
.local
.ifindex
;
447 zns
= zebra_ns_lookup(NS_DEFAULT
);
448 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
449 if (!ifp
) // unexpected
451 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
452 if (mac
->fwd_info
.local
.vid
)
453 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
454 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
455 vty_out(vty
, " Remote VTEP: %s",
456 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
457 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
458 vty_out(vty
, " Auto Mac ");
462 /* print all the associated neigh */
463 vty_out(vty
, " Neighbors:\n");
464 if (!listcount(mac
->neigh_list
))
465 vty_out(vty
, " No Neighbors\n");
467 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
468 vty_out(vty
, " %s %s\n",
469 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
470 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
471 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
482 * Print MAC hash entry - called for display of all MACs.
484 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
487 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
490 struct mac_walk_ctx
*wctx
= ctxt
;
493 json_mac_hdr
= wctx
->json
;
494 mac
= (zebra_mac_t
*)backet
->data
;
498 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
501 json_mac
= json_object_new_object();
503 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
504 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
505 struct zebra_ns
*zns
;
507 struct interface
*ifp
;
510 zns
= zebra_ns_lookup(NS_DEFAULT
);
511 ifindex
= mac
->fwd_info
.local
.ifindex
;
512 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
513 if (!ifp
) // unexpected
515 vid
= mac
->fwd_info
.local
.vid
;
516 if (json_mac_hdr
== NULL
)
517 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
520 json_object_string_add(json_mac
, "type", "local");
521 json_object_string_add(json_mac
, "intf", ifp
->name
);
524 if (json_mac_hdr
== NULL
)
525 vty_out(vty
, " %-5u", vid
);
527 json_object_int_add(json_mac
, "vlan", vid
);
529 if (json_mac_hdr
== NULL
)
532 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
534 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
535 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
536 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
538 if (wctx
->count
== 0) {
539 if (json_mac_hdr
== NULL
) {
540 vty_out(vty
, "\nVNI %u\n\n",
543 "%-17s %-6s %-21s %-5s\n",
549 if (json_mac_hdr
== NULL
)
550 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
552 inet_ntoa(mac
->fwd_info
555 json_object_string_add(json_mac
, "type",
557 json_object_string_add(
558 json_mac
, "remoteVtep",
559 inet_ntoa(mac
->fwd_info
561 json_object_object_add(json_mac_hdr
,
567 if (json_mac_hdr
== NULL
)
568 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
570 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
572 json_object_string_add(json_mac
, "type",
574 json_object_string_add(
575 json_mac
, "remoteVtep",
576 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
577 json_object_object_add(json_mac_hdr
, buf1
,
586 * Print MACs for all VNI.
588 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
591 json_object
*json
= NULL
, *json_vni
= NULL
;
592 json_object
*json_mac
= NULL
;
595 struct mac_walk_ctx
*wctx
= ctxt
;
596 char vni_str
[VNI_STR_LEN
];
598 vty
= (struct vty
*)wctx
->vty
;
599 json
= (struct json_object
*)wctx
->json
;
601 zvni
= (zebra_vni_t
*)backet
->data
;
604 vty_out(vty
, "{}\n");
609 /*We are iterating over a new VNI, set the count to 0*/
612 num_macs
= num_valid_macs(zvni
);
617 json_vni
= json_object_new_object();
618 json_mac
= json_object_new_object();
619 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
622 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
624 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
625 zvni
->vni
, num_macs
);
626 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
627 "Intf/Remote VTEP", "VLAN");
629 json_object_int_add(json_vni
, "numMacs", num_macs
);
631 /* assign per-vni to wctx->json object to fill macs
632 * under the vni. Re-assign primary json object to fill
633 * next vni information.
635 wctx
->json
= json_mac
;
636 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
640 json_object_object_add(json_vni
, "macs", json_mac
);
641 json_object_object_add(json
, vni_str
, json_vni
);
645 static void zl3vni_print_nh_hash(struct hash_backet
*backet
,
648 struct nh_walk_ctx
*wctx
= NULL
;
649 struct vty
*vty
= NULL
;
650 struct json_object
*json
= NULL
;
651 struct json_object
*json_nh
= NULL
;
652 zebra_neigh_t
*n
= NULL
;
653 char buf1
[ETHER_ADDR_STRLEN
];
655 wctx
= (struct nh_walk_ctx
*)ctx
;
659 json_nh
= json_object_new_object();
660 n
= (zebra_neigh_t
*)backet
->data
;
665 vty_out(vty
, "%15s %-17s %6d\n",
666 inet_ntoa(n
->r_vtep_ip
),
667 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
670 json_object_string_add(json_nh
, "vtep-ip",
671 inet_ntoa(n
->r_vtep_ip
));
672 json_object_string_add(json_nh
, "rmac",
673 prefix_mac2str(&n
->emac
, buf1
,
675 json_object_int_add(json_nh
, "refCnt", n
->nh_refcnt
);
679 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
682 struct vty
*vty
= NULL
;
683 json_object
*json
= NULL
;
684 json_object
*json_vni
= NULL
;
685 json_object
*json_mac
= NULL
;
686 zebra_l3vni_t
*zl3vni
= NULL
;
688 struct rmac_walk_ctx
*wctx
= NULL
;
689 char vni_str
[VNI_STR_LEN
];
691 wctx
= (struct rmac_walk_ctx
*)ctx
;
692 vty
= (struct vty
*)wctx
->vty
;
693 json
= (struct json_object
*)wctx
->json
;
695 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
698 vty_out(vty
, "{}\n");
702 num_rmacs
= hashcount(zl3vni
->rmac_table
);
707 json_vni
= json_object_new_object();
708 json_mac
= json_object_new_array();
709 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
713 vty_out(vty
, "\nVNI %u #MACs %u\n\n",
714 zl3vni
->vni
, num_rmacs
);
715 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
716 "Remote VTEP", "Refcnt");
718 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
720 /* assign per-vni to wctx->json object to fill macs
721 * under the vni. Re-assign primary json object to fill
722 * next vni information.
724 wctx
->json
= json_mac
;
725 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, wctx
);
728 json_object_object_add(json_vni
, "rmacs", json_mac
);
729 json_object_object_add(json
, vni_str
, json_vni
);
733 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
,
736 zebra_mac_t
*zrmac
= NULL
;
737 struct rmac_walk_ctx
*wctx
= NULL
;
738 struct vty
*vty
= NULL
;
739 struct json_object
*json
= NULL
;
740 struct json_object
*json_rmac
= NULL
;
741 char buf
[ETHER_ADDR_STRLEN
];
743 wctx
= (struct rmac_walk_ctx
*)ctx
;
747 json_rmac
= json_object_new_object();
748 zrmac
= (zebra_mac_t
*)backet
->data
;
753 vty_out(vty
, "%-17s %-21s %-6d\n",
754 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
755 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
),
758 json_object_string_add(json_rmac
, "rmac",
759 prefix_mac2str(&zrmac
->macaddr
, buf
,
761 json_object_string_add(json_rmac
, "vtep-ip",
762 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
763 json_object_int_add(json_rmac
, "refcnt", zrmac
->rmac_refcnt
);
764 json_object_array_add(json
, json_rmac
);
768 /* print a specific L3 VNI entry */
769 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
771 char buf
[ETHER_ADDR_STRLEN
];
772 struct vty
*vty
= NULL
;
773 json_object
*json
= NULL
;
774 zebra_vni_t
*zvni
= NULL
;
775 json_object
*json_vni_list
= NULL
;
776 struct listnode
*node
= NULL
, *nnode
= NULL
;
782 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
783 vty_out(vty
, " Vxlan-Intf: %s\n",
784 zl3vni_vxlan_if_name(zl3vni
));
785 vty_out(vty
, " SVI-If: %s\n",
786 zl3vni_svi_if_name(zl3vni
));
787 vty_out(vty
, " State: %s\n",
788 zl3vni_state2str(zl3vni
));
789 vty_out(vty
, " Vrf: %s\n",
790 zl3vni_vrf_name(zl3vni
));
791 vty_out(vty
, " Rmac: %s\n",
792 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
793 vty_out(vty
, " L2-VNIs: ");
794 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
795 vty_out(vty
, "%u ", zvni
->vni
);
798 json_vni_list
= json_object_new_array();
799 json_object_int_add(json
, "vni", zl3vni
->vni
);
800 json_object_string_add(json
, "vxlan-intf",
801 zl3vni_vxlan_if_name(zl3vni
));
802 json_object_string_add(json
, "svi-if",
803 zl3vni_svi_if_name(zl3vni
));
804 json_object_string_add(json
, "state",
805 zl3vni_state2str(zl3vni
));
806 json_object_string_add(json
, "vrf",
807 zl3vni_vrf_name(zl3vni
));
808 json_object_string_add(json
, "rmac",
809 zl3vni_rmac2str(zl3vni
, buf
,
811 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
812 json_object_array_add(json_vni_list
,
813 json_object_new_int(zvni
->vni
));
815 json_object_object_add(json
, "l2-vnis", json_vni_list
);
820 * Print a specific VNI entry.
822 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
828 json_object
*json
= NULL
;
829 json_object
*json_vtep_list
= NULL
;
830 json_object
*json_ip_str
= NULL
;
836 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
837 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
839 json_object_int_add(json
, "vni", zvni
->vni
);
840 json_object_string_add(json
, "vrf",
841 vrf_id_to_name(zvni
->vrf_id
));
844 if (!zvni
->vxlan_if
) { // unexpected
846 vty_out(vty
, " VxLAN interface: unknown\n");
849 num_macs
= num_valid_macs(zvni
);
850 num_neigh
= hashcount(zvni
->neigh_table
);
852 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
853 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
854 inet_ntoa(zvni
->local_vtep_ip
));
856 json_object_string_add(json
, "vxlanInterface",
857 zvni
->vxlan_if
->name
);
858 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
859 json_object_string_add(json
, "vtepIp",
860 inet_ntoa(zvni
->local_vtep_ip
));
861 json_object_string_add(json
, "advertiseGatewayMacip",
862 zvni
->advertise_gw_macip
? "Yes" : "No");
863 json_object_int_add(json
, "numMacs", num_macs
);
864 json_object_int_add(json
, "numArpNd", num_neigh
);
868 vty_out(vty
, " No remote VTEPs known for this VNI\n");
871 vty_out(vty
, " Remote VTEPs for this VNI:\n");
873 json_vtep_list
= json_object_new_array();
874 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
876 vty_out(vty
, " %s\n",
877 inet_ntoa(zvtep
->vtep_ip
));
879 json_ip_str
= json_object_new_string(
880 inet_ntoa(zvtep
->vtep_ip
));
881 json_object_array_add(json_vtep_list
,
886 json_object_object_add(json
, "numRemoteVteps",
891 " Number of MACs (local and remote) known for this VNI: %u\n",
894 " Number of ARPs (IPv4 and IPv6, local and remote) "
895 "known for this VNI: %u\n",
897 vty_out(vty
, " Advertise-gw-macip: %s\n",
898 zvni
->advertise_gw_macip
? "Yes" : "No");
902 /* print a L3 VNI hash entry */
903 static void zl3vni_print_hash(struct hash_backet
*backet
,
906 char buf
[ETHER_ADDR_STRLEN
];
907 struct vty
*vty
= NULL
;
908 json_object
*json
= NULL
;
909 zebra_l3vni_t
*zl3vni
= NULL
;
914 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
919 vty_out(vty
, "%-10u %-20s %-20s %-5s %-37s %-18s\n",
921 zl3vni_vxlan_if_name(zl3vni
),
922 zl3vni_svi_if_name(zl3vni
),
923 zl3vni_state2str(zl3vni
),
924 zl3vni_vrf_name(zl3vni
),
925 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
927 json_object_int_add(json
, "vni", zl3vni
->vni
);
928 json_object_string_add(json
, "vxlan-if",
929 zl3vni_vxlan_if_name(zl3vni
));
930 json_object_string_add(json
, "svi-if",
931 zl3vni_svi_if_name(zl3vni
));
932 json_object_string_add(json
, "state",
933 zl3vni_state2str(zl3vni
));
934 json_object_string_add(json
, "vrf",
935 zl3vni_vrf_name(zl3vni
));
936 json_object_string_add(json
, "rmac",
937 zl3vni_rmac2str(zl3vni
, buf
,
944 * Print a VNI hash entry - called for display of all VNIs.
946 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
951 u_int32_t num_vteps
= 0;
952 u_int32_t num_macs
= 0;
953 u_int32_t num_neigh
= 0;
954 json_object
*json
= NULL
;
955 json_object
*json_vni
= NULL
;
956 json_object
*json_ip_str
= NULL
;
957 json_object
*json_vtep_list
= NULL
;
962 zvni
= (zebra_vni_t
*)backet
->data
;
972 num_macs
= num_valid_macs(zvni
);
973 num_neigh
= hashcount(zvni
->neigh_table
);
975 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
977 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
978 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
980 vrf_id_to_name(zvni
->vrf_id
));
982 char vni_str
[VNI_STR_LEN
];
983 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
984 json_vni
= json_object_new_object();
985 json_object_string_add(json_vni
, "vxlanIf",
986 zvni
->vxlan_if
? zvni
->vxlan_if
->name
988 json_object_string_add(json_vni
, "vtepIp",
989 inet_ntoa(zvni
->local_vtep_ip
));
990 json_object_int_add(json_vni
, "numMacs", num_macs
);
991 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
992 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
994 json_vtep_list
= json_object_new_array();
995 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
996 json_ip_str
= json_object_new_string(
997 inet_ntoa(zvtep
->vtep_ip
));
998 json_object_array_add(json_vtep_list
,
1001 json_object_object_add(json_vni
, "remoteVteps",
1004 json_object_object_add(json
, vni_str
, json_vni
);
1009 * Inform BGP about local MACIP.
1011 static int zvni_macip_send_msg_to_client(vni_t vni
,
1012 struct ethaddr
*macaddr
,
1013 struct ipaddr
*ip
, u_char flags
,
1016 char buf
[ETHER_ADDR_STRLEN
];
1017 char buf2
[INET6_ADDRSTRLEN
];
1019 struct zserv
*client
= NULL
;
1020 struct stream
*s
= NULL
;
1022 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1023 /* BGP may not be running. */
1030 zserv_create_header(s
, cmd
, VRF_DEFAULT
);
1031 stream_putl(s
, vni
);
1032 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1035 if (IS_IPADDR_V4(ip
))
1036 ipa_len
= IPV4_MAX_BYTELEN
;
1037 else if (IS_IPADDR_V6(ip
))
1038 ipa_len
= IPV6_MAX_BYTELEN
;
1040 stream_putl(s
, ipa_len
); /* IP address length */
1042 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1044 stream_putl(s
, 0); /* Just MAC. */
1046 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1049 /* Write packet size. */
1050 stream_putw_at(s
, 0, stream_get_endp(s
));
1052 if (IS_ZEBRA_DEBUG_VXLAN
)
1054 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1055 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
1056 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1057 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1058 zebra_route_string(client
->proto
));
1060 if (cmd
== ZEBRA_MACIP_ADD
)
1061 client
->macipadd_cnt
++;
1063 client
->macipdel_cnt
++;
1065 return zebra_server_send_message(client
);
1069 * Make hash key for neighbors.
1071 static unsigned int neigh_hash_keymake(void *p
)
1073 zebra_neigh_t
*n
= p
;
1074 struct ipaddr
*ip
= &n
->ip
;
1076 if (IS_IPADDR_V4(ip
))
1077 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1079 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1080 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1084 * Compare two neighbor hash structures.
1086 static int neigh_cmp(const void *p1
, const void *p2
)
1088 const zebra_neigh_t
*n1
= p1
;
1089 const zebra_neigh_t
*n2
= p2
;
1091 if (n1
== NULL
&& n2
== NULL
)
1094 if (n1
== NULL
|| n2
== NULL
)
1097 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1101 * Callback to allocate neighbor hash entry.
1103 static void *zvni_neigh_alloc(void *p
)
1105 const zebra_neigh_t
*tmp_n
= p
;
1108 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1115 * Add neighbor entry.
1117 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1118 struct ethaddr
*mac
)
1120 zebra_neigh_t tmp_n
;
1121 zebra_neigh_t
*n
= NULL
;
1122 zebra_mac_t
*zmac
= NULL
;
1124 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1125 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1126 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1129 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1130 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1132 /* Associate the neigh to mac */
1133 zmac
= zvni_mac_lookup(zvni
, mac
);
1135 listnode_add_sort(zmac
->neigh_list
, n
);
1141 * Delete neighbor entry.
1143 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1145 zebra_neigh_t
*tmp_n
;
1146 zebra_mac_t
*zmac
= NULL
;
1148 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1150 listnode_delete(zmac
->neigh_list
, n
);
1152 /* Free the VNI hash entry and allocated memory. */
1153 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1155 XFREE(MTYPE_NEIGH
, tmp_n
);
1161 * Free neighbor hash entry (callback)
1163 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1165 struct neigh_walk_ctx
*wctx
= arg
;
1166 zebra_neigh_t
*n
= backet
->data
;
1168 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1169 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1170 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1171 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1172 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1173 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1174 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1175 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1178 if (wctx
->uninstall
)
1179 zvni_neigh_uninstall(wctx
->zvni
, n
);
1181 return zvni_neigh_del(wctx
->zvni
, n
);
1188 * Delete all neighbor entries from specific VTEP for a particular VNI.
1190 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1191 struct in_addr
*r_vtep_ip
)
1193 struct neigh_walk_ctx wctx
;
1195 if (!zvni
->neigh_table
)
1198 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1200 wctx
.uninstall
= uninstall
;
1201 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1202 wctx
.r_vtep_ip
= *r_vtep_ip
;
1204 hash_iterate(zvni
->neigh_table
,
1205 (void (*)(struct hash_backet
*,
1206 void *))zvni_neigh_del_hash_entry
,
1211 * Delete all neighbor entries for this VNI.
1213 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
1214 int uninstall
, int upd_client
, u_int32_t flags
)
1216 struct neigh_walk_ctx wctx
;
1218 if (!zvni
->neigh_table
)
1221 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1223 wctx
.uninstall
= uninstall
;
1224 wctx
.upd_client
= upd_client
;
1227 hash_iterate(zvni
->neigh_table
,
1228 (void (*)(struct hash_backet
*,
1229 void *))zvni_neigh_del_hash_entry
,
1234 * Look up neighbor hash entry.
1236 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1241 memset(&tmp
, 0, sizeof(tmp
));
1242 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1243 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1248 /* Process all neigh associated to a mac upon local mac add event */
1249 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1252 zebra_neigh_t
*n
= NULL
;
1253 struct listnode
*node
= NULL
;
1254 char buf
[ETHER_ADDR_STRLEN
];
1255 char buf2
[INET6_ADDRSTRLEN
];
1257 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1258 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1259 /* MAC is learnt locally, program all inactive neigh
1260 * pointing to this mac */
1261 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1262 if (IS_ZEBRA_DEBUG_VXLAN
)
1264 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1265 ipaddr2str(&n
->ip
, buf2
,
1267 prefix_mac2str(&n
->emac
, buf
,
1271 ZEBRA_NEIGH_SET_ACTIVE(n
);
1272 zvni_neigh_send_add_to_client(
1273 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1275 if (IS_ZEBRA_DEBUG_VXLAN
)
1277 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1278 ipaddr2str(&n
->ip
, buf2
,
1280 prefix_mac2str(&n
->emac
, buf
,
1284 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1285 /* TODO: assume the neigh has moved too ?? */
1290 /* Process all neigh associated to a mac upon local mac del event */
1291 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1294 zebra_neigh_t
*n
= NULL
;
1295 struct listnode
*node
= NULL
;
1296 char buf
[ETHER_ADDR_STRLEN
];
1297 char buf2
[INET6_ADDRSTRLEN
];
1299 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1300 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1301 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1302 if (IS_ZEBRA_DEBUG_VXLAN
)
1304 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1305 ipaddr2str(&n
->ip
, buf2
,
1307 prefix_mac2str(&n
->emac
, buf
,
1311 ZEBRA_NEIGH_SET_INACTIVE(n
);
1312 zvni_neigh_send_del_to_client(
1313 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1315 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1316 if (IS_ZEBRA_DEBUG_VXLAN
)
1318 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1319 prefix_mac2str(&n
->emac
, buf
,
1322 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1327 /* process all neigh associated to a mac entry upon remote mac add */
1328 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1331 zebra_neigh_t
*n
= NULL
;
1332 struct listnode
*node
= NULL
;
1333 char buf
[ETHER_ADDR_STRLEN
];
1334 char buf2
[INET6_ADDRSTRLEN
];
1336 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1337 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1338 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1339 if (IS_ZEBRA_DEBUG_VXLAN
)
1341 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1342 ipaddr2str(&n
->ip
, buf2
,
1344 prefix_mac2str(&n
->emac
, buf
,
1348 ZEBRA_NEIGH_SET_INACTIVE(n
);
1349 zvni_neigh_send_del_to_client(
1350 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1356 /* process all neigh associated to mac entry upon remote mac del */
1357 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1360 zebra_neigh_t
*n
= NULL
;
1361 struct listnode
*node
= NULL
;
1362 char buf
[ETHER_ADDR_STRLEN
];
1363 char buf2
[INET6_ADDRSTRLEN
];
1365 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1366 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1367 if (IS_ZEBRA_DEBUG_VXLAN
)
1369 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1370 prefix_mac2str(&n
->emac
, buf
,
1373 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1379 * Inform BGP about local neighbor addition.
1381 static int zvni_neigh_send_add_to_client(vni_t vni
,
1383 struct ethaddr
*macaddr
, u_char flags
)
1385 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1390 * Inform BGP about local neighbor deletion.
1392 static int zvni_neigh_send_del_to_client(vni_t vni
,
1394 struct ethaddr
*macaddr
, u_char flags
)
1396 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1401 * Install remote neighbor into the kernel.
1403 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1405 struct zebra_if
*zif
;
1406 struct zebra_l2info_vxlan
*vxl
;
1407 struct interface
*vlan_if
;
1409 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1412 zif
= zvni
->vxlan_if
->info
;
1415 vxl
= &zif
->l2info
.vxl
;
1417 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1421 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1425 * Uninstall remote neighbor from the kernel.
1427 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1429 struct zebra_if
*zif
;
1430 struct zebra_l2info_vxlan
*vxl
;
1431 struct interface
*vlan_if
;
1433 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1436 if (!zvni
->vxlan_if
) {
1437 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1442 zif
= zvni
->vxlan_if
->info
;
1445 vxl
= &zif
->l2info
.vxl
;
1446 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1450 return kernel_del_neigh(vlan_if
, &n
->ip
);
1454 * Install neighbor hash entry - called upon access VLAN change.
1456 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1459 struct neigh_walk_ctx
*wctx
= ctxt
;
1461 n
= (zebra_neigh_t
*)backet
->data
;
1465 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1466 zvni_neigh_install(wctx
->zvni
, n
);
1469 /* Get the VRR interface for SVI if any */
1470 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1472 struct zebra_vrf
*zvrf
= NULL
;
1473 struct interface
*tmp_if
= NULL
;
1474 struct zebra_if
*zif
= NULL
;
1476 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1479 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1484 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1487 if (zif
->link
== ifp
)
1494 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1496 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1497 struct connected
*c
= NULL
;
1498 struct ethaddr macaddr
;
1500 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1502 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1505 memset(&ip
, 0, sizeof(struct ipaddr
));
1506 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1509 if (c
->address
->family
== AF_INET
) {
1510 ip
.ipa_type
= IPADDR_V4
;
1511 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1512 sizeof(struct in_addr
));
1513 } else if (c
->address
->family
== AF_INET6
) {
1514 ip
.ipa_type
= IPADDR_V6
;
1515 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1516 sizeof(struct in6_addr
));
1521 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1527 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1529 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1530 struct connected
*c
= NULL
;
1531 struct ethaddr macaddr
;
1533 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1535 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1538 memset(&ip
, 0, sizeof(struct ipaddr
));
1539 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1542 if (c
->address
->family
== AF_INET
) {
1543 ip
.ipa_type
= IPADDR_V4
;
1544 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1545 sizeof(struct in_addr
));
1546 } else if (c
->address
->family
== AF_INET6
) {
1547 ip
.ipa_type
= IPADDR_V6
;
1548 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1549 sizeof(struct in6_addr
));
1554 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1561 * zvni_gw_macip_add_to_client
1563 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1564 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1567 struct ethaddr rmac
;
1568 char buf
[ETHER_ADDR_STRLEN
];
1569 char buf1
[ETHER_ADDR_STRLEN
];
1570 char buf2
[INET6_ADDRSTRLEN
];
1571 zebra_neigh_t
*n
= NULL
;
1572 zebra_mac_t
*mac
= NULL
;
1573 struct zebra_if
*zif
= NULL
;
1574 struct zebra_l2info_vxlan
*vxl
= NULL
;
1576 memset(&rmac
, 0, sizeof(struct ethaddr
));
1578 zif
= zvni
->vxlan_if
->info
;
1582 vxl
= &zif
->l2info
.vxl
;
1584 /* get the l3-vni */
1585 l3vni
= zvni_get_l3vni(zvni
);
1588 zvni_get_rmac(zvni
, &rmac
);
1590 mac
= zvni_mac_lookup(zvni
, macaddr
);
1592 mac
= zvni_mac_add(zvni
, macaddr
);
1594 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1595 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1596 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1601 /* Set "local" forwarding info. */
1602 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1603 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1604 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1605 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1606 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1608 n
= zvni_neigh_lookup(zvni
, ip
);
1610 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1613 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1614 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1615 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1616 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1621 /* Set "local" forwarding info. */
1622 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1623 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1624 n
->ifindex
= ifp
->ifindex
;
1626 if (IS_ZEBRA_DEBUG_VXLAN
)
1628 "SVI %s(%u) L2-VNI %u L3-VNI %u RMAC %s , sending GW MAC %s IP %s add to BGP",
1629 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1631 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)),
1632 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1633 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1635 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1642 * zvni_gw_macip_del_from_client
1644 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1648 struct ethaddr rmac
;
1649 char buf
[ETHER_ADDR_STRLEN
];
1650 char buf1
[ETHER_ADDR_STRLEN
];
1651 char buf2
[INET6_ADDRSTRLEN
];
1652 zebra_neigh_t
*n
= NULL
;
1653 zebra_mac_t
*mac
= NULL
;
1655 memset(&rmac
, 0, sizeof(struct ethaddr
));
1657 /* get the l30vni */
1658 l3vni
= zvni_get_l3vni(zvni
);
1661 zvni_get_rmac(zvni
, &rmac
);
1663 /* If the neigh entry is not present nothing to do*/
1664 n
= zvni_neigh_lookup(zvni
, ip
);
1668 /* mac entry should be present */
1669 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1671 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1672 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1673 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1677 /* If the entry is not local nothing to do*/
1678 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1681 if (IS_ZEBRA_DEBUG_VXLAN
)
1683 "SVI %s(%u) L2-VNI %u, L3-VNI %u RMAC %s sending GW MAC %s IP %s del to BGP",
1684 ifp
->name
, ifp
->ifindex
, zvni
->vni
, l3vni
,
1685 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
1686 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1687 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1689 /* Remove neighbor from BGP. */
1690 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1693 /* Delete this neighbor entry. */
1694 zvni_neigh_del(zvni
, n
);
1696 /* see if the mac needs to be deleted as well*/
1698 zvni_deref_ip2mac(zvni
, mac
, 0);
1703 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1706 zebra_vni_t
*zvni
= NULL
;
1707 struct zebra_if
*zif
= NULL
;
1708 struct zebra_l2info_vxlan zl2_info
;
1709 struct interface
*vlan_if
= NULL
;
1710 struct interface
*vrr_if
= NULL
;
1711 struct interface
*ifp
;
1713 /* Add primary SVI MAC*/
1714 zvni
= (zebra_vni_t
*)backet
->data
;
1718 ifp
= zvni
->vxlan_if
;
1723 /* If down or not mapped to a bridge, we're done. */
1724 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1727 zl2_info
= zif
->l2info
.vxl
;
1729 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1733 /* Del primary MAC-IP */
1734 zvni_del_macip_for_intf(vlan_if
, zvni
);
1736 /* Del VRR MAC-IP - if any*/
1737 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1739 zvni_del_macip_for_intf(vrr_if
, zvni
);
1744 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1747 zebra_vni_t
*zvni
= NULL
;
1748 struct zebra_if
*zif
= NULL
;
1749 struct zebra_l2info_vxlan zl2_info
;
1750 struct interface
*vlan_if
= NULL
;
1751 struct interface
*vrr_if
= NULL
;
1752 struct interface
*ifp
= NULL
;
1754 zvni
= (zebra_vni_t
*)backet
->data
;
1758 if (!advertise_gw_macip_enabled(zvni
))
1761 ifp
= zvni
->vxlan_if
;
1766 /* If down or not mapped to a bridge, we're done. */
1767 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1769 zl2_info
= zif
->l2info
.vxl
;
1771 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1772 zif
->brslave_info
.br_if
);
1776 /* Add primary SVI MAC-IP */
1777 zvni_add_macip_for_intf(vlan_if
, zvni
);
1779 /* Add VRR MAC-IP - if any*/
1780 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1782 zvni_add_macip_for_intf(vrr_if
, zvni
);
1788 * Make hash key for MAC.
1790 static unsigned int mac_hash_keymake(void *p
)
1792 zebra_mac_t
*pmac
= p
;
1793 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1795 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1799 * Compare two MAC addresses.
1801 static int mac_cmp(const void *p1
, const void *p2
)
1803 const zebra_mac_t
*pmac1
= p1
;
1804 const zebra_mac_t
*pmac2
= p2
;
1806 if (pmac1
== NULL
&& pmac2
== NULL
)
1809 if (pmac1
== NULL
|| pmac2
== NULL
)
1812 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1818 * Callback to allocate MAC hash entry.
1820 static void *zvni_mac_alloc(void *p
)
1822 const zebra_mac_t
*tmp_mac
= p
;
1825 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1828 return ((void *)mac
);
1834 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1836 zebra_mac_t tmp_mac
;
1837 zebra_mac_t
*mac
= NULL
;
1839 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1840 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1841 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1844 mac
->neigh_list
= list_new();
1845 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1853 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1855 zebra_mac_t
*tmp_mac
;
1857 list_delete_and_null(&mac
->neigh_list
);
1859 /* Free the VNI hash entry and allocated memory. */
1860 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1862 XFREE(MTYPE_MAC
, tmp_mac
);
1868 * Free MAC hash entry (callback)
1870 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1872 struct mac_walk_ctx
*wctx
= arg
;
1873 zebra_mac_t
*mac
= backet
->data
;
1876 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1877 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1878 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1879 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1880 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1881 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1882 &wctx
->r_vtep_ip
))) {
1883 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1884 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
1886 zvni_mac_send_del_to_client(
1887 wctx
->zvni
->vni
, &mac
->macaddr
,
1888 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
1891 if (wctx
->uninstall
)
1892 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
1894 return zvni_mac_del(wctx
->zvni
, mac
);
1901 * Delete all MAC entries from specific VTEP for a particular VNI.
1903 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1904 struct in_addr
*r_vtep_ip
)
1906 struct mac_walk_ctx wctx
;
1908 if (!zvni
->mac_table
)
1911 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1913 wctx
.uninstall
= uninstall
;
1914 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
1915 wctx
.r_vtep_ip
= *r_vtep_ip
;
1917 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1918 void *))zvni_mac_del_hash_entry
,
1923 * Delete all MAC entries for this VNI.
1925 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
1926 int uninstall
, int upd_client
, u_int32_t flags
)
1928 struct mac_walk_ctx wctx
;
1930 if (!zvni
->mac_table
)
1933 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1935 wctx
.uninstall
= uninstall
;
1936 wctx
.upd_client
= upd_client
;
1939 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1940 void *))zvni_mac_del_hash_entry
,
1945 * Look up MAC hash entry.
1947 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
1952 memset(&tmp
, 0, sizeof(tmp
));
1953 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
1954 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
1960 * Inform BGP about local MAC addition.
1962 static int zvni_mac_send_add_to_client(vni_t vni
,
1963 struct ethaddr
*macaddr
, u_char flags
)
1965 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
1970 * Inform BGP about local MAC deletion.
1972 static int zvni_mac_send_del_to_client(vni_t vni
,
1973 struct ethaddr
*macaddr
, u_char flags
)
1975 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
1980 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1981 * notifications, to see if they are of interest.
1983 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
1984 struct interface
*br_if
, vlanid_t vid
)
1986 struct zebra_ns
*zns
;
1987 struct route_node
*rn
;
1988 struct interface
*tmp_if
= NULL
;
1989 struct zebra_if
*zif
;
1990 struct zebra_l2info_bridge
*br
;
1991 struct zebra_l2info_vxlan
*vxl
= NULL
;
1992 u_char bridge_vlan_aware
;
1996 /* Determine if bridge is VLAN-aware or not */
1999 br
= &zif
->l2info
.br
;
2000 bridge_vlan_aware
= br
->vlan_aware
;
2002 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2003 /* TODO: Optimize with a hash. */
2004 zns
= zebra_ns_lookup(NS_DEFAULT
);
2005 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2006 tmp_if
= (struct interface
*)rn
->info
;
2010 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2012 if (!if_is_operative(tmp_if
))
2014 vxl
= &zif
->l2info
.vxl
;
2016 if (zif
->brslave_info
.br_if
!= br_if
)
2019 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2028 zvni
= zvni_lookup(vxl
->vni
);
2033 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2034 * neighbor notifications, to see if they are of interest.
2036 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2037 struct interface
*br_if
)
2039 struct zebra_ns
*zns
;
2040 struct route_node
*rn
;
2041 struct interface
*tmp_if
= NULL
;
2042 struct zebra_if
*zif
;
2043 struct zebra_l2info_bridge
*br
;
2044 struct zebra_l2info_vxlan
*vxl
= NULL
;
2045 u_char bridge_vlan_aware
;
2053 /* Make sure the linked interface is a bridge. */
2054 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2057 /* Determine if bridge is VLAN-aware or not */
2060 br
= &zif
->l2info
.br
;
2061 bridge_vlan_aware
= br
->vlan_aware
;
2062 if (bridge_vlan_aware
) {
2063 struct zebra_l2info_vlan
*vl
;
2065 if (!IS_ZEBRA_IF_VLAN(ifp
))
2070 vl
= &zif
->l2info
.vl
;
2074 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2075 /* TODO: Optimize with a hash. */
2076 zns
= zebra_ns_lookup(NS_DEFAULT
);
2077 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2078 tmp_if
= (struct interface
*)rn
->info
;
2082 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2084 if (!if_is_operative(tmp_if
))
2086 vxl
= &zif
->l2info
.vxl
;
2088 if (zif
->brslave_info
.br_if
!= br_if
)
2091 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2100 zvni
= zvni_lookup(vxl
->vni
);
2104 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2106 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2107 * linked to the bridge
2108 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2111 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2113 struct zebra_ns
*zns
;
2114 struct route_node
*rn
;
2115 struct interface
*tmp_if
= NULL
;
2116 struct zebra_if
*zif
;
2117 struct zebra_l2info_bridge
*br
;
2118 struct zebra_l2info_vlan
*vl
;
2119 u_char bridge_vlan_aware
;
2122 /* Defensive check, caller expected to invoke only with valid bridge. */
2126 /* Determine if bridge is VLAN-aware or not */
2129 br
= &zif
->l2info
.br
;
2130 bridge_vlan_aware
= br
->vlan_aware
;
2132 /* Check oper status of the SVI. */
2133 if (!bridge_vlan_aware
)
2134 return if_is_operative(br_if
) ? br_if
: NULL
;
2136 /* Identify corresponding VLAN interface. */
2137 /* TODO: Optimize with a hash. */
2138 zns
= zebra_ns_lookup(NS_DEFAULT
);
2139 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2140 tmp_if
= (struct interface
*)rn
->info
;
2141 /* Check oper status of the SVI. */
2142 if (!tmp_if
|| !if_is_operative(tmp_if
))
2145 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2146 || zif
->link
!= br_if
)
2148 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2150 if (vl
->vid
== vid
) {
2156 return found
? tmp_if
: NULL
;
2160 * Install remote MAC into the kernel.
2162 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2164 struct zebra_if
*zif
;
2165 struct zebra_l2info_vxlan
*vxl
;
2168 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2171 zif
= zvni
->vxlan_if
->info
;
2174 vxl
= &zif
->l2info
.vxl
;
2176 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2178 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2179 mac
->fwd_info
.r_vtep_ip
, sticky
);
2183 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2184 * moves to remote, we have to uninstall any existing local entry first.
2186 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2188 struct zebra_if
*zif
;
2189 struct zebra_l2info_vxlan
*vxl
;
2190 struct in_addr vtep_ip
= {.s_addr
= 0};
2191 struct zebra_ns
*zns
;
2192 struct interface
*ifp
;
2194 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2197 if (!zvni
->vxlan_if
) {
2198 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2203 zif
= zvni
->vxlan_if
->info
;
2206 vxl
= &zif
->l2info
.vxl
;
2209 zns
= zebra_ns_lookup(NS_DEFAULT
);
2210 ifp
= if_lookup_by_index_per_ns(zns
,
2211 mac
->fwd_info
.local
.ifindex
);
2212 if (!ifp
) // unexpected
2215 ifp
= zvni
->vxlan_if
;
2216 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2219 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2224 * Install MAC hash entry - called upon access VLAN change.
2226 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2229 struct mac_walk_ctx
*wctx
= ctxt
;
2231 mac
= (zebra_mac_t
*)backet
->data
;
2235 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2236 zvni_mac_install(wctx
->zvni
, mac
);
2240 * Decrement neighbor refcount of MAC; uninstall and free it if
2243 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2246 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2247 || !list_isempty(mac
->neigh_list
))
2251 zvni_mac_uninstall(zvni
, mac
, 0);
2253 zvni_mac_del(zvni
, mac
);
2257 * Read and populate local MACs and neighbors corresponding to this VNI.
2259 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
2260 struct interface
*ifp
)
2262 struct zebra_ns
*zns
;
2263 struct zebra_if
*zif
;
2264 struct interface
*vlan_if
;
2265 struct zebra_l2info_vxlan
*vxl
;
2266 struct interface
*vrr_if
;
2269 vxl
= &zif
->l2info
.vxl
;
2270 zns
= zebra_ns_lookup(NS_DEFAULT
);
2272 if (IS_ZEBRA_DEBUG_VXLAN
)
2274 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2275 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2276 zif
->brslave_info
.bridge_ifindex
);
2278 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2279 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2282 if (advertise_gw_macip_enabled(zvni
)) {
2283 /* Add SVI MAC-IP */
2284 zvni_add_macip_for_intf(vlan_if
, zvni
);
2286 /* Add VRR MAC-IP - if any*/
2287 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2289 zvni_add_macip_for_intf(vrr_if
, zvni
);
2292 neigh_read_for_vlan(zns
, vlan_if
);
2297 * Hash function for VNI.
2299 static unsigned int vni_hash_keymake(void *p
)
2301 const zebra_vni_t
*zvni
= p
;
2303 return (jhash_1word(zvni
->vni
, 0));
2307 * Compare 2 VNI hash entries.
2309 static int vni_hash_cmp(const void *p1
, const void *p2
)
2311 const zebra_vni_t
*zvni1
= p1
;
2312 const zebra_vni_t
*zvni2
= p2
;
2314 return (zvni1
->vni
== zvni2
->vni
);
2318 * Callback to allocate VNI hash entry.
2320 static void *zvni_alloc(void *p
)
2322 const zebra_vni_t
*tmp_vni
= p
;
2325 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2326 zvni
->vni
= tmp_vni
->vni
;
2327 return ((void *)zvni
);
2331 * Look up VNI hash entry.
2333 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2335 struct zebra_vrf
*zvrf
;
2336 zebra_vni_t tmp_vni
;
2337 zebra_vni_t
*zvni
= NULL
;
2339 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2341 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2343 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2349 * Add VNI hash entry.
2351 static zebra_vni_t
*zvni_add(vni_t vni
)
2353 struct zebra_vrf
*zvrf
;
2354 zebra_vni_t tmp_zvni
;
2355 zebra_vni_t
*zvni
= NULL
;
2357 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2359 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2361 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2364 /* Create hash table for MAC */
2366 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2368 /* Create hash table for neighbors */
2369 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2370 "Zebra VNI Neighbor Table");
2376 * Delete VNI hash entry.
2378 static int zvni_del(zebra_vni_t
*zvni
)
2380 struct zebra_vrf
*zvrf
;
2381 zebra_vni_t
*tmp_zvni
;
2383 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2386 zvni
->vxlan_if
= NULL
;
2388 /* Free the neighbor hash table. */
2389 hash_free(zvni
->neigh_table
);
2390 zvni
->neigh_table
= NULL
;
2392 /* Free the MAC hash table. */
2393 hash_free(zvni
->mac_table
);
2394 zvni
->mac_table
= NULL
;
2396 /* Free the VNI hash entry and allocated memory. */
2397 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2399 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2405 * Inform BGP about local VNI addition.
2407 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2409 struct zserv
*client
;
2412 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2413 /* BGP may not be running. */
2420 zserv_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2421 stream_putl(s
, zvni
->vni
);
2422 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2423 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2425 /* Write packet size. */
2426 stream_putw_at(s
, 0, stream_get_endp(s
));
2428 if (IS_ZEBRA_DEBUG_VXLAN
)
2429 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2430 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2431 vrf_id_to_name(zvni
->vrf_id
),
2432 zebra_route_string(client
->proto
));
2434 client
->vniadd_cnt
++;
2435 return zebra_server_send_message(client
);
2439 * Inform BGP about local VNI deletion.
2441 static int zvni_send_del_to_client(vni_t vni
)
2443 struct zserv
*client
;
2446 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2447 /* BGP may not be running. */
2454 zserv_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2455 stream_putl(s
, vni
);
2457 /* Write packet size. */
2458 stream_putw_at(s
, 0, stream_get_endp(s
));
2460 if (IS_ZEBRA_DEBUG_VXLAN
)
2461 zlog_debug("Send VNI_DEL %u to %s", vni
,
2462 zebra_route_string(client
->proto
));
2464 client
->vnidel_cnt
++;
2465 return zebra_server_send_message(client
);
2469 * Build the VNI hash table by going over the VxLAN interfaces. This
2470 * is called when EVPN (advertise-all-vni) is enabled.
2472 static void zvni_build_hash_table()
2474 struct zebra_ns
*zns
;
2475 struct route_node
*rn
;
2476 struct interface
*ifp
;
2478 /* Walk VxLAN interfaces and create VNI hash. */
2479 zns
= zebra_ns_lookup(NS_DEFAULT
);
2480 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2482 struct zebra_if
*zif
;
2483 struct zebra_l2info_vxlan
*vxl
;
2485 ifp
= (struct interface
*)rn
->info
;
2489 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2492 vxl
= &zif
->l2info
.vxl
;
2495 if (is_vni_l3(vni
)) {
2496 zebra_l3vni_t
*zl3vni
= NULL
;
2498 if (IS_ZEBRA_DEBUG_VXLAN
)
2499 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2500 ifp
->name
, ifp
->ifindex
, vni
);
2502 zl3vni
= zl3vni_lookup(vni
);
2505 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
2506 ifp
->name
, ifp
->ifindex
, vni
);
2510 /* associate with vxlan_if */
2511 zl3vni
->vxlan_if
= ifp
;
2513 /* we need to associate with SVI.
2514 * we can associate with svi-if only after association
2515 * with vxlan-intf is complete */
2516 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2518 if (is_l3vni_oper_up(zl3vni
))
2519 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2522 zebra_vni_t
*zvni
= NULL
;
2523 zebra_l3vni_t
*zl3vni
= NULL
;
2524 struct interface
*vlan_if
= NULL
;
2526 if (IS_ZEBRA_DEBUG_VXLAN
)
2528 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2529 ifp
->name
, ifp
->ifindex
, vni
,
2530 inet_ntoa(vxl
->vtep_ip
));
2532 /* VNI hash entry is not expected to exist. */
2533 zvni
= zvni_lookup(vni
);
2536 "VNI hash already present for IF %s(%u) L2-VNI %u",
2537 ifp
->name
, ifp
->ifindex
, vni
);
2541 zvni
= zvni_add(vni
);
2544 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2545 ifp
->name
, ifp
->ifindex
, vni
);
2549 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2550 zvni
->vxlan_if
= ifp
;
2551 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2552 zif
->brslave_info
.br_if
);
2554 zvni
->vrf_id
= vlan_if
->vrf_id
;
2555 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2557 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2561 /* Inform BGP if intf is up and mapped to bridge. */
2562 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2563 zvni_send_add_to_client(zvni
);
2569 * See if remote VTEP matches with prefix.
2571 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2573 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2577 * Locate remote VTEP in VNI hash table.
2579 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2581 zebra_vtep_t
*zvtep
;
2586 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2587 if (zvni_vtep_match(vtep_ip
, zvtep
))
2595 * Add remote VTEP to VNI hash table.
2597 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2599 zebra_vtep_t
*zvtep
;
2601 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2603 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2607 zvtep
->vtep_ip
= *vtep_ip
;
2610 zvni
->vteps
->prev
= zvtep
;
2611 zvtep
->next
= zvni
->vteps
;
2612 zvni
->vteps
= zvtep
;
2618 * Remove remote VTEP from VNI hash table.
2620 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2623 zvtep
->next
->prev
= zvtep
->prev
;
2625 zvtep
->prev
->next
= zvtep
->next
;
2627 zvni
->vteps
= zvtep
->next
;
2629 zvtep
->prev
= zvtep
->next
= NULL
;
2630 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2636 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2637 * uninstall from kernel if asked to.
2639 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2641 zebra_vtep_t
*zvtep
, *zvtep_next
;
2646 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2647 zvtep_next
= zvtep
->next
;
2649 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2650 zvni_vtep_del(zvni
, zvtep
);
2657 * Install remote VTEP into the kernel.
2659 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2661 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2665 * Uninstall remote VTEP from the kernel.
2667 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2669 if (!zvni
->vxlan_if
) {
2670 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2675 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2679 * Cleanup VNI/VTEP and update kernel
2681 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2683 zebra_vni_t
*zvni
= NULL
;
2684 zebra_l3vni_t
*zl3vni
= NULL
;
2686 zvni
= (zebra_vni_t
*)backet
->data
;
2690 /* remove from l3-vni list */
2691 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
2693 listnode_delete(zl3vni
->l2vnis
, zvni
);
2695 /* Free up all neighbors and MACs, if any. */
2696 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2697 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2699 /* Free up all remote VTEPs, if any. */
2700 zvni_vtep_del_all(zvni
, 1);
2702 /* Delete the hash entry. */
2707 * Look up MAC hash entry.
2709 /*static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
2710 struct ethaddr *rmac)
2715 memset(&tmp, 0, sizeof(tmp));
2716 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
2717 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
2723 * Callback to allocate RMAC hash entry.
2725 /*static void *zl3vni_rmac_alloc(void *p)
2727 const zebra_mac_t *tmp_rmac = p;
2730 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
2733 return ((void *)zrmac);
2737 * Add RMAC entry to l3-vni
2739 /*static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
2740 struct ethaddr *rmac)
2742 zebra_mac_t tmp_rmac;
2743 zebra_mac_t *zrmac = NULL;
2745 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
2746 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
2747 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
2750 zrmac->neigh_list = list_new();
2751 zrmac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
2759 /*static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni,
2762 zebra_mac_t *tmp_rmac;
2764 list_delete(zrmac->neigh_list);
2766 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
2768 XFREE(MTYPE_MAC, tmp_rmac);
2774 * Install remote RMAC into the kernel.
2776 /*static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni,
2779 struct zebra_if *zif = NULL;
2780 struct zebra_l2info_vxlan *vxl = NULL;
2782 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
2783 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
2786 zif = zl3vni->vxlan_if->info;
2790 vxl = &zif->l2info.vxl;
2792 return kernel_add_mac(zl3vni->vxlan_if, vxl->access_vlan,
2794 zrmac->fwd_info.r_vtep_ip, 0);
2798 * Uninstall remote RMAC from the kernel.
2800 /*static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
2803 char buf[ETHER_ADDR_STRLEN];
2804 struct zebra_if *zif = NULL;
2805 struct zebra_l2info_vxlan *vxl = NULL;
2807 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
2808 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
2811 if (!zl3vni->vxlan_if) {
2812 zlog_err("RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
2813 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
2814 zl3vni->vni, zl3vni);
2818 zif = zl3vni->vxlan_if->info;
2822 vxl = &zif->l2info.vxl;
2824 return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
2825 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
2829 * Look up nh hash entry on a l3-vni.
2831 /*static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
2837 memset(&tmp, 0, sizeof(tmp));
2838 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
2839 n = hash_lookup(zl3vni->nh_table, &tmp);
2846 * Callback to allocate NH hash entry on L3-VNI.
2848 /*static void *zl3vni_nh_alloc(void *p)
2850 const zebra_neigh_t *tmp_n = p;
2853 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
2860 * Add neighbor entry.
2862 /*static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
2864 struct ethaddr *mac)
2866 zebra_neigh_t tmp_n;
2867 zebra_neigh_t *n = NULL;
2869 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
2870 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
2871 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
2874 memcpy(&n->emac, mac, ETH_ALEN);
2880 * Delete neighbor entry.
2882 /*static int zl3vni_nh_del(zebra_l3vni_t *zl3vni,
2885 zebra_neigh_t *tmp_n;
2887 tmp_n = hash_release(zl3vni->nh_table, n);
2889 XFREE(MTYPE_NEIGH, tmp_n);
2895 * Install remote nh as neigh into the kernel.
2897 /*static int zl3vni_nh_install(zebra_l3vni_t *zl3vni,
2900 if (!is_l3vni_oper_up(zl3vni))
2903 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
2904 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
2907 return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
2911 * Uninstall remote nh from the kernel.
2913 /*static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni,
2916 if (!is_l3vni_oper_up(zl3vni))
2919 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
2920 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
2923 return kernel_del_neigh(zl3vni->svi_if, &n->ip);
2927 * Hash function for L3 VNI.
2929 static unsigned int l3vni_hash_keymake(void *p
)
2931 const zebra_l3vni_t
*zl3vni
= p
;
2933 return jhash_1word(zl3vni
->vni
, 0);
2937 * Compare 2 L3 VNI hash entries.
2939 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
2941 const zebra_l3vni_t
*zl3vni1
= p1
;
2942 const zebra_l3vni_t
*zl3vni2
= p2
;
2944 return (zl3vni1
->vni
== zl3vni2
->vni
);
2948 * Callback to allocate L3 VNI hash entry.
2950 static void *zl3vni_alloc(void *p
)
2952 zebra_l3vni_t
*zl3vni
= NULL
;
2953 const zebra_l3vni_t
*tmp_l3vni
= p
;
2955 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
2956 zl3vni
->vni
= tmp_l3vni
->vni
;
2957 return ((void *)zl3vni
);
2961 * Look up L3 VNI hash entry.
2963 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
2965 struct zebra_ns
*zns
;
2966 zebra_l3vni_t tmp_l3vni
;
2967 zebra_l3vni_t
*zl3vni
= NULL
;
2969 zns
= zebra_ns_lookup(NS_DEFAULT
);
2971 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
2972 tmp_l3vni
.vni
= vni
;
2973 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
2979 * Add L3 VNI hash entry.
2981 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
2983 zebra_l3vni_t tmp_zl3vni
;
2984 struct zebra_ns
*zns
= NULL
;
2985 zebra_l3vni_t
*zl3vni
= NULL
;
2987 zns
= zebra_ns_lookup(NS_DEFAULT
);
2990 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
2991 tmp_zl3vni
.vni
= vni
;
2993 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
2996 zl3vni
->vrf_id
= vrf_id
;
2997 zl3vni
->svi_if
= NULL
;
2998 zl3vni
->vxlan_if
= NULL
;
2999 zl3vni
->l2vnis
= list_new();
3000 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3002 /* Create hash table for remote RMAC */
3003 zl3vni
->rmac_table
=
3004 hash_create(mac_hash_keymake
, mac_cmp
,
3005 "Zebra L3-VNI RMAC-Table");
3007 /* Create hash table for neighbors */
3008 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3009 "Zebra L3-VNI next-hop table");
3015 * Delete L3 VNI hash entry.
3017 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3019 struct zebra_ns
*zns
;
3020 zebra_l3vni_t
*tmp_zl3vni
;
3022 zns
= zebra_ns_lookup(NS_DEFAULT
);
3025 /* free the list of l2vnis */
3026 list_delete_and_null(&zl3vni
->l2vnis
);
3027 zl3vni
->l2vnis
= NULL
;
3029 /* Free the rmac table */
3030 hash_free(zl3vni
->rmac_table
);
3031 zl3vni
->rmac_table
= NULL
;
3033 /* Free the nh table */
3034 hash_free(zl3vni
->nh_table
);
3035 zl3vni
->nh_table
= NULL
;
3037 /* Free the VNI hash entry and allocated memory. */
3038 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3040 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3045 static int is_vni_l3(vni_t vni
)
3047 zebra_l3vni_t
*zl3vni
= NULL
;
3049 zl3vni
= zl3vni_lookup(vni
);
3055 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3057 struct zebra_ns
*zns
= NULL
;
3058 struct route_node
*rn
= NULL
;
3059 struct interface
*ifp
= NULL
;
3061 /* loop through all vxlan-interface */
3062 zns
= zebra_ns_lookup(NS_DEFAULT
);
3063 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3065 struct zebra_if
*zif
= NULL
;
3066 struct zebra_l2info_vxlan
*vxl
= NULL
;
3068 ifp
= (struct interface
*)rn
->info
;
3073 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3076 vxl
= &zif
->l2info
.vxl
;
3077 if (vxl
->vni
== zl3vni
->vni
)
3084 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3086 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3087 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3089 if (!zl3vni
->vxlan_if
)
3092 zif
= zl3vni
->vxlan_if
->info
;
3096 vxl
= &zif
->l2info
.vxl
;
3098 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3101 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3103 struct zebra_vrf
*zvrf
= NULL
;
3105 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3109 return zl3vni_lookup(zvrf
->l3vni
);
3113 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3114 * neighbor notifications, to see if they are of interest.
3116 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3117 struct interface
*br_if
)
3121 u_char bridge_vlan_aware
= 0;
3122 zebra_l3vni_t
*zl3vni
= NULL
;
3123 struct zebra_ns
*zns
= NULL
;
3124 struct route_node
*rn
= NULL
;
3125 struct zebra_if
*zif
= NULL
;
3126 struct interface
*tmp_if
= NULL
;
3127 struct zebra_l2info_bridge
*br
= NULL
;
3128 struct zebra_l2info_vxlan
*vxl
= NULL
;
3133 /* Make sure the linked interface is a bridge. */
3134 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3137 /* Determine if bridge is VLAN-aware or not */
3140 br
= &zif
->l2info
.br
;
3141 bridge_vlan_aware
= br
->vlan_aware
;
3142 if (bridge_vlan_aware
) {
3143 struct zebra_l2info_vlan
*vl
;
3145 if (!IS_ZEBRA_IF_VLAN(ifp
))
3150 vl
= &zif
->l2info
.vl
;
3154 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3155 /* TODO: Optimize with a hash. */
3156 zns
= zebra_ns_lookup(NS_DEFAULT
);
3157 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3158 tmp_if
= (struct interface
*)rn
->info
;
3162 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3164 if (!if_is_operative(tmp_if
))
3166 vxl
= &zif
->l2info
.vxl
;
3168 if (zif
->brslave_info
.br_if
!= br_if
)
3171 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3180 zl3vni
= zl3vni_lookup(vxl
->vni
);
3185 * Inform BGP about l3-vni.
3187 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3189 struct stream
*s
= NULL
;
3190 struct zserv
*client
= NULL
;
3191 struct ethaddr rmac
;
3192 char buf
[ETHER_ADDR_STRLEN
];
3194 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3195 /* BGP may not be running. */
3200 memset(&rmac
, 0, sizeof(struct ethaddr
));
3201 zl3vni_get_rmac(zl3vni
, &rmac
);
3206 zserv_create_header(s
, ZEBRA_L3VNI_ADD
,
3207 zl3vni_vrf_id(zl3vni
));
3208 stream_putl(s
, zl3vni
->vni
);
3209 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3211 /* Write packet size. */
3212 stream_putw_at(s
, 0, stream_get_endp(s
));
3214 if (IS_ZEBRA_DEBUG_VXLAN
)
3215 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s to %s",
3216 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3217 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3218 zebra_route_string(client
->proto
));
3220 client
->l3vniadd_cnt
++;
3221 return zebra_server_send_message(client
);
3225 * Inform BGP about local l3-VNI deletion.
3227 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3229 struct stream
*s
= NULL
;
3230 struct zserv
*client
= NULL
;
3232 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3233 /* BGP may not be running. */
3240 zserv_create_header(s
, ZEBRA_L3VNI_DEL
,
3241 zl3vni_vrf_id(zl3vni
));
3242 stream_putl(s
, zl3vni
->vni
);
3244 /* Write packet size. */
3245 stream_putw_at(s
, 0, stream_get_endp(s
));
3247 if (IS_ZEBRA_DEBUG_VXLAN
)
3248 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3250 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3251 zebra_route_string(client
->proto
));
3253 client
->l3vnidel_cnt
++;
3254 return zebra_server_send_message(client
);
3257 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3259 if (IS_ZEBRA_DEBUG_VXLAN
)
3260 zlog_debug("L3-VNI %u is UP - send add to BGP and update all neigh enries",
3263 /* send l3vni add to BGP */
3264 zl3vni_send_add_to_client(zl3vni
);
3267 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3269 if (IS_ZEBRA_DEBUG_VXLAN
)
3270 zlog_debug("L3-VNI %u is Down - send del to BGP and update all neigh enries",
3273 /* send l3-vni del to BGP*/
3274 zl3vni_send_del_to_client(zl3vni
);
3277 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
,
3280 zebra_vni_t
*zvni
= (zebra_vni_t
*) backet
->data
;
3281 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*) ctxt
;
3283 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3284 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3287 /* l3vni from zvni */
3288 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
)
3290 zebra_l3vni_t
*zl3vni
= NULL
;
3292 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3293 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3299 /* rmac from l3vni */
3300 static void zvni_get_rmac(zebra_vni_t
*zvni
,
3301 struct ethaddr
*rmac
)
3303 zebra_l3vni_t
*zl3vni
= NULL
;
3305 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3306 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3310 memcpy(rmac
->octet
, zl3vni
->svi_if
->hw_addr
, ETH_ALEN
);
3314 * handle transition of vni from l2 to l3 and vice versa
3316 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
,
3319 zebra_vni_t
*zvni
= NULL
;
3321 /* There is a possibility that VNI notification was already received
3322 * from kernel and we programmed it as L2-VNI
3323 * In such a case we need to delete this L2-VNI first, so
3324 * that it can be reprogrammed as L3-VNI in the system. It is also
3325 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3326 * interface is still present in kernel. In this case to keep it
3327 * symmetric, we will delete the l3-vni and reprogram it as l2-vni */
3329 /* Locate hash entry */
3330 zvni
= zvni_lookup(vni
);
3334 if (IS_ZEBRA_DEBUG_VXLAN
)
3335 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3338 /* Delete VNI from BGP. */
3339 zvni_send_del_to_client(zvni
->vni
);
3341 /* Free up all neighbors and MAC, if any. */
3342 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3343 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3345 /* Free up all remote VTEPs, if any. */
3346 zvni_vtep_del_all(zvni
, 0);
3348 /* Delete the hash entry. */
3349 if (zvni_del(zvni
)) {
3350 zlog_err("Failed to del VNI hash %p, VNI %u",
3355 /* TODO_MITESH: This needs to be thought through. We don't have
3356 * enough information at this point to reprogram the vni as
3357 * l2-vni. One way is to store the required info in l3-vni and
3358 * used it solely for this purpose */
3364 /* Public functions */
3366 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
,
3370 zebra_l3vni_t
*zl3vni
;
3371 u_int32_t num_rmacs
;
3372 struct rmac_walk_ctx wctx
;
3373 json_object
*json
= NULL
;
3374 json_object
*json_rmac
= NULL
;
3376 if (!is_evpn_enabled())
3379 zl3vni
= zl3vni_lookup(l3vni
);
3382 vty_out(vty
, "{}\n");
3384 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3387 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3392 json
= json_object_new_object();
3393 json_rmac
= json_object_new_array();
3396 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3398 wctx
.json
= json_rmac
;
3402 "Number of Remote RMACs known for this VNI: %u\n",
3404 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
3405 "Remote VTEP", "Refcnt");
3407 json_object_int_add(json
, "numRmacs", num_rmacs
);
3409 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3412 json_object_object_add(json
, "rmacs", json_rmac
);
3413 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3414 json
, JSON_C_TO_STRING_PRETTY
));
3415 json_object_free(json
);
3419 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
,
3422 struct zebra_ns
*zns
= NULL
;
3423 struct rmac_walk_ctx wctx
;
3424 json_object
*json
= NULL
;
3426 if (!is_evpn_enabled()) {
3428 vty_out(vty
, "{}\n");
3432 zns
= zebra_ns_lookup(NS_DEFAULT
);
3437 json
= json_object_new_object();
3439 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3443 hash_iterate(zns
->l3vni_table
, zl3vni_print_rmac_hash_all_vni
, &wctx
);
3446 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3447 json
, JSON_C_TO_STRING_PRETTY
));
3448 json_object_free(json
);
3452 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
,
3457 struct nh_walk_ctx
*wctx
;
3458 json_object
*json
= NULL
;
3459 json_object
*json_nh
= NULL
;
3460 zebra_l3vni_t
*zl3vni
= NULL
;
3462 if (!is_evpn_enabled())
3465 zl3vni
= zl3vni_lookup(l3vni
);
3468 vty_out(vty
, "{}\n");
3470 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3474 num_nh
= hashcount(zl3vni
->nh_table
);
3479 json
= json_object_new_object();
3480 json_nh
= json_object_new_array();
3484 wctx
->json
= json_nh
;
3488 "Number of NH Neighbors known for this VNI: %u\n",
3490 vty_out(vty
, "%15s %-17s %6s\n", "IP",
3493 json_object_int_add(json
, "numNh", num_nh
);
3495 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
3498 json_object_object_add(json
, "next-hop-neighbors", json_nh
);
3499 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3500 json
, JSON_C_TO_STRING_PRETTY
));
3501 json_object_free(json
);
3505 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
,
3512 * Display L3 VNI information (VTY command handler).
3514 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
3517 json_object
*json
= NULL
;
3518 zebra_l3vni_t
*zl3vni
= NULL
;
3523 if (!is_evpn_enabled())
3526 zl3vni
= zl3vni_lookup(vni
);
3529 vty_out(vty
, "{}\n");
3531 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3536 json
= json_object_new_object();
3538 zl3vni_print(zl3vni
, (void *)args
);
3541 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3542 json
, JSON_C_TO_STRING_PRETTY
));
3543 json_object_free(json
);
3548 * Display L3 VNI hash table (VTY command handler).
3550 void zebra_vxlan_print_l3vnis(struct vty
*vty
, u_char use_json
)
3554 json_object
*json
= NULL
;
3555 struct zebra_ns
*zns
= NULL
;
3560 if (!is_evpn_enabled())
3563 zns
= zebra_ns_lookup(NS_DEFAULT
);
3566 num_vnis
= hashcount(zns
->l3vni_table
);
3569 vty_out(vty
, "{}\n");
3574 json
= json_object_new_object();
3575 json_object_int_add(json
, "numVnis", num_vnis
);
3577 vty_out(vty
, "Number of L3 VNIs: %u\n", num_vnis
);
3578 vty_out(vty
, "%-10s %-20s %-20s %-5s %-37s %-18s\n", "VNI",
3579 "Vx-intf", "L3-SVI", "State", "VRF", "Rmac");
3582 hash_iterate(zns
->l3vni_table
,
3583 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
3587 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3588 json
, JSON_C_TO_STRING_PRETTY
));
3589 json_object_free(json
);
3594 * Display Neighbors for a VNI (VTY command handler).
3596 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3597 vni_t vni
, u_char use_json
)
3600 u_int32_t num_neigh
;
3601 struct neigh_walk_ctx wctx
;
3602 json_object
*json
= NULL
;
3604 if (!is_evpn_enabled())
3606 zvni
= zvni_lookup(vni
);
3609 vty_out(vty
, "{}\n");
3611 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3614 num_neigh
= hashcount(zvni
->neigh_table
);
3619 json
= json_object_new_object();
3621 /* Since we have IPv6 addresses to deal with which can vary widely in
3622 * size, we try to be a bit more elegant in display by first computing
3623 * the maximum width.
3625 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
3628 wctx
.addr_width
= 15;
3630 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
3634 "Number of ARPs (local and remote) known for this VNI: %u\n",
3636 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
3637 "Type", "MAC", "Remote VTEP");
3639 json_object_int_add(json
, "numArpNd", num_neigh
);
3641 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
3643 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3644 json
, JSON_C_TO_STRING_PRETTY
));
3645 json_object_free(json
);
3650 * Display neighbors across all VNIs (VTY command handler).
3652 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3655 json_object
*json
= NULL
;
3658 if (!is_evpn_enabled())
3662 json
= json_object_new_object();
3666 hash_iterate(zvrf
->vni_table
,
3667 (void (*)(struct hash_backet
*,
3668 void *))zvni_print_neigh_hash_all_vni
,
3671 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3672 json
, JSON_C_TO_STRING_PRETTY
));
3673 json_object_free(json
);
3678 * Display specific neighbor for a VNI, if present (VTY command handler).
3680 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
3681 struct zebra_vrf
*zvrf
, vni_t vni
,
3682 struct ipaddr
*ip
, u_char use_json
)
3686 json_object
*json
= NULL
;
3688 if (!is_evpn_enabled())
3690 zvni
= zvni_lookup(vni
);
3693 vty_out(vty
, "{}\n");
3695 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3698 n
= zvni_neigh_lookup(zvni
, ip
);
3702 "%% Requested neighbor does not exist in VNI %u\n",
3707 json
= json_object_new_object();
3709 zvni_print_neigh(n
, vty
, json
);
3712 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3713 json
, JSON_C_TO_STRING_PRETTY
));
3714 json_object_free(json
);
3719 * Display neighbors for a VNI from specific VTEP (VTY command handler).
3720 * By definition, these are remote neighbors.
3722 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3723 vni_t vni
, struct in_addr vtep_ip
,
3727 u_int32_t num_neigh
;
3728 struct neigh_walk_ctx wctx
;
3729 json_object
*json
= NULL
;
3731 if (!is_evpn_enabled())
3733 zvni
= zvni_lookup(vni
);
3736 vty_out(vty
, "{}\n");
3738 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3741 num_neigh
= hashcount(zvni
->neigh_table
);
3745 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
3748 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
3749 wctx
.r_vtep_ip
= vtep_ip
;
3751 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
3754 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3755 json
, JSON_C_TO_STRING_PRETTY
));
3756 json_object_free(json
);
3761 * Display MACs for a VNI (VTY command handler).
3763 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3764 vni_t vni
, u_char use_json
)
3768 struct mac_walk_ctx wctx
;
3769 json_object
*json
= NULL
;
3770 json_object
*json_mac
= NULL
;
3772 if (!is_evpn_enabled())
3774 zvni
= zvni_lookup(vni
);
3777 vty_out(vty
, "{}\n");
3779 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3782 num_macs
= num_valid_macs(zvni
);
3787 json
= json_object_new_object();
3788 json_mac
= json_object_new_object();
3791 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
3794 wctx
.json
= json_mac
;
3798 "Number of MACs (local and remote) known for this VNI: %u\n",
3800 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
3801 "Intf/Remote VTEP", "VLAN");
3803 json_object_int_add(json
, "numMacs", num_macs
);
3805 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
3808 json_object_object_add(json
, "macs", json_mac
);
3809 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3810 json
, JSON_C_TO_STRING_PRETTY
));
3811 json_object_free(json
);
3816 * Display MACs for all VNIs (VTY command handler).
3818 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3821 struct mac_walk_ctx wctx
;
3822 json_object
*json
= NULL
;
3824 if (!is_evpn_enabled()) {
3826 vty_out(vty
, "{}\n");
3830 json
= json_object_new_object();
3832 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
3835 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
3838 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3839 json
, JSON_C_TO_STRING_PRETTY
));
3840 json_object_free(json
);
3845 * Display MACs for all VNIs (VTY command handler).
3847 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
3848 struct zebra_vrf
*zvrf
,
3849 struct in_addr vtep_ip
,
3852 struct mac_walk_ctx wctx
;
3853 json_object
*json
= NULL
;
3855 if (!is_evpn_enabled())
3859 json
= json_object_new_object();
3861 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
3863 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
3864 wctx
.r_vtep_ip
= vtep_ip
;
3866 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
3869 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3870 json
, JSON_C_TO_STRING_PRETTY
));
3871 json_object_free(json
);
3876 * Display specific MAC for a VNI, if present (VTY command handler).
3878 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3879 vni_t vni
, struct ethaddr
*macaddr
)
3884 if (!is_evpn_enabled())
3886 zvni
= zvni_lookup(vni
);
3888 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3891 mac
= zvni_mac_lookup(zvni
, macaddr
);
3893 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
3898 zvni_print_mac(mac
, vty
);
3902 * Display MACs for a VNI from specific VTEP (VTY command handler).
3904 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3905 vni_t vni
, struct in_addr vtep_ip
,
3910 struct mac_walk_ctx wctx
;
3911 json_object
*json
= NULL
;
3912 json_object
*json_mac
= NULL
;
3914 if (!is_evpn_enabled())
3916 zvni
= zvni_lookup(vni
);
3919 vty_out(vty
, "{}\n");
3921 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3924 num_macs
= num_valid_macs(zvni
);
3929 json
= json_object_new_object();
3930 json_mac
= json_object_new_object();
3933 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
3936 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
3937 wctx
.r_vtep_ip
= vtep_ip
;
3938 wctx
.json
= json_mac
;
3939 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
3942 json_object_int_add(json
, "numMacs", wctx
.count
);
3944 json_object_object_add(json
, "macs", json_mac
);
3945 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3946 json
, JSON_C_TO_STRING_PRETTY
));
3947 json_object_free(json
);
3953 * Display VNI information (VTY command handler).
3955 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
3959 json_object
*json
= NULL
;
3962 if (!is_evpn_enabled())
3964 zvni
= zvni_lookup(vni
);
3967 vty_out(vty
, "{}\n");
3969 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3973 json
= json_object_new_object();
3976 zvni_print(zvni
, (void *)args
);
3978 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3979 json
, JSON_C_TO_STRING_PRETTY
));
3980 json_object_free(json
);
3985 * Display VNI hash table (VTY command handler).
3987 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3991 json_object
*json
= NULL
;
3994 if (!is_evpn_enabled())
3996 num_vnis
= hashcount(zvrf
->vni_table
);
3999 vty_out(vty
, "{}\n");
4003 json
= json_object_new_object();
4004 json_object_string_add(json
, "advertiseGatewayMacip",
4005 zvrf
->advertise_gw_macip
? "Yes" : "No");
4006 json_object_int_add(json
, "numVnis", num_vnis
);
4008 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4009 zvrf
->advertise_gw_macip
? "Yes" : "No");
4010 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
4011 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
4012 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
4013 "# Remote VTEPs", "VRF");
4018 hash_iterate(zvrf
->vni_table
,
4019 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4023 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4024 json
, JSON_C_TO_STRING_PRETTY
));
4025 json_object_free(json
);
4030 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4031 * kernel. This may result in either the neighbor getting deleted from
4032 * our database or being re-added to the kernel (if it is a valid
4035 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4036 struct interface
*link_if
, struct ipaddr
*ip
)
4039 struct ethaddr rmac
;
4040 char buf
[INET6_ADDRSTRLEN
];
4041 char buf1
[INET6_ADDRSTRLEN
];
4042 char buf2
[ETHER_ADDR_STRLEN
];
4043 zebra_neigh_t
*n
= NULL
;
4044 zebra_vni_t
*zvni
= NULL
;
4045 zebra_mac_t
*zmac
= NULL
;
4047 memset(&rmac
, 0, sizeof(struct ethaddr
));
4049 /* We are only interested in neighbors on an SVI that resides on top
4050 * of a VxLAN bridge.
4052 zvni
= zvni_from_svi(ifp
, link_if
);
4055 if (!zvni
->vxlan_if
) {
4057 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4062 /* get the l3-vni */
4063 l3vni
= zvni_get_l3vni(zvni
);
4066 zvni_get_rmac(zvni
, &rmac
);
4068 if (IS_ZEBRA_DEBUG_VXLAN
)
4069 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u L3-VNI %u RMAC %s",
4070 ipaddr2str(ip
, buf
, sizeof(buf
)),
4071 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
4072 l3vni
, prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4074 /* If entry doesn't exist, nothing to do. */
4075 n
= zvni_neigh_lookup(zvni
, ip
);
4079 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4081 if (IS_ZEBRA_DEBUG_VXLAN
)
4083 "Trying to del a neigh %s without a mac %s on VNI %u",
4084 ipaddr2str(ip
, buf
, sizeof(buf
)),
4085 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4091 /* If it is a remote entry, the kernel has aged this out or someone has
4092 * deleted it, it needs to be re-installed as Quagga is the owner.
4094 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4095 zvni_neigh_install(zvni
, n
);
4099 /* Remove neighbor from BGP. */
4100 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4101 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
4104 /* Delete this neighbor entry. */
4105 zvni_neigh_del(zvni
, n
);
4107 /* see if the AUTO mac needs to be deleted */
4108 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4109 && !listcount(zmac
->neigh_list
))
4110 zvni_mac_del(zvni
, zmac
);
4116 * Handle neighbor add or update (on a VLAN device / L3 interface)
4119 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4120 struct interface
*link_if
,
4122 struct ethaddr
*macaddr
, u_int16_t state
,
4126 struct ethaddr rmac
;
4127 char buf
[ETHER_ADDR_STRLEN
];
4128 char buf1
[ETHER_ADDR_STRLEN
];
4129 char buf2
[INET6_ADDRSTRLEN
];
4130 zebra_vni_t
*zvni
= NULL
;
4131 zebra_neigh_t
*n
= NULL
;
4132 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4134 memset(&rmac
, 0, sizeof(struct ethaddr
));
4136 /* We are only interested in neighbors on an SVI that resides on top
4137 * of a VxLAN bridge.
4139 zvni
= zvni_from_svi(ifp
, link_if
);
4143 /* get the l3-vni */
4144 l3vni
= zvni_get_l3vni(zvni
);
4147 zvni_get_rmac(zvni
, &rmac
);
4149 if (IS_ZEBRA_DEBUG_VXLAN
)
4151 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u L3-VNI %u RMAC %s",
4152 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4153 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4154 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4156 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4158 /* create a dummy MAC if the MAC is not already present */
4159 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4161 if (IS_ZEBRA_DEBUG_VXLAN
)
4163 "AUTO MAC %s created for neigh %s on VNI %u",
4164 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4165 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
4167 zmac
= zvni_mac_add(zvni
, macaddr
);
4169 zlog_warn("Failed to add MAC %s VNI %u",
4170 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4175 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4176 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4177 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4180 /* If same entry already exists, it might be a change or it might be a
4181 * move from remote to local.
4183 n
= zvni_neigh_lookup(zvni
, ip
);
4185 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4186 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
4189 /* Update any params and return - client doesn't
4190 * care about a purely local change.
4192 n
->ifindex
= ifp
->ifindex
;
4196 /* If the MAC has changed,
4197 * need to issue a delete first
4198 * as this means a different MACIP route.
4199 * Also, need to do some unlinking/relinking.
4201 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4203 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4205 listnode_delete(old_zmac
->neigh_list
, n
);
4206 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4209 /* Set "local" forwarding info. */
4210 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4211 n
->ifindex
= ifp
->ifindex
;
4212 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4214 /* Link to new MAC */
4215 listnode_add_sort(zmac
->neigh_list
, n
);
4216 } else if (ext_learned
)
4217 /* The neighbor is remote and that is the notification we got.
4220 /* TODO: Evaluate if we need to do anything here. */
4223 /* Neighbor has moved from remote to local. */
4225 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4226 n
->r_vtep_ip
.s_addr
= 0;
4227 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4228 n
->ifindex
= ifp
->ifindex
;
4231 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4234 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4235 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4236 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4237 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4240 /* Set "local" forwarding info. */
4241 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4242 n
->ifindex
= ifp
->ifindex
;
4245 /* Before we program this in BGP, we need to check if MAC is locally
4247 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4248 if (IS_ZEBRA_DEBUG_VXLAN
)
4250 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4251 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4252 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4259 if (IS_ZEBRA_DEBUG_VXLAN
)
4260 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u L3-VNI %u with RMAC %s",
4261 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4262 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4265 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4267 ZEBRA_NEIGH_SET_ACTIVE(n
);
4269 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
4274 * Handle message from client to delete a remote MACIP for a VNI.
4276 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
4277 struct zebra_vrf
*zvrf
)
4281 struct ethaddr macaddr
;
4282 struct ethaddr rmac
;
4284 struct in_addr vtep_ip
;
4288 u_short l
= 0, ipa_len
;
4289 char buf
[ETHER_ADDR_STRLEN
];
4290 char buf1
[INET6_ADDRSTRLEN
];
4291 char buf3
[INET6_ADDRSTRLEN
];
4292 struct interface
*ifp
= NULL
;
4293 struct zebra_if
*zif
= NULL
;
4295 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4296 memset(&rmac
, 0, sizeof(struct ethaddr
));
4297 memset(&ip
, 0, sizeof(struct ipaddr
));
4298 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4302 while (l
< length
) {
4303 /* Obtain each remote MACIP and process. */
4304 /* Message contains VNI, followed by MAC followed by IP (if any)
4305 * followed by remote VTEP IP.
4309 memset(&ip
, 0, sizeof(ip
));
4310 STREAM_GETL(s
, vni
);
4311 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4312 STREAM_GETL(s
, ipa_len
);
4314 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4316 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4318 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4319 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4320 l
+= IPV4_MAX_BYTELEN
;
4321 stream_get(&rmac
.octet
, s
, ETH_ALEN
);
4324 if (IS_ZEBRA_DEBUG_VXLAN
)
4326 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s RMAC %s from %s",
4327 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4328 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4330 prefix_mac2str(&rmac
, buf3
, sizeof(buf3
)),
4331 zebra_route_string(client
->proto
));
4333 /* Locate VNI hash entry - expected to exist. */
4334 zvni
= zvni_lookup(vni
);
4336 if (IS_ZEBRA_DEBUG_VXLAN
)
4338 "Failed to locate VNI hash upon remote MACIP DEL, "
4343 ifp
= zvni
->vxlan_if
;
4346 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4352 /* If down or not mapped to a bridge, we're done. */
4353 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4356 /* The remote VTEP specified is normally expected to exist, but
4358 * possible that the peer may delete the VTEP before deleting
4360 * referring to the VTEP, in which case the handler (see
4362 * would have already deleted the MACs.
4364 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4367 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4369 n
= zvni_neigh_lookup(zvni
, &ip
);
4373 "Failed to locate MAC %s for neigh %s VNI %u",
4374 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4375 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4379 /* If the remote mac or neighbor doesn't exist there is nothing
4381 * to do. Otherwise, uninstall the entry and then remove it.
4386 /* Uninstall remote neighbor or MAC. */
4388 /* When the MAC changes for an IP, it is possible the
4390 * update the new MAC before trying to delete the "old"
4392 * (as these are two different MACIP routes). Do the
4394 * if the MAC matches.
4396 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4397 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
4400 zvni_neigh_uninstall(zvni
, n
);
4401 zvni_neigh_del(zvni
, n
);
4402 zvni_deref_ip2mac(zvni
, mac
, 1);
4405 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4406 zvni_process_neigh_on_remote_mac_del(zvni
,
4409 if (list_isempty(mac
->neigh_list
)) {
4410 zvni_mac_uninstall(zvni
, mac
, 0);
4411 zvni_mac_del(zvni
, mac
);
4413 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4423 * Handle message from client to add a remote MACIP for a VNI. This
4424 * could be just the add of a MAC address or the add of a neighbor
4427 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
4428 struct zebra_vrf
*zvrf
)
4432 struct ethaddr macaddr
;
4433 struct ethaddr rmac
;
4435 struct in_addr vtep_ip
;
4437 zebra_vtep_t
*zvtep
;
4438 zebra_mac_t
*mac
, *old_mac
;
4440 u_short l
= 0, ipa_len
;
4441 int update_mac
= 0, update_neigh
= 0;
4442 char buf
[ETHER_ADDR_STRLEN
];
4443 char buf1
[INET6_ADDRSTRLEN
];
4444 char buf2
[ETHER_ADDR_STRLEN
];
4446 struct interface
*ifp
= NULL
;
4447 struct zebra_if
*zif
= NULL
;
4449 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4450 memset(&rmac
, 0, sizeof(struct ethaddr
));
4451 memset(&ip
, 0, sizeof(struct ipaddr
));
4452 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4454 if (!EVPN_ENABLED(zvrf
)) {
4455 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
4456 __PRETTY_FUNCTION__
);
4462 while (l
< length
) {
4463 /* Obtain each remote MACIP and process. */
4464 /* Message contains VNI, followed by MAC followed by IP (if any)
4465 * followed by remote VTEP IP.
4467 update_mac
= update_neigh
= 0;
4470 memset(&ip
, 0, sizeof(ip
));
4471 STREAM_GETL(s
, vni
);
4472 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4473 STREAM_GETL(s
, ipa_len
);
4475 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4477 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4479 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4480 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4481 l
+= IPV4_MAX_BYTELEN
;
4483 /* Get 'sticky' flag. */
4484 STREAM_GETC(s
, sticky
);
4487 /* Get router mac */
4488 stream_get(&rmac
.octet
, s
, ETH_ALEN
);
4491 if (IS_ZEBRA_DEBUG_VXLAN
)
4493 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s RMAC %s from %s",
4494 sticky
? "sticky " : "",
4495 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4496 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4498 prefix_mac2str(&rmac
, buf2
, sizeof(buf2
)),
4499 zebra_route_string(client
->proto
));
4501 /* Locate VNI hash entry - expected to exist. */
4502 zvni
= zvni_lookup(vni
);
4505 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
4509 ifp
= zvni
->vxlan_if
;
4512 "VNI %u hash %p doesn't have intf upon remote MACIP add",
4518 /* If down or not mapped to a bridge, we're done. */
4519 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4522 /* The remote VTEP specified should normally exist, but it is
4524 * that when peering comes up, peer may advertise MACIP routes
4526 * advertising type-3 routes.
4528 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4530 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4532 "Failed to add remote VTEP, VNI %u zvni %p",
4537 zvni_vtep_install(zvni
, &vtep_ip
);
4540 /* First, check if the remote MAC is unknown or has a change. If
4542 * that needs to be updated first. Note that client could
4544 * MAC and MACIP separately or just install the latter.
4546 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4547 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4548 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
4550 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
4555 mac
= zvni_mac_add(zvni
, &macaddr
);
4558 "Failed to add MAC %s VNI %u Remote VTEP %s",
4559 prefix_mac2str(&macaddr
, buf
,
4561 vni
, inet_ntoa(vtep_ip
));
4565 /* Is this MAC created for a MACIP? */
4567 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4570 /* Set "auto" and "remote" forwarding info. */
4571 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4572 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4573 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4574 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4577 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4579 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4581 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
4583 /* Install the entry. */
4584 zvni_mac_install(zvni
, mac
);
4587 /* If there is no IP, continue - after clearing AUTO flag of
4590 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4594 /* Check if the remote neighbor itself is unknown or has a
4596 * If so, create or update and then install the entry.
4598 n
= zvni_neigh_lookup(zvni
, &ip
);
4599 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4600 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
4601 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
4606 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
4609 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
4610 ipaddr2str(&ip
, buf1
,
4612 prefix_mac2str(&macaddr
, buf
,
4614 vni
, inet_ntoa(vtep_ip
));
4618 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
4620 /* MAC change, update neigh list for old and new
4622 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
4624 listnode_delete(old_mac
->neigh_list
, n
);
4625 zvni_deref_ip2mac(zvni
, old_mac
, 1);
4627 listnode_add_sort(mac
->neigh_list
, n
);
4628 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
4631 /* Set "remote" forwarding info. */
4632 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4633 /* TODO: Handle MAC change. */
4634 n
->r_vtep_ip
= vtep_ip
;
4635 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4637 /* Install the entry. */
4638 zvni_neigh_install(zvni
, n
);
4647 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
4648 * us, this must involve a multihoming scenario. Treat this as implicit delete
4649 * of any prior local MAC.
4651 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
4652 struct interface
*br_if
,
4653 struct ethaddr
*macaddr
, vlanid_t vid
)
4655 struct zebra_if
*zif
;
4656 struct zebra_l2info_vxlan
*vxl
;
4660 char buf
[ETHER_ADDR_STRLEN
];
4665 vxl
= &zif
->l2info
.vxl
;
4668 /* Check if EVPN is enabled. */
4669 if (!is_evpn_enabled())
4672 /* Locate hash entry; it is expected to exist. */
4673 zvni
= zvni_lookup(vni
);
4677 /* If entry doesn't exist, nothing to do. */
4678 mac
= zvni_mac_lookup(zvni
, macaddr
);
4682 /* Is it a local entry? */
4683 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
4686 if (IS_ZEBRA_DEBUG_VXLAN
)
4688 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
4689 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4690 ifp
->name
, ifp
->ifindex
, vni
);
4692 /* Remove MAC from BGP. */
4693 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
4694 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
4695 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
4698 * If there are no neigh associated with the mac delete the mac
4699 * else mark it as AUTO for forward reference
4701 if (!listcount(mac
->neigh_list
)) {
4702 zvni_mac_del(zvni
, mac
);
4704 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4705 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4712 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
4713 * This can happen because the remote MAC entries are also added as "dynamic",
4714 * so the kernel can ageout the entry.
4716 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
4717 struct interface
*br_if
,
4718 struct ethaddr
*macaddr
, vlanid_t vid
)
4720 struct zebra_if
*zif
;
4721 struct zebra_l2info_vxlan
*vxl
;
4725 char buf
[ETHER_ADDR_STRLEN
];
4729 vxl
= &zif
->l2info
.vxl
;
4732 /* Check if EVPN is enabled. */
4733 if (!is_evpn_enabled())
4736 /* Locate hash entry; it is expected to exist. */
4737 zvni
= zvni_lookup(vni
);
4741 /* If entry doesn't exist, nothing to do. */
4742 mac
= zvni_mac_lookup(zvni
, macaddr
);
4746 /* Is it a remote entry? */
4747 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
4750 if (IS_ZEBRA_DEBUG_VXLAN
)
4751 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
4752 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4755 zvni_mac_install(zvni
, mac
);
4760 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
4762 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
4763 struct ethaddr
*macaddr
, vlanid_t vid
)
4767 char buf
[ETHER_ADDR_STRLEN
];
4770 /* We are interested in MACs only on ports or (port, VLAN) that
4773 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
4776 if (!zvni
->vxlan_if
) {
4777 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
4782 if (IS_ZEBRA_DEBUG_VXLAN
)
4783 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
4784 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4785 ifp
->ifindex
, vid
, zvni
->vni
);
4787 /* If entry doesn't exist, nothing to do. */
4788 mac
= zvni_mac_lookup(zvni
, macaddr
);
4792 /* Is it a local entry? */
4793 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
4796 /* Remove MAC from BGP. */
4797 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
4798 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
4799 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
4801 /* Update all the neigh entries associated with this mac */
4802 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
4805 * If there are no neigh associated with the mac delete the mac
4806 * else mark it as AUTO for forward reference
4808 if (!listcount(mac
->neigh_list
)) {
4809 zvni_mac_del(zvni
, mac
);
4811 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4812 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4819 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
4821 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
4822 struct interface
*br_if
,
4823 struct ethaddr
*macaddr
, vlanid_t vid
,
4828 char buf
[ETHER_ADDR_STRLEN
];
4832 /* We are interested in MACs only on ports or (port, VLAN) that
4835 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
4837 if (IS_ZEBRA_DEBUG_VXLAN
)
4839 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
4840 sticky
? "sticky " : "",
4841 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4842 ifp
->name
, ifp
->ifindex
, vid
);
4846 if (!zvni
->vxlan_if
) {
4847 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
4852 if (IS_ZEBRA_DEBUG_VXLAN
)
4854 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
4855 sticky
? "sticky " : "",
4856 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4857 ifp
->ifindex
, vid
, zvni
->vni
);
4859 /* If same entry already exists, nothing to do. */
4860 mac
= zvni_mac_lookup(zvni
, macaddr
);
4862 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
4863 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
4869 * return if nothing has changed.
4870 * inform bgp if sticky flag has changed
4871 * update locally and do not inform bgp if local
4872 * parameters like interface has changed
4874 if (mac_sticky
== sticky
4875 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
4876 && mac
->fwd_info
.local
.vid
== vid
) {
4877 if (IS_ZEBRA_DEBUG_VXLAN
)
4879 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
4880 "entry exists and has not changed ",
4881 sticky
? "sticky " : "",
4882 prefix_mac2str(macaddr
, buf
,
4884 ifp
->name
, ifp
->ifindex
, vid
,
4887 } else if (mac_sticky
!= sticky
) {
4890 add
= 0; /* This is an update of local
4893 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4895 * If we have already learned the MAC as a remote sticky
4897 * this is a operator error and we must log a warning
4899 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
4901 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
4902 prefix_mac2str(macaddr
, buf
,
4904 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
4912 mac
= zvni_mac_add(zvni
, macaddr
);
4914 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
4915 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4916 ifp
->name
, ifp
->ifindex
, vid
);
4921 /* Set "local" forwarding info. */
4922 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4923 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4924 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4925 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4926 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
4927 mac
->fwd_info
.local
.vid
= vid
;
4930 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4932 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4934 /* Inform BGP if required. */
4936 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
4937 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
4945 * Handle message from client to delete a remote VTEP for a VNI.
4947 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
4948 struct zebra_vrf
*zvrf
)
4953 struct in_addr vtep_ip
;
4955 zebra_vtep_t
*zvtep
;
4956 struct interface
*ifp
;
4957 struct zebra_if
*zif
;
4959 if (!is_evpn_enabled()) {
4960 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
4961 __PRETTY_FUNCTION__
);
4965 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
4966 zlog_err("Recv MACIP DEL for non-default VRF %u",
4973 while (l
< length
) {
4974 /* Obtain each remote VTEP and process. */
4975 STREAM_GETL(s
, vni
);
4977 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4978 l
+= IPV4_MAX_BYTELEN
;
4980 if (IS_ZEBRA_DEBUG_VXLAN
)
4981 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
4982 inet_ntoa(vtep_ip
), vni
,
4983 zebra_route_string(client
->proto
));
4985 /* Locate VNI hash entry - expected to exist. */
4986 zvni
= zvni_lookup(vni
);
4988 if (IS_ZEBRA_DEBUG_VXLAN
)
4990 "Failed to locate VNI hash upon remote VTEP DEL, "
4996 ifp
= zvni
->vxlan_if
;
4999 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5005 /* If down or not mapped to a bridge, we're done. */
5006 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5009 /* If the remote VTEP does not exist, there's nothing more to
5011 * Otherwise, uninstall any remote MACs pointing to this VTEP
5013 * then, the VTEP entry itself and remove it.
5015 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5019 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5020 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5021 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5022 zvni_vtep_del(zvni
, zvtep
);
5030 * Handle message from client to add a remote VTEP for a VNI.
5032 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
5033 struct zebra_vrf
*zvrf
)
5038 struct in_addr vtep_ip
;
5040 struct interface
*ifp
;
5041 struct zebra_if
*zif
;
5043 if (!is_evpn_enabled()) {
5044 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5045 __PRETTY_FUNCTION__
);
5049 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5050 zlog_err("Recv MACIP ADD for non-default VRF %u",
5057 while (l
< length
) {
5058 /* Obtain each remote VTEP and process. */
5059 STREAM_GETL(s
, vni
);
5061 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5062 l
+= IPV4_MAX_BYTELEN
;
5064 if (IS_ZEBRA_DEBUG_VXLAN
)
5065 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5066 inet_ntoa(vtep_ip
), vni
,
5067 zebra_route_string(client
->proto
));
5069 /* Locate VNI hash entry - expected to exist. */
5070 zvni
= zvni_lookup(vni
);
5073 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5078 ifp
= zvni
->vxlan_if
;
5081 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5088 /* If down or not mapped to a bridge, we're done. */
5089 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5092 /* If the remote VTEP already exists,
5093 there's nothing more to do. */
5094 if (zvni_vtep_find(zvni
, &vtep_ip
))
5097 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5099 "Failed to add remote VTEP, VNI %u zvni %p",
5104 zvni_vtep_install(zvni
, &vtep_ip
);
5112 * Add/Del gateway macip to evpn
5114 * 1. SVI interface on a vlan aware bridge
5115 * 2. SVI interface on a vlan unaware bridge
5116 * 3. vrr interface (MACVLAN) associated to a SVI
5117 * We advertise macip routes for an interface if it is associated to VxLan vlan
5119 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5123 struct ethaddr macaddr
;
5124 zebra_vni_t
*zvni
= NULL
;
5126 memset(&ip
, 0, sizeof(struct ipaddr
));
5127 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5129 /* Check if EVPN is enabled. */
5130 if (!is_evpn_enabled())
5133 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5134 struct interface
*svi_if
=
5135 NULL
; /* SVI corresponding to the MACVLAN */
5136 struct zebra_if
*ifp_zif
=
5137 NULL
; /* Zebra daemon specific info for MACVLAN */
5138 struct zebra_if
*svi_if_zif
=
5139 NULL
; /* Zebra daemon specific info for SVI*/
5141 ifp_zif
= ifp
->info
;
5146 * for a MACVLAN interface the link represents the svi_if
5148 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5149 ifp_zif
->link_ifindex
);
5151 zlog_err("MACVLAN %s(%u) without link information",
5152 ifp
->name
, ifp
->ifindex
);
5156 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5158 * If it is a vlan aware bridge then the link gives the
5159 * bridge information
5161 struct interface
*svi_if_link
= NULL
;
5163 svi_if_zif
= svi_if
->info
;
5165 svi_if_link
= if_lookup_by_index_per_ns(
5166 zebra_ns_lookup(NS_DEFAULT
),
5167 svi_if_zif
->link_ifindex
);
5168 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5170 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5172 * If it is a vlan unaware bridge then svi is the bridge
5175 zvni
= zvni_from_svi(svi_if
, svi_if
);
5177 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5178 struct zebra_if
*svi_if_zif
=
5179 NULL
; /* Zebra daemon specific info for SVI */
5180 struct interface
*svi_if_link
=
5181 NULL
; /* link info for the SVI = bridge info */
5183 svi_if_zif
= ifp
->info
;
5184 svi_if_link
= if_lookup_by_index_per_ns(
5185 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5186 if (svi_if_zif
&& svi_if_link
)
5187 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5188 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5189 zvni
= zvni_from_svi(ifp
, ifp
);
5195 if (!zvni
->vxlan_if
) {
5196 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5202 /* check if we are advertising gw macip routes */
5203 if (!advertise_gw_macip_enabled(zvni
))
5206 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5208 if (p
->family
== AF_INET
) {
5209 ip
.ipa_type
= IPADDR_V4
;
5210 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5211 sizeof(struct in_addr
));
5212 } else if (p
->family
== AF_INET6
) {
5213 ip
.ipa_type
= IPADDR_V6
;
5214 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5215 sizeof(struct in6_addr
));
5220 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5222 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5228 * Handle SVI interface going down.
5229 * SVI can be associated to either L3-VNI or L2-VNI.
5230 * For L2-VNI: At this point, this is a NOP since
5231 * the kernel deletes the neighbor entries on this SVI (if any).
5232 * We only need to update the vrf corresponding to zvni.
5233 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5236 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5238 zebra_l3vni_t
*zl3vni
= NULL
;
5240 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5243 /* process l3-vni down */
5244 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5246 /* remove association with svi-if */
5247 zl3vni
->svi_if
= NULL
;
5249 zebra_vni_t
*zvni
= NULL
;
5251 /* since we dont have svi corresponding to zvni, we associate it
5252 * to default vrf. Note: the corresponding neigh entries on the
5253 * SVI would have already been deleted */
5254 zvni
= zvni_from_svi(ifp
, link_if
);
5256 zvni
->vrf_id
= VRF_DEFAULT
;
5258 /* update the tenant vrf in BGP */
5259 zvni_send_add_to_client(zvni
);
5266 * Handle SVI interface coming up.
5267 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5269 * For L2-VNI: we need to install any remote neighbors entried (used for
5271 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5273 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5275 zebra_vni_t
*zvni
= NULL
;
5276 zebra_l3vni_t
*zl3vni
= NULL
;
5278 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5281 /* associate with svi */
5282 zl3vni
->svi_if
= ifp
;
5284 /* process oper-up */
5285 if (is_l3vni_oper_up(zl3vni
))
5286 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5289 /* process SVI up for l2-vni */
5290 struct neigh_walk_ctx n_wctx
;
5292 zvni
= zvni_from_svi(ifp
, link_if
);
5296 if (!zvni
->vxlan_if
) {
5297 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5302 if (IS_ZEBRA_DEBUG_VXLAN
)
5303 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5304 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5305 vrf_id_to_name(ifp
->vrf_id
));
5307 /* update the vrf information for l2-vni and inform bgp */
5308 zvni
->vrf_id
= ifp
->vrf_id
;
5309 zvni_send_add_to_client(zvni
);
5311 /* Install any remote neighbors for this VNI. */
5312 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5314 hash_iterate(zvni
->neigh_table
,
5315 zvni_install_neigh_hash
,
5323 * Handle VxLAN interface down
5325 int zebra_vxlan_if_down(struct interface
*ifp
)
5328 struct zebra_if
*zif
= NULL
;
5329 struct zebra_l2info_vxlan
*vxl
= NULL
;
5331 /* Check if EVPN is enabled. */
5332 if (!is_evpn_enabled())
5337 vxl
= &zif
->l2info
.vxl
;
5341 if (is_vni_l3(vni
)) {
5343 /* process-if-down for l3-vni */
5344 zebra_l3vni_t
*zl3vni
= NULL
;
5346 if (IS_ZEBRA_DEBUG_VXLAN
)
5347 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
5348 ifp
->name
, ifp
->ifindex
, vni
);
5350 zl3vni
= zl3vni_lookup(vni
);
5353 "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
5354 ifp
->name
, ifp
->ifindex
, vni
);
5358 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5361 /* process if-down for l2-vni */
5364 if (IS_ZEBRA_DEBUG_VXLAN
)
5365 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
5366 ifp
->name
, ifp
->ifindex
, vni
);
5368 /* Locate hash entry; it is expected to exist. */
5369 zvni
= zvni_lookup(vni
);
5372 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5373 ifp
->name
, ifp
->ifindex
, vni
);
5377 assert(zvni
->vxlan_if
== ifp
);
5379 /* Delete this VNI from BGP. */
5380 zvni_send_del_to_client(zvni
->vni
);
5382 /* Free up all neighbors and MACs, if any. */
5383 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5384 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5386 /* Free up all remote VTEPs, if any. */
5387 zvni_vtep_del_all(zvni
, 1);
5393 * Handle VxLAN interface up - update BGP if required.
5395 int zebra_vxlan_if_up(struct interface
*ifp
)
5398 struct zebra_if
*zif
= NULL
;
5399 struct zebra_l2info_vxlan
*vxl
= NULL
;
5401 /* Check if EVPN is enabled. */
5402 if (!is_evpn_enabled())
5407 vxl
= &zif
->l2info
.vxl
;
5410 if (is_vni_l3(vni
)) {
5412 /* Handle L3-VNI add */
5413 zebra_l3vni_t
*zl3vni
= NULL
;
5415 if (IS_ZEBRA_DEBUG_VXLAN
)
5416 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
5417 ifp
->name
, ifp
->ifindex
, vni
);
5419 zl3vni
= zl3vni_lookup(vni
);
5422 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
5423 ifp
->name
, ifp
->ifindex
, vni
);
5427 /* we need to associate with SVI, if any, we can associate with
5428 * svi-if only after association with vxlan-intf is complete */
5429 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5431 if (is_l3vni_oper_up(zl3vni
))
5432 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5434 /* Handle L2-VNI add */
5436 zebra_vni_t
*zvni
= NULL
;
5437 zebra_l3vni_t
*zl3vni
= NULL
;
5438 struct interface
*vlan_if
= NULL
;
5440 if (IS_ZEBRA_DEBUG_VXLAN
)
5441 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
5442 ifp
->name
, ifp
->ifindex
, vni
);
5444 /* Locate hash entry; it is expected to exist. */
5445 zvni
= zvni_lookup(vni
);
5448 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
5449 ifp
->name
, ifp
->ifindex
, vni
);
5453 assert(zvni
->vxlan_if
== ifp
);
5454 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5455 zif
->brslave_info
.br_if
);
5457 zvni
->vrf_id
= vlan_if
->vrf_id
;
5458 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
5460 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
5463 /* If part of a bridge, inform BGP about this VNI. */
5464 /* Also, read and populate local MACs and neighbors. */
5465 if (zif
->brslave_info
.br_if
) {
5466 zvni_send_add_to_client(zvni
);
5467 zvni_read_mac_neigh(zvni
, ifp
);
5475 * Handle VxLAN interface delete. Locate and remove entry in hash table
5476 * and update BGP, if required.
5478 int zebra_vxlan_if_del(struct interface
*ifp
)
5481 struct zebra_if
*zif
= NULL
;
5482 struct zebra_l2info_vxlan
*vxl
= NULL
;
5484 /* Check if EVPN is enabled. */
5485 if (!is_evpn_enabled())
5490 vxl
= &zif
->l2info
.vxl
;
5493 if (is_vni_l3(vni
)) {
5495 /* process if-del for l3-vni */
5496 zebra_l3vni_t
*zl3vni
= NULL
;
5498 if (IS_ZEBRA_DEBUG_VXLAN
)
5499 zlog_debug("Del L3-VNI %u intf %s(%u)",
5500 vni
, ifp
->name
, ifp
->ifindex
);
5502 zl3vni
= zl3vni_lookup(vni
);
5505 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5506 ifp
->name
, ifp
->ifindex
, vni
);
5510 /* process oper-down for l3-vni */
5511 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5513 /* remove the association with vxlan_if */
5514 zl3vni
->vxlan_if
= NULL
;
5517 /* process if-del for l2-vni*/
5518 zebra_vni_t
*zvni
= NULL
;
5519 zebra_l3vni_t
*zl3vni
= NULL
;
5521 if (IS_ZEBRA_DEBUG_VXLAN
)
5522 zlog_debug("Del L2-VNI %u intf %s(%u)",
5523 vni
, ifp
->name
, ifp
->ifindex
);
5525 /* Locate hash entry; it is expected to exist. */
5526 zvni
= zvni_lookup(vni
);
5529 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
5530 ifp
->name
, ifp
->ifindex
, vni
);
5534 /* remove from l3-vni list */
5535 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
5537 listnode_delete(zl3vni
->l2vnis
, zvni
);
5539 /* Delete VNI from BGP. */
5540 zvni_send_del_to_client(zvni
->vni
);
5542 /* Free up all neighbors and MAC, if any. */
5543 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
5544 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
5546 /* Free up all remote VTEPs, if any. */
5547 zvni_vtep_del_all(zvni
, 0);
5549 /* Delete the hash entry. */
5550 if (zvni_del(zvni
)) {
5551 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
5552 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
5561 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
5563 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
5566 struct zebra_if
*zif
= NULL
;
5567 struct zebra_l2info_vxlan
*vxl
= NULL
;
5569 /* Check if EVPN is enabled. */
5570 if (!is_evpn_enabled())
5575 vxl
= &zif
->l2info
.vxl
;
5578 if (is_vni_l3(vni
)) {
5579 zebra_l3vni_t
*zl3vni
= NULL
;
5581 zl3vni
= zl3vni_lookup(vni
);
5584 "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
5585 ifp
->name
, ifp
->ifindex
, vni
);
5589 if (IS_ZEBRA_DEBUG_VXLAN
)
5591 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
5592 vni
, ifp
->name
, ifp
->ifindex
,
5593 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5594 zif
->brslave_info
.bridge_ifindex
, chgflags
);
5596 /* Removed from bridge? Cleanup and return */
5597 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5598 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
5599 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5603 /* access-vlan change - process oper down, associate with new
5604 * svi_if and then process oper up again */
5605 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5606 if (if_is_operative(ifp
)) {
5607 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5608 zl3vni
->svi_if
= NULL
;
5609 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5610 if (is_l3vni_oper_up(zl3vni
))
5611 zebra_vxlan_process_l3vni_oper_up(
5616 /* if we have a valid new master, process l3-vni oper up */
5617 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
5618 if (is_l3vni_oper_up(zl3vni
))
5619 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5622 zebra_vni_t
*zvni
= NULL
;
5624 /* Update VNI hash. */
5625 zvni
= zvni_lookup(vni
);
5628 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
5629 ifp
->name
, ifp
->ifindex
, vni
);
5633 if (IS_ZEBRA_DEBUG_VXLAN
)
5635 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
5636 vni
, ifp
->name
, ifp
->ifindex
,
5637 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5638 zif
->brslave_info
.bridge_ifindex
, chgflags
);
5640 /* Removed from bridge? Cleanup and return */
5641 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5642 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
5643 /* Delete from client, remove all remote VTEPs */
5644 /* Also, free up all MACs and neighbors. */
5645 zvni_send_del_to_client(zvni
->vni
);
5646 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5647 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5648 zvni_vtep_del_all(zvni
, 1);
5652 /* Handle other changes. */
5653 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5654 /* Remove all existing local neigh and MACs for this VNI
5655 * (including from BGP)
5657 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
5658 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
5661 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
5662 zvni
->vxlan_if
= ifp
;
5664 /* Take further actions needed.
5665 * Note that if we are here, there is a change of interest.
5667 /* If down or not mapped to a bridge, we're done. */
5668 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5671 /* Inform BGP, if there is a change of interest. */
5673 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
5674 zvni_send_add_to_client(zvni
);
5676 /* If there is a valid new master or a VLAN mapping change,
5677 * read and populate local MACs and neighbors.
5678 * Also, reinstall any remote MACs and neighbors
5679 * for this VNI (based on new VLAN).
5681 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5682 zvni_read_mac_neigh(zvni
, ifp
);
5683 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5684 struct mac_walk_ctx m_wctx
;
5685 struct neigh_walk_ctx n_wctx
;
5687 zvni_read_mac_neigh(zvni
, ifp
);
5689 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
5691 hash_iterate(zvni
->mac_table
,
5692 zvni_install_mac_hash
,
5695 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5697 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
5706 * Handle VxLAN interface add.
5708 int zebra_vxlan_if_add(struct interface
*ifp
)
5711 struct zebra_if
*zif
= NULL
;
5712 struct zebra_l2info_vxlan
*vxl
= NULL
;
5714 /* Check if EVPN is enabled. */
5715 if (!is_evpn_enabled())
5720 vxl
= &zif
->l2info
.vxl
;
5723 if (is_vni_l3(vni
)) {
5725 /* process if-add for l3-vni*/
5726 zebra_l3vni_t
*zl3vni
= NULL
;
5728 if (IS_ZEBRA_DEBUG_VXLAN
)
5730 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
5731 vni
, ifp
->name
, ifp
->ifindex
,
5732 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5733 zif
->brslave_info
.bridge_ifindex
);
5736 * we expect the l3-vni has entry to be present here.
5737 * The only place l3-vni is created in zebra is vrf-vni mapping
5738 * command. This might change when we have the switchd support
5739 * for l3-vxlan interface.
5741 zl3vni
= zl3vni_lookup(vni
);
5744 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5745 ifp
->name
, ifp
->ifindex
, vni
);
5749 /* associate with vxlan_if */
5750 zl3vni
->vxlan_if
= ifp
;
5752 /* Associate with SVI, if any. We can associate with svi-if only
5753 * after association with vxlan_if is complete */
5754 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5756 if (is_l3vni_oper_up(zl3vni
))
5757 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5760 /* process if-add for l2-vni */
5761 zebra_vni_t
*zvni
= NULL
;
5762 zebra_l3vni_t
*zl3vni
= NULL
;
5763 struct interface
*vlan_if
= NULL
;
5765 /* Create or update VNI hash. */
5766 zvni
= zvni_lookup(vni
);
5768 zvni
= zvni_add(vni
);
5771 "Failed to add VNI hash, IF %s(%u) VNI %u",
5772 ifp
->name
, ifp
->ifindex
, vni
);
5777 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
5778 zvni
->vxlan_if
= ifp
;
5779 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5780 zif
->brslave_info
.br_if
);
5782 zvni
->vrf_id
= vlan_if
->vrf_id
;
5783 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
5785 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
5788 if (IS_ZEBRA_DEBUG_VXLAN
)
5790 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
5792 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
) :
5794 ifp
->name
, ifp
->ifindex
,
5795 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5796 zif
->brslave_info
.bridge_ifindex
);
5798 /* If down or not mapped to a bridge, we're done. */
5799 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5803 zvni_send_add_to_client(zvni
);
5805 /* Read and populate local MACs and neighbors */
5806 zvni_read_mac_neigh(zvni
, ifp
);
5812 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
,
5813 vni_t vni
, char *err
,
5816 zebra_l3vni_t
*zl3vni
= NULL
;
5817 struct zebra_vrf
*zvrf_default
= NULL
;
5819 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
5823 if (IS_ZEBRA_DEBUG_VXLAN
)
5824 zlog_debug("vrf %s vni %u %s",
5827 add
? "ADD" : "DEL");
5831 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
5833 /* check if the vni is already present under zvrf */
5835 snprintf(err
, ERR_STR_SZ
,
5836 "VNI is already configured under the vrf");
5840 /* check if this VNI is already present in the system */
5841 zl3vni
= zl3vni_lookup(vni
);
5843 snprintf(err
, ERR_STR_SZ
,
5844 "VNI is already configured as L3-VNI");
5848 /* add the L3-VNI to the global table */
5849 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
5851 snprintf(err
, ERR_STR_SZ
,
5852 "Could not add L3-VNI");
5856 /* associate the vrf with vni */
5859 /* associate with vxlan-intf;
5860 * we need to associate with the vxlan-intf first */
5861 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
5863 /* associate with corresponding SVI interface, we can associate
5864 * with svi-if only after vxlan interface association is
5866 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5868 /* formulate l2vni list */
5869 hash_iterate(zvrf_default
->vni_table
,
5870 zvni_add_to_l3vni_list
, zl3vni
);
5872 if (is_l3vni_oper_up(zl3vni
))
5873 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5876 zl3vni
= zl3vni_lookup(vni
);
5878 snprintf(err
, ERR_STR_SZ
, "VNI doesn't exist");
5882 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5887 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
5892 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
5894 zebra_l3vni_t
*zl3vni
= NULL
;
5896 zl3vni
= zl3vni_from_vrf(zvrf_id(zvrf
));
5900 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5902 zebra_vxlan_handle_vni_transition(zvrf
, zl3vni
->vni
, 0);
5908 * Handle message from client to enable/disable advertisement of g/w macip
5911 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
5912 struct zebra_vrf
*zvrf
)
5917 zebra_vni_t
*zvni
= NULL
;
5918 struct interface
*ifp
= NULL
;
5920 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5921 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
5927 STREAM_GETC(s
, advertise
);
5928 STREAM_GET(&vni
, s
, 3);
5931 if (IS_ZEBRA_DEBUG_VXLAN
)
5932 zlog_debug("EVPN gateway macip Adv %s, currently %s",
5933 advertise
? "enabled" : "disabled",
5934 advertise_gw_macip_enabled(NULL
)
5938 if (zvrf
->advertise_gw_macip
== advertise
)
5941 zvrf
->advertise_gw_macip
= advertise
;
5943 if (advertise_gw_macip_enabled(zvni
))
5944 hash_iterate(zvrf
->vni_table
,
5945 zvni_gw_macip_add_for_vni_hash
, NULL
);
5947 hash_iterate(zvrf
->vni_table
,
5948 zvni_gw_macip_del_for_vni_hash
, NULL
);
5951 struct zebra_if
*zif
= NULL
;
5952 struct zebra_l2info_vxlan zl2_info
;
5953 struct interface
*vlan_if
= NULL
;
5954 struct interface
*vrr_if
= NULL
;
5956 if (IS_ZEBRA_DEBUG_VXLAN
)
5958 "EVPN gateway macip Adv %s on VNI %d , currently %s",
5959 advertise
? "enabled" : "disabled", vni
,
5960 advertise_gw_macip_enabled(zvni
)
5964 zvni
= zvni_lookup(vni
);
5968 if (zvni
->advertise_gw_macip
== advertise
)
5971 zvni
->advertise_gw_macip
= advertise
;
5973 ifp
= zvni
->vxlan_if
;
5979 /* If down or not mapped to a bridge, we're done. */
5980 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5983 zl2_info
= zif
->l2info
.vxl
;
5985 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
5986 zif
->brslave_info
.br_if
);
5990 if (advertise_gw_macip_enabled(zvni
)) {
5991 /* Add primary SVI MAC-IP */
5992 zvni_add_macip_for_intf(vlan_if
, zvni
);
5994 /* Add VRR MAC-IP - if any*/
5995 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
5997 zvni_add_macip_for_intf(vrr_if
, zvni
);
5999 /* Del primary MAC-IP */
6000 zvni_del_macip_for_intf(vlan_if
, zvni
);
6002 /* Del VRR MAC-IP - if any*/
6003 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6005 zvni_del_macip_for_intf(vrr_if
, zvni
);
6015 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6016 * When enabled, the VNI hash table will be built and MAC FDB table read;
6017 * when disabled, the entries should be deleted and remote VTEPs and MACs
6018 * uninstalled from the kernel.
6020 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
6021 u_short length
, struct zebra_vrf
*zvrf
)
6026 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6027 zlog_err("EVPN VNI Adv for non-default VRF %u",
6033 STREAM_GETC(s
, advertise
);
6035 if (IS_ZEBRA_DEBUG_VXLAN
)
6036 zlog_debug("EVPN VNI Adv %s, currently %s",
6037 advertise
? "enabled" : "disabled",
6038 is_evpn_enabled() ? "enabled" : "disabled");
6040 if (zvrf
->advertise_all_vni
== advertise
)
6043 zvrf
->advertise_all_vni
= advertise
;
6044 if (is_evpn_enabled()) {
6045 /* Build VNI hash table and inform BGP. */
6046 zvni_build_hash_table();
6048 /* Add all SVI (L3 GW) MACs to BGP*/
6049 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6052 /* Read the MAC FDB */
6053 macfdb_read(zvrf
->zns
);
6055 /* Read neighbors */
6056 neigh_read(zvrf
->zns
);
6058 /* Cleanup VTEPs for all VNIs - uninstall from
6059 * kernel and free entries.
6061 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6069 * Allocate VNI hash table for this VRF and do other initialization.
6070 * NOTE: Currently supported only for default VRF.
6072 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6076 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6077 "Zebra VRF VNI Table");
6080 /* Close all VNI handling */
6081 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6085 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6086 hash_free(zvrf
->vni_table
);
6089 /* init the l3vni table */
6090 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6092 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6093 "Zebra VRF L3 VNI table");
6096 /* free l3vni table */
6097 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6099 hash_free(zns
->l3vni_table
);