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(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, vni_t vni
,
88 struct ethaddr
*macaddr
, u_char flags
);
89 static int zvni_neigh_send_del_to_client(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, vni_t vni
,
111 struct ethaddr
*macaddr
, u_char flags
);
112 static int zvni_mac_send_del_to_client(struct zebra_vrf
*zvrf
, 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(struct zebra_vrf
*zvrf
, vni_t vni
);
124 static zebra_vni_t
*zvni_add(struct zebra_vrf
*zvrf
, vni_t vni
);
125 static int zvni_del(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
);
126 static int zvni_send_add_to_client(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
);
127 static int zvni_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
);
128 static void zvni_build_hash_table(struct zebra_vrf
*zvrf
);
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(struct zebra_vrf
*zvrf
,
145 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
148 /* Private functions */
150 static int advertise_gw_macip_enabled(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
)
152 if (zvrf
&& zvrf
->advertise_gw_macip
)
155 if (zvni
&& zvni
->advertise_gw_macip
)
162 * Helper function to determine maximum width of neighbor IP address for
163 * display - just because we're dealing with IPv6 addresses that can
166 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
169 char buf
[INET6_ADDRSTRLEN
];
170 struct neigh_walk_ctx
*wctx
= ctxt
;
173 n
= (zebra_neigh_t
*)backet
->data
;
177 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
178 if (width
> wctx
->addr_width
)
179 wctx
->addr_width
= width
;
183 * Print a specific neighbor entry.
185 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
188 char buf1
[ETHER_ADDR_STRLEN
];
189 char buf2
[INET6_ADDRSTRLEN
];
191 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
192 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
193 vty
= (struct vty
*)ctxt
;
195 vty_out(vty
, "IP: %s\n",
196 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
197 vty_out(vty
, " MAC: %s",
198 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
200 json_object_string_add(json
, "ip", buf2
);
201 json_object_string_add(json
, "mac", buf1
);
203 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
205 vty_out(vty
, " Remote VTEP: %s",
206 inet_ntoa(n
->r_vtep_ip
));
207 vty_out(vty
, " State: %s", IS_ZEBRA_NEIGH_ACTIVE(n
)
211 json_object_string_add(json
, "remoteVtep",
212 inet_ntoa(n
->r_vtep_ip
));
219 * Print neighbor hash entry - called for display of all neighbors.
221 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
224 json_object
*json_vni
= NULL
, *json_row
= NULL
;
226 char buf1
[ETHER_ADDR_STRLEN
];
227 char buf2
[INET6_ADDRSTRLEN
];
228 struct neigh_walk_ctx
*wctx
= ctxt
;
231 json_vni
= wctx
->json
;
232 n
= (zebra_neigh_t
*)backet
->data
;
237 json_row
= json_object_new_object();
239 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
240 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
241 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
242 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
243 if (json_vni
== NULL
) {
244 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
245 buf2
, "local", buf1
);
247 json_object_string_add(json_row
, "type", "local");
248 json_object_string_add(json_row
, "mac", buf1
);
252 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
253 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
254 if (json_vni
== NULL
) {
255 if (wctx
->count
== 0)
257 "%*s %-6s %-17s %-21s\n",
260 "MAC", "Remote VTEP");
261 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
262 -wctx
->addr_width
, buf2
,
264 inet_ntoa(n
->r_vtep_ip
));
266 json_object_string_add(json_row
, "type",
268 json_object_string_add(json_row
, "mac",
270 json_object_string_add(
271 json_row
, "remoteVtep",
272 inet_ntoa(n
->r_vtep_ip
));
277 if (json_vni
== NULL
) {
278 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
279 -wctx
->addr_width
, buf2
, "remote", buf1
,
280 inet_ntoa(n
->r_vtep_ip
));
282 json_object_string_add(json_row
, "type",
284 json_object_string_add(json_row
, "mac", buf1
);
285 json_object_string_add(json_row
, "remoteVtep",
286 inet_ntoa(n
->r_vtep_ip
));
293 json_object_object_add(json_vni
, buf2
, json_row
);
297 * Print neighbors for all VNI.
299 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
303 json_object
*json
= NULL
, *json_vni
= NULL
;
306 struct neigh_walk_ctx wctx
;
307 char vni_str
[VNI_STR_LEN
];
309 vty
= (struct vty
*)args
[0];
310 json
= (json_object
*)args
[1];
312 zvni
= (zebra_vni_t
*)backet
->data
;
315 vty_out(vty
, "{}\n");
318 num_neigh
= hashcount(zvni
->neigh_table
);
321 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
322 zvni
->vni
, num_neigh
);
324 json_vni
= json_object_new_object();
325 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
326 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
330 json_object_object_add(json
, vni_str
, json_vni
);
334 /* Since we have IPv6 addresses to deal with which can vary widely in
335 * size, we try to be a bit more elegant in display by first computing
338 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
341 wctx
.addr_width
= 15;
342 wctx
.json
= json_vni
;
343 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
346 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
347 "Type", "MAC", "Remote VTEP");
348 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
351 json_object_object_add(json
, vni_str
, json_vni
);
355 * Print a specific MAC entry.
357 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
360 zebra_neigh_t
*n
= NULL
;
361 struct listnode
*node
= NULL
;
363 char buf2
[INET6_ADDRSTRLEN
];
365 vty
= (struct vty
*)ctxt
;
366 vty_out(vty
, "MAC: %s",
367 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
368 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
369 struct zebra_ns
*zns
;
370 struct interface
*ifp
;
373 ifindex
= mac
->fwd_info
.local
.ifindex
;
374 zns
= zebra_ns_lookup(NS_DEFAULT
);
375 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
376 if (!ifp
) // unexpected
378 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
379 if (mac
->fwd_info
.local
.vid
)
380 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
381 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
382 vty_out(vty
, " Remote VTEP: %s",
383 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
384 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
385 vty_out(vty
, " Auto Mac ");
387 vty_out(vty
, " ARP ref: %u\n", mac
->neigh_refcnt
);
389 /* print all the associated neigh */
390 vty_out(vty
, " Neighbors:\n");
391 if (!listcount(mac
->neigh_list
))
392 vty_out(vty
, " No Neighbors\n");
394 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
395 vty_out(vty
, " %s %s\n",
396 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
397 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
398 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
409 * Print MAC hash entry - called for display of all MACs.
411 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
414 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
417 struct mac_walk_ctx
*wctx
= ctxt
;
420 json_mac_hdr
= wctx
->json
;
421 mac
= (zebra_mac_t
*)backet
->data
;
425 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
428 json_mac
= json_object_new_object();
430 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
431 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
432 struct zebra_ns
*zns
;
434 struct interface
*ifp
;
437 zns
= zebra_ns_lookup(NS_DEFAULT
);
438 ifindex
= mac
->fwd_info
.local
.ifindex
;
439 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
440 if (!ifp
) // unexpected
442 vid
= mac
->fwd_info
.local
.vid
;
443 if (json_mac_hdr
== NULL
)
444 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
447 json_object_string_add(json_mac
, "type", "local");
448 json_object_string_add(json_mac
, "intf", ifp
->name
);
451 if (json_mac_hdr
== NULL
)
452 vty_out(vty
, " %-5u", vid
);
454 json_object_int_add(json_mac
, "vlan", vid
);
456 if (json_mac_hdr
== NULL
)
459 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
461 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
462 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
463 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
465 if (wctx
->count
== 0) {
466 if (json_mac_hdr
== NULL
) {
467 vty_out(vty
, "\nVNI %u\n\n",
470 "%-17s %-6s %-21s %-5s\n",
476 if (json_mac_hdr
== NULL
)
477 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
479 inet_ntoa(mac
->fwd_info
482 json_object_string_add(json_mac
, "type",
484 json_object_string_add(
485 json_mac
, "remoteVtep",
486 inet_ntoa(mac
->fwd_info
488 json_object_object_add(json_mac_hdr
,
494 if (json_mac_hdr
== NULL
)
495 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
497 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
499 json_object_string_add(json_mac
, "type",
501 json_object_string_add(
502 json_mac
, "remoteVtep",
503 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
504 json_object_object_add(json_mac_hdr
, buf1
,
513 * Print MACs for all VNI.
515 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
518 json_object
*json
= NULL
, *json_vni
= NULL
;
519 json_object
*json_mac
= NULL
;
522 struct mac_walk_ctx
*wctx
= ctxt
;
523 char vni_str
[VNI_STR_LEN
];
525 vty
= (struct vty
*)wctx
->vty
;
526 json
= (struct json_object
*)wctx
->json
;
528 zvni
= (zebra_vni_t
*)backet
->data
;
531 vty_out(vty
, "{}\n");
536 /*We are iterating over a new VNI, set the count to 0*/
539 num_macs
= hashcount(zvni
->mac_table
);
544 json_vni
= json_object_new_object();
545 json_mac
= json_object_new_object();
546 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
549 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
551 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
552 zvni
->vni
, num_macs
);
553 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
554 "Intf/Remote VTEP", "VLAN");
556 json_object_int_add(json_vni
, "numMacs", num_macs
);
558 /* assign per-vni to wctx->json object to fill macs
559 * under the vni. Re-assign primary json object to fill
560 * next vni information.
562 wctx
->json
= json_mac
;
563 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
567 json_object_object_add(json_vni
, "macs", json_mac
);
568 json_object_object_add(json
, vni_str
, json_vni
);
573 * Print a specific VNI entry.
575 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
581 json_object
*json
= NULL
;
582 json_object
*json_vtep_list
= NULL
;
583 json_object
*json_ip_str
= NULL
;
589 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
591 json_object_int_add(json
, "vni", zvni
->vni
);
593 if (!zvni
->vxlan_if
) { // unexpected
595 vty_out(vty
, " VxLAN interface: unknown\n");
598 num_macs
= hashcount(zvni
->mac_table
);
599 num_neigh
= hashcount(zvni
->neigh_table
);
601 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
602 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
603 inet_ntoa(zvni
->local_vtep_ip
));
605 json_object_string_add(json
, "vxlanInterface",
606 zvni
->vxlan_if
->name
);
607 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
608 json_object_string_add(json
, "vtepIp",
609 inet_ntoa(zvni
->local_vtep_ip
));
610 json_object_string_add(json
, "advertiseGatewayMacip",
611 zvni
->advertise_gw_macip
? "Yes" : "No");
612 json_object_int_add(json
, "numMacs", num_macs
);
613 json_object_int_add(json
, "numArpNd", num_neigh
);
617 vty_out(vty
, " No remote VTEPs known for this VNI\n");
620 vty_out(vty
, " Remote VTEPs for this VNI:\n");
622 json_vtep_list
= json_object_new_array();
623 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
625 vty_out(vty
, " %s\n",
626 inet_ntoa(zvtep
->vtep_ip
));
628 json_ip_str
= json_object_new_string(
629 inet_ntoa(zvtep
->vtep_ip
));
630 json_object_array_add(json_vtep_list
,
635 json_object_object_add(json
, "numRemoteVteps",
640 " Number of MACs (local and remote) known for this VNI: %u\n",
643 " Number of ARPs (IPv4 and IPv6, local and remote) "
644 "known for this VNI: %u\n",
646 vty_out(vty
, " Advertise-gw-macip: %s\n",
647 zvni
->advertise_gw_macip
? "Yes" : "No");
652 * Print a VNI hash entry - called for display of all VNIs.
654 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
659 u_int32_t num_vteps
= 0;
660 u_int32_t num_macs
= 0;
661 u_int32_t num_neigh
= 0;
662 json_object
*json
= NULL
;
663 json_object
*json_vni
= NULL
;
664 json_object
*json_ip_str
= NULL
;
665 json_object
*json_vtep_list
= NULL
;
670 zvni
= (zebra_vni_t
*)backet
->data
;
680 num_macs
= hashcount(zvni
->mac_table
);
681 num_neigh
= hashcount(zvni
->neigh_table
);
683 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni
->vni
,
684 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
685 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
688 char vni_str
[VNI_STR_LEN
];
689 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
690 json_vni
= json_object_new_object();
691 json_object_string_add(json_vni
, "vxlanIf",
692 zvni
->vxlan_if
? zvni
->vxlan_if
->name
694 json_object_string_add(json_vni
, "vtepIp",
695 inet_ntoa(zvni
->local_vtep_ip
));
696 json_object_int_add(json_vni
, "numMacs", num_macs
);
697 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
698 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
700 json_vtep_list
= json_object_new_array();
701 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
702 json_ip_str
= json_object_new_string(
703 inet_ntoa(zvtep
->vtep_ip
));
704 json_object_array_add(json_vtep_list
,
707 json_object_object_add(json_vni
, "remoteVteps",
710 json_object_object_add(json
, vni_str
, json_vni
);
715 * Inform BGP about local MACIP.
717 static int zvni_macip_send_msg_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
718 struct ethaddr
*macaddr
,
719 struct ipaddr
*ip
, u_char flags
,
722 struct zserv
*client
;
725 char buf
[ETHER_ADDR_STRLEN
];
726 char buf2
[INET6_ADDRSTRLEN
];
728 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
729 /* BGP may not be running. */
736 zserv_create_header(s
, cmd
, zvrf_id(zvrf
));
738 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
741 if (IS_IPADDR_V4(ip
))
742 ipa_len
= IPV4_MAX_BYTELEN
;
743 else if (IS_IPADDR_V6(ip
))
744 ipa_len
= IPV6_MAX_BYTELEN
;
746 stream_putl(s
, ipa_len
); /* IP address length */
748 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
750 stream_putl(s
, 0); /* Just MAC. */
752 stream_putc(s
, flags
); /* sticky mac/gateway mac */
754 /* Write packet size. */
755 stream_putw_at(s
, 0, stream_get_endp(s
));
757 if (IS_ZEBRA_DEBUG_VXLAN
)
759 "%u:Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s",
760 zvrf_id(zvrf
), (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
761 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
762 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
763 zebra_route_string(client
->proto
));
765 if (cmd
== ZEBRA_MACIP_ADD
)
766 client
->macipadd_cnt
++;
768 client
->macipdel_cnt
++;
770 return zebra_server_send_message(client
);
774 * Make hash key for neighbors.
776 static unsigned int neigh_hash_keymake(void *p
)
778 zebra_neigh_t
*n
= p
;
779 struct ipaddr
*ip
= &n
->ip
;
781 if (IS_IPADDR_V4(ip
))
782 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
784 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
785 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
789 * Compare two neighbor hash structures.
791 static int neigh_cmp(const void *p1
, const void *p2
)
793 const zebra_neigh_t
*n1
= p1
;
794 const zebra_neigh_t
*n2
= p2
;
796 if (n1
== NULL
&& n2
== NULL
)
799 if (n1
== NULL
|| n2
== NULL
)
802 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
806 * Callback to allocate neighbor hash entry.
808 static void *zvni_neigh_alloc(void *p
)
810 const zebra_neigh_t
*tmp_n
= p
;
813 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
820 * Add neighbor entry.
822 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
826 zebra_neigh_t
*n
= NULL
;
827 zebra_mac_t
*zmac
= NULL
;
829 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
830 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
831 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
834 memcpy(&n
->emac
, mac
, ETH_ALEN
);
835 n
->state
= ZEBRA_NEIGH_INACTIVE
;
837 /* Associate the neigh to mac */
838 zmac
= zvni_mac_lookup(zvni
, mac
);
840 listnode_add_sort(zmac
->neigh_list
, n
);
846 * Delete neighbor entry.
848 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
850 zebra_neigh_t
*tmp_n
;
851 zebra_mac_t
*zmac
= NULL
;
853 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
855 listnode_delete(zmac
->neigh_list
, n
);
857 /* Free the VNI hash entry and allocated memory. */
858 tmp_n
= hash_release(zvni
->neigh_table
, n
);
860 XFREE(MTYPE_NEIGH
, tmp_n
);
866 * Free neighbor hash entry (callback)
868 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
870 struct neigh_walk_ctx
*wctx
= arg
;
871 zebra_neigh_t
*n
= backet
->data
;
873 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
874 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
875 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
876 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
877 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
878 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
879 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
880 zvni_neigh_send_del_to_client(wctx
->zvrf
,
881 wctx
->zvni
->vni
, &n
->ip
,
885 zvni_neigh_uninstall(wctx
->zvni
, n
);
887 return zvni_neigh_del(wctx
->zvni
, n
);
894 * Delete all neighbor entries from specific VTEP for a particular VNI.
896 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
897 struct in_addr
*r_vtep_ip
)
899 struct neigh_walk_ctx wctx
;
901 if (!zvni
->neigh_table
)
904 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
906 wctx
.uninstall
= uninstall
;
907 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
908 wctx
.r_vtep_ip
= *r_vtep_ip
;
910 hash_iterate(zvni
->neigh_table
,
911 (void (*)(struct hash_backet
*,
912 void *))zvni_neigh_del_hash_entry
,
917 * Delete all neighbor entries for this VNI.
919 static void zvni_neigh_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
920 int uninstall
, int upd_client
, u_int32_t flags
)
922 struct neigh_walk_ctx wctx
;
924 if (!zvni
->neigh_table
)
927 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
930 wctx
.uninstall
= uninstall
;
931 wctx
.upd_client
= upd_client
;
934 hash_iterate(zvni
->neigh_table
,
935 (void (*)(struct hash_backet
*,
936 void *))zvni_neigh_del_hash_entry
,
941 * Look up neighbor hash entry.
943 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
948 memset(&tmp
, 0, sizeof(tmp
));
949 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
950 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
955 /* Process all neigh associated to a mac upon local mac add event */
956 static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf
*zvrf
,
960 zebra_neigh_t
*n
= NULL
;
961 struct listnode
*node
= NULL
;
962 char buf
[ETHER_ADDR_STRLEN
];
963 char buf2
[INET6_ADDRSTRLEN
];
965 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
966 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
967 /* MAC is learnt locally, program all inactive neigh
968 * pointing to this mac */
969 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
970 if (IS_ZEBRA_DEBUG_VXLAN
)
972 "%u: neigh %s (MAC %s) on VNI %u is now ACTIVE",
974 ipaddr2str(&n
->ip
, buf2
,
976 prefix_mac2str(&n
->emac
, buf
,
980 ZEBRA_NEIGH_SET_ACTIVE(n
);
981 zvni_neigh_send_add_to_client(
982 zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
, 0);
984 if (IS_ZEBRA_DEBUG_VXLAN
)
986 "%u: neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
988 ipaddr2str(&n
->ip
, buf2
,
990 prefix_mac2str(&n
->emac
, buf
,
994 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
995 /* TODO: assume the neigh has moved too ?? */
1000 /* Process all neigh associated to a mac upon local mac del event */
1001 static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf
*zvrf
,
1005 zebra_neigh_t
*n
= NULL
;
1006 struct listnode
*node
= NULL
;
1007 char buf
[ETHER_ADDR_STRLEN
];
1008 char buf2
[INET6_ADDRSTRLEN
];
1010 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1011 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1012 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1013 if (IS_ZEBRA_DEBUG_VXLAN
)
1015 "%u: neigh %s (MAC %s) on VNI %u is now INACTIVE",
1017 ipaddr2str(&n
->ip
, buf2
,
1019 prefix_mac2str(&n
->emac
, buf
,
1023 ZEBRA_NEIGH_SET_INACTIVE(n
);
1024 zvni_neigh_send_del_to_client(
1025 zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1027 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1028 if (IS_ZEBRA_DEBUG_VXLAN
)
1030 "%u: local MAC %s getting deleted on VNI %u has remote neigh %s",
1032 prefix_mac2str(&n
->emac
, buf
,
1035 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1040 /* process all neigh associated to a mac entry upon remote mac add */
1041 static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf
*zvrf
,
1045 zebra_neigh_t
*n
= NULL
;
1046 struct listnode
*node
= NULL
;
1047 char buf
[ETHER_ADDR_STRLEN
];
1048 char buf2
[INET6_ADDRSTRLEN
];
1050 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1051 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1052 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1053 if (IS_ZEBRA_DEBUG_VXLAN
)
1055 "%u: neigh %s (MAC %s) on VNI %u INACTIVE",
1057 ipaddr2str(&n
->ip
, buf2
,
1059 prefix_mac2str(&n
->emac
, buf
,
1063 ZEBRA_NEIGH_SET_INACTIVE(n
);
1064 zvni_neigh_send_del_to_client(
1065 zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1071 /* process all neigh associated to mac entry upon remote mac del */
1072 static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf
*zvrf
,
1076 zebra_neigh_t
*n
= NULL
;
1077 struct listnode
*node
= NULL
;
1078 char buf
[ETHER_ADDR_STRLEN
];
1079 char buf2
[INET6_ADDRSTRLEN
];
1081 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1082 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1083 if (IS_ZEBRA_DEBUG_VXLAN
)
1085 "%u: remote MAC %s getting deleted on VNI %u has local neigh %s",
1087 prefix_mac2str(&n
->emac
, buf
,
1090 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1096 * Inform BGP about local neighbor addition.
1098 static int zvni_neigh_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
1100 struct ethaddr
*macaddr
, u_char flags
)
1102 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, ip
, flags
,
1107 * Inform BGP about local neighbor deletion.
1109 static int zvni_neigh_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
1111 struct ethaddr
*macaddr
, u_char flags
)
1113 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, ip
, flags
,
1118 * Install remote neighbor into the kernel.
1120 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1122 struct zebra_vrf
*zvrf
;
1123 struct zebra_if
*zif
;
1124 struct zebra_l2info_vxlan
*vxl
;
1125 struct interface
*vlan_if
;
1127 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1130 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1132 zif
= zvni
->vxlan_if
->info
;
1135 vxl
= &zif
->l2info
.vxl
;
1137 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
1138 zif
->brslave_info
.br_if
);
1142 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1146 * Uninstall remote neighbor from the kernel.
1148 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1150 struct zebra_vrf
*zvrf
;
1151 struct zebra_if
*zif
;
1152 struct zebra_l2info_vxlan
*vxl
;
1153 struct interface
*vlan_if
;
1155 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1158 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1160 if (!zvni
->vxlan_if
) {
1161 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1166 zif
= zvni
->vxlan_if
->info
;
1169 vxl
= &zif
->l2info
.vxl
;
1170 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
1171 zif
->brslave_info
.br_if
);
1175 return kernel_del_neigh(vlan_if
, &n
->ip
);
1179 * Install neighbor hash entry - called upon access VLAN change.
1181 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1184 struct neigh_walk_ctx
*wctx
= ctxt
;
1186 n
= (zebra_neigh_t
*)backet
->data
;
1190 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1191 zvni_neigh_install(wctx
->zvni
, n
);
1194 /* Get the VRR interface for SVI if any */
1195 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1197 struct zebra_vrf
*zvrf
= NULL
;
1198 struct interface
*tmp_if
= NULL
;
1199 struct zebra_if
*zif
= NULL
;
1200 struct listnode
*node
;
1202 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1205 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1210 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1213 if (zif
->link
== ifp
)
1220 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1222 struct zebra_vrf
*zvrf
= NULL
;
1223 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1224 struct connected
*c
= NULL
;
1225 struct ethaddr macaddr
;
1227 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1231 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1233 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1236 memset(&ip
, 0, sizeof(struct ipaddr
));
1237 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1240 if (c
->address
->family
== AF_INET
) {
1241 ip
.ipa_type
= IPADDR_V4
;
1242 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1243 sizeof(struct in_addr
));
1244 } else if (c
->address
->family
== AF_INET6
) {
1245 ip
.ipa_type
= IPADDR_V6
;
1246 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1247 sizeof(struct in6_addr
));
1252 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1258 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1260 struct zebra_vrf
*zvrf
= NULL
;
1261 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1262 struct connected
*c
= NULL
;
1263 struct ethaddr macaddr
;
1265 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1269 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1271 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1274 memset(&ip
, 0, sizeof(struct ipaddr
));
1275 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1278 if (c
->address
->family
== AF_INET
) {
1279 ip
.ipa_type
= IPADDR_V4
;
1280 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1281 sizeof(struct in_addr
));
1282 } else if (c
->address
->family
== AF_INET6
) {
1283 ip
.ipa_type
= IPADDR_V6
;
1284 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1285 sizeof(struct in6_addr
));
1290 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1297 * zvni_gw_macip_add_to_client
1299 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1300 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1302 struct zebra_vrf
*zvrf
= NULL
;
1303 struct zebra_if
*zif
= NULL
;
1304 struct zebra_l2info_vxlan
*vxl
= NULL
;
1305 zebra_neigh_t
*n
= NULL
;
1306 zebra_mac_t
*mac
= NULL
;
1307 char buf
[ETHER_ADDR_STRLEN
];
1308 char buf2
[INET6_ADDRSTRLEN
];
1310 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1314 zif
= zvni
->vxlan_if
->info
;
1318 vxl
= &zif
->l2info
.vxl
;
1320 mac
= zvni_mac_lookup(zvni
, macaddr
);
1322 mac
= zvni_mac_add(zvni
, macaddr
);
1324 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
1326 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1327 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1332 /* Set "local" forwarding info. */
1333 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1334 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1335 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1336 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1337 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1339 n
= zvni_neigh_lookup(zvni
, ip
);
1341 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1344 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1345 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1346 prefix_mac2str(macaddr
, NULL
,
1348 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1353 /* Set "local" forwarding info. */
1354 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1355 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1356 n
->ifindex
= ifp
->ifindex
;
1358 /* We have a neigh associated to mac increment the refcnt*/
1359 mac
->neigh_refcnt
++;
1361 if (IS_ZEBRA_DEBUG_VXLAN
)
1363 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
1364 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1365 prefix_mac2str(macaddr
, NULL
, ETHER_ADDR_STRLEN
),
1366 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1368 zvni_neigh_send_add_to_client(zvrf
, zvni
->vni
, ip
, macaddr
,
1375 * zvni_gw_macip_del_from_client
1377 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1380 struct zebra_vrf
*zvrf
= NULL
;
1381 zebra_neigh_t
*n
= NULL
;
1382 zebra_mac_t
*mac
= NULL
;
1383 char buf2
[INET6_ADDRSTRLEN
];
1385 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1389 /* If the neigh entry is not present nothing to do*/
1390 n
= zvni_neigh_lookup(zvni
, ip
);
1394 /* mac entry should be present */
1395 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1397 zlog_err("%u: MAC %s doesnt exsists for neigh %s on VNI %u",
1399 prefix_mac2str(&n
->emac
, NULL
, ETHER_ADDR_STRLEN
),
1400 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1402 /* If the entry is not local nothing to do*/
1403 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1406 if (IS_ZEBRA_DEBUG_VXLAN
)
1408 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1409 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1410 prefix_mac2str(&(n
->emac
), NULL
, ETHER_ADDR_STRLEN
),
1411 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1413 /* Remove neighbor from BGP. */
1414 zvni_neigh_send_del_to_client(zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
,
1417 /* Delete this neighbor entry. */
1418 zvni_neigh_del(zvni
, n
);
1420 /* see if the mac needs to be deleted as well*/
1421 zvni_deref_ip2mac(zvni
, mac
, 0);
1426 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1429 zebra_vni_t
*zvni
= NULL
;
1430 struct zebra_if
*zif
= NULL
;
1431 struct zebra_l2info_vxlan zl2_info
;
1432 struct interface
*vlan_if
= NULL
;
1433 struct interface
*vrr_if
= NULL
;
1435 /* Add primary SVI MAC*/
1436 zvni
= (zebra_vni_t
*)backet
->data
;
1440 zif
= zvni
->vxlan_if
->info
;
1441 zl2_info
= zif
->l2info
.vxl
;
1443 vlan_if
= zvni_map_to_svi(zvrf
, zl2_info
.access_vlan
,
1444 zif
->brslave_info
.br_if
);
1448 /* Del primary MAC-IP */
1449 zvni_del_macip_for_intf(vlan_if
, zvni
);
1451 /* Del VRR MAC-IP - if any*/
1452 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1454 zvni_del_macip_for_intf(vrr_if
, zvni
);
1459 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1462 zebra_vni_t
*zvni
= NULL
;
1463 struct zebra_if
*zif
= NULL
;
1464 struct zebra_l2info_vxlan zl2_info
;
1465 struct interface
*vlan_if
= NULL
;
1466 struct interface
*vrr_if
= NULL
;
1468 zvni
= (zebra_vni_t
*)backet
->data
;
1472 if (!advertise_gw_macip_enabled(zvrf
, zvni
))
1475 zif
= zvni
->vxlan_if
->info
;
1476 zl2_info
= zif
->l2info
.vxl
;
1478 vlan_if
= zvni_map_to_svi(zvrf
, zl2_info
.access_vlan
,
1479 zif
->brslave_info
.br_if
);
1483 if (!advertise_gw_macip_enabled(zvrf
, zvni
))
1486 /* Add primary SVI MAC-IP */
1487 zvni_add_macip_for_intf(vlan_if
, zvni
);
1489 /* Add VRR MAC-IP - if any*/
1490 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1492 zvni_add_macip_for_intf(vrr_if
, zvni
);
1498 * Make hash key for MAC.
1500 static unsigned int mac_hash_keymake(void *p
)
1502 zebra_mac_t
*pmac
= p
;
1503 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1505 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1509 * Compare two MAC addresses.
1511 static int mac_cmp(const void *p1
, const void *p2
)
1513 const zebra_mac_t
*pmac1
= p1
;
1514 const zebra_mac_t
*pmac2
= p2
;
1516 if (pmac1
== NULL
&& pmac2
== NULL
)
1519 if (pmac1
== NULL
|| pmac2
== NULL
)
1522 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1528 * Callback to allocate MAC hash entry.
1530 static void *zvni_mac_alloc(void *p
)
1532 const zebra_mac_t
*tmp_mac
= p
;
1535 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1538 return ((void *)mac
);
1544 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1546 zebra_mac_t tmp_mac
;
1547 zebra_mac_t
*mac
= NULL
;
1549 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1550 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1551 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1554 mac
->neigh_list
= list_new();
1555 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1563 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1565 zebra_mac_t
*tmp_mac
;
1567 list_delete(mac
->neigh_list
);
1569 /* Free the VNI hash entry and allocated memory. */
1570 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1572 XFREE(MTYPE_MAC
, tmp_mac
);
1578 * Free MAC hash entry (callback)
1580 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1582 struct mac_walk_ctx
*wctx
= arg
;
1583 zebra_mac_t
*mac
= backet
->data
;
1586 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1587 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1588 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1589 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1590 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1591 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1592 &wctx
->r_vtep_ip
))) {
1593 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1594 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
1596 zvni_mac_send_del_to_client(
1597 wctx
->zvrf
, wctx
->zvni
->vni
, &mac
->macaddr
,
1598 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
1601 if (wctx
->uninstall
)
1602 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
1604 return zvni_mac_del(wctx
->zvni
, mac
);
1611 * Delete all MAC entries from specific VTEP for a particular VNI.
1613 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1614 struct in_addr
*r_vtep_ip
)
1616 struct mac_walk_ctx wctx
;
1618 if (!zvni
->mac_table
)
1621 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1623 wctx
.uninstall
= uninstall
;
1624 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
1625 wctx
.r_vtep_ip
= *r_vtep_ip
;
1627 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1628 void *))zvni_mac_del_hash_entry
,
1633 * Delete all MAC entries for this VNI.
1635 static void zvni_mac_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
1636 int uninstall
, int upd_client
, u_int32_t flags
)
1638 struct mac_walk_ctx wctx
;
1640 if (!zvni
->mac_table
)
1643 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1646 wctx
.uninstall
= uninstall
;
1647 wctx
.upd_client
= upd_client
;
1650 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1651 void *))zvni_mac_del_hash_entry
,
1656 * Look up MAC hash entry.
1658 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
1663 memset(&tmp
, 0, sizeof(tmp
));
1664 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
1665 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
1671 * Inform BGP about local MAC addition.
1673 static int zvni_mac_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
1674 struct ethaddr
*macaddr
, u_char flags
)
1676 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, NULL
, flags
,
1681 * Inform BGP about local MAC deletion.
1683 static int zvni_mac_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
1684 struct ethaddr
*macaddr
, u_char flags
)
1686 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, NULL
, flags
,
1691 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1692 * notifications, to see if there are of interest.
1693 * TODO: Need to make this as a hash table.
1695 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
1696 struct interface
*br_if
, vlanid_t vid
)
1698 struct zebra_vrf
*zvrf
;
1699 struct listnode
*node
;
1700 struct interface
*tmp_if
;
1701 struct zebra_if
*zif
;
1702 struct zebra_l2info_bridge
*br
;
1703 struct zebra_l2info_vxlan
*vxl
;
1704 u_char bridge_vlan_aware
;
1707 /* Locate VRF corresponding to interface. */
1708 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1711 /* Determine if bridge is VLAN-aware or not */
1714 br
= &zif
->l2info
.br
;
1715 bridge_vlan_aware
= br
->vlan_aware
;
1717 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1718 /* TODO: Optimize with a hash. */
1719 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1721 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1723 if (!if_is_operative(tmp_if
))
1725 vxl
= &zif
->l2info
.vxl
;
1727 if (zif
->brslave_info
.br_if
!= br_if
)
1730 if (!bridge_vlan_aware
)
1733 if (vxl
->access_vlan
== vid
)
1740 zvni
= zvni_lookup(zvrf
, vxl
->vni
);
1745 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1746 * neighbor notifications, to see if they are of interest.
1747 * TODO: Need to make this as a hash table.
1749 static zebra_vni_t
*zvni_map_svi(struct interface
*ifp
, struct interface
*br_if
)
1751 struct zebra_vrf
*zvrf
;
1752 struct listnode
*node
;
1753 struct interface
*tmp_if
;
1754 struct zebra_if
*zif
;
1755 struct zebra_l2info_bridge
*br
;
1756 struct zebra_l2info_vxlan
*vxl
;
1757 u_char bridge_vlan_aware
;
1761 /* Make sure the linked interface is a bridge. */
1762 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
1765 /* Locate VRF corresponding to interface. */
1766 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1769 /* Determine if bridge is VLAN-aware or not */
1772 br
= &zif
->l2info
.br
;
1773 bridge_vlan_aware
= br
->vlan_aware
;
1774 if (bridge_vlan_aware
) {
1775 struct zebra_l2info_vlan
*vl
;
1777 if (!IS_ZEBRA_IF_VLAN(ifp
))
1782 vl
= &zif
->l2info
.vl
;
1786 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1787 /* TODO: Optimize with a hash. */
1788 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1790 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1792 if (!if_is_operative(tmp_if
))
1794 vxl
= &zif
->l2info
.vxl
;
1796 if (zif
->brslave_info
.br_if
!= br_if
)
1799 if (!bridge_vlan_aware
)
1802 if (vxl
->access_vlan
== vid
)
1809 zvni
= zvni_lookup(zvrf
, vxl
->vni
);
1813 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
1815 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1816 * linked to the bridge
1817 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1820 static struct interface
*zvni_map_to_svi(struct zebra_vrf
*zvrf
, vlanid_t vid
,
1821 struct interface
*br_if
)
1823 struct listnode
*node
;
1824 struct interface
*tmp_if
;
1825 struct zebra_if
*zif
;
1826 struct zebra_l2info_bridge
*br
;
1827 struct zebra_l2info_vlan
*vl
;
1828 u_char bridge_vlan_aware
;
1830 /* Determine if bridge is VLAN-aware or not */
1833 br
= &zif
->l2info
.br
;
1834 bridge_vlan_aware
= br
->vlan_aware
;
1836 /* Check oper status of the SVI. */
1837 if (!bridge_vlan_aware
)
1838 return if_is_operative(br_if
) ? br_if
: NULL
;
1840 /* Identify corresponding VLAN interface. */
1841 /* TODO: Optimize with a hash. */
1842 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1843 /* Check oper status of the SVI. */
1844 if (!if_is_operative(tmp_if
))
1847 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
1848 || zif
->link
!= br_if
)
1850 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
1860 * Install remote MAC into the kernel.
1862 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1864 struct zebra_if
*zif
;
1865 struct zebra_l2info_vxlan
*vxl
;
1868 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
1871 zif
= zvni
->vxlan_if
->info
;
1874 vxl
= &zif
->l2info
.vxl
;
1876 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
1878 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
1879 mac
->fwd_info
.r_vtep_ip
, sticky
);
1883 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1884 * moves to remote, we have to uninstall any existing local entry first.
1886 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
1888 struct zebra_if
*zif
;
1889 struct zebra_l2info_vxlan
*vxl
;
1890 struct in_addr vtep_ip
= {.s_addr
= 0};
1891 struct zebra_ns
*zns
;
1892 struct interface
*ifp
;
1894 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
1897 if (!zvni
->vxlan_if
) {
1898 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1903 zif
= zvni
->vxlan_if
->info
;
1906 vxl
= &zif
->l2info
.vxl
;
1909 zns
= zebra_ns_lookup(NS_DEFAULT
);
1910 ifp
= if_lookup_by_index_per_ns(zns
,
1911 mac
->fwd_info
.local
.ifindex
);
1912 if (!ifp
) // unexpected
1915 ifp
= zvni
->vxlan_if
;
1916 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
1919 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
1924 * Install MAC hash entry - called upon access VLAN change.
1926 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
1929 struct mac_walk_ctx
*wctx
= ctxt
;
1931 mac
= (zebra_mac_t
*)backet
->data
;
1935 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
1936 zvni_mac_install(wctx
->zvni
, mac
);
1940 * Decrement neighbor refcount of MAC; uninstall and free it if
1943 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
1946 if (mac
->neigh_refcnt
)
1947 mac
->neigh_refcnt
--;
1949 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
) || mac
->neigh_refcnt
> 0)
1953 zvni_mac_uninstall(zvni
, mac
, 0);
1955 zvni_mac_del(zvni
, mac
);
1959 * Read and populate local MACs and neighbors corresponding to this VNI.
1961 static void zvni_read_mac_neigh(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
1962 struct interface
*ifp
)
1964 struct zebra_if
*zif
;
1965 struct interface
*vlan_if
;
1966 struct zebra_l2info_vxlan
*vxl
;
1967 struct interface
*vrr_if
;
1970 vxl
= &zif
->l2info
.vxl
;
1972 if (IS_ZEBRA_DEBUG_VXLAN
)
1974 "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1975 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1976 zif
->brslave_info
.bridge_ifindex
);
1978 macfdb_read_for_bridge(zvrf
->zns
, ifp
, zif
->brslave_info
.br_if
);
1979 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
1980 zif
->brslave_info
.br_if
);
1983 if (advertise_gw_macip_enabled(zvrf
, zvni
)) {
1984 /* Add SVI MAC-IP */
1985 zvni_add_macip_for_intf(vlan_if
, zvni
);
1987 /* Add VRR MAC-IP - if any*/
1988 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1990 zvni_add_macip_for_intf(vrr_if
, zvni
);
1993 neigh_read_for_vlan(zvrf
->zns
, vlan_if
);
1998 * Hash function for VNI.
2000 static unsigned int vni_hash_keymake(void *p
)
2002 const zebra_vni_t
*zvni
= p
;
2004 return (jhash_1word(zvni
->vni
, 0));
2008 * Compare 2 VNI hash entries.
2010 static int vni_hash_cmp(const void *p1
, const void *p2
)
2012 const zebra_vni_t
*zvni1
= p1
;
2013 const zebra_vni_t
*zvni2
= p2
;
2015 return (zvni1
->vni
== zvni2
->vni
);
2019 * Callback to allocate VNI hash entry.
2021 static void *zvni_alloc(void *p
)
2023 const zebra_vni_t
*tmp_vni
= p
;
2026 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2027 zvni
->vni
= tmp_vni
->vni
;
2028 return ((void *)zvni
);
2032 * Look up VNI hash entry.
2034 static zebra_vni_t
*zvni_lookup(struct zebra_vrf
*zvrf
, vni_t vni
)
2036 zebra_vni_t tmp_vni
;
2037 zebra_vni_t
*zvni
= NULL
;
2039 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2041 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2047 * Add VNI hash entry.
2049 static zebra_vni_t
*zvni_add(struct zebra_vrf
*zvrf
, vni_t vni
)
2051 zebra_vni_t tmp_zvni
;
2052 zebra_vni_t
*zvni
= NULL
;
2054 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2056 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2059 /* Create hash table for MAC */
2061 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2063 /* Create hash table for neighbors */
2064 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2065 "Zebra VNI Neighbor Table");
2071 * Delete VNI hash entry.
2073 static int zvni_del(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
)
2075 zebra_vni_t
*tmp_zvni
;
2077 zvni
->vxlan_if
= NULL
;
2079 /* Free the neighbor hash table. */
2080 hash_free(zvni
->neigh_table
);
2081 zvni
->neigh_table
= NULL
;
2083 /* Free the MAC hash table. */
2084 hash_free(zvni
->mac_table
);
2085 zvni
->mac_table
= NULL
;
2087 /* Free the VNI hash entry and allocated memory. */
2088 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2090 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2096 * Inform BGP about local VNI addition.
2098 static int zvni_send_add_to_client(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
)
2100 struct zserv
*client
;
2103 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
2104 /* BGP may not be running. */
2111 zserv_create_header(s
, ZEBRA_VNI_ADD
, zvrf_id(zvrf
));
2112 stream_putl(s
, zvni
->vni
);
2113 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2115 /* Write packet size. */
2116 stream_putw_at(s
, 0, stream_get_endp(s
));
2118 if (IS_ZEBRA_DEBUG_VXLAN
)
2119 zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf
),
2120 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2121 zebra_route_string(client
->proto
));
2123 client
->vniadd_cnt
++;
2124 return zebra_server_send_message(client
);
2128 * Inform BGP about local VNI deletion.
2130 static int zvni_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
)
2132 struct zserv
*client
;
2135 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
2136 /* BGP may not be running. */
2143 zserv_create_header(s
, ZEBRA_VNI_DEL
, zvrf_id(zvrf
));
2144 stream_putl(s
, vni
);
2146 /* Write packet size. */
2147 stream_putw_at(s
, 0, stream_get_endp(s
));
2149 if (IS_ZEBRA_DEBUG_VXLAN
)
2150 zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf
), vni
,
2151 zebra_route_string(client
->proto
));
2153 client
->vnidel_cnt
++;
2154 return zebra_server_send_message(client
);
2158 * Build the VNI hash table by going over the VxLAN interfaces. This
2159 * is called when EVPN (advertise-all-vni) is enabled.
2161 static void zvni_build_hash_table(struct zebra_vrf
*zvrf
)
2163 struct listnode
*node
;
2164 struct interface
*ifp
;
2166 /* Walk VxLAN interfaces and create VNI hash. */
2167 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, ifp
)) {
2168 struct zebra_if
*zif
;
2169 struct zebra_l2info_vxlan
*vxl
;
2174 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2176 vxl
= &zif
->l2info
.vxl
;
2180 if (IS_ZEBRA_DEBUG_VXLAN
)
2182 "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
2183 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
,
2184 inet_ntoa(vxl
->vtep_ip
));
2186 /* VNI hash entry is not expected to exist. */
2187 zvni
= zvni_lookup(zvrf
, vni
);
2190 "VNI hash already present for VRF %d IF %s(%u) VNI %u",
2191 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
);
2195 zvni
= zvni_add(zvrf
, vni
);
2198 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
2199 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
);
2203 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2204 zvni
->vxlan_if
= ifp
;
2206 /* Inform BGP if interface is up and mapped to bridge. */
2207 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2208 zvni_send_add_to_client(zvrf
, zvni
);
2213 * See if remote VTEP matches with prefix.
2215 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2217 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2221 * Locate remote VTEP in VNI hash table.
2223 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2225 zebra_vtep_t
*zvtep
;
2230 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2231 if (zvni_vtep_match(vtep_ip
, zvtep
))
2239 * Add remote VTEP to VNI hash table.
2241 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2243 zebra_vtep_t
*zvtep
;
2245 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2247 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2251 zvtep
->vtep_ip
= *vtep_ip
;
2254 zvni
->vteps
->prev
= zvtep
;
2255 zvtep
->next
= zvni
->vteps
;
2256 zvni
->vteps
= zvtep
;
2262 * Remove remote VTEP from VNI hash table.
2264 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2267 zvtep
->next
->prev
= zvtep
->prev
;
2269 zvtep
->prev
->next
= zvtep
->next
;
2271 zvni
->vteps
= zvtep
->next
;
2273 zvtep
->prev
= zvtep
->next
= NULL
;
2274 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2280 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2281 * uninstall from kernel if asked to.
2283 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2285 zebra_vtep_t
*zvtep
, *zvtep_next
;
2290 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2291 zvtep_next
= zvtep
->next
;
2293 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2294 zvni_vtep_del(zvni
, zvtep
);
2301 * Install remote VTEP into the kernel.
2303 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2305 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2309 * Uninstall remote VTEP from the kernel.
2311 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2313 if (!zvni
->vxlan_if
) {
2314 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2319 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2323 * Cleanup VNI/VTEP and update kernel
2325 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2329 zvni
= (zebra_vni_t
*)backet
->data
;
2333 /* Free up all neighbors and MACs, if any. */
2334 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
2335 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
2337 /* Free up all remote VTEPs, if any. */
2338 zvni_vtep_del_all(zvni
, 1);
2340 /* Delete the hash entry. */
2341 zvni_del(zvrf
, zvni
);
2345 /* Public functions */
2348 * Display Neighbors for a VNI (VTY command handler).
2350 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2351 vni_t vni
, u_char use_json
)
2354 u_int32_t num_neigh
;
2355 struct neigh_walk_ctx wctx
;
2356 json_object
*json
= NULL
;
2358 if (!EVPN_ENABLED(zvrf
))
2360 zvni
= zvni_lookup(zvrf
, vni
);
2363 vty_out(vty
, "{}\n");
2365 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2368 num_neigh
= hashcount(zvni
->neigh_table
);
2373 json
= json_object_new_object();
2375 /* Since we have IPv6 addresses to deal with which can vary widely in
2376 * size, we try to be a bit more elegant in display by first computing
2377 * the maximum width.
2379 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
2382 wctx
.addr_width
= 15;
2384 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
2388 "Number of ARPs (local and remote) known for this VNI: %u\n",
2390 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
2391 "Type", "MAC", "Remote VTEP");
2393 json_object_int_add(json
, "numArpNd", num_neigh
);
2395 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
2397 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2398 json
, JSON_C_TO_STRING_PRETTY
));
2399 json_object_free(json
);
2404 * Display neighbors across all VNIs (VTY command handler).
2406 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2409 json_object
*json
= NULL
;
2412 if (!EVPN_ENABLED(zvrf
))
2416 json
= json_object_new_object();
2420 hash_iterate(zvrf
->vni_table
,
2421 (void (*)(struct hash_backet
*,
2422 void *))zvni_print_neigh_hash_all_vni
,
2425 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2426 json
, JSON_C_TO_STRING_PRETTY
));
2427 json_object_free(json
);
2432 * Display specific neighbor for a VNI, if present (VTY command handler).
2434 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
2435 struct zebra_vrf
*zvrf
, vni_t vni
,
2436 struct ipaddr
*ip
, u_char use_json
)
2440 json_object
*json
= NULL
;
2442 if (!EVPN_ENABLED(zvrf
))
2444 zvni
= zvni_lookup(zvrf
, vni
);
2447 vty_out(vty
, "{}\n");
2449 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2452 n
= zvni_neigh_lookup(zvni
, ip
);
2456 "%% Requested neighbor does not exist in VNI %u\n",
2461 json
= json_object_new_object();
2463 zvni_print_neigh(n
, vty
, json
);
2466 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2467 json
, JSON_C_TO_STRING_PRETTY
));
2468 json_object_free(json
);
2473 * Display neighbors for a VNI from specific VTEP (VTY command handler).
2474 * By definition, these are remote neighbors.
2476 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2477 vni_t vni
, struct in_addr vtep_ip
,
2481 u_int32_t num_neigh
;
2482 struct neigh_walk_ctx wctx
;
2483 json_object
*json
= NULL
;
2485 if (!EVPN_ENABLED(zvrf
))
2487 zvni
= zvni_lookup(zvrf
, vni
);
2490 vty_out(vty
, "{}\n");
2492 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2495 num_neigh
= hashcount(zvni
->neigh_table
);
2499 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
2502 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
2503 wctx
.r_vtep_ip
= vtep_ip
;
2505 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
2508 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2509 json
, JSON_C_TO_STRING_PRETTY
));
2510 json_object_free(json
);
2515 * Display MACs for a VNI (VTY command handler).
2517 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2518 vni_t vni
, u_char use_json
)
2522 struct mac_walk_ctx wctx
;
2523 json_object
*json
= NULL
;
2524 json_object
*json_mac
= NULL
;
2526 if (!EVPN_ENABLED(zvrf
))
2528 zvni
= zvni_lookup(zvrf
, vni
);
2531 vty_out(vty
, "{}\n");
2533 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2536 num_macs
= hashcount(zvni
->mac_table
);
2541 json
= json_object_new_object();
2542 json_mac
= json_object_new_object();
2545 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2548 wctx
.json
= json_mac
;
2552 "Number of MACs (local and remote) known for this VNI: %u\n",
2554 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
2555 "Intf/Remote VTEP", "VLAN");
2557 json_object_int_add(json
, "numMacs", num_macs
);
2559 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
2562 json_object_object_add(json
, "macs", json_mac
);
2563 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2564 json
, JSON_C_TO_STRING_PRETTY
));
2565 json_object_free(json
);
2570 * Display MACs for all VNIs (VTY command handler).
2572 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2575 struct mac_walk_ctx wctx
;
2576 json_object
*json
= NULL
;
2578 if (!EVPN_ENABLED(zvrf
)) {
2580 vty_out(vty
, "{}\n");
2584 json
= json_object_new_object();
2586 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2589 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
2592 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2593 json
, JSON_C_TO_STRING_PRETTY
));
2594 json_object_free(json
);
2599 * Display MACs for all VNIs (VTY command handler).
2601 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
2602 struct zebra_vrf
*zvrf
,
2603 struct in_addr vtep_ip
,
2606 struct mac_walk_ctx wctx
;
2607 json_object
*json
= NULL
;
2609 if (!EVPN_ENABLED(zvrf
))
2613 json
= json_object_new_object();
2615 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2617 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
2618 wctx
.r_vtep_ip
= vtep_ip
;
2620 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
2623 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2624 json
, JSON_C_TO_STRING_PRETTY
));
2625 json_object_free(json
);
2630 * Display specific MAC for a VNI, if present (VTY command handler).
2632 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2633 vni_t vni
, struct ethaddr
*macaddr
)
2638 if (!EVPN_ENABLED(zvrf
))
2640 zvni
= zvni_lookup(zvrf
, vni
);
2642 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2645 mac
= zvni_mac_lookup(zvni
, macaddr
);
2647 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
2652 zvni_print_mac(mac
, vty
);
2656 * Display MACs for a VNI from specific VTEP (VTY command handler).
2658 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2659 vni_t vni
, struct in_addr vtep_ip
,
2664 struct mac_walk_ctx wctx
;
2665 json_object
*json
= NULL
;
2666 json_object
*json_mac
= NULL
;
2668 if (!EVPN_ENABLED(zvrf
))
2670 zvni
= zvni_lookup(zvrf
, vni
);
2673 vty_out(vty
, "{}\n");
2675 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2678 num_macs
= hashcount(zvni
->mac_table
);
2683 json
= json_object_new_object();
2684 json_mac
= json_object_new_object();
2687 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2690 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
2691 wctx
.r_vtep_ip
= vtep_ip
;
2692 wctx
.json
= json_mac
;
2693 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
2696 json_object_int_add(json
, "numMacs", wctx
.count
);
2698 json_object_object_add(json
, "macs", json_mac
);
2699 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2700 json
, JSON_C_TO_STRING_PRETTY
));
2701 json_object_free(json
);
2707 * Display VNI information (VTY command handler).
2709 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
2713 json_object
*json
= NULL
;
2716 if (!EVPN_ENABLED(zvrf
))
2718 zvni
= zvni_lookup(zvrf
, vni
);
2721 vty_out(vty
, "{}\n");
2723 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
2727 json
= json_object_new_object();
2730 zvni_print(zvni
, (void *)args
);
2732 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2733 json
, JSON_C_TO_STRING_PRETTY
));
2734 json_object_free(json
);
2739 * Display VNI hash table (VTY command handler).
2741 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
2745 json_object
*json
= NULL
;
2748 if (!EVPN_ENABLED(zvrf
))
2750 num_vnis
= hashcount(zvrf
->vni_table
);
2753 vty_out(vty
, "{}\n");
2757 json
= json_object_new_object();
2758 json_object_string_add(json
, "advertiseGatewayMacip",
2759 zvrf
->advertise_gw_macip
? "Yes" : "No");
2760 json_object_int_add(json
, "numVnis", num_vnis
);
2762 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
2763 zvrf
->advertise_gw_macip
? "Yes" : "No");
2764 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
2765 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI",
2766 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
2772 hash_iterate(zvrf
->vni_table
,
2773 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
2777 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2778 json
, JSON_C_TO_STRING_PRETTY
));
2779 json_object_free(json
);
2784 * Handle neighbor delete (on a VLAN device / L3 interface) from the
2785 * kernel. This may result in either the neighbor getting deleted from
2786 * our database or being re-added to the kernel (if it is a valid
2789 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
2790 struct interface
*link_if
, struct ipaddr
*ip
)
2794 struct zebra_vrf
*zvrf
;
2795 char buf
[INET6_ADDRSTRLEN
];
2796 char buf2
[ETHER_ADDR_STRLEN
];
2799 /* We are only interested in neighbors on an SVI that resides on top
2800 * of a VxLAN bridge.
2802 zvni
= zvni_map_svi(ifp
, link_if
);
2805 if (!zvni
->vxlan_if
) {
2807 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
2812 if (IS_ZEBRA_DEBUG_VXLAN
)
2813 zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
2814 ifp
->vrf_id
, ipaddr2str(ip
, buf
, sizeof(buf
)),
2815 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2817 /* If entry doesn't exist, nothing to do. */
2818 n
= zvni_neigh_lookup(zvni
, ip
);
2822 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2824 if (IS_ZEBRA_DEBUG_VXLAN
)
2826 "%u: trying to del a neigh %s without a mac %s on VNI %u",
2827 ifp
->vrf_id
, ipaddr2str(ip
, buf
, sizeof(buf
)),
2828 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
2834 /* If it is a remote entry, the kernel has aged this out or someone has
2835 * deleted it, it needs to be re-installed as Quagga is the owner.
2837 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2838 zvni_neigh_install(zvni
, n
);
2842 /* Locate VRF corresponding to interface. */
2843 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
2846 /* Remove neighbor from BGP. */
2847 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2848 zvni_neigh_send_del_to_client(zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
,
2851 /* Delete this neighbor entry. */
2852 zvni_neigh_del(zvni
, n
);
2854 /* see if the AUTO mac needs to be deleted */
2855 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
2856 || !listcount(zmac
->neigh_list
))
2857 zvni_mac_del(zvni
, zmac
);
2863 * Handle neighbor add or update (on a VLAN device / L3 interface)
2866 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
2867 struct interface
*link_if
,
2869 struct ethaddr
*macaddr
, u_int16_t state
,
2874 struct zebra_vrf
*zvrf
;
2876 char buf
[ETHER_ADDR_STRLEN
];
2877 char buf2
[INET6_ADDRSTRLEN
];
2878 int send_upd
= 1, send_del
= 0;
2880 /* We are only interested in neighbors on an SVI that resides on top
2881 * of a VxLAN bridge.
2883 zvni
= zvni_map_svi(ifp
, link_if
);
2887 /* Locate VRF corresponding to interface. */
2888 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
2891 if (IS_ZEBRA_DEBUG_VXLAN
)
2893 "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
2895 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2896 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
2897 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
2900 /* create a dummy MAC if the MAC is not already present */
2901 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2903 if (IS_ZEBRA_DEBUG_VXLAN
)
2905 "%u: AUTO MAC %s created for neigh %s on VNI %u",
2907 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2908 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
2910 zmac
= zvni_mac_add(zvni
, macaddr
);
2912 zlog_warn("%u:Failed to add MAC %s VNI %u",
2914 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2919 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
2920 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
2921 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
2924 /* If same entry already exists, it might be a change or it might be a
2925 * move from remote to local.
2927 n
= zvni_neigh_lookup(zvni
, ip
);
2929 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2930 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2933 if (n
->ifindex
== ifp
->ifindex
)
2934 /* we're not interested in whatever has
2937 /* client doesn't care about a purely local
2941 /* If the MAC has changed, issue a delete first
2943 * different MACIP route.
2946 } else if (ext_learned
)
2947 /* The neighbor is remote and that is the notification we got.
2950 /* TODO: Evaluate if we need to do anything here. */
2953 /* Neighbor has moved from remote to local. */
2955 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2956 n
->r_vtep_ip
.s_addr
= 0;
2959 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2962 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2963 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2964 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2965 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2970 /* Issue delete for older info, if needed. */
2972 zvni_neigh_send_del_to_client(zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
,
2975 /* Set "local" forwarding info. */
2976 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2977 n
->ifindex
= ifp
->ifindex
;
2979 /* Before we program this in BGP, we need to check if MAC is locally
2981 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
2982 if (IS_ZEBRA_DEBUG_VXLAN
)
2984 "%u: Skipping neigh %s add to client as MAC %s is not local on VNI %u",
2985 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2986 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2992 /* Inform BGP if required. */
2994 if (IS_ZEBRA_DEBUG_VXLAN
)
2996 "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
2997 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2998 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3001 ZEBRA_NEIGH_SET_ACTIVE(n
);
3002 return zvni_neigh_send_add_to_client(zvrf
, zvni
->vni
, ip
,
3010 * Handle message from client to delete a remote MACIP for a VNI.
3012 int zebra_vxlan_remote_macip_del(struct zserv
*client
, int sock
, u_short length
,
3013 struct zebra_vrf
*zvrf
)
3017 struct ethaddr macaddr
;
3019 struct in_addr vtep_ip
;
3023 u_short l
= 0, ipa_len
;
3024 char buf
[ETHER_ADDR_STRLEN
];
3025 char buf1
[INET6_ADDRSTRLEN
];
3029 while (l
< length
) {
3030 /* Obtain each remote MACIP and process. */
3031 /* Message contains VNI, followed by MAC followed by IP (if any)
3032 * followed by remote VTEP IP.
3036 memset(&ip
, 0, sizeof(ip
));
3037 vni
= (vni_t
)stream_getl(s
);
3038 stream_get(&macaddr
.octet
, s
, ETH_ALEN
);
3039 ipa_len
= stream_getl(s
);
3041 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
3043 stream_get(&ip
.ip
.addr
, s
, ipa_len
);
3045 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
3046 vtep_ip
.s_addr
= stream_get_ipv4(s
);
3047 l
+= IPV4_MAX_BYTELEN
;
3049 if (IS_ZEBRA_DEBUG_VXLAN
)
3051 "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
3053 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3054 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
3056 zebra_route_string(client
->proto
));
3058 /* Locate VNI hash entry - expected to exist. */
3059 zvni
= zvni_lookup(zvrf
, vni
);
3061 if (IS_ZEBRA_DEBUG_VXLAN
)
3063 "Failed to locate VNI hash upon remote MACIP DEL, "
3065 zvrf_id(zvrf
), vni
);
3068 if (!zvni
->vxlan_if
) {
3070 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
3075 /* The remote VTEP specified is normally expected to exist, but
3077 * possible that the peer may delete the VTEP before deleting
3079 * referring to the VTEP, in which case the handler (see
3081 * would have already deleted the MACs.
3083 if (!zvni_vtep_find(zvni
, &vtep_ip
))
3086 /* If the local VxLAN interface is not up (should be a transient
3087 * event), there's nothing more to do.
3089 if (!if_is_operative(zvni
->vxlan_if
))
3092 mac
= zvni_mac_lookup(zvni
, &macaddr
);
3094 n
= zvni_neigh_lookup(zvni
, &ip
);
3098 "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
3099 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3100 ipaddr2str(&ip
, buf1
, sizeof(buf1
)),
3101 zvrf_id(zvrf
), vni
);
3105 /* If the remote mac or neighbor doesn't exist there is nothing
3107 * to do. Otherwise, uninstall the entry and then remove it.
3112 /* Uninstall remote neighbor or MAC. */
3114 /* When the MAC changes for an IP, it is possible the
3116 * update the new MAC before trying to delete the "old"
3118 * (as these are two different MACIP routes). Do the
3120 * if the MAC matches.
3122 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
3123 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
3126 zvni_neigh_uninstall(zvni
, n
);
3127 zvni_neigh_del(zvni
, n
);
3128 zvni_deref_ip2mac(zvni
, mac
, 1);
3131 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
3132 zvni_process_neigh_on_remote_mac_del(zvrf
, zvni
,
3135 if (!mac
->neigh_refcnt
) {
3136 zvni_mac_uninstall(zvni
, mac
, 0);
3137 zvni_mac_del(zvni
, mac
);
3139 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3148 * Handle message from client to add a remote MACIP for a VNI. This
3149 * could be just the add of a MAC address or the add of a neighbor
3152 int zebra_vxlan_remote_macip_add(struct zserv
*client
, int sock
, u_short length
,
3153 struct zebra_vrf
*zvrf
)
3157 struct ethaddr macaddr
;
3159 struct in_addr vtep_ip
;
3161 zebra_vtep_t
*zvtep
;
3162 zebra_mac_t
*mac
, *old_mac
;
3164 u_short l
= 0, ipa_len
;
3165 int update_mac
= 0, update_neigh
= 0;
3166 char buf
[ETHER_ADDR_STRLEN
];
3167 char buf1
[INET6_ADDRSTRLEN
];
3170 assert(EVPN_ENABLED(zvrf
));
3174 while (l
< length
) {
3175 /* Obtain each remote MACIP and process. */
3176 /* Message contains VNI, followed by MAC followed by IP (if any)
3177 * followed by remote VTEP IP.
3179 update_mac
= update_neigh
= 0;
3182 memset(&ip
, 0, sizeof(ip
));
3183 vni
= (vni_t
)stream_getl(s
);
3184 stream_get(&macaddr
.octet
, s
, ETH_ALEN
);
3185 ipa_len
= stream_getl(s
);
3187 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
3189 stream_get(&ip
.ip
.addr
, s
, ipa_len
);
3191 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
3192 vtep_ip
.s_addr
= stream_get_ipv4(s
);
3193 l
+= IPV4_MAX_BYTELEN
;
3195 /* Get 'sticky' flag. */
3196 sticky
= stream_getc(s
);
3199 if (IS_ZEBRA_DEBUG_VXLAN
)
3201 "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
3202 zvrf_id(zvrf
), sticky
? "sticky " : "",
3203 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
3204 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
3206 zebra_route_string(client
->proto
));
3208 /* Locate VNI hash entry - expected to exist. */
3209 zvni
= zvni_lookup(zvrf
, vni
);
3212 "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
3213 zvrf_id(zvrf
), vni
);
3216 if (!zvni
->vxlan_if
) {
3218 "VNI %u hash %p doesn't have intf upon remote MACIP add",
3222 /* If the local VxLAN interface is not up (should be a transient
3223 * event), there's nothing more to do.
3225 if (!if_is_operative(zvni
->vxlan_if
))
3228 /* The remote VTEP specified should normally exist, but it is
3230 * that when peering comes up, peer may advertise MACIP routes
3232 * advertising type-3 routes.
3234 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
3236 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
3238 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
3239 zvrf_id(zvrf
), vni
, zvni
);
3243 zvni_vtep_install(zvni
, &vtep_ip
);
3246 /* First, check if the remote MAC is unknown or has a change. If
3248 * that needs to be updated first. Note that client could
3250 * MAC and MACIP separately or just install the latter.
3252 mac
= zvni_mac_lookup(zvni
, &macaddr
);
3253 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
3254 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
3256 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
3261 mac
= zvni_mac_add(zvni
, &macaddr
);
3264 "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
3266 prefix_mac2str(&macaddr
, buf
,
3268 vni
, inet_ntoa(vtep_ip
));
3272 /* Is this MAC created for a MACIP? */
3274 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3275 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
3276 /* Moving from local to remote, issue delete. */
3277 zvni_mac_uninstall(zvni
, mac
, 1);
3280 /* Set "auto" and "remote" forwarding info. */
3281 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3282 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
3283 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
3284 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
3287 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3289 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3291 zvni_process_neigh_on_remote_mac_add(zvrf
, zvni
, mac
);
3293 /* Install the entry. */
3294 zvni_mac_install(zvni
, mac
);
3297 /* If there is no IP, continue - after clearing AUTO flag of
3300 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3304 /* Check if the remote neighbor itself is unknown or has a
3306 * If so, create or update and then install the entry.
3308 n
= zvni_neigh_lookup(zvni
, &ip
);
3309 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
3310 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
3311 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
3316 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
3319 "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
3321 ipaddr2str(&ip
, buf1
,
3323 prefix_mac2str(&macaddr
, buf
,
3325 vni
, inet_ntoa(vtep_ip
));
3329 /* New neighbor referring to this MAC. */
3330 mac
->neigh_refcnt
++;
3331 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
3333 /* MAC change, update ref counts for old and new
3335 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
3337 zvni_deref_ip2mac(zvni
, old_mac
, 1);
3338 mac
->neigh_refcnt
++;
3339 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
3342 /* Set "remote" forwarding info. */
3343 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
3344 /* TODO: Handle MAC change. */
3345 n
->r_vtep_ip
= vtep_ip
;
3346 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3348 /* Install the entry. */
3349 zvni_neigh_install(zvni
, n
);
3357 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
3358 * us, this must involve a multihoming scenario. Treat this as implicit delete
3359 * of any prior local MAC.
3361 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
3362 struct interface
*br_if
,
3363 struct ethaddr
*macaddr
, vlanid_t vid
)
3365 struct zebra_if
*zif
;
3366 struct zebra_vrf
*zvrf
;
3367 struct zebra_l2info_vxlan
*vxl
;
3371 char buf
[ETHER_ADDR_STRLEN
];
3376 vxl
= &zif
->l2info
.vxl
;
3379 /* Locate VRF corresponding to interface. */
3380 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
3383 /* If EVPN is not enabled, nothing to do. */
3384 if (!EVPN_ENABLED(zvrf
))
3387 /* Locate hash entry; it is expected to exist. */
3388 zvni
= zvni_lookup(zvrf
, vni
);
3392 /* If entry doesn't exist, nothing to do. */
3393 mac
= zvni_mac_lookup(zvni
, macaddr
);
3397 /* Is it a local entry? */
3398 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
3401 if (IS_ZEBRA_DEBUG_VXLAN
)
3403 "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
3404 ifp
->vrf_id
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3405 ifp
->name
, ifp
->ifindex
, vni
);
3407 /* Remove MAC from BGP. */
3408 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
3409 zvni_mac_send_del_to_client(zvrf
, zvni
->vni
, macaddr
,
3410 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
3413 * If there are no neigh associated with the mac delete the mac
3414 * else mark it as AUTO for forward reference
3416 if (!listcount(mac
->neigh_list
)) {
3417 zvni_mac_del(zvni
, mac
);
3419 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3420 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3427 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
3428 * This can happen because the remote MAC entries are also added as "dynamic",
3429 * so the kernel can ageout the entry.
3431 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
3432 struct interface
*br_if
,
3433 struct ethaddr
*macaddr
, vlanid_t vid
)
3435 struct zebra_if
*zif
;
3436 struct zebra_vrf
*zvrf
;
3437 struct zebra_l2info_vxlan
*vxl
;
3441 char buf
[ETHER_ADDR_STRLEN
];
3445 vxl
= &zif
->l2info
.vxl
;
3448 /* Locate VRF corresponding to interface. */
3449 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
3452 /* If EVPN is not enabled, nothing to do. */
3453 if (!EVPN_ENABLED(zvrf
))
3456 /* Locate hash entry; it is expected to exist. */
3457 zvni
= zvni_lookup(zvrf
, vni
);
3461 /* If entry doesn't exist, nothing to do. */
3462 mac
= zvni_mac_lookup(zvni
, macaddr
);
3466 /* Is it a remote entry? */
3467 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
3470 if (IS_ZEBRA_DEBUG_VXLAN
)
3471 zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
3473 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3476 zvni_mac_install(zvni
, mac
);
3481 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
3483 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
3484 struct ethaddr
*macaddr
, vlanid_t vid
)
3488 struct zebra_vrf
*zvrf
;
3489 char buf
[ETHER_ADDR_STRLEN
];
3492 /* We are interested in MACs only on ports or (port, VLAN) that
3495 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
3498 if (!zvni
->vxlan_if
) {
3499 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
3504 if (IS_ZEBRA_DEBUG_VXLAN
)
3505 zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
3507 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3508 ifp
->ifindex
, vid
, zvni
->vni
);
3510 /* If entry doesn't exist, nothing to do. */
3511 mac
= zvni_mac_lookup(zvni
, macaddr
);
3515 /* Is it a local entry? */
3516 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
3519 /* Locate VRF corresponding to interface. */
3520 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
3523 /* Remove MAC from BGP. */
3524 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
3525 zvni_mac_send_del_to_client(zvrf
, zvni
->vni
, macaddr
,
3526 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
3528 /* Update all the neigh entries associated with this mac */
3529 zvni_process_neigh_on_local_mac_del(zvrf
, zvni
, mac
);
3532 * If there are no neigh associated with the mac delete the mac
3533 * else mark it as AUTO for forward reference
3535 if (!listcount(mac
->neigh_list
)) {
3536 zvni_mac_del(zvni
, mac
);
3538 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3539 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3546 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
3548 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
3549 struct interface
*br_if
,
3550 struct ethaddr
*macaddr
, vlanid_t vid
,
3555 struct zebra_vrf
*zvrf
;
3556 char buf
[ETHER_ADDR_STRLEN
];
3560 /* We are interested in MACs only on ports or (port, VLAN) that
3563 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
3565 if (IS_ZEBRA_DEBUG_VXLAN
)
3567 "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
3568 ifp
->vrf_id
, sticky
? "sticky " : "",
3569 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3570 ifp
->name
, ifp
->ifindex
, vid
);
3574 if (!zvni
->vxlan_if
) {
3575 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
3580 if (IS_ZEBRA_DEBUG_VXLAN
)
3582 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
3583 ifp
->vrf_id
, sticky
? "sticky " : "",
3584 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
3585 ifp
->ifindex
, vid
, zvni
->vni
);
3587 /* If same entry already exists, nothing to do. */
3588 mac
= zvni_mac_lookup(zvni
, macaddr
);
3590 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
3591 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
3597 * return if nothing has changed.
3598 * inform bgp if sticky flag has changed
3599 * update locally and do not inform bgp if local
3600 * parameters like interface has changed
3602 if (mac_sticky
== sticky
3603 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
3604 && mac
->fwd_info
.local
.vid
== vid
) {
3605 if (IS_ZEBRA_DEBUG_VXLAN
)
3607 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
3608 "entry exists and has not changed ",
3610 sticky
? "sticky " : "",
3611 prefix_mac2str(macaddr
, buf
,
3613 ifp
->name
, ifp
->ifindex
, vid
,
3616 } else if (mac_sticky
!= sticky
) {
3619 add
= 0; /* This is an update of local
3622 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
3624 * If we have already learned the MAC as a remote sticky
3626 * this is a operator error and we must log a warning
3628 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
3630 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
3631 prefix_mac2str(macaddr
, buf
,
3633 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
3640 /* Locate VRF corresponding to interface. */
3641 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
3645 mac
= zvni_mac_add(zvni
, macaddr
);
3647 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
3649 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
3650 ifp
->name
, ifp
->ifindex
, vid
);
3655 /* Set "local" forwarding info. */
3656 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
3657 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
3658 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
3659 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
3660 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
3661 mac
->fwd_info
.local
.vid
= vid
;
3664 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3666 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
3668 /* Inform BGP if required. */
3670 zvni_process_neigh_on_local_mac_add(zvrf
, zvni
, mac
);
3671 return zvni_mac_send_add_to_client(zvrf
, zvni
->vni
, macaddr
,
3679 * Handle message from client to delete a remote VTEP for a VNI.
3681 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, int sock
, u_short length
,
3682 struct zebra_vrf
*zvrf
)
3687 struct in_addr vtep_ip
;
3689 zebra_vtep_t
*zvtep
;
3693 while (l
< length
) {
3694 /* Obtain each remote VTEP and process. */
3695 vni
= (vni_t
)stream_getl(s
);
3697 vtep_ip
.s_addr
= stream_get_ipv4(s
);
3698 l
+= IPV4_MAX_BYTELEN
;
3700 if (IS_ZEBRA_DEBUG_VXLAN
)
3701 zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
3702 zvrf_id(zvrf
), inet_ntoa(vtep_ip
), vni
,
3703 zebra_route_string(client
->proto
));
3705 /* Locate VNI hash entry - expected to exist. */
3706 zvni
= zvni_lookup(zvrf
, vni
);
3708 if (IS_ZEBRA_DEBUG_VXLAN
)
3710 "Failed to locate VNI hash upon remote VTEP DEL, "
3712 zvrf_id(zvrf
), vni
);
3716 /* If the remote VTEP does not exist, there's nothing more to
3718 * Otherwise, uninstall any remote MACs pointing to this VTEP
3720 * then, the VTEP entry itself and remove it.
3722 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
3726 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
3727 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
3728 zvni_vtep_uninstall(zvni
, &vtep_ip
);
3729 zvni_vtep_del(zvni
, zvtep
);
3736 * Handle message from client to add a remote VTEP for a VNI.
3738 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, int sock
, u_short length
,
3739 struct zebra_vrf
*zvrf
)
3744 struct in_addr vtep_ip
;
3747 assert(EVPN_ENABLED(zvrf
));
3751 while (l
< length
) {
3752 /* Obtain each remote VTEP and process. */
3753 vni
= (vni_t
)stream_getl(s
);
3755 vtep_ip
.s_addr
= stream_get_ipv4(s
);
3756 l
+= IPV4_MAX_BYTELEN
;
3758 if (IS_ZEBRA_DEBUG_VXLAN
)
3759 zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
3760 zvrf_id(zvrf
), inet_ntoa(vtep_ip
), vni
,
3761 zebra_route_string(client
->proto
));
3763 /* Locate VNI hash entry - expected to exist. */
3764 zvni
= zvni_lookup(zvrf
, vni
);
3767 "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
3768 zvrf_id(zvrf
), vni
);
3771 if (!zvni
->vxlan_if
) {
3773 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
3779 /* If the remote VTEP already exists, or the local VxLAN
3781 * not up (should be a transient event), there's nothing more
3783 * Otherwise, add and install the entry.
3785 if (zvni_vtep_find(zvni
, &vtep_ip
))
3788 if (!if_is_operative(zvni
->vxlan_if
))
3791 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
3793 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
3794 zvrf_id(zvrf
), vni
, zvni
);
3798 zvni_vtep_install(zvni
, &vtep_ip
);
3805 * Add/Del gateway macip to evpn
3807 * 1. SVI interface on a vlan aware bridge
3808 * 2. SVI interface on a vlan unaware bridge
3809 * 3. vrr interface (MACVLAN) associated to a SVI
3810 * We advertise macip routes for an interface if it is associated to VxLan vlan
3812 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
3816 struct ethaddr macaddr
;
3817 zebra_vni_t
*zvni
= NULL
;
3818 struct zebra_vrf
*zvrf
= NULL
;
3820 memset(&ip
, 0, sizeof(struct ipaddr
));
3821 memset(&macaddr
, 0, sizeof(struct ethaddr
));
3823 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
3827 if (!EVPN_ENABLED(zvrf
))
3830 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
3831 struct interface
*svi_if
=
3832 NULL
; /* SVI corresponding to the MACVLAN */
3833 struct zebra_if
*ifp_zif
=
3834 NULL
; /* Zebra daemon specific info for MACVLAN */
3835 struct zebra_if
*svi_if_zif
=
3836 NULL
; /* Zebra daemon specific info for SVI*/
3838 ifp_zif
= ifp
->info
;
3842 svi_if
= ifp_zif
->link
;
3844 zlog_err("%u:MACVLAN %s(%u) without link information",
3845 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
);
3849 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
3850 svi_if_zif
= svi_if
->info
;
3852 zvni
= zvni_map_svi(svi_if
, svi_if_zif
->link
);
3853 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
3854 zvni
= zvni_map_svi(svi_if
, svi_if
);
3856 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
3857 struct zebra_if
*svi_if_zif
=
3858 NULL
; /* Zebra daemon specific info for SVI*/
3860 svi_if_zif
= ifp
->info
;
3862 zvni
= zvni_map_svi(ifp
, svi_if_zif
->link
);
3863 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
3864 zvni
= zvni_map_svi(ifp
, ifp
);
3870 if (!zvni
->vxlan_if
) {
3871 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
3877 /* check if we are advertising gw macip routes */
3878 if (!advertise_gw_macip_enabled(zvrf
, zvni
))
3881 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
3883 if (p
->family
== AF_INET
) {
3884 ip
.ipa_type
= IPADDR_V4
;
3885 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
3886 sizeof(struct in_addr
));
3887 } else if (p
->family
== AF_INET6
) {
3888 ip
.ipa_type
= IPADDR_V6
;
3889 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
3890 sizeof(struct in6_addr
));
3895 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
3897 zvni_gw_macip_del(ifp
, zvni
, &ip
);
3903 * Handle SVI interface going down. At this point, this is a NOP since
3904 * the kernel deletes the neighbor entries on this SVI (if any).
3906 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
3912 * Handle SVI interface coming up. This may or may not be of interest,
3913 * but if this is a SVI on a VxLAN bridge, we need to install any remote
3914 * neighbor entries (which will be used for EVPN ARP suppression).
3916 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
3919 struct neigh_walk_ctx n_wctx
;
3921 zvni
= zvni_map_svi(ifp
, link_if
);
3925 if (!zvni
->vxlan_if
) {
3926 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
3931 if (IS_ZEBRA_DEBUG_VXLAN
)
3932 zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
3933 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
3935 /* Install any remote neighbors for this VNI. */
3936 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
3938 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
, &n_wctx
);
3944 * Handle VxLAN interface down - update BGP if required, and do
3947 int zebra_vxlan_if_down(struct interface
*ifp
)
3949 struct zebra_if
*zif
;
3950 struct zebra_vrf
*zvrf
;
3952 struct zebra_l2info_vxlan
*vxl
;
3955 /* Locate VRF corresponding to interface. */
3956 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
3959 /* If EVPN is not enabled, nothing further to be done. */
3960 if (!EVPN_ENABLED(zvrf
))
3965 vxl
= &zif
->l2info
.vxl
;
3968 if (IS_ZEBRA_DEBUG_VXLAN
)
3969 zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp
->vrf_id
,
3970 ifp
->name
, ifp
->ifindex
, vni
);
3972 /* Locate hash entry; it is expected to exist. */
3973 zvni
= zvni_lookup(zvrf
, vni
);
3976 "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
3977 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
3981 assert(zvni
->vxlan_if
== ifp
);
3983 /* Delete this VNI from BGP. */
3984 zvni_send_del_to_client(zvrf
, zvni
->vni
);
3986 /* Free up all neighbors and MACs, if any. */
3987 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
3988 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
3990 /* Free up all remote VTEPs, if any. */
3991 zvni_vtep_del_all(zvni
, 1);
3997 * Handle VxLAN interface up - update BGP if required.
3999 int zebra_vxlan_if_up(struct interface
*ifp
)
4001 struct zebra_if
*zif
;
4002 struct zebra_vrf
*zvrf
;
4004 struct zebra_l2info_vxlan
*vxl
;
4007 /* Locate VRF corresponding to interface. */
4008 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
4011 /* If EVPN is not enabled, nothing further to be done. */
4012 if (!EVPN_ENABLED(zvrf
))
4017 vxl
= &zif
->l2info
.vxl
;
4020 if (IS_ZEBRA_DEBUG_VXLAN
)
4021 zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp
->vrf_id
,
4022 ifp
->name
, ifp
->ifindex
, vni
);
4024 /* Locate hash entry; it is expected to exist. */
4025 zvni
= zvni_lookup(zvrf
, vni
);
4028 "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
4029 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
4033 assert(zvni
->vxlan_if
== ifp
);
4035 /* If part of a bridge, inform BGP about this VNI. */
4036 /* Also, read and populate local MACs and neighbors. */
4037 if (zif
->brslave_info
.br_if
) {
4038 zvni_send_add_to_client(zvrf
, zvni
);
4039 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
4046 * Handle VxLAN interface delete. Locate and remove entry in hash table
4047 * and update BGP, if required.
4049 int zebra_vxlan_if_del(struct interface
*ifp
)
4051 struct zebra_if
*zif
;
4052 struct zebra_vrf
*zvrf
;
4054 struct zebra_l2info_vxlan
*vxl
;
4057 /* Locate VRF corresponding to interface. */
4058 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
4061 /* If EVPN is not enabled, nothing further to be done. */
4062 if (!EVPN_ENABLED(zvrf
))
4067 vxl
= &zif
->l2info
.vxl
;
4070 if (IS_ZEBRA_DEBUG_VXLAN
)
4071 zlog_debug("%u:Del VNI %u intf %s(%u)", ifp
->vrf_id
, vni
,
4072 ifp
->name
, ifp
->ifindex
);
4074 /* Locate hash entry; it is expected to exist. */
4075 zvni
= zvni_lookup(zvrf
, vni
);
4078 "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
4079 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
4083 /* Delete VNI from BGP. */
4084 zvni_send_del_to_client(zvrf
, zvni
->vni
);
4086 /* Free up all neighbors and MAC, if any. */
4087 zvni_neigh_del_all(zvrf
, zvni
, 0, 0, DEL_ALL_NEIGH
);
4088 zvni_mac_del_all(zvrf
, zvni
, 0, 0, DEL_ALL_MAC
);
4090 /* Free up all remote VTEPs, if any. */
4091 zvni_vtep_del_all(zvni
, 0);
4093 /* Delete the hash entry. */
4094 if (zvni_del(zvrf
, zvni
)) {
4095 zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
4096 zvni
, ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4104 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
4106 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
4108 struct zebra_if
*zif
;
4109 struct zebra_vrf
*zvrf
;
4111 struct zebra_l2info_vxlan
*vxl
;
4114 /* Locate VRF corresponding to interface. */
4115 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
4118 /* If EVPN is not enabled, nothing further to be done. */
4119 if (!EVPN_ENABLED(zvrf
))
4124 vxl
= &zif
->l2info
.vxl
;
4127 /* Update VNI hash. */
4128 zvni
= zvni_lookup(zvrf
, vni
);
4131 "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
4132 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
4136 if (IS_ZEBRA_DEBUG_VXLAN
)
4138 "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
4139 "master %u chg 0x%x",
4140 ifp
->vrf_id
, vni
, ifp
->name
, ifp
->ifindex
,
4141 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
4142 zif
->brslave_info
.bridge_ifindex
, chgflags
);
4144 /* Removed from bridge? */
4145 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
4146 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
4147 /* Delete from client, remove all remote VTEPs */
4148 /* Also, free up all MACs and neighbors. */
4149 zvni_send_del_to_client(zvrf
, zvni
->vni
);
4150 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
4151 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
4152 zvni_vtep_del_all(zvni
, 1);
4153 } else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
4154 /* Remove all existing local neighbors and MACs for this VNI
4155 * (including from BGP)
4157 zvni_neigh_del_all(zvrf
, zvni
, 0, 1, DEL_LOCAL_MAC
);
4158 zvni_mac_del_all(zvrf
, zvni
, 0, 1, DEL_LOCAL_MAC
);
4161 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
4162 zvni
->vxlan_if
= ifp
;
4164 /* Take further actions needed. Note that if we are here, there is a
4165 * change of interest.
4167 /* If down or not mapped to a bridge, we're done. */
4168 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4171 /* Inform BGP, if there is a change of interest. */
4173 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
4174 zvni_send_add_to_client(zvrf
, zvni
);
4176 /* If there is a valid new master or a VLAN mapping change, read and
4177 * populate local MACs and neighbors. Also, reinstall any remote MACs
4178 * and neighbors for this VNI (based on new VLAN).
4180 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
4181 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
4182 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
4183 struct mac_walk_ctx m_wctx
;
4184 struct neigh_walk_ctx n_wctx
;
4186 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
4188 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
4190 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
, &m_wctx
);
4192 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
4194 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
4202 * Handle VxLAN interface add.
4204 int zebra_vxlan_if_add(struct interface
*ifp
)
4206 struct zebra_if
*zif
;
4207 struct zebra_vrf
*zvrf
;
4209 struct zebra_l2info_vxlan
*vxl
;
4212 /* Locate VRF corresponding to interface. */
4213 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
4216 /* If EVPN is not enabled, nothing further to be done. */
4217 if (!EVPN_ENABLED(zvrf
))
4222 vxl
= &zif
->l2info
.vxl
;
4225 if (IS_ZEBRA_DEBUG_VXLAN
)
4227 "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
4228 ifp
->vrf_id
, vni
, ifp
->name
, ifp
->ifindex
,
4229 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
4230 zif
->brslave_info
.bridge_ifindex
);
4232 /* Create or update VNI hash. */
4233 zvni
= zvni_lookup(zvrf
, vni
);
4235 zvni
= zvni_add(zvrf
, vni
);
4238 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
4239 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
4244 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
4245 zvni
->vxlan_if
= ifp
;
4247 /* If down or not mapped to a bridge, we're done. */
4248 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4252 zvni_send_add_to_client(zvrf
, zvni
);
4254 /* Read and populate local MACs and neighbors */
4255 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
4261 * Handle message from client to enable/disable advertisement of g/w macip
4264 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, int sock
,
4265 u_short length
, struct zebra_vrf
*zvrf
)
4270 zebra_vni_t
*zvni
= NULL
;
4273 advertise
= stream_getc(s
);
4274 vni
= stream_get3(s
);
4277 if (IS_ZEBRA_DEBUG_VXLAN
)
4278 zlog_debug("%u:EVPN gateway macip Adv %s, currently %s",
4280 advertise
? "enabled" : "disabled",
4281 advertise_gw_macip_enabled(zvrf
, NULL
)
4285 if (zvrf
->advertise_gw_macip
== advertise
)
4288 zvrf
->advertise_gw_macip
= advertise
;
4290 if (advertise_gw_macip_enabled(zvrf
, zvni
))
4291 hash_iterate(zvrf
->vni_table
,
4292 zvni_gw_macip_add_for_vni_hash
, zvrf
);
4294 hash_iterate(zvrf
->vni_table
,
4295 zvni_gw_macip_del_for_vni_hash
, zvrf
);
4298 struct zebra_if
*zif
= NULL
;
4299 struct zebra_l2info_vxlan zl2_info
;
4300 struct interface
*vlan_if
= NULL
;
4301 struct interface
*vrr_if
= NULL
;
4303 if (IS_ZEBRA_DEBUG_VXLAN
)
4305 "%u:EVPN gateway macip Adv %s on VNI %d , currently %s",
4307 advertise
? "enabled" : "disabled", vni
,
4308 advertise_gw_macip_enabled(zvrf
, zvni
)
4312 zvni
= zvni_lookup(zvrf
, vni
);
4316 if (zvni
->advertise_gw_macip
== advertise
)
4319 zvni
->advertise_gw_macip
= advertise
;
4321 zif
= zvni
->vxlan_if
->info
;
4322 zl2_info
= zif
->l2info
.vxl
;
4324 vlan_if
= zvni_map_to_svi(zvrf
, zl2_info
.access_vlan
,
4325 zif
->brslave_info
.br_if
);
4329 if (advertise_gw_macip_enabled(zvrf
, zvni
)) {
4330 /* Add primary SVI MAC-IP */
4331 zvni_add_macip_for_intf(vlan_if
, zvni
);
4333 /* Add VRR MAC-IP - if any*/
4334 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
4336 zvni_add_macip_for_intf(vrr_if
, zvni
);
4338 /* Del primary MAC-IP */
4339 zvni_del_macip_for_intf(vlan_if
, zvni
);
4341 /* Del VRR MAC-IP - if any*/
4342 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
4344 zvni_del_macip_for_intf(vrr_if
, zvni
);
4353 * Handle message from client to learn (or stop learning) about VNIs and MACs.
4354 * When enabled, the VNI hash table will be built and MAC FDB table read;
4355 * when disabled, the entries should be deleted and remote VTEPs and MACs
4356 * uninstalled from the kernel.
4358 int zebra_vxlan_advertise_all_vni(struct zserv
*client
, int sock
,
4359 u_short length
, struct zebra_vrf
*zvrf
)
4365 advertise
= stream_getc(s
);
4367 if (IS_ZEBRA_DEBUG_VXLAN
)
4368 zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf
),
4369 advertise
? "enabled" : "disabled",
4370 EVPN_ENABLED(zvrf
) ? "enabled" : "disabled");
4372 if (zvrf
->advertise_all_vni
== advertise
)
4375 zvrf
->advertise_all_vni
= advertise
;
4376 if (EVPN_ENABLED(zvrf
)) {
4377 /* Build VNI hash table and inform BGP. */
4378 zvni_build_hash_table(zvrf
);
4380 /* Add all SVI (L3 GW) MACs to BGP*/
4381 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
4384 /* Read the MAC FDB */
4385 macfdb_read(zvrf
->zns
);
4387 /* Read neighbors */
4388 neigh_read(zvrf
->zns
);
4390 /* Cleanup VTEPs for all VNIs - uninstall from
4391 * kernel and free entries.
4393 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
4400 * Allocate VNI hash table for this VRF and do other initialization.
4401 * NOTE: Currently supported only for default VRF.
4403 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
4407 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
4408 "Zebra VRF VNI Table");
4411 /* Close all VNI handling */
4412 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
4414 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
4415 hash_free(zvrf
->vni_table
);