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"
50 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
51 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
52 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
53 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
58 /* static function declarations */
59 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
);
60 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
61 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
63 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
64 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
65 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
66 static void zvni_print(zebra_vni_t
*zvni
, void *ctxt
);
67 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
);
69 static int zvni_macip_send_msg_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
70 struct ethaddr
*macaddr
,
71 struct ipaddr
*ip
, u_char sticky
,
73 static unsigned int neigh_hash_keymake(void *p
);
74 static int neigh_cmp(const void *p1
, const void *p2
);
75 static void *zvni_neigh_alloc(void *p
);
76 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
77 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
78 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
79 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
80 struct in_addr
*r_vtep_ip
);
81 static void zvni_neigh_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
82 int uninstall
, int upd_client
, u_int32_t flags
);
83 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
84 static int zvni_neigh_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
86 struct ethaddr
*macaddr
);
87 static int zvni_neigh_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
89 struct ethaddr
*macaddr
);
90 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
91 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
92 static zebra_vni_t
*zvni_map_svi(struct interface
*ifp
,
93 struct interface
*br_if
);
94 static struct interface
*zvni_map_to_svi(struct zebra_vrf
*zvrf
, vlanid_t vid
,
95 struct interface
*br_if
);
97 static unsigned int mac_hash_keymake(void *p
);
98 static int mac_cmp(const void *p1
, const void *p2
);
99 static void *zvni_mac_alloc(void *p
);
100 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
101 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
102 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
103 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
104 struct in_addr
*r_vtep_ip
);
105 static void zvni_mac_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
106 int uninstall
, int upd_client
, u_int32_t flags
);
107 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
108 static int zvni_mac_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
109 struct ethaddr
*macaddr
, u_char sticky
);
110 static int zvni_mac_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
111 struct ethaddr
*macaddr
, u_char sticky
);
112 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
113 struct interface
*br_if
, vlanid_t vid
);
114 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
115 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
116 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
118 static unsigned int vni_hash_keymake(void *p
);
119 static int vni_hash_cmp(const void *p1
, const void *p2
);
120 static void *zvni_alloc(void *p
);
121 static zebra_vni_t
*zvni_lookup(struct zebra_vrf
*zvrf
, vni_t vni
);
122 static zebra_vni_t
*zvni_add(struct zebra_vrf
*zvrf
, vni_t vni
);
123 static int zvni_del(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
);
124 static int zvni_send_add_to_client(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
);
125 static int zvni_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
);
126 static void zvni_build_hash_table(struct zebra_vrf
*zvrf
);
127 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
128 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
129 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
130 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
131 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
132 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
133 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
136 /* Private functions */
139 * Helper function to determine maximum width of neighbor IP address for
140 * display - just because we're dealing with IPv6 addresses that can
143 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
146 char buf
[INET6_ADDRSTRLEN
];
147 struct neigh_walk_ctx
*wctx
= ctxt
;
150 n
= (zebra_neigh_t
*)backet
->data
;
154 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
155 if (width
> wctx
->addr_width
)
156 wctx
->addr_width
= width
;
160 * Print a specific neighbor entry.
162 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
)
165 char buf1
[ETHER_ADDR_STRLEN
];
166 char buf2
[INET6_ADDRSTRLEN
];
168 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)), vty
= (struct vty
*)ctxt
;
169 vty_out(vty
, "IP: %s\n", ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
170 vty_out(vty
, " MAC: %s", prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
171 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
172 vty_out(vty
, " Remote VTEP: %s", inet_ntoa(n
->r_vtep_ip
));
177 * Print neighbor hash entry - called for display of all neighbors.
179 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
183 char buf1
[ETHER_ADDR_STRLEN
];
184 char buf2
[INET6_ADDRSTRLEN
];
185 struct neigh_walk_ctx
*wctx
= ctxt
;
188 n
= (zebra_neigh_t
*)backet
->data
;
192 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
193 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
194 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
195 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
196 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
, buf2
,
200 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
201 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
202 if (wctx
->count
== 0)
203 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
204 -wctx
->addr_width
, "Neighbor",
205 "Type", "MAC", "Remote VTEP");
206 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
207 -wctx
->addr_width
, buf2
, "remote", buf1
,
208 inet_ntoa(n
->r_vtep_ip
));
212 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
213 -wctx
->addr_width
, buf2
, "remote", buf1
,
214 inet_ntoa(n
->r_vtep_ip
));
221 * Print neighbors for all VNI.
223 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
229 struct neigh_walk_ctx wctx
;
231 vty
= (struct vty
*)ctxt
;
232 zvni
= (zebra_vni_t
*)backet
->data
;
236 num_neigh
= hashcount(zvni
->neigh_table
);
237 vty_out(vty
, "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
238 zvni
->vni
, num_neigh
);
242 /* Since we have IPv6 addresses to deal with which can vary widely in
243 * size, we try to be a bit more elegant in display by first computing
246 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
249 wctx
.addr_width
= 15;
250 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
252 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP", "Type",
253 "MAC", "Remote VTEP");
254 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
258 * Print a specific MAC entry.
260 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
265 vty
= (struct vty
*)ctxt
;
266 vty_out(vty
, "MAC: %s",
267 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
268 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
269 struct zebra_ns
*zns
;
270 struct interface
*ifp
;
273 ifindex
= mac
->fwd_info
.local
.ifindex
;
274 zns
= zebra_ns_lookup(NS_DEFAULT
);
275 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
276 if (!ifp
) // unexpected
278 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
279 if (mac
->fwd_info
.local
.vid
)
280 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
282 vty_out(vty
, " Remote VTEP: %s",
283 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
285 vty_out(vty
, " ARP ref: %u", mac
->neigh_refcnt
);
290 * Print MAC hash entry - called for display of all MACs.
292 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
297 struct mac_walk_ctx
*wctx
= ctxt
;
300 mac
= (zebra_mac_t
*)backet
->data
;
304 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
305 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
306 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
307 struct zebra_ns
*zns
;
309 struct interface
*ifp
;
312 zns
= zebra_ns_lookup(NS_DEFAULT
);
313 ifindex
= mac
->fwd_info
.local
.ifindex
;
314 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
315 if (!ifp
) // unexpected
317 vid
= mac
->fwd_info
.local
.vid
;
318 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local", ifp
->name
);
320 vty_out(vty
, " %-5u", vid
);
324 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
325 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
327 if (wctx
->count
== 0) {
328 vty_out(vty
, "\nVNI %u",
330 vty_out(vty
, "%-17s %-6s %-21s %-5s",
332 "Intf/Remote VTEP", "VLAN");
334 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "remote",
335 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
339 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "remote",
340 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
347 * Print MACs for all VNI.
349 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
354 struct mac_walk_ctx
*wctx
= ctxt
;
356 vty
= (struct vty
*)wctx
->vty
;
358 zvni
= (zebra_vni_t
*)backet
->data
;
363 /*We are iterating over a new VNI, set the count to 0*/
366 num_macs
= hashcount(zvni
->mac_table
);
369 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
370 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
371 zvni
->vni
, num_macs
);
372 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
373 "Intf/Remote VTEP", "VLAN");
376 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
380 * Print a specific VNI entry.
382 static void zvni_print(zebra_vni_t
*zvni
, void *ctxt
)
389 vty
= (struct vty
*)ctxt
;
391 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
392 if (!zvni
->vxlan_if
) { // unexpected
393 vty_out(vty
, " VxLAN interface: unknown\n");
396 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
397 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
398 inet_ntoa(zvni
->local_vtep_ip
));
401 vty_out(vty
, " No remote VTEPs known for this VNI\n");
403 vty_out(vty
, " Remote VTEPs for this VNI:\n");
404 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
)
405 vty_out(vty
, " %s\n", inet_ntoa(zvtep
->vtep_ip
));
407 num_macs
= hashcount(zvni
->mac_table
);
409 " Number of MACs (local and remote) known for this VNI: %u\n",
411 num_neigh
= hashcount(zvni
->neigh_table
);
413 " Number of ARPs (IPv4 and IPv6, local and remote) "
414 "known for this VNI: %u",
419 * Print a VNI hash entry - called for display of all VNIs.
421 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
)
426 u_int32_t num_vteps
= 0;
427 u_int32_t num_macs
= 0;
428 u_int32_t num_neigh
= 0;
430 vty
= (struct vty
*)ctxt
;
431 zvni
= (zebra_vni_t
*)backet
->data
;
441 num_macs
= hashcount(zvni
->mac_table
);
442 num_neigh
= hashcount(zvni
->neigh_table
);
443 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni
->vni
,
444 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
445 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
, num_vteps
);
449 * Inform BGP about local MACIP.
451 static int zvni_macip_send_msg_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
452 struct ethaddr
*macaddr
,
453 struct ipaddr
*ip
, u_char sticky
,
456 struct zserv
*client
;
459 char buf
[ETHER_ADDR_STRLEN
];
460 char buf2
[INET6_ADDRSTRLEN
];
462 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
463 /* BGP may not be running. */
470 zserv_create_header(s
, cmd
, zvrf_id(zvrf
));
472 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
475 if (IS_IPADDR_V4(ip
))
476 ipa_len
= IPV4_MAX_BYTELEN
;
477 else if (IS_IPADDR_V6(ip
))
478 ipa_len
= IPV6_MAX_BYTELEN
;
480 stream_putl(s
, ipa_len
); /* IP address length */
482 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
484 stream_putl(s
, 0); /* Just MAC. */
486 stream_putc(s
, sticky
); /* Sticky MAC? */
488 /* Write packet size. */
489 stream_putw_at(s
, 0, stream_get_endp(s
));
491 if (IS_ZEBRA_DEBUG_VXLAN
)
492 zlog_debug("%u:Send MACIP %s %sMAC %s IP %s VNI %u to %s",
494 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
495 sticky
? "sticky " : "",
496 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
497 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
498 zebra_route_string(client
->proto
));
500 if (cmd
== ZEBRA_MACIP_ADD
)
501 client
->macipadd_cnt
++;
503 client
->macipdel_cnt
++;
505 return zebra_server_send_message(client
);
509 * Make hash key for neighbors.
511 static unsigned int neigh_hash_keymake(void *p
)
513 zebra_neigh_t
*n
= p
;
514 struct ipaddr
*ip
= &n
->ip
;
516 if (IS_IPADDR_V4(ip
))
517 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
519 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
520 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
524 * Compare two neighbor hash structures.
526 static int neigh_cmp(const void *p1
, const void *p2
)
528 const zebra_neigh_t
*n1
= p1
;
529 const zebra_neigh_t
*n2
= p2
;
531 if (n1
== NULL
&& n2
== NULL
)
534 if (n1
== NULL
|| n2
== NULL
)
537 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
541 * Callback to allocate neighbor hash entry.
543 static void *zvni_neigh_alloc(void *p
)
545 const zebra_neigh_t
*tmp_n
= p
;
548 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
555 * Add neighbor entry.
557 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
560 zebra_neigh_t
*n
= NULL
;
562 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
563 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
564 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
571 * Delete neighbor entry.
573 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
575 zebra_neigh_t
*tmp_n
;
577 /* Free the VNI hash entry and allocated memory. */
578 tmp_n
= hash_release(zvni
->neigh_table
, n
);
580 XFREE(MTYPE_NEIGH
, tmp_n
);
586 * Free neighbor hash entry (callback)
588 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
590 struct neigh_walk_ctx
*wctx
= arg
;
591 zebra_neigh_t
*n
= backet
->data
;
593 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
594 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
595 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
596 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
597 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
598 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
599 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
600 zvni_neigh_send_del_to_client(
601 wctx
->zvrf
, wctx
->zvni
->vni
, &n
->ip
, &n
->emac
);
604 zvni_neigh_uninstall(wctx
->zvni
, n
);
606 return zvni_neigh_del(wctx
->zvni
, n
);
613 * Delete all neighbor entries from specific VTEP for a particular VNI.
615 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
616 struct in_addr
*r_vtep_ip
)
618 struct neigh_walk_ctx wctx
;
620 if (!zvni
->neigh_table
)
623 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
625 wctx
.uninstall
= uninstall
;
626 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
627 wctx
.r_vtep_ip
= *r_vtep_ip
;
629 hash_iterate(zvni
->neigh_table
,
630 (void (*)(struct hash_backet
*,
631 void *))zvni_neigh_del_hash_entry
,
636 * Delete all neighbor entries for this VNI.
638 static void zvni_neigh_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
639 int uninstall
, int upd_client
, u_int32_t flags
)
641 struct neigh_walk_ctx wctx
;
643 if (!zvni
->neigh_table
)
646 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
649 wctx
.uninstall
= uninstall
;
650 wctx
.upd_client
= upd_client
;
653 hash_iterate(zvni
->neigh_table
,
654 (void (*)(struct hash_backet
*,
655 void *))zvni_neigh_del_hash_entry
,
660 * Look up neighbor hash entry.
662 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
667 memset(&tmp
, 0, sizeof(tmp
));
668 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
669 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
675 * Inform BGP about local neighbor addition.
677 static int zvni_neigh_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
679 struct ethaddr
*macaddr
)
681 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, ip
, 0,
686 * Inform BGP about local neighbor deletion.
688 static int zvni_neigh_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
690 struct ethaddr
*macaddr
)
692 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, ip
, 0,
697 * Install remote neighbor into the kernel.
699 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
701 struct zebra_vrf
*zvrf
;
702 struct zebra_if
*zif
;
703 struct zebra_l2info_vxlan
*vxl
;
704 struct interface
*vlan_if
;
706 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
709 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
711 zif
= zvni
->vxlan_if
->info
;
714 vxl
= &zif
->l2info
.vxl
;
716 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
717 zif
->brslave_info
.br_if
);
721 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
725 * Uninstall remote neighbor from the kernel.
727 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
729 struct zebra_vrf
*zvrf
;
730 struct zebra_if
*zif
;
731 struct zebra_l2info_vxlan
*vxl
;
732 struct interface
*vlan_if
;
734 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
737 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
739 if (!zvni
->vxlan_if
) {
740 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
745 zif
= zvni
->vxlan_if
->info
;
748 vxl
= &zif
->l2info
.vxl
;
749 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
750 zif
->brslave_info
.br_if
);
754 return kernel_del_neigh(vlan_if
, &n
->ip
);
758 * Install neighbor hash entry - called upon access VLAN change.
760 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
763 struct neigh_walk_ctx
*wctx
= ctxt
;
765 n
= (zebra_neigh_t
*)backet
->data
;
769 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
770 zvni_neigh_install(wctx
->zvni
, n
);
774 * Make hash key for MAC.
776 static unsigned int mac_hash_keymake(void *p
)
778 zebra_mac_t
*pmac
= p
;
779 const void *pnt
= (void *)pmac
->macaddr
.octet
;
781 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
785 * Compare two MAC addresses.
787 static int mac_cmp(const void *p1
, const void *p2
)
789 const zebra_mac_t
*pmac1
= p1
;
790 const zebra_mac_t
*pmac2
= p2
;
792 if (pmac1
== NULL
&& pmac2
== NULL
)
795 if (pmac1
== NULL
|| pmac2
== NULL
)
798 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
804 * Callback to allocate MAC hash entry.
806 static void *zvni_mac_alloc(void *p
)
808 const zebra_mac_t
*tmp_mac
= p
;
811 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
814 return ((void *)mac
);
820 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
823 zebra_mac_t
*mac
= NULL
;
825 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
826 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
827 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
836 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
838 zebra_mac_t
*tmp_mac
;
840 /* Free the VNI hash entry and allocated memory. */
841 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
843 XFREE(MTYPE_MAC
, tmp_mac
);
849 * Free MAC hash entry (callback)
851 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
853 struct mac_walk_ctx
*wctx
= arg
;
854 zebra_mac_t
*mac
= backet
->data
;
857 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
858 || ((wctx
->flags
& DEL_REMOTE_MAC
)
859 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
860 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
861 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
862 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
863 &wctx
->r_vtep_ip
))) {
864 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
865 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
867 zvni_mac_send_del_to_client(wctx
->zvrf
, wctx
->zvni
->vni
,
868 &mac
->macaddr
, sticky
);
872 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
874 return zvni_mac_del(wctx
->zvni
, mac
);
881 * Delete all MAC entries from specific VTEP for a particular VNI.
883 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
884 struct in_addr
*r_vtep_ip
)
886 struct mac_walk_ctx wctx
;
888 if (!zvni
->mac_table
)
891 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
893 wctx
.uninstall
= uninstall
;
894 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
895 wctx
.r_vtep_ip
= *r_vtep_ip
;
897 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
898 void *))zvni_mac_del_hash_entry
,
903 * Delete all MAC entries for this VNI.
905 static void zvni_mac_del_all(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
906 int uninstall
, int upd_client
, u_int32_t flags
)
908 struct mac_walk_ctx wctx
;
910 if (!zvni
->mac_table
)
913 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
916 wctx
.uninstall
= uninstall
;
917 wctx
.upd_client
= upd_client
;
920 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
921 void *))zvni_mac_del_hash_entry
,
926 * Look up MAC hash entry.
928 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
933 memset(&tmp
, 0, sizeof(tmp
));
934 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
935 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
941 * Inform BGP about local MAC addition.
943 static int zvni_mac_send_add_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
944 struct ethaddr
*macaddr
, u_char sticky
)
946 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, NULL
, sticky
,
951 * Inform BGP about local MAC deletion.
953 static int zvni_mac_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
,
954 struct ethaddr
*macaddr
, u_char sticky
)
956 return zvni_macip_send_msg_to_client(zvrf
, vni
, macaddr
, NULL
, sticky
,
961 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
962 * notifications, to see if there are of interest.
963 * TODO: Need to make this as a hash table.
965 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
966 struct interface
*br_if
, vlanid_t vid
)
968 struct zebra_vrf
*zvrf
;
969 struct listnode
*node
;
970 struct interface
*tmp_if
;
971 struct zebra_if
*zif
;
972 struct zebra_l2info_bridge
*br
;
973 struct zebra_l2info_vxlan
*vxl
;
974 u_char bridge_vlan_aware
;
977 /* Locate VRF corresponding to interface. */
978 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
981 /* Determine if bridge is VLAN-aware or not */
984 br
= &zif
->l2info
.br
;
985 bridge_vlan_aware
= br
->vlan_aware
;
987 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
988 /* TODO: Optimize with a hash. */
989 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
991 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
993 if (!if_is_operative(tmp_if
))
995 vxl
= &zif
->l2info
.vxl
;
997 if (zif
->brslave_info
.br_if
!= br_if
)
1000 if (!bridge_vlan_aware
)
1003 if (vxl
->access_vlan
== vid
)
1010 zvni
= zvni_lookup(zvrf
, vxl
->vni
);
1015 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1016 * neighbor notifications, to see if they are of interest.
1017 * TODO: Need to make this as a hash table.
1019 static zebra_vni_t
*zvni_map_svi(struct interface
*ifp
, struct interface
*br_if
)
1021 struct zebra_vrf
*zvrf
;
1022 struct listnode
*node
;
1023 struct interface
*tmp_if
;
1024 struct zebra_if
*zif
;
1025 struct zebra_l2info_bridge
*br
;
1026 struct zebra_l2info_vxlan
*vxl
;
1027 u_char bridge_vlan_aware
;
1031 /* Make sure the linked interface is a bridge. */
1032 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
1035 /* Locate VRF corresponding to interface. */
1036 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1039 /* Determine if bridge is VLAN-aware or not */
1042 br
= &zif
->l2info
.br
;
1043 bridge_vlan_aware
= br
->vlan_aware
;
1044 if (bridge_vlan_aware
) {
1045 struct zebra_l2info_vlan
*vl
;
1047 if (!IS_ZEBRA_IF_VLAN(ifp
))
1052 vl
= &zif
->l2info
.vl
;
1056 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1057 /* TODO: Optimize with a hash. */
1058 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1060 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1062 if (!if_is_operative(tmp_if
))
1064 vxl
= &zif
->l2info
.vxl
;
1066 if (zif
->brslave_info
.br_if
!= br_if
)
1069 if (!bridge_vlan_aware
)
1072 if (vxl
->access_vlan
== vid
)
1079 zvni
= zvni_lookup(zvrf
, vxl
->vni
);
1083 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
1085 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1086 * linked to the bridge
1087 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1090 static struct interface
*zvni_map_to_svi(struct zebra_vrf
*zvrf
, vlanid_t vid
,
1091 struct interface
*br_if
)
1093 struct listnode
*node
;
1094 struct interface
*tmp_if
;
1095 struct zebra_if
*zif
;
1096 struct zebra_l2info_bridge
*br
;
1097 struct zebra_l2info_vlan
*vl
;
1098 u_char bridge_vlan_aware
;
1100 /* Determine if bridge is VLAN-aware or not */
1103 br
= &zif
->l2info
.br
;
1104 bridge_vlan_aware
= br
->vlan_aware
;
1106 /* Check oper status of the SVI. */
1107 if (!bridge_vlan_aware
)
1108 return if_is_operative(br_if
) ? br_if
: NULL
;
1110 /* Identify corresponding VLAN interface. */
1111 /* TODO: Optimize with a hash. */
1112 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, tmp_if
)) {
1113 /* Check oper status of the SVI. */
1114 if (!if_is_operative(tmp_if
))
1117 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
1118 || zif
->link
!= br_if
)
1120 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
1130 * Install remote MAC into the kernel.
1132 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1134 struct zebra_if
*zif
;
1135 struct zebra_l2info_vxlan
*vxl
;
1138 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
1141 zif
= zvni
->vxlan_if
->info
;
1144 vxl
= &zif
->l2info
.vxl
;
1146 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
1148 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
1149 mac
->fwd_info
.r_vtep_ip
, sticky
);
1153 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1154 * moves to remote, we have to uninstall any existing local entry first.
1156 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
1158 struct zebra_if
*zif
;
1159 struct zebra_l2info_vxlan
*vxl
;
1160 struct in_addr vtep_ip
= {.s_addr
= 0};
1161 struct zebra_ns
*zns
;
1162 struct interface
*ifp
;
1164 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
1167 if (!zvni
->vxlan_if
) {
1168 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1173 zif
= zvni
->vxlan_if
->info
;
1176 vxl
= &zif
->l2info
.vxl
;
1179 zns
= zebra_ns_lookup(NS_DEFAULT
);
1180 ifp
= if_lookup_by_index_per_ns(zns
,
1181 mac
->fwd_info
.local
.ifindex
);
1182 if (!ifp
) // unexpected
1185 ifp
= zvni
->vxlan_if
;
1186 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
1189 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
1194 * Install MAC hash entry - called upon access VLAN change.
1196 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
1199 struct mac_walk_ctx
*wctx
= ctxt
;
1201 mac
= (zebra_mac_t
*)backet
->data
;
1205 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
1206 zvni_mac_install(wctx
->zvni
, mac
);
1210 * Decrement neighbor refcount of MAC; uninstall and free it if
1213 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
1216 if (mac
->neigh_refcnt
)
1217 mac
->neigh_refcnt
--;
1219 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
) || mac
->neigh_refcnt
> 0)
1223 zvni_mac_uninstall(zvni
, mac
, 0);
1225 zvni_mac_del(zvni
, mac
);
1229 * Read and populate local MACs and neighbors corresponding to this VNI.
1231 static void zvni_read_mac_neigh(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
,
1232 struct interface
*ifp
)
1234 struct zebra_if
*zif
;
1235 struct interface
*vlan_if
;
1236 struct zebra_l2info_vxlan
*vxl
;
1239 vxl
= &zif
->l2info
.vxl
;
1241 if (IS_ZEBRA_DEBUG_VXLAN
)
1243 "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1244 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1245 zif
->brslave_info
.bridge_ifindex
);
1247 macfdb_read_for_bridge(zvrf
->zns
, ifp
, zif
->brslave_info
.br_if
);
1248 vlan_if
= zvni_map_to_svi(zvrf
, vxl
->access_vlan
,
1249 zif
->brslave_info
.br_if
);
1251 neigh_read_for_vlan(zvrf
->zns
, vlan_if
);
1255 * Hash function for VNI.
1257 static unsigned int vni_hash_keymake(void *p
)
1259 const zebra_vni_t
*zvni
= p
;
1261 return (jhash_1word(zvni
->vni
, 0));
1265 * Compare 2 VNI hash entries.
1267 static int vni_hash_cmp(const void *p1
, const void *p2
)
1269 const zebra_vni_t
*zvni1
= p1
;
1270 const zebra_vni_t
*zvni2
= p2
;
1272 return (zvni1
->vni
== zvni2
->vni
);
1276 * Callback to allocate VNI hash entry.
1278 static void *zvni_alloc(void *p
)
1280 const zebra_vni_t
*tmp_vni
= p
;
1283 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
1284 zvni
->vni
= tmp_vni
->vni
;
1285 return ((void *)zvni
);
1289 * Look up VNI hash entry.
1291 static zebra_vni_t
*zvni_lookup(struct zebra_vrf
*zvrf
, vni_t vni
)
1293 zebra_vni_t tmp_vni
;
1294 zebra_vni_t
*zvni
= NULL
;
1296 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
1298 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
1304 * Add VNI hash entry.
1306 static zebra_vni_t
*zvni_add(struct zebra_vrf
*zvrf
, vni_t vni
)
1308 zebra_vni_t tmp_zvni
;
1309 zebra_vni_t
*zvni
= NULL
;
1311 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
1313 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
1316 /* Create hash table for MAC */
1318 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
1320 /* Create hash table for neighbors */
1321 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
1322 "Zebra VNI Neighbor Table");
1328 * Delete VNI hash entry.
1330 static int zvni_del(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
)
1332 zebra_vni_t
*tmp_zvni
;
1334 zvni
->vxlan_if
= NULL
;
1336 /* Free the neighbor hash table. */
1337 hash_free(zvni
->neigh_table
);
1338 zvni
->neigh_table
= NULL
;
1340 /* Free the MAC hash table. */
1341 hash_free(zvni
->mac_table
);
1342 zvni
->mac_table
= NULL
;
1344 /* Free the VNI hash entry and allocated memory. */
1345 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
1347 XFREE(MTYPE_ZVNI
, tmp_zvni
);
1353 * Inform BGP about local VNI addition.
1355 static int zvni_send_add_to_client(struct zebra_vrf
*zvrf
, zebra_vni_t
*zvni
)
1357 struct zserv
*client
;
1360 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
1361 /* BGP may not be running. */
1368 zserv_create_header(s
, ZEBRA_VNI_ADD
, zvrf_id(zvrf
));
1369 stream_putl(s
, zvni
->vni
);
1370 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
1372 /* Write packet size. */
1373 stream_putw_at(s
, 0, stream_get_endp(s
));
1375 if (IS_ZEBRA_DEBUG_VXLAN
)
1376 zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf
),
1377 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
1378 zebra_route_string(client
->proto
));
1380 client
->vniadd_cnt
++;
1381 return zebra_server_send_message(client
);
1385 * Inform BGP about local VNI deletion.
1387 static int zvni_send_del_to_client(struct zebra_vrf
*zvrf
, vni_t vni
)
1389 struct zserv
*client
;
1392 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
1393 /* BGP may not be running. */
1400 zserv_create_header(s
, ZEBRA_VNI_DEL
, zvrf_id(zvrf
));
1401 stream_putl(s
, vni
);
1403 /* Write packet size. */
1404 stream_putw_at(s
, 0, stream_get_endp(s
));
1406 if (IS_ZEBRA_DEBUG_VXLAN
)
1407 zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf
), vni
,
1408 zebra_route_string(client
->proto
));
1410 client
->vnidel_cnt
++;
1411 return zebra_server_send_message(client
);
1415 * Build the VNI hash table by going over the VxLAN interfaces. This
1416 * is called when EVPN (advertise-all-vni) is enabled.
1418 static void zvni_build_hash_table(struct zebra_vrf
*zvrf
)
1420 struct listnode
*node
;
1421 struct interface
*ifp
;
1423 /* Walk VxLAN interfaces and create VNI hash. */
1424 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf
)), node
, ifp
)) {
1425 struct zebra_if
*zif
;
1426 struct zebra_l2info_vxlan
*vxl
;
1431 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
1433 vxl
= &zif
->l2info
.vxl
;
1437 if (IS_ZEBRA_DEBUG_VXLAN
)
1439 "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
1440 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
,
1441 inet_ntoa(vxl
->vtep_ip
));
1443 /* VNI hash entry is not expected to exist. */
1444 zvni
= zvni_lookup(zvrf
, vni
);
1447 "VNI hash already present for VRF %d IF %s(%u) VNI %u",
1448 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
);
1452 zvni
= zvni_add(zvrf
, vni
);
1455 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
1456 zvrf_id(zvrf
), ifp
->name
, ifp
->ifindex
, vni
);
1460 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
1461 zvni
->vxlan_if
= ifp
;
1463 /* Inform BGP if interface is up and mapped to bridge. */
1464 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
1465 zvni_send_add_to_client(zvrf
, zvni
);
1470 * See if remote VTEP matches with prefix.
1472 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
1474 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
1478 * Locate remote VTEP in VNI hash table.
1480 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
1482 zebra_vtep_t
*zvtep
;
1487 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1488 if (zvni_vtep_match(vtep_ip
, zvtep
))
1496 * Add remote VTEP to VNI hash table.
1498 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
1500 zebra_vtep_t
*zvtep
;
1502 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
1504 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
1508 zvtep
->vtep_ip
= *vtep_ip
;
1511 zvni
->vteps
->prev
= zvtep
;
1512 zvtep
->next
= zvni
->vteps
;
1513 zvni
->vteps
= zvtep
;
1519 * Remove remote VTEP from VNI hash table.
1521 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
1524 zvtep
->next
->prev
= zvtep
->prev
;
1526 zvtep
->prev
->next
= zvtep
->next
;
1528 zvni
->vteps
= zvtep
->next
;
1530 zvtep
->prev
= zvtep
->next
= NULL
;
1531 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
1537 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
1538 * uninstall from kernel if asked to.
1540 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
1542 zebra_vtep_t
*zvtep
, *zvtep_next
;
1547 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
1548 zvtep_next
= zvtep
->next
;
1550 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
1551 zvni_vtep_del(zvni
, zvtep
);
1558 * Install remote VTEP into the kernel.
1560 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
1562 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
1566 * Uninstall remote VTEP from the kernel.
1568 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
1570 if (!zvni
->vxlan_if
) {
1571 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1576 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
1580 * Cleanup VNI/VTEP and update kernel
1582 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
1586 zvni
= (zebra_vni_t
*)backet
->data
;
1590 /* Free up all neighbors and MACs, if any. */
1591 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
1592 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
1594 /* Free up all remote VTEPs, if any. */
1595 zvni_vtep_del_all(zvni
, 1);
1597 /* Delete the hash entry. */
1598 zvni_del(zvrf
, zvni
);
1602 /* Public functions */
1605 * Display Neighbors for a VNI (VTY command handler).
1607 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1611 u_int32_t num_neigh
;
1612 struct neigh_walk_ctx wctx
;
1614 if (!EVPN_ENABLED(zvrf
))
1616 zvni
= zvni_lookup(zvrf
, vni
);
1618 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1621 num_neigh
= hashcount(zvni
->neigh_table
);
1625 /* Since we have IPv6 addresses to deal with which can vary widely in
1626 * size, we try to be a bit more elegant in display by first computing
1627 * the maximum width.
1629 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1632 wctx
.addr_width
= 15;
1633 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
1636 "Number of ARPs (local and remote) known for this VNI: %u\n",
1638 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP", "Type",
1639 "MAC", "Remote VTEP");
1641 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
1645 * Display neighbors across all VNIs (VTY command handler).
1647 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
)
1649 if (!EVPN_ENABLED(zvrf
))
1651 hash_iterate(zvrf
->vni_table
, zvni_print_neigh_hash_all_vni
, vty
);
1655 * Display specific neighbor for a VNI, if present (VTY command handler).
1657 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
1658 struct zebra_vrf
*zvrf
, vni_t vni
,
1664 if (!EVPN_ENABLED(zvrf
))
1666 zvni
= zvni_lookup(zvrf
, vni
);
1668 vty_out(vty
, "%% VNI %u does not exist", vni
);
1671 n
= zvni_neigh_lookup(zvni
, ip
);
1673 vty_out(vty
, "%% Requested neighbor does not exist in VNI %u\n",
1678 zvni_print_neigh(n
, vty
);
1682 * Display neighbors for a VNI from specific VTEP (VTY command handler).
1683 * By definition, these are remote neighbors.
1685 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1686 vni_t vni
, struct in_addr vtep_ip
)
1689 u_int32_t num_neigh
;
1690 struct neigh_walk_ctx wctx
;
1692 if (!EVPN_ENABLED(zvrf
))
1694 zvni
= zvni_lookup(zvrf
, vni
);
1696 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1699 num_neigh
= hashcount(zvni
->neigh_table
);
1703 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1706 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
1707 wctx
.r_vtep_ip
= vtep_ip
;
1709 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
1713 * Display MACs for a VNI (VTY command handler).
1715 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1720 struct mac_walk_ctx wctx
;
1722 if (!EVPN_ENABLED(zvrf
))
1724 zvni
= zvni_lookup(zvrf
, vni
);
1726 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1729 num_macs
= hashcount(zvni
->mac_table
);
1733 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1738 "Number of MACs (local and remote) known for this VNI: %u\n",
1740 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
1741 "Intf/Remote VTEP", "VLAN");
1743 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
1747 * Display MACs for all VNIs (VTY command handler).
1749 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
)
1751 struct mac_walk_ctx wctx
;
1753 if (!EVPN_ENABLED(zvrf
))
1755 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1757 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
1761 * Display MACs for all VNIs (VTY command handler).
1763 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
1764 struct zebra_vrf
*zvrf
,
1765 struct in_addr vtep_ip
)
1767 struct mac_walk_ctx wctx
;
1769 if (!EVPN_ENABLED(zvrf
))
1771 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1773 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
1774 wctx
.r_vtep_ip
= vtep_ip
;
1775 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
1779 * Display specific MAC for a VNI, if present (VTY command handler).
1781 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1782 vni_t vni
, struct ethaddr
*macaddr
)
1787 if (!EVPN_ENABLED(zvrf
))
1789 zvni
= zvni_lookup(zvrf
, vni
);
1791 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1794 mac
= zvni_mac_lookup(zvni
, macaddr
);
1796 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
1801 zvni_print_mac(mac
, vty
);
1805 * Display MACs for a VNI from specific VTEP (VTY command handler).
1807 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1808 vni_t vni
, struct in_addr vtep_ip
)
1812 struct mac_walk_ctx wctx
;
1814 if (!EVPN_ENABLED(zvrf
))
1816 zvni
= zvni_lookup(zvrf
, vni
);
1818 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1821 num_macs
= hashcount(zvni
->mac_table
);
1824 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1827 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
1828 wctx
.r_vtep_ip
= vtep_ip
;
1829 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
1834 * Display VNI information (VTY command handler).
1836 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
)
1840 if (!EVPN_ENABLED(zvrf
))
1842 zvni
= zvni_lookup(zvrf
, vni
);
1844 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
1847 zvni_print(zvni
, (void *)vty
);
1851 * Display VNI hash table (VTY command handler).
1853 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
)
1857 if (!EVPN_ENABLED(zvrf
))
1859 num_vnis
= hashcount(zvrf
->vni_table
);
1862 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
1863 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI", "VxLAN IF",
1864 "VTEP IP", "# MACs", "# ARPs", "# Remote VTEPs");
1865 hash_iterate(zvrf
->vni_table
, zvni_print_hash
, vty
);
1869 * Handle neighbor delete (on a VLAN device / L3 interface) from the
1870 * kernel. This may result in either the neighbor getting deleted from
1871 * our database or being re-added to the kernel (if it is a valid
1874 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
1875 struct interface
*link_if
, struct ipaddr
*ip
)
1879 struct zebra_vrf
*zvrf
;
1880 char buf
[INET6_ADDRSTRLEN
];
1882 /* We are only interested in neighbors on an SVI that resides on top
1883 * of a VxLAN bridge.
1885 zvni
= zvni_map_svi(ifp
, link_if
);
1888 if (!zvni
->vxlan_if
) {
1890 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
1895 if (IS_ZEBRA_DEBUG_VXLAN
)
1896 zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
1897 ifp
->vrf_id
, ipaddr2str(ip
, buf
, sizeof(buf
)),
1898 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1900 /* If entry doesn't exist, nothing to do. */
1901 n
= zvni_neigh_lookup(zvni
, ip
);
1905 /* If it is a remote entry, the kernel has aged this out or someone has
1906 * deleted it, it needs to be re-installed as Quagga is the owner.
1908 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1909 zvni_neigh_install(zvni
, n
);
1913 /* Locate VRF corresponding to interface. */
1914 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1917 /* Remove neighbor from BGP. */
1918 zvni_neigh_send_del_to_client(zvrf
, zvni
->vni
, &n
->ip
, &n
->emac
);
1920 /* Delete this neighbor entry. */
1921 zvni_neigh_del(zvni
, n
);
1927 * Handle neighbor add or update (on a VLAN device / L3 interface)
1930 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
1931 struct interface
*link_if
,
1933 struct ethaddr
*macaddr
, u_int16_t state
,
1938 struct zebra_vrf
*zvrf
;
1939 char buf
[ETHER_ADDR_STRLEN
];
1940 char buf2
[INET6_ADDRSTRLEN
];
1941 int send_upd
= 1, send_del
= 0;
1943 /* We are only interested in neighbors on an SVI that resides on top
1944 * of a VxLAN bridge.
1946 zvni
= zvni_map_svi(ifp
, link_if
);
1950 /* Locate VRF corresponding to interface. */
1951 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
1954 if (IS_ZEBRA_DEBUG_VXLAN
)
1956 "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
1958 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1959 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
1960 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
1963 /* If same entry already exists, it might be a change or it might be a
1964 * move from remote to local.
1966 n
= zvni_neigh_lookup(zvni
, ip
);
1968 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1969 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
1972 if (n
->ifindex
== ifp
->ifindex
)
1973 /* we're not interested in whatever has
1976 /* client doesn't care about a purely local
1980 /* If the MAC has changed, issue a delete first
1982 * different MACIP route.
1985 } else if (ext_learned
)
1986 /* The neighbor is remote and that is the notification we got.
1989 /* TODO: Evaluate if we need to do anything here. */
1992 /* Neighbor has moved from remote to local. */
1994 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
1995 n
->r_vtep_ip
.s_addr
= 0;
1998 n
= zvni_neigh_add(zvni
, ip
);
2001 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2002 ifp
->vrf_id
, ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2003 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2004 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2009 /* Issue delete for older info, if needed. */
2011 zvni_neigh_send_del_to_client(zvrf
, zvni
->vni
, &n
->ip
,
2014 /* Set "local" forwarding info. */
2015 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2016 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2017 n
->ifindex
= ifp
->ifindex
;
2019 /* Inform BGP if required. */
2021 return zvni_neigh_send_add_to_client(zvrf
, zvni
->vni
, ip
,
2028 * Handle message from client to delete a remote MACIP for a VNI.
2030 int zebra_vxlan_remote_macip_del(struct zserv
*client
, int sock
, u_short length
,
2031 struct zebra_vrf
*zvrf
)
2035 struct ethaddr macaddr
;
2037 struct in_addr vtep_ip
;
2041 u_short l
= 0, ipa_len
;
2042 char buf
[ETHER_ADDR_STRLEN
];
2043 char buf1
[INET6_ADDRSTRLEN
];
2047 while (l
< length
) {
2048 /* Obtain each remote MACIP and process. */
2049 /* Message contains VNI, followed by MAC followed by IP (if any)
2050 * followed by remote VTEP IP.
2054 memset(&ip
, 0, sizeof(ip
));
2055 vni
= (vni_t
)stream_getl(s
);
2056 stream_get(&macaddr
.octet
, s
, ETH_ALEN
);
2057 ipa_len
= stream_getl(s
);
2059 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
2061 stream_get(&ip
.ip
.addr
, s
, ipa_len
);
2063 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
2064 vtep_ip
.s_addr
= stream_get_ipv4(s
);
2065 l
+= IPV4_MAX_BYTELEN
;
2067 if (IS_ZEBRA_DEBUG_VXLAN
)
2069 "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
2071 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
2072 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
2074 zebra_route_string(client
->proto
));
2076 /* Locate VNI hash entry - expected to exist. */
2077 zvni
= zvni_lookup(zvrf
, vni
);
2079 if (IS_ZEBRA_DEBUG_VXLAN
)
2081 "Failed to locate VNI hash upon remote MACIP DEL, "
2083 zvrf_id(zvrf
), vni
);
2086 if (!zvni
->vxlan_if
) {
2088 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
2093 /* The remote VTEP specified is normally expected to exist, but
2095 * possible that the peer may delete the VTEP before deleting
2097 * referring to the VTEP, in which case the handler (see
2099 * would have already deleted the MACs.
2101 if (!zvni_vtep_find(zvni
, &vtep_ip
))
2104 /* If the local VxLAN interface is not up (should be a transient
2105 * event), there's nothing more to do.
2107 if (!if_is_operative(zvni
->vxlan_if
))
2110 mac
= zvni_mac_lookup(zvni
, &macaddr
);
2112 n
= zvni_neigh_lookup(zvni
, &ip
);
2116 "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
2117 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
2118 ipaddr2str(&ip
, buf1
, sizeof(buf1
)),
2119 zvrf_id(zvrf
), vni
);
2123 /* If the remote mac or neighbor doesn't exist there is nothing
2125 * to do. Otherwise, uninstall the entry and then remove it.
2130 /* Uninstall remote neighbor or MAC. */
2132 /* When the MAC changes for an IP, it is possible the
2134 * update the new MAC before trying to delete the "old"
2136 * (as these are two different MACIP routes). Do the
2138 * if the MAC matches.
2140 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
2141 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
2144 zvni_neigh_uninstall(zvni
, n
);
2145 zvni_neigh_del(zvni
, n
);
2146 zvni_deref_ip2mac(zvni
, mac
, 1);
2149 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
2150 if (!mac
->neigh_refcnt
) {
2151 zvni_mac_uninstall(zvni
, mac
, 0);
2152 zvni_mac_del(zvni
, mac
);
2154 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
2163 * Handle message from client to add a remote MACIP for a VNI. This
2164 * could be just the add of a MAC address or the add of a neighbor
2167 int zebra_vxlan_remote_macip_add(struct zserv
*client
, int sock
, u_short length
,
2168 struct zebra_vrf
*zvrf
)
2172 struct ethaddr macaddr
;
2174 struct in_addr vtep_ip
;
2176 zebra_vtep_t
*zvtep
;
2177 zebra_mac_t
*mac
, *old_mac
;
2179 u_short l
= 0, ipa_len
;
2180 int update_mac
= 0, update_neigh
= 0;
2181 char buf
[ETHER_ADDR_STRLEN
];
2182 char buf1
[INET6_ADDRSTRLEN
];
2185 assert(EVPN_ENABLED(zvrf
));
2189 while (l
< length
) {
2190 /* Obtain each remote MACIP and process. */
2191 /* Message contains VNI, followed by MAC followed by IP (if any)
2192 * followed by remote VTEP IP.
2194 update_mac
= update_neigh
= 0;
2197 memset(&ip
, 0, sizeof(ip
));
2198 vni
= (vni_t
)stream_getl(s
);
2199 stream_get(&macaddr
.octet
, s
, ETH_ALEN
);
2200 ipa_len
= stream_getl(s
);
2202 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
2204 stream_get(&ip
.ip
.addr
, s
, ipa_len
);
2206 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
2207 vtep_ip
.s_addr
= stream_get_ipv4(s
);
2208 l
+= IPV4_MAX_BYTELEN
;
2210 /* Get 'sticky' flag. */
2211 sticky
= stream_getc(s
);
2214 if (IS_ZEBRA_DEBUG_VXLAN
)
2216 "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
2217 zvrf_id(zvrf
), sticky
? "sticky " : "",
2218 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
2219 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
2221 zebra_route_string(client
->proto
));
2223 /* Locate VNI hash entry - expected to exist. */
2224 zvni
= zvni_lookup(zvrf
, vni
);
2227 "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
2228 zvrf_id(zvrf
), vni
);
2231 if (!zvni
->vxlan_if
) {
2233 "VNI %u hash %p doesn't have intf upon remote MACIP add",
2237 /* If the local VxLAN interface is not up (should be a transient
2238 * event), there's nothing more to do.
2240 if (!if_is_operative(zvni
->vxlan_if
))
2243 /* The remote VTEP specified should normally exist, but it is
2245 * that when peering comes up, peer may advertise MACIP routes
2247 * advertising type-3 routes.
2249 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
2251 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
2253 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2254 zvrf_id(zvrf
), vni
, zvni
);
2258 zvni_vtep_install(zvni
, &vtep_ip
);
2261 /* First, check if the remote MAC is unknown or has a change. If
2263 * that needs to be updated first. Note that client could
2265 * MAC and MACIP separately or just install the latter.
2267 mac
= zvni_mac_lookup(zvni
, &macaddr
);
2268 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
2269 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
2271 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
2276 mac
= zvni_mac_add(zvni
, &macaddr
);
2279 "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
2281 prefix_mac2str(&macaddr
, buf
,
2283 vni
, inet_ntoa(vtep_ip
));
2287 /* Is this MAC created for a MACIP? */
2289 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
2290 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
2291 /* Moving from local to remote, issue delete. */
2292 zvni_mac_uninstall(zvni
, mac
, 1);
2295 /* Set "auto" and "remote" forwarding info. */
2296 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
2297 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
2298 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
2299 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
2302 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
2304 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
2306 /* Install the entry. */
2307 zvni_mac_install(zvni
, mac
);
2310 /* If there is no IP, continue - after clearing AUTO flag of
2313 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
2317 /* Check if the remote neighbor itself is unknown or has a
2319 * If so, create or update and then install the entry.
2321 n
= zvni_neigh_lookup(zvni
, &ip
);
2322 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
2323 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
2324 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
2329 n
= zvni_neigh_add(zvni
, &ip
);
2332 "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2334 ipaddr2str(&ip
, buf1
,
2336 prefix_mac2str(&macaddr
, buf
,
2338 vni
, inet_ntoa(vtep_ip
));
2342 /* New neighbor referring to this MAC. */
2343 mac
->neigh_refcnt
++;
2344 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
2346 /* MAC change, update ref counts for old and new
2348 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
2350 zvni_deref_ip2mac(zvni
, old_mac
, 1);
2351 mac
->neigh_refcnt
++;
2354 /* Set "remote" forwarding info. */
2355 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2356 /* TODO: Handle MAC change. */
2357 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
2358 n
->r_vtep_ip
= vtep_ip
;
2359 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2361 /* Install the entry. */
2362 zvni_neigh_install(zvni
, n
);
2370 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
2371 * us, this must involve a multihoming scenario. Treat this as implicit delete
2372 * of any prior local MAC.
2374 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
2375 struct interface
*br_if
,
2376 struct ethaddr
*macaddr
, vlanid_t vid
)
2378 struct zebra_if
*zif
;
2379 struct zebra_vrf
*zvrf
;
2380 struct zebra_l2info_vxlan
*vxl
;
2384 char buf
[ETHER_ADDR_STRLEN
];
2389 vxl
= &zif
->l2info
.vxl
;
2392 /* Locate VRF corresponding to interface. */
2393 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2396 /* If EVPN is not enabled, nothing to do. */
2397 if (!EVPN_ENABLED(zvrf
))
2400 /* Locate hash entry; it is expected to exist. */
2401 zvni
= zvni_lookup(zvrf
, vni
);
2405 /* If entry doesn't exist, nothing to do. */
2406 mac
= zvni_mac_lookup(zvni
, macaddr
);
2410 /* Is it a local entry? */
2411 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
2414 if (IS_ZEBRA_DEBUG_VXLAN
)
2416 "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
2417 ifp
->vrf_id
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2418 ifp
->name
, ifp
->ifindex
, vni
);
2420 /* Remove MAC from BGP. */
2421 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2422 zvni_mac_send_del_to_client(zvrf
, zvni
->vni
, macaddr
, sticky
);
2424 /* Delete this MAC entry. */
2425 zvni_mac_del(zvni
, mac
);
2431 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
2432 * This can happen because the remote MAC entries are also added as "dynamic",
2433 * so the kernel can ageout the entry.
2435 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
2436 struct interface
*br_if
,
2437 struct ethaddr
*macaddr
, vlanid_t vid
)
2439 struct zebra_if
*zif
;
2440 struct zebra_vrf
*zvrf
;
2441 struct zebra_l2info_vxlan
*vxl
;
2445 char buf
[ETHER_ADDR_STRLEN
];
2449 vxl
= &zif
->l2info
.vxl
;
2452 /* Locate VRF corresponding to interface. */
2453 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2456 /* If EVPN is not enabled, nothing to do. */
2457 if (!EVPN_ENABLED(zvrf
))
2460 /* Locate hash entry; it is expected to exist. */
2461 zvni
= zvni_lookup(zvrf
, vni
);
2465 /* If entry doesn't exist, nothing to do. */
2466 mac
= zvni_mac_lookup(zvni
, macaddr
);
2470 /* Is it a remote entry? */
2471 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2474 if (IS_ZEBRA_DEBUG_VXLAN
)
2475 zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
2477 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
2480 zvni_mac_install(zvni
, mac
);
2485 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
2487 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
2488 struct ethaddr
*macaddr
, vlanid_t vid
)
2492 struct zebra_vrf
*zvrf
;
2493 char buf
[ETHER_ADDR_STRLEN
];
2496 /* We are interested in MACs only on ports or (port, VLAN) that
2499 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
2502 if (!zvni
->vxlan_if
) {
2503 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
2508 if (IS_ZEBRA_DEBUG_VXLAN
)
2509 zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
2511 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
2512 ifp
->ifindex
, vid
, zvni
->vni
);
2514 /* If entry doesn't exist, nothing to do. */
2515 mac
= zvni_mac_lookup(zvni
, macaddr
);
2519 /* Is it a local entry? */
2520 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
2523 /* Locate VRF corresponding to interface. */
2524 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
2527 /* Remove MAC from BGP. */
2528 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2529 zvni_mac_send_del_to_client(zvrf
, zvni
->vni
, macaddr
, sticky
);
2531 /* Delete this MAC entry. */
2532 zvni_mac_del(zvni
, mac
);
2538 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
2540 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
2541 struct interface
*br_if
,
2542 struct ethaddr
*macaddr
, vlanid_t vid
,
2547 struct zebra_vrf
*zvrf
;
2548 char buf
[ETHER_ADDR_STRLEN
];
2552 /* We are interested in MACs only on ports or (port, VLAN) that
2555 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
2557 if (IS_ZEBRA_DEBUG_VXLAN
)
2559 "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
2560 ifp
->vrf_id
, sticky
? "sticky " : "",
2561 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2562 ifp
->name
, ifp
->ifindex
, vid
);
2566 if (!zvni
->vxlan_if
) {
2567 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
2572 if (IS_ZEBRA_DEBUG_VXLAN
)
2574 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
2575 ifp
->vrf_id
, sticky
? "sticky " : "",
2576 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
2577 ifp
->ifindex
, vid
, zvni
->vni
);
2579 /* If same entry already exists, nothing to do. */
2580 mac
= zvni_mac_lookup(zvni
, macaddr
);
2582 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
2583 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
2587 if (mac_sticky
== sticky
2588 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
2589 && mac
->fwd_info
.local
.vid
== vid
) {
2590 if (IS_ZEBRA_DEBUG_VXLAN
)
2592 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
2593 "entry exists and has not changed ",
2595 sticky
? "sticky " : "",
2596 prefix_mac2str(macaddr
, buf
,
2598 ifp
->name
, ifp
->ifindex
, vid
,
2603 add
= 0; /* This is an update of local interface. */
2607 /* Locate VRF corresponding to interface. */
2608 zvrf
= vrf_info_lookup(zvni
->vxlan_if
->vrf_id
);
2612 mac
= zvni_mac_add(zvni
, macaddr
);
2614 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
2616 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2617 ifp
->name
, ifp
->ifindex
, vid
);
2622 /* Set "local" forwarding info. */
2623 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
2624 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
2625 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
2626 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
2627 mac
->fwd_info
.local
.vid
= vid
;
2630 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
2632 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
2634 /* Inform BGP if required. */
2636 return zvni_mac_send_add_to_client(zvrf
, zvni
->vni
, macaddr
,
2643 * Handle message from client to delete a remote VTEP for a VNI.
2645 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, int sock
, u_short length
,
2646 struct zebra_vrf
*zvrf
)
2651 struct in_addr vtep_ip
;
2653 zebra_vtep_t
*zvtep
;
2657 while (l
< length
) {
2658 /* Obtain each remote VTEP and process. */
2659 vni
= (vni_t
)stream_getl(s
);
2661 vtep_ip
.s_addr
= stream_get_ipv4(s
);
2662 l
+= IPV4_MAX_BYTELEN
;
2664 if (IS_ZEBRA_DEBUG_VXLAN
)
2665 zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
2666 zvrf_id(zvrf
), inet_ntoa(vtep_ip
), vni
,
2667 zebra_route_string(client
->proto
));
2669 /* Locate VNI hash entry - expected to exist. */
2670 zvni
= zvni_lookup(zvrf
, vni
);
2672 if (IS_ZEBRA_DEBUG_VXLAN
)
2674 "Failed to locate VNI hash upon remote VTEP DEL, "
2676 zvrf_id(zvrf
), vni
);
2680 /* If the remote VTEP does not exist, there's nothing more to
2682 * Otherwise, uninstall any remote MACs pointing to this VTEP
2684 * then, the VTEP entry itself and remove it.
2686 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
2690 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
2691 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
2692 zvni_vtep_uninstall(zvni
, &vtep_ip
);
2693 zvni_vtep_del(zvni
, zvtep
);
2700 * Handle message from client to add a remote VTEP for a VNI.
2702 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, int sock
, u_short length
,
2703 struct zebra_vrf
*zvrf
)
2708 struct in_addr vtep_ip
;
2711 assert(EVPN_ENABLED(zvrf
));
2715 while (l
< length
) {
2716 /* Obtain each remote VTEP and process. */
2717 vni
= (vni_t
)stream_getl(s
);
2719 vtep_ip
.s_addr
= stream_get_ipv4(s
);
2720 l
+= IPV4_MAX_BYTELEN
;
2722 if (IS_ZEBRA_DEBUG_VXLAN
)
2723 zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
2724 zvrf_id(zvrf
), inet_ntoa(vtep_ip
), vni
,
2725 zebra_route_string(client
->proto
));
2727 /* Locate VNI hash entry - expected to exist. */
2728 zvni
= zvni_lookup(zvrf
, vni
);
2731 "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
2732 zvrf_id(zvrf
), vni
);
2735 if (!zvni
->vxlan_if
) {
2737 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
2743 /* If the remote VTEP already exists, or the local VxLAN
2745 * not up (should be a transient event), there's nothing more
2747 * Otherwise, add and install the entry.
2749 if (zvni_vtep_find(zvni
, &vtep_ip
))
2752 if (!if_is_operative(zvni
->vxlan_if
))
2755 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
2757 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2758 zvrf_id(zvrf
), vni
, zvni
);
2762 zvni_vtep_install(zvni
, &vtep_ip
);
2769 * Handle SVI interface going down. At this point, this is a NOP since
2770 * the kernel deletes the neighbor entries on this SVI (if any).
2772 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
2778 * Handle SVI interface coming up. This may or may not be of interest,
2779 * but if this is a SVI on a VxLAN bridge, we need to install any remote
2780 * neighbor entries (which will be used for EVPN ARP suppression).
2782 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
2785 struct neigh_walk_ctx n_wctx
;
2787 zvni
= zvni_map_svi(ifp
, link_if
);
2791 if (!zvni
->vxlan_if
) {
2792 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
2797 if (IS_ZEBRA_DEBUG_VXLAN
)
2798 zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
2799 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2801 /* Install any remote neighbors for this VNI. */
2802 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
2804 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
, &n_wctx
);
2810 * Handle VxLAN interface down - update BGP if required, and do
2813 int zebra_vxlan_if_down(struct interface
*ifp
)
2815 struct zebra_if
*zif
;
2816 struct zebra_vrf
*zvrf
;
2818 struct zebra_l2info_vxlan
*vxl
;
2821 /* Locate VRF corresponding to interface. */
2822 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2825 /* If EVPN is not enabled, nothing further to be done. */
2826 if (!EVPN_ENABLED(zvrf
))
2831 vxl
= &zif
->l2info
.vxl
;
2834 if (IS_ZEBRA_DEBUG_VXLAN
)
2835 zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp
->vrf_id
,
2836 ifp
->name
, ifp
->ifindex
, vni
);
2838 /* Locate hash entry; it is expected to exist. */
2839 zvni
= zvni_lookup(zvrf
, vni
);
2842 "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
2843 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
2847 assert(zvni
->vxlan_if
== ifp
);
2849 /* Delete this VNI from BGP. */
2850 zvni_send_del_to_client(zvrf
, zvni
->vni
);
2852 /* Free up all neighbors and MACs, if any. */
2853 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
2854 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
2856 /* Free up all remote VTEPs, if any. */
2857 zvni_vtep_del_all(zvni
, 1);
2863 * Handle VxLAN interface up - update BGP if required.
2865 int zebra_vxlan_if_up(struct interface
*ifp
)
2867 struct zebra_if
*zif
;
2868 struct zebra_vrf
*zvrf
;
2870 struct zebra_l2info_vxlan
*vxl
;
2873 /* Locate VRF corresponding to interface. */
2874 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2877 /* If EVPN is not enabled, nothing further to be done. */
2878 if (!EVPN_ENABLED(zvrf
))
2883 vxl
= &zif
->l2info
.vxl
;
2886 if (IS_ZEBRA_DEBUG_VXLAN
)
2887 zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp
->vrf_id
,
2888 ifp
->name
, ifp
->ifindex
, vni
);
2890 /* Locate hash entry; it is expected to exist. */
2891 zvni
= zvni_lookup(zvrf
, vni
);
2894 "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
2895 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
2899 assert(zvni
->vxlan_if
== ifp
);
2901 /* If part of a bridge, inform BGP about this VNI. */
2902 /* Also, read and populate local MACs and neighbors. */
2903 if (zif
->brslave_info
.br_if
) {
2904 zvni_send_add_to_client(zvrf
, zvni
);
2905 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
2912 * Handle VxLAN interface delete. Locate and remove entry in hash table
2913 * and update BGP, if required.
2915 int zebra_vxlan_if_del(struct interface
*ifp
)
2917 struct zebra_if
*zif
;
2918 struct zebra_vrf
*zvrf
;
2920 struct zebra_l2info_vxlan
*vxl
;
2923 /* Locate VRF corresponding to interface. */
2924 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2927 /* If EVPN is not enabled, nothing further to be done. */
2928 if (!EVPN_ENABLED(zvrf
))
2933 vxl
= &zif
->l2info
.vxl
;
2936 if (IS_ZEBRA_DEBUG_VXLAN
)
2937 zlog_debug("%u:Del VNI %u intf %s(%u)", ifp
->vrf_id
, vni
,
2938 ifp
->name
, ifp
->ifindex
);
2940 /* Locate hash entry; it is expected to exist. */
2941 zvni
= zvni_lookup(zvrf
, vni
);
2944 "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
2945 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
2949 /* Delete VNI from BGP. */
2950 zvni_send_del_to_client(zvrf
, zvni
->vni
);
2952 /* Free up all neighbors and MAC, if any. */
2953 zvni_neigh_del_all(zvrf
, zvni
, 0, 0, DEL_ALL_NEIGH
);
2954 zvni_mac_del_all(zvrf
, zvni
, 0, 0, DEL_ALL_MAC
);
2956 /* Free up all remote VTEPs, if any. */
2957 zvni_vtep_del_all(zvni
, 0);
2959 /* Delete the hash entry. */
2960 if (zvni_del(zvrf
, zvni
)) {
2961 zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
2962 zvni
, ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2970 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
2972 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
2974 struct zebra_if
*zif
;
2975 struct zebra_vrf
*zvrf
;
2977 struct zebra_l2info_vxlan
*vxl
;
2980 /* Locate VRF corresponding to interface. */
2981 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
2984 /* If EVPN is not enabled, nothing further to be done. */
2985 if (!EVPN_ENABLED(zvrf
))
2990 vxl
= &zif
->l2info
.vxl
;
2993 /* Update VNI hash. */
2994 zvni
= zvni_lookup(zvrf
, vni
);
2997 "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
2998 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
3002 if (IS_ZEBRA_DEBUG_VXLAN
)
3004 "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
3005 "master %u chg 0x%x",
3006 ifp
->vrf_id
, vni
, ifp
->name
, ifp
->ifindex
,
3007 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
3008 zif
->brslave_info
.bridge_ifindex
, chgflags
);
3010 /* Removed from bridge? */
3011 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
3012 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
3013 /* Delete from client, remove all remote VTEPs */
3014 /* Also, free up all MACs and neighbors. */
3015 zvni_send_del_to_client(zvrf
, zvni
->vni
);
3016 zvni_neigh_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_NEIGH
);
3017 zvni_mac_del_all(zvrf
, zvni
, 1, 0, DEL_ALL_MAC
);
3018 zvni_vtep_del_all(zvni
, 1);
3019 } else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
3020 /* Remove all existing local neighbors and MACs for this VNI
3021 * (including from BGP)
3023 zvni_neigh_del_all(zvrf
, zvni
, 0, 1, DEL_LOCAL_MAC
);
3024 zvni_mac_del_all(zvrf
, zvni
, 0, 1, DEL_LOCAL_MAC
);
3027 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
3028 zvni
->vxlan_if
= ifp
;
3030 /* Take further actions needed. Note that if we are here, there is a
3031 * change of interest.
3033 /* If down or not mapped to a bridge, we're done. */
3034 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3037 /* Inform BGP, if there is a change of interest. */
3039 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
3040 zvni_send_add_to_client(zvrf
, zvni
);
3042 /* If there is a valid new master or a VLAN mapping change, read and
3043 * populate local MACs and neighbors. Also, reinstall any remote MACs
3044 * and neighbors for this VNI (based on new VLAN).
3046 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
3047 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
3048 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
3049 struct mac_walk_ctx m_wctx
;
3050 struct neigh_walk_ctx n_wctx
;
3052 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
3054 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
3056 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
, &m_wctx
);
3058 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
3060 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
3068 * Handle VxLAN interface add.
3070 int zebra_vxlan_if_add(struct interface
*ifp
)
3072 struct zebra_if
*zif
;
3073 struct zebra_vrf
*zvrf
;
3075 struct zebra_l2info_vxlan
*vxl
;
3078 /* Locate VRF corresponding to interface. */
3079 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
3082 /* If EVPN is not enabled, nothing further to be done. */
3083 if (!EVPN_ENABLED(zvrf
))
3088 vxl
= &zif
->l2info
.vxl
;
3091 if (IS_ZEBRA_DEBUG_VXLAN
)
3093 "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
3094 ifp
->vrf_id
, vni
, ifp
->name
, ifp
->ifindex
,
3095 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
3096 zif
->brslave_info
.bridge_ifindex
);
3098 /* Create or update VNI hash. */
3099 zvni
= zvni_lookup(zvrf
, vni
);
3101 zvni
= zvni_add(zvrf
, vni
);
3104 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
3105 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, vni
);
3110 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
3111 zvni
->vxlan_if
= ifp
;
3113 /* If down or not mapped to a bridge, we're done. */
3114 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
3118 zvni_send_add_to_client(zvrf
, zvni
);
3120 /* Read and populate local MACs and neighbors */
3121 zvni_read_mac_neigh(zvrf
, zvni
, ifp
);
3127 * Handle message from client to learn (or stop learning) about VNIs and MACs.
3128 * When enabled, the VNI hash table will be built and MAC FDB table read;
3129 * when disabled, the entries should be deleted and remote VTEPs and MACs
3130 * uninstalled from the kernel.
3132 int zebra_vxlan_advertise_all_vni(struct zserv
*client
, int sock
,
3133 u_short length
, struct zebra_vrf
*zvrf
)
3139 advertise
= stream_getc(s
);
3141 if (IS_ZEBRA_DEBUG_VXLAN
)
3142 zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf
),
3143 advertise
? "enabled" : "disabled",
3144 EVPN_ENABLED(zvrf
) ? "enabled" : "disabled");
3146 if (zvrf
->advertise_all_vni
== advertise
)
3149 zvrf
->advertise_all_vni
= advertise
;
3150 if (EVPN_ENABLED(zvrf
)) {
3151 /* Build VNI hash table and inform BGP. */
3152 zvni_build_hash_table(zvrf
);
3154 /* Read the MAC FDB */
3155 macfdb_read(zvrf
->zns
);
3157 /* Read neighbors */
3158 neigh_read(zvrf
->zns
);
3160 /* Cleanup VTEPs for all VNIs - uninstall from
3161 * kernel and free entries.
3163 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
3170 * Allocate VNI hash table for this VRF and do other initialization.
3171 * NOTE: Currently supported only for default VRF.
3173 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
3177 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
3178 "Zebra VRF VNI Table");
3181 /* Close all VNI handling */
3182 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
3184 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);