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
, HOST_PREFIX
, "host prefix");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
54 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
55 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
56 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
61 /* static function declarations */
62 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
63 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
64 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
66 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
68 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
);
69 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
70 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
71 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
72 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
73 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
75 static int zvni_macip_send_msg_to_client(vni_t vni
,
76 struct ethaddr
*macaddr
,
77 struct ipaddr
*ip
, u_char flags
,
79 static unsigned int neigh_hash_keymake(void *p
);
80 static int neigh_cmp(const void *p1
, const void *p2
);
81 static void *zvni_neigh_alloc(void *p
);
82 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
84 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
85 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
86 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
87 struct in_addr
*r_vtep_ip
);
88 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
89 int uninstall
, int upd_client
, u_int32_t flags
);
90 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
91 static int zvni_neigh_send_add_to_client(vni_t vni
,
93 struct ethaddr
*macaddr
, u_char flags
);
94 static int zvni_neigh_send_del_to_client(vni_t vni
,
96 struct ethaddr
*macaddr
, u_char flags
);
97 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
98 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
99 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
100 struct interface
*br_if
);
101 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
102 struct interface
*br_if
);
104 /* l3-vni next-hop neigh related APIs */
105 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
107 static void *zl3vni_nh_alloc(void *p
);
108 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
109 struct ipaddr
*vtep_ip
,
110 struct ethaddr
*rmac
);
111 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
112 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
113 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
115 /* l3-vni rmac related APIs */
116 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
117 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
118 struct ethaddr
*rmac
);
119 static void *zl3vni_rmac_alloc(void *p
);
120 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
121 struct ethaddr
*rmac
);
122 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
123 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
124 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
127 /* l3-vni related APIs*/
128 static int is_vni_l3(vni_t
);
129 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
130 static void *zl3vni_alloc(void *p
);
131 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
132 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
133 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
134 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
);
135 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
136 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
137 static void zvni_get_rmac(zebra_vni_t
*zvni
, struct ethaddr
*rmac
);
138 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
139 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
141 static unsigned int mac_hash_keymake(void *p
);
142 static int mac_cmp(const void *p1
, const void *p2
);
143 static void *zvni_mac_alloc(void *p
);
144 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
145 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
146 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
147 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
148 struct in_addr
*r_vtep_ip
);
149 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
150 int uninstall
, int upd_client
, u_int32_t flags
);
151 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
152 static int zvni_mac_send_add_to_client(vni_t vni
,
153 struct ethaddr
*macaddr
, u_char flags
);
154 static int zvni_mac_send_del_to_client(vni_t vni
,
155 struct ethaddr
*macaddr
, u_char flags
);
156 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
157 struct interface
*br_if
, vlanid_t vid
);
158 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
159 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
160 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
162 static unsigned int vni_hash_keymake(void *p
);
163 static int vni_hash_cmp(const void *p1
, const void *p2
);
164 static void *zvni_alloc(void *p
);
165 static zebra_vni_t
*zvni_lookup(vni_t vni
);
166 static zebra_vni_t
*zvni_add(vni_t vni
);
167 static int zvni_del(zebra_vni_t
*zvni
);
168 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
169 static int zvni_send_del_to_client(vni_t vni
);
170 static void zvni_build_hash_table();
171 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
172 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
173 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
174 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
175 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
176 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
177 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
178 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
179 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
180 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
181 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
182 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
184 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
185 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
186 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
189 /* Private functions */
192 * Return number of valid MACs in a VNI's MAC hash table - all
193 * remote MACs and non-internal (auto) local MACs count.
195 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
198 u_int32_t num_macs
= 0;
200 struct hash_backet
*hb
;
203 hash
= zvni
->mac_table
;
206 for (i
= 0; i
< hash
->size
; i
++) {
207 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
208 mac
= (zebra_mac_t
*)hb
->data
;
209 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
210 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
218 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
220 struct zebra_vrf
*zvrf
;
222 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
223 if (zvrf
&& zvrf
->advertise_gw_macip
)
226 if (zvni
&& zvni
->advertise_gw_macip
)
233 * Helper function to determine maximum width of neighbor IP address for
234 * display - just because we're dealing with IPv6 addresses that can
237 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
240 char buf
[INET6_ADDRSTRLEN
];
241 struct neigh_walk_ctx
*wctx
= ctxt
;
244 n
= (zebra_neigh_t
*)backet
->data
;
248 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
249 if (width
> wctx
->addr_width
)
250 wctx
->addr_width
= width
;
254 * Print a specific neighbor entry.
256 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
259 char buf1
[ETHER_ADDR_STRLEN
];
260 char buf2
[INET6_ADDRSTRLEN
];
262 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
263 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
264 vty
= (struct vty
*)ctxt
;
266 vty_out(vty
, "IP: %s\n",
267 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
268 vty_out(vty
, " MAC: %s",
269 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
271 json_object_string_add(json
, "ip", buf2
);
272 json_object_string_add(json
, "mac", buf1
);
274 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
276 vty_out(vty
, " Remote VTEP: %s",
277 inet_ntoa(n
->r_vtep_ip
));
279 json_object_string_add(json
, "remoteVtep",
280 inet_ntoa(n
->r_vtep_ip
));
282 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
285 vty_out(vty
, " State: %s",
286 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
295 * Print neighbor hash entry - called for display of all neighbors.
297 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
300 json_object
*json_vni
= NULL
, *json_row
= NULL
;
302 char buf1
[ETHER_ADDR_STRLEN
];
303 char buf2
[INET6_ADDRSTRLEN
];
304 struct neigh_walk_ctx
*wctx
= ctxt
;
307 json_vni
= wctx
->json
;
308 n
= (zebra_neigh_t
*)backet
->data
;
313 json_row
= json_object_new_object();
315 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
316 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
317 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
318 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
319 if (json_vni
== NULL
) {
320 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
321 buf2
, "local", buf1
);
323 json_object_string_add(json_row
, "type", "local");
324 json_object_string_add(json_row
, "mac", buf1
);
328 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
329 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
330 if (json_vni
== NULL
) {
331 if (wctx
->count
== 0)
333 "%*s %-6s %-17s %-21s\n",
336 "MAC", "Remote VTEP");
337 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
338 -wctx
->addr_width
, buf2
,
340 inet_ntoa(n
->r_vtep_ip
));
342 json_object_string_add(json_row
, "type",
344 json_object_string_add(json_row
, "mac",
346 json_object_string_add(
347 json_row
, "remoteVtep",
348 inet_ntoa(n
->r_vtep_ip
));
353 if (json_vni
== NULL
) {
354 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
355 -wctx
->addr_width
, buf2
, "remote", buf1
,
356 inet_ntoa(n
->r_vtep_ip
));
358 json_object_string_add(json_row
, "type",
360 json_object_string_add(json_row
, "mac", buf1
);
361 json_object_string_add(json_row
, "remoteVtep",
362 inet_ntoa(n
->r_vtep_ip
));
369 json_object_object_add(json_vni
, buf2
, json_row
);
373 * Print neighbors for all VNI.
375 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
379 json_object
*json
= NULL
, *json_vni
= NULL
;
382 struct neigh_walk_ctx wctx
;
383 char vni_str
[VNI_STR_LEN
];
385 vty
= (struct vty
*)args
[0];
386 json
= (json_object
*)args
[1];
388 zvni
= (zebra_vni_t
*)backet
->data
;
391 vty_out(vty
, "{}\n");
394 num_neigh
= hashcount(zvni
->neigh_table
);
397 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
398 zvni
->vni
, num_neigh
);
400 json_vni
= json_object_new_object();
401 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
402 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
406 json_object_object_add(json
, vni_str
, json_vni
);
410 /* Since we have IPv6 addresses to deal with which can vary widely in
411 * size, we try to be a bit more elegant in display by first computing
414 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
417 wctx
.addr_width
= 15;
418 wctx
.json
= json_vni
;
419 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
422 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
423 "Type", "MAC", "Remote VTEP");
424 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
427 json_object_object_add(json
, vni_str
, json_vni
);
430 /* print a specific next hop for an l3vni */
431 static void zl3vni_print_nh(zebra_neigh_t
*n
,
435 char buf1
[ETHER_ADDR_STRLEN
];
436 char buf2
[INET6_ADDRSTRLEN
];
437 struct listnode
*node
= NULL
;
438 struct prefix
*p
= NULL
;
439 json_object
*json_hosts
= NULL
;
442 vty_out(vty
, "Ip: %s\n",
443 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
444 vty_out(vty
, " RMAC: %s\n",
445 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
446 vty_out(vty
, " Host-List:\n");
447 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
448 vty_out(vty
, " %s\n",
449 prefix2str(p
, buf2
, sizeof(buf2
)));
451 json_hosts
= json_object_new_array();
452 json_object_string_add(json
, "ip",
453 ipaddr2str(&(n
->ip
), buf2
,
455 json_object_string_add(json
, "rmac",
456 prefix_mac2str(&n
->emac
, buf2
,
458 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
459 json_object_array_add(json_hosts
,
460 json_object_new_string(
463 json_object_object_add(json
, "hosts", json_hosts
);
467 /* Print a specific RMAC entry */
468 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
,
471 char buf1
[ETHER_ADDR_STRLEN
];
472 char buf2
[PREFIX_STRLEN
];
473 struct listnode
*node
= NULL
;
474 struct prefix
*p
= NULL
;
476 vty_out(vty
, "MAC: %s\n",
477 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
478 vty_out(vty
, " Remote VTEP: %s\n",
479 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
480 vty_out(vty
, " Host-List:\n");
481 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
482 vty_out(vty
, " %s\n",
483 prefix2str(p
, buf2
, sizeof(buf2
)));
487 * Print a specific MAC entry.
489 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
492 zebra_neigh_t
*n
= NULL
;
493 struct listnode
*node
= NULL
;
495 char buf2
[INET6_ADDRSTRLEN
];
497 vty
= (struct vty
*)ctxt
;
498 vty_out(vty
, "MAC: %s",
499 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
500 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
501 struct zebra_ns
*zns
;
502 struct interface
*ifp
;
505 ifindex
= mac
->fwd_info
.local
.ifindex
;
506 zns
= zebra_ns_lookup(NS_DEFAULT
);
507 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
508 if (!ifp
) // unexpected
510 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
511 if (mac
->fwd_info
.local
.vid
)
512 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
513 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
514 vty_out(vty
, " Remote VTEP: %s",
515 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
516 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
517 vty_out(vty
, " Auto Mac ");
521 /* print all the associated neigh */
522 vty_out(vty
, " Neighbors:\n");
523 if (!listcount(mac
->neigh_list
))
524 vty_out(vty
, " No Neighbors\n");
526 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
527 vty_out(vty
, " %s %s\n",
528 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
529 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
530 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
541 * Print MAC hash entry - called for display of all MACs.
543 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
546 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
549 struct mac_walk_ctx
*wctx
= ctxt
;
552 json_mac_hdr
= wctx
->json
;
553 mac
= (zebra_mac_t
*)backet
->data
;
557 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
560 json_mac
= json_object_new_object();
562 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
563 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
564 struct zebra_ns
*zns
;
566 struct interface
*ifp
;
569 zns
= zebra_ns_lookup(NS_DEFAULT
);
570 ifindex
= mac
->fwd_info
.local
.ifindex
;
571 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
572 if (!ifp
) // unexpected
574 vid
= mac
->fwd_info
.local
.vid
;
575 if (json_mac_hdr
== NULL
)
576 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
579 json_object_string_add(json_mac
, "type", "local");
580 json_object_string_add(json_mac
, "intf", ifp
->name
);
583 if (json_mac_hdr
== NULL
)
584 vty_out(vty
, " %-5u", vid
);
586 json_object_int_add(json_mac
, "vlan", vid
);
588 if (json_mac_hdr
== NULL
)
591 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
593 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
594 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
595 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
597 if (wctx
->count
== 0) {
598 if (json_mac_hdr
== NULL
) {
599 vty_out(vty
, "\nVNI %u\n\n",
602 "%-17s %-6s %-21s %-5s\n",
608 if (json_mac_hdr
== NULL
)
609 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
611 inet_ntoa(mac
->fwd_info
614 json_object_string_add(json_mac
, "type",
616 json_object_string_add(
617 json_mac
, "remoteVtep",
618 inet_ntoa(mac
->fwd_info
620 json_object_object_add(json_mac_hdr
,
626 if (json_mac_hdr
== NULL
)
627 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
629 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
631 json_object_string_add(json_mac
, "type",
633 json_object_string_add(
634 json_mac
, "remoteVtep",
635 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
636 json_object_object_add(json_mac_hdr
, buf1
,
645 * Print MACs for all VNI.
647 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
650 json_object
*json
= NULL
, *json_vni
= NULL
;
651 json_object
*json_mac
= NULL
;
654 struct mac_walk_ctx
*wctx
= ctxt
;
655 char vni_str
[VNI_STR_LEN
];
657 vty
= (struct vty
*)wctx
->vty
;
658 json
= (struct json_object
*)wctx
->json
;
660 zvni
= (zebra_vni_t
*)backet
->data
;
663 vty_out(vty
, "{}\n");
668 /*We are iterating over a new VNI, set the count to 0*/
671 num_macs
= num_valid_macs(zvni
);
676 json_vni
= json_object_new_object();
677 json_mac
= json_object_new_object();
678 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
681 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
683 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
684 zvni
->vni
, num_macs
);
685 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
686 "Intf/Remote VTEP", "VLAN");
688 json_object_int_add(json_vni
, "numMacs", num_macs
);
690 /* assign per-vni to wctx->json object to fill macs
691 * under the vni. Re-assign primary json object to fill
692 * next vni information.
694 wctx
->json
= json_mac
;
695 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
699 json_object_object_add(json_vni
, "macs", json_mac
);
700 json_object_object_add(json
, vni_str
, json_vni
);
704 static void zl3vni_print_nh_hash(struct hash_backet
*backet
,
707 struct nh_walk_ctx
*wctx
= NULL
;
708 struct vty
*vty
= NULL
;
709 struct json_object
*json_vni
= NULL
;
710 struct json_object
*json_nh
= NULL
;
711 zebra_neigh_t
*n
= NULL
;
712 char buf1
[ETHER_ADDR_STRLEN
];
713 char buf2
[INET6_ADDRSTRLEN
];
715 wctx
= (struct nh_walk_ctx
*)ctx
;
717 json_vni
= wctx
->json
;
719 json_nh
= json_object_new_object();
720 n
= (zebra_neigh_t
*)backet
->data
;
725 vty_out(vty
, "%-15s %-17s %6d\n",
726 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
727 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
728 listcount(n
->host_list
));
730 json_object_string_add(json_nh
, "nexthop-ip",
731 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
732 json_object_string_add(json_nh
, "rmac",
733 prefix_mac2str(&n
->emac
, buf1
,
735 json_object_int_add(json_nh
, "refCnt", listcount(n
->host_list
));
736 json_object_object_add(json_vni
,
737 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
742 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
745 struct vty
*vty
= NULL
;
746 json_object
*json
= NULL
;
747 json_object
*json_vni
= NULL
;
748 zebra_l3vni_t
*zl3vni
= NULL
;
750 struct nh_walk_ctx wctx
;
751 char vni_str
[VNI_STR_LEN
];
753 vty
= (struct vty
*)args
[0];
754 json
= (struct json_object
*)args
[1];
756 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
759 vty_out(vty
, "{}\n");
763 num_nh
= hashcount(zl3vni
->nh_table
);
768 json_vni
= json_object_new_object();
769 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
773 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n",
774 zl3vni
->vni
, num_nh
);
775 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
778 json_object_int_add(json_vni
, "numNh", num_nh
);
780 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
782 wctx
.json
= json_vni
;
783 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
785 json_object_object_add(json
, vni_str
, json_vni
);
788 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
791 struct vty
*vty
= NULL
;
792 json_object
*json
= NULL
;
793 json_object
*json_vni
= NULL
;
794 zebra_l3vni_t
*zl3vni
= NULL
;
796 struct rmac_walk_ctx wctx
;
797 char vni_str
[VNI_STR_LEN
];
799 vty
= (struct vty
*)args
[0];
800 json
= (struct json_object
*)args
[1];
802 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
805 vty_out(vty
, "{}\n");
809 num_rmacs
= hashcount(zl3vni
->rmac_table
);
814 json_vni
= json_object_new_object();
815 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
819 vty_out(vty
, "\nVNI %u #MACs %u\n\n",
820 zl3vni
->vni
, num_rmacs
);
821 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
822 "Remote VTEP", "Refcnt");
824 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
826 /* assign per-vni to wctx->json object to fill macs
827 * under the vni. Re-assign primary json object to fill
828 * next vni information.
830 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
832 wctx
.json
= json_vni
;
833 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
835 json_object_object_add(json
, vni_str
, json_vni
);
838 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
,
841 zebra_mac_t
*zrmac
= NULL
;
842 struct rmac_walk_ctx
*wctx
= NULL
;
843 struct vty
*vty
= NULL
;
844 struct json_object
*json
= NULL
;
845 struct json_object
*json_rmac
= NULL
;
846 char buf
[ETHER_ADDR_STRLEN
];
848 wctx
= (struct rmac_walk_ctx
*)ctx
;
852 json_rmac
= json_object_new_object();
853 zrmac
= (zebra_mac_t
*)backet
->data
;
858 vty_out(vty
, "%-17s %-21s %-6d\n",
859 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
860 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
),
861 listcount(zrmac
->host_list
));
863 json_object_string_add(json_rmac
, "rmac",
864 prefix_mac2str(&zrmac
->macaddr
, buf
,
866 json_object_string_add(json_rmac
, "vtep-ip",
867 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
868 json_object_int_add(json_rmac
, "refcnt",
869 listcount(zrmac
->host_list
));
870 json_object_object_add(json
,
871 prefix_mac2str(&zrmac
->macaddr
, buf
,
877 /* print a specific L3 VNI entry */
878 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
880 char buf
[ETHER_ADDR_STRLEN
];
881 struct vty
*vty
= NULL
;
882 json_object
*json
= NULL
;
883 zebra_vni_t
*zvni
= NULL
;
884 json_object
*json_vni_list
= NULL
;
885 struct listnode
*node
= NULL
, *nnode
= NULL
;
891 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
892 vty_out(vty
, " Vxlan-Intf: %s\n",
893 zl3vni_vxlan_if_name(zl3vni
));
894 vty_out(vty
, " SVI-If: %s\n",
895 zl3vni_svi_if_name(zl3vni
));
896 vty_out(vty
, " State: %s\n",
897 zl3vni_state2str(zl3vni
));
898 vty_out(vty
, " Vrf: %s\n",
899 zl3vni_vrf_name(zl3vni
));
900 vty_out(vty
, " Rmac: %s\n",
901 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
902 vty_out(vty
, " L2-VNIs: ");
903 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
904 vty_out(vty
, "%u ", zvni
->vni
);
907 json_vni_list
= json_object_new_array();
908 json_object_int_add(json
, "vni", zl3vni
->vni
);
909 json_object_string_add(json
, "vxlan-intf",
910 zl3vni_vxlan_if_name(zl3vni
));
911 json_object_string_add(json
, "svi-if",
912 zl3vni_svi_if_name(zl3vni
));
913 json_object_string_add(json
, "state",
914 zl3vni_state2str(zl3vni
));
915 json_object_string_add(json
, "vrf",
916 zl3vni_vrf_name(zl3vni
));
917 json_object_string_add(json
, "rmac",
918 zl3vni_rmac2str(zl3vni
, buf
,
920 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
921 json_object_array_add(json_vni_list
,
922 json_object_new_int(zvni
->vni
));
924 json_object_object_add(json
, "l2-vnis", json_vni_list
);
929 * Print a specific VNI entry.
931 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
937 json_object
*json
= NULL
;
938 json_object
*json_vtep_list
= NULL
;
939 json_object
*json_ip_str
= NULL
;
945 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
946 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
948 json_object_int_add(json
, "vni", zvni
->vni
);
949 json_object_string_add(json
, "vrf",
950 vrf_id_to_name(zvni
->vrf_id
));
953 if (!zvni
->vxlan_if
) { // unexpected
955 vty_out(vty
, " VxLAN interface: unknown\n");
958 num_macs
= num_valid_macs(zvni
);
959 num_neigh
= hashcount(zvni
->neigh_table
);
961 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
962 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
963 inet_ntoa(zvni
->local_vtep_ip
));
965 json_object_string_add(json
, "vxlanInterface",
966 zvni
->vxlan_if
->name
);
967 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
968 json_object_string_add(json
, "vtepIp",
969 inet_ntoa(zvni
->local_vtep_ip
));
970 json_object_string_add(json
, "advertiseGatewayMacip",
971 zvni
->advertise_gw_macip
? "Yes" : "No");
972 json_object_int_add(json
, "numMacs", num_macs
);
973 json_object_int_add(json
, "numArpNd", num_neigh
);
977 vty_out(vty
, " No remote VTEPs known for this VNI\n");
980 vty_out(vty
, " Remote VTEPs for this VNI:\n");
982 json_vtep_list
= json_object_new_array();
983 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
985 vty_out(vty
, " %s\n",
986 inet_ntoa(zvtep
->vtep_ip
));
988 json_ip_str
= json_object_new_string(
989 inet_ntoa(zvtep
->vtep_ip
));
990 json_object_array_add(json_vtep_list
,
995 json_object_object_add(json
, "numRemoteVteps",
1000 " Number of MACs (local and remote) known for this VNI: %u\n",
1003 " Number of ARPs (IPv4 and IPv6, local and remote) "
1004 "known for this VNI: %u\n",
1006 vty_out(vty
, " Advertise-gw-macip: %s\n",
1007 zvni
->advertise_gw_macip
? "Yes" : "No");
1011 /* print a L3 VNI hash entry */
1012 static void zl3vni_print_hash(struct hash_backet
*backet
,
1015 char buf
[ETHER_ADDR_STRLEN
];
1016 struct vty
*vty
= NULL
;
1017 json_object
*json
= NULL
;
1018 json_object
*json_vni
= NULL
;
1019 zebra_l3vni_t
*zl3vni
= NULL
;
1021 vty
= (struct vty
*)ctx
[0];
1022 json
= (json_object
*)ctx
[1];
1024 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1029 vty_out(vty
, "%-10u %-20s %-20s %-5s %-37s %-18s\n",
1031 zl3vni_vxlan_if_name(zl3vni
),
1032 zl3vni_svi_if_name(zl3vni
),
1033 zl3vni_state2str(zl3vni
),
1034 zl3vni_vrf_name(zl3vni
),
1035 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
1037 char vni_str
[VNI_STR_LEN
];
1039 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1040 json_vni
= json_object_new_object();
1041 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1042 json_object_string_add(json_vni
, "vxlan-if",
1043 zl3vni_vxlan_if_name(zl3vni
));
1044 json_object_string_add(json_vni
, "svi-if",
1045 zl3vni_svi_if_name(zl3vni
));
1046 json_object_string_add(json_vni
, "state",
1047 zl3vni_state2str(zl3vni
));
1048 json_object_string_add(json_vni
, "vrf",
1049 zl3vni_vrf_name(zl3vni
));
1050 json_object_string_add(json_vni
, "rmac",
1051 zl3vni_rmac2str(zl3vni
, buf
,
1053 json_object_object_add(json
, vni_str
, json_vni
);
1059 * Print a VNI hash entry - called for display of all VNIs.
1061 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1065 zebra_vtep_t
*zvtep
;
1066 u_int32_t num_vteps
= 0;
1067 u_int32_t num_macs
= 0;
1068 u_int32_t num_neigh
= 0;
1069 json_object
*json
= NULL
;
1070 json_object
*json_vni
= NULL
;
1071 json_object
*json_ip_str
= NULL
;
1072 json_object
*json_vtep_list
= NULL
;
1077 zvni
= (zebra_vni_t
*)backet
->data
;
1081 zvtep
= zvni
->vteps
;
1084 zvtep
= zvtep
->next
;
1087 num_macs
= num_valid_macs(zvni
);
1088 num_neigh
= hashcount(zvni
->neigh_table
);
1090 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
1092 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1093 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
1095 vrf_id_to_name(zvni
->vrf_id
));
1097 char vni_str
[VNI_STR_LEN
];
1098 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1099 json_vni
= json_object_new_object();
1100 json_object_string_add(json_vni
, "vxlanIf",
1101 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1103 json_object_string_add(json_vni
, "vtepIp",
1104 inet_ntoa(zvni
->local_vtep_ip
));
1105 json_object_int_add(json_vni
, "numMacs", num_macs
);
1106 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1107 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1109 json_vtep_list
= json_object_new_array();
1110 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1111 json_ip_str
= json_object_new_string(
1112 inet_ntoa(zvtep
->vtep_ip
));
1113 json_object_array_add(json_vtep_list
,
1116 json_object_object_add(json_vni
, "remoteVteps",
1119 json_object_object_add(json
, vni_str
, json_vni
);
1124 * Inform BGP about local MACIP.
1126 static int zvni_macip_send_msg_to_client(vni_t vni
,
1127 struct ethaddr
*macaddr
,
1128 struct ipaddr
*ip
, u_char flags
,
1131 char buf
[ETHER_ADDR_STRLEN
];
1132 char buf2
[INET6_ADDRSTRLEN
];
1134 struct zserv
*client
= NULL
;
1135 struct stream
*s
= NULL
;
1137 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1138 /* BGP may not be running. */
1145 zserv_create_header(s
, cmd
, VRF_DEFAULT
);
1146 stream_putl(s
, vni
);
1147 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1150 if (IS_IPADDR_V4(ip
))
1151 ipa_len
= IPV4_MAX_BYTELEN
;
1152 else if (IS_IPADDR_V6(ip
))
1153 ipa_len
= IPV6_MAX_BYTELEN
;
1155 stream_putl(s
, ipa_len
); /* IP address length */
1157 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1159 stream_putl(s
, 0); /* Just MAC. */
1161 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1164 /* Write packet size. */
1165 stream_putw_at(s
, 0, stream_get_endp(s
));
1167 if (IS_ZEBRA_DEBUG_VXLAN
)
1169 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1170 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
1171 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1172 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1173 zebra_route_string(client
->proto
));
1175 if (cmd
== ZEBRA_MACIP_ADD
)
1176 client
->macipadd_cnt
++;
1178 client
->macipdel_cnt
++;
1180 return zebra_server_send_message(client
);
1184 * Make hash key for neighbors.
1186 static unsigned int neigh_hash_keymake(void *p
)
1188 zebra_neigh_t
*n
= p
;
1189 struct ipaddr
*ip
= &n
->ip
;
1191 if (IS_IPADDR_V4(ip
))
1192 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1194 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1195 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1199 * Compare two neighbor hash structures.
1201 static int neigh_cmp(const void *p1
, const void *p2
)
1203 const zebra_neigh_t
*n1
= p1
;
1204 const zebra_neigh_t
*n2
= p2
;
1206 if (n1
== NULL
&& n2
== NULL
)
1209 if (n1
== NULL
|| n2
== NULL
)
1212 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1216 * Callback to allocate neighbor hash entry.
1218 static void *zvni_neigh_alloc(void *p
)
1220 const zebra_neigh_t
*tmp_n
= p
;
1223 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1230 * Add neighbor entry.
1232 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1233 struct ethaddr
*mac
)
1235 zebra_neigh_t tmp_n
;
1236 zebra_neigh_t
*n
= NULL
;
1237 zebra_mac_t
*zmac
= NULL
;
1239 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1240 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1241 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1244 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1245 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1247 /* Associate the neigh to mac */
1248 zmac
= zvni_mac_lookup(zvni
, mac
);
1250 listnode_add_sort(zmac
->neigh_list
, n
);
1256 * Delete neighbor entry.
1258 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1260 zebra_neigh_t
*tmp_n
;
1261 zebra_mac_t
*zmac
= NULL
;
1263 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1265 listnode_delete(zmac
->neigh_list
, n
);
1267 /* Free the VNI hash entry and allocated memory. */
1268 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1270 XFREE(MTYPE_NEIGH
, tmp_n
);
1276 * Free neighbor hash entry (callback)
1278 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1280 struct neigh_walk_ctx
*wctx
= arg
;
1281 zebra_neigh_t
*n
= backet
->data
;
1283 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1284 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1285 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1286 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1287 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1288 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1289 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1290 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1293 if (wctx
->uninstall
)
1294 zvni_neigh_uninstall(wctx
->zvni
, n
);
1296 return zvni_neigh_del(wctx
->zvni
, n
);
1303 * Delete all neighbor entries from specific VTEP for a particular VNI.
1305 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1306 struct in_addr
*r_vtep_ip
)
1308 struct neigh_walk_ctx wctx
;
1310 if (!zvni
->neigh_table
)
1313 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1315 wctx
.uninstall
= uninstall
;
1316 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1317 wctx
.r_vtep_ip
= *r_vtep_ip
;
1319 hash_iterate(zvni
->neigh_table
,
1320 (void (*)(struct hash_backet
*,
1321 void *))zvni_neigh_del_hash_entry
,
1326 * Delete all neighbor entries for this VNI.
1328 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
1329 int uninstall
, int upd_client
, u_int32_t flags
)
1331 struct neigh_walk_ctx wctx
;
1333 if (!zvni
->neigh_table
)
1336 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1338 wctx
.uninstall
= uninstall
;
1339 wctx
.upd_client
= upd_client
;
1342 hash_iterate(zvni
->neigh_table
,
1343 (void (*)(struct hash_backet
*,
1344 void *))zvni_neigh_del_hash_entry
,
1349 * Look up neighbor hash entry.
1351 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1356 memset(&tmp
, 0, sizeof(tmp
));
1357 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1358 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1363 /* Process all neigh associated to a mac upon local mac add event */
1364 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1367 zebra_neigh_t
*n
= NULL
;
1368 struct listnode
*node
= NULL
;
1369 char buf
[ETHER_ADDR_STRLEN
];
1370 char buf2
[INET6_ADDRSTRLEN
];
1372 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1373 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1374 /* MAC is learnt locally, program all inactive neigh
1375 * pointing to this mac */
1376 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1377 if (IS_ZEBRA_DEBUG_VXLAN
)
1379 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1380 ipaddr2str(&n
->ip
, buf2
,
1382 prefix_mac2str(&n
->emac
, buf
,
1386 ZEBRA_NEIGH_SET_ACTIVE(n
);
1387 zvni_neigh_send_add_to_client(
1388 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1390 if (IS_ZEBRA_DEBUG_VXLAN
)
1392 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1393 ipaddr2str(&n
->ip
, buf2
,
1395 prefix_mac2str(&n
->emac
, buf
,
1399 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1400 /* TODO: assume the neigh has moved too ?? */
1405 /* Process all neigh associated to a mac upon local mac del event */
1406 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1409 zebra_neigh_t
*n
= NULL
;
1410 struct listnode
*node
= NULL
;
1411 char buf
[ETHER_ADDR_STRLEN
];
1412 char buf2
[INET6_ADDRSTRLEN
];
1414 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1415 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1416 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1417 if (IS_ZEBRA_DEBUG_VXLAN
)
1419 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1420 ipaddr2str(&n
->ip
, buf2
,
1422 prefix_mac2str(&n
->emac
, buf
,
1426 ZEBRA_NEIGH_SET_INACTIVE(n
);
1427 zvni_neigh_send_del_to_client(
1428 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1430 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1431 if (IS_ZEBRA_DEBUG_VXLAN
)
1433 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1434 prefix_mac2str(&n
->emac
, buf
,
1437 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1442 /* process all neigh associated to a mac entry upon remote mac add */
1443 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1446 zebra_neigh_t
*n
= NULL
;
1447 struct listnode
*node
= NULL
;
1448 char buf
[ETHER_ADDR_STRLEN
];
1449 char buf2
[INET6_ADDRSTRLEN
];
1451 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1452 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1453 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1454 if (IS_ZEBRA_DEBUG_VXLAN
)
1456 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1457 ipaddr2str(&n
->ip
, buf2
,
1459 prefix_mac2str(&n
->emac
, buf
,
1463 ZEBRA_NEIGH_SET_INACTIVE(n
);
1464 zvni_neigh_send_del_to_client(
1465 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1471 /* process all neigh associated to mac entry upon remote mac del */
1472 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1475 zebra_neigh_t
*n
= NULL
;
1476 struct listnode
*node
= NULL
;
1477 char buf
[ETHER_ADDR_STRLEN
];
1478 char buf2
[INET6_ADDRSTRLEN
];
1480 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1481 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1482 if (IS_ZEBRA_DEBUG_VXLAN
)
1484 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1485 prefix_mac2str(&n
->emac
, buf
,
1488 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1494 * Inform BGP about local neighbor addition.
1496 static int zvni_neigh_send_add_to_client(vni_t vni
,
1498 struct ethaddr
*macaddr
, u_char flags
)
1500 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1505 * Inform BGP about local neighbor deletion.
1507 static int zvni_neigh_send_del_to_client(vni_t vni
,
1509 struct ethaddr
*macaddr
, u_char flags
)
1511 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1516 * Install remote neighbor into the kernel.
1518 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1520 struct zebra_if
*zif
;
1521 struct zebra_l2info_vxlan
*vxl
;
1522 struct interface
*vlan_if
;
1524 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1527 zif
= zvni
->vxlan_if
->info
;
1530 vxl
= &zif
->l2info
.vxl
;
1532 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1536 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1540 * Uninstall remote neighbor from the kernel.
1542 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1544 struct zebra_if
*zif
;
1545 struct zebra_l2info_vxlan
*vxl
;
1546 struct interface
*vlan_if
;
1548 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1551 if (!zvni
->vxlan_if
) {
1552 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1557 zif
= zvni
->vxlan_if
->info
;
1560 vxl
= &zif
->l2info
.vxl
;
1561 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1565 return kernel_del_neigh(vlan_if
, &n
->ip
);
1569 * Install neighbor hash entry - called upon access VLAN change.
1571 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1574 struct neigh_walk_ctx
*wctx
= ctxt
;
1576 n
= (zebra_neigh_t
*)backet
->data
;
1580 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1581 zvni_neigh_install(wctx
->zvni
, n
);
1584 /* Get the VRR interface for SVI if any */
1585 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1587 struct zebra_vrf
*zvrf
= NULL
;
1588 struct interface
*tmp_if
= NULL
;
1589 struct zebra_if
*zif
= NULL
;
1591 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1594 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1599 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1602 if (zif
->link
== ifp
)
1609 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1611 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1612 struct connected
*c
= NULL
;
1613 struct ethaddr macaddr
;
1615 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1617 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1620 memset(&ip
, 0, sizeof(struct ipaddr
));
1621 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1624 if (c
->address
->family
== AF_INET
) {
1625 ip
.ipa_type
= IPADDR_V4
;
1626 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1627 sizeof(struct in_addr
));
1628 } else if (c
->address
->family
== AF_INET6
) {
1629 ip
.ipa_type
= IPADDR_V6
;
1630 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1631 sizeof(struct in6_addr
));
1636 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1642 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1644 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1645 struct connected
*c
= NULL
;
1646 struct ethaddr macaddr
;
1648 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1650 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1653 memset(&ip
, 0, sizeof(struct ipaddr
));
1654 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1657 if (c
->address
->family
== AF_INET
) {
1658 ip
.ipa_type
= IPADDR_V4
;
1659 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1660 sizeof(struct in_addr
));
1661 } else if (c
->address
->family
== AF_INET6
) {
1662 ip
.ipa_type
= IPADDR_V6
;
1663 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1664 sizeof(struct in6_addr
));
1669 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1676 * zvni_gw_macip_add_to_client
1678 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1679 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1682 struct ethaddr rmac
;
1683 char buf
[ETHER_ADDR_STRLEN
];
1684 char buf1
[ETHER_ADDR_STRLEN
];
1685 char buf2
[INET6_ADDRSTRLEN
];
1686 zebra_neigh_t
*n
= NULL
;
1687 zebra_mac_t
*mac
= NULL
;
1688 struct zebra_if
*zif
= NULL
;
1689 struct zebra_l2info_vxlan
*vxl
= NULL
;
1691 memset(&rmac
, 0, sizeof(struct ethaddr
));
1693 zif
= zvni
->vxlan_if
->info
;
1697 vxl
= &zif
->l2info
.vxl
;
1699 /* get the l3-vni */
1700 l3vni
= zvni_get_l3vni(zvni
);
1703 zvni_get_rmac(zvni
, &rmac
);
1705 mac
= zvni_mac_lookup(zvni
, macaddr
);
1707 mac
= zvni_mac_add(zvni
, macaddr
);
1709 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1710 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1711 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1716 /* Set "local" forwarding info. */
1717 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1718 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1719 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1720 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1721 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1723 n
= zvni_neigh_lookup(zvni
, ip
);
1725 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1728 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1729 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1730 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1731 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1736 /* Set "local" forwarding info. */
1737 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1738 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1739 n
->ifindex
= ifp
->ifindex
;
1741 if (IS_ZEBRA_DEBUG_VXLAN
)
1743 "SVI %s(%u) L2-VNI %u L3-VNI %u RMAC %s , sending GW MAC %s IP %s add to BGP",
1744 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1746 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)),
1747 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1748 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1750 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1757 * zvni_gw_macip_del_from_client
1759 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1763 struct ethaddr rmac
;
1764 char buf
[ETHER_ADDR_STRLEN
];
1765 char buf1
[ETHER_ADDR_STRLEN
];
1766 char buf2
[INET6_ADDRSTRLEN
];
1767 zebra_neigh_t
*n
= NULL
;
1768 zebra_mac_t
*mac
= NULL
;
1770 memset(&rmac
, 0, sizeof(struct ethaddr
));
1772 /* get the l30vni */
1773 l3vni
= zvni_get_l3vni(zvni
);
1776 zvni_get_rmac(zvni
, &rmac
);
1778 /* If the neigh entry is not present nothing to do*/
1779 n
= zvni_neigh_lookup(zvni
, ip
);
1783 /* mac entry should be present */
1784 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1786 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1787 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1788 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1792 /* If the entry is not local nothing to do*/
1793 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1796 if (IS_ZEBRA_DEBUG_VXLAN
)
1798 "SVI %s(%u) L2-VNI %u, L3-VNI %u RMAC %s sending GW MAC %s IP %s del to BGP",
1799 ifp
->name
, ifp
->ifindex
, zvni
->vni
, l3vni
,
1800 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
1801 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1802 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1804 /* Remove neighbor from BGP. */
1805 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1808 /* Delete this neighbor entry. */
1809 zvni_neigh_del(zvni
, n
);
1811 /* see if the mac needs to be deleted as well*/
1813 zvni_deref_ip2mac(zvni
, mac
, 0);
1818 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1821 zebra_vni_t
*zvni
= NULL
;
1822 struct zebra_if
*zif
= NULL
;
1823 struct zebra_l2info_vxlan zl2_info
;
1824 struct interface
*vlan_if
= NULL
;
1825 struct interface
*vrr_if
= NULL
;
1826 struct interface
*ifp
;
1828 /* Add primary SVI MAC*/
1829 zvni
= (zebra_vni_t
*)backet
->data
;
1833 ifp
= zvni
->vxlan_if
;
1838 /* If down or not mapped to a bridge, we're done. */
1839 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1842 zl2_info
= zif
->l2info
.vxl
;
1844 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1848 /* Del primary MAC-IP */
1849 zvni_del_macip_for_intf(vlan_if
, zvni
);
1851 /* Del VRR MAC-IP - if any*/
1852 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1854 zvni_del_macip_for_intf(vrr_if
, zvni
);
1859 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1862 zebra_vni_t
*zvni
= NULL
;
1863 struct zebra_if
*zif
= NULL
;
1864 struct zebra_l2info_vxlan zl2_info
;
1865 struct interface
*vlan_if
= NULL
;
1866 struct interface
*vrr_if
= NULL
;
1867 struct interface
*ifp
= NULL
;
1869 zvni
= (zebra_vni_t
*)backet
->data
;
1873 if (!advertise_gw_macip_enabled(zvni
))
1876 ifp
= zvni
->vxlan_if
;
1881 /* If down or not mapped to a bridge, we're done. */
1882 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1884 zl2_info
= zif
->l2info
.vxl
;
1886 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1887 zif
->brslave_info
.br_if
);
1891 /* Add primary SVI MAC-IP */
1892 zvni_add_macip_for_intf(vlan_if
, zvni
);
1894 /* Add VRR MAC-IP - if any*/
1895 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1897 zvni_add_macip_for_intf(vrr_if
, zvni
);
1903 * Make hash key for MAC.
1905 static unsigned int mac_hash_keymake(void *p
)
1907 zebra_mac_t
*pmac
= p
;
1908 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1910 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1914 * Compare two MAC addresses.
1916 static int mac_cmp(const void *p1
, const void *p2
)
1918 const zebra_mac_t
*pmac1
= p1
;
1919 const zebra_mac_t
*pmac2
= p2
;
1921 if (pmac1
== NULL
&& pmac2
== NULL
)
1924 if (pmac1
== NULL
|| pmac2
== NULL
)
1927 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1933 * Callback to allocate MAC hash entry.
1935 static void *zvni_mac_alloc(void *p
)
1937 const zebra_mac_t
*tmp_mac
= p
;
1940 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1943 return ((void *)mac
);
1949 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1951 zebra_mac_t tmp_mac
;
1952 zebra_mac_t
*mac
= NULL
;
1954 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1955 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1956 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1959 mac
->neigh_list
= list_new();
1960 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1968 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1970 zebra_mac_t
*tmp_mac
;
1972 list_delete_and_null(&mac
->neigh_list
);
1974 /* Free the VNI hash entry and allocated memory. */
1975 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1977 XFREE(MTYPE_MAC
, tmp_mac
);
1983 * Free MAC hash entry (callback)
1985 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1987 struct mac_walk_ctx
*wctx
= arg
;
1988 zebra_mac_t
*mac
= backet
->data
;
1991 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1992 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1993 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1994 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1995 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1996 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1997 &wctx
->r_vtep_ip
))) {
1998 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1999 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
2001 zvni_mac_send_del_to_client(
2002 wctx
->zvni
->vni
, &mac
->macaddr
,
2003 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
2006 if (wctx
->uninstall
)
2007 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2009 return zvni_mac_del(wctx
->zvni
, mac
);
2016 * Delete all MAC entries from specific VTEP for a particular VNI.
2018 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2019 struct in_addr
*r_vtep_ip
)
2021 struct mac_walk_ctx wctx
;
2023 if (!zvni
->mac_table
)
2026 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2028 wctx
.uninstall
= uninstall
;
2029 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2030 wctx
.r_vtep_ip
= *r_vtep_ip
;
2032 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2033 void *))zvni_mac_del_hash_entry
,
2038 * Delete all MAC entries for this VNI.
2040 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
2041 int uninstall
, int upd_client
, u_int32_t flags
)
2043 struct mac_walk_ctx wctx
;
2045 if (!zvni
->mac_table
)
2048 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2050 wctx
.uninstall
= uninstall
;
2051 wctx
.upd_client
= upd_client
;
2054 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2055 void *))zvni_mac_del_hash_entry
,
2060 * Look up MAC hash entry.
2062 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2067 memset(&tmp
, 0, sizeof(tmp
));
2068 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2069 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2075 * Inform BGP about local MAC addition.
2077 static int zvni_mac_send_add_to_client(vni_t vni
,
2078 struct ethaddr
*macaddr
, u_char flags
)
2080 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2085 * Inform BGP about local MAC deletion.
2087 static int zvni_mac_send_del_to_client(vni_t vni
,
2088 struct ethaddr
*macaddr
, u_char flags
)
2090 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2095 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2096 * notifications, to see if they are of interest.
2098 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2099 struct interface
*br_if
, vlanid_t vid
)
2101 struct zebra_ns
*zns
;
2102 struct route_node
*rn
;
2103 struct interface
*tmp_if
= NULL
;
2104 struct zebra_if
*zif
;
2105 struct zebra_l2info_bridge
*br
;
2106 struct zebra_l2info_vxlan
*vxl
= NULL
;
2107 u_char bridge_vlan_aware
;
2111 /* Determine if bridge is VLAN-aware or not */
2114 br
= &zif
->l2info
.br
;
2115 bridge_vlan_aware
= br
->vlan_aware
;
2117 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2118 /* TODO: Optimize with a hash. */
2119 zns
= zebra_ns_lookup(NS_DEFAULT
);
2120 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2121 tmp_if
= (struct interface
*)rn
->info
;
2125 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2127 if (!if_is_operative(tmp_if
))
2129 vxl
= &zif
->l2info
.vxl
;
2131 if (zif
->brslave_info
.br_if
!= br_if
)
2134 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2143 zvni
= zvni_lookup(vxl
->vni
);
2148 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2149 * neighbor notifications, to see if they are of interest.
2151 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2152 struct interface
*br_if
)
2154 struct zebra_ns
*zns
;
2155 struct route_node
*rn
;
2156 struct interface
*tmp_if
= NULL
;
2157 struct zebra_if
*zif
;
2158 struct zebra_l2info_bridge
*br
;
2159 struct zebra_l2info_vxlan
*vxl
= NULL
;
2160 u_char bridge_vlan_aware
;
2168 /* Make sure the linked interface is a bridge. */
2169 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2172 /* Determine if bridge is VLAN-aware or not */
2175 br
= &zif
->l2info
.br
;
2176 bridge_vlan_aware
= br
->vlan_aware
;
2177 if (bridge_vlan_aware
) {
2178 struct zebra_l2info_vlan
*vl
;
2180 if (!IS_ZEBRA_IF_VLAN(ifp
))
2185 vl
= &zif
->l2info
.vl
;
2189 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
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
;
2197 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2199 if (!if_is_operative(tmp_if
))
2201 vxl
= &zif
->l2info
.vxl
;
2203 if (zif
->brslave_info
.br_if
!= br_if
)
2206 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2215 zvni
= zvni_lookup(vxl
->vni
);
2219 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2221 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2222 * linked to the bridge
2223 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2226 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2228 struct zebra_ns
*zns
;
2229 struct route_node
*rn
;
2230 struct interface
*tmp_if
= NULL
;
2231 struct zebra_if
*zif
;
2232 struct zebra_l2info_bridge
*br
;
2233 struct zebra_l2info_vlan
*vl
;
2234 u_char bridge_vlan_aware
;
2237 /* Defensive check, caller expected to invoke only with valid bridge. */
2241 /* Determine if bridge is VLAN-aware or not */
2244 br
= &zif
->l2info
.br
;
2245 bridge_vlan_aware
= br
->vlan_aware
;
2247 /* Check oper status of the SVI. */
2248 if (!bridge_vlan_aware
)
2249 return if_is_operative(br_if
) ? br_if
: NULL
;
2251 /* Identify corresponding VLAN interface. */
2252 /* TODO: Optimize with a hash. */
2253 zns
= zebra_ns_lookup(NS_DEFAULT
);
2254 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2255 tmp_if
= (struct interface
*)rn
->info
;
2256 /* Check oper status of the SVI. */
2257 if (!tmp_if
|| !if_is_operative(tmp_if
))
2260 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2261 || zif
->link
!= br_if
)
2263 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2265 if (vl
->vid
== vid
) {
2271 return found
? tmp_if
: NULL
;
2275 * Install remote MAC into the kernel.
2277 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2279 struct zebra_if
*zif
;
2280 struct zebra_l2info_vxlan
*vxl
;
2283 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2286 zif
= zvni
->vxlan_if
->info
;
2289 vxl
= &zif
->l2info
.vxl
;
2291 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2293 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2294 mac
->fwd_info
.r_vtep_ip
, sticky
);
2298 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2299 * moves to remote, we have to uninstall any existing local entry first.
2301 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2303 struct zebra_if
*zif
;
2304 struct zebra_l2info_vxlan
*vxl
;
2305 struct in_addr vtep_ip
= {.s_addr
= 0};
2306 struct zebra_ns
*zns
;
2307 struct interface
*ifp
;
2309 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2312 if (!zvni
->vxlan_if
) {
2313 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2318 zif
= zvni
->vxlan_if
->info
;
2321 vxl
= &zif
->l2info
.vxl
;
2324 zns
= zebra_ns_lookup(NS_DEFAULT
);
2325 ifp
= if_lookup_by_index_per_ns(zns
,
2326 mac
->fwd_info
.local
.ifindex
);
2327 if (!ifp
) // unexpected
2330 ifp
= zvni
->vxlan_if
;
2331 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2334 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2339 * Install MAC hash entry - called upon access VLAN change.
2341 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2344 struct mac_walk_ctx
*wctx
= ctxt
;
2346 mac
= (zebra_mac_t
*)backet
->data
;
2350 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2351 zvni_mac_install(wctx
->zvni
, mac
);
2355 * Decrement neighbor refcount of MAC; uninstall and free it if
2358 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2361 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2362 || !list_isempty(mac
->neigh_list
))
2366 zvni_mac_uninstall(zvni
, mac
, 0);
2368 zvni_mac_del(zvni
, mac
);
2372 * Read and populate local MACs and neighbors corresponding to this VNI.
2374 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
2375 struct interface
*ifp
)
2377 struct zebra_ns
*zns
;
2378 struct zebra_if
*zif
;
2379 struct interface
*vlan_if
;
2380 struct zebra_l2info_vxlan
*vxl
;
2381 struct interface
*vrr_if
;
2384 vxl
= &zif
->l2info
.vxl
;
2385 zns
= zebra_ns_lookup(NS_DEFAULT
);
2387 if (IS_ZEBRA_DEBUG_VXLAN
)
2389 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2390 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2391 zif
->brslave_info
.bridge_ifindex
);
2393 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2394 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2397 if (advertise_gw_macip_enabled(zvni
)) {
2398 /* Add SVI MAC-IP */
2399 zvni_add_macip_for_intf(vlan_if
, zvni
);
2401 /* Add VRR MAC-IP - if any*/
2402 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2404 zvni_add_macip_for_intf(vrr_if
, zvni
);
2407 neigh_read_for_vlan(zns
, vlan_if
);
2412 * Hash function for VNI.
2414 static unsigned int vni_hash_keymake(void *p
)
2416 const zebra_vni_t
*zvni
= p
;
2418 return (jhash_1word(zvni
->vni
, 0));
2422 * Compare 2 VNI hash entries.
2424 static int vni_hash_cmp(const void *p1
, const void *p2
)
2426 const zebra_vni_t
*zvni1
= p1
;
2427 const zebra_vni_t
*zvni2
= p2
;
2429 return (zvni1
->vni
== zvni2
->vni
);
2433 * Callback to allocate VNI hash entry.
2435 static void *zvni_alloc(void *p
)
2437 const zebra_vni_t
*tmp_vni
= p
;
2440 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2441 zvni
->vni
= tmp_vni
->vni
;
2442 return ((void *)zvni
);
2446 * Look up VNI hash entry.
2448 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2450 struct zebra_vrf
*zvrf
;
2451 zebra_vni_t tmp_vni
;
2452 zebra_vni_t
*zvni
= NULL
;
2454 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2456 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2458 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2464 * Add VNI hash entry.
2466 static zebra_vni_t
*zvni_add(vni_t vni
)
2468 struct zebra_vrf
*zvrf
;
2469 zebra_vni_t tmp_zvni
;
2470 zebra_vni_t
*zvni
= NULL
;
2472 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2474 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2476 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2479 /* Create hash table for MAC */
2481 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2483 /* Create hash table for neighbors */
2484 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2485 "Zebra VNI Neighbor Table");
2491 * Delete VNI hash entry.
2493 static int zvni_del(zebra_vni_t
*zvni
)
2495 struct zebra_vrf
*zvrf
;
2496 zebra_vni_t
*tmp_zvni
;
2498 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2501 zvni
->vxlan_if
= NULL
;
2503 /* Free the neighbor hash table. */
2504 hash_free(zvni
->neigh_table
);
2505 zvni
->neigh_table
= NULL
;
2507 /* Free the MAC hash table. */
2508 hash_free(zvni
->mac_table
);
2509 zvni
->mac_table
= NULL
;
2511 /* Free the VNI hash entry and allocated memory. */
2512 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2514 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2520 * Inform BGP about local VNI addition.
2522 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2524 struct zserv
*client
;
2527 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2528 /* BGP may not be running. */
2535 zserv_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2536 stream_putl(s
, zvni
->vni
);
2537 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2538 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2540 /* Write packet size. */
2541 stream_putw_at(s
, 0, stream_get_endp(s
));
2543 if (IS_ZEBRA_DEBUG_VXLAN
)
2544 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2545 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2546 vrf_id_to_name(zvni
->vrf_id
),
2547 zebra_route_string(client
->proto
));
2549 client
->vniadd_cnt
++;
2550 return zebra_server_send_message(client
);
2554 * Inform BGP about local VNI deletion.
2556 static int zvni_send_del_to_client(vni_t vni
)
2558 struct zserv
*client
;
2561 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2562 /* BGP may not be running. */
2569 zserv_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2570 stream_putl(s
, vni
);
2572 /* Write packet size. */
2573 stream_putw_at(s
, 0, stream_get_endp(s
));
2575 if (IS_ZEBRA_DEBUG_VXLAN
)
2576 zlog_debug("Send VNI_DEL %u to %s", vni
,
2577 zebra_route_string(client
->proto
));
2579 client
->vnidel_cnt
++;
2580 return zebra_server_send_message(client
);
2584 * Build the VNI hash table by going over the VxLAN interfaces. This
2585 * is called when EVPN (advertise-all-vni) is enabled.
2587 static void zvni_build_hash_table()
2589 struct zebra_ns
*zns
;
2590 struct route_node
*rn
;
2591 struct interface
*ifp
;
2593 /* Walk VxLAN interfaces and create VNI hash. */
2594 zns
= zebra_ns_lookup(NS_DEFAULT
);
2595 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2597 struct zebra_if
*zif
;
2598 struct zebra_l2info_vxlan
*vxl
;
2600 ifp
= (struct interface
*)rn
->info
;
2604 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2607 vxl
= &zif
->l2info
.vxl
;
2610 if (is_vni_l3(vni
)) {
2611 zebra_l3vni_t
*zl3vni
= NULL
;
2613 if (IS_ZEBRA_DEBUG_VXLAN
)
2614 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2615 ifp
->name
, ifp
->ifindex
, vni
);
2617 zl3vni
= zl3vni_lookup(vni
);
2620 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
2621 ifp
->name
, ifp
->ifindex
, vni
);
2625 /* associate with vxlan_if */
2626 zl3vni
->vxlan_if
= ifp
;
2628 /* we need to associate with SVI.
2629 * we can associate with svi-if only after association
2630 * with vxlan-intf is complete */
2631 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2633 if (is_l3vni_oper_up(zl3vni
))
2634 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2637 zebra_vni_t
*zvni
= NULL
;
2638 zebra_l3vni_t
*zl3vni
= NULL
;
2639 struct interface
*vlan_if
= NULL
;
2641 if (IS_ZEBRA_DEBUG_VXLAN
)
2643 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2644 ifp
->name
, ifp
->ifindex
, vni
,
2645 inet_ntoa(vxl
->vtep_ip
));
2647 /* VNI hash entry is not expected to exist. */
2648 zvni
= zvni_lookup(vni
);
2651 "VNI hash already present for IF %s(%u) L2-VNI %u",
2652 ifp
->name
, ifp
->ifindex
, vni
);
2656 zvni
= zvni_add(vni
);
2659 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2660 ifp
->name
, ifp
->ifindex
, vni
);
2664 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2665 zvni
->vxlan_if
= ifp
;
2666 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2667 zif
->brslave_info
.br_if
);
2669 zvni
->vrf_id
= vlan_if
->vrf_id
;
2670 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2672 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2676 /* Inform BGP if intf is up and mapped to bridge. */
2677 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2678 zvni_send_add_to_client(zvni
);
2684 * See if remote VTEP matches with prefix.
2686 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2688 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2692 * Locate remote VTEP in VNI hash table.
2694 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2696 zebra_vtep_t
*zvtep
;
2701 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2702 if (zvni_vtep_match(vtep_ip
, zvtep
))
2710 * Add remote VTEP to VNI hash table.
2712 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2714 zebra_vtep_t
*zvtep
;
2716 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2718 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2722 zvtep
->vtep_ip
= *vtep_ip
;
2725 zvni
->vteps
->prev
= zvtep
;
2726 zvtep
->next
= zvni
->vteps
;
2727 zvni
->vteps
= zvtep
;
2733 * Remove remote VTEP from VNI hash table.
2735 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2738 zvtep
->next
->prev
= zvtep
->prev
;
2740 zvtep
->prev
->next
= zvtep
->next
;
2742 zvni
->vteps
= zvtep
->next
;
2744 zvtep
->prev
= zvtep
->next
= NULL
;
2745 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2751 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2752 * uninstall from kernel if asked to.
2754 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2756 zebra_vtep_t
*zvtep
, *zvtep_next
;
2761 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2762 zvtep_next
= zvtep
->next
;
2764 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2765 zvni_vtep_del(zvni
, zvtep
);
2772 * Install remote VTEP into the kernel.
2774 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2776 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2780 * Uninstall remote VTEP from the kernel.
2782 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2784 if (!zvni
->vxlan_if
) {
2785 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2790 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2794 * Cleanup VNI/VTEP and update kernel
2796 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2798 zebra_vni_t
*zvni
= NULL
;
2799 zebra_l3vni_t
*zl3vni
= NULL
;
2801 zvni
= (zebra_vni_t
*)backet
->data
;
2805 /* remove from l3-vni list */
2806 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
2808 listnode_delete(zl3vni
->l2vnis
, zvni
);
2810 /* Free up all neighbors and MACs, if any. */
2811 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2812 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2814 /* Free up all remote VTEPs, if any. */
2815 zvni_vtep_del_all(zvni
, 1);
2817 /* Delete the hash entry. */
2821 static int is_host_present_in_host_list(struct list
*list
,
2822 struct prefix
*host
)
2824 struct listnode
*node
= NULL
;
2825 struct prefix
*p
= NULL
;
2827 for (ALL_LIST_ELEMENTS_RO(list
, node
, p
)) {
2828 if (prefix_same(p
, host
))
2834 static void host_list_add_host(struct list
*list
,
2835 struct prefix
*host
)
2837 struct prefix
*p
= NULL
;
2839 p
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct prefix
));
2840 memcpy(p
, host
, sizeof(struct prefix
));
2842 listnode_add_sort(list
, p
);
2845 static void host_list_delete_host(struct list
*list
,
2846 struct prefix
*host
)
2848 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
2849 struct prefix
*p
= NULL
;
2851 for (ALL_LIST_ELEMENTS(list
, node
, nnode
, p
)) {
2852 if (prefix_same(p
, host
)) {
2853 XFREE(MTYPE_HOST_PREFIX
, p
);
2859 list_delete_node(list
, node_to_del
);
2863 * Look up MAC hash entry.
2865 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
2866 struct ethaddr
*rmac
)
2871 memset(&tmp
, 0, sizeof(tmp
));
2872 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
2873 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
2879 * Callback to allocate RMAC hash entry.
2881 static void *zl3vni_rmac_alloc(void *p
)
2883 const zebra_mac_t
*tmp_rmac
= p
;
2886 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2889 return ((void *)zrmac
);
2893 * Add RMAC entry to l3-vni
2895 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
2896 struct ethaddr
*rmac
)
2898 zebra_mac_t tmp_rmac
;
2899 zebra_mac_t
*zrmac
= NULL
;
2901 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
2902 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
2903 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
2906 zrmac
->host_list
= list_new();
2907 zrmac
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
2909 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
2910 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
2918 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
,
2921 zebra_mac_t
*tmp_rmac
;
2923 if (zrmac
->host_list
)
2924 list_delete(zrmac
->host_list
);
2925 zrmac
->host_list
= NULL
;
2927 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
2929 XFREE(MTYPE_MAC
, tmp_rmac
);
2935 * Install remote RMAC into the kernel.
2937 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
,
2940 struct zebra_if
*zif
= NULL
;
2941 struct zebra_l2info_vxlan
*vxl
= NULL
;
2943 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2944 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2947 zif
= zl3vni
->vxlan_if
->info
;
2951 vxl
= &zif
->l2info
.vxl
;
2953 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2955 zrmac
->fwd_info
.r_vtep_ip
, 0);
2959 * Uninstall remote RMAC from the kernel.
2961 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
2964 char buf
[ETHER_ADDR_STRLEN
];
2965 struct zebra_if
*zif
= NULL
;
2966 struct zebra_l2info_vxlan
*vxl
= NULL
;
2968 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2969 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2972 if (!zl3vni
->vxlan_if
) {
2973 zlog_err("RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
2974 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
2975 zl3vni
->vni
, zl3vni
);
2979 zif
= zl3vni
->vxlan_if
->info
;
2983 vxl
= &zif
->l2info
.vxl
;
2985 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2986 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
2989 /* handle rmac add */
2990 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
,
2991 struct ethaddr
*rmac
,
2992 struct ipaddr
*vtep_ip
,
2993 struct prefix
*host_prefix
)
2995 char buf
[ETHER_ADDR_STRLEN
];
2996 char buf1
[INET6_ADDRSTRLEN
];
2997 zebra_mac_t
*zrmac
= NULL
;
2999 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3002 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3005 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3006 prefix_mac2str(rmac
, buf
,
3008 zl3vni
->vni
, ipaddr2str(vtep_ip
, buf1
,
3012 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3013 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3015 /* install rmac in kernel */
3016 zl3vni_rmac_install(zl3vni
, zrmac
);
3019 if (!is_host_present_in_host_list(zrmac
->host_list
, host_prefix
))
3020 host_list_add_host(zrmac
->host_list
, host_prefix
);
3025 /* handle rmac delete */
3026 static int zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
,
3027 struct ethaddr
*rmac
,
3028 struct prefix
*host_prefix
)
3030 zebra_mac_t
*zrmac
= NULL
;
3032 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3036 host_list_delete_host(zrmac
->host_list
, host_prefix
);
3037 if (list_isempty(zrmac
->host_list
)) {
3039 /* uninstall from kernel */
3040 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3042 /* del the rmac entry */
3043 zl3vni_rmac_del(zl3vni
, zrmac
);
3049 * Look up nh hash entry on a l3-vni.
3051 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
3057 memset(&tmp
, 0, sizeof(tmp
));
3058 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3059 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3066 * Callback to allocate NH hash entry on L3-VNI.
3068 static void *zl3vni_nh_alloc(void *p
)
3070 const zebra_neigh_t
*tmp_n
= p
;
3073 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3080 * Add neighbor entry.
3082 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
3084 struct ethaddr
*mac
)
3086 zebra_neigh_t tmp_n
;
3087 zebra_neigh_t
*n
= NULL
;
3089 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3090 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3091 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3094 n
->host_list
= list_new();
3095 n
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
3097 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3098 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3099 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3105 * Delete neighbor entry.
3107 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
,
3110 zebra_neigh_t
*tmp_n
;
3113 list_delete(n
->host_list
);
3114 n
->host_list
= NULL
;
3116 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3118 XFREE(MTYPE_NEIGH
, tmp_n
);
3124 * Install remote nh as neigh into the kernel.
3126 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
,
3129 if (!is_l3vni_oper_up(zl3vni
))
3132 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3133 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3136 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3140 * Uninstall remote nh from the kernel.
3142 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
,
3145 if (!is_l3vni_oper_up(zl3vni
))
3148 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3149 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3152 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3155 /* add remote vtep as a neigh entry */
3156 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
,
3157 struct ipaddr
*vtep_ip
,
3158 struct ethaddr
*rmac
,
3159 struct prefix
*host_prefix
)
3161 char buf
[ETHER_ADDR_STRLEN
];
3162 char buf1
[INET6_ADDRSTRLEN
];
3163 zebra_neigh_t
*nh
= NULL
;
3165 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3167 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3171 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3172 ipaddr2str(vtep_ip
, buf1
,
3174 prefix_mac2str(rmac
, buf
,
3180 /* install the nh neigh in kernel */
3181 zl3vni_nh_install(zl3vni
, nh
);
3184 if (!is_host_present_in_host_list(nh
->host_list
, host_prefix
))
3185 host_list_add_host(nh
->host_list
, host_prefix
);
3190 /* handle nh neigh delete */
3191 static int zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
,
3192 struct ipaddr
*vtep_ip
,
3193 struct prefix
*host_prefix
)
3195 zebra_neigh_t
*nh
= NULL
;
3197 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3201 host_list_delete_host(nh
->host_list
, host_prefix
);
3202 if (list_isempty(nh
->host_list
)) {
3204 /* uninstall from kernel */
3205 zl3vni_nh_uninstall(zl3vni
, nh
);
3207 /* delete the nh entry */
3208 zl3vni_nh_del(zl3vni
, nh
);
3215 * Hash function for L3 VNI.
3217 static unsigned int l3vni_hash_keymake(void *p
)
3219 const zebra_l3vni_t
*zl3vni
= p
;
3221 return jhash_1word(zl3vni
->vni
, 0);
3225 * Compare 2 L3 VNI hash entries.
3227 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3229 const zebra_l3vni_t
*zl3vni1
= p1
;
3230 const zebra_l3vni_t
*zl3vni2
= p2
;
3232 return (zl3vni1
->vni
== zl3vni2
->vni
);
3236 * Callback to allocate L3 VNI hash entry.
3238 static void *zl3vni_alloc(void *p
)
3240 zebra_l3vni_t
*zl3vni
= NULL
;
3241 const zebra_l3vni_t
*tmp_l3vni
= p
;
3243 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3244 zl3vni
->vni
= tmp_l3vni
->vni
;
3245 return ((void *)zl3vni
);
3249 * Look up L3 VNI hash entry.
3251 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3253 struct zebra_ns
*zns
;
3254 zebra_l3vni_t tmp_l3vni
;
3255 zebra_l3vni_t
*zl3vni
= NULL
;
3257 zns
= zebra_ns_lookup(NS_DEFAULT
);
3259 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3260 tmp_l3vni
.vni
= vni
;
3261 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3267 * Add L3 VNI hash entry.
3269 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3271 zebra_l3vni_t tmp_zl3vni
;
3272 struct zebra_ns
*zns
= NULL
;
3273 zebra_l3vni_t
*zl3vni
= NULL
;
3275 zns
= zebra_ns_lookup(NS_DEFAULT
);
3278 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3279 tmp_zl3vni
.vni
= vni
;
3281 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3284 zl3vni
->vrf_id
= vrf_id
;
3285 zl3vni
->svi_if
= NULL
;
3286 zl3vni
->vxlan_if
= NULL
;
3287 zl3vni
->l2vnis
= list_new();
3288 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3290 /* Create hash table for remote RMAC */
3291 zl3vni
->rmac_table
=
3292 hash_create(mac_hash_keymake
, mac_cmp
,
3293 "Zebra L3-VNI RMAC-Table");
3295 /* Create hash table for neighbors */
3296 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3297 "Zebra L3-VNI next-hop table");
3303 * Delete L3 VNI hash entry.
3305 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3307 struct zebra_ns
*zns
;
3308 zebra_l3vni_t
*tmp_zl3vni
;
3310 zns
= zebra_ns_lookup(NS_DEFAULT
);
3313 /* free the list of l2vnis */
3314 list_delete_and_null(&zl3vni
->l2vnis
);
3315 zl3vni
->l2vnis
= NULL
;
3317 /* Free the rmac table */
3318 hash_free(zl3vni
->rmac_table
);
3319 zl3vni
->rmac_table
= NULL
;
3321 /* Free the nh table */
3322 hash_free(zl3vni
->nh_table
);
3323 zl3vni
->nh_table
= NULL
;
3325 /* Free the VNI hash entry and allocated memory. */
3326 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3328 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3333 static int is_vni_l3(vni_t vni
)
3335 zebra_l3vni_t
*zl3vni
= NULL
;
3337 zl3vni
= zl3vni_lookup(vni
);
3343 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3345 struct zebra_ns
*zns
= NULL
;
3346 struct route_node
*rn
= NULL
;
3347 struct interface
*ifp
= NULL
;
3349 /* loop through all vxlan-interface */
3350 zns
= zebra_ns_lookup(NS_DEFAULT
);
3351 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3353 struct zebra_if
*zif
= NULL
;
3354 struct zebra_l2info_vxlan
*vxl
= NULL
;
3356 ifp
= (struct interface
*)rn
->info
;
3361 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3364 vxl
= &zif
->l2info
.vxl
;
3365 if (vxl
->vni
== zl3vni
->vni
)
3372 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3374 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3375 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3377 if (!zl3vni
->vxlan_if
)
3380 zif
= zl3vni
->vxlan_if
->info
;
3384 vxl
= &zif
->l2info
.vxl
;
3386 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3389 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3391 struct zebra_vrf
*zvrf
= NULL
;
3393 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3397 return zl3vni_lookup(zvrf
->l3vni
);
3401 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3402 * neighbor notifications, to see if they are of interest.
3404 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3405 struct interface
*br_if
)
3409 u_char bridge_vlan_aware
= 0;
3410 zebra_l3vni_t
*zl3vni
= NULL
;
3411 struct zebra_ns
*zns
= NULL
;
3412 struct route_node
*rn
= NULL
;
3413 struct zebra_if
*zif
= NULL
;
3414 struct interface
*tmp_if
= NULL
;
3415 struct zebra_l2info_bridge
*br
= NULL
;
3416 struct zebra_l2info_vxlan
*vxl
= NULL
;
3421 /* Make sure the linked interface is a bridge. */
3422 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3425 /* Determine if bridge is VLAN-aware or not */
3428 br
= &zif
->l2info
.br
;
3429 bridge_vlan_aware
= br
->vlan_aware
;
3430 if (bridge_vlan_aware
) {
3431 struct zebra_l2info_vlan
*vl
;
3433 if (!IS_ZEBRA_IF_VLAN(ifp
))
3438 vl
= &zif
->l2info
.vl
;
3442 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3443 /* TODO: Optimize with a hash. */
3444 zns
= zebra_ns_lookup(NS_DEFAULT
);
3445 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3446 tmp_if
= (struct interface
*)rn
->info
;
3450 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3452 if (!if_is_operative(tmp_if
))
3454 vxl
= &zif
->l2info
.vxl
;
3456 if (zif
->brslave_info
.br_if
!= br_if
)
3459 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3468 zl3vni
= zl3vni_lookup(vxl
->vni
);
3473 * Inform BGP about l3-vni.
3475 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3477 struct stream
*s
= NULL
;
3478 struct zserv
*client
= NULL
;
3479 struct ethaddr rmac
;
3480 char buf
[ETHER_ADDR_STRLEN
];
3482 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3483 /* BGP may not be running. */
3488 memset(&rmac
, 0, sizeof(struct ethaddr
));
3489 zl3vni_get_rmac(zl3vni
, &rmac
);
3494 zserv_create_header(s
, ZEBRA_L3VNI_ADD
,
3495 zl3vni_vrf_id(zl3vni
));
3496 stream_putl(s
, zl3vni
->vni
);
3497 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3499 /* Write packet size. */
3500 stream_putw_at(s
, 0, stream_get_endp(s
));
3502 if (IS_ZEBRA_DEBUG_VXLAN
)
3503 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s to %s",
3504 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3505 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3506 zebra_route_string(client
->proto
));
3508 client
->l3vniadd_cnt
++;
3509 return zebra_server_send_message(client
);
3513 * Inform BGP about local l3-VNI deletion.
3515 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3517 struct stream
*s
= NULL
;
3518 struct zserv
*client
= NULL
;
3520 client
= zebra_find_client(ZEBRA_ROUTE_BGP
);
3521 /* BGP may not be running. */
3528 zserv_create_header(s
, ZEBRA_L3VNI_DEL
,
3529 zl3vni_vrf_id(zl3vni
));
3530 stream_putl(s
, zl3vni
->vni
);
3532 /* Write packet size. */
3533 stream_putw_at(s
, 0, stream_get_endp(s
));
3535 if (IS_ZEBRA_DEBUG_VXLAN
)
3536 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3538 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3539 zebra_route_string(client
->proto
));
3541 client
->l3vnidel_cnt
++;
3542 return zebra_server_send_message(client
);
3545 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3547 if (IS_ZEBRA_DEBUG_VXLAN
)
3548 zlog_debug("L3-VNI %u is UP - send add to BGP and update all neigh enries",
3551 /* send l3vni add to BGP */
3552 zl3vni_send_add_to_client(zl3vni
);
3555 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3557 if (IS_ZEBRA_DEBUG_VXLAN
)
3558 zlog_debug("L3-VNI %u is Down - send del to BGP and update all neigh enries",
3561 /* send l3-vni del to BGP*/
3562 zl3vni_send_del_to_client(zl3vni
);
3565 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
,
3568 zebra_vni_t
*zvni
= (zebra_vni_t
*) backet
->data
;
3569 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*) ctxt
;
3571 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3572 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3575 /* l3vni from zvni */
3576 static vni_t
zvni_get_l3vni(zebra_vni_t
*zvni
)
3578 zebra_l3vni_t
*zl3vni
= NULL
;
3580 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3581 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3587 /* rmac from l3vni */
3588 static void zvni_get_rmac(zebra_vni_t
*zvni
,
3589 struct ethaddr
*rmac
)
3591 zebra_l3vni_t
*zl3vni
= NULL
;
3593 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
3594 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3598 memcpy(rmac
->octet
, zl3vni
->svi_if
->hw_addr
, ETH_ALEN
);
3602 * handle transition of vni from l2 to l3 and vice versa
3604 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
,
3607 zebra_vni_t
*zvni
= NULL
;
3609 /* There is a possibility that VNI notification was already received
3610 * from kernel and we programmed it as L2-VNI
3611 * In such a case we need to delete this L2-VNI first, so
3612 * that it can be reprogrammed as L3-VNI in the system. It is also
3613 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3614 * interface is still present in kernel. In this case to keep it
3615 * symmetric, we will delete the l3-vni and reprogram it as l2-vni */
3617 /* Locate hash entry */
3618 zvni
= zvni_lookup(vni
);
3622 if (IS_ZEBRA_DEBUG_VXLAN
)
3623 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3626 /* Delete VNI from BGP. */
3627 zvni_send_del_to_client(zvni
->vni
);
3629 /* Free up all neighbors and MAC, if any. */
3630 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3631 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3633 /* Free up all remote VTEPs, if any. */
3634 zvni_vtep_del_all(zvni
, 0);
3636 /* Delete the hash entry. */
3637 if (zvni_del(zvni
)) {
3638 zlog_err("Failed to del VNI hash %p, VNI %u",
3643 /* TODO_MITESH: This needs to be thought through. We don't have
3644 * enough information at this point to reprogram the vni as
3645 * l2-vni. One way is to store the required info in l3-vni and
3646 * used it solely for this purpose */
3652 /* Public functions */
3654 /* handle evpn route in vrf table */
3655 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
,
3656 struct ethaddr
*rmac
,
3657 struct ipaddr
*vtep_ip
,
3658 struct prefix
*host_prefix
)
3660 zebra_l3vni_t
*zl3vni
= NULL
;
3662 zl3vni
= zl3vni_from_vrf(vrf_id
);
3663 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3666 /* add the next hop neighbor */
3667 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
3670 zl3vni_remote_rmac_add(zl3vni
, rmac
, vtep_ip
, host_prefix
);
3673 /* handle evpn vrf route delete */
3674 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
3675 struct ethaddr
*rmac
,
3676 struct ipaddr
*vtep_ip
,
3677 struct prefix
*host_prefix
)
3679 zebra_l3vni_t
*zl3vni
= NULL
;
3681 zl3vni
= zl3vni_from_vrf(vrf_id
);
3682 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3685 /* delete the next hop entry */
3686 zl3vni_remote_nh_del(zl3vni
, vtep_ip
, host_prefix
);
3688 /* delete the rmac entry */
3689 zl3vni_remote_rmac_del(zl3vni
, rmac
, host_prefix
);
3692 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
,
3694 struct ethaddr
*rmac
)
3696 zebra_l3vni_t
*zl3vni
= NULL
;
3697 zebra_mac_t
*zrmac
= NULL
;
3699 if (!is_evpn_enabled())
3702 zl3vni
= zl3vni_lookup(l3vni
);
3704 vty_out(vty
, "%% L3-VNI %u doesnt exist\n",
3709 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3711 vty_out(vty
, "%% Requested RMAC doesnt exist in L3-VNI %u",
3716 zl3vni_print_rmac(zrmac
, vty
);
3719 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
,
3723 zebra_l3vni_t
*zl3vni
;
3724 u_int32_t num_rmacs
;
3725 struct rmac_walk_ctx wctx
;
3726 json_object
*json
= NULL
;
3727 json_object
*json_rmac
= NULL
;
3729 if (!is_evpn_enabled())
3732 zl3vni
= zl3vni_lookup(l3vni
);
3735 vty_out(vty
, "{}\n");
3737 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3740 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3745 json
= json_object_new_object();
3746 json_rmac
= json_object_new_array();
3749 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3751 wctx
.json
= json_rmac
;
3755 "Number of Remote RMACs known for this VNI: %u\n",
3757 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
3758 "Remote VTEP", "Refcnt");
3760 json_object_int_add(json
, "numRmacs", num_rmacs
);
3762 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3765 json_object_object_add(json
, "rmacs", json_rmac
);
3766 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3767 json
, JSON_C_TO_STRING_PRETTY
));
3768 json_object_free(json
);
3772 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
,
3775 struct zebra_ns
*zns
= NULL
;
3776 json_object
*json
= NULL
;
3779 if (!is_evpn_enabled()) {
3781 vty_out(vty
, "{}\n");
3785 zns
= zebra_ns_lookup(NS_DEFAULT
);
3788 vty_out(vty
, "{}\n");
3793 json
= json_object_new_object();
3797 hash_iterate(zns
->l3vni_table
,
3798 (void (*)(struct hash_backet
*,
3799 void *))zl3vni_print_rmac_hash_all_vni
,
3803 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3804 json
, JSON_C_TO_STRING_PRETTY
));
3805 json_object_free(json
);
3809 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
,
3814 zebra_l3vni_t
*zl3vni
= NULL
;
3815 zebra_neigh_t
*n
= NULL
;
3816 json_object
*json
= NULL
;
3818 if (!is_evpn_enabled()) {
3820 vty_out(vty
, "{}\n");
3825 json
= json_object_new_object();
3827 zl3vni
= zl3vni_lookup(l3vni
);
3830 vty_out(vty
, "{}\n");
3832 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3836 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3839 vty_out(vty
, "{}\n");
3842 "%% Requested next-hop not present for L3-VNI %u",
3847 zl3vni_print_nh(n
, vty
, json
);
3850 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3851 json
, JSON_C_TO_STRING_PRETTY
));
3852 json_object_free(json
);
3856 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
,
3861 struct nh_walk_ctx wctx
;
3862 json_object
*json
= NULL
;
3863 zebra_l3vni_t
*zl3vni
= NULL
;
3865 if (!is_evpn_enabled())
3868 zl3vni
= zl3vni_lookup(l3vni
);
3871 vty_out(vty
, "{}\n");
3873 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3877 num_nh
= hashcount(zl3vni
->nh_table
);
3882 json
= json_object_new_object();
3888 "Number of NH Neighbors known for this VNI: %u\n",
3890 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
3893 json_object_int_add(json
, "numNh", num_nh
);
3895 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
3898 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3899 json
, JSON_C_TO_STRING_PRETTY
));
3900 json_object_free(json
);
3904 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
,
3907 struct zebra_ns
*zns
= NULL
;
3908 json_object
*json
= NULL
;
3911 if (!is_evpn_enabled()) {
3913 vty_out(vty
, "{}\n");
3917 zns
= zebra_ns_lookup(NS_DEFAULT
);
3922 json
= json_object_new_object();
3926 hash_iterate(zns
->l3vni_table
,
3927 (void (*)(struct hash_backet
*,
3928 void *))zl3vni_print_nh_hash_all_vni
,
3932 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3933 json
, JSON_C_TO_STRING_PRETTY
));
3934 json_object_free(json
);
3940 * Display L3 VNI information (VTY command handler).
3942 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
3945 json_object
*json
= NULL
;
3946 zebra_l3vni_t
*zl3vni
= NULL
;
3948 if (!is_evpn_enabled()) {
3950 vty_out(vty
, "{}\n");
3954 zl3vni
= zl3vni_lookup(vni
);
3957 vty_out(vty
, "{}\n");
3959 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
3964 json
= json_object_new_object();
3968 zl3vni_print(zl3vni
, (void *)args
);
3971 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3972 json
, JSON_C_TO_STRING_PRETTY
));
3973 json_object_free(json
);
3978 * Display L3 VNI hash table (VTY command handler).
3980 void zebra_vxlan_print_l3vnis(struct vty
*vty
, u_char use_json
)
3984 json_object
*json
= NULL
;
3985 struct zebra_ns
*zns
= NULL
;
3987 if (!is_evpn_enabled()) {
3989 vty_out(vty
, "{}\n");
3993 zns
= zebra_ns_lookup(NS_DEFAULT
);
3996 num_vnis
= hashcount(zns
->l3vni_table
);
3999 vty_out(vty
, "{}\n");
4004 json
= json_object_new_object();
4005 json_object_int_add(json
, "numVnis", num_vnis
);
4007 vty_out(vty
, "Number of L3 VNIs: %u\n", num_vnis
);
4008 vty_out(vty
, "%-10s %-20s %-20s %-5s %-37s %-18s\n", "VNI",
4009 "Vx-intf", "L3-SVI", "State", "VRF", "Rmac");
4014 hash_iterate(zns
->l3vni_table
,
4015 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
4019 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4020 json
, JSON_C_TO_STRING_PRETTY
));
4021 json_object_free(json
);
4026 * Display Neighbors for a VNI (VTY command handler).
4028 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4029 vni_t vni
, u_char use_json
)
4032 u_int32_t num_neigh
;
4033 struct neigh_walk_ctx wctx
;
4034 json_object
*json
= NULL
;
4036 if (!is_evpn_enabled())
4038 zvni
= zvni_lookup(vni
);
4041 vty_out(vty
, "{}\n");
4043 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4046 num_neigh
= hashcount(zvni
->neigh_table
);
4051 json
= json_object_new_object();
4053 /* Since we have IPv6 addresses to deal with which can vary widely in
4054 * size, we try to be a bit more elegant in display by first computing
4055 * the maximum width.
4057 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4060 wctx
.addr_width
= 15;
4062 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4066 "Number of ARPs (local and remote) known for this VNI: %u\n",
4068 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
4069 "Type", "MAC", "Remote VTEP");
4071 json_object_int_add(json
, "numArpNd", num_neigh
);
4073 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4075 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4076 json
, JSON_C_TO_STRING_PRETTY
));
4077 json_object_free(json
);
4082 * Display neighbors across all VNIs (VTY command handler).
4084 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4087 json_object
*json
= NULL
;
4090 if (!is_evpn_enabled())
4094 json
= json_object_new_object();
4098 hash_iterate(zvrf
->vni_table
,
4099 (void (*)(struct hash_backet
*,
4100 void *))zvni_print_neigh_hash_all_vni
,
4103 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4104 json
, JSON_C_TO_STRING_PRETTY
));
4105 json_object_free(json
);
4110 * Display specific neighbor for a VNI, if present (VTY command handler).
4112 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4113 struct zebra_vrf
*zvrf
, vni_t vni
,
4114 struct ipaddr
*ip
, u_char use_json
)
4118 json_object
*json
= NULL
;
4120 if (!is_evpn_enabled())
4122 zvni
= zvni_lookup(vni
);
4125 vty_out(vty
, "{}\n");
4127 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4130 n
= zvni_neigh_lookup(zvni
, ip
);
4134 "%% Requested neighbor does not exist in VNI %u\n",
4139 json
= json_object_new_object();
4141 zvni_print_neigh(n
, vty
, json
);
4144 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4145 json
, JSON_C_TO_STRING_PRETTY
));
4146 json_object_free(json
);
4151 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4152 * By definition, these are remote neighbors.
4154 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4155 vni_t vni
, struct in_addr vtep_ip
,
4159 u_int32_t num_neigh
;
4160 struct neigh_walk_ctx wctx
;
4161 json_object
*json
= NULL
;
4163 if (!is_evpn_enabled())
4165 zvni
= zvni_lookup(vni
);
4168 vty_out(vty
, "{}\n");
4170 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4173 num_neigh
= hashcount(zvni
->neigh_table
);
4177 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4180 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4181 wctx
.r_vtep_ip
= vtep_ip
;
4183 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4186 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4187 json
, JSON_C_TO_STRING_PRETTY
));
4188 json_object_free(json
);
4193 * Display MACs for a VNI (VTY command handler).
4195 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4196 vni_t vni
, u_char use_json
)
4200 struct mac_walk_ctx wctx
;
4201 json_object
*json
= NULL
;
4202 json_object
*json_mac
= NULL
;
4204 if (!is_evpn_enabled())
4206 zvni
= zvni_lookup(vni
);
4209 vty_out(vty
, "{}\n");
4211 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4214 num_macs
= num_valid_macs(zvni
);
4219 json
= json_object_new_object();
4220 json_mac
= json_object_new_object();
4223 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4226 wctx
.json
= json_mac
;
4230 "Number of MACs (local and remote) known for this VNI: %u\n",
4232 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4233 "Intf/Remote VTEP", "VLAN");
4235 json_object_int_add(json
, "numMacs", num_macs
);
4237 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4240 json_object_object_add(json
, "macs", json_mac
);
4241 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4242 json
, JSON_C_TO_STRING_PRETTY
));
4243 json_object_free(json
);
4248 * Display MACs for all VNIs (VTY command handler).
4250 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4253 struct mac_walk_ctx wctx
;
4254 json_object
*json
= NULL
;
4256 if (!is_evpn_enabled()) {
4258 vty_out(vty
, "{}\n");
4262 json
= json_object_new_object();
4264 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4267 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4270 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4271 json
, JSON_C_TO_STRING_PRETTY
));
4272 json_object_free(json
);
4277 * Display MACs for all VNIs (VTY command handler).
4279 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4280 struct zebra_vrf
*zvrf
,
4281 struct in_addr vtep_ip
,
4284 struct mac_walk_ctx wctx
;
4285 json_object
*json
= NULL
;
4287 if (!is_evpn_enabled())
4291 json
= json_object_new_object();
4293 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4295 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4296 wctx
.r_vtep_ip
= vtep_ip
;
4298 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4301 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4302 json
, JSON_C_TO_STRING_PRETTY
));
4303 json_object_free(json
);
4308 * Display specific MAC for a VNI, if present (VTY command handler).
4310 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4311 vni_t vni
, struct ethaddr
*macaddr
)
4316 if (!is_evpn_enabled())
4318 zvni
= zvni_lookup(vni
);
4320 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4323 mac
= zvni_mac_lookup(zvni
, macaddr
);
4325 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4330 zvni_print_mac(mac
, vty
);
4334 * Display MACs for a VNI from specific VTEP (VTY command handler).
4336 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4337 vni_t vni
, struct in_addr vtep_ip
,
4342 struct mac_walk_ctx wctx
;
4343 json_object
*json
= NULL
;
4344 json_object
*json_mac
= NULL
;
4346 if (!is_evpn_enabled())
4348 zvni
= zvni_lookup(vni
);
4351 vty_out(vty
, "{}\n");
4353 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4356 num_macs
= num_valid_macs(zvni
);
4361 json
= json_object_new_object();
4362 json_mac
= json_object_new_object();
4365 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4368 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4369 wctx
.r_vtep_ip
= vtep_ip
;
4370 wctx
.json
= json_mac
;
4371 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4374 json_object_int_add(json
, "numMacs", wctx
.count
);
4376 json_object_object_add(json
, "macs", json_mac
);
4377 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4378 json
, JSON_C_TO_STRING_PRETTY
));
4379 json_object_free(json
);
4385 * Display VNI information (VTY command handler).
4387 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4391 json_object
*json
= NULL
;
4394 if (!is_evpn_enabled())
4396 zvni
= zvni_lookup(vni
);
4399 vty_out(vty
, "{}\n");
4401 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4405 json
= json_object_new_object();
4408 zvni_print(zvni
, (void *)args
);
4410 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4411 json
, JSON_C_TO_STRING_PRETTY
));
4412 json_object_free(json
);
4417 * Display VNI hash table (VTY command handler).
4419 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4423 json_object
*json
= NULL
;
4426 if (!is_evpn_enabled())
4428 num_vnis
= hashcount(zvrf
->vni_table
);
4431 vty_out(vty
, "{}\n");
4435 json
= json_object_new_object();
4436 json_object_string_add(json
, "advertiseGatewayMacip",
4437 zvrf
->advertise_gw_macip
? "Yes" : "No");
4438 json_object_int_add(json
, "numVnis", num_vnis
);
4440 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4441 zvrf
->advertise_gw_macip
? "Yes" : "No");
4442 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
4443 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
4444 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
4445 "# Remote VTEPs", "VRF");
4450 hash_iterate(zvrf
->vni_table
,
4451 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4455 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4456 json
, JSON_C_TO_STRING_PRETTY
));
4457 json_object_free(json
);
4462 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4463 * kernel. This may result in either the neighbor getting deleted from
4464 * our database or being re-added to the kernel (if it is a valid
4467 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4468 struct interface
*link_if
, struct ipaddr
*ip
)
4471 struct ethaddr rmac
;
4472 char buf
[INET6_ADDRSTRLEN
];
4473 char buf1
[INET6_ADDRSTRLEN
];
4474 char buf2
[ETHER_ADDR_STRLEN
];
4475 zebra_neigh_t
*n
= NULL
;
4476 zebra_vni_t
*zvni
= NULL
;
4477 zebra_mac_t
*zmac
= NULL
;
4479 memset(&rmac
, 0, sizeof(struct ethaddr
));
4481 /* We are only interested in neighbors on an SVI that resides on top
4482 * of a VxLAN bridge.
4484 zvni
= zvni_from_svi(ifp
, link_if
);
4487 if (!zvni
->vxlan_if
) {
4489 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4494 /* get the l3-vni */
4495 l3vni
= zvni_get_l3vni(zvni
);
4498 zvni_get_rmac(zvni
, &rmac
);
4500 if (IS_ZEBRA_DEBUG_VXLAN
)
4501 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u L3-VNI %u RMAC %s",
4502 ipaddr2str(ip
, buf
, sizeof(buf
)),
4503 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
4504 l3vni
, prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4506 /* If entry doesn't exist, nothing to do. */
4507 n
= zvni_neigh_lookup(zvni
, ip
);
4511 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4513 if (IS_ZEBRA_DEBUG_VXLAN
)
4515 "Trying to del a neigh %s without a mac %s on VNI %u",
4516 ipaddr2str(ip
, buf
, sizeof(buf
)),
4517 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4523 /* If it is a remote entry, the kernel has aged this out or someone has
4524 * deleted it, it needs to be re-installed as Quagga is the owner.
4526 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4527 zvni_neigh_install(zvni
, n
);
4531 /* Remove neighbor from BGP. */
4532 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4533 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
4536 /* Delete this neighbor entry. */
4537 zvni_neigh_del(zvni
, n
);
4539 /* see if the AUTO mac needs to be deleted */
4540 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4541 && !listcount(zmac
->neigh_list
))
4542 zvni_mac_del(zvni
, zmac
);
4548 * Handle neighbor add or update (on a VLAN device / L3 interface)
4551 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4552 struct interface
*link_if
,
4554 struct ethaddr
*macaddr
, u_int16_t state
,
4558 struct ethaddr rmac
;
4559 char buf
[ETHER_ADDR_STRLEN
];
4560 char buf1
[ETHER_ADDR_STRLEN
];
4561 char buf2
[INET6_ADDRSTRLEN
];
4562 zebra_vni_t
*zvni
= NULL
;
4563 zebra_neigh_t
*n
= NULL
;
4564 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4566 memset(&rmac
, 0, sizeof(struct ethaddr
));
4568 /* We are only interested in neighbors on an SVI that resides on top
4569 * of a VxLAN bridge.
4571 zvni
= zvni_from_svi(ifp
, link_if
);
4575 /* get the l3-vni */
4576 l3vni
= zvni_get_l3vni(zvni
);
4579 zvni_get_rmac(zvni
, &rmac
);
4581 if (IS_ZEBRA_DEBUG_VXLAN
)
4583 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u L3-VNI %u RMAC %s",
4584 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4585 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4586 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4588 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4590 /* create a dummy MAC if the MAC is not already present */
4591 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4593 if (IS_ZEBRA_DEBUG_VXLAN
)
4595 "AUTO MAC %s created for neigh %s on VNI %u",
4596 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4597 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
4599 zmac
= zvni_mac_add(zvni
, macaddr
);
4601 zlog_warn("Failed to add MAC %s VNI %u",
4602 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4607 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4608 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4609 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4612 /* If same entry already exists, it might be a change or it might be a
4613 * move from remote to local.
4615 n
= zvni_neigh_lookup(zvni
, ip
);
4617 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4618 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
4621 /* Update any params and return - client doesn't
4622 * care about a purely local change.
4624 n
->ifindex
= ifp
->ifindex
;
4628 /* If the MAC has changed,
4629 * need to issue a delete first
4630 * as this means a different MACIP route.
4631 * Also, need to do some unlinking/relinking.
4633 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4635 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4637 listnode_delete(old_zmac
->neigh_list
, n
);
4638 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4641 /* Set "local" forwarding info. */
4642 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4643 n
->ifindex
= ifp
->ifindex
;
4644 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4646 /* Link to new MAC */
4647 listnode_add_sort(zmac
->neigh_list
, n
);
4648 } else if (ext_learned
)
4649 /* The neighbor is remote and that is the notification we got.
4652 /* TODO: Evaluate if we need to do anything here. */
4655 /* Neighbor has moved from remote to local. */
4657 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4658 n
->r_vtep_ip
.s_addr
= 0;
4659 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4660 n
->ifindex
= ifp
->ifindex
;
4663 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4666 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4667 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4668 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4669 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4672 /* Set "local" forwarding info. */
4673 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4674 n
->ifindex
= ifp
->ifindex
;
4677 /* Before we program this in BGP, we need to check if MAC is locally
4679 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4680 if (IS_ZEBRA_DEBUG_VXLAN
)
4682 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4683 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4684 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4691 if (IS_ZEBRA_DEBUG_VXLAN
)
4692 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u L3-VNI %u with RMAC %s",
4693 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4694 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4697 prefix_mac2str(&rmac
, buf1
, sizeof(buf1
)));
4699 ZEBRA_NEIGH_SET_ACTIVE(n
);
4701 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
4706 * Handle message from client to delete a remote MACIP for a VNI.
4708 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
4709 struct zebra_vrf
*zvrf
)
4713 struct ethaddr macaddr
;
4715 struct in_addr vtep_ip
;
4719 u_short l
= 0, ipa_len
;
4720 char buf
[ETHER_ADDR_STRLEN
];
4721 char buf1
[INET6_ADDRSTRLEN
];
4722 struct interface
*ifp
= NULL
;
4723 struct zebra_if
*zif
= NULL
;
4725 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4726 memset(&ip
, 0, sizeof(struct ipaddr
));
4727 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4731 while (l
< length
) {
4732 /* Obtain each remote MACIP and process. */
4733 /* Message contains VNI, followed by MAC followed by IP (if any)
4734 * followed by remote VTEP IP.
4738 memset(&ip
, 0, sizeof(ip
));
4739 STREAM_GETL(s
, vni
);
4740 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4741 STREAM_GETL(s
, ipa_len
);
4743 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4745 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4747 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4748 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4749 l
+= IPV4_MAX_BYTELEN
;
4751 if (IS_ZEBRA_DEBUG_VXLAN
)
4753 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4754 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4755 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4757 zebra_route_string(client
->proto
));
4759 /* Locate VNI hash entry - expected to exist. */
4760 zvni
= zvni_lookup(vni
);
4762 if (IS_ZEBRA_DEBUG_VXLAN
)
4764 "Failed to locate VNI hash upon remote MACIP DEL, "
4769 ifp
= zvni
->vxlan_if
;
4772 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4778 /* If down or not mapped to a bridge, we're done. */
4779 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4782 /* The remote VTEP specified is normally expected to exist, but
4784 * possible that the peer may delete the VTEP before deleting
4786 * referring to the VTEP, in which case the handler (see
4788 * would have already deleted the MACs.
4790 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4793 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4795 n
= zvni_neigh_lookup(zvni
, &ip
);
4799 "Failed to locate MAC %s for neigh %s VNI %u",
4800 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4801 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4805 /* If the remote mac or neighbor doesn't exist there is nothing
4807 * to do. Otherwise, uninstall the entry and then remove it.
4812 /* Uninstall remote neighbor or MAC. */
4814 /* When the MAC changes for an IP, it is possible the
4816 * update the new MAC before trying to delete the "old"
4818 * (as these are two different MACIP routes). Do the
4820 * if the MAC matches.
4822 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4823 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
4826 zvni_neigh_uninstall(zvni
, n
);
4827 zvni_neigh_del(zvni
, n
);
4828 zvni_deref_ip2mac(zvni
, mac
, 1);
4831 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4832 zvni_process_neigh_on_remote_mac_del(zvni
,
4835 if (list_isempty(mac
->neigh_list
)) {
4836 zvni_mac_uninstall(zvni
, mac
, 0);
4837 zvni_mac_del(zvni
, mac
);
4839 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4849 * Handle message from client to add a remote MACIP for a VNI. This
4850 * could be just the add of a MAC address or the add of a neighbor
4853 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
4854 struct zebra_vrf
*zvrf
)
4858 struct ethaddr macaddr
;
4860 struct in_addr vtep_ip
;
4862 zebra_vtep_t
*zvtep
;
4863 zebra_mac_t
*mac
, *old_mac
;
4865 u_short l
= 0, ipa_len
;
4866 int update_mac
= 0, update_neigh
= 0;
4867 char buf
[ETHER_ADDR_STRLEN
];
4868 char buf1
[INET6_ADDRSTRLEN
];
4870 struct interface
*ifp
= NULL
;
4871 struct zebra_if
*zif
= NULL
;
4873 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4874 memset(&ip
, 0, sizeof(struct ipaddr
));
4875 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4877 if (!EVPN_ENABLED(zvrf
)) {
4878 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
4879 __PRETTY_FUNCTION__
);
4885 while (l
< length
) {
4886 /* Obtain each remote MACIP and process. */
4887 /* Message contains VNI, followed by MAC followed by IP (if any)
4888 * followed by remote VTEP IP.
4890 update_mac
= update_neigh
= 0;
4893 memset(&ip
, 0, sizeof(ip
));
4894 STREAM_GETL(s
, vni
);
4895 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4896 STREAM_GETL(s
, ipa_len
);
4898 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4900 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4902 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4903 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4904 l
+= IPV4_MAX_BYTELEN
;
4906 /* Get 'sticky' flag. */
4907 STREAM_GETC(s
, sticky
);
4910 if (IS_ZEBRA_DEBUG_VXLAN
)
4912 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
4913 sticky
? "sticky " : "",
4914 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4915 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4917 zebra_route_string(client
->proto
));
4919 /* Locate VNI hash entry - expected to exist. */
4920 zvni
= zvni_lookup(vni
);
4923 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
4927 ifp
= zvni
->vxlan_if
;
4930 "VNI %u hash %p doesn't have intf upon remote MACIP add",
4936 /* If down or not mapped to a bridge, we're done. */
4937 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4940 /* The remote VTEP specified should normally exist, but it is
4942 * that when peering comes up, peer may advertise MACIP routes
4944 * advertising type-3 routes.
4946 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4948 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4950 "Failed to add remote VTEP, VNI %u zvni %p",
4955 zvni_vtep_install(zvni
, &vtep_ip
);
4958 /* First, check if the remote MAC is unknown or has a change. If
4960 * that needs to be updated first. Note that client could
4962 * MAC and MACIP separately or just install the latter.
4964 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4965 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4966 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
4968 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
4973 mac
= zvni_mac_add(zvni
, &macaddr
);
4976 "Failed to add MAC %s VNI %u Remote VTEP %s",
4977 prefix_mac2str(&macaddr
, buf
,
4979 vni
, inet_ntoa(vtep_ip
));
4983 /* Is this MAC created for a MACIP? */
4985 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4988 /* Set "auto" and "remote" forwarding info. */
4989 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4990 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4991 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4992 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4995 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4997 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4999 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
5001 /* Install the entry. */
5002 zvni_mac_install(zvni
, mac
);
5005 /* If there is no IP, continue - after clearing AUTO flag of
5008 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5012 /* Check if the remote neighbor itself is unknown or has a
5014 * If so, create or update and then install the entry.
5016 n
= zvni_neigh_lookup(zvni
, &ip
);
5017 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5018 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
5019 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
5024 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
5027 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5028 ipaddr2str(&ip
, buf1
,
5030 prefix_mac2str(&macaddr
, buf
,
5032 vni
, inet_ntoa(vtep_ip
));
5036 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
5038 /* MAC change, update neigh list for old and new
5040 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
5042 listnode_delete(old_mac
->neigh_list
, n
);
5043 zvni_deref_ip2mac(zvni
, old_mac
, 1);
5045 listnode_add_sort(mac
->neigh_list
, n
);
5046 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
5049 /* Set "remote" forwarding info. */
5050 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
5051 /* TODO: Handle MAC change. */
5052 n
->r_vtep_ip
= vtep_ip
;
5053 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
5055 /* Install the entry. */
5056 zvni_neigh_install(zvni
, n
);
5065 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5066 * us, this must involve a multihoming scenario. Treat this as implicit delete
5067 * of any prior local MAC.
5069 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5070 struct interface
*br_if
,
5071 struct ethaddr
*macaddr
, vlanid_t vid
)
5073 struct zebra_if
*zif
;
5074 struct zebra_l2info_vxlan
*vxl
;
5078 char buf
[ETHER_ADDR_STRLEN
];
5083 vxl
= &zif
->l2info
.vxl
;
5086 /* Check if EVPN is enabled. */
5087 if (!is_evpn_enabled())
5090 /* Locate hash entry; it is expected to exist. */
5091 zvni
= zvni_lookup(vni
);
5095 /* If entry doesn't exist, nothing to do. */
5096 mac
= zvni_mac_lookup(zvni
, macaddr
);
5100 /* Is it a local entry? */
5101 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5104 if (IS_ZEBRA_DEBUG_VXLAN
)
5106 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5107 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5108 ifp
->name
, ifp
->ifindex
, vni
);
5110 /* Remove MAC from BGP. */
5111 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
5112 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
5113 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
5116 * If there are no neigh associated with the mac delete the mac
5117 * else mark it as AUTO for forward reference
5119 if (!listcount(mac
->neigh_list
)) {
5120 zvni_mac_del(zvni
, mac
);
5122 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5123 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5130 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5131 * This can happen because the remote MAC entries are also added as "dynamic",
5132 * so the kernel can ageout the entry.
5134 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5135 struct interface
*br_if
,
5136 struct ethaddr
*macaddr
, vlanid_t vid
)
5138 struct zebra_if
*zif
;
5139 struct zebra_l2info_vxlan
*vxl
;
5143 char buf
[ETHER_ADDR_STRLEN
];
5147 vxl
= &zif
->l2info
.vxl
;
5150 /* Check if EVPN is enabled. */
5151 if (!is_evpn_enabled())
5154 /* Locate hash entry; it is expected to exist. */
5155 zvni
= zvni_lookup(vni
);
5159 /* If entry doesn't exist, nothing to do. */
5160 mac
= zvni_mac_lookup(zvni
, macaddr
);
5164 /* Is it a remote entry? */
5165 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5168 if (IS_ZEBRA_DEBUG_VXLAN
)
5169 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5170 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5173 zvni_mac_install(zvni
, mac
);
5178 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5180 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5181 struct ethaddr
*macaddr
, vlanid_t vid
)
5185 char buf
[ETHER_ADDR_STRLEN
];
5188 /* We are interested in MACs only on ports or (port, VLAN) that
5191 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5194 if (!zvni
->vxlan_if
) {
5195 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5200 if (IS_ZEBRA_DEBUG_VXLAN
)
5201 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5202 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5203 ifp
->ifindex
, vid
, zvni
->vni
);
5205 /* If entry doesn't exist, nothing to do. */
5206 mac
= zvni_mac_lookup(zvni
, macaddr
);
5210 /* Is it a local entry? */
5211 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5214 /* Remove MAC from BGP. */
5215 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
5216 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
5217 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
5219 /* Update all the neigh entries associated with this mac */
5220 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5223 * If there are no neigh associated with the mac delete the mac
5224 * else mark it as AUTO for forward reference
5226 if (!listcount(mac
->neigh_list
)) {
5227 zvni_mac_del(zvni
, mac
);
5229 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5230 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5237 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5239 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5240 struct interface
*br_if
,
5241 struct ethaddr
*macaddr
, vlanid_t vid
,
5246 char buf
[ETHER_ADDR_STRLEN
];
5250 /* We are interested in MACs only on ports or (port, VLAN) that
5253 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5255 if (IS_ZEBRA_DEBUG_VXLAN
)
5257 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5258 sticky
? "sticky " : "",
5259 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5260 ifp
->name
, ifp
->ifindex
, vid
);
5264 if (!zvni
->vxlan_if
) {
5265 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5270 if (IS_ZEBRA_DEBUG_VXLAN
)
5272 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5273 sticky
? "sticky " : "",
5274 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5275 ifp
->ifindex
, vid
, zvni
->vni
);
5277 /* If same entry already exists, nothing to do. */
5278 mac
= zvni_mac_lookup(zvni
, macaddr
);
5280 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5281 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5287 * return if nothing has changed.
5288 * inform bgp if sticky flag has changed
5289 * update locally and do not inform bgp if local
5290 * parameters like interface has changed
5292 if (mac_sticky
== sticky
5293 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5294 && mac
->fwd_info
.local
.vid
== vid
) {
5295 if (IS_ZEBRA_DEBUG_VXLAN
)
5297 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5298 "entry exists and has not changed ",
5299 sticky
? "sticky " : "",
5300 prefix_mac2str(macaddr
, buf
,
5302 ifp
->name
, ifp
->ifindex
, vid
,
5305 } else if (mac_sticky
!= sticky
) {
5308 add
= 0; /* This is an update of local
5311 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5313 * If we have already learned the MAC as a remote sticky
5315 * this is a operator error and we must log a warning
5317 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5319 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5320 prefix_mac2str(macaddr
, buf
,
5322 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5330 mac
= zvni_mac_add(zvni
, macaddr
);
5332 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5333 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5334 ifp
->name
, ifp
->ifindex
, vid
);
5339 /* Set "local" forwarding info. */
5340 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5341 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5342 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5343 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5344 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5345 mac
->fwd_info
.local
.vid
= vid
;
5348 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5350 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5352 /* Inform BGP if required. */
5354 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5355 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5363 * Handle message from client to delete a remote VTEP for a VNI.
5365 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
5366 struct zebra_vrf
*zvrf
)
5371 struct in_addr vtep_ip
;
5373 zebra_vtep_t
*zvtep
;
5374 struct interface
*ifp
;
5375 struct zebra_if
*zif
;
5377 if (!is_evpn_enabled()) {
5378 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5379 __PRETTY_FUNCTION__
);
5383 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5384 zlog_err("Recv MACIP DEL for non-default VRF %u",
5391 while (l
< length
) {
5392 /* Obtain each remote VTEP and process. */
5393 STREAM_GETL(s
, vni
);
5395 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5396 l
+= IPV4_MAX_BYTELEN
;
5398 if (IS_ZEBRA_DEBUG_VXLAN
)
5399 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5400 inet_ntoa(vtep_ip
), vni
,
5401 zebra_route_string(client
->proto
));
5403 /* Locate VNI hash entry - expected to exist. */
5404 zvni
= zvni_lookup(vni
);
5406 if (IS_ZEBRA_DEBUG_VXLAN
)
5408 "Failed to locate VNI hash upon remote VTEP DEL, "
5414 ifp
= zvni
->vxlan_if
;
5417 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5423 /* If down or not mapped to a bridge, we're done. */
5424 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5427 /* If the remote VTEP does not exist, there's nothing more to
5429 * Otherwise, uninstall any remote MACs pointing to this VTEP
5431 * then, the VTEP entry itself and remove it.
5433 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5437 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5438 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5439 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5440 zvni_vtep_del(zvni
, zvtep
);
5448 * Handle message from client to add a remote VTEP for a VNI.
5450 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
5451 struct zebra_vrf
*zvrf
)
5456 struct in_addr vtep_ip
;
5458 struct interface
*ifp
;
5459 struct zebra_if
*zif
;
5461 if (!is_evpn_enabled()) {
5462 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5463 __PRETTY_FUNCTION__
);
5467 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5468 zlog_err("Recv MACIP ADD for non-default VRF %u",
5475 while (l
< length
) {
5476 /* Obtain each remote VTEP and process. */
5477 STREAM_GETL(s
, vni
);
5479 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5480 l
+= IPV4_MAX_BYTELEN
;
5482 if (IS_ZEBRA_DEBUG_VXLAN
)
5483 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5484 inet_ntoa(vtep_ip
), vni
,
5485 zebra_route_string(client
->proto
));
5487 /* Locate VNI hash entry - expected to exist. */
5488 zvni
= zvni_lookup(vni
);
5491 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5496 ifp
= zvni
->vxlan_if
;
5499 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5506 /* If down or not mapped to a bridge, we're done. */
5507 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5510 /* If the remote VTEP already exists,
5511 there's nothing more to do. */
5512 if (zvni_vtep_find(zvni
, &vtep_ip
))
5515 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5517 "Failed to add remote VTEP, VNI %u zvni %p",
5522 zvni_vtep_install(zvni
, &vtep_ip
);
5530 * Add/Del gateway macip to evpn
5532 * 1. SVI interface on a vlan aware bridge
5533 * 2. SVI interface on a vlan unaware bridge
5534 * 3. vrr interface (MACVLAN) associated to a SVI
5535 * We advertise macip routes for an interface if it is associated to VxLan vlan
5537 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5541 struct ethaddr macaddr
;
5542 zebra_vni_t
*zvni
= NULL
;
5544 memset(&ip
, 0, sizeof(struct ipaddr
));
5545 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5547 /* Check if EVPN is enabled. */
5548 if (!is_evpn_enabled())
5551 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5552 struct interface
*svi_if
=
5553 NULL
; /* SVI corresponding to the MACVLAN */
5554 struct zebra_if
*ifp_zif
=
5555 NULL
; /* Zebra daemon specific info for MACVLAN */
5556 struct zebra_if
*svi_if_zif
=
5557 NULL
; /* Zebra daemon specific info for SVI*/
5559 ifp_zif
= ifp
->info
;
5564 * for a MACVLAN interface the link represents the svi_if
5566 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5567 ifp_zif
->link_ifindex
);
5569 zlog_err("MACVLAN %s(%u) without link information",
5570 ifp
->name
, ifp
->ifindex
);
5574 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5576 * If it is a vlan aware bridge then the link gives the
5577 * bridge information
5579 struct interface
*svi_if_link
= NULL
;
5581 svi_if_zif
= svi_if
->info
;
5583 svi_if_link
= if_lookup_by_index_per_ns(
5584 zebra_ns_lookup(NS_DEFAULT
),
5585 svi_if_zif
->link_ifindex
);
5586 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5588 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5590 * If it is a vlan unaware bridge then svi is the bridge
5593 zvni
= zvni_from_svi(svi_if
, svi_if
);
5595 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5596 struct zebra_if
*svi_if_zif
=
5597 NULL
; /* Zebra daemon specific info for SVI */
5598 struct interface
*svi_if_link
=
5599 NULL
; /* link info for the SVI = bridge info */
5601 svi_if_zif
= ifp
->info
;
5602 svi_if_link
= if_lookup_by_index_per_ns(
5603 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5604 if (svi_if_zif
&& svi_if_link
)
5605 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5606 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5607 zvni
= zvni_from_svi(ifp
, ifp
);
5613 if (!zvni
->vxlan_if
) {
5614 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5620 /* check if we are advertising gw macip routes */
5621 if (!advertise_gw_macip_enabled(zvni
))
5624 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5626 if (p
->family
== AF_INET
) {
5627 ip
.ipa_type
= IPADDR_V4
;
5628 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5629 sizeof(struct in_addr
));
5630 } else if (p
->family
== AF_INET6
) {
5631 ip
.ipa_type
= IPADDR_V6
;
5632 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5633 sizeof(struct in6_addr
));
5638 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5640 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5646 * Handle SVI interface going down.
5647 * SVI can be associated to either L3-VNI or L2-VNI.
5648 * For L2-VNI: At this point, this is a NOP since
5649 * the kernel deletes the neighbor entries on this SVI (if any).
5650 * We only need to update the vrf corresponding to zvni.
5651 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5654 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5656 zebra_l3vni_t
*zl3vni
= NULL
;
5658 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5661 /* process l3-vni down */
5662 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5664 /* remove association with svi-if */
5665 zl3vni
->svi_if
= NULL
;
5667 zebra_vni_t
*zvni
= NULL
;
5669 /* since we dont have svi corresponding to zvni, we associate it
5670 * to default vrf. Note: the corresponding neigh entries on the
5671 * SVI would have already been deleted */
5672 zvni
= zvni_from_svi(ifp
, link_if
);
5674 zvni
->vrf_id
= VRF_DEFAULT
;
5676 /* update the tenant vrf in BGP */
5677 zvni_send_add_to_client(zvni
);
5684 * Handle SVI interface coming up.
5685 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5687 * For L2-VNI: we need to install any remote neighbors entried (used for
5689 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5691 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5693 zebra_vni_t
*zvni
= NULL
;
5694 zebra_l3vni_t
*zl3vni
= NULL
;
5696 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5699 /* associate with svi */
5700 zl3vni
->svi_if
= ifp
;
5702 /* process oper-up */
5703 if (is_l3vni_oper_up(zl3vni
))
5704 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5707 /* process SVI up for l2-vni */
5708 struct neigh_walk_ctx n_wctx
;
5710 zvni
= zvni_from_svi(ifp
, link_if
);
5714 if (!zvni
->vxlan_if
) {
5715 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5720 if (IS_ZEBRA_DEBUG_VXLAN
)
5721 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5722 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5723 vrf_id_to_name(ifp
->vrf_id
));
5725 /* update the vrf information for l2-vni and inform bgp */
5726 zvni
->vrf_id
= ifp
->vrf_id
;
5727 zvni_send_add_to_client(zvni
);
5729 /* Install any remote neighbors for this VNI. */
5730 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5732 hash_iterate(zvni
->neigh_table
,
5733 zvni_install_neigh_hash
,
5741 * Handle VxLAN interface down
5743 int zebra_vxlan_if_down(struct interface
*ifp
)
5746 struct zebra_if
*zif
= NULL
;
5747 struct zebra_l2info_vxlan
*vxl
= NULL
;
5749 /* Check if EVPN is enabled. */
5750 if (!is_evpn_enabled())
5755 vxl
= &zif
->l2info
.vxl
;
5759 if (is_vni_l3(vni
)) {
5761 /* process-if-down for l3-vni */
5762 zebra_l3vni_t
*zl3vni
= NULL
;
5764 if (IS_ZEBRA_DEBUG_VXLAN
)
5765 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
5766 ifp
->name
, ifp
->ifindex
, vni
);
5768 zl3vni
= zl3vni_lookup(vni
);
5771 "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
5772 ifp
->name
, ifp
->ifindex
, vni
);
5776 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5779 /* process if-down for l2-vni */
5782 if (IS_ZEBRA_DEBUG_VXLAN
)
5783 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
5784 ifp
->name
, ifp
->ifindex
, vni
);
5786 /* Locate hash entry; it is expected to exist. */
5787 zvni
= zvni_lookup(vni
);
5790 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5791 ifp
->name
, ifp
->ifindex
, vni
);
5795 assert(zvni
->vxlan_if
== ifp
);
5797 /* Delete this VNI from BGP. */
5798 zvni_send_del_to_client(zvni
->vni
);
5800 /* Free up all neighbors and MACs, if any. */
5801 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5802 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5804 /* Free up all remote VTEPs, if any. */
5805 zvni_vtep_del_all(zvni
, 1);
5811 * Handle VxLAN interface up - update BGP if required.
5813 int zebra_vxlan_if_up(struct interface
*ifp
)
5816 struct zebra_if
*zif
= NULL
;
5817 struct zebra_l2info_vxlan
*vxl
= NULL
;
5819 /* Check if EVPN is enabled. */
5820 if (!is_evpn_enabled())
5825 vxl
= &zif
->l2info
.vxl
;
5828 if (is_vni_l3(vni
)) {
5830 /* Handle L3-VNI add */
5831 zebra_l3vni_t
*zl3vni
= NULL
;
5833 if (IS_ZEBRA_DEBUG_VXLAN
)
5834 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
5835 ifp
->name
, ifp
->ifindex
, vni
);
5837 zl3vni
= zl3vni_lookup(vni
);
5840 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
5841 ifp
->name
, ifp
->ifindex
, vni
);
5845 /* we need to associate with SVI, if any, we can associate with
5846 * svi-if only after association with vxlan-intf is complete */
5847 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5849 if (is_l3vni_oper_up(zl3vni
))
5850 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5852 /* Handle L2-VNI add */
5854 zebra_vni_t
*zvni
= NULL
;
5855 zebra_l3vni_t
*zl3vni
= NULL
;
5856 struct interface
*vlan_if
= NULL
;
5858 if (IS_ZEBRA_DEBUG_VXLAN
)
5859 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
5860 ifp
->name
, ifp
->ifindex
, vni
);
5862 /* Locate hash entry; it is expected to exist. */
5863 zvni
= zvni_lookup(vni
);
5866 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
5867 ifp
->name
, ifp
->ifindex
, vni
);
5871 assert(zvni
->vxlan_if
== ifp
);
5872 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5873 zif
->brslave_info
.br_if
);
5875 zvni
->vrf_id
= vlan_if
->vrf_id
;
5876 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
5878 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
5881 /* If part of a bridge, inform BGP about this VNI. */
5882 /* Also, read and populate local MACs and neighbors. */
5883 if (zif
->brslave_info
.br_if
) {
5884 zvni_send_add_to_client(zvni
);
5885 zvni_read_mac_neigh(zvni
, ifp
);
5893 * Handle VxLAN interface delete. Locate and remove entry in hash table
5894 * and update BGP, if required.
5896 int zebra_vxlan_if_del(struct interface
*ifp
)
5899 struct zebra_if
*zif
= NULL
;
5900 struct zebra_l2info_vxlan
*vxl
= NULL
;
5902 /* Check if EVPN is enabled. */
5903 if (!is_evpn_enabled())
5908 vxl
= &zif
->l2info
.vxl
;
5911 if (is_vni_l3(vni
)) {
5913 /* process if-del for l3-vni */
5914 zebra_l3vni_t
*zl3vni
= NULL
;
5916 if (IS_ZEBRA_DEBUG_VXLAN
)
5917 zlog_debug("Del L3-VNI %u intf %s(%u)",
5918 vni
, ifp
->name
, ifp
->ifindex
);
5920 zl3vni
= zl3vni_lookup(vni
);
5923 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5924 ifp
->name
, ifp
->ifindex
, vni
);
5928 /* process oper-down for l3-vni */
5929 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5931 /* remove the association with vxlan_if */
5932 zl3vni
->vxlan_if
= NULL
;
5935 /* process if-del for l2-vni*/
5936 zebra_vni_t
*zvni
= NULL
;
5937 zebra_l3vni_t
*zl3vni
= NULL
;
5939 if (IS_ZEBRA_DEBUG_VXLAN
)
5940 zlog_debug("Del L2-VNI %u intf %s(%u)",
5941 vni
, ifp
->name
, ifp
->ifindex
);
5943 /* Locate hash entry; it is expected to exist. */
5944 zvni
= zvni_lookup(vni
);
5947 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
5948 ifp
->name
, ifp
->ifindex
, vni
);
5952 /* remove from l3-vni list */
5953 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
5955 listnode_delete(zl3vni
->l2vnis
, zvni
);
5957 /* Delete VNI from BGP. */
5958 zvni_send_del_to_client(zvni
->vni
);
5960 /* Free up all neighbors and MAC, if any. */
5961 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
5962 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
5964 /* Free up all remote VTEPs, if any. */
5965 zvni_vtep_del_all(zvni
, 0);
5967 /* Delete the hash entry. */
5968 if (zvni_del(zvni
)) {
5969 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
5970 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
5979 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
5981 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
5984 struct zebra_if
*zif
= NULL
;
5985 struct zebra_l2info_vxlan
*vxl
= NULL
;
5987 /* Check if EVPN is enabled. */
5988 if (!is_evpn_enabled())
5993 vxl
= &zif
->l2info
.vxl
;
5996 if (is_vni_l3(vni
)) {
5997 zebra_l3vni_t
*zl3vni
= NULL
;
5999 zl3vni
= zl3vni_lookup(vni
);
6002 "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
6003 ifp
->name
, ifp
->ifindex
, vni
);
6007 if (IS_ZEBRA_DEBUG_VXLAN
)
6009 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6010 vni
, ifp
->name
, ifp
->ifindex
,
6011 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6012 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6014 /* Removed from bridge? Cleanup and return */
6015 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6016 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6017 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6021 /* access-vlan change - process oper down, associate with new
6022 * svi_if and then process oper up again */
6023 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6024 if (if_is_operative(ifp
)) {
6025 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6026 zl3vni
->svi_if
= NULL
;
6027 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6028 if (is_l3vni_oper_up(zl3vni
))
6029 zebra_vxlan_process_l3vni_oper_up(
6034 /* if we have a valid new master, process l3-vni oper up */
6035 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6036 if (is_l3vni_oper_up(zl3vni
))
6037 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6040 zebra_vni_t
*zvni
= NULL
;
6042 /* Update VNI hash. */
6043 zvni
= zvni_lookup(vni
);
6046 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6047 ifp
->name
, ifp
->ifindex
, vni
);
6051 if (IS_ZEBRA_DEBUG_VXLAN
)
6053 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6054 vni
, ifp
->name
, ifp
->ifindex
,
6055 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6056 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6058 /* Removed from bridge? Cleanup and return */
6059 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6060 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6061 /* Delete from client, remove all remote VTEPs */
6062 /* Also, free up all MACs and neighbors. */
6063 zvni_send_del_to_client(zvni
->vni
);
6064 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6065 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6066 zvni_vtep_del_all(zvni
, 1);
6070 /* Handle other changes. */
6071 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6072 /* Remove all existing local neigh and MACs for this VNI
6073 * (including from BGP)
6075 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6076 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6079 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6080 zvni
->vxlan_if
= ifp
;
6082 /* Take further actions needed.
6083 * Note that if we are here, there is a change of interest.
6085 /* If down or not mapped to a bridge, we're done. */
6086 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6089 /* Inform BGP, if there is a change of interest. */
6091 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6092 zvni_send_add_to_client(zvni
);
6094 /* If there is a valid new master or a VLAN mapping change,
6095 * read and populate local MACs and neighbors.
6096 * Also, reinstall any remote MACs and neighbors
6097 * for this VNI (based on new VLAN).
6099 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6100 zvni_read_mac_neigh(zvni
, ifp
);
6101 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6102 struct mac_walk_ctx m_wctx
;
6103 struct neigh_walk_ctx n_wctx
;
6105 zvni_read_mac_neigh(zvni
, ifp
);
6107 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6109 hash_iterate(zvni
->mac_table
,
6110 zvni_install_mac_hash
,
6113 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6115 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6124 * Handle VxLAN interface add.
6126 int zebra_vxlan_if_add(struct interface
*ifp
)
6129 struct zebra_if
*zif
= NULL
;
6130 struct zebra_l2info_vxlan
*vxl
= NULL
;
6132 /* Check if EVPN is enabled. */
6133 if (!is_evpn_enabled())
6138 vxl
= &zif
->l2info
.vxl
;
6141 if (is_vni_l3(vni
)) {
6143 /* process if-add for l3-vni*/
6144 zebra_l3vni_t
*zl3vni
= NULL
;
6146 if (IS_ZEBRA_DEBUG_VXLAN
)
6148 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6149 vni
, ifp
->name
, ifp
->ifindex
,
6150 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6151 zif
->brslave_info
.bridge_ifindex
);
6154 * we expect the l3-vni has entry to be present here.
6155 * The only place l3-vni is created in zebra is vrf-vni mapping
6156 * command. This might change when we have the switchd support
6157 * for l3-vxlan interface.
6159 zl3vni
= zl3vni_lookup(vni
);
6162 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
6163 ifp
->name
, ifp
->ifindex
, vni
);
6167 /* associate with vxlan_if */
6168 zl3vni
->vxlan_if
= ifp
;
6170 /* Associate with SVI, if any. We can associate with svi-if only
6171 * after association with vxlan_if is complete */
6172 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6174 if (is_l3vni_oper_up(zl3vni
))
6175 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6178 /* process if-add for l2-vni */
6179 zebra_vni_t
*zvni
= NULL
;
6180 zebra_l3vni_t
*zl3vni
= NULL
;
6181 struct interface
*vlan_if
= NULL
;
6183 /* Create or update VNI hash. */
6184 zvni
= zvni_lookup(vni
);
6186 zvni
= zvni_add(vni
);
6189 "Failed to add VNI hash, IF %s(%u) VNI %u",
6190 ifp
->name
, ifp
->ifindex
, vni
);
6195 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6196 zvni
->vxlan_if
= ifp
;
6197 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6198 zif
->brslave_info
.br_if
);
6200 zvni
->vrf_id
= vlan_if
->vrf_id
;
6201 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6203 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6206 if (IS_ZEBRA_DEBUG_VXLAN
)
6208 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6210 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
) :
6212 ifp
->name
, ifp
->ifindex
,
6213 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6214 zif
->brslave_info
.bridge_ifindex
);
6216 /* If down or not mapped to a bridge, we're done. */
6217 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6221 zvni_send_add_to_client(zvni
);
6223 /* Read and populate local MACs and neighbors */
6224 zvni_read_mac_neigh(zvni
, ifp
);
6230 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
,
6231 vni_t vni
, char *err
,
6234 zebra_l3vni_t
*zl3vni
= NULL
;
6235 struct zebra_vrf
*zvrf_default
= NULL
;
6237 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6241 if (IS_ZEBRA_DEBUG_VXLAN
)
6242 zlog_debug("vrf %s vni %u %s",
6245 add
? "ADD" : "DEL");
6249 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6251 /* check if the vni is already present under zvrf */
6253 snprintf(err
, ERR_STR_SZ
,
6254 "VNI is already configured under the vrf");
6258 /* check if this VNI is already present in the system */
6259 zl3vni
= zl3vni_lookup(vni
);
6261 snprintf(err
, ERR_STR_SZ
,
6262 "VNI is already configured as L3-VNI");
6266 /* add the L3-VNI to the global table */
6267 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6269 snprintf(err
, ERR_STR_SZ
,
6270 "Could not add L3-VNI");
6274 /* associate the vrf with vni */
6277 /* associate with vxlan-intf;
6278 * we need to associate with the vxlan-intf first */
6279 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6281 /* associate with corresponding SVI interface, we can associate
6282 * with svi-if only after vxlan interface association is
6284 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6286 /* formulate l2vni list */
6287 hash_iterate(zvrf_default
->vni_table
,
6288 zvni_add_to_l3vni_list
, zl3vni
);
6290 if (is_l3vni_oper_up(zl3vni
))
6291 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6294 zl3vni
= zl3vni_lookup(vni
);
6296 snprintf(err
, ERR_STR_SZ
, "VNI doesn't exist");
6300 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6305 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6310 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6312 zebra_l3vni_t
*zl3vni
= NULL
;
6314 zl3vni
= zl3vni_from_vrf(zvrf_id(zvrf
));
6318 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6320 zebra_vxlan_handle_vni_transition(zvrf
, zl3vni
->vni
, 0);
6326 * Handle message from client to enable/disable advertisement of g/w macip
6329 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
6330 struct zebra_vrf
*zvrf
)
6335 zebra_vni_t
*zvni
= NULL
;
6336 struct interface
*ifp
= NULL
;
6338 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6339 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6345 STREAM_GETC(s
, advertise
);
6346 STREAM_GET(&vni
, s
, 3);
6349 if (IS_ZEBRA_DEBUG_VXLAN
)
6350 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6351 advertise
? "enabled" : "disabled",
6352 advertise_gw_macip_enabled(NULL
)
6356 if (zvrf
->advertise_gw_macip
== advertise
)
6359 zvrf
->advertise_gw_macip
= advertise
;
6361 if (advertise_gw_macip_enabled(zvni
))
6362 hash_iterate(zvrf
->vni_table
,
6363 zvni_gw_macip_add_for_vni_hash
, NULL
);
6365 hash_iterate(zvrf
->vni_table
,
6366 zvni_gw_macip_del_for_vni_hash
, NULL
);
6369 struct zebra_if
*zif
= NULL
;
6370 struct zebra_l2info_vxlan zl2_info
;
6371 struct interface
*vlan_if
= NULL
;
6372 struct interface
*vrr_if
= NULL
;
6374 if (IS_ZEBRA_DEBUG_VXLAN
)
6376 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6377 advertise
? "enabled" : "disabled", vni
,
6378 advertise_gw_macip_enabled(zvni
)
6382 zvni
= zvni_lookup(vni
);
6386 if (zvni
->advertise_gw_macip
== advertise
)
6389 zvni
->advertise_gw_macip
= advertise
;
6391 ifp
= zvni
->vxlan_if
;
6397 /* If down or not mapped to a bridge, we're done. */
6398 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6401 zl2_info
= zif
->l2info
.vxl
;
6403 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6404 zif
->brslave_info
.br_if
);
6408 if (advertise_gw_macip_enabled(zvni
)) {
6409 /* Add primary SVI MAC-IP */
6410 zvni_add_macip_for_intf(vlan_if
, zvni
);
6412 /* Add VRR MAC-IP - if any*/
6413 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6415 zvni_add_macip_for_intf(vrr_if
, zvni
);
6417 /* Del primary MAC-IP */
6418 zvni_del_macip_for_intf(vlan_if
, zvni
);
6420 /* Del VRR MAC-IP - if any*/
6421 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6423 zvni_del_macip_for_intf(vrr_if
, zvni
);
6433 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6434 * When enabled, the VNI hash table will be built and MAC FDB table read;
6435 * when disabled, the entries should be deleted and remote VTEPs and MACs
6436 * uninstalled from the kernel.
6438 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
6439 u_short length
, struct zebra_vrf
*zvrf
)
6444 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6445 zlog_err("EVPN VNI Adv for non-default VRF %u",
6451 STREAM_GETC(s
, advertise
);
6453 if (IS_ZEBRA_DEBUG_VXLAN
)
6454 zlog_debug("EVPN VNI Adv %s, currently %s",
6455 advertise
? "enabled" : "disabled",
6456 is_evpn_enabled() ? "enabled" : "disabled");
6458 if (zvrf
->advertise_all_vni
== advertise
)
6461 zvrf
->advertise_all_vni
= advertise
;
6462 if (is_evpn_enabled()) {
6463 /* Build VNI hash table and inform BGP. */
6464 zvni_build_hash_table();
6466 /* Add all SVI (L3 GW) MACs to BGP*/
6467 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6470 /* Read the MAC FDB */
6471 macfdb_read(zvrf
->zns
);
6473 /* Read neighbors */
6474 neigh_read(zvrf
->zns
);
6476 /* Cleanup VTEPs for all VNIs - uninstall from
6477 * kernel and free entries.
6479 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6487 * Allocate VNI hash table for this VRF and do other initialization.
6488 * NOTE: Currently supported only for default VRF.
6490 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6494 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6495 "Zebra VRF VNI Table");
6498 /* Close all VNI handling */
6499 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6503 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6504 hash_free(zvrf
->vni_table
);
6507 /* init the l3vni table */
6508 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6510 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6511 "Zebra VRF L3 VNI table");
6514 /* free l3vni table */
6515 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6517 hash_free(zns
->l3vni_table
);
6520 /* get the l3vni svi ifindex */
6521 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6523 zebra_l3vni_t
*zl3vni
= NULL
;
6525 zl3vni
= zl3vni_from_vrf(vrf_id
);
6526 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6529 return zl3vni
->svi_if
->ifindex
;