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
, ZVNI_VTEP
, "VNI remote VTEP");
53 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
54 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
59 /* static function declarations */
60 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
61 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
62 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
64 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
65 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
66 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
67 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
68 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
70 static int zvni_macip_send_msg_to_client(vni_t vni
,
71 struct ethaddr
*macaddr
,
72 struct ipaddr
*ip
, u_char flags
,
74 static unsigned int neigh_hash_keymake(void *p
);
75 static int neigh_cmp(const void *p1
, const void *p2
);
76 static void *zvni_neigh_alloc(void *p
);
77 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
79 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
80 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
81 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
82 struct in_addr
*r_vtep_ip
);
83 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
84 int uninstall
, int upd_client
, u_int32_t flags
);
85 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
86 static int zvni_neigh_send_add_to_client(vni_t vni
,
88 struct ethaddr
*macaddr
, u_char flags
);
89 static int zvni_neigh_send_del_to_client(vni_t vni
,
91 struct ethaddr
*macaddr
, u_char flags
);
92 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
93 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
94 static zebra_vni_t
*zvni_map_svi(struct interface
*ifp
,
95 struct interface
*br_if
);
96 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
97 struct interface
*br_if
);
99 static unsigned int mac_hash_keymake(void *p
);
100 static int mac_cmp(const void *p1
, const void *p2
);
101 static void *zvni_mac_alloc(void *p
);
102 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
103 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
104 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
105 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
106 struct in_addr
*r_vtep_ip
);
107 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
108 int uninstall
, int upd_client
, u_int32_t flags
);
109 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
110 static int zvni_mac_send_add_to_client(vni_t vni
,
111 struct ethaddr
*macaddr
, u_char flags
);
112 static int zvni_mac_send_del_to_client(vni_t vni
,
113 struct ethaddr
*macaddr
, u_char flags
);
114 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
115 struct interface
*br_if
, vlanid_t vid
);
116 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
117 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
118 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
120 static unsigned int vni_hash_keymake(void *p
);
121 static int vni_hash_cmp(const void *p1
, const void *p2
);
122 static void *zvni_alloc(void *p
);
123 static zebra_vni_t
*zvni_lookup(vni_t vni
);
124 static zebra_vni_t
*zvni_add(vni_t vni
);
125 static int zvni_del(zebra_vni_t
*zvni
);
126 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
127 static int zvni_send_del_to_client(vni_t vni
);
128 static void zvni_build_hash_table();
129 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
130 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
131 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
132 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
133 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
134 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
135 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
136 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
137 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
138 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
139 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
140 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
142 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
143 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
144 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
147 /* Private functions */
150 * Return number of valid MACs in a VNI's MAC hash table - all
151 * remote MACs and non-internal (auto) local MACs count.
153 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
156 u_int32_t num_macs
= 0;
158 struct hash_backet
*hb
;
161 hash
= zvni
->mac_table
;
164 for (i
= 0; i
< hash
->size
; i
++) {
165 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
166 mac
= (zebra_mac_t
*)hb
->data
;
167 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
168 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
176 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
178 struct zebra_vrf
*zvrf
;
180 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
181 if (zvrf
&& zvrf
->advertise_gw_macip
)
184 if (zvni
&& zvni
->advertise_gw_macip
)
191 * Helper function to determine maximum width of neighbor IP address for
192 * display - just because we're dealing with IPv6 addresses that can
195 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
198 char buf
[INET6_ADDRSTRLEN
];
199 struct neigh_walk_ctx
*wctx
= ctxt
;
202 n
= (zebra_neigh_t
*)backet
->data
;
206 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
207 if (width
> wctx
->addr_width
)
208 wctx
->addr_width
= width
;
212 * Print a specific neighbor entry.
214 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
217 char buf1
[ETHER_ADDR_STRLEN
];
218 char buf2
[INET6_ADDRSTRLEN
];
220 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
221 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
222 vty
= (struct vty
*)ctxt
;
224 vty_out(vty
, "IP: %s\n",
225 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
226 vty_out(vty
, " MAC: %s",
227 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
229 json_object_string_add(json
, "ip", buf2
);
230 json_object_string_add(json
, "mac", buf1
);
232 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
234 vty_out(vty
, " Remote VTEP: %s",
235 inet_ntoa(n
->r_vtep_ip
));
237 json_object_string_add(json
, "remoteVtep",
238 inet_ntoa(n
->r_vtep_ip
));
240 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
243 vty_out(vty
, " State: %s",
244 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
253 * Print neighbor hash entry - called for display of all neighbors.
255 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
258 json_object
*json_vni
= NULL
, *json_row
= NULL
;
260 char buf1
[ETHER_ADDR_STRLEN
];
261 char buf2
[INET6_ADDRSTRLEN
];
262 struct neigh_walk_ctx
*wctx
= ctxt
;
265 json_vni
= wctx
->json
;
266 n
= (zebra_neigh_t
*)backet
->data
;
271 json_row
= json_object_new_object();
273 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
274 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
275 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
276 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
277 if (json_vni
== NULL
) {
278 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
279 buf2
, "local", buf1
);
281 json_object_string_add(json_row
, "type", "local");
282 json_object_string_add(json_row
, "mac", buf1
);
286 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
287 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
288 if (json_vni
== NULL
) {
289 if (wctx
->count
== 0)
291 "%*s %-6s %-17s %-21s\n",
294 "MAC", "Remote VTEP");
295 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
296 -wctx
->addr_width
, buf2
,
298 inet_ntoa(n
->r_vtep_ip
));
300 json_object_string_add(json_row
, "type",
302 json_object_string_add(json_row
, "mac",
304 json_object_string_add(
305 json_row
, "remoteVtep",
306 inet_ntoa(n
->r_vtep_ip
));
311 if (json_vni
== NULL
) {
312 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
313 -wctx
->addr_width
, buf2
, "remote", buf1
,
314 inet_ntoa(n
->r_vtep_ip
));
316 json_object_string_add(json_row
, "type",
318 json_object_string_add(json_row
, "mac", buf1
);
319 json_object_string_add(json_row
, "remoteVtep",
320 inet_ntoa(n
->r_vtep_ip
));
327 json_object_object_add(json_vni
, buf2
, json_row
);
331 * Print neighbors for all VNI.
333 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
337 json_object
*json
= NULL
, *json_vni
= NULL
;
340 struct neigh_walk_ctx wctx
;
341 char vni_str
[VNI_STR_LEN
];
343 vty
= (struct vty
*)args
[0];
344 json
= (json_object
*)args
[1];
346 zvni
= (zebra_vni_t
*)backet
->data
;
349 vty_out(vty
, "{}\n");
352 num_neigh
= hashcount(zvni
->neigh_table
);
355 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
356 zvni
->vni
, num_neigh
);
358 json_vni
= json_object_new_object();
359 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
360 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
364 json_object_object_add(json
, vni_str
, json_vni
);
368 /* Since we have IPv6 addresses to deal with which can vary widely in
369 * size, we try to be a bit more elegant in display by first computing
372 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
375 wctx
.addr_width
= 15;
376 wctx
.json
= json_vni
;
377 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
380 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
381 "Type", "MAC", "Remote VTEP");
382 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
385 json_object_object_add(json
, vni_str
, json_vni
);
389 * Print a specific MAC entry.
391 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
394 zebra_neigh_t
*n
= NULL
;
395 struct listnode
*node
= NULL
;
397 char buf2
[INET6_ADDRSTRLEN
];
399 vty
= (struct vty
*)ctxt
;
400 vty_out(vty
, "MAC: %s",
401 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
402 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
403 struct zebra_ns
*zns
;
404 struct interface
*ifp
;
407 ifindex
= mac
->fwd_info
.local
.ifindex
;
408 zns
= zebra_ns_lookup(NS_DEFAULT
);
409 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
410 if (!ifp
) // unexpected
412 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
413 if (mac
->fwd_info
.local
.vid
)
414 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
415 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
416 vty_out(vty
, " Remote VTEP: %s",
417 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
418 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
419 vty_out(vty
, " Auto Mac ");
423 /* print all the associated neigh */
424 vty_out(vty
, " Neighbors:\n");
425 if (!listcount(mac
->neigh_list
))
426 vty_out(vty
, " No Neighbors\n");
428 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
429 vty_out(vty
, " %s %s\n",
430 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
431 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
432 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
443 * Print MAC hash entry - called for display of all MACs.
445 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
448 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
451 struct mac_walk_ctx
*wctx
= ctxt
;
454 json_mac_hdr
= wctx
->json
;
455 mac
= (zebra_mac_t
*)backet
->data
;
459 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
462 json_mac
= json_object_new_object();
464 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
465 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
466 struct zebra_ns
*zns
;
468 struct interface
*ifp
;
471 zns
= zebra_ns_lookup(NS_DEFAULT
);
472 ifindex
= mac
->fwd_info
.local
.ifindex
;
473 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
474 if (!ifp
) // unexpected
476 vid
= mac
->fwd_info
.local
.vid
;
477 if (json_mac_hdr
== NULL
)
478 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
481 json_object_string_add(json_mac
, "type", "local");
482 json_object_string_add(json_mac
, "intf", ifp
->name
);
485 if (json_mac_hdr
== NULL
)
486 vty_out(vty
, " %-5u", vid
);
488 json_object_int_add(json_mac
, "vlan", vid
);
490 if (json_mac_hdr
== NULL
)
493 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
495 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
496 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
497 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
499 if (wctx
->count
== 0) {
500 if (json_mac_hdr
== NULL
) {
501 vty_out(vty
, "\nVNI %u\n\n",
504 "%-17s %-6s %-21s %-5s\n",
510 if (json_mac_hdr
== NULL
)
511 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
513 inet_ntoa(mac
->fwd_info
516 json_object_string_add(json_mac
, "type",
518 json_object_string_add(
519 json_mac
, "remoteVtep",
520 inet_ntoa(mac
->fwd_info
522 json_object_object_add(json_mac_hdr
,
528 if (json_mac_hdr
== NULL
)
529 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
531 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
533 json_object_string_add(json_mac
, "type",
535 json_object_string_add(
536 json_mac
, "remoteVtep",
537 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
538 json_object_object_add(json_mac_hdr
, buf1
,
547 * Print MACs for all VNI.
549 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
552 json_object
*json
= NULL
, *json_vni
= NULL
;
553 json_object
*json_mac
= NULL
;
556 struct mac_walk_ctx
*wctx
= ctxt
;
557 char vni_str
[VNI_STR_LEN
];
559 vty
= (struct vty
*)wctx
->vty
;
560 json
= (struct json_object
*)wctx
->json
;
562 zvni
= (zebra_vni_t
*)backet
->data
;
565 vty_out(vty
, "{}\n");
570 /*We are iterating over a new VNI, set the count to 0*/
573 num_macs
= num_valid_macs(zvni
);
578 json_vni
= json_object_new_object();
579 json_mac
= json_object_new_object();
580 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
583 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
585 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
586 zvni
->vni
, num_macs
);
587 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
588 "Intf/Remote VTEP", "VLAN");
590 json_object_int_add(json_vni
, "numMacs", num_macs
);
592 /* assign per-vni to wctx->json object to fill macs
593 * under the vni. Re-assign primary json object to fill
594 * next vni information.
596 wctx
->json
= json_mac
;
597 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
601 json_object_object_add(json_vni
, "macs", json_mac
);
602 json_object_object_add(json
, vni_str
, json_vni
);
607 * Print a specific VNI entry.
609 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
615 json_object
*json
= NULL
;
616 json_object
*json_vtep_list
= NULL
;
617 json_object
*json_ip_str
= NULL
;
623 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
625 json_object_int_add(json
, "vni", zvni
->vni
);
627 if (!zvni
->vxlan_if
) { // unexpected
629 vty_out(vty
, " VxLAN interface: unknown\n");
632 num_macs
= num_valid_macs(zvni
);
633 num_neigh
= hashcount(zvni
->neigh_table
);
635 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
636 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
637 inet_ntoa(zvni
->local_vtep_ip
));
639 json_object_string_add(json
, "vxlanInterface",
640 zvni
->vxlan_if
->name
);
641 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
642 json_object_string_add(json
, "vtepIp",
643 inet_ntoa(zvni
->local_vtep_ip
));
644 json_object_string_add(json
, "advertiseGatewayMacip",
645 zvni
->advertise_gw_macip
? "Yes" : "No");
646 json_object_int_add(json
, "numMacs", num_macs
);
647 json_object_int_add(json
, "numArpNd", num_neigh
);
651 vty_out(vty
, " No remote VTEPs known for this VNI\n");
654 vty_out(vty
, " Remote VTEPs for this VNI:\n");
656 json_vtep_list
= json_object_new_array();
657 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
659 vty_out(vty
, " %s\n",
660 inet_ntoa(zvtep
->vtep_ip
));
662 json_ip_str
= json_object_new_string(
663 inet_ntoa(zvtep
->vtep_ip
));
664 json_object_array_add(json_vtep_list
,
669 json_object_object_add(json
, "numRemoteVteps",
674 " Number of MACs (local and remote) known for this VNI: %u\n",
677 " Number of ARPs (IPv4 and IPv6, local and remote) "
678 "known for this VNI: %u\n",
680 vty_out(vty
, " Advertise-gw-macip: %s\n",
681 zvni
->advertise_gw_macip
? "Yes" : "No");
686 * Print a VNI hash entry - called for display of all VNIs.
688 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
693 u_int32_t num_vteps
= 0;
694 u_int32_t num_macs
= 0;
695 u_int32_t num_neigh
= 0;
696 json_object
*json
= NULL
;
697 json_object
*json_vni
= NULL
;
698 json_object
*json_ip_str
= NULL
;
699 json_object
*json_vtep_list
= NULL
;
704 zvni
= (zebra_vni_t
*)backet
->data
;
714 num_macs
= num_valid_macs(zvni
);
715 num_neigh
= hashcount(zvni
->neigh_table
);
717 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni
->vni
,
718 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
719 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
722 char vni_str
[VNI_STR_LEN
];
723 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
724 json_vni
= json_object_new_object();
725 json_object_string_add(json_vni
, "vxlanIf",
726 zvni
->vxlan_if
? zvni
->vxlan_if
->name
728 json_object_string_add(json_vni
, "vtepIp",
729 inet_ntoa(zvni
->local_vtep_ip
));
730 json_object_int_add(json_vni
, "numMacs", num_macs
);
731 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
732 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
734 json_vtep_list
= json_object_new_array();
735 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
736 json_ip_str
= json_object_new_string(
737 inet_ntoa(zvtep
->vtep_ip
));
738 json_object_array_add(json_vtep_list
,
741 json_object_object_add(json_vni
, "remoteVteps",
744 json_object_object_add(json
, vni_str
, json_vni
);
749 * Inform BGP about local MACIP.
751 static int zvni_macip_send_msg_to_client(vni_t vni
,
752 struct ethaddr
*macaddr
,
753 struct ipaddr
*ip
, u_char flags
,
756 struct zserv
*client
;
759 char buf
[ETHER_ADDR_STRLEN
];
760 char buf2
[INET6_ADDRSTRLEN
];
762 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
763 /* BGP may not be running. */
770 zserv_create_header(s
, cmd
, VRF_DEFAULT
);
772 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
775 if (IS_IPADDR_V4(ip
))
776 ipa_len
= IPV4_MAX_BYTELEN
;
777 else if (IS_IPADDR_V6(ip
))
778 ipa_len
= IPV6_MAX_BYTELEN
;
780 stream_putl(s
, ipa_len
); /* IP address length */
782 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
784 stream_putl(s
, 0); /* Just MAC. */
786 stream_putc(s
, flags
); /* sticky mac/gateway mac */
788 /* Write packet size. */
789 stream_putw_at(s
, 0, stream_get_endp(s
));
791 if (IS_ZEBRA_DEBUG_VXLAN
)
793 "Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s",
794 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
795 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
796 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
797 zebra_route_string(client
->proto
));
799 if (cmd
== ZEBRA_MACIP_ADD
)
800 client
->macipadd_cnt
++;
802 client
->macipdel_cnt
++;
804 return zebra_server_send_message(client
);
808 * Make hash key for neighbors.
810 static unsigned int neigh_hash_keymake(void *p
)
812 zebra_neigh_t
*n
= p
;
813 struct ipaddr
*ip
= &n
->ip
;
815 if (IS_IPADDR_V4(ip
))
816 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
818 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
819 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
823 * Compare two neighbor hash structures.
825 static int neigh_cmp(const void *p1
, const void *p2
)
827 const zebra_neigh_t
*n1
= p1
;
828 const zebra_neigh_t
*n2
= p2
;
830 if (n1
== NULL
&& n2
== NULL
)
833 if (n1
== NULL
|| n2
== NULL
)
836 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
840 * Callback to allocate neighbor hash entry.
842 static void *zvni_neigh_alloc(void *p
)
844 const zebra_neigh_t
*tmp_n
= p
;
847 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
854 * Add neighbor entry.
856 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
860 zebra_neigh_t
*n
= NULL
;
861 zebra_mac_t
*zmac
= NULL
;
863 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
864 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
865 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
868 memcpy(&n
->emac
, mac
, ETH_ALEN
);
869 n
->state
= ZEBRA_NEIGH_INACTIVE
;
871 /* Associate the neigh to mac */
872 zmac
= zvni_mac_lookup(zvni
, mac
);
874 listnode_add_sort(zmac
->neigh_list
, n
);
880 * Delete neighbor entry.
882 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
884 zebra_neigh_t
*tmp_n
;
885 zebra_mac_t
*zmac
= NULL
;
887 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
889 listnode_delete(zmac
->neigh_list
, n
);
891 /* Free the VNI hash entry and allocated memory. */
892 tmp_n
= hash_release(zvni
->neigh_table
, n
);
894 XFREE(MTYPE_NEIGH
, tmp_n
);
900 * Free neighbor hash entry (callback)
902 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
904 struct neigh_walk_ctx
*wctx
= arg
;
905 zebra_neigh_t
*n
= backet
->data
;
907 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
908 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
909 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
910 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
911 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
912 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
913 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
914 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
918 zvni_neigh_uninstall(wctx
->zvni
, n
);
920 return zvni_neigh_del(wctx
->zvni
, n
);
927 * Delete all neighbor entries from specific VTEP for a particular VNI.
929 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
930 struct in_addr
*r_vtep_ip
)
932 struct neigh_walk_ctx wctx
;
934 if (!zvni
->neigh_table
)
937 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
939 wctx
.uninstall
= uninstall
;
940 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
941 wctx
.r_vtep_ip
= *r_vtep_ip
;
943 hash_iterate(zvni
->neigh_table
,
944 (void (*)(struct hash_backet
*,
945 void *))zvni_neigh_del_hash_entry
,
950 * Delete all neighbor entries for this VNI.
952 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
953 int uninstall
, int upd_client
, u_int32_t flags
)
955 struct neigh_walk_ctx wctx
;
957 if (!zvni
->neigh_table
)
960 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
962 wctx
.uninstall
= uninstall
;
963 wctx
.upd_client
= upd_client
;
966 hash_iterate(zvni
->neigh_table
,
967 (void (*)(struct hash_backet
*,
968 void *))zvni_neigh_del_hash_entry
,
973 * Look up neighbor hash entry.
975 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
980 memset(&tmp
, 0, sizeof(tmp
));
981 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
982 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
987 /* Process all neigh associated to a mac upon local mac add event */
988 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
991 zebra_neigh_t
*n
= NULL
;
992 struct listnode
*node
= NULL
;
993 char buf
[ETHER_ADDR_STRLEN
];
994 char buf2
[INET6_ADDRSTRLEN
];
996 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
997 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
998 /* MAC is learnt locally, program all inactive neigh
999 * pointing to this mac */
1000 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1001 if (IS_ZEBRA_DEBUG_VXLAN
)
1003 "neigh %s (MAC %s) on VNI %u is now ACTIVE",
1004 ipaddr2str(&n
->ip
, buf2
,
1006 prefix_mac2str(&n
->emac
, buf
,
1010 ZEBRA_NEIGH_SET_ACTIVE(n
);
1011 zvni_neigh_send_add_to_client(
1012 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1014 if (IS_ZEBRA_DEBUG_VXLAN
)
1016 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1017 ipaddr2str(&n
->ip
, buf2
,
1019 prefix_mac2str(&n
->emac
, buf
,
1023 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1024 /* TODO: assume the neigh has moved too ?? */
1029 /* Process all neigh associated to a mac upon local mac del event */
1030 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1033 zebra_neigh_t
*n
= NULL
;
1034 struct listnode
*node
= NULL
;
1035 char buf
[ETHER_ADDR_STRLEN
];
1036 char buf2
[INET6_ADDRSTRLEN
];
1038 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1039 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1040 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1041 if (IS_ZEBRA_DEBUG_VXLAN
)
1043 "neigh %s (MAC %s) on VNI %u is now INACTIVE",
1044 ipaddr2str(&n
->ip
, buf2
,
1046 prefix_mac2str(&n
->emac
, buf
,
1050 ZEBRA_NEIGH_SET_INACTIVE(n
);
1051 zvni_neigh_send_del_to_client(
1052 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1054 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1055 if (IS_ZEBRA_DEBUG_VXLAN
)
1057 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1058 prefix_mac2str(&n
->emac
, buf
,
1061 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1066 /* process all neigh associated to a mac entry upon remote mac add */
1067 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1070 zebra_neigh_t
*n
= NULL
;
1071 struct listnode
*node
= NULL
;
1072 char buf
[ETHER_ADDR_STRLEN
];
1073 char buf2
[INET6_ADDRSTRLEN
];
1075 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1076 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1077 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1078 if (IS_ZEBRA_DEBUG_VXLAN
)
1080 "neigh %s (MAC %s) on VNI %u INACTIVE",
1081 ipaddr2str(&n
->ip
, buf2
,
1083 prefix_mac2str(&n
->emac
, buf
,
1087 ZEBRA_NEIGH_SET_INACTIVE(n
);
1088 zvni_neigh_send_del_to_client(
1089 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1095 /* process all neigh associated to mac entry upon remote mac del */
1096 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1099 zebra_neigh_t
*n
= NULL
;
1100 struct listnode
*node
= NULL
;
1101 char buf
[ETHER_ADDR_STRLEN
];
1102 char buf2
[INET6_ADDRSTRLEN
];
1104 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1105 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1106 if (IS_ZEBRA_DEBUG_VXLAN
)
1108 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1109 prefix_mac2str(&n
->emac
, buf
,
1112 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1118 * Inform BGP about local neighbor addition.
1120 static int zvni_neigh_send_add_to_client(vni_t vni
,
1122 struct ethaddr
*macaddr
, u_char flags
)
1124 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1129 * Inform BGP about local neighbor deletion.
1131 static int zvni_neigh_send_del_to_client(vni_t vni
,
1133 struct ethaddr
*macaddr
, u_char flags
)
1135 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1140 * Install remote neighbor into the kernel.
1142 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1144 struct zebra_if
*zif
;
1145 struct zebra_l2info_vxlan
*vxl
;
1146 struct interface
*vlan_if
;
1148 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1151 zif
= zvni
->vxlan_if
->info
;
1154 vxl
= &zif
->l2info
.vxl
;
1156 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1160 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1164 * Uninstall remote neighbor from the kernel.
1166 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1168 struct zebra_if
*zif
;
1169 struct zebra_l2info_vxlan
*vxl
;
1170 struct interface
*vlan_if
;
1172 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1175 if (!zvni
->vxlan_if
) {
1176 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1181 zif
= zvni
->vxlan_if
->info
;
1184 vxl
= &zif
->l2info
.vxl
;
1185 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1189 return kernel_del_neigh(vlan_if
, &n
->ip
);
1193 * Install neighbor hash entry - called upon access VLAN change.
1195 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1198 struct neigh_walk_ctx
*wctx
= ctxt
;
1200 n
= (zebra_neigh_t
*)backet
->data
;
1204 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1205 zvni_neigh_install(wctx
->zvni
, n
);
1208 /* Get the VRR interface for SVI if any */
1209 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1211 struct zebra_vrf
*zvrf
= NULL
;
1212 struct interface
*tmp_if
= NULL
;
1213 struct zebra_if
*zif
= NULL
;
1215 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1218 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1223 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1226 if (zif
->link
== ifp
)
1233 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1235 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1236 struct connected
*c
= NULL
;
1237 struct ethaddr macaddr
;
1239 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1241 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1244 memset(&ip
, 0, sizeof(struct ipaddr
));
1245 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1248 if (c
->address
->family
== AF_INET
) {
1249 ip
.ipa_type
= IPADDR_V4
;
1250 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1251 sizeof(struct in_addr
));
1252 } else if (c
->address
->family
== AF_INET6
) {
1253 ip
.ipa_type
= IPADDR_V6
;
1254 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1255 sizeof(struct in6_addr
));
1260 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1266 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1268 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1269 struct connected
*c
= NULL
;
1270 struct ethaddr macaddr
;
1272 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1274 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1277 memset(&ip
, 0, sizeof(struct ipaddr
));
1278 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1281 if (c
->address
->family
== AF_INET
) {
1282 ip
.ipa_type
= IPADDR_V4
;
1283 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1284 sizeof(struct in_addr
));
1285 } else if (c
->address
->family
== AF_INET6
) {
1286 ip
.ipa_type
= IPADDR_V6
;
1287 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1288 sizeof(struct in6_addr
));
1293 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1300 * zvni_gw_macip_add_to_client
1302 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1303 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1305 struct zebra_if
*zif
= NULL
;
1306 struct zebra_l2info_vxlan
*vxl
= NULL
;
1307 zebra_neigh_t
*n
= NULL
;
1308 zebra_mac_t
*mac
= NULL
;
1309 char buf
[ETHER_ADDR_STRLEN
];
1310 char buf2
[INET6_ADDRSTRLEN
];
1312 zif
= zvni
->vxlan_if
->info
;
1316 vxl
= &zif
->l2info
.vxl
;
1318 mac
= zvni_mac_lookup(zvni
, macaddr
);
1320 mac
= zvni_mac_add(zvni
, macaddr
);
1322 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1323 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1324 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1329 /* Set "local" forwarding info. */
1330 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1331 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1332 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1333 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1334 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1336 n
= zvni_neigh_lookup(zvni
, ip
);
1338 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1341 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1342 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1343 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1344 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1349 /* Set "local" forwarding info. */
1350 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1351 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1352 n
->ifindex
= ifp
->ifindex
;
1354 if (IS_ZEBRA_DEBUG_VXLAN
)
1356 "SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
1357 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1358 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1359 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1361 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1368 * zvni_gw_macip_del_from_client
1370 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1373 zebra_neigh_t
*n
= NULL
;
1374 zebra_mac_t
*mac
= NULL
;
1375 char buf1
[ETHER_ADDR_STRLEN
];
1376 char buf2
[INET6_ADDRSTRLEN
];
1378 /* If the neigh entry is not present nothing to do*/
1379 n
= zvni_neigh_lookup(zvni
, ip
);
1383 /* mac entry should be present */
1384 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1386 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1387 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1388 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1392 /* If the entry is not local nothing to do*/
1393 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1396 if (IS_ZEBRA_DEBUG_VXLAN
)
1398 "SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1399 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1400 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1401 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1403 /* Remove neighbor from BGP. */
1404 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1407 /* Delete this neighbor entry. */
1408 zvni_neigh_del(zvni
, n
);
1410 /* see if the mac needs to be deleted as well*/
1412 zvni_deref_ip2mac(zvni
, mac
, 0);
1417 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1420 zebra_vni_t
*zvni
= NULL
;
1421 struct zebra_if
*zif
= NULL
;
1422 struct zebra_l2info_vxlan zl2_info
;
1423 struct interface
*vlan_if
= NULL
;
1424 struct interface
*vrr_if
= NULL
;
1425 struct interface
*ifp
;
1427 /* Add primary SVI MAC*/
1428 zvni
= (zebra_vni_t
*)backet
->data
;
1432 ifp
= zvni
->vxlan_if
;
1437 /* If down or not mapped to a bridge, we're done. */
1438 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1441 zl2_info
= zif
->l2info
.vxl
;
1443 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1447 /* Del primary MAC-IP */
1448 zvni_del_macip_for_intf(vlan_if
, zvni
);
1450 /* Del VRR MAC-IP - if any*/
1451 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1453 zvni_del_macip_for_intf(vrr_if
, zvni
);
1458 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1461 zebra_vni_t
*zvni
= NULL
;
1462 struct zebra_if
*zif
= NULL
;
1463 struct zebra_l2info_vxlan zl2_info
;
1464 struct interface
*vlan_if
= NULL
;
1465 struct interface
*vrr_if
= NULL
;
1466 struct interface
*ifp
= NULL
;
1468 zvni
= (zebra_vni_t
*)backet
->data
;
1472 if (!advertise_gw_macip_enabled(zvni
))
1475 ifp
= zvni
->vxlan_if
;
1480 /* If down or not mapped to a bridge, we're done. */
1481 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1483 zl2_info
= zif
->l2info
.vxl
;
1485 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1486 zif
->brslave_info
.br_if
);
1490 /* Add primary SVI MAC-IP */
1491 zvni_add_macip_for_intf(vlan_if
, zvni
);
1493 /* Add VRR MAC-IP - if any*/
1494 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1496 zvni_add_macip_for_intf(vrr_if
, zvni
);
1502 * Make hash key for MAC.
1504 static unsigned int mac_hash_keymake(void *p
)
1506 zebra_mac_t
*pmac
= p
;
1507 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1509 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1513 * Compare two MAC addresses.
1515 static int mac_cmp(const void *p1
, const void *p2
)
1517 const zebra_mac_t
*pmac1
= p1
;
1518 const zebra_mac_t
*pmac2
= p2
;
1520 if (pmac1
== NULL
&& pmac2
== NULL
)
1523 if (pmac1
== NULL
|| pmac2
== NULL
)
1526 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1532 * Callback to allocate MAC hash entry.
1534 static void *zvni_mac_alloc(void *p
)
1536 const zebra_mac_t
*tmp_mac
= p
;
1539 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1542 return ((void *)mac
);
1548 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1550 zebra_mac_t tmp_mac
;
1551 zebra_mac_t
*mac
= NULL
;
1553 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1554 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1555 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1558 mac
->neigh_list
= list_new();
1559 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1567 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1569 zebra_mac_t
*tmp_mac
;
1571 list_delete_and_null(&mac
->neigh_list
);
1573 /* Free the VNI hash entry and allocated memory. */
1574 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1576 XFREE(MTYPE_MAC
, tmp_mac
);
1582 * Free MAC hash entry (callback)
1584 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1586 struct mac_walk_ctx
*wctx
= arg
;
1587 zebra_mac_t
*mac
= backet
->data
;
1590 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1591 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1592 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1593 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1594 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1595 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1596 &wctx
->r_vtep_ip
))) {
1597 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1598 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
1600 zvni_mac_send_del_to_client(
1601 wctx
->zvni
->vni
, &mac
->macaddr
,
1602 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
1605 if (wctx
->uninstall
)
1606 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
1608 return zvni_mac_del(wctx
->zvni
, mac
);
1615 * Delete all MAC entries from specific VTEP for a particular VNI.
1617 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1618 struct in_addr
*r_vtep_ip
)
1620 struct mac_walk_ctx wctx
;
1622 if (!zvni
->mac_table
)
1625 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1627 wctx
.uninstall
= uninstall
;
1628 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
1629 wctx
.r_vtep_ip
= *r_vtep_ip
;
1631 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1632 void *))zvni_mac_del_hash_entry
,
1637 * Delete all MAC entries for this VNI.
1639 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
1640 int uninstall
, int upd_client
, u_int32_t flags
)
1642 struct mac_walk_ctx wctx
;
1644 if (!zvni
->mac_table
)
1647 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1649 wctx
.uninstall
= uninstall
;
1650 wctx
.upd_client
= upd_client
;
1653 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1654 void *))zvni_mac_del_hash_entry
,
1659 * Look up MAC hash entry.
1661 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
1666 memset(&tmp
, 0, sizeof(tmp
));
1667 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
1668 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
1674 * Inform BGP about local MAC addition.
1676 static int zvni_mac_send_add_to_client(vni_t vni
,
1677 struct ethaddr
*macaddr
, u_char flags
)
1679 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
1684 * Inform BGP about local MAC deletion.
1686 static int zvni_mac_send_del_to_client(vni_t vni
,
1687 struct ethaddr
*macaddr
, u_char flags
)
1689 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
1694 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1695 * notifications, to see if they are of interest.
1697 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
1698 struct interface
*br_if
, vlanid_t vid
)
1700 struct zebra_ns
*zns
;
1701 struct route_node
*rn
;
1702 struct interface
*tmp_if
= NULL
;
1703 struct zebra_if
*zif
;
1704 struct zebra_l2info_bridge
*br
;
1705 struct zebra_l2info_vxlan
*vxl
= NULL
;
1706 u_char bridge_vlan_aware
;
1710 /* Determine if bridge is VLAN-aware or not */
1713 br
= &zif
->l2info
.br
;
1714 bridge_vlan_aware
= br
->vlan_aware
;
1716 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1717 /* TODO: Optimize with a hash. */
1718 zns
= zebra_ns_lookup(NS_DEFAULT
);
1719 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1720 tmp_if
= (struct interface
*)rn
->info
;
1724 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1726 if (!if_is_operative(tmp_if
))
1728 vxl
= &zif
->l2info
.vxl
;
1730 if (zif
->brslave_info
.br_if
!= br_if
)
1733 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
1742 zvni
= zvni_lookup(vxl
->vni
);
1747 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1748 * neighbor notifications, to see if they are of interest.
1750 static zebra_vni_t
*zvni_map_svi(struct interface
*ifp
, struct interface
*br_if
)
1752 struct zebra_ns
*zns
;
1753 struct route_node
*rn
;
1754 struct interface
*tmp_if
= NULL
;
1755 struct zebra_if
*zif
;
1756 struct zebra_l2info_bridge
*br
;
1757 struct zebra_l2info_vxlan
*vxl
= NULL
;
1758 u_char bridge_vlan_aware
;
1766 /* Make sure the linked interface is a bridge. */
1767 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
1770 /* Determine if bridge is VLAN-aware or not */
1773 br
= &zif
->l2info
.br
;
1774 bridge_vlan_aware
= br
->vlan_aware
;
1775 if (bridge_vlan_aware
) {
1776 struct zebra_l2info_vlan
*vl
;
1778 if (!IS_ZEBRA_IF_VLAN(ifp
))
1783 vl
= &zif
->l2info
.vl
;
1787 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1788 /* TODO: Optimize with a hash. */
1789 zns
= zebra_ns_lookup(NS_DEFAULT
);
1790 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1791 tmp_if
= (struct interface
*)rn
->info
;
1795 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1797 if (!if_is_operative(tmp_if
))
1799 vxl
= &zif
->l2info
.vxl
;
1801 if (zif
->brslave_info
.br_if
!= br_if
)
1804 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
1813 zvni
= zvni_lookup(vxl
->vni
);
1817 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
1819 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1820 * linked to the bridge
1821 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1824 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
1826 struct zebra_ns
*zns
;
1827 struct route_node
*rn
;
1828 struct interface
*tmp_if
= NULL
;
1829 struct zebra_if
*zif
;
1830 struct zebra_l2info_bridge
*br
;
1831 struct zebra_l2info_vlan
*vl
;
1832 u_char bridge_vlan_aware
;
1835 /* Defensive check, caller expected to invoke only with valid bridge. */
1839 /* Determine if bridge is VLAN-aware or not */
1842 br
= &zif
->l2info
.br
;
1843 bridge_vlan_aware
= br
->vlan_aware
;
1845 /* Check oper status of the SVI. */
1846 if (!bridge_vlan_aware
)
1847 return if_is_operative(br_if
) ? br_if
: NULL
;
1849 /* Identify corresponding VLAN interface. */
1850 /* TODO: Optimize with a hash. */
1851 zns
= zebra_ns_lookup(NS_DEFAULT
);
1852 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1853 tmp_if
= (struct interface
*)rn
->info
;
1854 /* Check oper status of the SVI. */
1855 if (!tmp_if
|| !if_is_operative(tmp_if
))
1858 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
1859 || zif
->link
!= br_if
)
1861 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
1863 if (vl
->vid
== vid
) {
1869 return found
? tmp_if
: NULL
;
1873 * Install remote MAC into the kernel.
1875 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1877 struct zebra_if
*zif
;
1878 struct zebra_l2info_vxlan
*vxl
;
1881 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
1884 zif
= zvni
->vxlan_if
->info
;
1887 vxl
= &zif
->l2info
.vxl
;
1889 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
1891 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
1892 mac
->fwd_info
.r_vtep_ip
, sticky
);
1896 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1897 * moves to remote, we have to uninstall any existing local entry first.
1899 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
1901 struct zebra_if
*zif
;
1902 struct zebra_l2info_vxlan
*vxl
;
1903 struct in_addr vtep_ip
= {.s_addr
= 0};
1904 struct zebra_ns
*zns
;
1905 struct interface
*ifp
;
1907 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
1910 if (!zvni
->vxlan_if
) {
1911 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1916 zif
= zvni
->vxlan_if
->info
;
1919 vxl
= &zif
->l2info
.vxl
;
1922 zns
= zebra_ns_lookup(NS_DEFAULT
);
1923 ifp
= if_lookup_by_index_per_ns(zns
,
1924 mac
->fwd_info
.local
.ifindex
);
1925 if (!ifp
) // unexpected
1928 ifp
= zvni
->vxlan_if
;
1929 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
1932 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
1937 * Install MAC hash entry - called upon access VLAN change.
1939 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
1942 struct mac_walk_ctx
*wctx
= ctxt
;
1944 mac
= (zebra_mac_t
*)backet
->data
;
1948 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
1949 zvni_mac_install(wctx
->zvni
, mac
);
1953 * Decrement neighbor refcount of MAC; uninstall and free it if
1956 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
1959 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
1960 || !list_isempty(mac
->neigh_list
))
1964 zvni_mac_uninstall(zvni
, mac
, 0);
1966 zvni_mac_del(zvni
, mac
);
1970 * Read and populate local MACs and neighbors corresponding to this VNI.
1972 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
1973 struct interface
*ifp
)
1975 struct zebra_ns
*zns
;
1976 struct zebra_if
*zif
;
1977 struct interface
*vlan_if
;
1978 struct zebra_l2info_vxlan
*vxl
;
1979 struct interface
*vrr_if
;
1982 vxl
= &zif
->l2info
.vxl
;
1983 zns
= zebra_ns_lookup(NS_DEFAULT
);
1985 if (IS_ZEBRA_DEBUG_VXLAN
)
1987 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1988 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1989 zif
->brslave_info
.bridge_ifindex
);
1991 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
1992 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1995 if (advertise_gw_macip_enabled(zvni
)) {
1996 /* Add SVI MAC-IP */
1997 zvni_add_macip_for_intf(vlan_if
, zvni
);
1999 /* Add VRR MAC-IP - if any*/
2000 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2002 zvni_add_macip_for_intf(vrr_if
, zvni
);
2005 neigh_read_for_vlan(zns
, vlan_if
);
2010 * Hash function for VNI.
2012 static unsigned int vni_hash_keymake(void *p
)
2014 const zebra_vni_t
*zvni
= p
;
2016 return (jhash_1word(zvni
->vni
, 0));
2020 * Compare 2 VNI hash entries.
2022 static int vni_hash_cmp(const void *p1
, const void *p2
)
2024 const zebra_vni_t
*zvni1
= p1
;
2025 const zebra_vni_t
*zvni2
= p2
;
2027 return (zvni1
->vni
== zvni2
->vni
);
2031 * Callback to allocate VNI hash entry.
2033 static void *zvni_alloc(void *p
)
2035 const zebra_vni_t
*tmp_vni
= p
;
2038 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2039 zvni
->vni
= tmp_vni
->vni
;
2040 return ((void *)zvni
);
2044 * Look up VNI hash entry.
2046 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2048 struct zebra_vrf
*zvrf
;
2049 zebra_vni_t tmp_vni
;
2050 zebra_vni_t
*zvni
= NULL
;
2052 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2054 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2056 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2062 * Add VNI hash entry.
2064 static zebra_vni_t
*zvni_add(vni_t vni
)
2066 struct zebra_vrf
*zvrf
;
2067 zebra_vni_t tmp_zvni
;
2068 zebra_vni_t
*zvni
= NULL
;
2070 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2072 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2074 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2077 /* Create hash table for MAC */
2079 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2081 /* Create hash table for neighbors */
2082 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2083 "Zebra VNI Neighbor Table");
2089 * Delete VNI hash entry.
2091 static int zvni_del(zebra_vni_t
*zvni
)
2093 struct zebra_vrf
*zvrf
;
2094 zebra_vni_t
*tmp_zvni
;
2096 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2099 zvni
->vxlan_if
= NULL
;
2101 /* Free the neighbor hash table. */
2102 hash_free(zvni
->neigh_table
);
2103 zvni
->neigh_table
= NULL
;
2105 /* Free the MAC hash table. */
2106 hash_free(zvni
->mac_table
);
2107 zvni
->mac_table
= NULL
;
2109 /* Free the VNI hash entry and allocated memory. */
2110 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2112 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2118 * Inform BGP about local VNI addition.
2120 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2122 struct zserv
*client
;
2125 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2126 /* BGP may not be running. */
2133 zserv_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2134 stream_putl(s
, zvni
->vni
);
2135 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2137 /* Write packet size. */
2138 stream_putw_at(s
, 0, stream_get_endp(s
));
2140 if (IS_ZEBRA_DEBUG_VXLAN
)
2141 zlog_debug("Send VNI_ADD %u %s to %s",
2142 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2143 zebra_route_string(client
->proto
));
2145 client
->vniadd_cnt
++;
2146 return zebra_server_send_message(client
);
2150 * Inform BGP about local VNI deletion.
2152 static int zvni_send_del_to_client(vni_t vni
)
2154 struct zserv
*client
;
2157 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2158 /* BGP may not be running. */
2165 zserv_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2166 stream_putl(s
, vni
);
2168 /* Write packet size. */
2169 stream_putw_at(s
, 0, stream_get_endp(s
));
2171 if (IS_ZEBRA_DEBUG_VXLAN
)
2172 zlog_debug("Send VNI_DEL %u to %s", vni
,
2173 zebra_route_string(client
->proto
));
2175 client
->vnidel_cnt
++;
2176 return zebra_server_send_message(client
);
2180 * Build the VNI hash table by going over the VxLAN interfaces. This
2181 * is called when EVPN (advertise-all-vni) is enabled.
2183 static void zvni_build_hash_table()
2185 struct zebra_ns
*zns
;
2186 struct route_node
*rn
;
2187 struct interface
*ifp
;
2189 /* Walk VxLAN interfaces and create VNI hash. */
2190 zns
= zebra_ns_lookup(NS_DEFAULT
);
2191 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2192 struct zebra_if
*zif
;
2193 struct zebra_l2info_vxlan
*vxl
;
2197 ifp
= (struct interface
*)rn
->info
;
2201 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2203 vxl
= &zif
->l2info
.vxl
;
2207 if (IS_ZEBRA_DEBUG_VXLAN
)
2209 "Create VNI hash for intf %s(%u) VNI %u local IP %s",
2210 ifp
->name
, ifp
->ifindex
, vni
,
2211 inet_ntoa(vxl
->vtep_ip
));
2213 /* VNI hash entry is not expected to exist. */
2214 zvni
= zvni_lookup(vni
);
2217 "VNI hash already present for IF %s(%u) VNI %u",
2218 ifp
->name
, ifp
->ifindex
, vni
);
2222 zvni
= zvni_add(vni
);
2225 "Failed to add VNI hash, IF %s(%u) VNI %u",
2226 ifp
->name
, ifp
->ifindex
, vni
);
2230 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2231 zvni
->vxlan_if
= ifp
;
2233 /* Inform BGP if interface is up and mapped to bridge. */
2234 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2235 zvni_send_add_to_client(zvni
);
2240 * See if remote VTEP matches with prefix.
2242 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2244 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2248 * Locate remote VTEP in VNI hash table.
2250 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2252 zebra_vtep_t
*zvtep
;
2257 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2258 if (zvni_vtep_match(vtep_ip
, zvtep
))
2266 * Add remote VTEP to VNI hash table.
2268 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2270 zebra_vtep_t
*zvtep
;
2272 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2274 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2278 zvtep
->vtep_ip
= *vtep_ip
;
2281 zvni
->vteps
->prev
= zvtep
;
2282 zvtep
->next
= zvni
->vteps
;
2283 zvni
->vteps
= zvtep
;
2289 * Remove remote VTEP from VNI hash table.
2291 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2294 zvtep
->next
->prev
= zvtep
->prev
;
2296 zvtep
->prev
->next
= zvtep
->next
;
2298 zvni
->vteps
= zvtep
->next
;
2300 zvtep
->prev
= zvtep
->next
= NULL
;
2301 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2307 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2308 * uninstall from kernel if asked to.
2310 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2312 zebra_vtep_t
*zvtep
, *zvtep_next
;
2317 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2318 zvtep_next
= zvtep
->next
;
2320 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2321 zvni_vtep_del(zvni
, zvtep
);
2328 * Install remote VTEP into the kernel.
2330 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2332 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2336 * Uninstall remote VTEP from the kernel.
2338 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2340 if (!zvni
->vxlan_if
) {
2341 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2346 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2350 * Cleanup VNI/VTEP and update kernel
2352 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2356 zvni
= (zebra_vni_t
*)backet
->data
;
2360 /* Free up all neighbors and MACs, if any. */
2361 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2362 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2364 /* Free up all remote VTEPs, if any. */
2365 zvni_vtep_del_all(zvni
, 1);
2367 /* Delete the hash entry. */
2372 /* Public functions */
2375 * Display Neighbors for a VNI (VTY command handler).
2377 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2378 vni_t vni
, u_char use_json
)
2381 u_int32_t num_neigh
;
2382 struct neigh_walk_ctx wctx
;
2383 json_object
*json
= NULL
;
2385 if (!is_evpn_enabled())
2387 zvni
= zvni_lookup(vni
);
2390 vty_out(vty
, "{}\n");
2392 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2395 num_neigh
= hashcount(zvni
->neigh_table
);
2400 json
= json_object_new_object();
2402 /* Since we have IPv6 addresses to deal with which can vary widely in
2403 * size, we try to be a bit more elegant in display by first computing
2404 * the maximum width.
2406 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
2409 wctx
.addr_width
= 15;
2411 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
2415 "Number of ARPs (local and remote) known for this VNI: %u\n",
2417 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
2418 "Type", "MAC", "Remote VTEP");
2420 json_object_int_add(json
, "numArpNd", num_neigh
);
2422 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
2424 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2425 json
, JSON_C_TO_STRING_PRETTY
));
2426 json_object_free(json
);
2431 * Display neighbors across all VNIs (VTY command handler).
2433 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2436 json_object
*json
= NULL
;
2439 if (!is_evpn_enabled())
2443 json
= json_object_new_object();
2447 hash_iterate(zvrf
->vni_table
,
2448 (void (*)(struct hash_backet
*,
2449 void *))zvni_print_neigh_hash_all_vni
,
2452 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2453 json
, JSON_C_TO_STRING_PRETTY
));
2454 json_object_free(json
);
2459 * Display specific neighbor for a VNI, if present (VTY command handler).
2461 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
2462 struct zebra_vrf
*zvrf
, vni_t vni
,
2463 struct ipaddr
*ip
, u_char use_json
)
2467 json_object
*json
= NULL
;
2469 if (!is_evpn_enabled())
2471 zvni
= zvni_lookup(vni
);
2474 vty_out(vty
, "{}\n");
2476 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2479 n
= zvni_neigh_lookup(zvni
, ip
);
2483 "%% Requested neighbor does not exist in VNI %u\n",
2488 json
= json_object_new_object();
2490 zvni_print_neigh(n
, vty
, json
);
2493 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2494 json
, JSON_C_TO_STRING_PRETTY
));
2495 json_object_free(json
);
2500 * Display neighbors for a VNI from specific VTEP (VTY command handler).
2501 * By definition, these are remote neighbors.
2503 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2504 vni_t vni
, struct in_addr vtep_ip
,
2508 u_int32_t num_neigh
;
2509 struct neigh_walk_ctx wctx
;
2510 json_object
*json
= NULL
;
2512 if (!is_evpn_enabled())
2514 zvni
= zvni_lookup(vni
);
2517 vty_out(vty
, "{}\n");
2519 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2522 num_neigh
= hashcount(zvni
->neigh_table
);
2526 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
2529 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
2530 wctx
.r_vtep_ip
= vtep_ip
;
2532 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
2535 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2536 json
, JSON_C_TO_STRING_PRETTY
));
2537 json_object_free(json
);
2542 * Display MACs for a VNI (VTY command handler).
2544 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2545 vni_t vni
, u_char use_json
)
2549 struct mac_walk_ctx wctx
;
2550 json_object
*json
= NULL
;
2551 json_object
*json_mac
= NULL
;
2553 if (!is_evpn_enabled())
2555 zvni
= zvni_lookup(vni
);
2558 vty_out(vty
, "{}\n");
2560 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2563 num_macs
= num_valid_macs(zvni
);
2568 json
= json_object_new_object();
2569 json_mac
= json_object_new_object();
2572 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2575 wctx
.json
= json_mac
;
2579 "Number of MACs (local and remote) known for this VNI: %u\n",
2581 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
2582 "Intf/Remote VTEP", "VLAN");
2584 json_object_int_add(json
, "numMacs", num_macs
);
2586 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
2589 json_object_object_add(json
, "macs", json_mac
);
2590 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2591 json
, JSON_C_TO_STRING_PRETTY
));
2592 json_object_free(json
);
2597 * Display MACs for all VNIs (VTY command handler).
2599 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2602 struct mac_walk_ctx wctx
;
2603 json_object
*json
= NULL
;
2605 if (!is_evpn_enabled()) {
2607 vty_out(vty
, "{}\n");
2611 json
= json_object_new_object();
2613 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2616 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
2619 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2620 json
, JSON_C_TO_STRING_PRETTY
));
2621 json_object_free(json
);
2626 * Display MACs for all VNIs (VTY command handler).
2628 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
2629 struct zebra_vrf
*zvrf
,
2630 struct in_addr vtep_ip
,
2633 struct mac_walk_ctx wctx
;
2634 json_object
*json
= NULL
;
2636 if (!is_evpn_enabled())
2640 json
= json_object_new_object();
2642 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2644 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
2645 wctx
.r_vtep_ip
= vtep_ip
;
2647 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
2650 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2651 json
, JSON_C_TO_STRING_PRETTY
));
2652 json_object_free(json
);
2657 * Display specific MAC for a VNI, if present (VTY command handler).
2659 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2660 vni_t vni
, struct ethaddr
*macaddr
)
2665 if (!is_evpn_enabled())
2667 zvni
= zvni_lookup(vni
);
2669 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2672 mac
= zvni_mac_lookup(zvni
, macaddr
);
2674 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
2679 zvni_print_mac(mac
, vty
);
2683 * Display MACs for a VNI from specific VTEP (VTY command handler).
2685 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2686 vni_t vni
, struct in_addr vtep_ip
,
2691 struct mac_walk_ctx wctx
;
2692 json_object
*json
= NULL
;
2693 json_object
*json_mac
= NULL
;
2695 if (!is_evpn_enabled())
2697 zvni
= zvni_lookup(vni
);
2700 vty_out(vty
, "{}\n");
2702 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2705 num_macs
= num_valid_macs(zvni
);
2710 json
= json_object_new_object();
2711 json_mac
= json_object_new_object();
2714 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2717 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
2718 wctx
.r_vtep_ip
= vtep_ip
;
2719 wctx
.json
= json_mac
;
2720 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
2723 json_object_int_add(json
, "numMacs", wctx
.count
);
2725 json_object_object_add(json
, "macs", json_mac
);
2726 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2727 json
, JSON_C_TO_STRING_PRETTY
));
2728 json_object_free(json
);
2734 * Display VNI information (VTY command handler).
2736 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
2740 json_object
*json
= NULL
;
2743 if (!is_evpn_enabled())
2745 zvni
= zvni_lookup(vni
);
2748 vty_out(vty
, "{}\n");
2750 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2754 json
= json_object_new_object();
2757 zvni_print(zvni
, (void *)args
);
2759 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2760 json
, JSON_C_TO_STRING_PRETTY
));
2761 json_object_free(json
);
2766 * Display VNI hash table (VTY command handler).
2768 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2772 json_object
*json
= NULL
;
2775 if (!is_evpn_enabled())
2777 num_vnis
= hashcount(zvrf
->vni_table
);
2780 vty_out(vty
, "{}\n");
2784 json
= json_object_new_object();
2785 json_object_string_add(json
, "advertiseGatewayMacip",
2786 zvrf
->advertise_gw_macip
? "Yes" : "No");
2787 json_object_int_add(json
, "numVnis", num_vnis
);
2789 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
2790 zvrf
->advertise_gw_macip
? "Yes" : "No");
2791 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
2792 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI",
2793 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
2799 hash_iterate(zvrf
->vni_table
,
2800 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
2804 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2805 json
, JSON_C_TO_STRING_PRETTY
));
2806 json_object_free(json
);
2811 * Handle neighbor delete (on a VLAN device / L3 interface) from the
2812 * kernel. This may result in either the neighbor getting deleted from
2813 * our database or being re-added to the kernel (if it is a valid
2816 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
2817 struct interface
*link_if
, struct ipaddr
*ip
)
2821 char buf
[INET6_ADDRSTRLEN
];
2822 char buf2
[ETHER_ADDR_STRLEN
];
2825 /* We are only interested in neighbors on an SVI that resides on top
2826 * of a VxLAN bridge.
2828 zvni
= zvni_map_svi(ifp
, link_if
);
2831 if (!zvni
->vxlan_if
) {
2833 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
2838 if (IS_ZEBRA_DEBUG_VXLAN
)
2839 zlog_debug("Del neighbor %s intf %s(%u) -> VNI %u",
2840 ipaddr2str(ip
, buf
, sizeof(buf
)),
2841 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2843 /* If entry doesn't exist, nothing to do. */
2844 n
= zvni_neigh_lookup(zvni
, ip
);
2848 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2850 if (IS_ZEBRA_DEBUG_VXLAN
)
2852 "Trying to del a neigh %s without a mac %s on VNI %u",
2853 ipaddr2str(ip
, buf
, sizeof(buf
)),
2854 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
2860 /* If it is a remote entry, the kernel has aged this out or someone has
2861 * deleted it, it needs to be re-installed as Quagga is the owner.
2863 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2864 zvni_neigh_install(zvni
, n
);
2868 /* Remove neighbor from BGP. */
2869 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2870 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
2873 /* Delete this neighbor entry. */
2874 zvni_neigh_del(zvni
, n
);
2876 /* see if the AUTO mac needs to be deleted */
2877 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
2878 && !listcount(zmac
->neigh_list
))
2879 zvni_mac_del(zvni
, zmac
);
2885 * Handle neighbor add or update (on a VLAN device / L3 interface)
2888 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
2889 struct interface
*link_if
,
2891 struct ethaddr
*macaddr
, u_int16_t state
,
2896 zebra_mac_t
*zmac
, *old_zmac
;
2897 char buf
[ETHER_ADDR_STRLEN
];
2898 char buf2
[INET6_ADDRSTRLEN
];
2900 /* We are only interested in neighbors on an SVI that resides on top
2901 * of a VxLAN bridge.
2903 zvni
= zvni_map_svi(ifp
, link_if
);
2907 if (IS_ZEBRA_DEBUG_VXLAN
)
2909 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
2911 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2912 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
2913 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
2916 /* create a dummy MAC if the MAC is not already present */
2917 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2919 if (IS_ZEBRA_DEBUG_VXLAN
)
2921 "AUTO MAC %s created for neigh %s on VNI %u",
2922 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2923 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
2925 zmac
= zvni_mac_add(zvni
, macaddr
);
2927 zlog_warn("Failed to add MAC %s VNI %u",
2928 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2933 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
2934 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
2935 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
2938 /* If same entry already exists, it might be a change or it might be a
2939 * move from remote to local.
2941 n
= zvni_neigh_lookup(zvni
, ip
);
2943 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2944 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2947 /* Update any params and return - client doesn't
2948 * care about a purely local change.
2950 n
->ifindex
= ifp
->ifindex
;
2954 /* If the MAC has changed,
2955 * need to issue a delete first
2956 * as this means a different MACIP route.
2957 * Also, need to do some unlinking/relinking.
2959 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
2961 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2963 listnode_delete(old_zmac
->neigh_list
, n
);
2964 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2967 /* Set "local" forwarding info. */
2968 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2969 n
->ifindex
= ifp
->ifindex
;
2970 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2972 /* Link to new MAC */
2973 listnode_add_sort(zmac
->neigh_list
, n
);
2974 } else if (ext_learned
)
2975 /* The neighbor is remote and that is the notification we got.
2978 /* TODO: Evaluate if we need to do anything here. */
2981 /* Neighbor has moved from remote to local. */
2983 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2984 n
->r_vtep_ip
.s_addr
= 0;
2985 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2986 n
->ifindex
= ifp
->ifindex
;
2989 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2992 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2993 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2994 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2995 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2998 /* Set "local" forwarding info. */
2999 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
3000 n
->ifindex
= ifp
->ifindex
;
3003 /* Before we program this in BGP, we need to check if MAC is locally
3005 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
3006 if (IS_ZEBRA_DEBUG_VXLAN
)
3008 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
3009 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
3010 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3017 if (IS_ZEBRA_DEBUG_VXLAN
)
3018 zlog_debug("neigh %s (MAC %s) is now ACTIVE on VNI %u",
3019 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
3020 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3023 ZEBRA_NEIGH_SET_ACTIVE(n
);
3024 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
3029 * Handle message from client to delete a remote MACIP for a VNI.
3031 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
3032 struct zebra_vrf
*zvrf
)
3036 struct ethaddr macaddr
;
3038 struct in_addr vtep_ip
;
3042 u_short l
= 0, ipa_len
;
3043 char buf
[ETHER_ADDR_STRLEN
];
3044 char buf1
[INET6_ADDRSTRLEN
];
3045 struct interface
*ifp
= NULL
;
3046 struct zebra_if
*zif
= NULL
;
3050 while (l
< length
) {
3051 /* Obtain each remote MACIP and process. */
3052 /* Message contains VNI, followed by MAC followed by IP (if any)
3053 * followed by remote VTEP IP.
3057 memset(&ip
, 0, sizeof(ip
));
3058 STREAM_GETL(s
, vni
);
3059 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
3060 STREAM_GETL(s
, ipa_len
);
3062 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
3064 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
3066 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
3067 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
3068 l
+= IPV4_MAX_BYTELEN
;
3070 if (IS_ZEBRA_DEBUG_VXLAN
)
3072 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
3073 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3074 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
3076 zebra_route_string(client
->proto
));
3078 /* Locate VNI hash entry - expected to exist. */
3079 zvni
= zvni_lookup(vni
);
3081 if (IS_ZEBRA_DEBUG_VXLAN
)
3083 "Failed to locate VNI hash upon remote MACIP DEL, "
3088 ifp
= zvni
->vxlan_if
;
3091 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
3097 /* If down or not mapped to a bridge, we're done. */
3098 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3101 /* The remote VTEP specified is normally expected to exist, but
3103 * possible that the peer may delete the VTEP before deleting
3105 * referring to the VTEP, in which case the handler (see
3107 * would have already deleted the MACs.
3109 if (!zvni_vtep_find(zvni
, &vtep_ip
))
3112 mac
= zvni_mac_lookup(zvni
, &macaddr
);
3114 n
= zvni_neigh_lookup(zvni
, &ip
);
3118 "Failed to locate MAC %s for neigh %s VNI %u",
3119 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3120 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
3124 /* If the remote mac or neighbor doesn't exist there is nothing
3126 * to do. Otherwise, uninstall the entry and then remove it.
3131 /* Uninstall remote neighbor or MAC. */
3133 /* When the MAC changes for an IP, it is possible the
3135 * update the new MAC before trying to delete the "old"
3137 * (as these are two different MACIP routes). Do the
3139 * if the MAC matches.
3141 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
3142 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
3145 zvni_neigh_uninstall(zvni
, n
);
3146 zvni_neigh_del(zvni
, n
);
3147 zvni_deref_ip2mac(zvni
, mac
, 1);
3150 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
3151 zvni_process_neigh_on_remote_mac_del(zvni
,
3154 if (list_isempty(mac
->neigh_list
)) {
3155 zvni_mac_uninstall(zvni
, mac
, 0);
3156 zvni_mac_del(zvni
, mac
);
3158 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3168 * Handle message from client to add a remote MACIP for a VNI. This
3169 * could be just the add of a MAC address or the add of a neighbor
3172 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
3173 struct zebra_vrf
*zvrf
)
3177 struct ethaddr macaddr
;
3179 struct in_addr vtep_ip
;
3181 zebra_vtep_t
*zvtep
;
3182 zebra_mac_t
*mac
, *old_mac
;
3184 u_short l
= 0, ipa_len
;
3185 int update_mac
= 0, update_neigh
= 0;
3186 char buf
[ETHER_ADDR_STRLEN
];
3187 char buf1
[INET6_ADDRSTRLEN
];
3189 struct interface
*ifp
= NULL
;
3190 struct zebra_if
*zif
= NULL
;
3192 if (!EVPN_ENABLED(zvrf
)) {
3193 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
3194 __PRETTY_FUNCTION__
);
3200 while (l
< length
) {
3201 /* Obtain each remote MACIP and process. */
3202 /* Message contains VNI, followed by MAC followed by IP (if any)
3203 * followed by remote VTEP IP.
3205 update_mac
= update_neigh
= 0;
3208 memset(&ip
, 0, sizeof(ip
));
3209 STREAM_GETL(s
, vni
);
3210 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
3211 STREAM_GETL(s
, ipa_len
);
3213 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
3215 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
3217 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
3218 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
3219 l
+= IPV4_MAX_BYTELEN
;
3221 /* Get 'sticky' flag. */
3222 STREAM_GETC(s
, sticky
);
3225 if (IS_ZEBRA_DEBUG_VXLAN
)
3227 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
3228 sticky
? "sticky " : "",
3229 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3230 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
3232 zebra_route_string(client
->proto
));
3234 /* Locate VNI hash entry - expected to exist. */
3235 zvni
= zvni_lookup(vni
);
3238 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
3242 ifp
= zvni
->vxlan_if
;
3245 "VNI %u hash %p doesn't have intf upon remote MACIP add",
3251 /* If down or not mapped to a bridge, we're done. */
3252 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3255 /* The remote VTEP specified should normally exist, but it is
3257 * that when peering comes up, peer may advertise MACIP routes
3259 * advertising type-3 routes.
3261 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
3263 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
3265 "Failed to add remote VTEP, VNI %u zvni %p",
3270 zvni_vtep_install(zvni
, &vtep_ip
);
3273 /* First, check if the remote MAC is unknown or has a change. If
3275 * that needs to be updated first. Note that client could
3277 * MAC and MACIP separately or just install the latter.
3279 mac
= zvni_mac_lookup(zvni
, &macaddr
);
3280 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
3281 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
3283 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
3288 mac
= zvni_mac_add(zvni
, &macaddr
);
3291 "Failed to add MAC %s VNI %u Remote VTEP %s",
3292 prefix_mac2str(&macaddr
, buf
,
3294 vni
, inet_ntoa(vtep_ip
));
3298 /* Is this MAC created for a MACIP? */
3300 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3303 /* Set "auto" and "remote" forwarding info. */
3304 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3305 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
3306 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
3307 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
3310 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3312 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3314 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
3316 /* Install the entry. */
3317 zvni_mac_install(zvni
, mac
);
3320 /* If there is no IP, continue - after clearing AUTO flag of
3323 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3327 /* Check if the remote neighbor itself is unknown or has a
3329 * If so, create or update and then install the entry.
3331 n
= zvni_neigh_lookup(zvni
, &ip
);
3332 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
3333 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
3334 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
3339 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
3342 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
3343 ipaddr2str(&ip
, buf1
,
3345 prefix_mac2str(&macaddr
, buf
,
3347 vni
, inet_ntoa(vtep_ip
));
3351 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
3353 /* MAC change, update neigh list for old and new
3355 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
3357 listnode_delete(old_mac
->neigh_list
, n
);
3358 zvni_deref_ip2mac(zvni
, old_mac
, 1);
3360 listnode_add_sort(mac
->neigh_list
, n
);
3361 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
3364 /* Set "remote" forwarding info. */
3365 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
3366 /* TODO: Handle MAC change. */
3367 n
->r_vtep_ip
= vtep_ip
;
3368 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3370 /* Install the entry. */
3371 zvni_neigh_install(zvni
, n
);
3380 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
3381 * us, this must involve a multihoming scenario. Treat this as implicit delete
3382 * of any prior local MAC.
3384 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
3385 struct interface
*br_if
,
3386 struct ethaddr
*macaddr
, vlanid_t vid
)
3388 struct zebra_if
*zif
;
3389 struct zebra_l2info_vxlan
*vxl
;
3393 char buf
[ETHER_ADDR_STRLEN
];
3398 vxl
= &zif
->l2info
.vxl
;
3401 /* Check if EVPN is enabled. */
3402 if (!is_evpn_enabled())
3405 /* Locate hash entry; it is expected to exist. */
3406 zvni
= zvni_lookup(vni
);
3410 /* If entry doesn't exist, nothing to do. */
3411 mac
= zvni_mac_lookup(zvni
, macaddr
);
3415 /* Is it a local entry? */
3416 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
3419 if (IS_ZEBRA_DEBUG_VXLAN
)
3421 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
3422 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3423 ifp
->name
, ifp
->ifindex
, vni
);
3425 /* Remove MAC from BGP. */
3426 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
3427 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
3428 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
3431 * If there are no neigh associated with the mac delete the mac
3432 * else mark it as AUTO for forward reference
3434 if (!listcount(mac
->neigh_list
)) {
3435 zvni_mac_del(zvni
, mac
);
3437 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3438 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3445 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
3446 * This can happen because the remote MAC entries are also added as "dynamic",
3447 * so the kernel can ageout the entry.
3449 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
3450 struct interface
*br_if
,
3451 struct ethaddr
*macaddr
, vlanid_t vid
)
3453 struct zebra_if
*zif
;
3454 struct zebra_l2info_vxlan
*vxl
;
3458 char buf
[ETHER_ADDR_STRLEN
];
3462 vxl
= &zif
->l2info
.vxl
;
3465 /* Check if EVPN is enabled. */
3466 if (!is_evpn_enabled())
3469 /* Locate hash entry; it is expected to exist. */
3470 zvni
= zvni_lookup(vni
);
3474 /* If entry doesn't exist, nothing to do. */
3475 mac
= zvni_mac_lookup(zvni
, macaddr
);
3479 /* Is it a remote entry? */
3480 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
3483 if (IS_ZEBRA_DEBUG_VXLAN
)
3484 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
3485 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3488 zvni_mac_install(zvni
, mac
);
3493 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
3495 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
3496 struct ethaddr
*macaddr
, vlanid_t vid
)
3500 char buf
[ETHER_ADDR_STRLEN
];
3503 /* We are interested in MACs only on ports or (port, VLAN) that
3506 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
3509 if (!zvni
->vxlan_if
) {
3510 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
3515 if (IS_ZEBRA_DEBUG_VXLAN
)
3516 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
3517 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3518 ifp
->ifindex
, vid
, zvni
->vni
);
3520 /* If entry doesn't exist, nothing to do. */
3521 mac
= zvni_mac_lookup(zvni
, macaddr
);
3525 /* Is it a local entry? */
3526 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
3529 /* Remove MAC from BGP. */
3530 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
3531 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
3532 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
3534 /* Update all the neigh entries associated with this mac */
3535 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
3538 * If there are no neigh associated with the mac delete the mac
3539 * else mark it as AUTO for forward reference
3541 if (!listcount(mac
->neigh_list
)) {
3542 zvni_mac_del(zvni
, mac
);
3544 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3545 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3552 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
3554 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
3555 struct interface
*br_if
,
3556 struct ethaddr
*macaddr
, vlanid_t vid
,
3561 char buf
[ETHER_ADDR_STRLEN
];
3565 /* We are interested in MACs only on ports or (port, VLAN) that
3568 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
3570 if (IS_ZEBRA_DEBUG_VXLAN
)
3572 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
3573 sticky
? "sticky " : "",
3574 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3575 ifp
->name
, ifp
->ifindex
, vid
);
3579 if (!zvni
->vxlan_if
) {
3580 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
3585 if (IS_ZEBRA_DEBUG_VXLAN
)
3587 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
3588 sticky
? "sticky " : "",
3589 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3590 ifp
->ifindex
, vid
, zvni
->vni
);
3592 /* If same entry already exists, nothing to do. */
3593 mac
= zvni_mac_lookup(zvni
, macaddr
);
3595 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
3596 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
3602 * return if nothing has changed.
3603 * inform bgp if sticky flag has changed
3604 * update locally and do not inform bgp if local
3605 * parameters like interface has changed
3607 if (mac_sticky
== sticky
3608 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
3609 && mac
->fwd_info
.local
.vid
== vid
) {
3610 if (IS_ZEBRA_DEBUG_VXLAN
)
3612 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
3613 "entry exists and has not changed ",
3614 sticky
? "sticky " : "",
3615 prefix_mac2str(macaddr
, buf
,
3617 ifp
->name
, ifp
->ifindex
, vid
,
3620 } else if (mac_sticky
!= sticky
) {
3623 add
= 0; /* This is an update of local
3626 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
3628 * If we have already learned the MAC as a remote sticky
3630 * this is a operator error and we must log a warning
3632 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
3634 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
3635 prefix_mac2str(macaddr
, buf
,
3637 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
3645 mac
= zvni_mac_add(zvni
, macaddr
);
3647 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
3648 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3649 ifp
->name
, ifp
->ifindex
, vid
);
3654 /* Set "local" forwarding info. */
3655 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
3656 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3657 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3658 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
3659 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
3660 mac
->fwd_info
.local
.vid
= vid
;
3663 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3665 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3667 /* Inform BGP if required. */
3669 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
3670 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
3678 * Handle message from client to delete a remote VTEP for a VNI.
3680 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
3681 struct zebra_vrf
*zvrf
)
3686 struct in_addr vtep_ip
;
3688 zebra_vtep_t
*zvtep
;
3689 struct interface
*ifp
;
3690 struct zebra_if
*zif
;
3692 if (!is_evpn_enabled()) {
3693 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
3694 __PRETTY_FUNCTION__
);
3698 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
3699 zlog_err("Recv MACIP DEL for non-default VRF %u",
3706 while (l
< length
) {
3707 /* Obtain each remote VTEP and process. */
3708 STREAM_GETL(s
, vni
);
3710 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
3711 l
+= IPV4_MAX_BYTELEN
;
3713 if (IS_ZEBRA_DEBUG_VXLAN
)
3714 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
3715 inet_ntoa(vtep_ip
), vni
,
3716 zebra_route_string(client
->proto
));
3718 /* Locate VNI hash entry - expected to exist. */
3719 zvni
= zvni_lookup(vni
);
3721 if (IS_ZEBRA_DEBUG_VXLAN
)
3723 "Failed to locate VNI hash upon remote VTEP DEL, "
3729 ifp
= zvni
->vxlan_if
;
3732 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
3738 /* If down or not mapped to a bridge, we're done. */
3739 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3742 /* If the remote VTEP does not exist, there's nothing more to
3744 * Otherwise, uninstall any remote MACs pointing to this VTEP
3746 * then, the VTEP entry itself and remove it.
3748 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
3752 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
3753 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
3754 zvni_vtep_uninstall(zvni
, &vtep_ip
);
3755 zvni_vtep_del(zvni
, zvtep
);
3763 * Handle message from client to add a remote VTEP for a VNI.
3765 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
3766 struct zebra_vrf
*zvrf
)
3771 struct in_addr vtep_ip
;
3773 struct interface
*ifp
;
3774 struct zebra_if
*zif
;
3776 if (!is_evpn_enabled()) {
3777 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
3778 __PRETTY_FUNCTION__
);
3782 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
3783 zlog_err("Recv MACIP ADD for non-default VRF %u",
3790 while (l
< length
) {
3791 /* Obtain each remote VTEP and process. */
3792 STREAM_GETL(s
, vni
);
3794 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
3795 l
+= IPV4_MAX_BYTELEN
;
3797 if (IS_ZEBRA_DEBUG_VXLAN
)
3798 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
3799 inet_ntoa(vtep_ip
), vni
,
3800 zebra_route_string(client
->proto
));
3802 /* Locate VNI hash entry - expected to exist. */
3803 zvni
= zvni_lookup(vni
);
3806 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
3811 ifp
= zvni
->vxlan_if
;
3814 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
3821 /* If down or not mapped to a bridge, we're done. */
3822 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3825 /* If the remote VTEP already exists,
3826 there's nothing more to do. */
3827 if (zvni_vtep_find(zvni
, &vtep_ip
))
3830 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
3832 "Failed to add remote VTEP, VNI %u zvni %p",
3837 zvni_vtep_install(zvni
, &vtep_ip
);
3845 * Add/Del gateway macip to evpn
3847 * 1. SVI interface on a vlan aware bridge
3848 * 2. SVI interface on a vlan unaware bridge
3849 * 3. vrr interface (MACVLAN) associated to a SVI
3850 * We advertise macip routes for an interface if it is associated to VxLan vlan
3852 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
3856 struct ethaddr macaddr
;
3857 zebra_vni_t
*zvni
= NULL
;
3859 memset(&ip
, 0, sizeof(struct ipaddr
));
3860 memset(&macaddr
, 0, sizeof(struct ethaddr
));
3862 /* Check if EVPN is enabled. */
3863 if (!is_evpn_enabled())
3866 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
3867 struct interface
*svi_if
=
3868 NULL
; /* SVI corresponding to the MACVLAN */
3869 struct zebra_if
*ifp_zif
=
3870 NULL
; /* Zebra daemon specific info for MACVLAN */
3871 struct zebra_if
*svi_if_zif
=
3872 NULL
; /* Zebra daemon specific info for SVI*/
3874 ifp_zif
= ifp
->info
;
3879 * for a MACVLAN interface the link represents the svi_if
3881 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
3882 ifp_zif
->link_ifindex
);
3884 zlog_err("MACVLAN %s(%u) without link information",
3885 ifp
->name
, ifp
->ifindex
);
3889 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
3891 * If it is a vlan aware bridge then the link gives the
3892 * bridge information
3894 struct interface
*svi_if_link
= NULL
;
3896 svi_if_zif
= svi_if
->info
;
3898 svi_if_link
= if_lookup_by_index_per_ns(
3899 zebra_ns_lookup(NS_DEFAULT
),
3900 svi_if_zif
->link_ifindex
);
3901 zvni
= zvni_map_svi(svi_if
, svi_if_link
);
3903 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
3905 * If it is a vlan unaware bridge then svi is the bridge
3908 zvni
= zvni_map_svi(svi_if
, svi_if
);
3910 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
3911 struct zebra_if
*svi_if_zif
=
3912 NULL
; /* Zebra daemon specific info for SVI */
3913 struct interface
*svi_if_link
=
3914 NULL
; /* link info for the SVI = bridge info */
3916 svi_if_zif
= ifp
->info
;
3917 svi_if_link
= if_lookup_by_index_per_ns(
3918 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
3919 if (svi_if_zif
&& svi_if_link
)
3920 zvni
= zvni_map_svi(ifp
, svi_if_link
);
3921 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
3922 zvni
= zvni_map_svi(ifp
, ifp
);
3928 if (!zvni
->vxlan_if
) {
3929 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
3935 /* check if we are advertising gw macip routes */
3936 if (!advertise_gw_macip_enabled(zvni
))
3939 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
3941 if (p
->family
== AF_INET
) {
3942 ip
.ipa_type
= IPADDR_V4
;
3943 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
3944 sizeof(struct in_addr
));
3945 } else if (p
->family
== AF_INET6
) {
3946 ip
.ipa_type
= IPADDR_V6
;
3947 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
3948 sizeof(struct in6_addr
));
3953 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
3955 zvni_gw_macip_del(ifp
, zvni
, &ip
);
3961 * Handle SVI interface going down. At this point, this is a NOP since
3962 * the kernel deletes the neighbor entries on this SVI (if any).
3964 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
3970 * Handle SVI interface coming up. This may or may not be of interest,
3971 * but if this is a SVI on a VxLAN bridge, we need to install any remote
3972 * neighbor entries (which will be used for EVPN ARP suppression).
3974 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
3977 struct neigh_walk_ctx n_wctx
;
3979 zvni
= zvni_map_svi(ifp
, link_if
);
3983 if (!zvni
->vxlan_if
) {
3984 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
3989 if (IS_ZEBRA_DEBUG_VXLAN
)
3990 zlog_debug("SVI %s(%u) VNI %u is UP, installing neighbors",
3991 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
3993 /* Install any remote neighbors for this VNI. */
3994 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
3996 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
, &n_wctx
);
4002 * Handle VxLAN interface down - update BGP if required, and do
4005 int zebra_vxlan_if_down(struct interface
*ifp
)
4007 struct zebra_if
*zif
;
4009 struct zebra_l2info_vxlan
*vxl
;
4012 /* Check if EVPN is enabled. */
4013 if (!is_evpn_enabled())
4018 vxl
= &zif
->l2info
.vxl
;
4021 if (IS_ZEBRA_DEBUG_VXLAN
)
4022 zlog_debug("Intf %s(%u) VNI %u is DOWN",
4023 ifp
->name
, ifp
->ifindex
, vni
);
4025 /* Locate hash entry; it is expected to exist. */
4026 zvni
= zvni_lookup(vni
);
4029 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
4030 ifp
->name
, ifp
->ifindex
, vni
);
4034 assert(zvni
->vxlan_if
== ifp
);
4036 /* Delete this VNI from BGP. */
4037 zvni_send_del_to_client(zvni
->vni
);
4039 /* Free up all neighbors and MACs, if any. */
4040 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
4041 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
4043 /* Free up all remote VTEPs, if any. */
4044 zvni_vtep_del_all(zvni
, 1);
4050 * Handle VxLAN interface up - update BGP if required.
4052 int zebra_vxlan_if_up(struct interface
*ifp
)
4054 struct zebra_if
*zif
;
4056 struct zebra_l2info_vxlan
*vxl
;
4059 /* Check if EVPN is enabled. */
4060 if (!is_evpn_enabled())
4065 vxl
= &zif
->l2info
.vxl
;
4068 if (IS_ZEBRA_DEBUG_VXLAN
)
4069 zlog_debug("Intf %s(%u) VNI %u is UP",
4070 ifp
->name
, ifp
->ifindex
, vni
);
4072 /* Locate hash entry; it is expected to exist. */
4073 zvni
= zvni_lookup(vni
);
4076 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
4077 ifp
->name
, ifp
->ifindex
, vni
);
4081 assert(zvni
->vxlan_if
== ifp
);
4083 /* If part of a bridge, inform BGP about this VNI. */
4084 /* Also, read and populate local MACs and neighbors. */
4085 if (zif
->brslave_info
.br_if
) {
4086 zvni_send_add_to_client(zvni
);
4087 zvni_read_mac_neigh(zvni
, ifp
);
4094 * Handle VxLAN interface delete. Locate and remove entry in hash table
4095 * and update BGP, if required.
4097 int zebra_vxlan_if_del(struct interface
*ifp
)
4099 struct zebra_if
*zif
;
4101 struct zebra_l2info_vxlan
*vxl
;
4104 /* Check if EVPN is enabled. */
4105 if (!is_evpn_enabled())
4110 vxl
= &zif
->l2info
.vxl
;
4113 if (IS_ZEBRA_DEBUG_VXLAN
)
4114 zlog_debug("Del VNI %u intf %s(%u)",
4115 vni
, ifp
->name
, ifp
->ifindex
);
4117 /* Locate hash entry; it is expected to exist. */
4118 zvni
= zvni_lookup(vni
);
4121 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
4122 ifp
->name
, ifp
->ifindex
, vni
);
4126 /* Delete VNI from BGP. */
4127 zvni_send_del_to_client(zvni
->vni
);
4129 /* Free up all neighbors and MAC, if any. */
4130 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
4131 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
4133 /* Free up all remote VTEPs, if any. */
4134 zvni_vtep_del_all(zvni
, 0);
4136 /* Delete the hash entry. */
4137 if (zvni_del(zvni
)) {
4138 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
4139 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4147 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
4149 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
4151 struct zebra_if
*zif
;
4153 struct zebra_l2info_vxlan
*vxl
;
4156 /* Check if EVPN is enabled. */
4157 if (!is_evpn_enabled())
4162 vxl
= &zif
->l2info
.vxl
;
4165 /* Update VNI hash. */
4166 zvni
= zvni_lookup(vni
);
4169 "Failed to find VNI hash on update, IF %s(%u) VNI %u",
4170 ifp
->name
, ifp
->ifindex
, vni
);
4174 if (IS_ZEBRA_DEBUG_VXLAN
)
4176 "Update VNI %u intf %s(%u) VLAN %u local IP %s "
4177 "master %u chg 0x%x",
4178 vni
, ifp
->name
, ifp
->ifindex
,
4179 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
4180 zif
->brslave_info
.bridge_ifindex
, chgflags
);
4182 /* Removed from bridge? Cleanup and return */
4183 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
4184 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
4185 /* Delete from client, remove all remote VTEPs */
4186 /* Also, free up all MACs and neighbors. */
4187 zvni_send_del_to_client(zvni
->vni
);
4188 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
4189 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
4190 zvni_vtep_del_all(zvni
, 1);
4194 /* Handle other changes. */
4195 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
4196 /* Remove all existing local neighbors and MACs for this VNI
4197 * (including from BGP)
4199 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
4200 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
4203 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
4204 zvni
->vxlan_if
= ifp
;
4206 /* Take further actions needed. Note that if we are here, there is a
4207 * change of interest.
4209 /* If down or not mapped to a bridge, we're done. */
4210 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4213 /* Inform BGP, if there is a change of interest. */
4215 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
4216 zvni_send_add_to_client(zvni
);
4218 /* If there is a valid new master or a VLAN mapping change, read and
4219 * populate local MACs and neighbors. Also, reinstall any remote MACs
4220 * and neighbors for this VNI (based on new VLAN).
4222 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
4223 zvni_read_mac_neigh(zvni
, ifp
);
4224 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
4225 struct mac_walk_ctx m_wctx
;
4226 struct neigh_walk_ctx n_wctx
;
4228 zvni_read_mac_neigh(zvni
, ifp
);
4230 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
4232 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
, &m_wctx
);
4234 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
4236 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
4244 * Handle VxLAN interface add.
4246 int zebra_vxlan_if_add(struct interface
*ifp
)
4248 struct zebra_if
*zif
;
4250 struct zebra_l2info_vxlan
*vxl
;
4253 /* Check if EVPN is enabled. */
4254 if (!is_evpn_enabled())
4259 vxl
= &zif
->l2info
.vxl
;
4262 if (IS_ZEBRA_DEBUG_VXLAN
)
4264 "Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
4265 vni
, ifp
->name
, ifp
->ifindex
,
4266 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
4267 zif
->brslave_info
.bridge_ifindex
);
4269 /* Create or update VNI hash. */
4270 zvni
= zvni_lookup(vni
);
4272 zvni
= zvni_add(vni
);
4275 "Failed to add VNI hash, IF %s(%u) VNI %u",
4276 ifp
->name
, ifp
->ifindex
, vni
);
4281 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
4282 zvni
->vxlan_if
= ifp
;
4284 /* If down or not mapped to a bridge, we're done. */
4285 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4289 zvni_send_add_to_client(zvni
);
4291 /* Read and populate local MACs and neighbors */
4292 zvni_read_mac_neigh(zvni
, ifp
);
4298 * Handle message from client to enable/disable advertisement of g/w macip
4301 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
4302 struct zebra_vrf
*zvrf
)
4307 zebra_vni_t
*zvni
= NULL
;
4308 struct interface
*ifp
= NULL
;
4310 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
4311 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
4317 STREAM_GETC(s
, advertise
);
4318 STREAM_GET(&vni
, s
, 3);
4321 if (IS_ZEBRA_DEBUG_VXLAN
)
4322 zlog_debug("EVPN gateway macip Adv %s, currently %s",
4323 advertise
? "enabled" : "disabled",
4324 advertise_gw_macip_enabled(NULL
)
4328 if (zvrf
->advertise_gw_macip
== advertise
)
4331 zvrf
->advertise_gw_macip
= advertise
;
4333 if (advertise_gw_macip_enabled(zvni
))
4334 hash_iterate(zvrf
->vni_table
,
4335 zvni_gw_macip_add_for_vni_hash
, NULL
);
4337 hash_iterate(zvrf
->vni_table
,
4338 zvni_gw_macip_del_for_vni_hash
, NULL
);
4341 struct zebra_if
*zif
= NULL
;
4342 struct zebra_l2info_vxlan zl2_info
;
4343 struct interface
*vlan_if
= NULL
;
4344 struct interface
*vrr_if
= NULL
;
4346 if (IS_ZEBRA_DEBUG_VXLAN
)
4348 "EVPN gateway macip Adv %s on VNI %d , currently %s",
4349 advertise
? "enabled" : "disabled", vni
,
4350 advertise_gw_macip_enabled(zvni
)
4354 zvni
= zvni_lookup(vni
);
4358 if (zvni
->advertise_gw_macip
== advertise
)
4361 zvni
->advertise_gw_macip
= advertise
;
4363 ifp
= zvni
->vxlan_if
;
4369 /* If down or not mapped to a bridge, we're done. */
4370 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4373 zl2_info
= zif
->l2info
.vxl
;
4375 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
4376 zif
->brslave_info
.br_if
);
4380 if (advertise_gw_macip_enabled(zvni
)) {
4381 /* Add primary SVI MAC-IP */
4382 zvni_add_macip_for_intf(vlan_if
, zvni
);
4384 /* Add VRR MAC-IP - if any*/
4385 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
4387 zvni_add_macip_for_intf(vrr_if
, zvni
);
4389 /* Del primary MAC-IP */
4390 zvni_del_macip_for_intf(vlan_if
, zvni
);
4392 /* Del VRR MAC-IP - if any*/
4393 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
4395 zvni_del_macip_for_intf(vrr_if
, zvni
);
4405 * Handle message from client to learn (or stop learning) about VNIs and MACs.
4406 * When enabled, the VNI hash table will be built and MAC FDB table read;
4407 * when disabled, the entries should be deleted and remote VTEPs and MACs
4408 * uninstalled from the kernel.
4410 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
4411 u_short length
, struct zebra_vrf
*zvrf
)
4416 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
4417 zlog_err("EVPN VNI Adv for non-default VRF %u",
4423 STREAM_GETC(s
, advertise
);
4425 if (IS_ZEBRA_DEBUG_VXLAN
)
4426 zlog_debug("EVPN VNI Adv %s, currently %s",
4427 advertise
? "enabled" : "disabled",
4428 is_evpn_enabled() ? "enabled" : "disabled");
4430 if (zvrf
->advertise_all_vni
== advertise
)
4433 zvrf
->advertise_all_vni
= advertise
;
4434 if (is_evpn_enabled()) {
4435 /* Build VNI hash table and inform BGP. */
4436 zvni_build_hash_table();
4438 /* Add all SVI (L3 GW) MACs to BGP*/
4439 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
4442 /* Read the MAC FDB */
4443 macfdb_read(zvrf
->zns
);
4445 /* Read neighbors */
4446 neigh_read(zvrf
->zns
);
4448 /* Cleanup VTEPs for all VNIs - uninstall from
4449 * kernel and free entries.
4451 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
4459 * Allocate VNI hash table for this VRF and do other initialization.
4460 * NOTE: Currently supported only for default VRF.
4462 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
4466 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
4467 "Zebra VRF VNI Table");
4470 /* Close all VNI handling */
4471 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
4475 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
4476 hash_free(zvrf
->vni_table
);