2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 #include "zebra/rib.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
51 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
54 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
55 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
60 /* static function declarations */
61 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
62 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
63 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
65 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
66 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
67 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
68 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
69 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
71 static int zvni_macip_send_msg_to_client(vni_t vni
,
72 struct ethaddr
*macaddr
,
73 struct ipaddr
*ip
, u_char flags
,
75 static unsigned int neigh_hash_keymake(void *p
);
76 static int neigh_cmp(const void *p1
, const void *p2
);
77 static void *zvni_neigh_alloc(void *p
);
78 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
80 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
81 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
82 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
83 struct in_addr
*r_vtep_ip
);
84 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
85 int uninstall
, int upd_client
, u_int32_t flags
);
86 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
87 static int zvni_neigh_send_add_to_client(vni_t vni
,
89 struct ethaddr
*macaddr
, u_char flags
);
90 static int zvni_neigh_send_del_to_client(vni_t vni
,
92 struct ethaddr
*macaddr
, u_char flags
);
93 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
94 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
95 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
96 struct interface
*br_if
);
97 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
98 struct interface
*br_if
);
100 /* l3-vni next-hop neigh related APIs */
101 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
103 static void *zl3vni_nh_alloc(void *p
);
104 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
105 struct ipaddr
*vtep_ip
,
106 struct ethaddr
*rmac
);
107 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
108 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
109 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
111 /* l3-vni rmac related APIs */
112 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
113 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*, void *);
114 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
115 struct ethaddr
*rmac
);
116 static void *zl3vni_rmac_alloc(void *p
);
117 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
118 struct ethaddr
*rmac
);
119 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
120 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
121 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
124 /* l3-vni related APIs*/
125 static int is_vni_l3(vni_t
);
126 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
127 static void *zl3vni_alloc(void *p
);
128 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
129 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
130 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
131 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
);
132 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
133 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
134 static void zvni_get_rmac(zebra_vni_t
*zvni
, struct ethaddr
*rmac
);
135 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
136 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
138 static unsigned int mac_hash_keymake(void *p
);
139 static int mac_cmp(const void *p1
, const void *p2
);
140 static void *zvni_mac_alloc(void *p
);
141 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
142 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
143 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
144 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
145 struct in_addr
*r_vtep_ip
);
146 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
147 int uninstall
, int upd_client
, u_int32_t flags
);
148 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
149 static int zvni_mac_send_add_to_client(vni_t vni
,
150 struct ethaddr
*macaddr
, u_char flags
);
151 static int zvni_mac_send_del_to_client(vni_t vni
,
152 struct ethaddr
*macaddr
, u_char flags
);
153 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
154 struct interface
*br_if
, vlanid_t vid
);
155 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
156 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
157 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
159 static unsigned int vni_hash_keymake(void *p
);
160 static int vni_hash_cmp(const void *p1
, const void *p2
);
161 static void *zvni_alloc(void *p
);
162 static zebra_vni_t
*zvni_lookup(vni_t vni
);
163 static zebra_vni_t
*zvni_add(vni_t vni
);
164 static int zvni_del(zebra_vni_t
*zvni
);
165 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
166 static int zvni_send_del_to_client(vni_t vni
);
167 static void zvni_build_hash_table();
168 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
169 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
170 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
171 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
172 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
173 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
174 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
175 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
176 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
177 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
178 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
179 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
181 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
182 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
183 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
186 /* Private functions */
189 * Return number of valid MACs in a VNI's MAC hash table - all
190 * remote MACs and non-internal (auto) local MACs count.
192 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
195 u_int32_t num_macs
= 0;
197 struct hash_backet
*hb
;
200 hash
= zvni
->mac_table
;
203 for (i
= 0; i
< hash
->size
; i
++) {
204 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
205 mac
= (zebra_mac_t
*)hb
->data
;
206 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
207 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
215 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
217 struct zebra_vrf
*zvrf
;
219 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
220 if (zvrf
&& zvrf
->advertise_gw_macip
)
223 if (zvni
&& zvni
->advertise_gw_macip
)
230 * Helper function to determine maximum width of neighbor IP address for
231 * display - just because we're dealing with IPv6 addresses that can
234 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
237 char buf
[INET6_ADDRSTRLEN
];
238 struct neigh_walk_ctx
*wctx
= ctxt
;
241 n
= (zebra_neigh_t
*)backet
->data
;
245 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
246 if (width
> wctx
->addr_width
)
247 wctx
->addr_width
= width
;
251 * Print a specific neighbor entry.
253 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
256 char buf1
[ETHER_ADDR_STRLEN
];
257 char buf2
[INET6_ADDRSTRLEN
];
259 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
260 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
261 vty
= (struct vty
*)ctxt
;
263 vty_out(vty
, "IP: %s\n",
264 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
265 vty_out(vty
, " MAC: %s",
266 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
268 json_object_string_add(json
, "ip", buf2
);
269 json_object_string_add(json
, "mac", buf1
);
271 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
273 vty_out(vty
, " Remote VTEP: %s",
274 inet_ntoa(n
->r_vtep_ip
));
276 json_object_string_add(json
, "remoteVtep",
277 inet_ntoa(n
->r_vtep_ip
));
279 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
282 vty_out(vty
, " State: %s",
283 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
292 * Print neighbor hash entry - called for display of all neighbors.
294 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
297 json_object
*json_vni
= NULL
, *json_row
= NULL
;
299 char buf1
[ETHER_ADDR_STRLEN
];
300 char buf2
[INET6_ADDRSTRLEN
];
301 struct neigh_walk_ctx
*wctx
= ctxt
;
304 json_vni
= wctx
->json
;
305 n
= (zebra_neigh_t
*)backet
->data
;
310 json_row
= json_object_new_object();
312 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
313 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
314 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
315 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
316 if (json_vni
== NULL
) {
317 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
318 buf2
, "local", buf1
);
320 json_object_string_add(json_row
, "type", "local");
321 json_object_string_add(json_row
, "mac", buf1
);
325 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
326 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
327 if (json_vni
== NULL
) {
328 if (wctx
->count
== 0)
330 "%*s %-6s %-17s %-21s\n",
333 "MAC", "Remote VTEP");
334 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
335 -wctx
->addr_width
, buf2
,
337 inet_ntoa(n
->r_vtep_ip
));
339 json_object_string_add(json_row
, "type",
341 json_object_string_add(json_row
, "mac",
343 json_object_string_add(
344 json_row
, "remoteVtep",
345 inet_ntoa(n
->r_vtep_ip
));
350 if (json_vni
== NULL
) {
351 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
352 -wctx
->addr_width
, buf2
, "remote", buf1
,
353 inet_ntoa(n
->r_vtep_ip
));
355 json_object_string_add(json_row
, "type",
357 json_object_string_add(json_row
, "mac", buf1
);
358 json_object_string_add(json_row
, "remoteVtep",
359 inet_ntoa(n
->r_vtep_ip
));
366 json_object_object_add(json_vni
, buf2
, json_row
);
370 * Print neighbors for all VNI.
372 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
376 json_object
*json
= NULL
, *json_vni
= NULL
;
379 struct neigh_walk_ctx wctx
;
380 char vni_str
[VNI_STR_LEN
];
382 vty
= (struct vty
*)args
[0];
383 json
= (json_object
*)args
[1];
385 zvni
= (zebra_vni_t
*)backet
->data
;
388 vty_out(vty
, "{}\n");
391 num_neigh
= hashcount(zvni
->neigh_table
);
394 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
395 zvni
->vni
, num_neigh
);
397 json_vni
= json_object_new_object();
398 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
399 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
403 json_object_object_add(json
, vni_str
, json_vni
);
407 /* Since we have IPv6 addresses to deal with which can vary widely in
408 * size, we try to be a bit more elegant in display by first computing
411 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
414 wctx
.addr_width
= 15;
415 wctx
.json
= json_vni
;
416 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
419 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
420 "Type", "MAC", "Remote VTEP");
421 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
424 json_object_object_add(json
, vni_str
, json_vni
);
428 * Print a specific MAC entry.
430 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
433 zebra_neigh_t
*n
= NULL
;
434 struct listnode
*node
= NULL
;
436 char buf2
[INET6_ADDRSTRLEN
];
438 vty
= (struct vty
*)ctxt
;
439 vty_out(vty
, "MAC: %s",
440 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
441 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
442 struct zebra_ns
*zns
;
443 struct interface
*ifp
;
446 ifindex
= mac
->fwd_info
.local
.ifindex
;
447 zns
= zebra_ns_lookup(NS_DEFAULT
);
448 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
449 if (!ifp
) // unexpected
451 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
452 if (mac
->fwd_info
.local
.vid
)
453 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
454 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
455 vty_out(vty
, " Remote VTEP: %s",
456 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
457 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
458 vty_out(vty
, " Auto Mac ");
462 /* print all the associated neigh */
463 vty_out(vty
, " Neighbors:\n");
464 if (!listcount(mac
->neigh_list
))
465 vty_out(vty
, " No Neighbors\n");
467 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
468 vty_out(vty
, " %s %s\n",
469 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
470 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
471 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
482 * Print MAC hash entry - called for display of all MACs.
484 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
487 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
490 struct mac_walk_ctx
*wctx
= ctxt
;
493 json_mac_hdr
= wctx
->json
;
494 mac
= (zebra_mac_t
*)backet
->data
;
498 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
501 json_mac
= json_object_new_object();
503 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
504 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
505 struct zebra_ns
*zns
;
507 struct interface
*ifp
;
510 zns
= zebra_ns_lookup(NS_DEFAULT
);
511 ifindex
= mac
->fwd_info
.local
.ifindex
;
512 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
513 if (!ifp
) // unexpected
515 vid
= mac
->fwd_info
.local
.vid
;
516 if (json_mac_hdr
== NULL
)
517 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
520 json_object_string_add(json_mac
, "type", "local");
521 json_object_string_add(json_mac
, "intf", ifp
->name
);
524 if (json_mac_hdr
== NULL
)
525 vty_out(vty
, " %-5u", vid
);
527 json_object_int_add(json_mac
, "vlan", vid
);
529 if (json_mac_hdr
== NULL
)
532 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
534 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
535 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
536 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
538 if (wctx
->count
== 0) {
539 if (json_mac_hdr
== NULL
) {
540 vty_out(vty
, "\nVNI %u\n\n",
543 "%-17s %-6s %-21s %-5s\n",
549 if (json_mac_hdr
== NULL
)
550 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
552 inet_ntoa(mac
->fwd_info
555 json_object_string_add(json_mac
, "type",
557 json_object_string_add(
558 json_mac
, "remoteVtep",
559 inet_ntoa(mac
->fwd_info
561 json_object_object_add(json_mac_hdr
,
567 if (json_mac_hdr
== NULL
)
568 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
570 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
572 json_object_string_add(json_mac
, "type",
574 json_object_string_add(
575 json_mac
, "remoteVtep",
576 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
577 json_object_object_add(json_mac_hdr
, buf1
,
586 * Print MACs for all VNI.
588 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
591 json_object
*json
= NULL
, *json_vni
= NULL
;
592 json_object
*json_mac
= NULL
;
595 struct mac_walk_ctx
*wctx
= ctxt
;
596 char vni_str
[VNI_STR_LEN
];
598 vty
= (struct vty
*)wctx
->vty
;
599 json
= (struct json_object
*)wctx
->json
;
601 zvni
= (zebra_vni_t
*)backet
->data
;
604 vty_out(vty
, "{}\n");
609 /*We are iterating over a new VNI, set the count to 0*/
612 num_macs
= num_valid_macs(zvni
);
617 json_vni
= json_object_new_object();
618 json_mac
= json_object_new_object();
619 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
622 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
624 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
625 zvni
->vni
, num_macs
);
626 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
627 "Intf/Remote VTEP", "VLAN");
629 json_object_int_add(json_vni
, "numMacs", num_macs
);
631 /* assign per-vni to wctx->json object to fill macs
632 * under the vni. Re-assign primary json object to fill
633 * next vni information.
635 wctx
->json
= json_mac
;
636 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
640 json_object_object_add(json_vni
, "macs", json_mac
);
641 json_object_object_add(json
, vni_str
, json_vni
);
645 static void zl3vni_print_nh_hash(struct hash_backet
*backet
,
648 struct nh_walk_ctx
*wctx
= NULL
;
649 struct vty
*vty
= NULL
;
650 struct json_object
*json
= NULL
;
651 struct json_object
*json_nh
= NULL
;
652 zebra_neigh_t
*n
= NULL
;
653 char buf1
[ETHER_ADDR_STRLEN
];
654 char buf2
[INET6_ADDRSTRLEN
];
656 wctx
= (struct nh_walk_ctx
*)ctx
;
660 json_nh
= json_object_new_object();
661 n
= (zebra_neigh_t
*)backet
->data
;
666 vty_out(vty
, "%-15s %-17s %6d\n",
667 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
668 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
671 json_object_string_add(json_nh
, "vtep-ip",
672 inet_ntoa(n
->r_vtep_ip
));
673 json_object_string_add(json_nh
, "rmac",
674 prefix_mac2str(&n
->emac
, buf1
,
676 json_object_int_add(json_nh
, "refCnt", n
->nh_refcnt
);
680 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
683 struct vty
*vty
= NULL
;
684 json_object
*json
= NULL
;
685 json_object
*json_vni
= NULL
;
686 json_object
*json_nh
= NULL
;
687 zebra_l3vni_t
*zl3vni
= NULL
;
689 struct nh_walk_ctx
*wctx
= NULL
;
690 char vni_str
[VNI_STR_LEN
];
692 wctx
= (struct nh_walk_ctx
*)ctx
;
693 vty
= (struct vty
*)wctx
->vty
;
694 json
= (struct json_object
*)wctx
->json
;
696 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
699 vty_out(vty
, "{}\n");
703 num_nh
= hashcount(zl3vni
->nh_table
);
708 json_vni
= json_object_new_object();
709 json_nh
= json_object_new_array();
710 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
714 vty_out(vty
, "\nVNI %u #Next-Hopss %u\n\n",
715 zl3vni
->vni
, num_nh
);
716 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
717 "Remote VTEP", "Refcnt");
718 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
721 json_object_int_add(json_vni
, "numNh", num_nh
);
723 wctx
->json
= json_nh
;
724 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, wctx
);
727 json_object_object_add(json_vni
, "nh", json_nh
);
728 json_object_object_add(json
, vni_str
, json_vni
);
732 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
735 struct vty
*vty
= NULL
;
736 json_object
*json
= NULL
;
737 json_object
*json_vni
= NULL
;
738 json_object
*json_mac
= NULL
;
739 zebra_l3vni_t
*zl3vni
= NULL
;
741 struct rmac_walk_ctx
*wctx
= NULL
;
742 char vni_str
[VNI_STR_LEN
];
744 wctx
= (struct rmac_walk_ctx
*)ctx
;
745 vty
= (struct vty
*)wctx
->vty
;
746 json
= (struct json_object
*)wctx
->json
;
748 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
751 vty_out(vty
, "{}\n");
755 num_rmacs
= hashcount(zl3vni
->rmac_table
);
760 json_vni
= json_object_new_object();
761 json_mac
= json_object_new_array();
762 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
766 vty_out(vty
, "\nVNI %u #MACs %u\n\n",
767 zl3vni
->vni
, num_rmacs
);
768 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
769 "Remote VTEP", "Refcnt");
771 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
773 /* assign per-vni to wctx->json object to fill macs
774 * under the vni. Re-assign primary json object to fill
775 * next vni information.
777 wctx
->json
= json_mac
;
778 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, wctx
);
781 json_object_object_add(json_vni
, "rmacs", json_mac
);
782 json_object_object_add(json
, vni_str
, json_vni
);
786 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
,
789 zebra_mac_t
*zrmac
= NULL
;
790 struct rmac_walk_ctx
*wctx
= NULL
;
791 struct vty
*vty
= NULL
;
792 struct json_object
*json
= NULL
;
793 struct json_object
*json_rmac
= NULL
;
794 char buf
[ETHER_ADDR_STRLEN
];
796 wctx
= (struct rmac_walk_ctx
*)ctx
;
800 json_rmac
= json_object_new_object();
801 zrmac
= (zebra_mac_t
*)backet
->data
;
806 vty_out(vty
, "%-17s %-21s %-6d\n",
807 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
808 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
),
811 json_object_string_add(json_rmac
, "rmac",
812 prefix_mac2str(&zrmac
->macaddr
, buf
,
814 json_object_string_add(json_rmac
, "vtep-ip",
815 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
816 json_object_int_add(json_rmac
, "refcnt", zrmac
->rmac_refcnt
);
817 json_object_array_add(json
, json_rmac
);
821 /* print a specific L3 VNI entry */
822 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
824 char buf
[ETHER_ADDR_STRLEN
];
825 struct vty
*vty
= NULL
;
826 json_object
*json
= NULL
;
827 zebra_vni_t
*zvni
= NULL
;
828 json_object
*json_vni_list
= NULL
;
829 struct listnode
*node
= NULL
, *nnode
= NULL
;
835 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
836 vty_out(vty
, " Vxlan-Intf: %s\n",
837 zl3vni_vxlan_if_name(zl3vni
));
838 vty_out(vty
, " SVI-If: %s\n",
839 zl3vni_svi_if_name(zl3vni
));
840 vty_out(vty
, " State: %s\n",
841 zl3vni_state2str(zl3vni
));
842 vty_out(vty
, " Vrf: %s\n",
843 zl3vni_vrf_name(zl3vni
));
844 vty_out(vty
, " Rmac: %s\n",
845 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
846 vty_out(vty
, " L2-VNIs: ");
847 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
848 vty_out(vty
, "%u ", zvni
->vni
);
851 json_vni_list
= json_object_new_array();
852 json_object_int_add(json
, "vni", zl3vni
->vni
);
853 json_object_string_add(json
, "vxlan-intf",
854 zl3vni_vxlan_if_name(zl3vni
));
855 json_object_string_add(json
, "svi-if",
856 zl3vni_svi_if_name(zl3vni
));
857 json_object_string_add(json
, "state",
858 zl3vni_state2str(zl3vni
));
859 json_object_string_add(json
, "vrf",
860 zl3vni_vrf_name(zl3vni
));
861 json_object_string_add(json
, "rmac",
862 zl3vni_rmac2str(zl3vni
, buf
,
864 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
865 json_object_array_add(json_vni_list
,
866 json_object_new_int(zvni
->vni
));
868 json_object_object_add(json
, "l2-vnis", json_vni_list
);
873 * Print a specific VNI entry.
875 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
881 json_object
*json
= NULL
;
882 json_object
*json_vtep_list
= NULL
;
883 json_object
*json_ip_str
= NULL
;
889 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
890 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
892 json_object_int_add(json
, "vni", zvni
->vni
);
893 json_object_string_add(json
, "vrf",
894 vrf_id_to_name(zvni
->vrf_id
));
897 if (!zvni
->vxlan_if
) { // unexpected
899 vty_out(vty
, " VxLAN interface: unknown\n");
902 num_macs
= num_valid_macs(zvni
);
903 num_neigh
= hashcount(zvni
->neigh_table
);
905 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
906 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
907 inet_ntoa(zvni
->local_vtep_ip
));
909 json_object_string_add(json
, "vxlanInterface",
910 zvni
->vxlan_if
->name
);
911 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
912 json_object_string_add(json
, "vtepIp",
913 inet_ntoa(zvni
->local_vtep_ip
));
914 json_object_string_add(json
, "advertiseGatewayMacip",
915 zvni
->advertise_gw_macip
? "Yes" : "No");
916 json_object_int_add(json
, "numMacs", num_macs
);
917 json_object_int_add(json
, "numArpNd", num_neigh
);
921 vty_out(vty
, " No remote VTEPs known for this VNI\n");
924 vty_out(vty
, " Remote VTEPs for this VNI:\n");
926 json_vtep_list
= json_object_new_array();
927 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
929 vty_out(vty
, " %s\n",
930 inet_ntoa(zvtep
->vtep_ip
));
932 json_ip_str
= json_object_new_string(
933 inet_ntoa(zvtep
->vtep_ip
));
934 json_object_array_add(json_vtep_list
,
939 json_object_object_add(json
, "numRemoteVteps",
944 " Number of MACs (local and remote) known for this VNI: %u\n",
947 " Number of ARPs (IPv4 and IPv6, local and remote) "
948 "known for this VNI: %u\n",
950 vty_out(vty
, " Advertise-gw-macip: %s\n",
951 zvni
->advertise_gw_macip
? "Yes" : "No");
955 /* print a L3 VNI hash entry */
956 static void zl3vni_print_hash(struct hash_backet
*backet
,
959 char buf
[ETHER_ADDR_STRLEN
];
960 struct vty
*vty
= NULL
;
961 json_object
*json
= NULL
;
962 zebra_l3vni_t
*zl3vni
= NULL
;
967 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
972 vty_out(vty
, "%-10u %-20s %-20s %-5s %-37s %-18s\n",
974 zl3vni_vxlan_if_name(zl3vni
),
975 zl3vni_svi_if_name(zl3vni
),
976 zl3vni_state2str(zl3vni
),
977 zl3vni_vrf_name(zl3vni
),
978 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
980 json_object_int_add(json
, "vni", zl3vni
->vni
);
981 json_object_string_add(json
, "vxlan-if",
982 zl3vni_vxlan_if_name(zl3vni
));
983 json_object_string_add(json
, "svi-if",
984 zl3vni_svi_if_name(zl3vni
));
985 json_object_string_add(json
, "state",
986 zl3vni_state2str(zl3vni
));
987 json_object_string_add(json
, "vrf",
988 zl3vni_vrf_name(zl3vni
));
989 json_object_string_add(json
, "rmac",
990 zl3vni_rmac2str(zl3vni
, buf
,
997 * Print a VNI hash entry - called for display of all VNIs.
999 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1003 zebra_vtep_t
*zvtep
;
1004 u_int32_t num_vteps
= 0;
1005 u_int32_t num_macs
= 0;
1006 u_int32_t num_neigh
= 0;
1007 json_object
*json
= NULL
;
1008 json_object
*json_vni
= NULL
;
1009 json_object
*json_ip_str
= NULL
;
1010 json_object
*json_vtep_list
= NULL
;
1015 zvni
= (zebra_vni_t
*)backet
->data
;
1019 zvtep
= zvni
->vteps
;
1022 zvtep
= zvtep
->next
;
1025 num_macs
= num_valid_macs(zvni
);
1026 num_neigh
= hashcount(zvni
->neigh_table
);
1028 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
1030 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1031 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
1033 vrf_id_to_name(zvni
->vrf_id
));
1035 char vni_str
[VNI_STR_LEN
];
1036 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1037 json_vni
= json_object_new_object();
1038 json_object_string_add(json_vni
, "vxlanIf",
1039 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1041 json_object_string_add(json_vni
, "vtepIp",
1042 inet_ntoa(zvni
->local_vtep_ip
));
1043 json_object_int_add(json_vni
, "numMacs", num_macs
);
1044 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1045 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1047 json_vtep_list
= json_object_new_array();
1048 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1049 json_ip_str
= json_object_new_string(
1050 inet_ntoa(zvtep
->vtep_ip
));
1051 json_object_array_add(json_vtep_list
,
1054 json_object_object_add(json_vni
, "remoteVteps",
1057 json_object_object_add(json
, vni_str
, json_vni
);
1062 * Inform BGP about local MACIP.
1064 static int zvni_macip_send_msg_to_client(vni_t vni
,
1065 struct ethaddr
*macaddr
,
1066 struct ipaddr
*ip
, u_char flags
,
1069 char buf
[ETHER_ADDR_STRLEN
];
1070 char buf2
[INET6_ADDRSTRLEN
];
1072 struct zserv
*client
= NULL
;
1073 struct stream
*s
= NULL
;
1075 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1076 /* BGP may not be running. */
1083 zserv_create_header(s
, cmd
, VRF_DEFAULT
);
1084 stream_putl(s
, vni
);
1085 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1088 if (IS_IPADDR_V4(ip
))
1089 ipa_len
= IPV4_MAX_BYTELEN
;
1090 else if (IS_IPADDR_V6(ip
))
1091 ipa_len
= IPV6_MAX_BYTELEN
;
1093 stream_putl(s
, ipa_len
); /* IP address length */
1095 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1097 stream_putl(s
, 0); /* Just MAC. */
1099 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1102 /* Write packet size. */
1103 stream_putw_at(s
, 0, stream_get_endp(s
));
1105 if (IS_ZEBRA_DEBUG_VXLAN
)
1107 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1108 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
1109 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1110 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1111 zebra_route_string(client
->proto
));
1113 if (cmd
== ZEBRA_MACIP_ADD
)
1114 client
->macipadd_cnt
++;
1116 client
->macipdel_cnt
++;
1118 return zebra_server_send_message(client
);
1122 * Make hash key for neighbors.
1124 static unsigned int neigh_hash_keymake(void *p
)
1126 zebra_neigh_t
*n
= p
;
1127 struct ipaddr
*ip
= &n
->ip
;
1129 if (IS_IPADDR_V4(ip
))
1130 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1132 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1133 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1137 * Compare two neighbor hash structures.
1139 static int neigh_cmp(const void *p1
, const void *p2
)
1141 const zebra_neigh_t
*n1
= p1
;
1142 const zebra_neigh_t
*n2
= p2
;
1144 if (n1
== NULL
&& n2
== NULL
)
1147 if (n1
== NULL
|| n2
== NULL
)
1150 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1154 * Callback to allocate neighbor hash entry.
1156 static void *zvni_neigh_alloc(void *p
)
1158 const zebra_neigh_t
*tmp_n
= p
;
1161 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1168 * Add neighbor entry.
1170 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1171 struct ethaddr
*mac
)
1173 zebra_neigh_t tmp_n
;
1174 zebra_neigh_t
*n
= NULL
;
1175 zebra_mac_t
*zmac
= NULL
;
1177 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1178 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1179 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1182 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1183 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1185 /* Associate the neigh to mac */
1186 zmac
= zvni_mac_lookup(zvni
, mac
);
1188 listnode_add_sort(zmac
->neigh_list
, n
);
1194 * Delete neighbor entry.
1196 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1198 zebra_neigh_t
*tmp_n
;
1199 zebra_mac_t
*zmac
= NULL
;
1201 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1203 listnode_delete(zmac
->neigh_list
, n
);
1205 /* Free the VNI hash entry and allocated memory. */
1206 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1208 XFREE(MTYPE_NEIGH
, tmp_n
);
1214 * Free neighbor hash entry (callback)
1216 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1218 struct neigh_walk_ctx
*wctx
= arg
;
1219 zebra_neigh_t
*n
= backet
->data
;
1221 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1222 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1223 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1224 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1225 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1226 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1227 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1228 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1231 if (wctx
->uninstall
)
1232 zvni_neigh_uninstall(wctx
->zvni
, n
);
1234 return zvni_neigh_del(wctx
->zvni
, n
);
1241 * Delete all neighbor entries from specific VTEP for a particular VNI.
1243 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1244 struct in_addr
*r_vtep_ip
)
1246 struct neigh_walk_ctx wctx
;
1248 if (!zvni
->neigh_table
)
1251 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1253 wctx
.uninstall
= uninstall
;
1254 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1255 wctx
.r_vtep_ip
= *r_vtep_ip
;
1257 hash_iterate(zvni
->neigh_table
,
1258 (void (*)(struct hash_backet
*,
1259 void *))zvni_neigh_del_hash_entry
,
1264 * Delete all neighbor entries for this VNI.
1266 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
1267 int uninstall
, int upd_client
, u_int32_t flags
)
1269 struct neigh_walk_ctx wctx
;
1271 if (!zvni
->neigh_table
)
1274 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1276 wctx
.uninstall
= uninstall
;
1277 wctx
.upd_client
= upd_client
;
1280 hash_iterate(zvni
->neigh_table
,
1281 (void (*)(struct hash_backet
*,
1282 void *))zvni_neigh_del_hash_entry
,
1287 * Look up neighbor hash entry.
1289 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1294 memset(&tmp
, 0, sizeof(tmp
));
1295 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1296 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1301 /* Process all neigh associated to a mac upon local mac add event */
1302 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1305 zebra_neigh_t
*n
= NULL
;
1306 struct listnode
*node
= NULL
;
1307 char buf
[ETHER_ADDR_STRLEN
];
1308 char buf2
[INET6_ADDRSTRLEN
];
1310 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1311 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1312 /* MAC is learnt locally, program all inactive neigh
1313 * pointing to this mac */
1314 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1315 if (IS_ZEBRA_DEBUG_VXLAN
)
1317 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1318 ipaddr2str(&n
->ip
, buf2
,
1320 prefix_mac2str(&n
->emac
, buf
,
1324 ZEBRA_NEIGH_SET_ACTIVE(n
);
1325 zvni_neigh_send_add_to_client(
1326 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1328 if (IS_ZEBRA_DEBUG_VXLAN
)
1330 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1331 ipaddr2str(&n
->ip
, buf2
,
1333 prefix_mac2str(&n
->emac
, buf
,
1337 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1338 /* TODO: assume the neigh has moved too ?? */
1343 /* Process all neigh associated to a mac upon local mac del event */
1344 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1347 zebra_neigh_t
*n
= NULL
;
1348 struct listnode
*node
= NULL
;
1349 char buf
[ETHER_ADDR_STRLEN
];
1350 char buf2
[INET6_ADDRSTRLEN
];
1352 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1353 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1354 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1355 if (IS_ZEBRA_DEBUG_VXLAN
)
1357 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1358 ipaddr2str(&n
->ip
, buf2
,
1360 prefix_mac2str(&n
->emac
, buf
,
1364 ZEBRA_NEIGH_SET_INACTIVE(n
);
1365 zvni_neigh_send_del_to_client(
1366 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1368 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1369 if (IS_ZEBRA_DEBUG_VXLAN
)
1371 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1372 prefix_mac2str(&n
->emac
, buf
,
1375 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1380 /* process all neigh associated to a mac entry upon remote mac add */
1381 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1384 zebra_neigh_t
*n
= NULL
;
1385 struct listnode
*node
= NULL
;
1386 char buf
[ETHER_ADDR_STRLEN
];
1387 char buf2
[INET6_ADDRSTRLEN
];
1389 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1390 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1391 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1392 if (IS_ZEBRA_DEBUG_VXLAN
)
1394 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1395 ipaddr2str(&n
->ip
, buf2
,
1397 prefix_mac2str(&n
->emac
, buf
,
1401 ZEBRA_NEIGH_SET_INACTIVE(n
);
1402 zvni_neigh_send_del_to_client(
1403 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1409 /* process all neigh associated to mac entry upon remote mac del */
1410 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1413 zebra_neigh_t
*n
= NULL
;
1414 struct listnode
*node
= NULL
;
1415 char buf
[ETHER_ADDR_STRLEN
];
1416 char buf2
[INET6_ADDRSTRLEN
];
1418 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1419 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1420 if (IS_ZEBRA_DEBUG_VXLAN
)
1422 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1423 prefix_mac2str(&n
->emac
, buf
,
1426 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1432 * Inform BGP about local neighbor addition.
1434 static int zvni_neigh_send_add_to_client(vni_t vni
,
1436 struct ethaddr
*macaddr
, u_char flags
)
1438 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1443 * Inform BGP about local neighbor deletion.
1445 static int zvni_neigh_send_del_to_client(vni_t vni
,
1447 struct ethaddr
*macaddr
, u_char flags
)
1449 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1454 * Install remote neighbor into the kernel.
1456 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1458 struct zebra_if
*zif
;
1459 struct zebra_l2info_vxlan
*vxl
;
1460 struct interface
*vlan_if
;
1462 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1465 zif
= zvni
->vxlan_if
->info
;
1468 vxl
= &zif
->l2info
.vxl
;
1470 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1474 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1478 * Uninstall remote neighbor from the kernel.
1480 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1482 struct zebra_if
*zif
;
1483 struct zebra_l2info_vxlan
*vxl
;
1484 struct interface
*vlan_if
;
1486 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1489 if (!zvni
->vxlan_if
) {
1490 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1495 zif
= zvni
->vxlan_if
->info
;
1498 vxl
= &zif
->l2info
.vxl
;
1499 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1503 return kernel_del_neigh(vlan_if
, &n
->ip
);
1507 * Install neighbor hash entry - called upon access VLAN change.
1509 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1512 struct neigh_walk_ctx
*wctx
= ctxt
;
1514 n
= (zebra_neigh_t
*)backet
->data
;
1518 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1519 zvni_neigh_install(wctx
->zvni
, n
);
1522 /* Get the VRR interface for SVI if any */
1523 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1525 struct zebra_vrf
*zvrf
= NULL
;
1526 struct interface
*tmp_if
= NULL
;
1527 struct zebra_if
*zif
= NULL
;
1529 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1532 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1537 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1540 if (zif
->link
== ifp
)
1547 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1549 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1550 struct connected
*c
= NULL
;
1551 struct ethaddr macaddr
;
1553 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1555 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1558 memset(&ip
, 0, sizeof(struct ipaddr
));
1559 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1562 if (c
->address
->family
== AF_INET
) {
1563 ip
.ipa_type
= IPADDR_V4
;
1564 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1565 sizeof(struct in_addr
));
1566 } else if (c
->address
->family
== AF_INET6
) {
1567 ip
.ipa_type
= IPADDR_V6
;
1568 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1569 sizeof(struct in6_addr
));
1574 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1580 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1582 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1583 struct connected
*c
= NULL
;
1584 struct ethaddr macaddr
;
1586 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1588 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1591 memset(&ip
, 0, sizeof(struct ipaddr
));
1592 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1595 if (c
->address
->family
== AF_INET
) {
1596 ip
.ipa_type
= IPADDR_V4
;
1597 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1598 sizeof(struct in_addr
));
1599 } else if (c
->address
->family
== AF_INET6
) {
1600 ip
.ipa_type
= IPADDR_V6
;
1601 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1602 sizeof(struct in6_addr
));
1607 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1614 * zvni_gw_macip_add_to_client
1616 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1617 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1620 struct ethaddr rmac
;
1621 char buf
[ETHER_ADDR_STRLEN
];
1622 char buf1
[ETHER_ADDR_STRLEN
];
1623 char buf2
[INET6_ADDRSTRLEN
];
1624 zebra_neigh_t
*n
= NULL
;
1625 zebra_mac_t
*mac
= NULL
;
1626 struct zebra_if
*zif
= NULL
;
1627 struct zebra_l2info_vxlan
*vxl
= NULL
;
1629 memset(&rmac
, 0, sizeof(struct ethaddr
));
1631 zif
= zvni
->vxlan_if
->info
;
1635 vxl
= &zif
->l2info
.vxl
;
1637 /* get the l3-vni */
1638 l3vni
= zvni_get_l3vni(zvni
);
1641 zvni_get_rmac(zvni
, &rmac
);
1643 mac
= zvni_mac_lookup(zvni
, macaddr
);
1645 mac
= zvni_mac_add(zvni
, macaddr
);
1647 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1648 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1649 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1654 /* Set "local" forwarding info. */
1655 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1656 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1657 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1658 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1659 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1661 n
= zvni_neigh_lookup(zvni
, ip
);
1663 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1666 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1667 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1668 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1669 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1674 /* Set "local" forwarding info. */
1675 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1676 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1677 n
->ifindex
= ifp
->ifindex
;
1679 if (IS_ZEBRA_DEBUG_VXLAN
)
1681 "SVI %s(%u) L2-VNI %u L3-VNI %u RMAC %s , sending GW MAC %s IP %s add to BGP",
1682 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1684 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)),
1685 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1686 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1688 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1695 * zvni_gw_macip_del_from_client
1697 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1701 struct ethaddr rmac
;
1702 char buf
[ETHER_ADDR_STRLEN
];
1703 char buf1
[ETHER_ADDR_STRLEN
];
1704 char buf2
[INET6_ADDRSTRLEN
];
1705 zebra_neigh_t
*n
= NULL
;
1706 zebra_mac_t
*mac
= NULL
;
1708 memset(&rmac
, 0, sizeof(struct ethaddr
));
1710 /* get the l30vni */
1711 l3vni
= zvni_get_l3vni(zvni
);
1714 zvni_get_rmac(zvni
, &rmac
);
1716 /* If the neigh entry is not present nothing to do*/
1717 n
= zvni_neigh_lookup(zvni
, ip
);
1721 /* mac entry should be present */
1722 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1724 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1725 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1726 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1730 /* If the entry is not local nothing to do*/
1731 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1734 if (IS_ZEBRA_DEBUG_VXLAN
)
1736 "SVI %s(%u) L2-VNI %u, L3-VNI %u RMAC %s sending GW MAC %s IP %s del to BGP",
1737 ifp
->name
, ifp
->ifindex
, zvni
->vni
, l3vni
,
1738 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
1739 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1740 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1742 /* Remove neighbor from BGP. */
1743 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1746 /* Delete this neighbor entry. */
1747 zvni_neigh_del(zvni
, n
);
1749 /* see if the mac needs to be deleted as well*/
1751 zvni_deref_ip2mac(zvni
, mac
, 0);
1756 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1759 zebra_vni_t
*zvni
= NULL
;
1760 struct zebra_if
*zif
= NULL
;
1761 struct zebra_l2info_vxlan zl2_info
;
1762 struct interface
*vlan_if
= NULL
;
1763 struct interface
*vrr_if
= NULL
;
1764 struct interface
*ifp
;
1766 /* Add primary SVI MAC*/
1767 zvni
= (zebra_vni_t
*)backet
->data
;
1771 ifp
= zvni
->vxlan_if
;
1776 /* If down or not mapped to a bridge, we're done. */
1777 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1780 zl2_info
= zif
->l2info
.vxl
;
1782 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1786 /* Del primary MAC-IP */
1787 zvni_del_macip_for_intf(vlan_if
, zvni
);
1789 /* Del VRR MAC-IP - if any*/
1790 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1792 zvni_del_macip_for_intf(vrr_if
, zvni
);
1797 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1800 zebra_vni_t
*zvni
= NULL
;
1801 struct zebra_if
*zif
= NULL
;
1802 struct zebra_l2info_vxlan zl2_info
;
1803 struct interface
*vlan_if
= NULL
;
1804 struct interface
*vrr_if
= NULL
;
1805 struct interface
*ifp
= NULL
;
1807 zvni
= (zebra_vni_t
*)backet
->data
;
1811 if (!advertise_gw_macip_enabled(zvni
))
1814 ifp
= zvni
->vxlan_if
;
1819 /* If down or not mapped to a bridge, we're done. */
1820 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1822 zl2_info
= zif
->l2info
.vxl
;
1824 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1825 zif
->brslave_info
.br_if
);
1829 /* Add primary SVI MAC-IP */
1830 zvni_add_macip_for_intf(vlan_if
, zvni
);
1832 /* Add VRR MAC-IP - if any*/
1833 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1835 zvni_add_macip_for_intf(vrr_if
, zvni
);
1841 * Make hash key for MAC.
1843 static unsigned int mac_hash_keymake(void *p
)
1845 zebra_mac_t
*pmac
= p
;
1846 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1848 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1852 * Compare two MAC addresses.
1854 static int mac_cmp(const void *p1
, const void *p2
)
1856 const zebra_mac_t
*pmac1
= p1
;
1857 const zebra_mac_t
*pmac2
= p2
;
1859 if (pmac1
== NULL
&& pmac2
== NULL
)
1862 if (pmac1
== NULL
|| pmac2
== NULL
)
1865 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1871 * Callback to allocate MAC hash entry.
1873 static void *zvni_mac_alloc(void *p
)
1875 const zebra_mac_t
*tmp_mac
= p
;
1878 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1881 return ((void *)mac
);
1887 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1889 zebra_mac_t tmp_mac
;
1890 zebra_mac_t
*mac
= NULL
;
1892 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1893 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1894 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1897 mac
->neigh_list
= list_new();
1898 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1906 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1908 zebra_mac_t
*tmp_mac
;
1910 list_delete_and_null(&mac
->neigh_list
);
1912 /* Free the VNI hash entry and allocated memory. */
1913 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1915 XFREE(MTYPE_MAC
, tmp_mac
);
1921 * Free MAC hash entry (callback)
1923 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1925 struct mac_walk_ctx
*wctx
= arg
;
1926 zebra_mac_t
*mac
= backet
->data
;
1929 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1930 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1931 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1932 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1933 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1934 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1935 &wctx
->r_vtep_ip
))) {
1936 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1937 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
1939 zvni_mac_send_del_to_client(
1940 wctx
->zvni
->vni
, &mac
->macaddr
,
1941 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
1944 if (wctx
->uninstall
)
1945 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
1947 return zvni_mac_del(wctx
->zvni
, mac
);
1954 * Delete all MAC entries from specific VTEP for a particular VNI.
1956 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1957 struct in_addr
*r_vtep_ip
)
1959 struct mac_walk_ctx wctx
;
1961 if (!zvni
->mac_table
)
1964 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1966 wctx
.uninstall
= uninstall
;
1967 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
1968 wctx
.r_vtep_ip
= *r_vtep_ip
;
1970 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1971 void *))zvni_mac_del_hash_entry
,
1976 * Delete all MAC entries for this VNI.
1978 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
1979 int uninstall
, int upd_client
, u_int32_t flags
)
1981 struct mac_walk_ctx wctx
;
1983 if (!zvni
->mac_table
)
1986 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
1988 wctx
.uninstall
= uninstall
;
1989 wctx
.upd_client
= upd_client
;
1992 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
1993 void *))zvni_mac_del_hash_entry
,
1998 * Look up MAC hash entry.
2000 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2005 memset(&tmp
, 0, sizeof(tmp
));
2006 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2007 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2013 * Inform BGP about local MAC addition.
2015 static int zvni_mac_send_add_to_client(vni_t vni
,
2016 struct ethaddr
*macaddr
, u_char flags
)
2018 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2023 * Inform BGP about local MAC deletion.
2025 static int zvni_mac_send_del_to_client(vni_t vni
,
2026 struct ethaddr
*macaddr
, u_char flags
)
2028 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2033 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2034 * notifications, to see if they are of interest.
2036 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2037 struct interface
*br_if
, vlanid_t vid
)
2039 struct zebra_ns
*zns
;
2040 struct route_node
*rn
;
2041 struct interface
*tmp_if
= NULL
;
2042 struct zebra_if
*zif
;
2043 struct zebra_l2info_bridge
*br
;
2044 struct zebra_l2info_vxlan
*vxl
= NULL
;
2045 u_char bridge_vlan_aware
;
2049 /* Determine if bridge is VLAN-aware or not */
2052 br
= &zif
->l2info
.br
;
2053 bridge_vlan_aware
= br
->vlan_aware
;
2055 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2056 /* TODO: Optimize with a hash. */
2057 zns
= zebra_ns_lookup(NS_DEFAULT
);
2058 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2059 tmp_if
= (struct interface
*)rn
->info
;
2063 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2065 if (!if_is_operative(tmp_if
))
2067 vxl
= &zif
->l2info
.vxl
;
2069 if (zif
->brslave_info
.br_if
!= br_if
)
2072 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2081 zvni
= zvni_lookup(vxl
->vni
);
2086 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2087 * neighbor notifications, to see if they are of interest.
2089 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2090 struct interface
*br_if
)
2092 struct zebra_ns
*zns
;
2093 struct route_node
*rn
;
2094 struct interface
*tmp_if
= NULL
;
2095 struct zebra_if
*zif
;
2096 struct zebra_l2info_bridge
*br
;
2097 struct zebra_l2info_vxlan
*vxl
= NULL
;
2098 u_char bridge_vlan_aware
;
2106 /* Make sure the linked interface is a bridge. */
2107 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2110 /* Determine if bridge is VLAN-aware or not */
2113 br
= &zif
->l2info
.br
;
2114 bridge_vlan_aware
= br
->vlan_aware
;
2115 if (bridge_vlan_aware
) {
2116 struct zebra_l2info_vlan
*vl
;
2118 if (!IS_ZEBRA_IF_VLAN(ifp
))
2123 vl
= &zif
->l2info
.vl
;
2127 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2128 /* TODO: Optimize with a hash. */
2129 zns
= zebra_ns_lookup(NS_DEFAULT
);
2130 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2131 tmp_if
= (struct interface
*)rn
->info
;
2135 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2137 if (!if_is_operative(tmp_if
))
2139 vxl
= &zif
->l2info
.vxl
;
2141 if (zif
->brslave_info
.br_if
!= br_if
)
2144 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2153 zvni
= zvni_lookup(vxl
->vni
);
2157 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2159 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2160 * linked to the bridge
2161 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2164 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2166 struct zebra_ns
*zns
;
2167 struct route_node
*rn
;
2168 struct interface
*tmp_if
= NULL
;
2169 struct zebra_if
*zif
;
2170 struct zebra_l2info_bridge
*br
;
2171 struct zebra_l2info_vlan
*vl
;
2172 u_char bridge_vlan_aware
;
2175 /* Defensive check, caller expected to invoke only with valid bridge. */
2179 /* Determine if bridge is VLAN-aware or not */
2182 br
= &zif
->l2info
.br
;
2183 bridge_vlan_aware
= br
->vlan_aware
;
2185 /* Check oper status of the SVI. */
2186 if (!bridge_vlan_aware
)
2187 return if_is_operative(br_if
) ? br_if
: NULL
;
2189 /* Identify corresponding VLAN interface. */
2190 /* TODO: Optimize with a hash. */
2191 zns
= zebra_ns_lookup(NS_DEFAULT
);
2192 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2193 tmp_if
= (struct interface
*)rn
->info
;
2194 /* Check oper status of the SVI. */
2195 if (!tmp_if
|| !if_is_operative(tmp_if
))
2198 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2199 || zif
->link
!= br_if
)
2201 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2203 if (vl
->vid
== vid
) {
2209 return found
? tmp_if
: NULL
;
2213 * Install remote MAC into the kernel.
2215 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2217 struct zebra_if
*zif
;
2218 struct zebra_l2info_vxlan
*vxl
;
2221 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2224 zif
= zvni
->vxlan_if
->info
;
2227 vxl
= &zif
->l2info
.vxl
;
2229 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2231 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2232 mac
->fwd_info
.r_vtep_ip
, sticky
);
2236 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2237 * moves to remote, we have to uninstall any existing local entry first.
2239 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2241 struct zebra_if
*zif
;
2242 struct zebra_l2info_vxlan
*vxl
;
2243 struct in_addr vtep_ip
= {.s_addr
= 0};
2244 struct zebra_ns
*zns
;
2245 struct interface
*ifp
;
2247 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2250 if (!zvni
->vxlan_if
) {
2251 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2256 zif
= zvni
->vxlan_if
->info
;
2259 vxl
= &zif
->l2info
.vxl
;
2262 zns
= zebra_ns_lookup(NS_DEFAULT
);
2263 ifp
= if_lookup_by_index_per_ns(zns
,
2264 mac
->fwd_info
.local
.ifindex
);
2265 if (!ifp
) // unexpected
2268 ifp
= zvni
->vxlan_if
;
2269 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2272 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2277 * Install MAC hash entry - called upon access VLAN change.
2279 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2282 struct mac_walk_ctx
*wctx
= ctxt
;
2284 mac
= (zebra_mac_t
*)backet
->data
;
2288 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2289 zvni_mac_install(wctx
->zvni
, mac
);
2293 * Decrement neighbor refcount of MAC; uninstall and free it if
2296 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2299 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2300 || !list_isempty(mac
->neigh_list
))
2304 zvni_mac_uninstall(zvni
, mac
, 0);
2306 zvni_mac_del(zvni
, mac
);
2310 * Read and populate local MACs and neighbors corresponding to this VNI.
2312 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
2313 struct interface
*ifp
)
2315 struct zebra_ns
*zns
;
2316 struct zebra_if
*zif
;
2317 struct interface
*vlan_if
;
2318 struct zebra_l2info_vxlan
*vxl
;
2319 struct interface
*vrr_if
;
2322 vxl
= &zif
->l2info
.vxl
;
2323 zns
= zebra_ns_lookup(NS_DEFAULT
);
2325 if (IS_ZEBRA_DEBUG_VXLAN
)
2327 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2328 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2329 zif
->brslave_info
.bridge_ifindex
);
2331 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2332 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2335 if (advertise_gw_macip_enabled(zvni
)) {
2336 /* Add SVI MAC-IP */
2337 zvni_add_macip_for_intf(vlan_if
, zvni
);
2339 /* Add VRR MAC-IP - if any*/
2340 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2342 zvni_add_macip_for_intf(vrr_if
, zvni
);
2345 neigh_read_for_vlan(zns
, vlan_if
);
2350 * Hash function for VNI.
2352 static unsigned int vni_hash_keymake(void *p
)
2354 const zebra_vni_t
*zvni
= p
;
2356 return (jhash_1word(zvni
->vni
, 0));
2360 * Compare 2 VNI hash entries.
2362 static int vni_hash_cmp(const void *p1
, const void *p2
)
2364 const zebra_vni_t
*zvni1
= p1
;
2365 const zebra_vni_t
*zvni2
= p2
;
2367 return (zvni1
->vni
== zvni2
->vni
);
2371 * Callback to allocate VNI hash entry.
2373 static void *zvni_alloc(void *p
)
2375 const zebra_vni_t
*tmp_vni
= p
;
2378 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2379 zvni
->vni
= tmp_vni
->vni
;
2380 return ((void *)zvni
);
2384 * Look up VNI hash entry.
2386 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2388 struct zebra_vrf
*zvrf
;
2389 zebra_vni_t tmp_vni
;
2390 zebra_vni_t
*zvni
= NULL
;
2392 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2394 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2396 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2402 * Add VNI hash entry.
2404 static zebra_vni_t
*zvni_add(vni_t vni
)
2406 struct zebra_vrf
*zvrf
;
2407 zebra_vni_t tmp_zvni
;
2408 zebra_vni_t
*zvni
= NULL
;
2410 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2412 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2414 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2417 /* Create hash table for MAC */
2419 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2421 /* Create hash table for neighbors */
2422 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2423 "Zebra VNI Neighbor Table");
2429 * Delete VNI hash entry.
2431 static int zvni_del(zebra_vni_t
*zvni
)
2433 struct zebra_vrf
*zvrf
;
2434 zebra_vni_t
*tmp_zvni
;
2436 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2439 zvni
->vxlan_if
= NULL
;
2441 /* Free the neighbor hash table. */
2442 hash_free(zvni
->neigh_table
);
2443 zvni
->neigh_table
= NULL
;
2445 /* Free the MAC hash table. */
2446 hash_free(zvni
->mac_table
);
2447 zvni
->mac_table
= NULL
;
2449 /* Free the VNI hash entry and allocated memory. */
2450 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2452 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2458 * Inform BGP about local VNI addition.
2460 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2462 struct zserv
*client
;
2465 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2466 /* BGP may not be running. */
2473 zserv_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2474 stream_putl(s
, zvni
->vni
);
2475 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2476 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2478 /* Write packet size. */
2479 stream_putw_at(s
, 0, stream_get_endp(s
));
2481 if (IS_ZEBRA_DEBUG_VXLAN
)
2482 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2483 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2484 vrf_id_to_name(zvni
->vrf_id
),
2485 zebra_route_string(client
->proto
));
2487 client
->vniadd_cnt
++;
2488 return zebra_server_send_message(client
);
2492 * Inform BGP about local VNI deletion.
2494 static int zvni_send_del_to_client(vni_t vni
)
2496 struct zserv
*client
;
2499 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2500 /* BGP may not be running. */
2507 zserv_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2508 stream_putl(s
, vni
);
2510 /* Write packet size. */
2511 stream_putw_at(s
, 0, stream_get_endp(s
));
2513 if (IS_ZEBRA_DEBUG_VXLAN
)
2514 zlog_debug("Send VNI_DEL %u to %s", vni
,
2515 zebra_route_string(client
->proto
));
2517 client
->vnidel_cnt
++;
2518 return zebra_server_send_message(client
);
2522 * Build the VNI hash table by going over the VxLAN interfaces. This
2523 * is called when EVPN (advertise-all-vni) is enabled.
2525 static void zvni_build_hash_table()
2527 struct zebra_ns
*zns
;
2528 struct route_node
*rn
;
2529 struct interface
*ifp
;
2531 /* Walk VxLAN interfaces and create VNI hash. */
2532 zns
= zebra_ns_lookup(NS_DEFAULT
);
2533 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2535 struct zebra_if
*zif
;
2536 struct zebra_l2info_vxlan
*vxl
;
2538 ifp
= (struct interface
*)rn
->info
;
2542 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2545 vxl
= &zif
->l2info
.vxl
;
2548 if (is_vni_l3(vni
)) {
2549 zebra_l3vni_t
*zl3vni
= NULL
;
2551 if (IS_ZEBRA_DEBUG_VXLAN
)
2552 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2553 ifp
->name
, ifp
->ifindex
, vni
);
2555 zl3vni
= zl3vni_lookup(vni
);
2558 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
2559 ifp
->name
, ifp
->ifindex
, vni
);
2563 /* associate with vxlan_if */
2564 zl3vni
->vxlan_if
= ifp
;
2566 /* we need to associate with SVI.
2567 * we can associate with svi-if only after association
2568 * with vxlan-intf is complete */
2569 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2571 if (is_l3vni_oper_up(zl3vni
))
2572 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2575 zebra_vni_t
*zvni
= NULL
;
2576 zebra_l3vni_t
*zl3vni
= NULL
;
2577 struct interface
*vlan_if
= NULL
;
2579 if (IS_ZEBRA_DEBUG_VXLAN
)
2581 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2582 ifp
->name
, ifp
->ifindex
, vni
,
2583 inet_ntoa(vxl
->vtep_ip
));
2585 /* VNI hash entry is not expected to exist. */
2586 zvni
= zvni_lookup(vni
);
2589 "VNI hash already present for IF %s(%u) L2-VNI %u",
2590 ifp
->name
, ifp
->ifindex
, vni
);
2594 zvni
= zvni_add(vni
);
2597 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2598 ifp
->name
, ifp
->ifindex
, vni
);
2602 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2603 zvni
->vxlan_if
= ifp
;
2604 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2605 zif
->brslave_info
.br_if
);
2607 zvni
->vrf_id
= vlan_if
->vrf_id
;
2608 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2610 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2614 /* Inform BGP if intf is up and mapped to bridge. */
2615 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2616 zvni_send_add_to_client(zvni
);
2622 * See if remote VTEP matches with prefix.
2624 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2626 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2630 * Locate remote VTEP in VNI hash table.
2632 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2634 zebra_vtep_t
*zvtep
;
2639 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2640 if (zvni_vtep_match(vtep_ip
, zvtep
))
2648 * Add remote VTEP to VNI hash table.
2650 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2652 zebra_vtep_t
*zvtep
;
2654 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2656 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2660 zvtep
->vtep_ip
= *vtep_ip
;
2663 zvni
->vteps
->prev
= zvtep
;
2664 zvtep
->next
= zvni
->vteps
;
2665 zvni
->vteps
= zvtep
;
2671 * Remove remote VTEP from VNI hash table.
2673 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2676 zvtep
->next
->prev
= zvtep
->prev
;
2678 zvtep
->prev
->next
= zvtep
->next
;
2680 zvni
->vteps
= zvtep
->next
;
2682 zvtep
->prev
= zvtep
->next
= NULL
;
2683 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2689 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2690 * uninstall from kernel if asked to.
2692 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2694 zebra_vtep_t
*zvtep
, *zvtep_next
;
2699 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2700 zvtep_next
= zvtep
->next
;
2702 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2703 zvni_vtep_del(zvni
, zvtep
);
2710 * Install remote VTEP into the kernel.
2712 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2714 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2718 * Uninstall remote VTEP from the kernel.
2720 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2722 if (!zvni
->vxlan_if
) {
2723 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2728 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2732 * Cleanup VNI/VTEP and update kernel
2734 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2736 zebra_vni_t
*zvni
= NULL
;
2737 zebra_l3vni_t
*zl3vni
= NULL
;
2739 zvni
= (zebra_vni_t
*)backet
->data
;
2743 /* remove from l3-vni list */
2744 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
2746 listnode_delete(zl3vni
->l2vnis
, zvni
);
2748 /* Free up all neighbors and MACs, if any. */
2749 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2750 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2752 /* Free up all remote VTEPs, if any. */
2753 zvni_vtep_del_all(zvni
, 1);
2755 /* Delete the hash entry. */
2760 * Look up MAC hash entry.
2762 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
2763 struct ethaddr
*rmac
)
2768 memset(&tmp
, 0, sizeof(tmp
));
2769 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
2770 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
2776 * Callback to allocate RMAC hash entry.
2778 static void *zl3vni_rmac_alloc(void *p
)
2780 const zebra_mac_t
*tmp_rmac
= p
;
2783 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2786 return ((void *)zrmac
);
2790 * Add RMAC entry to l3-vni
2792 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
2793 struct ethaddr
*rmac
)
2795 zebra_mac_t tmp_rmac
;
2796 zebra_mac_t
*zrmac
= NULL
;
2798 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
2799 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
2800 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
2803 zrmac
->neigh_list
= list_new();
2804 zrmac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
2806 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
2807 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
2815 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
,
2818 zebra_mac_t
*tmp_rmac
;
2820 list_delete(zrmac
->neigh_list
);
2822 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
2824 XFREE(MTYPE_MAC
, tmp_rmac
);
2830 * Install remote RMAC into the kernel.
2832 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
,
2835 struct zebra_if
*zif
= NULL
;
2836 struct zebra_l2info_vxlan
*vxl
= NULL
;
2838 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2839 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2842 zif
= zl3vni
->vxlan_if
->info
;
2846 vxl
= &zif
->l2info
.vxl
;
2848 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2850 zrmac
->fwd_info
.r_vtep_ip
, 0);
2854 * Uninstall remote RMAC from the kernel.
2856 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
2859 char buf
[ETHER_ADDR_STRLEN
];
2860 struct zebra_if
*zif
= NULL
;
2861 struct zebra_l2info_vxlan
*vxl
= NULL
;
2863 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2864 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2867 if (!zl3vni
->vxlan_if
) {
2868 zlog_err("RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
2869 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
2870 zl3vni
->vni
, zl3vni
);
2874 zif
= zl3vni
->vxlan_if
->info
;
2878 vxl
= &zif
->l2info
.vxl
;
2880 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2881 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
2884 /* handle rmac add */
2885 static int zebra_vxlan_l3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
,
2886 struct ethaddr
*rmac
,
2887 struct ipaddr
*vtep_ip
)
2889 char buf
[ETHER_ADDR_STRLEN
];
2890 char buf1
[INET6_ADDRSTRLEN
];
2891 zebra_mac_t
*zrmac
= NULL
;
2893 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
2896 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
2899 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
2900 prefix_mac2str(rmac
, buf
,
2902 zl3vni
->vni
, ipaddr2str(vtep_ip
, buf1
,
2906 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
2907 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
2909 /* install rmac in kernel */
2910 zl3vni_rmac_install(zl3vni
, zrmac
);
2912 zrmac
->rmac_refcnt
++;
2917 /* handle rmac delete */
2918 static int zebra_vxlan_l3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
,
2919 struct ethaddr
*rmac
)
2921 zebra_mac_t
*zrmac
= NULL
;
2923 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
2927 zrmac
->rmac_refcnt
--;
2928 if (!zrmac
->rmac_refcnt
) {
2930 /* uninstall from kernel */
2931 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
2933 /* del the rmac entry */
2934 zl3vni_rmac_del(zl3vni
, zrmac
);
2940 * Look up nh hash entry on a l3-vni.
2942 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
2948 memset(&tmp
, 0, sizeof(tmp
));
2949 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
2950 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
2957 * Callback to allocate NH hash entry on L3-VNI.
2959 static void *zl3vni_nh_alloc(void *p
)
2961 const zebra_neigh_t
*tmp_n
= p
;
2964 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
2971 * Add neighbor entry.
2973 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
2975 struct ethaddr
*mac
)
2977 zebra_neigh_t tmp_n
;
2978 zebra_neigh_t
*n
= NULL
;
2980 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
2981 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
2982 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
2985 memcpy(&n
->emac
, mac
, ETH_ALEN
);
2986 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2987 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
2993 * Delete neighbor entry.
2995 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
,
2998 zebra_neigh_t
*tmp_n
;
3000 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3002 XFREE(MTYPE_NEIGH
, tmp_n
);
3008 * Install remote nh as neigh into the kernel.
3010 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
,
3013 if (!is_l3vni_oper_up(zl3vni
))
3016 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3017 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3020 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3024 * Uninstall remote nh from the kernel.
3026 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
,
3029 if (!is_l3vni_oper_up(zl3vni
))
3032 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3033 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3036 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3039 /* add remote vtep as a neigh entry */
3040 static int zebra_vxlan_l3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
,
3041 struct ipaddr
*vtep_ip
,
3042 struct ethaddr
*rmac
)
3044 char buf
[ETHER_ADDR_STRLEN
];
3045 char buf1
[INET6_ADDRSTRLEN
];
3046 zebra_neigh_t
*nh
= NULL
;
3048 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3050 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3054 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3055 ipaddr2str(vtep_ip
, buf1
,
3057 prefix_mac2str(rmac
, buf
,
3063 /* install the nh neigh in kernel */
3064 zl3vni_nh_install(zl3vni
, nh
);
3070 /* handle nh neigh delete */
3071 static int zebra_vxlan_l3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
,
3072 struct ipaddr
*vtep_ip
)
3074 zebra_neigh_t
*nh
= NULL
;
3076 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3081 if (!nh
->nh_refcnt
) {
3083 /* uninstall from kernel */
3084 zl3vni_nh_uninstall(zl3vni
, nh
);
3086 /* delete the nh entry */
3087 zl3vni_nh_del(zl3vni
, nh
);
3094 * Hash function for L3 VNI.
3096 static unsigned int l3vni_hash_keymake(void *p
)
3098 const zebra_l3vni_t
*zl3vni
= p
;
3100 return jhash_1word(zl3vni
->vni
, 0);
3104 * Compare 2 L3 VNI hash entries.
3106 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3108 const zebra_l3vni_t
*zl3vni1
= p1
;
3109 const zebra_l3vni_t
*zl3vni2
= p2
;
3111 return (zl3vni1
->vni
== zl3vni2
->vni
);
3115 * Callback to allocate L3 VNI hash entry.
3117 static void *zl3vni_alloc(void *p
)
3119 zebra_l3vni_t
*zl3vni
= NULL
;
3120 const zebra_l3vni_t
*tmp_l3vni
= p
;
3122 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3123 zl3vni
->vni
= tmp_l3vni
->vni
;
3124 return ((void *)zl3vni
);
3128 * Look up L3 VNI hash entry.
3130 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3132 struct zebra_ns
*zns
;
3133 zebra_l3vni_t tmp_l3vni
;
3134 zebra_l3vni_t
*zl3vni
= NULL
;
3136 zns
= zebra_ns_lookup(NS_DEFAULT
);
3138 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3139 tmp_l3vni
.vni
= vni
;
3140 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3146 * Add L3 VNI hash entry.
3148 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3150 zebra_l3vni_t tmp_zl3vni
;
3151 struct zebra_ns
*zns
= NULL
;
3152 zebra_l3vni_t
*zl3vni
= NULL
;
3154 zns
= zebra_ns_lookup(NS_DEFAULT
);
3157 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3158 tmp_zl3vni
.vni
= vni
;
3160 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3163 zl3vni
->vrf_id
= vrf_id
;
3164 zl3vni
->svi_if
= NULL
;
3165 zl3vni
->vxlan_if
= NULL
;
3166 zl3vni
->l2vnis
= list_new();
3167 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3169 /* Create hash table for remote RMAC */
3170 zl3vni
->rmac_table
=
3171 hash_create(mac_hash_keymake
, mac_cmp
,
3172 "Zebra L3-VNI RMAC-Table");
3174 /* Create hash table for neighbors */
3175 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3176 "Zebra L3-VNI next-hop table");
3182 * Delete L3 VNI hash entry.
3184 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3186 struct zebra_ns
*zns
;
3187 zebra_l3vni_t
*tmp_zl3vni
;
3189 zns
= zebra_ns_lookup(NS_DEFAULT
);
3192 /* free the list of l2vnis */
3193 list_delete_and_null(&zl3vni
->l2vnis
);
3194 zl3vni
->l2vnis
= NULL
;
3196 /* Free the rmac table */
3197 hash_free(zl3vni
->rmac_table
);
3198 zl3vni
->rmac_table
= NULL
;
3200 /* Free the nh table */
3201 hash_free(zl3vni
->nh_table
);
3202 zl3vni
->nh_table
= NULL
;
3204 /* Free the VNI hash entry and allocated memory. */
3205 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3207 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3212 static int is_vni_l3(vni_t vni
)
3214 zebra_l3vni_t
*zl3vni
= NULL
;
3216 zl3vni
= zl3vni_lookup(vni
);
3222 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3224 struct zebra_ns
*zns
= NULL
;
3225 struct route_node
*rn
= NULL
;
3226 struct interface
*ifp
= NULL
;
3228 /* loop through all vxlan-interface */
3229 zns
= zebra_ns_lookup(NS_DEFAULT
);
3230 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3232 struct zebra_if
*zif
= NULL
;
3233 struct zebra_l2info_vxlan
*vxl
= NULL
;
3235 ifp
= (struct interface
*)rn
->info
;
3240 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3243 vxl
= &zif
->l2info
.vxl
;
3244 if (vxl
->vni
== zl3vni
->vni
)
3251 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3253 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3254 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3256 if (!zl3vni
->vxlan_if
)
3259 zif
= zl3vni
->vxlan_if
->info
;
3263 vxl
= &zif
->l2info
.vxl
;
3265 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3268 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3270 struct zebra_vrf
*zvrf
= NULL
;
3272 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3276 return zl3vni_lookup(zvrf
->l3vni
);
3280 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3281 * neighbor notifications, to see if they are of interest.
3283 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3284 struct interface
*br_if
)
3288 u_char bridge_vlan_aware
= 0;
3289 zebra_l3vni_t
*zl3vni
= NULL
;
3290 struct zebra_ns
*zns
= NULL
;
3291 struct route_node
*rn
= NULL
;
3292 struct zebra_if
*zif
= NULL
;
3293 struct interface
*tmp_if
= NULL
;
3294 struct zebra_l2info_bridge
*br
= NULL
;
3295 struct zebra_l2info_vxlan
*vxl
= NULL
;
3300 /* Make sure the linked interface is a bridge. */
3301 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3304 /* Determine if bridge is VLAN-aware or not */
3307 br
= &zif
->l2info
.br
;
3308 bridge_vlan_aware
= br
->vlan_aware
;
3309 if (bridge_vlan_aware
) {
3310 struct zebra_l2info_vlan
*vl
;
3312 if (!IS_ZEBRA_IF_VLAN(ifp
))
3317 vl
= &zif
->l2info
.vl
;
3321 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3322 /* TODO: Optimize with a hash. */
3323 zns
= zebra_ns_lookup(NS_DEFAULT
);
3324 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3325 tmp_if
= (struct interface
*)rn
->info
;
3329 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3331 if (!if_is_operative(tmp_if
))
3333 vxl
= &zif
->l2info
.vxl
;
3335 if (zif
->brslave_info
.br_if
!= br_if
)
3338 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3347 zl3vni
= zl3vni_lookup(vxl
->vni
);
3352 * Inform BGP about l3-vni.
3354 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3356 struct stream
*s
= NULL
;
3357 struct zserv
*client
= NULL
;
3358 struct ethaddr rmac
;
3359 char buf
[ETHER_ADDR_STRLEN
];
3361 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3362 /* BGP may not be running. */
3367 memset(&rmac
, 0, sizeof(struct ethaddr
));
3368 zl3vni_get_rmac(zl3vni
, &rmac
);
3373 zserv_create_header(s
, ZEBRA_L3VNI_ADD
,
3374 zl3vni_vrf_id(zl3vni
));
3375 stream_putl(s
, zl3vni
->vni
);
3376 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3378 /* Write packet size. */
3379 stream_putw_at(s
, 0, stream_get_endp(s
));
3381 if (IS_ZEBRA_DEBUG_VXLAN
)
3382 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s to %s",
3383 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3384 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3385 zebra_route_string(client
->proto
));
3387 client
->l3vniadd_cnt
++;
3388 return zebra_server_send_message(client
);
3392 * Inform BGP about local l3-VNI deletion.
3394 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3396 struct stream
*s
= NULL
;
3397 struct zserv
*client
= NULL
;
3399 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3400 /* BGP may not be running. */
3407 zserv_create_header(s
, ZEBRA_L3VNI_DEL
,
3408 zl3vni_vrf_id(zl3vni
));
3409 stream_putl(s
, zl3vni
->vni
);
3411 /* Write packet size. */
3412 stream_putw_at(s
, 0, stream_get_endp(s
));
3414 if (IS_ZEBRA_DEBUG_VXLAN
)
3415 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3417 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3418 zebra_route_string(client
->proto
));
3420 client
->l3vnidel_cnt
++;
3421 return zebra_server_send_message(client
);
3424 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3426 if (IS_ZEBRA_DEBUG_VXLAN
)
3427 zlog_debug("L3-VNI %u is UP - send add to BGP and update all neigh enries",
3430 /* send l3vni add to BGP */
3431 zl3vni_send_add_to_client(zl3vni
);
3434 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3436 if (IS_ZEBRA_DEBUG_VXLAN
)
3437 zlog_debug("L3-VNI %u is Down - send del to BGP and update all neigh enries",
3440 /* send l3-vni del to BGP*/
3441 zl3vni_send_del_to_client(zl3vni
);
3444 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
,
3447 zebra_vni_t
*zvni
= (zebra_vni_t
*) backet
->data
;
3448 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*) ctxt
;
3450 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3451 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3454 /* l3vni from zvni */
3455 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
)
3457 zebra_l3vni_t
*zl3vni
= NULL
;
3459 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3460 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3466 /* rmac from l3vni */
3467 static void zvni_get_rmac(zebra_vni_t
*zvni
,
3468 struct ethaddr
*rmac
)
3470 zebra_l3vni_t
*zl3vni
= NULL
;
3472 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3473 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3477 memcpy(rmac
->octet
, zl3vni
->svi_if
->hw_addr
, ETH_ALEN
);
3481 * handle transition of vni from l2 to l3 and vice versa
3483 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
,
3486 zebra_vni_t
*zvni
= NULL
;
3488 /* There is a possibility that VNI notification was already received
3489 * from kernel and we programmed it as L2-VNI
3490 * In such a case we need to delete this L2-VNI first, so
3491 * that it can be reprogrammed as L3-VNI in the system. It is also
3492 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3493 * interface is still present in kernel. In this case to keep it
3494 * symmetric, we will delete the l3-vni and reprogram it as l2-vni */
3496 /* Locate hash entry */
3497 zvni
= zvni_lookup(vni
);
3501 if (IS_ZEBRA_DEBUG_VXLAN
)
3502 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3505 /* Delete VNI from BGP. */
3506 zvni_send_del_to_client(zvni
->vni
);
3508 /* Free up all neighbors and MAC, if any. */
3509 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3510 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3512 /* Free up all remote VTEPs, if any. */
3513 zvni_vtep_del_all(zvni
, 0);
3515 /* Delete the hash entry. */
3516 if (zvni_del(zvni
)) {
3517 zlog_err("Failed to del VNI hash %p, VNI %u",
3522 /* TODO_MITESH: This needs to be thought through. We don't have
3523 * enough information at this point to reprogram the vni as
3524 * l2-vni. One way is to store the required info in l3-vni and
3525 * used it solely for this purpose */
3531 /* Public functions */
3533 /* handle evpn route in vrf table */
3534 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
,
3535 struct ethaddr
*rmac
,
3538 zebra_l3vni_t
*zl3vni
= NULL
;
3540 zl3vni
= zl3vni_from_vrf(vrf_id
);
3541 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3544 /* add the next hop neighbor */
3545 zebra_vxlan_l3vni_remote_nh_add(zl3vni
, ip
, rmac
);
3548 zebra_vxlan_l3vni_remote_rmac_add(zl3vni
, rmac
, ip
);
3551 /* handle evpn vrf route delete */
3552 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
3553 struct ethaddr
*rmac
,
3556 zebra_l3vni_t
*zl3vni
= NULL
;
3558 zl3vni
= zl3vni_from_vrf(vrf_id
);
3559 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3562 /* delete the next hop entry */
3563 zebra_vxlan_l3vni_remote_nh_del(zl3vni
, ip
);
3565 /* delete the rmac entry */
3566 zebra_vxlan_l3vni_remote_rmac_del(zl3vni
, rmac
);
3570 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
,
3574 zebra_l3vni_t
*zl3vni
;
3575 u_int32_t num_rmacs
;
3576 struct rmac_walk_ctx wctx
;
3577 json_object
*json
= NULL
;
3578 json_object
*json_rmac
= NULL
;
3580 if (!is_evpn_enabled())
3583 zl3vni
= zl3vni_lookup(l3vni
);
3586 vty_out(vty
, "{}\n");
3588 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3591 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3596 json
= json_object_new_object();
3597 json_rmac
= json_object_new_array();
3600 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3602 wctx
.json
= json_rmac
;
3606 "Number of Remote RMACs known for this VNI: %u\n",
3608 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
3609 "Remote VTEP", "Refcnt");
3611 json_object_int_add(json
, "numRmacs", num_rmacs
);
3613 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3616 json_object_object_add(json
, "rmacs", json_rmac
);
3617 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3618 json
, JSON_C_TO_STRING_PRETTY
));
3619 json_object_free(json
);
3623 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
,
3626 struct zebra_ns
*zns
= NULL
;
3627 struct rmac_walk_ctx wctx
;
3628 json_object
*json
= NULL
;
3630 if (!is_evpn_enabled()) {
3632 vty_out(vty
, "{}\n");
3636 zns
= zebra_ns_lookup(NS_DEFAULT
);
3641 json
= json_object_new_object();
3643 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3647 hash_iterate(zns
->l3vni_table
, zl3vni_print_rmac_hash_all_vni
, &wctx
);
3650 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3651 json
, JSON_C_TO_STRING_PRETTY
));
3652 json_object_free(json
);
3656 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
,
3661 struct nh_walk_ctx wctx
;
3662 json_object
*json
= NULL
;
3663 json_object
*json_nh
= NULL
;
3664 zebra_l3vni_t
*zl3vni
= NULL
;
3666 if (!is_evpn_enabled())
3669 zl3vni
= zl3vni_lookup(l3vni
);
3672 vty_out(vty
, "{}\n");
3674 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3678 num_nh
= hashcount(zl3vni
->nh_table
);
3683 json
= json_object_new_object();
3684 json_nh
= json_object_new_array();
3688 wctx
.json
= json_nh
;
3692 "Number of NH Neighbors known for this VNI: %u\n",
3694 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
3697 json_object_int_add(json
, "numNh", num_nh
);
3699 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
3702 json_object_object_add(json
, "next-hop-neighbors", json_nh
);
3703 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3704 json
, JSON_C_TO_STRING_PRETTY
));
3705 json_object_free(json
);
3709 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
,
3712 struct zebra_ns
*zns
= NULL
;
3713 struct nh_walk_ctx wctx
;
3714 json_object
*json
= NULL
;
3716 if (!is_evpn_enabled()) {
3718 vty_out(vty
, "{}\n");
3722 zns
= zebra_ns_lookup(NS_DEFAULT
);
3727 json
= json_object_new_object();
3729 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
3733 hash_iterate(zns
->l3vni_table
, zl3vni_print_nh_hash_all_vni
, &wctx
);
3736 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3737 json
, JSON_C_TO_STRING_PRETTY
));
3738 json_object_free(json
);
3744 * Display L3 VNI information (VTY command handler).
3746 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
3749 json_object
*json
= NULL
;
3750 zebra_l3vni_t
*zl3vni
= NULL
;
3755 if (!is_evpn_enabled())
3758 zl3vni
= zl3vni_lookup(vni
);
3761 vty_out(vty
, "{}\n");
3763 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3768 json
= json_object_new_object();
3770 zl3vni_print(zl3vni
, (void *)args
);
3773 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3774 json
, JSON_C_TO_STRING_PRETTY
));
3775 json_object_free(json
);
3780 * Display L3 VNI hash table (VTY command handler).
3782 void zebra_vxlan_print_l3vnis(struct vty
*vty
, u_char use_json
)
3786 json_object
*json
= NULL
;
3787 struct zebra_ns
*zns
= NULL
;
3792 if (!is_evpn_enabled())
3795 zns
= zebra_ns_lookup(NS_DEFAULT
);
3798 num_vnis
= hashcount(zns
->l3vni_table
);
3801 vty_out(vty
, "{}\n");
3806 json
= json_object_new_object();
3807 json_object_int_add(json
, "numVnis", num_vnis
);
3809 vty_out(vty
, "Number of L3 VNIs: %u\n", num_vnis
);
3810 vty_out(vty
, "%-10s %-20s %-20s %-5s %-37s %-18s\n", "VNI",
3811 "Vx-intf", "L3-SVI", "State", "VRF", "Rmac");
3814 hash_iterate(zns
->l3vni_table
,
3815 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
3819 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3820 json
, JSON_C_TO_STRING_PRETTY
));
3821 json_object_free(json
);
3826 * Display Neighbors for a VNI (VTY command handler).
3828 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3829 vni_t vni
, u_char use_json
)
3832 u_int32_t num_neigh
;
3833 struct neigh_walk_ctx wctx
;
3834 json_object
*json
= NULL
;
3836 if (!is_evpn_enabled())
3838 zvni
= zvni_lookup(vni
);
3841 vty_out(vty
, "{}\n");
3843 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3846 num_neigh
= hashcount(zvni
->neigh_table
);
3851 json
= json_object_new_object();
3853 /* Since we have IPv6 addresses to deal with which can vary widely in
3854 * size, we try to be a bit more elegant in display by first computing
3855 * the maximum width.
3857 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
3860 wctx
.addr_width
= 15;
3862 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
3866 "Number of ARPs (local and remote) known for this VNI: %u\n",
3868 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
3869 "Type", "MAC", "Remote VTEP");
3871 json_object_int_add(json
, "numArpNd", num_neigh
);
3873 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
3875 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3876 json
, JSON_C_TO_STRING_PRETTY
));
3877 json_object_free(json
);
3882 * Display neighbors across all VNIs (VTY command handler).
3884 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3887 json_object
*json
= NULL
;
3890 if (!is_evpn_enabled())
3894 json
= json_object_new_object();
3898 hash_iterate(zvrf
->vni_table
,
3899 (void (*)(struct hash_backet
*,
3900 void *))zvni_print_neigh_hash_all_vni
,
3903 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3904 json
, JSON_C_TO_STRING_PRETTY
));
3905 json_object_free(json
);
3910 * Display specific neighbor for a VNI, if present (VTY command handler).
3912 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
3913 struct zebra_vrf
*zvrf
, vni_t vni
,
3914 struct ipaddr
*ip
, u_char use_json
)
3918 json_object
*json
= NULL
;
3920 if (!is_evpn_enabled())
3922 zvni
= zvni_lookup(vni
);
3925 vty_out(vty
, "{}\n");
3927 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3930 n
= zvni_neigh_lookup(zvni
, ip
);
3934 "%% Requested neighbor does not exist in VNI %u\n",
3939 json
= json_object_new_object();
3941 zvni_print_neigh(n
, vty
, json
);
3944 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3945 json
, JSON_C_TO_STRING_PRETTY
));
3946 json_object_free(json
);
3951 * Display neighbors for a VNI from specific VTEP (VTY command handler).
3952 * By definition, these are remote neighbors.
3954 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3955 vni_t vni
, struct in_addr vtep_ip
,
3959 u_int32_t num_neigh
;
3960 struct neigh_walk_ctx wctx
;
3961 json_object
*json
= NULL
;
3963 if (!is_evpn_enabled())
3965 zvni
= zvni_lookup(vni
);
3968 vty_out(vty
, "{}\n");
3970 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3973 num_neigh
= hashcount(zvni
->neigh_table
);
3977 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
3980 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
3981 wctx
.r_vtep_ip
= vtep_ip
;
3983 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
3986 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3987 json
, JSON_C_TO_STRING_PRETTY
));
3988 json_object_free(json
);
3993 * Display MACs for a VNI (VTY command handler).
3995 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
3996 vni_t vni
, u_char use_json
)
4000 struct mac_walk_ctx wctx
;
4001 json_object
*json
= NULL
;
4002 json_object
*json_mac
= NULL
;
4004 if (!is_evpn_enabled())
4006 zvni
= zvni_lookup(vni
);
4009 vty_out(vty
, "{}\n");
4011 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4014 num_macs
= num_valid_macs(zvni
);
4019 json
= json_object_new_object();
4020 json_mac
= json_object_new_object();
4023 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4026 wctx
.json
= json_mac
;
4030 "Number of MACs (local and remote) known for this VNI: %u\n",
4032 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4033 "Intf/Remote VTEP", "VLAN");
4035 json_object_int_add(json
, "numMacs", num_macs
);
4037 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4040 json_object_object_add(json
, "macs", json_mac
);
4041 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4042 json
, JSON_C_TO_STRING_PRETTY
));
4043 json_object_free(json
);
4048 * Display MACs for all VNIs (VTY command handler).
4050 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4053 struct mac_walk_ctx wctx
;
4054 json_object
*json
= NULL
;
4056 if (!is_evpn_enabled()) {
4058 vty_out(vty
, "{}\n");
4062 json
= json_object_new_object();
4064 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4067 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4070 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4071 json
, JSON_C_TO_STRING_PRETTY
));
4072 json_object_free(json
);
4077 * Display MACs for all VNIs (VTY command handler).
4079 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4080 struct zebra_vrf
*zvrf
,
4081 struct in_addr vtep_ip
,
4084 struct mac_walk_ctx wctx
;
4085 json_object
*json
= NULL
;
4087 if (!is_evpn_enabled())
4091 json
= json_object_new_object();
4093 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4095 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4096 wctx
.r_vtep_ip
= vtep_ip
;
4098 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4101 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4102 json
, JSON_C_TO_STRING_PRETTY
));
4103 json_object_free(json
);
4108 * Display specific MAC for a VNI, if present (VTY command handler).
4110 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4111 vni_t vni
, struct ethaddr
*macaddr
)
4116 if (!is_evpn_enabled())
4118 zvni
= zvni_lookup(vni
);
4120 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4123 mac
= zvni_mac_lookup(zvni
, macaddr
);
4125 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4130 zvni_print_mac(mac
, vty
);
4134 * Display MACs for a VNI from specific VTEP (VTY command handler).
4136 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4137 vni_t vni
, struct in_addr vtep_ip
,
4142 struct mac_walk_ctx wctx
;
4143 json_object
*json
= NULL
;
4144 json_object
*json_mac
= NULL
;
4146 if (!is_evpn_enabled())
4148 zvni
= zvni_lookup(vni
);
4151 vty_out(vty
, "{}\n");
4153 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4156 num_macs
= num_valid_macs(zvni
);
4161 json
= json_object_new_object();
4162 json_mac
= json_object_new_object();
4165 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4168 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4169 wctx
.r_vtep_ip
= vtep_ip
;
4170 wctx
.json
= json_mac
;
4171 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4174 json_object_int_add(json
, "numMacs", wctx
.count
);
4176 json_object_object_add(json
, "macs", json_mac
);
4177 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4178 json
, JSON_C_TO_STRING_PRETTY
));
4179 json_object_free(json
);
4185 * Display VNI information (VTY command handler).
4187 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4191 json_object
*json
= NULL
;
4194 if (!is_evpn_enabled())
4196 zvni
= zvni_lookup(vni
);
4199 vty_out(vty
, "{}\n");
4201 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4205 json
= json_object_new_object();
4208 zvni_print(zvni
, (void *)args
);
4210 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4211 json
, JSON_C_TO_STRING_PRETTY
));
4212 json_object_free(json
);
4217 * Display VNI hash table (VTY command handler).
4219 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4223 json_object
*json
= NULL
;
4226 if (!is_evpn_enabled())
4228 num_vnis
= hashcount(zvrf
->vni_table
);
4231 vty_out(vty
, "{}\n");
4235 json
= json_object_new_object();
4236 json_object_string_add(json
, "advertiseGatewayMacip",
4237 zvrf
->advertise_gw_macip
? "Yes" : "No");
4238 json_object_int_add(json
, "numVnis", num_vnis
);
4240 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4241 zvrf
->advertise_gw_macip
? "Yes" : "No");
4242 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
4243 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
4244 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
4245 "# Remote VTEPs", "VRF");
4250 hash_iterate(zvrf
->vni_table
,
4251 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4255 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4256 json
, JSON_C_TO_STRING_PRETTY
));
4257 json_object_free(json
);
4262 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4263 * kernel. This may result in either the neighbor getting deleted from
4264 * our database or being re-added to the kernel (if it is a valid
4267 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4268 struct interface
*link_if
, struct ipaddr
*ip
)
4271 struct ethaddr rmac
;
4272 char buf
[INET6_ADDRSTRLEN
];
4273 char buf1
[INET6_ADDRSTRLEN
];
4274 char buf2
[ETHER_ADDR_STRLEN
];
4275 zebra_neigh_t
*n
= NULL
;
4276 zebra_vni_t
*zvni
= NULL
;
4277 zebra_mac_t
*zmac
= NULL
;
4279 memset(&rmac
, 0, sizeof(struct ethaddr
));
4281 /* We are only interested in neighbors on an SVI that resides on top
4282 * of a VxLAN bridge.
4284 zvni
= zvni_from_svi(ifp
, link_if
);
4287 if (!zvni
->vxlan_if
) {
4289 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4294 /* get the l3-vni */
4295 l3vni
= zvni_get_l3vni(zvni
);
4298 zvni_get_rmac(zvni
, &rmac
);
4300 if (IS_ZEBRA_DEBUG_VXLAN
)
4301 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u L3-VNI %u RMAC %s",
4302 ipaddr2str(ip
, buf
, sizeof(buf
)),
4303 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
4304 l3vni
, prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4306 /* If entry doesn't exist, nothing to do. */
4307 n
= zvni_neigh_lookup(zvni
, ip
);
4311 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4313 if (IS_ZEBRA_DEBUG_VXLAN
)
4315 "Trying to del a neigh %s without a mac %s on VNI %u",
4316 ipaddr2str(ip
, buf
, sizeof(buf
)),
4317 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4323 /* If it is a remote entry, the kernel has aged this out or someone has
4324 * deleted it, it needs to be re-installed as Quagga is the owner.
4326 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4327 zvni_neigh_install(zvni
, n
);
4331 /* Remove neighbor from BGP. */
4332 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4333 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
4336 /* Delete this neighbor entry. */
4337 zvni_neigh_del(zvni
, n
);
4339 /* see if the AUTO mac needs to be deleted */
4340 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4341 && !listcount(zmac
->neigh_list
))
4342 zvni_mac_del(zvni
, zmac
);
4348 * Handle neighbor add or update (on a VLAN device / L3 interface)
4351 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4352 struct interface
*link_if
,
4354 struct ethaddr
*macaddr
, u_int16_t state
,
4358 struct ethaddr rmac
;
4359 char buf
[ETHER_ADDR_STRLEN
];
4360 char buf1
[ETHER_ADDR_STRLEN
];
4361 char buf2
[INET6_ADDRSTRLEN
];
4362 zebra_vni_t
*zvni
= NULL
;
4363 zebra_neigh_t
*n
= NULL
;
4364 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4366 memset(&rmac
, 0, sizeof(struct ethaddr
));
4368 /* We are only interested in neighbors on an SVI that resides on top
4369 * of a VxLAN bridge.
4371 zvni
= zvni_from_svi(ifp
, link_if
);
4375 /* get the l3-vni */
4376 l3vni
= zvni_get_l3vni(zvni
);
4379 zvni_get_rmac(zvni
, &rmac
);
4381 if (IS_ZEBRA_DEBUG_VXLAN
)
4383 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u L3-VNI %u RMAC %s",
4384 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4385 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4386 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4388 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4390 /* create a dummy MAC if the MAC is not already present */
4391 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4393 if (IS_ZEBRA_DEBUG_VXLAN
)
4395 "AUTO MAC %s created for neigh %s on VNI %u",
4396 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4397 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
4399 zmac
= zvni_mac_add(zvni
, macaddr
);
4401 zlog_warn("Failed to add MAC %s VNI %u",
4402 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4407 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4408 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4409 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4412 /* If same entry already exists, it might be a change or it might be a
4413 * move from remote to local.
4415 n
= zvni_neigh_lookup(zvni
, ip
);
4417 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4418 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
4421 /* Update any params and return - client doesn't
4422 * care about a purely local change.
4424 n
->ifindex
= ifp
->ifindex
;
4428 /* If the MAC has changed,
4429 * need to issue a delete first
4430 * as this means a different MACIP route.
4431 * Also, need to do some unlinking/relinking.
4433 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4435 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4437 listnode_delete(old_zmac
->neigh_list
, n
);
4438 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4441 /* Set "local" forwarding info. */
4442 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4443 n
->ifindex
= ifp
->ifindex
;
4444 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4446 /* Link to new MAC */
4447 listnode_add_sort(zmac
->neigh_list
, n
);
4448 } else if (ext_learned
)
4449 /* The neighbor is remote and that is the notification we got.
4452 /* TODO: Evaluate if we need to do anything here. */
4455 /* Neighbor has moved from remote to local. */
4457 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4458 n
->r_vtep_ip
.s_addr
= 0;
4459 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4460 n
->ifindex
= ifp
->ifindex
;
4463 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4466 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4467 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4468 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4469 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4472 /* Set "local" forwarding info. */
4473 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4474 n
->ifindex
= ifp
->ifindex
;
4477 /* Before we program this in BGP, we need to check if MAC is locally
4479 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4480 if (IS_ZEBRA_DEBUG_VXLAN
)
4482 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4483 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4484 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4491 if (IS_ZEBRA_DEBUG_VXLAN
)
4492 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u L3-VNI %u with RMAC %s",
4493 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4494 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4497 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4499 ZEBRA_NEIGH_SET_ACTIVE(n
);
4501 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
4506 * Handle message from client to delete a remote MACIP for a VNI.
4508 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
4509 struct zebra_vrf
*zvrf
)
4513 struct ethaddr macaddr
;
4515 struct in_addr vtep_ip
;
4519 u_short l
= 0, ipa_len
;
4520 char buf
[ETHER_ADDR_STRLEN
];
4521 char buf1
[INET6_ADDRSTRLEN
];
4522 struct interface
*ifp
= NULL
;
4523 struct zebra_if
*zif
= NULL
;
4525 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4526 memset(&ip
, 0, sizeof(struct ipaddr
));
4527 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4531 while (l
< length
) {
4532 /* Obtain each remote MACIP and process. */
4533 /* Message contains VNI, followed by MAC followed by IP (if any)
4534 * followed by remote VTEP IP.
4538 memset(&ip
, 0, sizeof(ip
));
4539 STREAM_GETL(s
, vni
);
4540 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4541 STREAM_GETL(s
, ipa_len
);
4543 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4545 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4547 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4548 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4549 l
+= IPV4_MAX_BYTELEN
;
4551 if (IS_ZEBRA_DEBUG_VXLAN
)
4553 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4554 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4555 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4557 zebra_route_string(client
->proto
));
4559 /* Locate VNI hash entry - expected to exist. */
4560 zvni
= zvni_lookup(vni
);
4562 if (IS_ZEBRA_DEBUG_VXLAN
)
4564 "Failed to locate VNI hash upon remote MACIP DEL, "
4569 ifp
= zvni
->vxlan_if
;
4572 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4578 /* If down or not mapped to a bridge, we're done. */
4579 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4582 /* The remote VTEP specified is normally expected to exist, but
4584 * possible that the peer may delete the VTEP before deleting
4586 * referring to the VTEP, in which case the handler (see
4588 * would have already deleted the MACs.
4590 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4593 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4595 n
= zvni_neigh_lookup(zvni
, &ip
);
4599 "Failed to locate MAC %s for neigh %s VNI %u",
4600 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4601 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4605 /* If the remote mac or neighbor doesn't exist there is nothing
4607 * to do. Otherwise, uninstall the entry and then remove it.
4612 /* Uninstall remote neighbor or MAC. */
4614 /* When the MAC changes for an IP, it is possible the
4616 * update the new MAC before trying to delete the "old"
4618 * (as these are two different MACIP routes). Do the
4620 * if the MAC matches.
4622 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4623 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
4626 zvni_neigh_uninstall(zvni
, n
);
4627 zvni_neigh_del(zvni
, n
);
4628 zvni_deref_ip2mac(zvni
, mac
, 1);
4631 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4632 zvni_process_neigh_on_remote_mac_del(zvni
,
4635 if (list_isempty(mac
->neigh_list
)) {
4636 zvni_mac_uninstall(zvni
, mac
, 0);
4637 zvni_mac_del(zvni
, mac
);
4639 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4649 * Handle message from client to add a remote MACIP for a VNI. This
4650 * could be just the add of a MAC address or the add of a neighbor
4653 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
4654 struct zebra_vrf
*zvrf
)
4658 struct ethaddr macaddr
;
4660 struct in_addr vtep_ip
;
4662 zebra_vtep_t
*zvtep
;
4663 zebra_mac_t
*mac
, *old_mac
;
4665 u_short l
= 0, ipa_len
;
4666 int update_mac
= 0, update_neigh
= 0;
4667 char buf
[ETHER_ADDR_STRLEN
];
4668 char buf1
[INET6_ADDRSTRLEN
];
4670 struct interface
*ifp
= NULL
;
4671 struct zebra_if
*zif
= NULL
;
4673 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4674 memset(&ip
, 0, sizeof(struct ipaddr
));
4675 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4677 if (!EVPN_ENABLED(zvrf
)) {
4678 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
4679 __PRETTY_FUNCTION__
);
4685 while (l
< length
) {
4686 /* Obtain each remote MACIP and process. */
4687 /* Message contains VNI, followed by MAC followed by IP (if any)
4688 * followed by remote VTEP IP.
4690 update_mac
= update_neigh
= 0;
4693 memset(&ip
, 0, sizeof(ip
));
4694 STREAM_GETL(s
, vni
);
4695 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4696 STREAM_GETL(s
, ipa_len
);
4698 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4700 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4702 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4703 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4704 l
+= IPV4_MAX_BYTELEN
;
4706 /* Get 'sticky' flag. */
4707 STREAM_GETC(s
, sticky
);
4710 if (IS_ZEBRA_DEBUG_VXLAN
)
4712 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
4713 sticky
? "sticky " : "",
4714 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4715 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4717 zebra_route_string(client
->proto
));
4719 /* Locate VNI hash entry - expected to exist. */
4720 zvni
= zvni_lookup(vni
);
4723 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
4727 ifp
= zvni
->vxlan_if
;
4730 "VNI %u hash %p doesn't have intf upon remote MACIP add",
4736 /* If down or not mapped to a bridge, we're done. */
4737 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4740 /* The remote VTEP specified should normally exist, but it is
4742 * that when peering comes up, peer may advertise MACIP routes
4744 * advertising type-3 routes.
4746 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4748 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4750 "Failed to add remote VTEP, VNI %u zvni %p",
4755 zvni_vtep_install(zvni
, &vtep_ip
);
4758 /* First, check if the remote MAC is unknown or has a change. If
4760 * that needs to be updated first. Note that client could
4762 * MAC and MACIP separately or just install the latter.
4764 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4765 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4766 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
4768 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
4773 mac
= zvni_mac_add(zvni
, &macaddr
);
4776 "Failed to add MAC %s VNI %u Remote VTEP %s",
4777 prefix_mac2str(&macaddr
, buf
,
4779 vni
, inet_ntoa(vtep_ip
));
4783 /* Is this MAC created for a MACIP? */
4785 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4788 /* Set "auto" and "remote" forwarding info. */
4789 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4790 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4791 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4792 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4795 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4797 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4799 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
4801 /* Install the entry. */
4802 zvni_mac_install(zvni
, mac
);
4805 /* If there is no IP, continue - after clearing AUTO flag of
4808 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4812 /* Check if the remote neighbor itself is unknown or has a
4814 * If so, create or update and then install the entry.
4816 n
= zvni_neigh_lookup(zvni
, &ip
);
4817 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4818 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
4819 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
4824 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
4827 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
4828 ipaddr2str(&ip
, buf1
,
4830 prefix_mac2str(&macaddr
, buf
,
4832 vni
, inet_ntoa(vtep_ip
));
4836 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
4838 /* MAC change, update neigh list for old and new
4840 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
4842 listnode_delete(old_mac
->neigh_list
, n
);
4843 zvni_deref_ip2mac(zvni
, old_mac
, 1);
4845 listnode_add_sort(mac
->neigh_list
, n
);
4846 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
4849 /* Set "remote" forwarding info. */
4850 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4851 /* TODO: Handle MAC change. */
4852 n
->r_vtep_ip
= vtep_ip
;
4853 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4855 /* Install the entry. */
4856 zvni_neigh_install(zvni
, n
);
4865 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
4866 * us, this must involve a multihoming scenario. Treat this as implicit delete
4867 * of any prior local MAC.
4869 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
4870 struct interface
*br_if
,
4871 struct ethaddr
*macaddr
, vlanid_t vid
)
4873 struct zebra_if
*zif
;
4874 struct zebra_l2info_vxlan
*vxl
;
4878 char buf
[ETHER_ADDR_STRLEN
];
4883 vxl
= &zif
->l2info
.vxl
;
4886 /* Check if EVPN is enabled. */
4887 if (!is_evpn_enabled())
4890 /* Locate hash entry; it is expected to exist. */
4891 zvni
= zvni_lookup(vni
);
4895 /* If entry doesn't exist, nothing to do. */
4896 mac
= zvni_mac_lookup(zvni
, macaddr
);
4900 /* Is it a local entry? */
4901 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
4904 if (IS_ZEBRA_DEBUG_VXLAN
)
4906 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
4907 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4908 ifp
->name
, ifp
->ifindex
, vni
);
4910 /* Remove MAC from BGP. */
4911 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
4912 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
4913 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
4916 * If there are no neigh associated with the mac delete the mac
4917 * else mark it as AUTO for forward reference
4919 if (!listcount(mac
->neigh_list
)) {
4920 zvni_mac_del(zvni
, mac
);
4922 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4923 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4930 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
4931 * This can happen because the remote MAC entries are also added as "dynamic",
4932 * so the kernel can ageout the entry.
4934 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
4935 struct interface
*br_if
,
4936 struct ethaddr
*macaddr
, vlanid_t vid
)
4938 struct zebra_if
*zif
;
4939 struct zebra_l2info_vxlan
*vxl
;
4943 char buf
[ETHER_ADDR_STRLEN
];
4947 vxl
= &zif
->l2info
.vxl
;
4950 /* Check if EVPN is enabled. */
4951 if (!is_evpn_enabled())
4954 /* Locate hash entry; it is expected to exist. */
4955 zvni
= zvni_lookup(vni
);
4959 /* If entry doesn't exist, nothing to do. */
4960 mac
= zvni_mac_lookup(zvni
, macaddr
);
4964 /* Is it a remote entry? */
4965 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
4968 if (IS_ZEBRA_DEBUG_VXLAN
)
4969 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
4970 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4973 zvni_mac_install(zvni
, mac
);
4978 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
4980 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
4981 struct ethaddr
*macaddr
, vlanid_t vid
)
4985 char buf
[ETHER_ADDR_STRLEN
];
4988 /* We are interested in MACs only on ports or (port, VLAN) that
4991 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
4994 if (!zvni
->vxlan_if
) {
4995 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5000 if (IS_ZEBRA_DEBUG_VXLAN
)
5001 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5002 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5003 ifp
->ifindex
, vid
, zvni
->vni
);
5005 /* If entry doesn't exist, nothing to do. */
5006 mac
= zvni_mac_lookup(zvni
, macaddr
);
5010 /* Is it a local entry? */
5011 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5014 /* Remove MAC from BGP. */
5015 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
5016 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
5017 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
5019 /* Update all the neigh entries associated with this mac */
5020 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5023 * If there are no neigh associated with the mac delete the mac
5024 * else mark it as AUTO for forward reference
5026 if (!listcount(mac
->neigh_list
)) {
5027 zvni_mac_del(zvni
, mac
);
5029 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5030 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5037 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5039 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5040 struct interface
*br_if
,
5041 struct ethaddr
*macaddr
, vlanid_t vid
,
5046 char buf
[ETHER_ADDR_STRLEN
];
5050 /* We are interested in MACs only on ports or (port, VLAN) that
5053 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5055 if (IS_ZEBRA_DEBUG_VXLAN
)
5057 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5058 sticky
? "sticky " : "",
5059 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5060 ifp
->name
, ifp
->ifindex
, vid
);
5064 if (!zvni
->vxlan_if
) {
5065 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5070 if (IS_ZEBRA_DEBUG_VXLAN
)
5072 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5073 sticky
? "sticky " : "",
5074 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5075 ifp
->ifindex
, vid
, zvni
->vni
);
5077 /* If same entry already exists, nothing to do. */
5078 mac
= zvni_mac_lookup(zvni
, macaddr
);
5080 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5081 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5087 * return if nothing has changed.
5088 * inform bgp if sticky flag has changed
5089 * update locally and do not inform bgp if local
5090 * parameters like interface has changed
5092 if (mac_sticky
== sticky
5093 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5094 && mac
->fwd_info
.local
.vid
== vid
) {
5095 if (IS_ZEBRA_DEBUG_VXLAN
)
5097 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5098 "entry exists and has not changed ",
5099 sticky
? "sticky " : "",
5100 prefix_mac2str(macaddr
, buf
,
5102 ifp
->name
, ifp
->ifindex
, vid
,
5105 } else if (mac_sticky
!= sticky
) {
5108 add
= 0; /* This is an update of local
5111 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5113 * If we have already learned the MAC as a remote sticky
5115 * this is a operator error and we must log a warning
5117 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5119 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5120 prefix_mac2str(macaddr
, buf
,
5122 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5130 mac
= zvni_mac_add(zvni
, macaddr
);
5132 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5133 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5134 ifp
->name
, ifp
->ifindex
, vid
);
5139 /* Set "local" forwarding info. */
5140 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5141 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5142 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5143 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5144 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5145 mac
->fwd_info
.local
.vid
= vid
;
5148 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5150 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5152 /* Inform BGP if required. */
5154 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5155 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5163 * Handle message from client to delete a remote VTEP for a VNI.
5165 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
5166 struct zebra_vrf
*zvrf
)
5171 struct in_addr vtep_ip
;
5173 zebra_vtep_t
*zvtep
;
5174 struct interface
*ifp
;
5175 struct zebra_if
*zif
;
5177 if (!is_evpn_enabled()) {
5178 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5179 __PRETTY_FUNCTION__
);
5183 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5184 zlog_err("Recv MACIP DEL for non-default VRF %u",
5191 while (l
< length
) {
5192 /* Obtain each remote VTEP and process. */
5193 STREAM_GETL(s
, vni
);
5195 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5196 l
+= IPV4_MAX_BYTELEN
;
5198 if (IS_ZEBRA_DEBUG_VXLAN
)
5199 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5200 inet_ntoa(vtep_ip
), vni
,
5201 zebra_route_string(client
->proto
));
5203 /* Locate VNI hash entry - expected to exist. */
5204 zvni
= zvni_lookup(vni
);
5206 if (IS_ZEBRA_DEBUG_VXLAN
)
5208 "Failed to locate VNI hash upon remote VTEP DEL, "
5214 ifp
= zvni
->vxlan_if
;
5217 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5223 /* If down or not mapped to a bridge, we're done. */
5224 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5227 /* If the remote VTEP does not exist, there's nothing more to
5229 * Otherwise, uninstall any remote MACs pointing to this VTEP
5231 * then, the VTEP entry itself and remove it.
5233 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5237 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5238 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5239 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5240 zvni_vtep_del(zvni
, zvtep
);
5248 * Handle message from client to add a remote VTEP for a VNI.
5250 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
5251 struct zebra_vrf
*zvrf
)
5256 struct in_addr vtep_ip
;
5258 struct interface
*ifp
;
5259 struct zebra_if
*zif
;
5261 if (!is_evpn_enabled()) {
5262 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5263 __PRETTY_FUNCTION__
);
5267 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5268 zlog_err("Recv MACIP ADD for non-default VRF %u",
5275 while (l
< length
) {
5276 /* Obtain each remote VTEP and process. */
5277 STREAM_GETL(s
, vni
);
5279 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5280 l
+= IPV4_MAX_BYTELEN
;
5282 if (IS_ZEBRA_DEBUG_VXLAN
)
5283 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5284 inet_ntoa(vtep_ip
), vni
,
5285 zebra_route_string(client
->proto
));
5287 /* Locate VNI hash entry - expected to exist. */
5288 zvni
= zvni_lookup(vni
);
5291 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5296 ifp
= zvni
->vxlan_if
;
5299 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5306 /* If down or not mapped to a bridge, we're done. */
5307 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5310 /* If the remote VTEP already exists,
5311 there's nothing more to do. */
5312 if (zvni_vtep_find(zvni
, &vtep_ip
))
5315 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5317 "Failed to add remote VTEP, VNI %u zvni %p",
5322 zvni_vtep_install(zvni
, &vtep_ip
);
5330 * Add/Del gateway macip to evpn
5332 * 1. SVI interface on a vlan aware bridge
5333 * 2. SVI interface on a vlan unaware bridge
5334 * 3. vrr interface (MACVLAN) associated to a SVI
5335 * We advertise macip routes for an interface if it is associated to VxLan vlan
5337 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5341 struct ethaddr macaddr
;
5342 zebra_vni_t
*zvni
= NULL
;
5344 memset(&ip
, 0, sizeof(struct ipaddr
));
5345 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5347 /* Check if EVPN is enabled. */
5348 if (!is_evpn_enabled())
5351 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5352 struct interface
*svi_if
=
5353 NULL
; /* SVI corresponding to the MACVLAN */
5354 struct zebra_if
*ifp_zif
=
5355 NULL
; /* Zebra daemon specific info for MACVLAN */
5356 struct zebra_if
*svi_if_zif
=
5357 NULL
; /* Zebra daemon specific info for SVI*/
5359 ifp_zif
= ifp
->info
;
5364 * for a MACVLAN interface the link represents the svi_if
5366 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5367 ifp_zif
->link_ifindex
);
5369 zlog_err("MACVLAN %s(%u) without link information",
5370 ifp
->name
, ifp
->ifindex
);
5374 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5376 * If it is a vlan aware bridge then the link gives the
5377 * bridge information
5379 struct interface
*svi_if_link
= NULL
;
5381 svi_if_zif
= svi_if
->info
;
5383 svi_if_link
= if_lookup_by_index_per_ns(
5384 zebra_ns_lookup(NS_DEFAULT
),
5385 svi_if_zif
->link_ifindex
);
5386 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5388 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5390 * If it is a vlan unaware bridge then svi is the bridge
5393 zvni
= zvni_from_svi(svi_if
, svi_if
);
5395 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5396 struct zebra_if
*svi_if_zif
=
5397 NULL
; /* Zebra daemon specific info for SVI */
5398 struct interface
*svi_if_link
=
5399 NULL
; /* link info for the SVI = bridge info */
5401 svi_if_zif
= ifp
->info
;
5402 svi_if_link
= if_lookup_by_index_per_ns(
5403 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5404 if (svi_if_zif
&& svi_if_link
)
5405 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5406 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5407 zvni
= zvni_from_svi(ifp
, ifp
);
5413 if (!zvni
->vxlan_if
) {
5414 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5420 /* check if we are advertising gw macip routes */
5421 if (!advertise_gw_macip_enabled(zvni
))
5424 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5426 if (p
->family
== AF_INET
) {
5427 ip
.ipa_type
= IPADDR_V4
;
5428 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5429 sizeof(struct in_addr
));
5430 } else if (p
->family
== AF_INET6
) {
5431 ip
.ipa_type
= IPADDR_V6
;
5432 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5433 sizeof(struct in6_addr
));
5438 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5440 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5446 * Handle SVI interface going down.
5447 * SVI can be associated to either L3-VNI or L2-VNI.
5448 * For L2-VNI: At this point, this is a NOP since
5449 * the kernel deletes the neighbor entries on this SVI (if any).
5450 * We only need to update the vrf corresponding to zvni.
5451 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5454 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5456 zebra_l3vni_t
*zl3vni
= NULL
;
5458 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5461 /* process l3-vni down */
5462 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5464 /* remove association with svi-if */
5465 zl3vni
->svi_if
= NULL
;
5467 zebra_vni_t
*zvni
= NULL
;
5469 /* since we dont have svi corresponding to zvni, we associate it
5470 * to default vrf. Note: the corresponding neigh entries on the
5471 * SVI would have already been deleted */
5472 zvni
= zvni_from_svi(ifp
, link_if
);
5474 zvni
->vrf_id
= VRF_DEFAULT
;
5476 /* update the tenant vrf in BGP */
5477 zvni_send_add_to_client(zvni
);
5484 * Handle SVI interface coming up.
5485 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5487 * For L2-VNI: we need to install any remote neighbors entried (used for
5489 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5491 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5493 zebra_vni_t
*zvni
= NULL
;
5494 zebra_l3vni_t
*zl3vni
= NULL
;
5496 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5499 /* associate with svi */
5500 zl3vni
->svi_if
= ifp
;
5502 /* process oper-up */
5503 if (is_l3vni_oper_up(zl3vni
))
5504 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5507 /* process SVI up for l2-vni */
5508 struct neigh_walk_ctx n_wctx
;
5510 zvni
= zvni_from_svi(ifp
, link_if
);
5514 if (!zvni
->vxlan_if
) {
5515 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5520 if (IS_ZEBRA_DEBUG_VXLAN
)
5521 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5522 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5523 vrf_id_to_name(ifp
->vrf_id
));
5525 /* update the vrf information for l2-vni and inform bgp */
5526 zvni
->vrf_id
= ifp
->vrf_id
;
5527 zvni_send_add_to_client(zvni
);
5529 /* Install any remote neighbors for this VNI. */
5530 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5532 hash_iterate(zvni
->neigh_table
,
5533 zvni_install_neigh_hash
,
5541 * Handle VxLAN interface down
5543 int zebra_vxlan_if_down(struct interface
*ifp
)
5546 struct zebra_if
*zif
= NULL
;
5547 struct zebra_l2info_vxlan
*vxl
= NULL
;
5549 /* Check if EVPN is enabled. */
5550 if (!is_evpn_enabled())
5555 vxl
= &zif
->l2info
.vxl
;
5559 if (is_vni_l3(vni
)) {
5561 /* process-if-down for l3-vni */
5562 zebra_l3vni_t
*zl3vni
= NULL
;
5564 if (IS_ZEBRA_DEBUG_VXLAN
)
5565 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
5566 ifp
->name
, ifp
->ifindex
, vni
);
5568 zl3vni
= zl3vni_lookup(vni
);
5571 "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
5572 ifp
->name
, ifp
->ifindex
, vni
);
5576 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5579 /* process if-down for l2-vni */
5582 if (IS_ZEBRA_DEBUG_VXLAN
)
5583 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
5584 ifp
->name
, ifp
->ifindex
, vni
);
5586 /* Locate hash entry; it is expected to exist. */
5587 zvni
= zvni_lookup(vni
);
5590 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5591 ifp
->name
, ifp
->ifindex
, vni
);
5595 assert(zvni
->vxlan_if
== ifp
);
5597 /* Delete this VNI from BGP. */
5598 zvni_send_del_to_client(zvni
->vni
);
5600 /* Free up all neighbors and MACs, if any. */
5601 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5602 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5604 /* Free up all remote VTEPs, if any. */
5605 zvni_vtep_del_all(zvni
, 1);
5611 * Handle VxLAN interface up - update BGP if required.
5613 int zebra_vxlan_if_up(struct interface
*ifp
)
5616 struct zebra_if
*zif
= NULL
;
5617 struct zebra_l2info_vxlan
*vxl
= NULL
;
5619 /* Check if EVPN is enabled. */
5620 if (!is_evpn_enabled())
5625 vxl
= &zif
->l2info
.vxl
;
5628 if (is_vni_l3(vni
)) {
5630 /* Handle L3-VNI add */
5631 zebra_l3vni_t
*zl3vni
= NULL
;
5633 if (IS_ZEBRA_DEBUG_VXLAN
)
5634 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
5635 ifp
->name
, ifp
->ifindex
, vni
);
5637 zl3vni
= zl3vni_lookup(vni
);
5640 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
5641 ifp
->name
, ifp
->ifindex
, vni
);
5645 /* we need to associate with SVI, if any, we can associate with
5646 * svi-if only after association with vxlan-intf is complete */
5647 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5649 if (is_l3vni_oper_up(zl3vni
))
5650 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5652 /* Handle L2-VNI add */
5654 zebra_vni_t
*zvni
= NULL
;
5655 zebra_l3vni_t
*zl3vni
= NULL
;
5656 struct interface
*vlan_if
= NULL
;
5658 if (IS_ZEBRA_DEBUG_VXLAN
)
5659 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
5660 ifp
->name
, ifp
->ifindex
, vni
);
5662 /* Locate hash entry; it is expected to exist. */
5663 zvni
= zvni_lookup(vni
);
5666 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
5667 ifp
->name
, ifp
->ifindex
, vni
);
5671 assert(zvni
->vxlan_if
== ifp
);
5672 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5673 zif
->brslave_info
.br_if
);
5675 zvni
->vrf_id
= vlan_if
->vrf_id
;
5676 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
5678 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
5681 /* If part of a bridge, inform BGP about this VNI. */
5682 /* Also, read and populate local MACs and neighbors. */
5683 if (zif
->brslave_info
.br_if
) {
5684 zvni_send_add_to_client(zvni
);
5685 zvni_read_mac_neigh(zvni
, ifp
);
5693 * Handle VxLAN interface delete. Locate and remove entry in hash table
5694 * and update BGP, if required.
5696 int zebra_vxlan_if_del(struct interface
*ifp
)
5699 struct zebra_if
*zif
= NULL
;
5700 struct zebra_l2info_vxlan
*vxl
= NULL
;
5702 /* Check if EVPN is enabled. */
5703 if (!is_evpn_enabled())
5708 vxl
= &zif
->l2info
.vxl
;
5711 if (is_vni_l3(vni
)) {
5713 /* process if-del for l3-vni */
5714 zebra_l3vni_t
*zl3vni
= NULL
;
5716 if (IS_ZEBRA_DEBUG_VXLAN
)
5717 zlog_debug("Del L3-VNI %u intf %s(%u)",
5718 vni
, ifp
->name
, ifp
->ifindex
);
5720 zl3vni
= zl3vni_lookup(vni
);
5723 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5724 ifp
->name
, ifp
->ifindex
, vni
);
5728 /* process oper-down for l3-vni */
5729 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5731 /* remove the association with vxlan_if */
5732 zl3vni
->vxlan_if
= NULL
;
5735 /* process if-del for l2-vni*/
5736 zebra_vni_t
*zvni
= NULL
;
5737 zebra_l3vni_t
*zl3vni
= NULL
;
5739 if (IS_ZEBRA_DEBUG_VXLAN
)
5740 zlog_debug("Del L2-VNI %u intf %s(%u)",
5741 vni
, ifp
->name
, ifp
->ifindex
);
5743 /* Locate hash entry; it is expected to exist. */
5744 zvni
= zvni_lookup(vni
);
5747 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
5748 ifp
->name
, ifp
->ifindex
, vni
);
5752 /* remove from l3-vni list */
5753 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
5755 listnode_delete(zl3vni
->l2vnis
, zvni
);
5757 /* Delete VNI from BGP. */
5758 zvni_send_del_to_client(zvni
->vni
);
5760 /* Free up all neighbors and MAC, if any. */
5761 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
5762 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
5764 /* Free up all remote VTEPs, if any. */
5765 zvni_vtep_del_all(zvni
, 0);
5767 /* Delete the hash entry. */
5768 if (zvni_del(zvni
)) {
5769 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
5770 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
5779 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
5781 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
5784 struct zebra_if
*zif
= NULL
;
5785 struct zebra_l2info_vxlan
*vxl
= NULL
;
5787 /* Check if EVPN is enabled. */
5788 if (!is_evpn_enabled())
5793 vxl
= &zif
->l2info
.vxl
;
5796 if (is_vni_l3(vni
)) {
5797 zebra_l3vni_t
*zl3vni
= NULL
;
5799 zl3vni
= zl3vni_lookup(vni
);
5802 "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
5803 ifp
->name
, ifp
->ifindex
, vni
);
5807 if (IS_ZEBRA_DEBUG_VXLAN
)
5809 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
5810 vni
, ifp
->name
, ifp
->ifindex
,
5811 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5812 zif
->brslave_info
.bridge_ifindex
, chgflags
);
5814 /* Removed from bridge? Cleanup and return */
5815 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5816 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
5817 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5821 /* access-vlan change - process oper down, associate with new
5822 * svi_if and then process oper up again */
5823 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5824 if (if_is_operative(ifp
)) {
5825 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5826 zl3vni
->svi_if
= NULL
;
5827 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5828 if (is_l3vni_oper_up(zl3vni
))
5829 zebra_vxlan_process_l3vni_oper_up(
5834 /* if we have a valid new master, process l3-vni oper up */
5835 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
5836 if (is_l3vni_oper_up(zl3vni
))
5837 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5840 zebra_vni_t
*zvni
= NULL
;
5842 /* Update VNI hash. */
5843 zvni
= zvni_lookup(vni
);
5846 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
5847 ifp
->name
, ifp
->ifindex
, vni
);
5851 if (IS_ZEBRA_DEBUG_VXLAN
)
5853 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
5854 vni
, ifp
->name
, ifp
->ifindex
,
5855 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5856 zif
->brslave_info
.bridge_ifindex
, chgflags
);
5858 /* Removed from bridge? Cleanup and return */
5859 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5860 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
5861 /* Delete from client, remove all remote VTEPs */
5862 /* Also, free up all MACs and neighbors. */
5863 zvni_send_del_to_client(zvni
->vni
);
5864 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5865 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5866 zvni_vtep_del_all(zvni
, 1);
5870 /* Handle other changes. */
5871 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5872 /* Remove all existing local neigh and MACs for this VNI
5873 * (including from BGP)
5875 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
5876 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
5879 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
5880 zvni
->vxlan_if
= ifp
;
5882 /* Take further actions needed.
5883 * Note that if we are here, there is a change of interest.
5885 /* If down or not mapped to a bridge, we're done. */
5886 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5889 /* Inform BGP, if there is a change of interest. */
5891 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
5892 zvni_send_add_to_client(zvni
);
5894 /* If there is a valid new master or a VLAN mapping change,
5895 * read and populate local MACs and neighbors.
5896 * Also, reinstall any remote MACs and neighbors
5897 * for this VNI (based on new VLAN).
5899 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
5900 zvni_read_mac_neigh(zvni
, ifp
);
5901 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
5902 struct mac_walk_ctx m_wctx
;
5903 struct neigh_walk_ctx n_wctx
;
5905 zvni_read_mac_neigh(zvni
, ifp
);
5907 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
5909 hash_iterate(zvni
->mac_table
,
5910 zvni_install_mac_hash
,
5913 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5915 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
5924 * Handle VxLAN interface add.
5926 int zebra_vxlan_if_add(struct interface
*ifp
)
5929 struct zebra_if
*zif
= NULL
;
5930 struct zebra_l2info_vxlan
*vxl
= NULL
;
5932 /* Check if EVPN is enabled. */
5933 if (!is_evpn_enabled())
5938 vxl
= &zif
->l2info
.vxl
;
5941 if (is_vni_l3(vni
)) {
5943 /* process if-add for l3-vni*/
5944 zebra_l3vni_t
*zl3vni
= NULL
;
5946 if (IS_ZEBRA_DEBUG_VXLAN
)
5948 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
5949 vni
, ifp
->name
, ifp
->ifindex
,
5950 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
5951 zif
->brslave_info
.bridge_ifindex
);
5954 * we expect the l3-vni has entry to be present here.
5955 * The only place l3-vni is created in zebra is vrf-vni mapping
5956 * command. This might change when we have the switchd support
5957 * for l3-vxlan interface.
5959 zl3vni
= zl3vni_lookup(vni
);
5962 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5963 ifp
->name
, ifp
->ifindex
, vni
);
5967 /* associate with vxlan_if */
5968 zl3vni
->vxlan_if
= ifp
;
5970 /* Associate with SVI, if any. We can associate with svi-if only
5971 * after association with vxlan_if is complete */
5972 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5974 if (is_l3vni_oper_up(zl3vni
))
5975 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5978 /* process if-add for l2-vni */
5979 zebra_vni_t
*zvni
= NULL
;
5980 zebra_l3vni_t
*zl3vni
= NULL
;
5981 struct interface
*vlan_if
= NULL
;
5983 /* Create or update VNI hash. */
5984 zvni
= zvni_lookup(vni
);
5986 zvni
= zvni_add(vni
);
5989 "Failed to add VNI hash, IF %s(%u) VNI %u",
5990 ifp
->name
, ifp
->ifindex
, vni
);
5995 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
5996 zvni
->vxlan_if
= ifp
;
5997 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5998 zif
->brslave_info
.br_if
);
6000 zvni
->vrf_id
= vlan_if
->vrf_id
;
6001 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6003 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6006 if (IS_ZEBRA_DEBUG_VXLAN
)
6008 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6010 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
) :
6012 ifp
->name
, ifp
->ifindex
,
6013 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6014 zif
->brslave_info
.bridge_ifindex
);
6016 /* If down or not mapped to a bridge, we're done. */
6017 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6021 zvni_send_add_to_client(zvni
);
6023 /* Read and populate local MACs and neighbors */
6024 zvni_read_mac_neigh(zvni
, ifp
);
6030 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
,
6031 vni_t vni
, char *err
,
6034 zebra_l3vni_t
*zl3vni
= NULL
;
6035 struct zebra_vrf
*zvrf_default
= NULL
;
6037 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6041 if (IS_ZEBRA_DEBUG_VXLAN
)
6042 zlog_debug("vrf %s vni %u %s",
6045 add
? "ADD" : "DEL");
6049 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6051 /* check if the vni is already present under zvrf */
6053 snprintf(err
, ERR_STR_SZ
,
6054 "VNI is already configured under the vrf");
6058 /* check if this VNI is already present in the system */
6059 zl3vni
= zl3vni_lookup(vni
);
6061 snprintf(err
, ERR_STR_SZ
,
6062 "VNI is already configured as L3-VNI");
6066 /* add the L3-VNI to the global table */
6067 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6069 snprintf(err
, ERR_STR_SZ
,
6070 "Could not add L3-VNI");
6074 /* associate the vrf with vni */
6077 /* associate with vxlan-intf;
6078 * we need to associate with the vxlan-intf first */
6079 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6081 /* associate with corresponding SVI interface, we can associate
6082 * with svi-if only after vxlan interface association is
6084 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6086 /* formulate l2vni list */
6087 hash_iterate(zvrf_default
->vni_table
,
6088 zvni_add_to_l3vni_list
, zl3vni
);
6090 if (is_l3vni_oper_up(zl3vni
))
6091 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6094 zl3vni
= zl3vni_lookup(vni
);
6096 snprintf(err
, ERR_STR_SZ
, "VNI doesn't exist");
6100 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6105 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6110 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6112 zebra_l3vni_t
*zl3vni
= NULL
;
6114 zl3vni
= zl3vni_from_vrf(zvrf_id(zvrf
));
6118 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6120 zebra_vxlan_handle_vni_transition(zvrf
, zl3vni
->vni
, 0);
6126 * Handle message from client to enable/disable advertisement of g/w macip
6129 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
6130 struct zebra_vrf
*zvrf
)
6135 zebra_vni_t
*zvni
= NULL
;
6136 struct interface
*ifp
= NULL
;
6138 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6139 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6145 STREAM_GETC(s
, advertise
);
6146 STREAM_GET(&vni
, s
, 3);
6149 if (IS_ZEBRA_DEBUG_VXLAN
)
6150 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6151 advertise
? "enabled" : "disabled",
6152 advertise_gw_macip_enabled(NULL
)
6156 if (zvrf
->advertise_gw_macip
== advertise
)
6159 zvrf
->advertise_gw_macip
= advertise
;
6161 if (advertise_gw_macip_enabled(zvni
))
6162 hash_iterate(zvrf
->vni_table
,
6163 zvni_gw_macip_add_for_vni_hash
, NULL
);
6165 hash_iterate(zvrf
->vni_table
,
6166 zvni_gw_macip_del_for_vni_hash
, NULL
);
6169 struct zebra_if
*zif
= NULL
;
6170 struct zebra_l2info_vxlan zl2_info
;
6171 struct interface
*vlan_if
= NULL
;
6172 struct interface
*vrr_if
= NULL
;
6174 if (IS_ZEBRA_DEBUG_VXLAN
)
6176 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6177 advertise
? "enabled" : "disabled", vni
,
6178 advertise_gw_macip_enabled(zvni
)
6182 zvni
= zvni_lookup(vni
);
6186 if (zvni
->advertise_gw_macip
== advertise
)
6189 zvni
->advertise_gw_macip
= advertise
;
6191 ifp
= zvni
->vxlan_if
;
6197 /* If down or not mapped to a bridge, we're done. */
6198 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6201 zl2_info
= zif
->l2info
.vxl
;
6203 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6204 zif
->brslave_info
.br_if
);
6208 if (advertise_gw_macip_enabled(zvni
)) {
6209 /* Add primary SVI MAC-IP */
6210 zvni_add_macip_for_intf(vlan_if
, zvni
);
6212 /* Add VRR MAC-IP - if any*/
6213 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6215 zvni_add_macip_for_intf(vrr_if
, zvni
);
6217 /* Del primary MAC-IP */
6218 zvni_del_macip_for_intf(vlan_if
, zvni
);
6220 /* Del VRR MAC-IP - if any*/
6221 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6223 zvni_del_macip_for_intf(vrr_if
, zvni
);
6233 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6234 * When enabled, the VNI hash table will be built and MAC FDB table read;
6235 * when disabled, the entries should be deleted and remote VTEPs and MACs
6236 * uninstalled from the kernel.
6238 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
6239 u_short length
, struct zebra_vrf
*zvrf
)
6244 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6245 zlog_err("EVPN VNI Adv for non-default VRF %u",
6251 STREAM_GETC(s
, advertise
);
6253 if (IS_ZEBRA_DEBUG_VXLAN
)
6254 zlog_debug("EVPN VNI Adv %s, currently %s",
6255 advertise
? "enabled" : "disabled",
6256 is_evpn_enabled() ? "enabled" : "disabled");
6258 if (zvrf
->advertise_all_vni
== advertise
)
6261 zvrf
->advertise_all_vni
= advertise
;
6262 if (is_evpn_enabled()) {
6263 /* Build VNI hash table and inform BGP. */
6264 zvni_build_hash_table();
6266 /* Add all SVI (L3 GW) MACs to BGP*/
6267 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6270 /* Read the MAC FDB */
6271 macfdb_read(zvrf
->zns
);
6273 /* Read neighbors */
6274 neigh_read(zvrf
->zns
);
6276 /* Cleanup VTEPs for all VNIs - uninstall from
6277 * kernel and free entries.
6279 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6287 * Allocate VNI hash table for this VRF and do other initialization.
6288 * NOTE: Currently supported only for default VRF.
6290 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6294 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6295 "Zebra VRF VNI Table");
6298 /* Close all VNI handling */
6299 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6303 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6304 hash_free(zvrf
->vni_table
);
6307 /* init the l3vni table */
6308 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6310 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6311 "Zebra VRF L3 VNI table");
6314 /* free l3vni table */
6315 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6317 hash_free(zns
->l3vni_table
);
6320 /* get the l3vni svi ifindex */
6321 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6323 zebra_l3vni_t
*zl3vni
= NULL
;
6325 zl3vni
= zl3vni_from_vrf(vrf_id
);
6326 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6329 return zl3vni
->svi_if
->ifindex
;