2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 #include "zebra/rib.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
50 DEFINE_MTYPE_STATIC(ZEBRA
, HOST_PREFIX
, "host prefix");
51 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
54 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
55 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
60 /* static function declarations */
61 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
63 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
64 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
65 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
67 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
69 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
71 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
72 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
73 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
74 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
75 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
77 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
78 struct ipaddr
*ip
, u_char flags
,
80 static unsigned int neigh_hash_keymake(void *p
);
81 static int neigh_cmp(const void *p1
, const void *p2
);
82 static void *zvni_neigh_alloc(void *p
);
83 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
85 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
86 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
87 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
88 struct in_addr
*r_vtep_ip
);
89 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
91 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
92 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
93 struct ethaddr
*macaddr
, u_char flags
);
94 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
95 struct ethaddr
*macaddr
, u_char flags
);
96 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
97 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
98 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
99 struct interface
*br_if
);
100 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
);
102 /* l3-vni next-hop neigh related APIs */
103 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
105 static void *zl3vni_nh_alloc(void *p
);
106 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
107 struct ipaddr
*vtep_ip
,
108 struct ethaddr
*rmac
);
109 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
110 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
111 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
113 /* l3-vni rmac related APIs */
114 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
115 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
116 struct ethaddr
*rmac
);
117 static void *zl3vni_rmac_alloc(void *p
);
118 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
119 struct ethaddr
*rmac
);
120 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
121 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
122 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
124 /* l3-vni related APIs*/
125 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
126 static void *zl3vni_alloc(void *p
);
127 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
128 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
129 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
130 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
131 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
132 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
133 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
135 static unsigned int mac_hash_keymake(void *p
);
136 static int mac_cmp(const void *p1
, const void *p2
);
137 static void *zvni_mac_alloc(void *p
);
138 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
139 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
140 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
141 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
142 struct in_addr
*r_vtep_ip
);
143 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
145 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
146 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
148 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
150 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
151 struct interface
*br_if
, vlanid_t vid
);
152 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
153 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
154 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
156 static unsigned int vni_hash_keymake(void *p
);
157 static int vni_hash_cmp(const void *p1
, const void *p2
);
158 static void *zvni_alloc(void *p
);
159 static zebra_vni_t
*zvni_lookup(vni_t vni
);
160 static zebra_vni_t
*zvni_add(vni_t vni
);
161 static int zvni_del(zebra_vni_t
*zvni
);
162 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
163 static int zvni_send_del_to_client(vni_t vni
);
164 static void zvni_build_hash_table();
165 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
166 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
167 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
168 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
169 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
170 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
171 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
172 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
173 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
174 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
175 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
176 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
178 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
179 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
180 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
183 /* Private functions */
186 * Return number of valid MACs in a VNI's MAC hash table - all
187 * remote MACs and non-internal (auto) local MACs count.
189 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
192 u_int32_t num_macs
= 0;
194 struct hash_backet
*hb
;
197 hash
= zvni
->mac_table
;
200 for (i
= 0; i
< hash
->size
; i
++) {
201 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
202 mac
= (zebra_mac_t
*)hb
->data
;
203 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
204 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
212 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
214 struct zebra_vrf
*zvrf
;
216 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
217 if (zvrf
&& zvrf
->advertise_gw_macip
)
220 if (zvni
&& zvni
->advertise_gw_macip
)
227 * Helper function to determine maximum width of neighbor IP address for
228 * display - just because we're dealing with IPv6 addresses that can
231 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
234 char buf
[INET6_ADDRSTRLEN
];
235 struct neigh_walk_ctx
*wctx
= ctxt
;
238 n
= (zebra_neigh_t
*)backet
->data
;
242 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
243 if (width
> wctx
->addr_width
)
244 wctx
->addr_width
= width
;
248 * Print a specific neighbor entry.
250 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
253 char buf1
[ETHER_ADDR_STRLEN
];
254 char buf2
[INET6_ADDRSTRLEN
];
256 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
257 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
258 vty
= (struct vty
*)ctxt
;
260 vty_out(vty
, "IP: %s\n",
261 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
262 vty_out(vty
, " MAC: %s",
263 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
265 json_object_string_add(json
, "ip", buf2
);
266 json_object_string_add(json
, "mac", buf1
);
268 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
270 vty_out(vty
, " Remote VTEP: %s",
271 inet_ntoa(n
->r_vtep_ip
));
273 json_object_string_add(json
, "remoteVtep",
274 inet_ntoa(n
->r_vtep_ip
));
276 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
279 vty_out(vty
, " State: %s",
280 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
284 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
286 vty_out(vty
, " Default-gateway");
288 json_object_boolean_true_add(json
, "defaultGateway");
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
, struct vty
*vty
,
434 char buf1
[ETHER_ADDR_STRLEN
];
435 char buf2
[INET6_ADDRSTRLEN
];
436 struct listnode
*node
= NULL
;
437 struct prefix
*p
= NULL
;
438 json_object
*json_hosts
= NULL
;
441 vty_out(vty
, "Ip: %s\n",
442 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
443 vty_out(vty
, " RMAC: %s\n",
444 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
445 vty_out(vty
, " Refcount: %d\n", listcount(n
->host_list
));
446 vty_out(vty
, " Prefixes:\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(
453 json
, "ip", ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)));
454 json_object_string_add(
456 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)));
457 json_object_int_add(json
, "refCount", listcount(n
->host_list
));
458 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
459 json_object_array_add(json_hosts
,
460 json_object_new_string(prefix2str(
461 p
, buf2
, sizeof(buf2
))));
462 json_object_object_add(json
, "prefixList", json_hosts
);
466 /* Print a specific RMAC entry */
467 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
470 char buf1
[ETHER_ADDR_STRLEN
];
471 char buf2
[PREFIX_STRLEN
];
472 struct listnode
*node
= NULL
;
473 struct prefix
*p
= NULL
;
474 json_object
*json_hosts
= NULL
;
477 vty_out(vty
, "MAC: %s\n",
478 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
479 vty_out(vty
, " Remote VTEP: %s\n",
480 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
481 vty_out(vty
, " Refcount: %d\n", listcount(zrmac
->host_list
));
482 vty_out(vty
, " Prefixes:\n");
483 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
484 vty_out(vty
, " %s\n",
485 prefix2str(p
, buf2
, sizeof(buf2
)));
487 json_hosts
= json_object_new_array();
488 json_object_string_add(
490 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
491 json_object_string_add(json
, "vtepIp",
492 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
493 json_object_int_add(json
, "refCount",
494 listcount(zrmac
->host_list
));
495 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
496 json_object_array_add(json_hosts
,
497 json_object_new_string(prefix2str(
498 p
, buf2
, sizeof(buf2
))));
499 json_object_object_add(json
, "prefixList", json_hosts
);
504 * Print a specific MAC entry.
506 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
509 zebra_neigh_t
*n
= NULL
;
510 struct listnode
*node
= NULL
;
512 char buf2
[INET6_ADDRSTRLEN
];
514 vty
= (struct vty
*)ctxt
;
515 vty_out(vty
, "MAC: %s",
516 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
517 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
518 struct zebra_ns
*zns
;
519 struct interface
*ifp
;
522 ifindex
= mac
->fwd_info
.local
.ifindex
;
523 zns
= zebra_ns_lookup(NS_DEFAULT
);
524 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
525 if (!ifp
) // unexpected
527 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
528 if (mac
->fwd_info
.local
.vid
)
529 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
530 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
531 vty_out(vty
, " Remote VTEP: %s",
532 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
533 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
534 vty_out(vty
, " Auto Mac ");
537 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
538 vty_out(vty
, " Sticky Mac ");
540 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
541 vty_out(vty
, " Default-gateway Mac ");
544 /* print all the associated neigh */
545 vty_out(vty
, " Neighbors:\n");
546 if (!listcount(mac
->neigh_list
))
547 vty_out(vty
, " No Neighbors\n");
549 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
550 vty_out(vty
, " %s %s\n",
551 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
552 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
553 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
564 * Print MAC hash entry - called for display of all MACs.
566 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
569 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
572 struct mac_walk_ctx
*wctx
= ctxt
;
575 json_mac_hdr
= wctx
->json
;
576 mac
= (zebra_mac_t
*)backet
->data
;
580 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
583 json_mac
= json_object_new_object();
585 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
586 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
587 struct zebra_ns
*zns
;
589 struct interface
*ifp
;
592 zns
= zebra_ns_lookup(NS_DEFAULT
);
593 ifindex
= mac
->fwd_info
.local
.ifindex
;
594 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
595 if (!ifp
) // unexpected
597 vid
= mac
->fwd_info
.local
.vid
;
598 if (json_mac_hdr
== NULL
)
599 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
602 json_object_string_add(json_mac
, "type", "local");
603 json_object_string_add(json_mac
, "intf", ifp
->name
);
606 if (json_mac_hdr
== NULL
)
607 vty_out(vty
, " %-5u", vid
);
609 json_object_int_add(json_mac
, "vlan", vid
);
611 if (json_mac_hdr
== NULL
)
614 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
616 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
617 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
618 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
620 if (wctx
->count
== 0) {
621 if (json_mac_hdr
== NULL
) {
622 vty_out(vty
, "\nVNI %u\n\n",
625 "%-17s %-6s %-21s %-5s\n",
631 if (json_mac_hdr
== NULL
)
632 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
634 inet_ntoa(mac
->fwd_info
637 json_object_string_add(json_mac
, "type",
639 json_object_string_add(
640 json_mac
, "remoteVtep",
641 inet_ntoa(mac
->fwd_info
643 json_object_object_add(json_mac_hdr
,
649 if (json_mac_hdr
== NULL
)
650 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
652 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
654 json_object_string_add(json_mac
, "type",
656 json_object_string_add(
657 json_mac
, "remoteVtep",
658 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
659 json_object_object_add(json_mac_hdr
, buf1
,
668 * Print MACs for all VNI.
670 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
673 json_object
*json
= NULL
, *json_vni
= NULL
;
674 json_object
*json_mac
= NULL
;
677 struct mac_walk_ctx
*wctx
= ctxt
;
678 char vni_str
[VNI_STR_LEN
];
680 vty
= (struct vty
*)wctx
->vty
;
681 json
= (struct json_object
*)wctx
->json
;
683 zvni
= (zebra_vni_t
*)backet
->data
;
686 vty_out(vty
, "{}\n");
691 /*We are iterating over a new VNI, set the count to 0*/
694 num_macs
= num_valid_macs(zvni
);
699 json_vni
= json_object_new_object();
700 json_mac
= json_object_new_object();
701 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
704 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
706 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
707 zvni
->vni
, num_macs
);
708 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
709 "Intf/Remote VTEP", "VLAN");
711 json_object_int_add(json_vni
, "numMacs", num_macs
);
713 /* assign per-vni to wctx->json object to fill macs
714 * under the vni. Re-assign primary json object to fill
715 * next vni information.
717 wctx
->json
= json_mac
;
718 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
722 json_object_object_add(json_vni
, "macs", json_mac
);
723 json_object_object_add(json
, vni_str
, json_vni
);
727 static void zl3vni_print_nh_hash(struct hash_backet
*backet
, void *ctx
)
729 struct nh_walk_ctx
*wctx
= NULL
;
730 struct vty
*vty
= NULL
;
731 struct json_object
*json_vni
= NULL
;
732 struct json_object
*json_nh
= NULL
;
733 zebra_neigh_t
*n
= NULL
;
734 char buf1
[ETHER_ADDR_STRLEN
];
735 char buf2
[INET6_ADDRSTRLEN
];
737 wctx
= (struct nh_walk_ctx
*)ctx
;
739 json_vni
= wctx
->json
;
741 json_nh
= json_object_new_object();
742 n
= (zebra_neigh_t
*)backet
->data
;
747 vty_out(vty
, "%-15s %-17s\n",
748 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
749 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
751 json_object_string_add(json_nh
, "nexthopIp",
752 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
753 json_object_string_add(
754 json_nh
, "routerMac",
755 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
756 json_object_object_add(json_vni
,
757 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
762 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
765 struct vty
*vty
= NULL
;
766 json_object
*json
= NULL
;
767 json_object
*json_vni
= NULL
;
768 zebra_l3vni_t
*zl3vni
= NULL
;
770 struct nh_walk_ctx wctx
;
771 char vni_str
[VNI_STR_LEN
];
773 vty
= (struct vty
*)args
[0];
774 json
= (struct json_object
*)args
[1];
776 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
779 vty_out(vty
, "{}\n");
783 num_nh
= hashcount(zl3vni
->nh_table
);
788 json_vni
= json_object_new_object();
789 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
793 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n", zl3vni
->vni
, num_nh
);
794 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
796 json_object_int_add(json_vni
, "numNextHops", num_nh
);
798 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
800 wctx
.json
= json_vni
;
801 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
803 json_object_object_add(json
, vni_str
, json_vni
);
806 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
809 struct vty
*vty
= NULL
;
810 json_object
*json
= NULL
;
811 json_object
*json_vni
= NULL
;
812 zebra_l3vni_t
*zl3vni
= NULL
;
814 struct rmac_walk_ctx wctx
;
815 char vni_str
[VNI_STR_LEN
];
817 vty
= (struct vty
*)args
[0];
818 json
= (struct json_object
*)args
[1];
820 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
823 vty_out(vty
, "{}\n");
827 num_rmacs
= hashcount(zl3vni
->rmac_table
);
832 json_vni
= json_object_new_object();
833 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
837 vty_out(vty
, "\nVNI %u #RMACs %u\n\n", zl3vni
->vni
, num_rmacs
);
838 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
840 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
842 /* assign per-vni to wctx->json object to fill macs
843 * under the vni. Re-assign primary json object to fill
844 * next vni information.
846 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
848 wctx
.json
= json_vni
;
849 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
851 json_object_object_add(json
, vni_str
, json_vni
);
854 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
, void *ctx
)
856 zebra_mac_t
*zrmac
= NULL
;
857 struct rmac_walk_ctx
*wctx
= NULL
;
858 struct vty
*vty
= NULL
;
859 struct json_object
*json
= NULL
;
860 struct json_object
*json_rmac
= NULL
;
861 char buf
[ETHER_ADDR_STRLEN
];
863 wctx
= (struct rmac_walk_ctx
*)ctx
;
867 json_rmac
= json_object_new_object();
868 zrmac
= (zebra_mac_t
*)backet
->data
;
873 vty_out(vty
, "%-17s %-21s\n",
874 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
875 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
877 json_object_string_add(
878 json_rmac
, "routerMac",
879 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)));
880 json_object_string_add(json_rmac
, "vtepIp",
881 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
882 json_object_object_add(
883 json
, prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
888 /* print a specific L3 VNI entry */
889 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
891 char buf
[ETHER_ADDR_STRLEN
];
892 struct vty
*vty
= NULL
;
893 json_object
*json
= NULL
;
894 zebra_vni_t
*zvni
= NULL
;
895 json_object
*json_vni_list
= NULL
;
896 struct listnode
*node
= NULL
, *nnode
= NULL
;
902 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
903 vty_out(vty
, " Type: %s\n", "L3");
904 vty_out(vty
, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni
));
905 vty_out(vty
, " Local Vtep Ip: %s\n",
906 inet_ntoa(zl3vni
->local_vtep_ip
));
907 vty_out(vty
, " Vxlan-Intf: %s\n",
908 zl3vni_vxlan_if_name(zl3vni
));
909 vty_out(vty
, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni
));
910 vty_out(vty
, " State: %s\n", zl3vni_state2str(zl3vni
));
911 vty_out(vty
, " VNI Filter: %s\n",
912 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
913 ? "prefix-routes-only"
915 vty_out(vty
, " Router MAC: %s\n",
916 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
917 vty_out(vty
, " L2 VNIs: ");
918 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
919 vty_out(vty
, "%u ", zvni
->vni
);
922 json_vni_list
= json_object_new_array();
923 json_object_int_add(json
, "vni", zl3vni
->vni
);
924 json_object_string_add(json
, "type", "L3");
925 json_object_string_add(json
, "localVtepIp",
926 inet_ntoa(zl3vni
->local_vtep_ip
));
927 json_object_string_add(json
, "vxlanIntf",
928 zl3vni_vxlan_if_name(zl3vni
));
929 json_object_string_add(json
, "sviIntf",
930 zl3vni_svi_if_name(zl3vni
));
931 json_object_string_add(json
, "state", zl3vni_state2str(zl3vni
));
932 json_object_string_add(json
, "vrf", zl3vni_vrf_name(zl3vni
));
933 json_object_string_add(
935 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
936 json_object_string_add(
938 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
939 ? "prefix-routes-only"
941 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
942 json_object_array_add(json_vni_list
,
943 json_object_new_int(zvni
->vni
));
945 json_object_object_add(json
, "l2Vnis", json_vni_list
);
950 * Print a specific VNI entry.
952 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
958 json_object
*json
= NULL
;
959 json_object
*json_vtep_list
= NULL
;
960 json_object
*json_ip_str
= NULL
;
966 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
967 vty_out(vty
, " Type: %s\n", "L2");
968 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
970 json_object_int_add(json
, "vni", zvni
->vni
);
971 json_object_string_add(json
, "type", "L2");
972 json_object_string_add(json
, "vrf",
973 vrf_id_to_name(zvni
->vrf_id
));
976 if (!zvni
->vxlan_if
) { // unexpected
978 vty_out(vty
, " VxLAN interface: unknown\n");
981 num_macs
= num_valid_macs(zvni
);
982 num_neigh
= hashcount(zvni
->neigh_table
);
984 vty_out(vty
, " VxLAN interface: %s\n", zvni
->vxlan_if
->name
);
985 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
986 vty_out(vty
, " Local VTEP IP: %s\n",
987 inet_ntoa(zvni
->local_vtep_ip
));
989 json_object_string_add(json
, "vxlanInterface",
990 zvni
->vxlan_if
->name
);
991 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
992 json_object_string_add(json
, "vtepIp",
993 inet_ntoa(zvni
->local_vtep_ip
));
994 json_object_string_add(json
, "advertiseGatewayMacip",
995 zvni
->advertise_gw_macip
? "Yes" : "No");
996 json_object_int_add(json
, "numMacs", num_macs
);
997 json_object_int_add(json
, "numArpNd", num_neigh
);
1001 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1004 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1006 json_vtep_list
= json_object_new_array();
1007 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1009 vty_out(vty
, " %s\n",
1010 inet_ntoa(zvtep
->vtep_ip
));
1012 json_ip_str
= json_object_new_string(
1013 inet_ntoa(zvtep
->vtep_ip
));
1014 json_object_array_add(json_vtep_list
,
1019 json_object_object_add(json
, "numRemoteVteps",
1024 " Number of MACs (local and remote) known for this VNI: %u\n",
1027 " Number of ARPs (IPv4 and IPv6, local and remote) "
1028 "known for this VNI: %u\n",
1030 vty_out(vty
, " Advertise-gw-macip: %s\n",
1031 zvni
->advertise_gw_macip
? "Yes" : "No");
1035 /* print a L3 VNI hash entry */
1036 static void zl3vni_print_hash(struct hash_backet
*backet
, void *ctx
[])
1038 struct vty
*vty
= NULL
;
1039 json_object
*json
= NULL
;
1040 json_object
*json_vni
= NULL
;
1041 zebra_l3vni_t
*zl3vni
= NULL
;
1043 vty
= (struct vty
*)ctx
[0];
1044 json
= (json_object
*)ctx
[1];
1046 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1051 vty_out(vty
, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1052 zl3vni
->vni
, "L3", zl3vni_vxlan_if_name(zl3vni
),
1053 hashcount(zl3vni
->rmac_table
),
1054 hashcount(zl3vni
->nh_table
), "n/a",
1055 zl3vni_vrf_name(zl3vni
));
1057 char vni_str
[VNI_STR_LEN
];
1059 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1060 json_vni
= json_object_new_object();
1061 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1062 json_object_string_add(json_vni
, "vxlanIf",
1063 zl3vni_vxlan_if_name(zl3vni
));
1064 json_object_int_add(json_vni
, "numMacs",
1065 hashcount(zl3vni
->rmac_table
));
1066 json_object_int_add(json_vni
, "numArpNd",
1067 hashcount(zl3vni
->nh_table
));
1068 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1069 json_object_string_add(json_vni
, "type", "L3");
1070 json_object_string_add(json_vni
, "tenantVrf",
1071 zl3vni_vrf_name(zl3vni
));
1072 json_object_object_add(json
, vni_str
, json_vni
);
1077 * Print a VNI hash entry - called for display of all VNIs.
1079 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1083 zebra_vtep_t
*zvtep
;
1084 u_int32_t num_vteps
= 0;
1085 u_int32_t num_macs
= 0;
1086 u_int32_t num_neigh
= 0;
1087 json_object
*json
= NULL
;
1088 json_object
*json_vni
= NULL
;
1089 json_object
*json_ip_str
= NULL
;
1090 json_object
*json_vtep_list
= NULL
;
1095 zvni
= (zebra_vni_t
*)backet
->data
;
1099 zvtep
= zvni
->vteps
;
1102 zvtep
= zvtep
->next
;
1105 num_macs
= num_valid_macs(zvni
);
1106 num_neigh
= hashcount(zvni
->neigh_table
);
1108 vty_out(vty
, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1110 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1111 num_macs
, num_neigh
, num_vteps
,
1112 vrf_id_to_name(zvni
->vrf_id
));
1114 char vni_str
[VNI_STR_LEN
];
1115 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1116 json_vni
= json_object_new_object();
1117 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1118 json_object_string_add(json_vni
, "type", "L2");
1119 json_object_string_add(json_vni
, "vxlanIf",
1120 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1122 json_object_int_add(json_vni
, "numMacs", num_macs
);
1123 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1124 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1125 json_object_string_add(json_vni
, "tenantVrf",
1126 vrf_id_to_name(zvni
->vrf_id
));
1128 json_vtep_list
= json_object_new_array();
1129 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1130 json_ip_str
= json_object_new_string(
1131 inet_ntoa(zvtep
->vtep_ip
));
1132 json_object_array_add(json_vtep_list
,
1135 json_object_object_add(json_vni
, "remoteVteps",
1138 json_object_object_add(json
, vni_str
, json_vni
);
1143 * Inform BGP about local MACIP.
1145 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
1146 struct ipaddr
*ip
, u_char flags
,
1149 char buf
[ETHER_ADDR_STRLEN
];
1150 char buf2
[INET6_ADDRSTRLEN
];
1152 struct zserv
*client
= NULL
;
1153 struct stream
*s
= NULL
;
1155 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1156 /* BGP may not be running. */
1160 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
1162 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1163 stream_putl(s
, vni
);
1164 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1167 if (IS_IPADDR_V4(ip
))
1168 ipa_len
= IPV4_MAX_BYTELEN
;
1169 else if (IS_IPADDR_V6(ip
))
1170 ipa_len
= IPV6_MAX_BYTELEN
;
1172 stream_putl(s
, ipa_len
); /* IP address length */
1174 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1176 stream_putl(s
, 0); /* Just MAC. */
1178 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1181 /* Write packet size. */
1182 stream_putw_at(s
, 0, stream_get_endp(s
));
1184 if (IS_ZEBRA_DEBUG_VXLAN
)
1186 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1187 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del", flags
,
1188 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1189 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1190 zebra_route_string(client
->proto
));
1192 if (cmd
== ZEBRA_MACIP_ADD
)
1193 client
->macipadd_cnt
++;
1195 client
->macipdel_cnt
++;
1197 return zebra_server_send_message(client
, s
);
1201 * Make hash key for neighbors.
1203 static unsigned int neigh_hash_keymake(void *p
)
1205 zebra_neigh_t
*n
= p
;
1206 struct ipaddr
*ip
= &n
->ip
;
1208 if (IS_IPADDR_V4(ip
))
1209 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1211 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1212 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1216 * Compare two neighbor hash structures.
1218 static int neigh_cmp(const void *p1
, const void *p2
)
1220 const zebra_neigh_t
*n1
= p1
;
1221 const zebra_neigh_t
*n2
= p2
;
1223 if (n1
== NULL
&& n2
== NULL
)
1226 if (n1
== NULL
|| n2
== NULL
)
1229 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1233 * Callback to allocate neighbor hash entry.
1235 static void *zvni_neigh_alloc(void *p
)
1237 const zebra_neigh_t
*tmp_n
= p
;
1240 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1247 * Add neighbor entry.
1249 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1250 struct ethaddr
*mac
)
1252 zebra_neigh_t tmp_n
;
1253 zebra_neigh_t
*n
= NULL
;
1254 zebra_mac_t
*zmac
= NULL
;
1256 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1257 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1258 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1261 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1262 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1264 /* Associate the neigh to mac */
1265 zmac
= zvni_mac_lookup(zvni
, mac
);
1267 listnode_add_sort(zmac
->neigh_list
, n
);
1273 * Delete neighbor entry.
1275 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1277 zebra_neigh_t
*tmp_n
;
1278 zebra_mac_t
*zmac
= NULL
;
1280 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1282 listnode_delete(zmac
->neigh_list
, n
);
1284 /* Free the VNI hash entry and allocated memory. */
1285 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1287 XFREE(MTYPE_NEIGH
, tmp_n
);
1293 * Free neighbor hash entry (callback)
1295 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1297 struct neigh_walk_ctx
*wctx
= arg
;
1298 zebra_neigh_t
*n
= backet
->data
;
1300 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1301 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1302 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1303 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1304 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1305 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1306 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1307 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1310 if (wctx
->uninstall
)
1311 zvni_neigh_uninstall(wctx
->zvni
, n
);
1313 return zvni_neigh_del(wctx
->zvni
, n
);
1320 * Delete all neighbor entries from specific VTEP for a particular VNI.
1322 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1323 struct in_addr
*r_vtep_ip
)
1325 struct neigh_walk_ctx wctx
;
1327 if (!zvni
->neigh_table
)
1330 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1332 wctx
.uninstall
= uninstall
;
1333 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1334 wctx
.r_vtep_ip
= *r_vtep_ip
;
1336 hash_iterate(zvni
->neigh_table
,
1337 (void (*)(struct hash_backet
*,
1338 void *))zvni_neigh_del_hash_entry
,
1343 * Delete all neighbor entries for this VNI.
1345 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
1348 struct neigh_walk_ctx wctx
;
1350 if (!zvni
->neigh_table
)
1353 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1355 wctx
.uninstall
= uninstall
;
1356 wctx
.upd_client
= upd_client
;
1359 hash_iterate(zvni
->neigh_table
,
1360 (void (*)(struct hash_backet
*,
1361 void *))zvni_neigh_del_hash_entry
,
1366 * Look up neighbor hash entry.
1368 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1373 memset(&tmp
, 0, sizeof(tmp
));
1374 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1375 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1380 /* Process all neigh associated to a mac upon local mac add event */
1381 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1384 zebra_neigh_t
*n
= NULL
;
1385 struct listnode
*node
= NULL
;
1386 char buf
[ETHER_ADDR_STRLEN
];
1387 char buf2
[INET6_ADDRSTRLEN
];
1389 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1390 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1391 /* MAC is learnt locally, program all inactive neigh
1392 * pointing to this mac */
1393 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1394 if (IS_ZEBRA_DEBUG_VXLAN
)
1396 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1397 ipaddr2str(&n
->ip
, buf2
,
1399 prefix_mac2str(&n
->emac
, buf
,
1403 ZEBRA_NEIGH_SET_ACTIVE(n
);
1404 zvni_neigh_send_add_to_client(
1405 zvni
->vni
, &n
->ip
, &n
->emac
, n
->flags
);
1407 if (IS_ZEBRA_DEBUG_VXLAN
)
1409 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1410 ipaddr2str(&n
->ip
, buf2
,
1412 prefix_mac2str(&n
->emac
, buf
,
1416 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1417 /* TODO: assume the neigh has moved too ?? */
1422 /* Process all neigh associated to a mac upon local mac del event */
1423 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1426 zebra_neigh_t
*n
= NULL
;
1427 struct listnode
*node
= NULL
;
1428 char buf
[ETHER_ADDR_STRLEN
];
1429 char buf2
[INET6_ADDRSTRLEN
];
1431 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1432 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1433 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1434 if (IS_ZEBRA_DEBUG_VXLAN
)
1436 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1437 ipaddr2str(&n
->ip
, buf2
,
1439 prefix_mac2str(&n
->emac
, buf
,
1443 ZEBRA_NEIGH_SET_INACTIVE(n
);
1444 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1447 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1448 if (IS_ZEBRA_DEBUG_VXLAN
)
1450 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1451 prefix_mac2str(&n
->emac
, buf
,
1454 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1459 /* process all neigh associated to a mac entry upon remote mac add */
1460 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1463 zebra_neigh_t
*n
= NULL
;
1464 struct listnode
*node
= NULL
;
1465 char buf
[ETHER_ADDR_STRLEN
];
1466 char buf2
[INET6_ADDRSTRLEN
];
1468 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1469 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1470 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1471 if (IS_ZEBRA_DEBUG_VXLAN
)
1473 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1474 ipaddr2str(&n
->ip
, buf2
,
1476 prefix_mac2str(&n
->emac
, buf
,
1480 ZEBRA_NEIGH_SET_INACTIVE(n
);
1481 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1488 /* process all neigh associated to mac entry upon remote mac del */
1489 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1492 zebra_neigh_t
*n
= NULL
;
1493 struct listnode
*node
= NULL
;
1494 char buf
[ETHER_ADDR_STRLEN
];
1495 char buf2
[INET6_ADDRSTRLEN
];
1497 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1498 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1499 if (IS_ZEBRA_DEBUG_VXLAN
)
1501 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1502 prefix_mac2str(&n
->emac
, buf
,
1505 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1511 * Inform BGP about local neighbor addition.
1513 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
1514 struct ethaddr
*macaddr
,
1519 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1520 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1522 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1527 * Inform BGP about local neighbor deletion.
1529 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
1530 struct ethaddr
*macaddr
, u_char flags
)
1532 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1537 * Install remote neighbor into the kernel.
1539 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1541 struct zebra_if
*zif
;
1542 struct zebra_l2info_vxlan
*vxl
;
1543 struct interface
*vlan_if
;
1545 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1548 zif
= zvni
->vxlan_if
->info
;
1551 vxl
= &zif
->l2info
.vxl
;
1553 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1557 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1561 * Uninstall remote neighbor from the kernel.
1563 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1565 struct zebra_if
*zif
;
1566 struct zebra_l2info_vxlan
*vxl
;
1567 struct interface
*vlan_if
;
1569 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1572 if (!zvni
->vxlan_if
) {
1573 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1578 zif
= zvni
->vxlan_if
->info
;
1581 vxl
= &zif
->l2info
.vxl
;
1582 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1586 return kernel_del_neigh(vlan_if
, &n
->ip
);
1590 * Install neighbor hash entry - called upon access VLAN change.
1592 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1595 struct neigh_walk_ctx
*wctx
= ctxt
;
1597 n
= (zebra_neigh_t
*)backet
->data
;
1601 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1602 zvni_neigh_install(wctx
->zvni
, n
);
1605 /* Get the VRR interface for SVI if any */
1606 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1608 struct zebra_vrf
*zvrf
= NULL
;
1609 struct interface
*tmp_if
= NULL
;
1610 struct zebra_if
*zif
= NULL
;
1612 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1615 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1620 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1623 if (zif
->link
== ifp
)
1630 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1632 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1633 struct connected
*c
= NULL
;
1634 struct ethaddr macaddr
;
1636 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1638 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1641 memset(&ip
, 0, sizeof(struct ipaddr
));
1642 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1645 if (c
->address
->family
== AF_INET
) {
1646 ip
.ipa_type
= IPADDR_V4
;
1647 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1648 sizeof(struct in_addr
));
1649 } else if (c
->address
->family
== AF_INET6
) {
1650 ip
.ipa_type
= IPADDR_V6
;
1651 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1652 sizeof(struct in6_addr
));
1657 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1663 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1665 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1666 struct connected
*c
= NULL
;
1667 struct ethaddr macaddr
;
1669 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1671 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1674 memset(&ip
, 0, sizeof(struct ipaddr
));
1675 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1678 if (c
->address
->family
== AF_INET
) {
1679 ip
.ipa_type
= IPADDR_V4
;
1680 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1681 sizeof(struct in_addr
));
1682 } else if (c
->address
->family
== AF_INET6
) {
1683 ip
.ipa_type
= IPADDR_V6
;
1684 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1685 sizeof(struct in6_addr
));
1690 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1696 static int zvni_advertise_subnet(zebra_vni_t
*zvni
, struct interface
*ifp
,
1699 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1700 struct connected
*c
= NULL
;
1701 struct ethaddr macaddr
;
1703 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1705 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1708 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1710 /* skip link local address */
1711 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1716 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1717 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1719 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1720 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1726 * zvni_gw_macip_add_to_client
1728 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1729 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1731 char buf
[ETHER_ADDR_STRLEN
];
1732 char buf2
[INET6_ADDRSTRLEN
];
1733 zebra_neigh_t
*n
= NULL
;
1734 zebra_mac_t
*mac
= NULL
;
1735 struct zebra_if
*zif
= NULL
;
1736 struct zebra_l2info_vxlan
*vxl
= NULL
;
1738 zif
= zvni
->vxlan_if
->info
;
1742 vxl
= &zif
->l2info
.vxl
;
1744 mac
= zvni_mac_lookup(zvni
, macaddr
);
1746 mac
= zvni_mac_add(zvni
, macaddr
);
1748 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1749 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1750 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1755 /* Set "local" forwarding info. */
1756 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1757 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1758 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1759 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1760 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1761 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1763 n
= zvni_neigh_lookup(zvni
, ip
);
1765 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1768 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1769 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1770 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1771 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1776 /* Set "local" forwarding info. */
1777 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1778 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1779 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1780 n
->ifindex
= ifp
->ifindex
;
1782 /* Only advertise in BGP if the knob is enabled */
1783 if (!advertise_gw_macip_enabled(zvni
))
1786 if (IS_ZEBRA_DEBUG_VXLAN
)
1788 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1789 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1790 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1791 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1793 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, n
->flags
);
1799 * zvni_gw_macip_del_from_client
1801 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1804 char buf1
[ETHER_ADDR_STRLEN
];
1805 char buf2
[INET6_ADDRSTRLEN
];
1806 zebra_neigh_t
*n
= NULL
;
1807 zebra_mac_t
*mac
= NULL
;
1809 /* If the neigh entry is not present nothing to do*/
1810 n
= zvni_neigh_lookup(zvni
, ip
);
1814 /* mac entry should be present */
1815 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1817 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1818 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1819 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1823 /* If the entry is not local nothing to do*/
1824 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1827 /* only need to delete the entry from bgp if we sent it before */
1828 if (IS_ZEBRA_DEBUG_VXLAN
)
1830 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1831 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1832 prefix_mac2str(&(n
->emac
), NULL
, ETHER_ADDR_STRLEN
),
1833 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1835 /* Remove neighbor from BGP. */
1836 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1837 ZEBRA_MACIP_TYPE_GW
);
1839 /* Delete this neighbor entry. */
1840 zvni_neigh_del(zvni
, n
);
1842 /* see if the mac needs to be deleted as well*/
1844 zvni_deref_ip2mac(zvni
, mac
, 0);
1849 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1852 zebra_vni_t
*zvni
= NULL
;
1853 struct zebra_if
*zif
= NULL
;
1854 struct zebra_l2info_vxlan zl2_info
;
1855 struct interface
*vlan_if
= NULL
;
1856 struct interface
*vrr_if
= NULL
;
1857 struct interface
*ifp
;
1859 /* Add primary SVI MAC*/
1860 zvni
= (zebra_vni_t
*)backet
->data
;
1864 ifp
= zvni
->vxlan_if
;
1869 /* If down or not mapped to a bridge, we're done. */
1870 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1873 zl2_info
= zif
->l2info
.vxl
;
1876 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1880 /* Del primary MAC-IP */
1881 zvni_del_macip_for_intf(vlan_if
, zvni
);
1883 /* Del VRR MAC-IP - if any*/
1884 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1886 zvni_del_macip_for_intf(vrr_if
, zvni
);
1891 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1894 zebra_vni_t
*zvni
= NULL
;
1895 struct zebra_if
*zif
= NULL
;
1896 struct zebra_l2info_vxlan zl2_info
;
1897 struct interface
*vlan_if
= NULL
;
1898 struct interface
*vrr_if
= NULL
;
1899 struct interface
*ifp
= NULL
;
1901 zvni
= (zebra_vni_t
*)backet
->data
;
1905 ifp
= zvni
->vxlan_if
;
1910 /* If down or not mapped to a bridge, we're done. */
1911 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1913 zl2_info
= zif
->l2info
.vxl
;
1916 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1920 /* Add primary SVI MAC-IP */
1921 zvni_add_macip_for_intf(vlan_if
, zvni
);
1923 /* Add VRR MAC-IP - if any*/
1924 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1926 zvni_add_macip_for_intf(vrr_if
, zvni
);
1932 * Make hash key for MAC.
1934 static unsigned int mac_hash_keymake(void *p
)
1936 zebra_mac_t
*pmac
= p
;
1937 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1939 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1943 * Compare two MAC addresses.
1945 static int mac_cmp(const void *p1
, const void *p2
)
1947 const zebra_mac_t
*pmac1
= p1
;
1948 const zebra_mac_t
*pmac2
= p2
;
1950 if (pmac1
== NULL
&& pmac2
== NULL
)
1953 if (pmac1
== NULL
|| pmac2
== NULL
)
1956 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
, ETH_ALEN
)
1961 * Callback to allocate MAC hash entry.
1963 static void *zvni_mac_alloc(void *p
)
1965 const zebra_mac_t
*tmp_mac
= p
;
1968 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1971 return ((void *)mac
);
1977 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1979 zebra_mac_t tmp_mac
;
1980 zebra_mac_t
*mac
= NULL
;
1982 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1983 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1984 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1987 mac
->neigh_list
= list_new();
1988 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1996 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1998 zebra_mac_t
*tmp_mac
;
2000 list_delete_and_null(&mac
->neigh_list
);
2002 /* Free the VNI hash entry and allocated memory. */
2003 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2005 XFREE(MTYPE_MAC
, tmp_mac
);
2011 * Free MAC hash entry (callback)
2013 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2015 struct mac_walk_ctx
*wctx
= arg
;
2016 zebra_mac_t
*mac
= backet
->data
;
2018 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2019 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2020 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2021 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2022 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2023 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2024 &wctx
->r_vtep_ip
))) {
2025 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2026 zvni_mac_send_del_to_client(wctx
->zvni
->vni
,
2027 &mac
->macaddr
, mac
->flags
);
2030 if (wctx
->uninstall
)
2031 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2033 return zvni_mac_del(wctx
->zvni
, mac
);
2040 * Delete all MAC entries from specific VTEP for a particular VNI.
2042 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2043 struct in_addr
*r_vtep_ip
)
2045 struct mac_walk_ctx wctx
;
2047 if (!zvni
->mac_table
)
2050 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2052 wctx
.uninstall
= uninstall
;
2053 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2054 wctx
.r_vtep_ip
= *r_vtep_ip
;
2056 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2057 void *))zvni_mac_del_hash_entry
,
2062 * Delete all MAC entries for this VNI.
2064 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
2067 struct mac_walk_ctx wctx
;
2069 if (!zvni
->mac_table
)
2072 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2074 wctx
.uninstall
= uninstall
;
2075 wctx
.upd_client
= upd_client
;
2078 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2079 void *))zvni_mac_del_hash_entry
,
2084 * Look up MAC hash entry.
2086 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2091 memset(&tmp
, 0, sizeof(tmp
));
2092 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2093 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2099 * Inform BGP about local MAC addition.
2101 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2106 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2107 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2108 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2109 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2111 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2116 * Inform BGP about local MAC deletion.
2118 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2123 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2124 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2125 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2126 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2128 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2133 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2134 * notifications, to see if they are of interest.
2136 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2137 struct interface
*br_if
, vlanid_t vid
)
2139 struct zebra_ns
*zns
;
2140 struct route_node
*rn
;
2141 struct interface
*tmp_if
= NULL
;
2142 struct zebra_if
*zif
;
2143 struct zebra_l2info_bridge
*br
;
2144 struct zebra_l2info_vxlan
*vxl
= NULL
;
2145 u_char bridge_vlan_aware
;
2149 /* Determine if bridge is VLAN-aware or not */
2152 br
= &zif
->l2info
.br
;
2153 bridge_vlan_aware
= br
->vlan_aware
;
2155 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2156 /* TODO: Optimize with a hash. */
2157 zns
= zebra_ns_lookup(NS_DEFAULT
);
2158 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2159 tmp_if
= (struct interface
*)rn
->info
;
2163 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2165 if (!if_is_operative(tmp_if
))
2167 vxl
= &zif
->l2info
.vxl
;
2169 if (zif
->brslave_info
.br_if
!= br_if
)
2172 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2181 zvni
= zvni_lookup(vxl
->vni
);
2186 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2187 * neighbor notifications, to see if they are of interest.
2189 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2190 struct interface
*br_if
)
2192 struct zebra_ns
*zns
;
2193 struct route_node
*rn
;
2194 struct interface
*tmp_if
= NULL
;
2195 struct zebra_if
*zif
;
2196 struct zebra_l2info_bridge
*br
;
2197 struct zebra_l2info_vxlan
*vxl
= NULL
;
2198 u_char bridge_vlan_aware
;
2206 /* Make sure the linked interface is a bridge. */
2207 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2210 /* Determine if bridge is VLAN-aware or not */
2213 br
= &zif
->l2info
.br
;
2214 bridge_vlan_aware
= br
->vlan_aware
;
2215 if (bridge_vlan_aware
) {
2216 struct zebra_l2info_vlan
*vl
;
2218 if (!IS_ZEBRA_IF_VLAN(ifp
))
2223 vl
= &zif
->l2info
.vl
;
2227 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2228 /* TODO: Optimize with a hash. */
2229 zns
= zebra_ns_lookup(NS_DEFAULT
);
2230 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2231 tmp_if
= (struct interface
*)rn
->info
;
2235 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2237 if (!if_is_operative(tmp_if
))
2239 vxl
= &zif
->l2info
.vxl
;
2241 if (zif
->brslave_info
.br_if
!= br_if
)
2244 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2253 zvni
= zvni_lookup(vxl
->vni
);
2257 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2259 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2260 * linked to the bridge
2261 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2264 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2266 struct zebra_ns
*zns
;
2267 struct route_node
*rn
;
2268 struct interface
*tmp_if
= NULL
;
2269 struct zebra_if
*zif
;
2270 struct zebra_l2info_bridge
*br
;
2271 struct zebra_l2info_vlan
*vl
;
2272 u_char bridge_vlan_aware
;
2275 /* Defensive check, caller expected to invoke only with valid bridge. */
2279 /* Determine if bridge is VLAN-aware or not */
2282 br
= &zif
->l2info
.br
;
2283 bridge_vlan_aware
= br
->vlan_aware
;
2285 /* Check oper status of the SVI. */
2286 if (!bridge_vlan_aware
)
2287 return if_is_operative(br_if
) ? br_if
: NULL
;
2289 /* Identify corresponding VLAN interface. */
2290 /* TODO: Optimize with a hash. */
2291 zns
= zebra_ns_lookup(NS_DEFAULT
);
2292 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2293 tmp_if
= (struct interface
*)rn
->info
;
2294 /* Check oper status of the SVI. */
2295 if (!tmp_if
|| !if_is_operative(tmp_if
))
2298 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2299 || zif
->link
!= br_if
)
2301 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2303 if (vl
->vid
== vid
) {
2309 return found
? tmp_if
: NULL
;
2313 * Install remote MAC into the kernel.
2315 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2317 struct zebra_if
*zif
;
2318 struct zebra_l2info_vxlan
*vxl
;
2321 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2324 zif
= zvni
->vxlan_if
->info
;
2327 vxl
= &zif
->l2info
.vxl
;
2329 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2331 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2332 mac
->fwd_info
.r_vtep_ip
, sticky
);
2336 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2337 * moves to remote, we have to uninstall any existing local entry first.
2339 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2341 struct zebra_if
*zif
;
2342 struct zebra_l2info_vxlan
*vxl
;
2343 struct in_addr vtep_ip
= {.s_addr
= 0};
2344 struct zebra_ns
*zns
;
2345 struct interface
*ifp
;
2347 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2350 if (!zvni
->vxlan_if
) {
2351 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2356 zif
= zvni
->vxlan_if
->info
;
2359 vxl
= &zif
->l2info
.vxl
;
2362 zns
= zebra_ns_lookup(NS_DEFAULT
);
2363 ifp
= if_lookup_by_index_per_ns(zns
,
2364 mac
->fwd_info
.local
.ifindex
);
2365 if (!ifp
) // unexpected
2368 ifp
= zvni
->vxlan_if
;
2369 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2372 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2377 * Install MAC hash entry - called upon access VLAN change.
2379 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2382 struct mac_walk_ctx
*wctx
= ctxt
;
2384 mac
= (zebra_mac_t
*)backet
->data
;
2388 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2389 zvni_mac_install(wctx
->zvni
, mac
);
2393 * Decrement neighbor refcount of MAC; uninstall and free it if
2396 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2399 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2400 || !list_isempty(mac
->neigh_list
))
2404 zvni_mac_uninstall(zvni
, mac
, 0);
2406 zvni_mac_del(zvni
, mac
);
2410 * Read and populate local MACs and neighbors corresponding to this VNI.
2412 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
, struct interface
*ifp
)
2414 struct zebra_ns
*zns
;
2415 struct zebra_if
*zif
;
2416 struct interface
*vlan_if
;
2417 struct zebra_l2info_vxlan
*vxl
;
2418 struct interface
*vrr_if
;
2421 vxl
= &zif
->l2info
.vxl
;
2422 zns
= zebra_ns_lookup(NS_DEFAULT
);
2424 if (IS_ZEBRA_DEBUG_VXLAN
)
2426 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2427 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2428 zif
->brslave_info
.bridge_ifindex
);
2430 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2431 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2434 /* Add SVI MAC-IP */
2435 zvni_add_macip_for_intf(vlan_if
, zvni
);
2437 /* Add VRR MAC-IP - if any*/
2438 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2440 zvni_add_macip_for_intf(vrr_if
, zvni
);
2442 neigh_read_for_vlan(zns
, vlan_if
);
2447 * Hash function for VNI.
2449 static unsigned int vni_hash_keymake(void *p
)
2451 const zebra_vni_t
*zvni
= p
;
2453 return (jhash_1word(zvni
->vni
, 0));
2457 * Compare 2 VNI hash entries.
2459 static int vni_hash_cmp(const void *p1
, const void *p2
)
2461 const zebra_vni_t
*zvni1
= p1
;
2462 const zebra_vni_t
*zvni2
= p2
;
2464 return (zvni1
->vni
== zvni2
->vni
);
2468 * Callback to allocate VNI hash entry.
2470 static void *zvni_alloc(void *p
)
2472 const zebra_vni_t
*tmp_vni
= p
;
2475 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2476 zvni
->vni
= tmp_vni
->vni
;
2477 return ((void *)zvni
);
2481 * Look up VNI hash entry.
2483 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2485 struct zebra_vrf
*zvrf
;
2486 zebra_vni_t tmp_vni
;
2487 zebra_vni_t
*zvni
= NULL
;
2489 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2491 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2493 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2499 * Add VNI hash entry.
2501 static zebra_vni_t
*zvni_add(vni_t vni
)
2503 struct zebra_vrf
*zvrf
;
2504 zebra_vni_t tmp_zvni
;
2505 zebra_vni_t
*zvni
= NULL
;
2507 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2509 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2511 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2514 /* Create hash table for MAC */
2516 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2518 /* Create hash table for neighbors */
2519 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2520 "Zebra VNI Neighbor Table");
2526 * Delete VNI hash entry.
2528 static int zvni_del(zebra_vni_t
*zvni
)
2530 struct zebra_vrf
*zvrf
;
2531 zebra_vni_t
*tmp_zvni
;
2533 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2536 zvni
->vxlan_if
= NULL
;
2538 /* Free the neighbor hash table. */
2539 hash_free(zvni
->neigh_table
);
2540 zvni
->neigh_table
= NULL
;
2542 /* Free the MAC hash table. */
2543 hash_free(zvni
->mac_table
);
2544 zvni
->mac_table
= NULL
;
2546 /* Free the VNI hash entry and allocated memory. */
2547 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2549 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2555 * Inform BGP about local VNI addition.
2557 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2559 struct zserv
*client
;
2562 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2563 /* BGP may not be running. */
2567 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2569 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2570 stream_putl(s
, zvni
->vni
);
2571 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2572 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2574 /* Write packet size. */
2575 stream_putw_at(s
, 0, stream_get_endp(s
));
2577 if (IS_ZEBRA_DEBUG_VXLAN
)
2578 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni
->vni
,
2579 inet_ntoa(zvni
->local_vtep_ip
),
2580 vrf_id_to_name(zvni
->vrf_id
),
2581 zebra_route_string(client
->proto
));
2583 client
->vniadd_cnt
++;
2584 return zebra_server_send_message(client
, s
);
2588 * Inform BGP about local VNI deletion.
2590 static int zvni_send_del_to_client(vni_t vni
)
2592 struct zserv
*client
;
2595 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2596 /* BGP may not be running. */
2600 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2603 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2604 stream_putl(s
, vni
);
2606 /* Write packet size. */
2607 stream_putw_at(s
, 0, stream_get_endp(s
));
2609 if (IS_ZEBRA_DEBUG_VXLAN
)
2610 zlog_debug("Send VNI_DEL %u to %s", vni
,
2611 zebra_route_string(client
->proto
));
2613 client
->vnidel_cnt
++;
2614 return zebra_server_send_message(client
, s
);
2618 * Build the VNI hash table by going over the VxLAN interfaces. This
2619 * is called when EVPN (advertise-all-vni) is enabled.
2621 static void zvni_build_hash_table()
2623 struct zebra_ns
*zns
;
2624 struct route_node
*rn
;
2625 struct interface
*ifp
;
2627 /* Walk VxLAN interfaces and create VNI hash. */
2628 zns
= zebra_ns_lookup(NS_DEFAULT
);
2629 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2631 zebra_vni_t
*zvni
= NULL
;
2632 zebra_l3vni_t
*zl3vni
= NULL
;
2633 struct zebra_if
*zif
;
2634 struct zebra_l2info_vxlan
*vxl
;
2636 ifp
= (struct interface
*)rn
->info
;
2640 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2643 vxl
= &zif
->l2info
.vxl
;
2646 /* L3-VNI and L2-VNI are handled seperately */
2647 zl3vni
= zl3vni_lookup(vni
);
2650 if (IS_ZEBRA_DEBUG_VXLAN
)
2652 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2653 ifp
->name
, ifp
->ifindex
, vni
);
2655 /* associate with vxlan_if */
2656 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2657 zl3vni
->vxlan_if
= ifp
;
2660 * we need to associate with SVI.
2661 * we can associate with svi-if only after association
2662 * with vxlan-intf is complete
2664 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2666 if (is_l3vni_oper_up(zl3vni
))
2667 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2670 struct interface
*vlan_if
= NULL
;
2672 if (IS_ZEBRA_DEBUG_VXLAN
)
2674 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2675 ifp
->name
, ifp
->ifindex
, vni
,
2676 inet_ntoa(vxl
->vtep_ip
));
2678 /* VNI hash entry is not expected to exist. */
2679 zvni
= zvni_lookup(vni
);
2682 "VNI hash already present for IF %s(%u) L2-VNI %u",
2683 ifp
->name
, ifp
->ifindex
, vni
);
2687 zvni
= zvni_add(vni
);
2690 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2691 ifp
->name
, ifp
->ifindex
, vni
);
2695 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2696 zvni
->vxlan_if
= ifp
;
2697 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2698 zif
->brslave_info
.br_if
);
2700 zvni
->vrf_id
= vlan_if
->vrf_id
;
2701 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2703 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2707 /* Inform BGP if intf is up and mapped to bridge. */
2708 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2709 zvni_send_add_to_client(zvni
);
2715 * See if remote VTEP matches with prefix.
2717 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2719 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2723 * Locate remote VTEP in VNI hash table.
2725 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2727 zebra_vtep_t
*zvtep
;
2732 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2733 if (zvni_vtep_match(vtep_ip
, zvtep
))
2741 * Add remote VTEP to VNI hash table.
2743 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2745 zebra_vtep_t
*zvtep
;
2747 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2749 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2753 zvtep
->vtep_ip
= *vtep_ip
;
2756 zvni
->vteps
->prev
= zvtep
;
2757 zvtep
->next
= zvni
->vteps
;
2758 zvni
->vteps
= zvtep
;
2764 * Remove remote VTEP from VNI hash table.
2766 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2769 zvtep
->next
->prev
= zvtep
->prev
;
2771 zvtep
->prev
->next
= zvtep
->next
;
2773 zvni
->vteps
= zvtep
->next
;
2775 zvtep
->prev
= zvtep
->next
= NULL
;
2776 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2782 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2783 * uninstall from kernel if asked to.
2785 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2787 zebra_vtep_t
*zvtep
, *zvtep_next
;
2792 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2793 zvtep_next
= zvtep
->next
;
2795 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2796 zvni_vtep_del(zvni
, zvtep
);
2803 * Install remote VTEP into the kernel.
2805 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2807 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2811 * Uninstall remote VTEP from the kernel.
2813 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2815 if (!zvni
->vxlan_if
) {
2816 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2821 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2825 * Cleanup VNI/VTEP and update kernel
2827 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
2829 zebra_vni_t
*zvni
= NULL
;
2830 zebra_l3vni_t
*zl3vni
= NULL
;
2831 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
2833 zvni
= (zebra_vni_t
*)backet
->data
;
2837 /* remove from l3-vni list */
2839 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
2841 listnode_delete(zl3vni
->l2vnis
, zvni
);
2843 /* Free up all neighbors and MACs, if any. */
2844 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2845 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2847 /* Free up all remote VTEPs, if any. */
2848 zvni_vtep_del_all(zvni
, 1);
2850 /* Delete the hash entry. */
2855 static void zl3vni_cleanup_all(struct hash_backet
*backet
, void *args
)
2857 zebra_l3vni_t
*zl3vni
= NULL
;
2859 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
2863 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
2866 static int is_host_present_in_host_list(struct list
*list
, struct prefix
*host
)
2868 struct listnode
*node
= NULL
;
2869 struct prefix
*p
= NULL
;
2871 for (ALL_LIST_ELEMENTS_RO(list
, node
, p
)) {
2872 if (prefix_same(p
, host
))
2878 static void host_list_add_host(struct list
*list
, struct prefix
*host
)
2880 struct prefix
*p
= NULL
;
2882 p
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct prefix
));
2883 memcpy(p
, host
, sizeof(struct prefix
));
2885 listnode_add_sort(list
, p
);
2888 static void host_list_delete_host(struct list
*list
, struct prefix
*host
)
2890 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
2891 struct prefix
*p
= NULL
;
2893 for (ALL_LIST_ELEMENTS(list
, node
, nnode
, p
)) {
2894 if (prefix_same(p
, host
)) {
2895 XFREE(MTYPE_HOST_PREFIX
, p
);
2901 list_delete_node(list
, node_to_del
);
2905 * Look up MAC hash entry.
2907 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
2908 struct ethaddr
*rmac
)
2913 memset(&tmp
, 0, sizeof(tmp
));
2914 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
2915 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
2921 * Callback to allocate RMAC hash entry.
2923 static void *zl3vni_rmac_alloc(void *p
)
2925 const zebra_mac_t
*tmp_rmac
= p
;
2928 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2931 return ((void *)zrmac
);
2935 * Add RMAC entry to l3-vni
2937 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
)
2939 zebra_mac_t tmp_rmac
;
2940 zebra_mac_t
*zrmac
= NULL
;
2942 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
2943 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
2944 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
2947 zrmac
->host_list
= list_new();
2948 zrmac
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
2950 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
2951 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
2959 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
2961 zebra_mac_t
*tmp_rmac
;
2963 if (zrmac
->host_list
)
2964 list_delete_and_null(&zrmac
->host_list
);
2965 zrmac
->host_list
= NULL
;
2967 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
2969 XFREE(MTYPE_MAC
, tmp_rmac
);
2975 * Install remote RMAC into the kernel.
2977 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
2979 struct zebra_if
*zif
= NULL
;
2980 struct zebra_l2info_vxlan
*vxl
= NULL
;
2982 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
2983 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2986 zif
= zl3vni
->vxlan_if
->info
;
2990 vxl
= &zif
->l2info
.vxl
;
2992 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2993 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
2997 * Uninstall remote RMAC from the kernel.
2999 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3001 char buf
[ETHER_ADDR_STRLEN
];
3002 struct zebra_if
*zif
= NULL
;
3003 struct zebra_l2info_vxlan
*vxl
= NULL
;
3005 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3006 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3009 if (!zl3vni
->vxlan_if
) {
3011 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3012 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3013 zl3vni
->vni
, zl3vni
);
3017 zif
= zl3vni
->vxlan_if
->info
;
3021 vxl
= &zif
->l2info
.vxl
;
3023 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3024 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3027 /* handle rmac add */
3028 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3029 struct ipaddr
*vtep_ip
,
3030 struct prefix
*host_prefix
)
3032 char buf
[ETHER_ADDR_STRLEN
];
3033 char buf1
[INET6_ADDRSTRLEN
];
3034 zebra_mac_t
*zrmac
= NULL
;
3036 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3039 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3042 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3043 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3045 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)));
3048 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3049 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3051 /* install rmac in kernel */
3052 zl3vni_rmac_install(zl3vni
, zrmac
);
3055 if (!is_host_present_in_host_list(zrmac
->host_list
, host_prefix
))
3056 host_list_add_host(zrmac
->host_list
, host_prefix
);
3061 /* handle rmac delete */
3062 static int zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3063 struct prefix
*host_prefix
)
3065 zebra_mac_t
*zrmac
= NULL
;
3067 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3071 host_list_delete_host(zrmac
->host_list
, host_prefix
);
3072 if (list_isempty(zrmac
->host_list
)) {
3074 /* uninstall from kernel */
3075 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3077 /* del the rmac entry */
3078 zl3vni_rmac_del(zl3vni
, zrmac
);
3084 * Look up nh hash entry on a l3-vni.
3086 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3091 memset(&tmp
, 0, sizeof(tmp
));
3092 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3093 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3100 * Callback to allocate NH hash entry on L3-VNI.
3102 static void *zl3vni_nh_alloc(void *p
)
3104 const zebra_neigh_t
*tmp_n
= p
;
3107 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3114 * Add neighbor entry.
3116 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3117 struct ethaddr
*mac
)
3119 zebra_neigh_t tmp_n
;
3120 zebra_neigh_t
*n
= NULL
;
3122 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3123 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3124 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3127 n
->host_list
= list_new();
3128 n
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
3130 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3131 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3132 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3138 * Delete neighbor entry.
3140 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3142 zebra_neigh_t
*tmp_n
;
3145 list_delete_and_null(&n
->host_list
);
3146 n
->host_list
= NULL
;
3148 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3150 XFREE(MTYPE_NEIGH
, tmp_n
);
3156 * Install remote nh as neigh into the kernel.
3158 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3160 if (!is_l3vni_oper_up(zl3vni
))
3163 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3164 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3167 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3171 * Uninstall remote nh from the kernel.
3173 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3175 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3176 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3179 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3182 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3185 /* add remote vtep as a neigh entry */
3186 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3187 struct ethaddr
*rmac
,
3188 struct prefix
*host_prefix
)
3190 char buf
[ETHER_ADDR_STRLEN
];
3191 char buf1
[INET6_ADDRSTRLEN
];
3192 zebra_neigh_t
*nh
= NULL
;
3194 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3196 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3200 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3201 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)),
3202 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3207 /* install the nh neigh in kernel */
3208 zl3vni_nh_install(zl3vni
, nh
);
3211 if (!is_host_present_in_host_list(nh
->host_list
, host_prefix
))
3212 host_list_add_host(nh
->host_list
, host_prefix
);
3217 /* handle nh neigh delete */
3218 static int zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3219 struct prefix
*host_prefix
)
3221 zebra_neigh_t
*nh
= NULL
;
3223 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3227 host_list_delete_host(nh
->host_list
, host_prefix
);
3228 if (list_isempty(nh
->host_list
)) {
3230 /* uninstall from kernel */
3231 zl3vni_nh_uninstall(zl3vni
, nh
);
3233 /* delete the nh entry */
3234 zl3vni_nh_del(zl3vni
, nh
);
3240 /* handle neigh update from kernel - the only thing of interest is to
3241 * readd stale entries.
3243 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3247 zebra_neigh_t
*n
= NULL
;
3249 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3253 /* all next hop neigh are remote and installed by frr.
3254 * If the kernel has aged this entry, re-install.
3256 if (state
& NUD_STALE
)
3257 zl3vni_nh_install(zl3vni
, n
);
3262 /* handle neigh delete from kernel */
3263 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3265 zebra_neigh_t
*n
= NULL
;
3267 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3271 /* all next hop neigh are remote and installed by frr.
3272 * If we get an age out notification for these neigh entries, we have to
3275 zl3vni_nh_install(zl3vni
, n
);
3281 * Hash function for L3 VNI.
3283 static unsigned int l3vni_hash_keymake(void *p
)
3285 const zebra_l3vni_t
*zl3vni
= p
;
3287 return jhash_1word(zl3vni
->vni
, 0);
3291 * Compare 2 L3 VNI hash entries.
3293 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3295 const zebra_l3vni_t
*zl3vni1
= p1
;
3296 const zebra_l3vni_t
*zl3vni2
= p2
;
3298 return (zl3vni1
->vni
== zl3vni2
->vni
);
3302 * Callback to allocate L3 VNI hash entry.
3304 static void *zl3vni_alloc(void *p
)
3306 zebra_l3vni_t
*zl3vni
= NULL
;
3307 const zebra_l3vni_t
*tmp_l3vni
= p
;
3309 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3310 zl3vni
->vni
= tmp_l3vni
->vni
;
3311 return ((void *)zl3vni
);
3315 * Look up L3 VNI hash entry.
3317 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3319 struct zebra_ns
*zns
;
3320 zebra_l3vni_t tmp_l3vni
;
3321 zebra_l3vni_t
*zl3vni
= NULL
;
3323 zns
= zebra_ns_lookup(NS_DEFAULT
);
3325 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3326 tmp_l3vni
.vni
= vni
;
3327 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3333 * Add L3 VNI hash entry.
3335 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3337 zebra_l3vni_t tmp_zl3vni
;
3338 struct zebra_ns
*zns
= NULL
;
3339 zebra_l3vni_t
*zl3vni
= NULL
;
3341 zns
= zebra_ns_lookup(NS_DEFAULT
);
3344 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3345 tmp_zl3vni
.vni
= vni
;
3347 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3350 zl3vni
->vrf_id
= vrf_id
;
3351 zl3vni
->svi_if
= NULL
;
3352 zl3vni
->vxlan_if
= NULL
;
3353 zl3vni
->l2vnis
= list_new();
3354 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3356 /* Create hash table for remote RMAC */
3357 zl3vni
->rmac_table
= hash_create(mac_hash_keymake
, mac_cmp
,
3358 "Zebra L3-VNI RMAC-Table");
3360 /* Create hash table for neighbors */
3361 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3362 "Zebra L3-VNI next-hop table");
3368 * Delete L3 VNI hash entry.
3370 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3372 struct zebra_ns
*zns
;
3373 zebra_l3vni_t
*tmp_zl3vni
;
3375 zns
= zebra_ns_lookup(NS_DEFAULT
);
3378 /* free the list of l2vnis */
3379 list_delete_and_null(&zl3vni
->l2vnis
);
3380 zl3vni
->l2vnis
= NULL
;
3382 /* Free the rmac table */
3383 hash_free(zl3vni
->rmac_table
);
3384 zl3vni
->rmac_table
= NULL
;
3386 /* Free the nh table */
3387 hash_free(zl3vni
->nh_table
);
3388 zl3vni
->nh_table
= NULL
;
3390 /* Free the VNI hash entry and allocated memory. */
3391 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3393 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3398 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3400 struct zebra_ns
*zns
= NULL
;
3401 struct route_node
*rn
= NULL
;
3402 struct interface
*ifp
= NULL
;
3404 /* loop through all vxlan-interface */
3405 zns
= zebra_ns_lookup(NS_DEFAULT
);
3406 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3408 struct zebra_if
*zif
= NULL
;
3409 struct zebra_l2info_vxlan
*vxl
= NULL
;
3411 ifp
= (struct interface
*)rn
->info
;
3416 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3419 vxl
= &zif
->l2info
.vxl
;
3420 if (vxl
->vni
== zl3vni
->vni
) {
3421 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3429 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3431 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3432 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3437 if (!zl3vni
->vxlan_if
)
3440 zif
= zl3vni
->vxlan_if
->info
;
3444 vxl
= &zif
->l2info
.vxl
;
3446 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3449 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3451 struct zebra_vrf
*zvrf
= NULL
;
3453 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3457 return zl3vni_lookup(zvrf
->l3vni
);
3461 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3462 * neighbor notifications, to see if they are of interest.
3464 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3465 struct interface
*br_if
)
3469 u_char bridge_vlan_aware
= 0;
3470 zebra_l3vni_t
*zl3vni
= NULL
;
3471 struct zebra_ns
*zns
= NULL
;
3472 struct route_node
*rn
= NULL
;
3473 struct zebra_if
*zif
= NULL
;
3474 struct interface
*tmp_if
= NULL
;
3475 struct zebra_l2info_bridge
*br
= NULL
;
3476 struct zebra_l2info_vxlan
*vxl
= NULL
;
3481 /* Make sure the linked interface is a bridge. */
3482 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3485 /* Determine if bridge is VLAN-aware or not */
3488 br
= &zif
->l2info
.br
;
3489 bridge_vlan_aware
= br
->vlan_aware
;
3490 if (bridge_vlan_aware
) {
3491 struct zebra_l2info_vlan
*vl
;
3493 if (!IS_ZEBRA_IF_VLAN(ifp
))
3498 vl
= &zif
->l2info
.vl
;
3502 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3503 /* TODO: Optimize with a hash. */
3504 zns
= zebra_ns_lookup(NS_DEFAULT
);
3505 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3506 tmp_if
= (struct interface
*)rn
->info
;
3510 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3512 if (!if_is_operative(tmp_if
))
3514 vxl
= &zif
->l2info
.vxl
;
3516 if (zif
->brslave_info
.br_if
!= br_if
)
3519 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3528 zl3vni
= zl3vni_lookup(vxl
->vni
);
3533 * Inform BGP about l3-vni.
3535 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3537 struct stream
*s
= NULL
;
3538 struct zserv
*client
= NULL
;
3539 struct ethaddr rmac
;
3540 char buf
[ETHER_ADDR_STRLEN
];
3542 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3543 /* BGP may not be running. */
3548 memset(&rmac
, 0, sizeof(struct ethaddr
));
3549 zl3vni_get_rmac(zl3vni
, &rmac
);
3551 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3553 zclient_create_header(s
, ZEBRA_L3VNI_ADD
, zl3vni_vrf_id(zl3vni
));
3554 stream_putl(s
, zl3vni
->vni
);
3555 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3556 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3557 stream_put(s
, &zl3vni
->filter
, sizeof(int));
3559 /* Write packet size. */
3560 stream_putw_at(s
, 0, stream_get_endp(s
));
3562 if (IS_ZEBRA_DEBUG_VXLAN
)
3564 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3565 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3566 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3567 inet_ntoa(zl3vni
->local_vtep_ip
),
3568 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
3569 ? "prefix-routes-only"
3571 zebra_route_string(client
->proto
));
3573 client
->l3vniadd_cnt
++;
3574 return zebra_server_send_message(client
, s
);
3578 * Inform BGP about local l3-VNI deletion.
3580 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3582 struct stream
*s
= NULL
;
3583 struct zserv
*client
= NULL
;
3585 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3586 /* BGP may not be running. */
3590 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3592 zclient_create_header(s
, ZEBRA_L3VNI_DEL
, zl3vni_vrf_id(zl3vni
));
3593 stream_putl(s
, zl3vni
->vni
);
3595 /* Write packet size. */
3596 stream_putw_at(s
, 0, stream_get_endp(s
));
3598 if (IS_ZEBRA_DEBUG_VXLAN
)
3599 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni
->vni
,
3600 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3601 zebra_route_string(client
->proto
));
3603 client
->l3vnidel_cnt
++;
3604 return zebra_server_send_message(client
, s
);
3607 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3612 /* send l3vni add to BGP */
3613 zl3vni_send_add_to_client(zl3vni
);
3616 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3621 /* send l3-vni del to BGP*/
3622 zl3vni_send_del_to_client(zl3vni
);
3625 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
, void *ctxt
)
3627 zebra_vni_t
*zvni
= (zebra_vni_t
*)backet
->data
;
3628 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*)ctxt
;
3630 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3631 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3635 * handle transition of vni from l2 to l3 and vice versa
3637 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
, vni_t vni
,
3640 zebra_vni_t
*zvni
= NULL
;
3642 /* There is a possibility that VNI notification was already received
3643 * from kernel and we programmed it as L2-VNI
3644 * In such a case we need to delete this L2-VNI first, so
3645 * that it can be reprogrammed as L3-VNI in the system. It is also
3646 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3647 * interface is still present in kernel. In this case to keep it
3648 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3651 /* Locate hash entry */
3652 zvni
= zvni_lookup(vni
);
3656 if (IS_ZEBRA_DEBUG_VXLAN
)
3657 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni
);
3659 /* Delete VNI from BGP. */
3660 zvni_send_del_to_client(zvni
->vni
);
3662 /* Free up all neighbors and MAC, if any. */
3663 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3664 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3666 /* Free up all remote VTEPs, if any. */
3667 zvni_vtep_del_all(zvni
, 0);
3669 /* Delete the hash entry. */
3670 if (zvni_del(zvni
)) {
3671 zlog_err("Failed to del VNI hash %p, VNI %u", zvni
,
3676 /* TODO_MITESH: This needs to be thought through. We don't have
3677 * enough information at this point to reprogram the vni as
3678 * l2-vni. One way is to store the required info in l3-vni and
3679 * used it solely for this purpose
3686 /* delete and uninstall rmac hash entry */
3687 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
, void *ctx
)
3689 zebra_mac_t
*zrmac
= NULL
;
3690 zebra_l3vni_t
*zl3vni
= NULL
;
3692 zrmac
= (zebra_mac_t
*)backet
->data
;
3693 zl3vni
= (zebra_l3vni_t
*)ctx
;
3694 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3695 zl3vni_rmac_del(zl3vni
, zrmac
);
3698 /* delete and uninstall nh hash entry */
3699 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
, void *ctx
)
3701 zebra_neigh_t
*n
= NULL
;
3702 zebra_l3vni_t
*zl3vni
= NULL
;
3704 n
= (zebra_neigh_t
*)backet
->data
;
3705 zl3vni
= (zebra_l3vni_t
*)ctx
;
3706 zl3vni_nh_uninstall(zl3vni
, n
);
3707 zl3vni_nh_del(zl3vni
, n
);
3710 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
3713 struct zserv
*client
= NULL
;
3714 struct stream
*s
= NULL
;
3715 char buf
[PREFIX_STRLEN
];
3717 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3718 /* BGP may not be running. */
3722 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3724 zclient_create_header(s
, cmd
, vrf_id
);
3725 stream_put(s
, p
, sizeof(struct prefix
));
3727 /* Write packet size. */
3728 stream_putw_at(s
, 0, stream_get_endp(s
));
3730 if (IS_ZEBRA_DEBUG_VXLAN
)
3731 zlog_debug("Send ip prefix %s %s on vrf %s",
3732 prefix2str(p
, buf
, sizeof(buf
)),
3733 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
3734 vrf_id_to_name(vrf_id
));
3736 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
3737 client
->prefixadd_cnt
++;
3739 client
->prefixdel_cnt
++;
3741 return zebra_server_send_message(client
, s
);
3744 /* re-add remote rmac if needed */
3745 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
3746 struct ethaddr
*rmac
)
3748 char buf
[ETHER_ADDR_STRLEN
];
3749 zebra_mac_t
*zrmac
= NULL
;
3751 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3755 if (IS_ZEBRA_DEBUG_VXLAN
)
3756 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
3757 prefix_mac2str(rmac
, buf
, sizeof(buf
)), zl3vni
->vni
);
3759 zl3vni_rmac_install(zl3vni
, zrmac
);
3763 /* Public functions */
3765 int is_l3vni_for_prefix_routes_only(vni_t vni
)
3767 zebra_l3vni_t
*zl3vni
= NULL
;
3769 zl3vni
= zl3vni_lookup(vni
);
3773 return CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
) ? 1 : 0;
3776 /* handle evpn route in vrf table */
3777 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
3778 struct ipaddr
*vtep_ip
,
3779 struct prefix
*host_prefix
)
3781 zebra_l3vni_t
*zl3vni
= NULL
;
3783 zl3vni
= zl3vni_from_vrf(vrf_id
);
3784 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3787 /* add the next hop neighbor */
3788 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
3791 zl3vni_remote_rmac_add(zl3vni
, rmac
, vtep_ip
, host_prefix
);
3794 /* handle evpn vrf route delete */
3795 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
3796 struct ipaddr
*vtep_ip
,
3797 struct prefix
*host_prefix
)
3799 zebra_l3vni_t
*zl3vni
= NULL
;
3801 zl3vni
= zl3vni_from_vrf(vrf_id
);
3805 /* delete the next hop entry */
3806 zl3vni_remote_nh_del(zl3vni
, vtep_ip
, host_prefix
);
3808 /* delete the rmac entry */
3809 zl3vni_remote_rmac_del(zl3vni
, rmac
, host_prefix
);
3812 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
, vni_t l3vni
,
3813 struct ethaddr
*rmac
,
3816 zebra_l3vni_t
*zl3vni
= NULL
;
3817 zebra_mac_t
*zrmac
= NULL
;
3818 json_object
*json
= NULL
;
3820 if (!is_evpn_enabled()) {
3822 vty_out(vty
, "{}\n");
3827 json
= json_object_new_object();
3829 zl3vni
= zl3vni_lookup(l3vni
);
3832 vty_out(vty
, "{}\n");
3834 vty_out(vty
, "%% L3-VNI %u doesnt exist\n", l3vni
);
3838 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3841 vty_out(vty
, "{}\n");
3844 "%% Requested RMAC doesnt exist in L3-VNI %u",
3849 zl3vni_print_rmac(zrmac
, vty
, json
);
3852 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3853 json
, JSON_C_TO_STRING_PRETTY
));
3854 json_object_free(json
);
3858 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
, vni_t l3vni
,
3861 zebra_l3vni_t
*zl3vni
;
3862 u_int32_t num_rmacs
;
3863 struct rmac_walk_ctx wctx
;
3864 json_object
*json
= NULL
;
3866 if (!is_evpn_enabled())
3869 zl3vni
= zl3vni_lookup(l3vni
);
3872 vty_out(vty
, "{}\n");
3874 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3877 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3882 json
= json_object_new_object();
3884 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3888 vty_out(vty
, "Number of Remote RMACs known for this VNI: %u\n",
3890 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
3892 json_object_int_add(json
, "numRmacs", num_rmacs
);
3894 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3897 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3898 json
, JSON_C_TO_STRING_PRETTY
));
3899 json_object_free(json
);
3903 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
, u_char use_json
)
3905 struct zebra_ns
*zns
= NULL
;
3906 json_object
*json
= NULL
;
3909 if (!is_evpn_enabled()) {
3911 vty_out(vty
, "{}\n");
3915 zns
= zebra_ns_lookup(NS_DEFAULT
);
3918 vty_out(vty
, "{}\n");
3923 json
= json_object_new_object();
3927 hash_iterate(zns
->l3vni_table
,
3928 (void (*)(struct hash_backet
*,
3929 void *))zl3vni_print_rmac_hash_all_vni
,
3933 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3934 json
, JSON_C_TO_STRING_PRETTY
));
3935 json_object_free(json
);
3939 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
, vni_t l3vni
,
3940 struct ipaddr
*ip
, u_char use_json
)
3942 zebra_l3vni_t
*zl3vni
= NULL
;
3943 zebra_neigh_t
*n
= NULL
;
3944 json_object
*json
= NULL
;
3946 if (!is_evpn_enabled()) {
3948 vty_out(vty
, "{}\n");
3953 json
= json_object_new_object();
3955 zl3vni
= zl3vni_lookup(l3vni
);
3958 vty_out(vty
, "{}\n");
3960 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3964 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3967 vty_out(vty
, "{}\n");
3970 "%% Requested next-hop not present for L3-VNI %u",
3975 zl3vni_print_nh(n
, vty
, json
);
3978 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3979 json
, JSON_C_TO_STRING_PRETTY
));
3980 json_object_free(json
);
3984 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
, vni_t l3vni
, u_char use_json
)
3987 struct nh_walk_ctx wctx
;
3988 json_object
*json
= NULL
;
3989 zebra_l3vni_t
*zl3vni
= NULL
;
3991 if (!is_evpn_enabled())
3994 zl3vni
= zl3vni_lookup(l3vni
);
3997 vty_out(vty
, "{}\n");
3999 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4003 num_nh
= hashcount(zl3vni
->nh_table
);
4008 json
= json_object_new_object();
4013 vty_out(vty
, "Number of NH Neighbors known for this VNI: %u\n",
4015 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4017 json_object_int_add(json
, "numNextHops", num_nh
);
4019 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4022 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4023 json
, JSON_C_TO_STRING_PRETTY
));
4024 json_object_free(json
);
4028 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
, u_char use_json
)
4030 struct zebra_ns
*zns
= NULL
;
4031 json_object
*json
= NULL
;
4034 if (!is_evpn_enabled()) {
4036 vty_out(vty
, "{}\n");
4040 zns
= zebra_ns_lookup(NS_DEFAULT
);
4045 json
= json_object_new_object();
4049 hash_iterate(zns
->l3vni_table
,
4050 (void (*)(struct hash_backet
*,
4051 void *))zl3vni_print_nh_hash_all_vni
,
4055 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4056 json
, JSON_C_TO_STRING_PRETTY
));
4057 json_object_free(json
);
4063 * Display L3 VNI information (VTY command handler).
4065 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
4068 json_object
*json
= NULL
;
4069 zebra_l3vni_t
*zl3vni
= NULL
;
4071 if (!is_evpn_enabled()) {
4073 vty_out(vty
, "{}\n");
4077 zl3vni
= zl3vni_lookup(vni
);
4080 vty_out(vty
, "{}\n");
4082 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4087 json
= json_object_new_object();
4091 zl3vni_print(zl3vni
, (void *)args
);
4094 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4095 json
, JSON_C_TO_STRING_PRETTY
));
4096 json_object_free(json
);
4100 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4101 json_object
*json_vrfs
)
4103 char buf
[ETHER_ADDR_STRLEN
];
4104 zebra_l3vni_t
*zl3vni
= NULL
;
4106 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4111 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4112 zvrf_name(zvrf
), zl3vni
->vni
,
4113 zl3vni_vxlan_if_name(zl3vni
),
4114 zl3vni_svi_if_name(zl3vni
), zl3vni_state2str(zl3vni
),
4115 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4117 json_object
*json_vrf
= NULL
;
4118 json_vrf
= json_object_new_object();
4119 json_object_string_add(json_vrf
, "vrf", zvrf_name(zvrf
));
4120 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4121 json_object_string_add(json_vrf
, "vxlanIntf",
4122 zl3vni_vxlan_if_name(zl3vni
));
4123 json_object_string_add(json_vrf
, "sviIntf",
4124 zl3vni_svi_if_name(zl3vni
));
4125 json_object_string_add(json_vrf
, "state",
4126 zl3vni_state2str(zl3vni
));
4127 json_object_string_add(
4128 json_vrf
, "routerMac",
4129 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4130 json_object_array_add(json_vrfs
, json_vrf
);
4135 * Display Neighbors for a VNI (VTY command handler).
4137 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4138 vni_t vni
, u_char use_json
)
4141 u_int32_t num_neigh
;
4142 struct neigh_walk_ctx wctx
;
4143 json_object
*json
= NULL
;
4145 if (!is_evpn_enabled())
4147 zvni
= zvni_lookup(vni
);
4150 vty_out(vty
, "{}\n");
4152 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4155 num_neigh
= hashcount(zvni
->neigh_table
);
4160 json
= json_object_new_object();
4162 /* Since we have IPv6 addresses to deal with which can vary widely in
4163 * size, we try to be a bit more elegant in display by first computing
4164 * the maximum width.
4166 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4169 wctx
.addr_width
= 15;
4171 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4175 "Number of ARPs (local and remote) known for this VNI: %u\n",
4177 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
4178 "Type", "MAC", "Remote VTEP");
4180 json_object_int_add(json
, "numArpNd", num_neigh
);
4182 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4184 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4185 json
, JSON_C_TO_STRING_PRETTY
));
4186 json_object_free(json
);
4191 * Display neighbors across all VNIs (VTY command handler).
4193 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4196 json_object
*json
= NULL
;
4199 if (!is_evpn_enabled())
4203 json
= json_object_new_object();
4207 hash_iterate(zvrf
->vni_table
,
4208 (void (*)(struct hash_backet
*,
4209 void *))zvni_print_neigh_hash_all_vni
,
4212 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4213 json
, JSON_C_TO_STRING_PRETTY
));
4214 json_object_free(json
);
4219 * Display specific neighbor for a VNI, if present (VTY command handler).
4221 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4222 struct zebra_vrf
*zvrf
, vni_t vni
,
4223 struct ipaddr
*ip
, u_char use_json
)
4227 json_object
*json
= NULL
;
4229 if (!is_evpn_enabled())
4231 zvni
= zvni_lookup(vni
);
4234 vty_out(vty
, "{}\n");
4236 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4239 n
= zvni_neigh_lookup(zvni
, ip
);
4243 "%% Requested neighbor does not exist in VNI %u\n",
4248 json
= json_object_new_object();
4250 zvni_print_neigh(n
, vty
, json
);
4253 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4254 json
, JSON_C_TO_STRING_PRETTY
));
4255 json_object_free(json
);
4260 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4261 * By definition, these are remote neighbors.
4263 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4264 vni_t vni
, struct in_addr vtep_ip
,
4268 u_int32_t num_neigh
;
4269 struct neigh_walk_ctx wctx
;
4270 json_object
*json
= NULL
;
4272 if (!is_evpn_enabled())
4274 zvni
= zvni_lookup(vni
);
4277 vty_out(vty
, "{}\n");
4279 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4282 num_neigh
= hashcount(zvni
->neigh_table
);
4286 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4289 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4290 wctx
.r_vtep_ip
= vtep_ip
;
4292 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4295 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4296 json
, JSON_C_TO_STRING_PRETTY
));
4297 json_object_free(json
);
4302 * Display MACs for a VNI (VTY command handler).
4304 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4305 vni_t vni
, u_char use_json
)
4309 struct mac_walk_ctx wctx
;
4310 json_object
*json
= NULL
;
4311 json_object
*json_mac
= NULL
;
4313 if (!is_evpn_enabled())
4315 zvni
= zvni_lookup(vni
);
4318 vty_out(vty
, "{}\n");
4320 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4323 num_macs
= num_valid_macs(zvni
);
4328 json
= json_object_new_object();
4329 json_mac
= json_object_new_object();
4332 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4335 wctx
.json
= json_mac
;
4339 "Number of MACs (local and remote) known for this VNI: %u\n",
4341 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4342 "Intf/Remote VTEP", "VLAN");
4344 json_object_int_add(json
, "numMacs", num_macs
);
4346 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4349 json_object_object_add(json
, "macs", json_mac
);
4350 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4351 json
, JSON_C_TO_STRING_PRETTY
));
4352 json_object_free(json
);
4357 * Display MACs for all VNIs (VTY command handler).
4359 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4362 struct mac_walk_ctx wctx
;
4363 json_object
*json
= NULL
;
4365 if (!is_evpn_enabled()) {
4367 vty_out(vty
, "{}\n");
4371 json
= json_object_new_object();
4373 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4376 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4379 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4380 json
, JSON_C_TO_STRING_PRETTY
));
4381 json_object_free(json
);
4386 * Display MACs for all VNIs (VTY command handler).
4388 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4389 struct zebra_vrf
*zvrf
,
4390 struct in_addr vtep_ip
,
4393 struct mac_walk_ctx wctx
;
4394 json_object
*json
= NULL
;
4396 if (!is_evpn_enabled())
4400 json
= json_object_new_object();
4402 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4404 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4405 wctx
.r_vtep_ip
= vtep_ip
;
4407 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
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 specific MAC for a VNI, if present (VTY command handler).
4419 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4420 vni_t vni
, struct ethaddr
*macaddr
)
4425 if (!is_evpn_enabled())
4427 zvni
= zvni_lookup(vni
);
4429 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4432 mac
= zvni_mac_lookup(zvni
, macaddr
);
4434 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4439 zvni_print_mac(mac
, vty
);
4443 * Display MACs for a VNI from specific VTEP (VTY command handler).
4445 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4446 vni_t vni
, struct in_addr vtep_ip
,
4451 struct mac_walk_ctx wctx
;
4452 json_object
*json
= NULL
;
4453 json_object
*json_mac
= NULL
;
4455 if (!is_evpn_enabled())
4457 zvni
= zvni_lookup(vni
);
4460 vty_out(vty
, "{}\n");
4462 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4465 num_macs
= num_valid_macs(zvni
);
4470 json
= json_object_new_object();
4471 json_mac
= json_object_new_object();
4474 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4477 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4478 wctx
.r_vtep_ip
= vtep_ip
;
4479 wctx
.json
= json_mac
;
4480 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4483 json_object_int_add(json
, "numMacs", wctx
.count
);
4485 json_object_object_add(json
, "macs", json_mac
);
4486 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4487 json
, JSON_C_TO_STRING_PRETTY
));
4488 json_object_free(json
);
4494 * Display VNI information (VTY command handler).
4496 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4499 json_object
*json
= NULL
;
4501 zebra_l3vni_t
*zl3vni
= NULL
;
4502 zebra_vni_t
*zvni
= NULL
;
4504 if (!is_evpn_enabled())
4508 json
= json_object_new_object();
4512 zl3vni
= zl3vni_lookup(vni
);
4514 zl3vni_print(zl3vni
, (void *)args
);
4516 zvni
= zvni_lookup(vni
);
4519 vty_out(vty
, "{}\n");
4521 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4525 zvni_print(zvni
, (void *)args
);
4529 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4530 json
, JSON_C_TO_STRING_PRETTY
));
4531 json_object_free(json
);
4535 /* Display all global details for EVPN */
4536 void zebra_vxlan_print_evpn(struct vty
*vty
, u_char uj
)
4541 json_object
*json
= NULL
;
4542 struct zebra_ns
*zns
= NULL
;
4543 struct zebra_vrf
*zvrf
= NULL
;
4545 if (!is_evpn_enabled())
4548 zns
= zebra_ns_lookup(NS_DEFAULT
);
4552 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
4556 num_l3vnis
= hashcount(zns
->l3vni_table
);
4557 num_l2vnis
= hashcount(zvrf
->vni_table
);
4558 num_vnis
= num_l2vnis
+ num_l3vnis
;
4561 json
= json_object_new_object();
4562 json_object_string_add(json
, "advertiseGatewayMacip",
4563 zvrf
->advertise_gw_macip
? "Yes" : "No");
4564 json_object_int_add(json
, "numVnis", num_vnis
);
4565 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
4566 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
4568 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
4569 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
4570 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4571 zvrf
->advertise_gw_macip
? "Yes" : "No");
4575 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4576 json
, JSON_C_TO_STRING_PRETTY
));
4577 json_object_free(json
);
4582 * Display VNI hash table (VTY command handler).
4584 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4587 json_object
*json
= NULL
;
4588 struct zebra_ns
*zns
= NULL
;
4591 if (!is_evpn_enabled())
4594 zns
= zebra_ns_lookup(NS_DEFAULT
);
4600 json
= json_object_new_object();
4602 vty_out(vty
, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
4603 "Type", "VxLAN IF", "# MACs", "# ARPs",
4604 "# Remote VTEPs", "Tenant VRF");
4609 /* Display all L2-VNIs */
4610 hash_iterate(zvrf
->vni_table
,
4611 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4614 /* Display all L3-VNIs */
4615 hash_iterate(zns
->l3vni_table
,
4616 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
4620 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4621 json
, JSON_C_TO_STRING_PRETTY
));
4622 json_object_free(json
);
4627 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4628 * kernel. This may result in either the neighbor getting deleted from
4629 * our database or being re-added to the kernel (if it is a valid
4632 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4633 struct interface
*link_if
, struct ipaddr
*ip
)
4635 char buf
[INET6_ADDRSTRLEN
];
4636 char buf2
[ETHER_ADDR_STRLEN
];
4637 zebra_neigh_t
*n
= NULL
;
4638 zebra_vni_t
*zvni
= NULL
;
4639 zebra_mac_t
*zmac
= NULL
;
4640 zebra_l3vni_t
*zl3vni
= NULL
;
4642 /* check if this is a remote neigh entry corresponding to remote
4645 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4647 return zl3vni_local_nh_del(zl3vni
, ip
);
4649 /* We are only interested in neighbors on an SVI that resides on top
4650 * of a VxLAN bridge.
4652 zvni
= zvni_from_svi(ifp
, link_if
);
4656 if (!zvni
->vxlan_if
) {
4658 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4663 if (IS_ZEBRA_DEBUG_VXLAN
)
4664 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4665 ipaddr2str(ip
, buf
, sizeof(buf
)), ifp
->name
,
4666 ifp
->ifindex
, zvni
->vni
);
4668 /* If entry doesn't exist, nothing to do. */
4669 n
= zvni_neigh_lookup(zvni
, ip
);
4673 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4675 if (IS_ZEBRA_DEBUG_VXLAN
)
4677 "Trying to del a neigh %s without a mac %s on VNI %u",
4678 ipaddr2str(ip
, buf
, sizeof(buf
)),
4679 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4685 /* If it is a remote entry, the kernel has aged this out or someone has
4686 * deleted it, it needs to be re-installed as Quagga is the owner.
4688 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4689 zvni_neigh_install(zvni
, n
);
4693 /* Remove neighbor from BGP. */
4694 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4695 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
, 0);
4697 /* Delete this neighbor entry. */
4698 zvni_neigh_del(zvni
, n
);
4700 /* see if the AUTO mac needs to be deleted */
4701 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4702 && !listcount(zmac
->neigh_list
))
4703 zvni_mac_del(zvni
, zmac
);
4709 * Handle neighbor add or update (on a VLAN device / L3 interface)
4712 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4713 struct interface
*link_if
,
4715 struct ethaddr
*macaddr
, u_int16_t state
,
4718 char buf
[ETHER_ADDR_STRLEN
];
4719 char buf2
[INET6_ADDRSTRLEN
];
4720 zebra_vni_t
*zvni
= NULL
;
4721 zebra_neigh_t
*n
= NULL
;
4722 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4723 zebra_l3vni_t
*zl3vni
= NULL
;
4725 /* check if this is a remote neigh entry corresponding to remote
4728 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4730 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
4732 /* We are only interested in neighbors on an SVI that resides on top
4733 * of a VxLAN bridge.
4735 zvni
= zvni_from_svi(ifp
, link_if
);
4739 if (IS_ZEBRA_DEBUG_VXLAN
)
4741 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4742 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4743 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4744 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4747 /* create a dummy MAC if the MAC is not already present */
4748 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4750 if (IS_ZEBRA_DEBUG_VXLAN
)
4751 zlog_debug("AUTO MAC %s created for neigh %s on VNI %u",
4752 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4753 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4756 zmac
= zvni_mac_add(zvni
, macaddr
);
4758 zlog_warn("Failed to add MAC %s VNI %u",
4759 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4764 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4765 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4766 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4769 /* If same entry already exists, it might be a change or it might be a
4770 * move from remote to local.
4772 n
= zvni_neigh_lookup(zvni
, ip
);
4774 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4775 if (memcmp(n
->emac
.octet
, macaddr
->octet
, ETH_ALEN
)
4777 /* Update any params and return - client doesn't
4778 * care about a purely local change.
4780 n
->ifindex
= ifp
->ifindex
;
4784 /* If the MAC has changed,
4785 * need to issue a delete first
4786 * as this means a different MACIP route.
4787 * Also, need to do some unlinking/relinking.
4789 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4791 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4793 listnode_delete(old_zmac
->neigh_list
, n
);
4794 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4797 /* Set "local" forwarding info. */
4798 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4799 n
->ifindex
= ifp
->ifindex
;
4800 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4802 /* Link to new MAC */
4803 listnode_add_sort(zmac
->neigh_list
, n
);
4804 } else if (ext_learned
)
4805 /* The neighbor is remote and that is the notification we got.
4808 /* TODO: Evaluate if we need to do anything here. */
4811 /* Neighbor has moved from remote to local. */
4813 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4814 n
->r_vtep_ip
.s_addr
= 0;
4815 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4816 n
->ifindex
= ifp
->ifindex
;
4819 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4822 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4823 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4824 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4825 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4828 /* Set "local" forwarding info. */
4829 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4830 n
->ifindex
= ifp
->ifindex
;
4833 /* Before we program this in BGP, we need to check if MAC is locally
4835 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4836 if (IS_ZEBRA_DEBUG_VXLAN
)
4838 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4839 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4840 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4847 if (IS_ZEBRA_DEBUG_VXLAN
)
4848 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
4849 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4850 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4852 ZEBRA_NEIGH_SET_ACTIVE(n
);
4854 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, n
->flags
);
4859 * Handle message from client to delete a remote MACIP for a VNI.
4861 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS
)
4865 struct ethaddr macaddr
;
4867 struct in_addr vtep_ip
;
4871 u_short l
= 0, ipa_len
;
4872 char buf
[ETHER_ADDR_STRLEN
];
4873 char buf1
[INET6_ADDRSTRLEN
];
4874 struct interface
*ifp
= NULL
;
4875 struct zebra_if
*zif
= NULL
;
4877 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4878 memset(&ip
, 0, sizeof(struct ipaddr
));
4879 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4883 while (l
< hdr
->length
) {
4884 /* Obtain each remote MACIP and process. */
4885 /* Message contains VNI, followed by MAC followed by IP (if any)
4886 * followed by remote VTEP IP.
4890 memset(&ip
, 0, sizeof(ip
));
4891 STREAM_GETL(s
, vni
);
4892 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4893 STREAM_GETL(s
, ipa_len
);
4895 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4897 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4899 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4900 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4901 l
+= IPV4_MAX_BYTELEN
;
4903 if (IS_ZEBRA_DEBUG_VXLAN
)
4905 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4906 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4907 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4909 zebra_route_string(client
->proto
));
4911 /* Locate VNI hash entry - expected to exist. */
4912 zvni
= zvni_lookup(vni
);
4914 if (IS_ZEBRA_DEBUG_VXLAN
)
4916 "Failed to locate VNI hash upon remote MACIP DEL, "
4921 ifp
= zvni
->vxlan_if
;
4924 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4930 /* If down or not mapped to a bridge, we're done. */
4931 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4934 /* The remote VTEP specified is normally expected to exist, but
4936 * possible that the peer may delete the VTEP before deleting
4938 * referring to the VTEP, in which case the handler (see
4940 * would have already deleted the MACs.
4942 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4945 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4947 n
= zvni_neigh_lookup(zvni
, &ip
);
4950 zlog_err("Failed to locate MAC %s for neigh %s VNI %u",
4951 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4952 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4956 /* If the remote mac or neighbor doesn't exist there is nothing
4958 * to do. Otherwise, uninstall the entry and then remove it.
4963 /* Ignore the delete if this mac is a gateway mac-ip */
4964 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
4965 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
4967 "%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway",
4969 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4970 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4974 /* Uninstall remote neighbor or MAC. */
4976 /* When the MAC changes for an IP, it is possible the
4978 * update the new MAC before trying to delete the "old"
4980 * (as these are two different MACIP routes). Do the
4982 * if the MAC matches.
4984 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4985 && (memcmp(n
->emac
.octet
, macaddr
.octet
, ETH_ALEN
)
4987 zvni_neigh_uninstall(zvni
, n
);
4988 zvni_neigh_del(zvni
, n
);
4989 zvni_deref_ip2mac(zvni
, mac
, 1);
4992 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4993 zvni_process_neigh_on_remote_mac_del(zvni
, mac
);
4995 if (list_isempty(mac
->neigh_list
)) {
4996 zvni_mac_uninstall(zvni
, mac
, 0);
4997 zvni_mac_del(zvni
, mac
);
4999 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5009 * Handle message from client to add a remote MACIP for a VNI. This
5010 * could be just the add of a MAC address or the add of a neighbor
5013 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS
)
5017 struct ethaddr macaddr
;
5019 struct in_addr vtep_ip
;
5021 zebra_vtep_t
*zvtep
;
5022 zebra_mac_t
*mac
, *old_mac
;
5024 u_short l
= 0, ipa_len
;
5025 int update_mac
= 0, update_neigh
= 0;
5026 char buf
[ETHER_ADDR_STRLEN
];
5027 char buf1
[INET6_ADDRSTRLEN
];
5030 struct interface
*ifp
= NULL
;
5031 struct zebra_if
*zif
= NULL
;
5033 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5034 memset(&ip
, 0, sizeof(struct ipaddr
));
5035 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5037 if (!EVPN_ENABLED(zvrf
)) {
5039 "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
5040 __PRETTY_FUNCTION__
);
5046 while (l
< hdr
->length
) {
5047 /* Obtain each remote MACIP and process. */
5048 /* Message contains VNI, followed by MAC followed by IP (if any)
5049 * followed by remote VTEP IP.
5051 update_mac
= update_neigh
= 0;
5054 memset(&ip
, 0, sizeof(ip
));
5055 STREAM_GETL(s
, vni
);
5056 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5057 STREAM_GETL(s
, ipa_len
);
5059 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5061 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5063 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5064 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5065 l
+= IPV4_MAX_BYTELEN
;
5067 /* Get flags - sticky mac and/or gateway mac */
5068 flags
= stream_getc(s
);
5069 sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
5072 if (IS_ZEBRA_DEBUG_VXLAN
)
5074 "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
5075 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5076 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
5077 inet_ntoa(vtep_ip
), flags
,
5078 zebra_route_string(client
->proto
));
5080 /* Locate VNI hash entry - expected to exist. */
5081 zvni
= zvni_lookup(vni
);
5084 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
5088 ifp
= zvni
->vxlan_if
;
5091 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5097 /* If down or not mapped to a bridge, we're done. */
5098 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5101 /* The remote VTEP specified should normally exist, but it is
5103 * that when peering comes up, peer may advertise MACIP routes
5105 * advertising type-3 routes.
5107 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5109 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5111 "Failed to add remote VTEP, VNI %u zvni %p",
5116 zvni_vtep_install(zvni
, &vtep_ip
);
5119 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5121 /* Ignore the update if the mac is already present
5123 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)
5124 && CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
5125 if (IS_ZEBRA_DEBUG_VXLAN
)
5127 "%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
5129 prefix_mac2str(&macaddr
, buf
,
5131 ipaddr2str(&ip
, buf1
, sizeof(buf1
)),
5136 /* check if the remote MAC is unknown or has a change.
5137 * If so, that needs to be updated first. Note that client could
5138 * install MAC and MACIP separately or just install the latter.
5140 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
5141 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
5143 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
5148 mac
= zvni_mac_add(zvni
, &macaddr
);
5151 "Failed to add MAC %s VNI %u Remote VTEP %s",
5152 prefix_mac2str(&macaddr
, buf
,
5154 vni
, inet_ntoa(vtep_ip
));
5158 /* Is this MAC created for a MACIP? */
5160 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5163 /* Set "auto" and "remote" forwarding info. */
5164 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5165 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5166 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5167 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
5170 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5172 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5174 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
5176 /* Install the entry. */
5177 zvni_mac_install(zvni
, mac
);
5180 /* If there is no IP, continue - after clearing AUTO flag of
5183 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5187 /* Check if the remote neighbor itself is unknown or has a
5189 * If so, create or update and then install the entry.
5191 n
= zvni_neigh_lookup(zvni
, &ip
);
5192 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5193 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
5194 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
5199 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
5202 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5203 ipaddr2str(&ip
, buf1
,
5205 prefix_mac2str(&macaddr
, buf
,
5207 vni
, inet_ntoa(vtep_ip
));
5211 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
5213 /* MAC change, update neigh list for old and new
5215 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
5217 listnode_delete(old_mac
->neigh_list
, n
);
5218 zvni_deref_ip2mac(zvni
, old_mac
, 1);
5220 listnode_add_sort(mac
->neigh_list
, n
);
5221 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
5224 /* Set "remote" forwarding info. */
5225 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
5226 /* TODO: Handle MAC change. */
5227 n
->r_vtep_ip
= vtep_ip
;
5228 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
5230 /* Install the entry. */
5231 zvni_neigh_install(zvni
, n
);
5240 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5241 * us, this must involve a multihoming scenario. Treat this as implicit delete
5242 * of any prior local MAC.
5244 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5245 struct interface
*br_if
,
5246 struct ethaddr
*macaddr
, vlanid_t vid
)
5248 struct zebra_if
*zif
;
5249 struct zebra_l2info_vxlan
*vxl
;
5253 char buf
[ETHER_ADDR_STRLEN
];
5257 vxl
= &zif
->l2info
.vxl
;
5260 /* Check if EVPN is enabled. */
5261 if (!is_evpn_enabled())
5264 /* Locate hash entry; it is expected to exist. */
5265 zvni
= zvni_lookup(vni
);
5269 /* If entry doesn't exist, nothing to do. */
5270 mac
= zvni_mac_lookup(zvni
, macaddr
);
5274 /* Is it a local entry? */
5275 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5278 if (IS_ZEBRA_DEBUG_VXLAN
)
5280 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5281 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5284 /* Remove MAC from BGP. */
5285 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5288 * If there are no neigh associated with the mac delete the mac
5289 * else mark it as AUTO for forward reference
5291 if (!listcount(mac
->neigh_list
)) {
5292 zvni_mac_del(zvni
, mac
);
5294 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5295 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5302 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5303 * This can happen because the remote MAC entries are also added as "dynamic",
5304 * so the kernel can ageout the entry.
5306 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5307 struct interface
*br_if
,
5308 struct ethaddr
*macaddr
, vlanid_t vid
)
5310 struct zebra_if
*zif
= NULL
;
5311 struct zebra_l2info_vxlan
*vxl
= NULL
;
5313 zebra_vni_t
*zvni
= NULL
;
5314 zebra_l3vni_t
*zl3vni
= NULL
;
5315 zebra_mac_t
*mac
= NULL
;
5316 char buf
[ETHER_ADDR_STRLEN
];
5320 vxl
= &zif
->l2info
.vxl
;
5323 /* Check if EVPN is enabled. */
5324 if (!is_evpn_enabled())
5327 /* check if this is a remote RMAC and readd simillar to remote macs */
5328 zl3vni
= zl3vni_lookup(vni
);
5330 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5332 /* Locate hash entry; it is expected to exist. */
5333 zvni
= zvni_lookup(vni
);
5337 /* If entry doesn't exist, nothing to do. */
5338 mac
= zvni_mac_lookup(zvni
, macaddr
);
5342 /* Is it a remote entry? */
5343 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5346 if (IS_ZEBRA_DEBUG_VXLAN
)
5347 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5348 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5351 zvni_mac_install(zvni
, mac
);
5356 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5358 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5359 struct ethaddr
*macaddr
, vlanid_t vid
)
5363 char buf
[ETHER_ADDR_STRLEN
];
5365 /* We are interested in MACs only on ports or (port, VLAN) that
5368 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5371 if (!zvni
->vxlan_if
) {
5372 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5377 if (IS_ZEBRA_DEBUG_VXLAN
)
5378 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5379 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5380 ifp
->ifindex
, vid
, zvni
->vni
);
5382 /* If entry doesn't exist, nothing to do. */
5383 mac
= zvni_mac_lookup(zvni
, macaddr
);
5387 /* Is it a local entry? */
5388 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5391 /* Remove MAC from BGP. */
5392 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5394 /* Update all the neigh entries associated with this mac */
5395 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5398 * If there are no neigh associated with the mac delete the mac
5399 * else mark it as AUTO for forward reference
5401 if (!listcount(mac
->neigh_list
)) {
5402 zvni_mac_del(zvni
, mac
);
5404 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5405 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5412 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5414 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5415 struct interface
*br_if
,
5416 struct ethaddr
*macaddr
, vlanid_t vid
,
5421 char buf
[ETHER_ADDR_STRLEN
];
5425 /* We are interested in MACs only on ports or (port, VLAN) that
5428 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5430 if (IS_ZEBRA_DEBUG_VXLAN
)
5432 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5433 sticky
? "sticky " : "",
5434 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5435 ifp
->name
, ifp
->ifindex
, vid
);
5439 if (!zvni
->vxlan_if
) {
5440 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5445 if (IS_ZEBRA_DEBUG_VXLAN
)
5446 zlog_debug("Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5447 sticky
? "sticky " : "",
5448 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5449 ifp
->ifindex
, vid
, zvni
->vni
);
5451 /* If same entry already exists, nothing to do. */
5452 mac
= zvni_mac_lookup(zvni
, macaddr
);
5454 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5455 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5461 * return if nothing has changed.
5462 * inform bgp if sticky flag has changed
5463 * update locally and do not inform bgp if local
5464 * parameters like interface has changed
5466 if (mac_sticky
== sticky
5467 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5468 && mac
->fwd_info
.local
.vid
== vid
) {
5469 if (IS_ZEBRA_DEBUG_VXLAN
)
5471 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5472 "entry exists and has not changed ",
5473 sticky
? "sticky " : "",
5474 prefix_mac2str(macaddr
, buf
,
5476 ifp
->name
, ifp
->ifindex
, vid
,
5479 } else if (mac_sticky
!= sticky
) {
5482 add
= 0; /* This is an update of local
5485 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5487 * If we have already learned the MAC as a remote sticky
5489 * this is a operator error and we must log a warning
5491 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5493 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5494 prefix_mac2str(macaddr
, buf
,
5496 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5504 mac
= zvni_mac_add(zvni
, macaddr
);
5506 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5507 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5508 ifp
->name
, ifp
->ifindex
, vid
);
5513 /* Set "local" forwarding info. */
5514 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5515 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5516 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5517 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5518 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5519 mac
->fwd_info
.local
.vid
= vid
;
5522 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5524 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5526 /* Inform BGP if required. */
5528 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5529 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5537 * Handle message from client to delete a remote VTEP for a VNI.
5539 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS
)
5544 struct in_addr vtep_ip
;
5546 zebra_vtep_t
*zvtep
;
5547 struct interface
*ifp
;
5548 struct zebra_if
*zif
;
5550 if (!is_evpn_enabled()) {
5552 "%s: EVPN is not enabled yet we have received a vtep del command",
5553 __PRETTY_FUNCTION__
);
5557 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5558 zlog_err("Recv MACIP DEL for non-default VRF %u",
5565 while (l
< hdr
->length
) {
5566 /* Obtain each remote VTEP and process. */
5567 STREAM_GETL(s
, vni
);
5569 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5570 l
+= IPV4_MAX_BYTELEN
;
5572 if (IS_ZEBRA_DEBUG_VXLAN
)
5573 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5574 inet_ntoa(vtep_ip
), vni
,
5575 zebra_route_string(client
->proto
));
5577 /* Locate VNI hash entry - expected to exist. */
5578 zvni
= zvni_lookup(vni
);
5580 if (IS_ZEBRA_DEBUG_VXLAN
)
5582 "Failed to locate VNI hash upon remote VTEP DEL, "
5588 ifp
= zvni
->vxlan_if
;
5591 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5597 /* If down or not mapped to a bridge, we're done. */
5598 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5601 /* If the remote VTEP does not exist, there's nothing more to
5603 * Otherwise, uninstall any remote MACs pointing to this VTEP
5605 * then, the VTEP entry itself and remove it.
5607 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5611 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5612 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5613 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5614 zvni_vtep_del(zvni
, zvtep
);
5622 * Handle message from client to add a remote VTEP for a VNI.
5624 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS
)
5629 struct in_addr vtep_ip
;
5631 struct interface
*ifp
;
5632 struct zebra_if
*zif
;
5634 if (!is_evpn_enabled()) {
5636 "%s: EVPN not enabled yet we received a vtep_add zapi call",
5637 __PRETTY_FUNCTION__
);
5641 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5642 zlog_err("Recv MACIP ADD for non-default VRF %u",
5649 while (l
< hdr
->length
) {
5650 /* Obtain each remote VTEP and process. */
5651 STREAM_GETL(s
, vni
);
5653 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5654 l
+= IPV4_MAX_BYTELEN
;
5656 if (IS_ZEBRA_DEBUG_VXLAN
)
5657 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5658 inet_ntoa(vtep_ip
), vni
,
5659 zebra_route_string(client
->proto
));
5661 /* Locate VNI hash entry - expected to exist. */
5662 zvni
= zvni_lookup(vni
);
5665 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5670 ifp
= zvni
->vxlan_if
;
5673 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5680 /* If down or not mapped to a bridge, we're done. */
5681 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5684 /* If the remote VTEP already exists,
5685 there's nothing more to do. */
5686 if (zvni_vtep_find(zvni
, &vtep_ip
))
5689 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5690 zlog_err("Failed to add remote VTEP, VNI %u zvni %p",
5695 zvni_vtep_install(zvni
, &vtep_ip
);
5703 * Add/Del gateway macip to evpn
5705 * 1. SVI interface on a vlan aware bridge
5706 * 2. SVI interface on a vlan unaware bridge
5707 * 3. vrr interface (MACVLAN) associated to a SVI
5708 * We advertise macip routes for an interface if it is associated to VxLan vlan
5710 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5714 struct ethaddr macaddr
;
5715 zebra_vni_t
*zvni
= NULL
;
5717 memset(&ip
, 0, sizeof(struct ipaddr
));
5718 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5720 /* Check if EVPN is enabled. */
5721 if (!is_evpn_enabled())
5724 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5725 struct interface
*svi_if
=
5726 NULL
; /* SVI corresponding to the MACVLAN */
5727 struct zebra_if
*ifp_zif
=
5728 NULL
; /* Zebra daemon specific info for MACVLAN */
5729 struct zebra_if
*svi_if_zif
=
5730 NULL
; /* Zebra daemon specific info for SVI*/
5732 ifp_zif
= ifp
->info
;
5737 * for a MACVLAN interface the link represents the svi_if
5739 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5740 ifp_zif
->link_ifindex
);
5742 zlog_err("MACVLAN %s(%u) without link information",
5743 ifp
->name
, ifp
->ifindex
);
5747 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5749 * If it is a vlan aware bridge then the link gives the
5750 * bridge information
5752 struct interface
*svi_if_link
= NULL
;
5754 svi_if_zif
= svi_if
->info
;
5756 svi_if_link
= if_lookup_by_index_per_ns(
5757 zebra_ns_lookup(NS_DEFAULT
),
5758 svi_if_zif
->link_ifindex
);
5759 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5761 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5763 * If it is a vlan unaware bridge then svi is the bridge
5766 zvni
= zvni_from_svi(svi_if
, svi_if
);
5768 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5769 struct zebra_if
*svi_if_zif
=
5770 NULL
; /* Zebra daemon specific info for SVI */
5771 struct interface
*svi_if_link
=
5772 NULL
; /* link info for the SVI = bridge info */
5774 svi_if_zif
= ifp
->info
;
5775 svi_if_link
= if_lookup_by_index_per_ns(
5776 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5777 if (svi_if_zif
&& svi_if_link
)
5778 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5779 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5780 zvni
= zvni_from_svi(ifp
, ifp
);
5786 if (!zvni
->vxlan_if
) {
5787 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5793 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5795 if (p
->family
== AF_INET
) {
5796 ip
.ipa_type
= IPADDR_V4
;
5797 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5798 sizeof(struct in_addr
));
5799 } else if (p
->family
== AF_INET6
) {
5800 ip
.ipa_type
= IPADDR_V6
;
5801 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5802 sizeof(struct in6_addr
));
5807 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5809 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5815 * Handle SVI interface going down.
5816 * SVI can be associated to either L3-VNI or L2-VNI.
5817 * For L2-VNI: At this point, this is a NOP since
5818 * the kernel deletes the neighbor entries on this SVI (if any).
5819 * We only need to update the vrf corresponding to zvni.
5820 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5823 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5825 zebra_l3vni_t
*zl3vni
= NULL
;
5827 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5830 /* process l3-vni down */
5831 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5833 /* remove association with svi-if */
5834 zl3vni
->svi_if
= NULL
;
5836 zebra_vni_t
*zvni
= NULL
;
5838 /* since we dont have svi corresponding to zvni, we associate it
5839 * to default vrf. Note: the corresponding neigh entries on the
5840 * SVI would have already been deleted */
5841 zvni
= zvni_from_svi(ifp
, link_if
);
5843 zvni
->vrf_id
= VRF_DEFAULT
;
5845 /* update the tenant vrf in BGP */
5846 zvni_send_add_to_client(zvni
);
5853 * Handle SVI interface coming up.
5854 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5856 * For L2-VNI: we need to install any remote neighbors entried (used for
5858 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5860 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5862 zebra_vni_t
*zvni
= NULL
;
5863 zebra_l3vni_t
*zl3vni
= NULL
;
5865 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5868 /* associate with svi */
5869 zl3vni
->svi_if
= ifp
;
5871 /* process oper-up */
5872 if (is_l3vni_oper_up(zl3vni
))
5873 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5876 /* process SVI up for l2-vni */
5877 struct neigh_walk_ctx n_wctx
;
5879 zvni
= zvni_from_svi(ifp
, link_if
);
5883 if (!zvni
->vxlan_if
) {
5884 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5889 if (IS_ZEBRA_DEBUG_VXLAN
)
5891 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5892 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5893 vrf_id_to_name(ifp
->vrf_id
));
5895 /* update the vrf information for l2-vni and inform bgp */
5896 zvni
->vrf_id
= ifp
->vrf_id
;
5897 zvni_send_add_to_client(zvni
);
5899 /* Install any remote neighbors for this VNI. */
5900 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5902 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
5910 * Handle VxLAN interface down
5912 int zebra_vxlan_if_down(struct interface
*ifp
)
5915 struct zebra_if
*zif
= NULL
;
5916 struct zebra_l2info_vxlan
*vxl
= NULL
;
5917 zebra_l3vni_t
*zl3vni
= NULL
;
5920 /* Check if EVPN is enabled. */
5921 if (!is_evpn_enabled())
5926 vxl
= &zif
->l2info
.vxl
;
5929 zl3vni
= zl3vni_lookup(vni
);
5931 /* process-if-down for l3-vni */
5932 if (IS_ZEBRA_DEBUG_VXLAN
)
5933 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
5936 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5938 /* process if-down for l2-vni */
5939 if (IS_ZEBRA_DEBUG_VXLAN
)
5940 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
5943 /* Locate hash entry; it is expected to exist. */
5944 zvni
= zvni_lookup(vni
);
5947 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5948 ifp
->name
, ifp
->ifindex
, vni
);
5952 assert(zvni
->vxlan_if
== ifp
);
5954 /* Delete this VNI from BGP. */
5955 zvni_send_del_to_client(zvni
->vni
);
5957 /* Free up all neighbors and MACs, if any. */
5958 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5959 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5961 /* Free up all remote VTEPs, if any. */
5962 zvni_vtep_del_all(zvni
, 1);
5968 * Handle VxLAN interface up - update BGP if required.
5970 int zebra_vxlan_if_up(struct interface
*ifp
)
5973 struct zebra_if
*zif
= NULL
;
5974 struct zebra_l2info_vxlan
*vxl
= NULL
;
5975 zebra_vni_t
*zvni
= NULL
;
5976 zebra_l3vni_t
*zl3vni
= NULL
;
5978 /* Check if EVPN is enabled. */
5979 if (!is_evpn_enabled())
5984 vxl
= &zif
->l2info
.vxl
;
5987 zl3vni
= zl3vni_lookup(vni
);
5990 if (IS_ZEBRA_DEBUG_VXLAN
)
5991 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp
->name
,
5994 /* we need to associate with SVI, if any, we can associate with
5995 * svi-if only after association with vxlan-intf is complete
5997 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5999 if (is_l3vni_oper_up(zl3vni
))
6000 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6002 /* Handle L2-VNI add */
6003 struct interface
*vlan_if
= NULL
;
6005 if (IS_ZEBRA_DEBUG_VXLAN
)
6006 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
6009 /* Locate hash entry; it is expected to exist. */
6010 zvni
= zvni_lookup(vni
);
6013 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6014 ifp
->name
, ifp
->ifindex
, vni
);
6018 assert(zvni
->vxlan_if
== ifp
);
6019 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6020 zif
->brslave_info
.br_if
);
6022 zvni
->vrf_id
= vlan_if
->vrf_id
;
6023 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6025 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6028 /* If part of a bridge, inform BGP about this VNI. */
6029 /* Also, read and populate local MACs and neighbors. */
6030 if (zif
->brslave_info
.br_if
) {
6031 zvni_send_add_to_client(zvni
);
6032 zvni_read_mac_neigh(zvni
, ifp
);
6040 * Handle VxLAN interface delete. Locate and remove entry in hash table
6041 * and update BGP, if required.
6043 int zebra_vxlan_if_del(struct interface
*ifp
)
6046 struct zebra_if
*zif
= NULL
;
6047 struct zebra_l2info_vxlan
*vxl
= NULL
;
6048 zebra_vni_t
*zvni
= NULL
;
6049 zebra_l3vni_t
*zl3vni
= NULL
;
6051 /* Check if EVPN is enabled. */
6052 if (!is_evpn_enabled())
6057 vxl
= &zif
->l2info
.vxl
;
6060 zl3vni
= zl3vni_lookup(vni
);
6063 if (IS_ZEBRA_DEBUG_VXLAN
)
6064 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
6067 /* process oper-down for l3-vni */
6068 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6070 /* remove the association with vxlan_if */
6071 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6072 zl3vni
->vxlan_if
= NULL
;
6075 /* process if-del for l2-vni*/
6076 if (IS_ZEBRA_DEBUG_VXLAN
)
6077 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
6080 /* Locate hash entry; it is expected to exist. */
6081 zvni
= zvni_lookup(vni
);
6084 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6085 ifp
->name
, ifp
->ifindex
, vni
);
6089 /* remove from l3-vni list */
6090 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6092 listnode_delete(zl3vni
->l2vnis
, zvni
);
6094 /* Delete VNI from BGP. */
6095 zvni_send_del_to_client(zvni
->vni
);
6097 /* Free up all neighbors and MAC, if any. */
6098 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6099 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6101 /* Free up all remote VTEPs, if any. */
6102 zvni_vtep_del_all(zvni
, 0);
6104 /* Delete the hash entry. */
6105 if (zvni_del(zvni
)) {
6106 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6107 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6115 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6117 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
6120 struct zebra_if
*zif
= NULL
;
6121 struct zebra_l2info_vxlan
*vxl
= NULL
;
6122 zebra_vni_t
*zvni
= NULL
;
6123 zebra_l3vni_t
*zl3vni
= NULL
;
6125 /* Check if EVPN is enabled. */
6126 if (!is_evpn_enabled())
6131 vxl
= &zif
->l2info
.vxl
;
6134 zl3vni
= zl3vni_lookup(vni
);
6137 if (IS_ZEBRA_DEBUG_VXLAN
)
6139 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6140 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6141 inet_ntoa(vxl
->vtep_ip
),
6142 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6144 /* Removed from bridge? Cleanup and return */
6145 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6146 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6147 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6151 /* access-vlan change - process oper down, associate with new
6152 * svi_if and then process oper up again
6154 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6155 if (if_is_operative(ifp
)) {
6156 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6157 zl3vni
->svi_if
= NULL
;
6158 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6159 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6160 if (is_l3vni_oper_up(zl3vni
))
6161 zebra_vxlan_process_l3vni_oper_up(
6167 * local-ip change - process oper down, associate with new
6168 * local-ip and then process oper up again
6170 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
6171 if (if_is_operative(ifp
)) {
6172 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6173 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6174 if (is_l3vni_oper_up(zl3vni
))
6175 zebra_vxlan_process_l3vni_oper_up(
6180 /* Update local tunnel IP. */
6181 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6183 /* if we have a valid new master, process l3-vni oper up */
6184 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6185 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
6186 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6190 /* Update VNI hash. */
6191 zvni
= zvni_lookup(vni
);
6194 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6195 ifp
->name
, ifp
->ifindex
, vni
);
6199 if (IS_ZEBRA_DEBUG_VXLAN
)
6201 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6202 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6203 inet_ntoa(vxl
->vtep_ip
),
6204 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6206 /* Removed from bridge? Cleanup and return */
6207 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6208 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6209 /* Delete from client, remove all remote VTEPs */
6210 /* Also, free up all MACs and neighbors. */
6211 zvni_send_del_to_client(zvni
->vni
);
6212 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6213 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6214 zvni_vtep_del_all(zvni
, 1);
6218 /* Handle other changes. */
6219 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6220 /* Remove all existing local neigh and MACs for this VNI
6221 * (including from BGP)
6223 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6224 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6227 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6228 zvni
->vxlan_if
= ifp
;
6230 /* Take further actions needed.
6231 * Note that if we are here, there is a change of interest.
6233 /* If down or not mapped to a bridge, we're done. */
6234 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6237 /* Inform BGP, if there is a change of interest. */
6239 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6240 zvni_send_add_to_client(zvni
);
6242 /* If there is a valid new master or a VLAN mapping change,
6243 * read and populate local MACs and neighbors.
6244 * Also, reinstall any remote MACs and neighbors
6245 * for this VNI (based on new VLAN).
6247 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6248 zvni_read_mac_neigh(zvni
, ifp
);
6249 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6250 struct mac_walk_ctx m_wctx
;
6251 struct neigh_walk_ctx n_wctx
;
6253 zvni_read_mac_neigh(zvni
, ifp
);
6255 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6257 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
,
6260 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6262 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6271 * Handle VxLAN interface add.
6273 int zebra_vxlan_if_add(struct interface
*ifp
)
6276 struct zebra_if
*zif
= NULL
;
6277 struct zebra_l2info_vxlan
*vxl
= NULL
;
6278 zebra_vni_t
*zvni
= NULL
;
6279 zebra_l3vni_t
*zl3vni
= NULL
;
6281 /* Check if EVPN is enabled. */
6282 if (!is_evpn_enabled())
6287 vxl
= &zif
->l2info
.vxl
;
6290 zl3vni
= zl3vni_lookup(vni
);
6293 /* process if-add for l3-vni*/
6294 if (IS_ZEBRA_DEBUG_VXLAN
)
6296 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6297 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6298 inet_ntoa(vxl
->vtep_ip
),
6299 zif
->brslave_info
.bridge_ifindex
);
6301 /* associate with vxlan_if */
6302 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6303 zl3vni
->vxlan_if
= ifp
;
6305 /* Associate with SVI, if any. We can associate with svi-if only
6306 * after association with vxlan_if is complete */
6307 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6309 if (is_l3vni_oper_up(zl3vni
))
6310 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6313 /* process if-add for l2-vni */
6314 struct interface
*vlan_if
= NULL
;
6316 /* Create or update VNI hash. */
6317 zvni
= zvni_lookup(vni
);
6319 zvni
= zvni_add(vni
);
6322 "Failed to add VNI hash, IF %s(%u) VNI %u",
6323 ifp
->name
, ifp
->ifindex
, vni
);
6328 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6329 zvni
->vxlan_if
= ifp
;
6330 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6331 zif
->brslave_info
.br_if
);
6333 zvni
->vrf_id
= vlan_if
->vrf_id
;
6334 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6336 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6339 if (IS_ZEBRA_DEBUG_VXLAN
)
6341 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6343 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
)
6345 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6346 inet_ntoa(vxl
->vtep_ip
),
6347 zif
->brslave_info
.bridge_ifindex
);
6349 /* If down or not mapped to a bridge, we're done. */
6350 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6354 zvni_send_add_to_client(zvni
);
6356 /* Read and populate local MACs and neighbors */
6357 zvni_read_mac_neigh(zvni
, ifp
);
6363 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
, vni_t vni
,
6364 char *err
, int err_str_sz
, int filter
,
6367 zebra_l3vni_t
*zl3vni
= NULL
;
6368 struct zebra_vrf
*zvrf_default
= NULL
;
6370 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6374 if (IS_ZEBRA_DEBUG_VXLAN
)
6375 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf
), vni
,
6376 add
? "ADD" : "DEL");
6380 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6382 /* check if the vni is already present under zvrf */
6384 snprintf(err
, err_str_sz
,
6385 "VNI is already configured under the vrf");
6389 /* check if this VNI is already present in the system */
6390 zl3vni
= zl3vni_lookup(vni
);
6392 snprintf(err
, err_str_sz
,
6393 "VNI is already configured as L3-VNI");
6397 /* add the L3-VNI to the global table */
6398 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6400 snprintf(err
, err_str_sz
, "Could not add L3-VNI");
6404 /* associate the vrf with vni */
6407 /* set the filter in l3vni to denote if we are using l3vni only
6411 SET_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
);
6413 /* associate with vxlan-intf;
6414 * we need to associate with the vxlan-intf first
6416 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6418 /* associate with corresponding SVI interface, we can associate
6419 * with svi-if only after vxlan interface association is
6422 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6424 /* formulate l2vni list */
6425 hash_iterate(zvrf_default
->vni_table
, zvni_add_to_l3vni_list
,
6428 if (is_l3vni_oper_up(zl3vni
))
6429 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6432 zl3vni
= zl3vni_lookup(vni
);
6434 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6438 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6440 /* delete and uninstall all rmacs */
6441 hash_iterate(zl3vni
->rmac_table
, zl3vni_del_rmac_hash_entry
,
6444 /* delete and uninstall all next-hops */
6445 hash_iterate(zl3vni
->nh_table
, zl3vni_del_nh_hash_entry
,
6451 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6456 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6458 zebra_l3vni_t
*zl3vni
= NULL
;
6461 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6465 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6466 if (is_l3vni_oper_up(zl3vni
))
6467 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6471 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6473 zebra_l3vni_t
*zl3vni
= NULL
;
6476 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6480 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6481 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6485 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6487 zebra_l3vni_t
*zl3vni
= NULL
;
6491 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6497 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6503 * Handle message from client to enable/disable advertisement of g/w macip
6506 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS
)
6511 zebra_vni_t
*zvni
= NULL
;
6512 struct interface
*ifp
= NULL
;
6513 struct zebra_if
*zif
= NULL
;
6514 struct zebra_l2info_vxlan zl2_info
;
6515 struct interface
*vlan_if
= NULL
;
6517 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6518 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6524 advertise
= stream_getc(s
);
6525 vni
= stream_get3(s
);
6527 zvni
= zvni_lookup(vni
);
6531 if (zvni
->advertise_subnet
== advertise
)
6534 if (IS_ZEBRA_DEBUG_VXLAN
)
6535 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
6536 advertise
? "enabled" : "disabled", vni
,
6537 zvni
->advertise_subnet
? "enabled" : "disabled");
6540 zvni
->advertise_subnet
= advertise
;
6542 ifp
= zvni
->vxlan_if
;
6548 /* If down or not mapped to a bridge, we're done. */
6549 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6552 zl2_info
= zif
->l2info
.vxl
;
6555 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
6559 if (zvni
->advertise_subnet
)
6560 zvni_advertise_subnet(zvni
, vlan_if
, 1);
6562 zvni_advertise_subnet(zvni
, vlan_if
, 0);
6566 * Handle message from client to enable/disable advertisement of g/w macip
6569 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS
)
6574 zebra_vni_t
*zvni
= NULL
;
6575 struct interface
*ifp
= NULL
;
6577 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6578 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6584 STREAM_GETC(s
, advertise
);
6585 STREAM_GET(&vni
, s
, 3);
6588 if (IS_ZEBRA_DEBUG_VXLAN
)
6589 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6590 advertise
? "enabled" : "disabled",
6591 advertise_gw_macip_enabled(NULL
)
6595 if (zvrf
->advertise_gw_macip
== advertise
)
6598 zvrf
->advertise_gw_macip
= advertise
;
6600 if (advertise_gw_macip_enabled(zvni
))
6601 hash_iterate(zvrf
->vni_table
,
6602 zvni_gw_macip_add_for_vni_hash
, NULL
);
6604 hash_iterate(zvrf
->vni_table
,
6605 zvni_gw_macip_del_for_vni_hash
, NULL
);
6608 struct zebra_if
*zif
= NULL
;
6609 struct zebra_l2info_vxlan zl2_info
;
6610 struct interface
*vlan_if
= NULL
;
6611 struct interface
*vrr_if
= NULL
;
6613 zvni
= zvni_lookup(vni
);
6617 if (IS_ZEBRA_DEBUG_VXLAN
)
6619 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6620 advertise
? "enabled" : "disabled", vni
,
6621 advertise_gw_macip_enabled(zvni
) ? "enabled"
6624 if (zvni
->advertise_gw_macip
== advertise
)
6627 zvni
->advertise_gw_macip
= advertise
;
6629 ifp
= zvni
->vxlan_if
;
6635 /* If down or not mapped to a bridge, we're done. */
6636 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6639 zl2_info
= zif
->l2info
.vxl
;
6641 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6642 zif
->brslave_info
.br_if
);
6646 if (advertise_gw_macip_enabled(zvni
)) {
6647 /* Add primary SVI MAC-IP */
6648 zvni_add_macip_for_intf(vlan_if
, zvni
);
6650 /* Add VRR MAC-IP - if any*/
6651 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6653 zvni_add_macip_for_intf(vrr_if
, zvni
);
6655 /* Del primary MAC-IP */
6656 zvni_del_macip_for_intf(vlan_if
, zvni
);
6658 /* Del VRR MAC-IP - if any*/
6659 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6661 zvni_del_macip_for_intf(vrr_if
, zvni
);
6671 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6672 * When enabled, the VNI hash table will be built and MAC FDB table read;
6673 * when disabled, the entries should be deleted and remote VTEPs and MACs
6674 * uninstalled from the kernel.
6676 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS
)
6678 struct stream
*s
= NULL
;
6680 struct zebra_ns
*zns
= NULL
;
6682 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6683 zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf
));
6688 STREAM_GETC(s
, advertise
);
6690 if (IS_ZEBRA_DEBUG_VXLAN
)
6691 zlog_debug("EVPN VNI Adv %s, currently %s",
6692 advertise
? "enabled" : "disabled",
6693 is_evpn_enabled() ? "enabled" : "disabled");
6695 if (zvrf
->advertise_all_vni
== advertise
)
6698 zvrf
->advertise_all_vni
= advertise
;
6699 if (is_evpn_enabled()) {
6700 /* Build VNI hash table and inform BGP. */
6701 zvni_build_hash_table();
6703 /* Add all SVI (L3 GW) MACs to BGP*/
6704 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6707 /* Read the MAC FDB */
6708 macfdb_read(zvrf
->zns
);
6710 /* Read neighbors */
6711 neigh_read(zvrf
->zns
);
6713 /* Cleanup VTEPs for all VNIs - uninstall from
6714 * kernel and free entries.
6716 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6718 /* cleanup all l3vnis */
6719 zns
= zebra_ns_lookup(NS_DEFAULT
);
6723 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
6731 * Allocate VNI hash table for this VRF and do other initialization.
6732 * NOTE: Currently supported only for default VRF.
6734 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6738 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6739 "Zebra VRF VNI Table");
6742 /* Cleanup VNI info, but don't free the table. */
6743 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
6747 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6750 /* Close all VNI handling */
6751 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6755 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6756 hash_free(zvrf
->vni_table
);
6759 /* init the l3vni table */
6760 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6762 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6763 "Zebra VRF L3 VNI table");
6766 /* free l3vni table */
6767 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6769 hash_free(zns
->l3vni_table
);
6772 /* get the l3vni svi ifindex */
6773 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6775 zebra_l3vni_t
*zl3vni
= NULL
;
6777 zl3vni
= zl3vni_from_vrf(vrf_id
);
6778 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6781 return zl3vni
->svi_if
->ifindex
;