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
,
64 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
65 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
66 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
68 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
70 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
72 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
73 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
74 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
75 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
76 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
78 static int zvni_macip_send_msg_to_client(vni_t vni
,
79 struct ethaddr
*macaddr
,
80 struct ipaddr
*ip
, u_char flags
,
82 static unsigned int neigh_hash_keymake(void *p
);
83 static int neigh_cmp(const void *p1
, const void *p2
);
84 static void *zvni_neigh_alloc(void *p
);
85 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
87 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
88 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
89 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
90 struct in_addr
*r_vtep_ip
);
91 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
92 int uninstall
, int upd_client
, u_int32_t flags
);
93 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
94 static int zvni_neigh_send_add_to_client(vni_t vni
,
96 struct ethaddr
*macaddr
, u_char flags
);
97 static int zvni_neigh_send_del_to_client(vni_t vni
,
99 struct ethaddr
*macaddr
, u_char flags
);
100 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
101 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
102 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
103 struct interface
*br_if
);
104 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
105 struct interface
*br_if
);
107 /* l3-vni next-hop neigh related APIs */
108 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
110 static void *zl3vni_nh_alloc(void *p
);
111 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
112 struct ipaddr
*vtep_ip
,
113 struct ethaddr
*rmac
);
114 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
115 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
116 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
118 /* l3-vni rmac related APIs */
119 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
120 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
121 struct ethaddr
*rmac
);
122 static void *zl3vni_rmac_alloc(void *p
);
123 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
124 struct ethaddr
*rmac
);
125 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
126 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
127 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
130 /* l3-vni related APIs*/
131 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
132 static void *zl3vni_alloc(void *p
);
133 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
134 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
135 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
136 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
137 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
138 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
139 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
141 static unsigned int mac_hash_keymake(void *p
);
142 static int mac_cmp(const void *p1
, const void *p2
);
143 static void *zvni_mac_alloc(void *p
);
144 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
145 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
146 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
147 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
148 struct in_addr
*r_vtep_ip
);
149 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
150 int uninstall
, int upd_client
, u_int32_t flags
);
151 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
152 static int zvni_mac_send_add_to_client(vni_t vni
,
153 struct ethaddr
*macaddr
, u_char flags
);
154 static int zvni_mac_send_del_to_client(vni_t vni
,
155 struct ethaddr
*macaddr
, u_char flags
);
156 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
157 struct interface
*br_if
, vlanid_t vid
);
158 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
159 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
160 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
162 static unsigned int vni_hash_keymake(void *p
);
163 static int vni_hash_cmp(const void *p1
, const void *p2
);
164 static void *zvni_alloc(void *p
);
165 static zebra_vni_t
*zvni_lookup(vni_t vni
);
166 static zebra_vni_t
*zvni_add(vni_t vni
);
167 static int zvni_del(zebra_vni_t
*zvni
);
168 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
169 static int zvni_send_del_to_client(vni_t vni
);
170 static void zvni_build_hash_table();
171 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
172 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
173 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
174 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
175 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
176 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
177 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
178 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
179 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
180 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
181 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
182 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
184 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
185 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
186 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
189 /* Private functions */
192 * Return number of valid MACs in a VNI's MAC hash table - all
193 * remote MACs and non-internal (auto) local MACs count.
195 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
198 u_int32_t num_macs
= 0;
200 struct hash_backet
*hb
;
203 hash
= zvni
->mac_table
;
206 for (i
= 0; i
< hash
->size
; i
++) {
207 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
208 mac
= (zebra_mac_t
*)hb
->data
;
209 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
210 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
218 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
220 struct zebra_vrf
*zvrf
;
222 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
223 if (zvrf
&& zvrf
->advertise_gw_macip
)
226 if (zvni
&& zvni
->advertise_gw_macip
)
233 * Helper function to determine maximum width of neighbor IP address for
234 * display - just because we're dealing with IPv6 addresses that can
237 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
240 char buf
[INET6_ADDRSTRLEN
];
241 struct neigh_walk_ctx
*wctx
= ctxt
;
244 n
= (zebra_neigh_t
*)backet
->data
;
248 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
249 if (width
> wctx
->addr_width
)
250 wctx
->addr_width
= width
;
254 * Print a specific neighbor entry.
256 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
259 char buf1
[ETHER_ADDR_STRLEN
];
260 char buf2
[INET6_ADDRSTRLEN
];
262 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
263 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
264 vty
= (struct vty
*)ctxt
;
266 vty_out(vty
, "IP: %s\n",
267 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
268 vty_out(vty
, " MAC: %s",
269 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
271 json_object_string_add(json
, "ip", buf2
);
272 json_object_string_add(json
, "mac", buf1
);
274 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
276 vty_out(vty
, " Remote VTEP: %s",
277 inet_ntoa(n
->r_vtep_ip
));
279 json_object_string_add(json
, "remoteVtep",
280 inet_ntoa(n
->r_vtep_ip
));
282 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
285 vty_out(vty
, " State: %s",
286 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
290 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
292 vty_out(vty
, " Default-gateway");
294 json_object_boolean_true_add(json
, "defaultGateway");
301 * Print neighbor hash entry - called for display of all neighbors.
303 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
306 json_object
*json_vni
= NULL
, *json_row
= NULL
;
308 char buf1
[ETHER_ADDR_STRLEN
];
309 char buf2
[INET6_ADDRSTRLEN
];
310 struct neigh_walk_ctx
*wctx
= ctxt
;
313 json_vni
= wctx
->json
;
314 n
= (zebra_neigh_t
*)backet
->data
;
319 json_row
= json_object_new_object();
321 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
322 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
323 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
324 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
325 if (json_vni
== NULL
) {
326 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
327 buf2
, "local", buf1
);
329 json_object_string_add(json_row
, "type", "local");
330 json_object_string_add(json_row
, "mac", buf1
);
334 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
335 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
336 if (json_vni
== NULL
) {
337 if (wctx
->count
== 0)
339 "%*s %-6s %-17s %-21s\n",
342 "MAC", "Remote VTEP");
343 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
344 -wctx
->addr_width
, buf2
,
346 inet_ntoa(n
->r_vtep_ip
));
348 json_object_string_add(json_row
, "type",
350 json_object_string_add(json_row
, "mac",
352 json_object_string_add(
353 json_row
, "remoteVtep",
354 inet_ntoa(n
->r_vtep_ip
));
359 if (json_vni
== NULL
) {
360 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
361 -wctx
->addr_width
, buf2
, "remote", buf1
,
362 inet_ntoa(n
->r_vtep_ip
));
364 json_object_string_add(json_row
, "type",
366 json_object_string_add(json_row
, "mac", buf1
);
367 json_object_string_add(json_row
, "remoteVtep",
368 inet_ntoa(n
->r_vtep_ip
));
375 json_object_object_add(json_vni
, buf2
, json_row
);
379 * Print neighbors for all VNI.
381 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
385 json_object
*json
= NULL
, *json_vni
= NULL
;
388 struct neigh_walk_ctx wctx
;
389 char vni_str
[VNI_STR_LEN
];
391 vty
= (struct vty
*)args
[0];
392 json
= (json_object
*)args
[1];
394 zvni
= (zebra_vni_t
*)backet
->data
;
397 vty_out(vty
, "{}\n");
400 num_neigh
= hashcount(zvni
->neigh_table
);
403 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
404 zvni
->vni
, num_neigh
);
406 json_vni
= json_object_new_object();
407 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
408 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
412 json_object_object_add(json
, vni_str
, json_vni
);
416 /* Since we have IPv6 addresses to deal with which can vary widely in
417 * size, we try to be a bit more elegant in display by first computing
420 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
423 wctx
.addr_width
= 15;
424 wctx
.json
= json_vni
;
425 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
428 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
429 "Type", "MAC", "Remote VTEP");
430 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
433 json_object_object_add(json
, vni_str
, json_vni
);
436 /* print a specific next hop for an l3vni */
437 static void zl3vni_print_nh(zebra_neigh_t
*n
,
441 char buf1
[ETHER_ADDR_STRLEN
];
442 char buf2
[INET6_ADDRSTRLEN
];
443 struct listnode
*node
= NULL
;
444 struct prefix
*p
= NULL
;
445 json_object
*json_hosts
= NULL
;
448 vty_out(vty
, "Ip: %s\n",
449 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
450 vty_out(vty
, " RMAC: %s\n",
451 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
452 vty_out(vty
, " Refcount: %d\n", listcount(n
->host_list
));
453 vty_out(vty
, " Prefixes:\n");
454 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
455 vty_out(vty
, " %s\n",
456 prefix2str(p
, buf2
, sizeof(buf2
)));
458 json_hosts
= json_object_new_array();
459 json_object_string_add(json
, "ip",
460 ipaddr2str(&(n
->ip
), buf2
,
462 json_object_string_add(json
, "routerMac",
463 prefix_mac2str(&n
->emac
, buf2
,
465 json_object_int_add(json
, "refCount", listcount(n
->host_list
));
466 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
467 json_object_array_add(json_hosts
,
468 json_object_new_string(
471 json_object_object_add(json
, "prefixList", json_hosts
);
475 /* Print a specific RMAC entry */
476 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
,
480 char buf1
[ETHER_ADDR_STRLEN
];
481 char buf2
[PREFIX_STRLEN
];
482 struct listnode
*node
= NULL
;
483 struct prefix
*p
= NULL
;
484 json_object
*json_hosts
= NULL
;
487 vty_out(vty
, "MAC: %s\n",
488 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
489 vty_out(vty
, " Remote VTEP: %s\n",
490 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
491 vty_out(vty
, " Refcount: %d\n", listcount(zrmac
->host_list
));
492 vty_out(vty
, " Prefixes:\n");
493 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
494 vty_out(vty
, " %s\n",
495 prefix2str(p
, buf2
, sizeof(buf2
)));
497 json_hosts
= json_object_new_array();
498 json_object_string_add(json
, "routerMac",
499 prefix_mac2str(&zrmac
->macaddr
,
502 json_object_string_add(json
, "vtepIp",
503 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
504 json_object_int_add(json
, "refCount",
505 listcount(zrmac
->host_list
));
506 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
507 json_object_array_add(json_hosts
,
508 json_object_new_string(
511 json_object_object_add(json
, "prefixList", json_hosts
);
516 * Print a specific MAC entry.
518 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
521 zebra_neigh_t
*n
= NULL
;
522 struct listnode
*node
= NULL
;
524 char buf2
[INET6_ADDRSTRLEN
];
526 vty
= (struct vty
*)ctxt
;
527 vty_out(vty
, "MAC: %s",
528 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
529 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
530 struct zebra_ns
*zns
;
531 struct interface
*ifp
;
534 ifindex
= mac
->fwd_info
.local
.ifindex
;
535 zns
= zebra_ns_lookup(NS_DEFAULT
);
536 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
537 if (!ifp
) // unexpected
539 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
540 if (mac
->fwd_info
.local
.vid
)
541 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
542 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
543 vty_out(vty
, " Remote VTEP: %s",
544 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
545 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
546 vty_out(vty
, " Auto Mac ");
549 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
550 vty_out(vty
, " Sticky Mac ");
552 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
553 vty_out(vty
, " Default-gateway Mac ");
556 /* print all the associated neigh */
557 vty_out(vty
, " Neighbors:\n");
558 if (!listcount(mac
->neigh_list
))
559 vty_out(vty
, " No Neighbors\n");
561 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
562 vty_out(vty
, " %s %s\n",
563 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
564 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
565 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
576 * Print MAC hash entry - called for display of all MACs.
578 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
581 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
584 struct mac_walk_ctx
*wctx
= ctxt
;
587 json_mac_hdr
= wctx
->json
;
588 mac
= (zebra_mac_t
*)backet
->data
;
592 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
595 json_mac
= json_object_new_object();
597 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
598 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
599 struct zebra_ns
*zns
;
601 struct interface
*ifp
;
604 zns
= zebra_ns_lookup(NS_DEFAULT
);
605 ifindex
= mac
->fwd_info
.local
.ifindex
;
606 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
607 if (!ifp
) // unexpected
609 vid
= mac
->fwd_info
.local
.vid
;
610 if (json_mac_hdr
== NULL
)
611 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
614 json_object_string_add(json_mac
, "type", "local");
615 json_object_string_add(json_mac
, "intf", ifp
->name
);
618 if (json_mac_hdr
== NULL
)
619 vty_out(vty
, " %-5u", vid
);
621 json_object_int_add(json_mac
, "vlan", vid
);
623 if (json_mac_hdr
== NULL
)
626 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
628 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
629 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
630 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
632 if (wctx
->count
== 0) {
633 if (json_mac_hdr
== NULL
) {
634 vty_out(vty
, "\nVNI %u\n\n",
637 "%-17s %-6s %-21s %-5s\n",
643 if (json_mac_hdr
== NULL
)
644 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
646 inet_ntoa(mac
->fwd_info
649 json_object_string_add(json_mac
, "type",
651 json_object_string_add(
652 json_mac
, "remoteVtep",
653 inet_ntoa(mac
->fwd_info
655 json_object_object_add(json_mac_hdr
,
661 if (json_mac_hdr
== NULL
)
662 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
664 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
666 json_object_string_add(json_mac
, "type",
668 json_object_string_add(
669 json_mac
, "remoteVtep",
670 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
671 json_object_object_add(json_mac_hdr
, buf1
,
680 * Print MACs for all VNI.
682 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
685 json_object
*json
= NULL
, *json_vni
= NULL
;
686 json_object
*json_mac
= NULL
;
689 struct mac_walk_ctx
*wctx
= ctxt
;
690 char vni_str
[VNI_STR_LEN
];
692 vty
= (struct vty
*)wctx
->vty
;
693 json
= (struct json_object
*)wctx
->json
;
695 zvni
= (zebra_vni_t
*)backet
->data
;
698 vty_out(vty
, "{}\n");
703 /*We are iterating over a new VNI, set the count to 0*/
706 num_macs
= num_valid_macs(zvni
);
711 json_vni
= json_object_new_object();
712 json_mac
= json_object_new_object();
713 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
716 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
718 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
719 zvni
->vni
, num_macs
);
720 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
721 "Intf/Remote VTEP", "VLAN");
723 json_object_int_add(json_vni
, "numMacs", num_macs
);
725 /* assign per-vni to wctx->json object to fill macs
726 * under the vni. Re-assign primary json object to fill
727 * next vni information.
729 wctx
->json
= json_mac
;
730 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
734 json_object_object_add(json_vni
, "macs", json_mac
);
735 json_object_object_add(json
, vni_str
, json_vni
);
739 static void zl3vni_print_nh_hash(struct hash_backet
*backet
,
742 struct nh_walk_ctx
*wctx
= NULL
;
743 struct vty
*vty
= NULL
;
744 struct json_object
*json_vni
= NULL
;
745 struct json_object
*json_nh
= NULL
;
746 zebra_neigh_t
*n
= NULL
;
747 char buf1
[ETHER_ADDR_STRLEN
];
748 char buf2
[INET6_ADDRSTRLEN
];
750 wctx
= (struct nh_walk_ctx
*)ctx
;
752 json_vni
= wctx
->json
;
754 json_nh
= json_object_new_object();
755 n
= (zebra_neigh_t
*)backet
->data
;
760 vty_out(vty
, "%-15s %-17s\n",
761 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
762 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
764 json_object_string_add(json_nh
, "nexthopIp",
765 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
766 json_object_string_add(json_nh
, "routerMac",
767 prefix_mac2str(&n
->emac
, buf1
,
769 json_object_object_add(json_vni
,
770 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
775 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
778 struct vty
*vty
= NULL
;
779 json_object
*json
= NULL
;
780 json_object
*json_vni
= NULL
;
781 zebra_l3vni_t
*zl3vni
= NULL
;
783 struct nh_walk_ctx wctx
;
784 char vni_str
[VNI_STR_LEN
];
786 vty
= (struct vty
*)args
[0];
787 json
= (struct json_object
*)args
[1];
789 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
792 vty_out(vty
, "{}\n");
796 num_nh
= hashcount(zl3vni
->nh_table
);
801 json_vni
= json_object_new_object();
802 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
806 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n",
807 zl3vni
->vni
, num_nh
);
808 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
810 json_object_int_add(json_vni
, "numNextHops", num_nh
);
812 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
814 wctx
.json
= json_vni
;
815 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
817 json_object_object_add(json
, vni_str
, json_vni
);
820 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
823 struct vty
*vty
= NULL
;
824 json_object
*json
= NULL
;
825 json_object
*json_vni
= NULL
;
826 zebra_l3vni_t
*zl3vni
= NULL
;
828 struct rmac_walk_ctx wctx
;
829 char vni_str
[VNI_STR_LEN
];
831 vty
= (struct vty
*)args
[0];
832 json
= (struct json_object
*)args
[1];
834 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
837 vty_out(vty
, "{}\n");
841 num_rmacs
= hashcount(zl3vni
->rmac_table
);
846 json_vni
= json_object_new_object();
847 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
851 vty_out(vty
, "\nVNI %u #RMACs %u\n\n",
852 zl3vni
->vni
, num_rmacs
);
853 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
855 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
857 /* assign per-vni to wctx->json object to fill macs
858 * under the vni. Re-assign primary json object to fill
859 * next vni information.
861 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
863 wctx
.json
= json_vni
;
864 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
866 json_object_object_add(json
, vni_str
, json_vni
);
869 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
,
872 zebra_mac_t
*zrmac
= NULL
;
873 struct rmac_walk_ctx
*wctx
= NULL
;
874 struct vty
*vty
= NULL
;
875 struct json_object
*json
= NULL
;
876 struct json_object
*json_rmac
= NULL
;
877 char buf
[ETHER_ADDR_STRLEN
];
879 wctx
= (struct rmac_walk_ctx
*)ctx
;
883 json_rmac
= json_object_new_object();
884 zrmac
= (zebra_mac_t
*)backet
->data
;
889 vty_out(vty
, "%-17s %-21s\n",
890 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
891 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
893 json_object_string_add(json_rmac
, "routerMac",
894 prefix_mac2str(&zrmac
->macaddr
, buf
,
896 json_object_string_add(json_rmac
, "vtepIp",
897 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
898 json_object_object_add(json
,
899 prefix_mac2str(&zrmac
->macaddr
, buf
,
905 /* print a specific L3 VNI entry */
906 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
908 char buf
[ETHER_ADDR_STRLEN
];
909 struct vty
*vty
= NULL
;
910 json_object
*json
= NULL
;
911 zebra_vni_t
*zvni
= NULL
;
912 json_object
*json_vni_list
= NULL
;
913 struct listnode
*node
= NULL
, *nnode
= NULL
;
919 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
920 vty_out(vty
, " Type: %s\n", "L3");
921 vty_out(vty
, " Tenant VRF: %s\n",
922 zl3vni_vrf_name(zl3vni
));
923 vty_out(vty
, " Local Vtep Ip: %s\n",
924 inet_ntoa(zl3vni
->local_vtep_ip
));
925 vty_out(vty
, " Vxlan-Intf: %s\n",
926 zl3vni_vxlan_if_name(zl3vni
));
927 vty_out(vty
, " SVI-If: %s\n",
928 zl3vni_svi_if_name(zl3vni
));
929 vty_out(vty
, " State: %s\n",
930 zl3vni_state2str(zl3vni
));
931 vty_out(vty
, " Router MAC: %s\n",
932 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
933 vty_out(vty
, " L2 VNIs: ");
934 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
935 vty_out(vty
, "%u ", zvni
->vni
);
938 json_vni_list
= json_object_new_array();
939 json_object_int_add(json
, "vni", zl3vni
->vni
);
940 json_object_string_add(json
, "type", "L3");
941 json_object_string_add(json
, "localVtepIp",
942 inet_ntoa(zl3vni
->local_vtep_ip
));
943 json_object_string_add(json
, "vxlanIntf",
944 zl3vni_vxlan_if_name(zl3vni
));
945 json_object_string_add(json
, "sviIntf",
946 zl3vni_svi_if_name(zl3vni
));
947 json_object_string_add(json
, "state",
948 zl3vni_state2str(zl3vni
));
949 json_object_string_add(json
, "vrf",
950 zl3vni_vrf_name(zl3vni
));
951 json_object_string_add(json
, "routerMac",
952 zl3vni_rmac2str(zl3vni
, buf
,
954 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
955 json_object_array_add(json_vni_list
,
956 json_object_new_int(zvni
->vni
));
958 json_object_object_add(json
, "l2Vnis", json_vni_list
);
963 * Print a specific VNI entry.
965 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
971 json_object
*json
= NULL
;
972 json_object
*json_vtep_list
= NULL
;
973 json_object
*json_ip_str
= NULL
;
979 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
980 vty_out(vty
, " Type: %s\n", "L2");
981 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
983 json_object_int_add(json
, "vni", zvni
->vni
);
984 json_object_string_add(json
, "type", "L2");
985 json_object_string_add(json
, "vrf",
986 vrf_id_to_name(zvni
->vrf_id
));
989 if (!zvni
->vxlan_if
) { // unexpected
991 vty_out(vty
, " VxLAN interface: unknown\n");
994 num_macs
= num_valid_macs(zvni
);
995 num_neigh
= hashcount(zvni
->neigh_table
);
997 vty_out(vty
, " VxLAN interface: %s\n",
998 zvni
->vxlan_if
->name
);
999 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
1000 vty_out(vty
," Local VTEP IP: %s\n",
1001 inet_ntoa(zvni
->local_vtep_ip
));
1003 json_object_string_add(json
, "vxlanInterface",
1004 zvni
->vxlan_if
->name
);
1005 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
1006 json_object_string_add(json
, "vtepIp",
1007 inet_ntoa(zvni
->local_vtep_ip
));
1008 json_object_string_add(json
, "advertiseGatewayMacip",
1009 zvni
->advertise_gw_macip
? "Yes" : "No");
1010 json_object_int_add(json
, "numMacs", num_macs
);
1011 json_object_int_add(json
, "numArpNd", num_neigh
);
1015 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1018 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1020 json_vtep_list
= json_object_new_array();
1021 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1023 vty_out(vty
, " %s\n",
1024 inet_ntoa(zvtep
->vtep_ip
));
1026 json_ip_str
= json_object_new_string(
1027 inet_ntoa(zvtep
->vtep_ip
));
1028 json_object_array_add(json_vtep_list
,
1033 json_object_object_add(json
, "numRemoteVteps",
1038 " Number of MACs (local and remote) known for this VNI: %u\n",
1041 " Number of ARPs (IPv4 and IPv6, local and remote) "
1042 "known for this VNI: %u\n",
1044 vty_out(vty
, " Advertise-gw-macip: %s\n",
1045 zvni
->advertise_gw_macip
? "Yes" : "No");
1049 /* print a L3 VNI hash entry */
1050 static void zl3vni_print_hash(struct hash_backet
*backet
,
1053 struct vty
*vty
= NULL
;
1054 json_object
*json
= NULL
;
1055 json_object
*json_vni
= NULL
;
1056 zebra_l3vni_t
*zl3vni
= NULL
;
1058 vty
= (struct vty
*)ctx
[0];
1059 json
= (json_object
*)ctx
[1];
1061 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1067 "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1069 zl3vni_vxlan_if_name(zl3vni
),
1070 hashcount(zl3vni
->rmac_table
),
1071 hashcount(zl3vni
->nh_table
),
1073 zl3vni_vrf_name(zl3vni
));
1075 char vni_str
[VNI_STR_LEN
];
1077 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1078 json_vni
= json_object_new_object();
1079 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1080 json_object_string_add(json_vni
, "vxlanIf",
1081 zl3vni_vxlan_if_name(zl3vni
));
1082 json_object_int_add(json_vni
, "numMacs",
1083 hashcount(zl3vni
->rmac_table
));
1084 json_object_int_add(json_vni
, "numArpNd",
1085 hashcount(zl3vni
->nh_table
));
1086 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1087 json_object_string_add(json_vni
, "type", "L3");
1088 json_object_string_add(json_vni
, "tenantVrf",
1089 zl3vni_vrf_name(zl3vni
));
1090 json_object_object_add(json
, vni_str
, json_vni
);
1096 * Print a VNI hash entry - called for display of all VNIs.
1098 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1102 zebra_vtep_t
*zvtep
;
1103 u_int32_t num_vteps
= 0;
1104 u_int32_t num_macs
= 0;
1105 u_int32_t num_neigh
= 0;
1106 json_object
*json
= NULL
;
1107 json_object
*json_vni
= NULL
;
1108 json_object
*json_ip_str
= NULL
;
1109 json_object
*json_vtep_list
= NULL
;
1114 zvni
= (zebra_vni_t
*)backet
->data
;
1118 zvtep
= zvni
->vteps
;
1121 zvtep
= zvtep
->next
;
1124 num_macs
= num_valid_macs(zvni
);
1125 num_neigh
= hashcount(zvni
->neigh_table
);
1128 "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1130 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1131 num_macs
, num_neigh
, num_vteps
,
1132 vrf_id_to_name(zvni
->vrf_id
));
1134 char vni_str
[VNI_STR_LEN
];
1135 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1136 json_vni
= json_object_new_object();
1137 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1138 json_object_string_add(json_vni
, "type", "L2");
1139 json_object_string_add(json_vni
, "vxlanIf",
1140 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1142 json_object_int_add(json_vni
, "numMacs", num_macs
);
1143 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1144 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1145 json_object_string_add(json_vni
, "tenantVrf",
1146 vrf_id_to_name(zvni
->vrf_id
));
1148 json_vtep_list
= json_object_new_array();
1149 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1150 json_ip_str
= json_object_new_string(
1151 inet_ntoa(zvtep
->vtep_ip
));
1152 json_object_array_add(json_vtep_list
,
1155 json_object_object_add(json_vni
, "remoteVteps",
1158 json_object_object_add(json
, vni_str
, json_vni
);
1163 * Inform BGP about local MACIP.
1165 static int zvni_macip_send_msg_to_client(vni_t vni
,
1166 struct ethaddr
*macaddr
,
1167 struct ipaddr
*ip
, u_char flags
,
1170 char buf
[ETHER_ADDR_STRLEN
];
1171 char buf2
[INET6_ADDRSTRLEN
];
1173 struct zserv
*client
= NULL
;
1174 struct stream
*s
= NULL
;
1176 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1177 /* BGP may not be running. */
1184 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1185 stream_putl(s
, vni
);
1186 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1189 if (IS_IPADDR_V4(ip
))
1190 ipa_len
= IPV4_MAX_BYTELEN
;
1191 else if (IS_IPADDR_V6(ip
))
1192 ipa_len
= IPV6_MAX_BYTELEN
;
1194 stream_putl(s
, ipa_len
); /* IP address length */
1196 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1198 stream_putl(s
, 0); /* Just MAC. */
1200 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1203 /* Write packet size. */
1204 stream_putw_at(s
, 0, stream_get_endp(s
));
1206 if (IS_ZEBRA_DEBUG_VXLAN
)
1208 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1209 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
1210 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1211 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1212 zebra_route_string(client
->proto
));
1214 if (cmd
== ZEBRA_MACIP_ADD
)
1215 client
->macipadd_cnt
++;
1217 client
->macipdel_cnt
++;
1219 return zebra_server_send_message(client
);
1223 * Make hash key for neighbors.
1225 static unsigned int neigh_hash_keymake(void *p
)
1227 zebra_neigh_t
*n
= p
;
1228 struct ipaddr
*ip
= &n
->ip
;
1230 if (IS_IPADDR_V4(ip
))
1231 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1233 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1234 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1238 * Compare two neighbor hash structures.
1240 static int neigh_cmp(const void *p1
, const void *p2
)
1242 const zebra_neigh_t
*n1
= p1
;
1243 const zebra_neigh_t
*n2
= p2
;
1245 if (n1
== NULL
&& n2
== NULL
)
1248 if (n1
== NULL
|| n2
== NULL
)
1251 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1255 * Callback to allocate neighbor hash entry.
1257 static void *zvni_neigh_alloc(void *p
)
1259 const zebra_neigh_t
*tmp_n
= p
;
1262 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1269 * Add neighbor entry.
1271 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1272 struct ethaddr
*mac
)
1274 zebra_neigh_t tmp_n
;
1275 zebra_neigh_t
*n
= NULL
;
1276 zebra_mac_t
*zmac
= NULL
;
1278 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1279 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1280 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1283 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1284 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1286 /* Associate the neigh to mac */
1287 zmac
= zvni_mac_lookup(zvni
, mac
);
1289 listnode_add_sort(zmac
->neigh_list
, n
);
1295 * Delete neighbor entry.
1297 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1299 zebra_neigh_t
*tmp_n
;
1300 zebra_mac_t
*zmac
= NULL
;
1302 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1304 listnode_delete(zmac
->neigh_list
, n
);
1306 /* Free the VNI hash entry and allocated memory. */
1307 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1309 XFREE(MTYPE_NEIGH
, tmp_n
);
1315 * Free neighbor hash entry (callback)
1317 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1319 struct neigh_walk_ctx
*wctx
= arg
;
1320 zebra_neigh_t
*n
= backet
->data
;
1322 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1323 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1324 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1325 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1326 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1327 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1328 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1329 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1332 if (wctx
->uninstall
)
1333 zvni_neigh_uninstall(wctx
->zvni
, n
);
1335 return zvni_neigh_del(wctx
->zvni
, n
);
1342 * Delete all neighbor entries from specific VTEP for a particular VNI.
1344 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1345 struct in_addr
*r_vtep_ip
)
1347 struct neigh_walk_ctx wctx
;
1349 if (!zvni
->neigh_table
)
1352 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1354 wctx
.uninstall
= uninstall
;
1355 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1356 wctx
.r_vtep_ip
= *r_vtep_ip
;
1358 hash_iterate(zvni
->neigh_table
,
1359 (void (*)(struct hash_backet
*,
1360 void *))zvni_neigh_del_hash_entry
,
1365 * Delete all neighbor entries for this VNI.
1367 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
1368 int uninstall
, int upd_client
, u_int32_t flags
)
1370 struct neigh_walk_ctx wctx
;
1372 if (!zvni
->neigh_table
)
1375 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1377 wctx
.uninstall
= uninstall
;
1378 wctx
.upd_client
= upd_client
;
1381 hash_iterate(zvni
->neigh_table
,
1382 (void (*)(struct hash_backet
*,
1383 void *))zvni_neigh_del_hash_entry
,
1388 * Look up neighbor hash entry.
1390 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1395 memset(&tmp
, 0, sizeof(tmp
));
1396 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1397 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1402 /* Process all neigh associated to a mac upon local mac add event */
1403 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1406 zebra_neigh_t
*n
= NULL
;
1407 struct listnode
*node
= NULL
;
1408 char buf
[ETHER_ADDR_STRLEN
];
1409 char buf2
[INET6_ADDRSTRLEN
];
1411 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1412 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1413 /* MAC is learnt locally, program all inactive neigh
1414 * pointing to this mac */
1415 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1416 if (IS_ZEBRA_DEBUG_VXLAN
)
1418 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1419 ipaddr2str(&n
->ip
, buf2
,
1421 prefix_mac2str(&n
->emac
, buf
,
1425 ZEBRA_NEIGH_SET_ACTIVE(n
);
1426 zvni_neigh_send_add_to_client(
1427 zvni
->vni
, &n
->ip
, &n
->emac
, n
->flags
);
1429 if (IS_ZEBRA_DEBUG_VXLAN
)
1431 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1432 ipaddr2str(&n
->ip
, buf2
,
1434 prefix_mac2str(&n
->emac
, buf
,
1438 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1439 /* TODO: assume the neigh has moved too ?? */
1444 /* Process all neigh associated to a mac upon local mac del event */
1445 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1448 zebra_neigh_t
*n
= NULL
;
1449 struct listnode
*node
= NULL
;
1450 char buf
[ETHER_ADDR_STRLEN
];
1451 char buf2
[INET6_ADDRSTRLEN
];
1453 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1454 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1455 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1456 if (IS_ZEBRA_DEBUG_VXLAN
)
1458 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1459 ipaddr2str(&n
->ip
, buf2
,
1461 prefix_mac2str(&n
->emac
, buf
,
1465 ZEBRA_NEIGH_SET_INACTIVE(n
);
1466 zvni_neigh_send_del_to_client(
1467 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1469 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1470 if (IS_ZEBRA_DEBUG_VXLAN
)
1472 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1473 prefix_mac2str(&n
->emac
, buf
,
1476 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1481 /* process all neigh associated to a mac entry upon remote mac add */
1482 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1485 zebra_neigh_t
*n
= NULL
;
1486 struct listnode
*node
= NULL
;
1487 char buf
[ETHER_ADDR_STRLEN
];
1488 char buf2
[INET6_ADDRSTRLEN
];
1490 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1491 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1492 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1493 if (IS_ZEBRA_DEBUG_VXLAN
)
1495 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1496 ipaddr2str(&n
->ip
, buf2
,
1498 prefix_mac2str(&n
->emac
, buf
,
1502 ZEBRA_NEIGH_SET_INACTIVE(n
);
1503 zvni_neigh_send_del_to_client(
1504 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1510 /* process all neigh associated to mac entry upon remote mac del */
1511 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1514 zebra_neigh_t
*n
= NULL
;
1515 struct listnode
*node
= NULL
;
1516 char buf
[ETHER_ADDR_STRLEN
];
1517 char buf2
[INET6_ADDRSTRLEN
];
1519 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1520 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1521 if (IS_ZEBRA_DEBUG_VXLAN
)
1523 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1524 prefix_mac2str(&n
->emac
, buf
,
1527 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1533 * Inform BGP about local neighbor addition.
1535 static int zvni_neigh_send_add_to_client(vni_t vni
,
1537 struct ethaddr
*macaddr
,
1542 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1543 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1545 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1550 * Inform BGP about local neighbor deletion.
1552 static int zvni_neigh_send_del_to_client(vni_t vni
,
1554 struct ethaddr
*macaddr
, u_char flags
)
1556 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1561 * Install remote neighbor into the kernel.
1563 static int zvni_neigh_install(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 zif
= zvni
->vxlan_if
->info
;
1575 vxl
= &zif
->l2info
.vxl
;
1577 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1581 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1585 * Uninstall remote neighbor from the kernel.
1587 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1589 struct zebra_if
*zif
;
1590 struct zebra_l2info_vxlan
*vxl
;
1591 struct interface
*vlan_if
;
1593 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1596 if (!zvni
->vxlan_if
) {
1597 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1602 zif
= zvni
->vxlan_if
->info
;
1605 vxl
= &zif
->l2info
.vxl
;
1606 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1610 return kernel_del_neigh(vlan_if
, &n
->ip
);
1614 * Install neighbor hash entry - called upon access VLAN change.
1616 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1619 struct neigh_walk_ctx
*wctx
= ctxt
;
1621 n
= (zebra_neigh_t
*)backet
->data
;
1625 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1626 zvni_neigh_install(wctx
->zvni
, n
);
1629 /* Get the VRR interface for SVI if any */
1630 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1632 struct zebra_vrf
*zvrf
= NULL
;
1633 struct interface
*tmp_if
= NULL
;
1634 struct zebra_if
*zif
= NULL
;
1636 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1639 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1644 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1647 if (zif
->link
== ifp
)
1654 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1656 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1657 struct connected
*c
= NULL
;
1658 struct ethaddr macaddr
;
1660 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1662 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1665 memset(&ip
, 0, sizeof(struct ipaddr
));
1666 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1669 if (c
->address
->family
== AF_INET
) {
1670 ip
.ipa_type
= IPADDR_V4
;
1671 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1672 sizeof(struct in_addr
));
1673 } else if (c
->address
->family
== AF_INET6
) {
1674 ip
.ipa_type
= IPADDR_V6
;
1675 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1676 sizeof(struct in6_addr
));
1681 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1687 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1689 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1690 struct connected
*c
= NULL
;
1691 struct ethaddr macaddr
;
1693 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1695 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1698 memset(&ip
, 0, sizeof(struct ipaddr
));
1699 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1702 if (c
->address
->family
== AF_INET
) {
1703 ip
.ipa_type
= IPADDR_V4
;
1704 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1705 sizeof(struct in_addr
));
1706 } else if (c
->address
->family
== AF_INET6
) {
1707 ip
.ipa_type
= IPADDR_V6
;
1708 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1709 sizeof(struct in6_addr
));
1714 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1720 static int zvni_advertise_subnet(zebra_vni_t
*zvni
,
1721 struct interface
*ifp
,
1724 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1725 struct connected
*c
= NULL
;
1726 struct ethaddr macaddr
;
1728 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1730 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1733 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1735 /* skip link local address */
1736 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1741 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1742 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1744 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1745 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1751 * zvni_gw_macip_add_to_client
1753 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1754 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1756 char buf
[ETHER_ADDR_STRLEN
];
1757 char buf2
[INET6_ADDRSTRLEN
];
1758 zebra_neigh_t
*n
= NULL
;
1759 zebra_mac_t
*mac
= NULL
;
1760 struct zebra_if
*zif
= NULL
;
1761 struct zebra_l2info_vxlan
*vxl
= NULL
;
1763 zif
= zvni
->vxlan_if
->info
;
1767 vxl
= &zif
->l2info
.vxl
;
1769 mac
= zvni_mac_lookup(zvni
, macaddr
);
1771 mac
= zvni_mac_add(zvni
, macaddr
);
1773 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1774 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1775 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1780 /* Set "local" forwarding info. */
1781 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1782 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1783 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1784 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1785 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1786 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1788 n
= zvni_neigh_lookup(zvni
, ip
);
1790 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1793 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1794 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1795 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1796 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1801 /* Set "local" forwarding info. */
1802 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1803 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1804 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1805 n
->ifindex
= ifp
->ifindex
;
1807 /* Only advertise in BGP if the knob is enabled */
1808 if (!advertise_gw_macip_enabled(zvni
))
1811 if (IS_ZEBRA_DEBUG_VXLAN
)
1813 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1814 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1815 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1816 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1818 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1825 * zvni_gw_macip_del_from_client
1827 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1830 char buf1
[ETHER_ADDR_STRLEN
];
1831 char buf2
[INET6_ADDRSTRLEN
];
1832 zebra_neigh_t
*n
= NULL
;
1833 zebra_mac_t
*mac
= NULL
;
1835 /* If the neigh entry is not present nothing to do*/
1836 n
= zvni_neigh_lookup(zvni
, ip
);
1840 /* mac entry should be present */
1841 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1843 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1844 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1845 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1849 /* If the entry is not local nothing to do*/
1850 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1853 /* only need to delete the entry from bgp if we sent it before */
1854 if (advertise_gw_macip_enabled(zvni
)) {
1855 if (IS_ZEBRA_DEBUG_VXLAN
)
1856 zlog_debug("%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1857 ifp
->vrf_id
, ifp
->name
,
1858 ifp
->ifindex
, zvni
->vni
,
1859 prefix_mac2str(&(n
->emac
),
1862 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1864 /* Remove neighbor from BGP. */
1865 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1866 ZEBRA_MACIP_TYPE_GW
);
1869 /* Delete this neighbor entry. */
1870 zvni_neigh_del(zvni
, n
);
1872 /* see if the mac needs to be deleted as well*/
1874 zvni_deref_ip2mac(zvni
, mac
, 0);
1879 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1882 zebra_vni_t
*zvni
= NULL
;
1883 struct zebra_if
*zif
= NULL
;
1884 struct zebra_l2info_vxlan zl2_info
;
1885 struct interface
*vlan_if
= NULL
;
1886 struct interface
*vrr_if
= NULL
;
1887 struct interface
*ifp
;
1889 /* Add primary SVI MAC*/
1890 zvni
= (zebra_vni_t
*)backet
->data
;
1894 ifp
= zvni
->vxlan_if
;
1899 /* If down or not mapped to a bridge, we're done. */
1900 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1903 zl2_info
= zif
->l2info
.vxl
;
1905 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1909 /* Del primary MAC-IP */
1910 zvni_del_macip_for_intf(vlan_if
, zvni
);
1912 /* Del VRR MAC-IP - if any*/
1913 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1915 zvni_del_macip_for_intf(vrr_if
, zvni
);
1920 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1923 zebra_vni_t
*zvni
= NULL
;
1924 struct zebra_if
*zif
= NULL
;
1925 struct zebra_l2info_vxlan zl2_info
;
1926 struct interface
*vlan_if
= NULL
;
1927 struct interface
*vrr_if
= NULL
;
1928 struct interface
*ifp
= NULL
;
1930 zvni
= (zebra_vni_t
*)backet
->data
;
1934 ifp
= zvni
->vxlan_if
;
1939 /* If down or not mapped to a bridge, we're done. */
1940 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1942 zl2_info
= zif
->l2info
.vxl
;
1944 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1945 zif
->brslave_info
.br_if
);
1949 /* Add primary SVI MAC-IP */
1950 zvni_add_macip_for_intf(vlan_if
, zvni
);
1952 /* Add VRR MAC-IP - if any*/
1953 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1955 zvni_add_macip_for_intf(vrr_if
, zvni
);
1961 * Make hash key for MAC.
1963 static unsigned int mac_hash_keymake(void *p
)
1965 zebra_mac_t
*pmac
= p
;
1966 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1968 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1972 * Compare two MAC addresses.
1974 static int mac_cmp(const void *p1
, const void *p2
)
1976 const zebra_mac_t
*pmac1
= p1
;
1977 const zebra_mac_t
*pmac2
= p2
;
1979 if (pmac1
== NULL
&& pmac2
== NULL
)
1982 if (pmac1
== NULL
|| pmac2
== NULL
)
1985 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1991 * Callback to allocate MAC hash entry.
1993 static void *zvni_mac_alloc(void *p
)
1995 const zebra_mac_t
*tmp_mac
= p
;
1998 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2001 return ((void *)mac
);
2007 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
2009 zebra_mac_t tmp_mac
;
2010 zebra_mac_t
*mac
= NULL
;
2012 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
2013 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
2014 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
2017 mac
->neigh_list
= list_new();
2018 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
2026 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2028 zebra_mac_t
*tmp_mac
;
2030 list_delete_and_null(&mac
->neigh_list
);
2032 /* Free the VNI hash entry and allocated memory. */
2033 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2035 XFREE(MTYPE_MAC
, tmp_mac
);
2041 * Free MAC hash entry (callback)
2043 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2045 struct mac_walk_ctx
*wctx
= arg
;
2046 zebra_mac_t
*mac
= backet
->data
;
2048 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2049 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2050 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2051 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2052 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2053 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2054 &wctx
->r_vtep_ip
))) {
2055 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2056 zvni_mac_send_del_to_client(
2057 wctx
->zvni
->vni
, &mac
->macaddr
,
2061 if (wctx
->uninstall
)
2062 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2064 return zvni_mac_del(wctx
->zvni
, mac
);
2071 * Delete all MAC entries from specific VTEP for a particular VNI.
2073 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2074 struct in_addr
*r_vtep_ip
)
2076 struct mac_walk_ctx wctx
;
2078 if (!zvni
->mac_table
)
2081 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2083 wctx
.uninstall
= uninstall
;
2084 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2085 wctx
.r_vtep_ip
= *r_vtep_ip
;
2087 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2088 void *))zvni_mac_del_hash_entry
,
2093 * Delete all MAC entries for this VNI.
2095 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
2096 int uninstall
, int upd_client
, u_int32_t flags
)
2098 struct mac_walk_ctx wctx
;
2100 if (!zvni
->mac_table
)
2103 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2105 wctx
.uninstall
= uninstall
;
2106 wctx
.upd_client
= upd_client
;
2109 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2110 void *))zvni_mac_del_hash_entry
,
2115 * Look up MAC hash entry.
2117 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2122 memset(&tmp
, 0, sizeof(tmp
));
2123 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2124 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2130 * Inform BGP about local MAC addition.
2132 static int zvni_mac_send_add_to_client(vni_t vni
,
2133 struct ethaddr
*macaddr
,
2138 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2139 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2140 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2141 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2143 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2148 * Inform BGP about local MAC deletion.
2150 static int zvni_mac_send_del_to_client(vni_t vni
,
2151 struct ethaddr
*macaddr
,
2156 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2157 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2158 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2159 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2161 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2166 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2167 * notifications, to see if they are of interest.
2169 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2170 struct interface
*br_if
, vlanid_t vid
)
2172 struct zebra_ns
*zns
;
2173 struct route_node
*rn
;
2174 struct interface
*tmp_if
= NULL
;
2175 struct zebra_if
*zif
;
2176 struct zebra_l2info_bridge
*br
;
2177 struct zebra_l2info_vxlan
*vxl
= NULL
;
2178 u_char bridge_vlan_aware
;
2182 /* Determine if bridge is VLAN-aware or not */
2185 br
= &zif
->l2info
.br
;
2186 bridge_vlan_aware
= br
->vlan_aware
;
2188 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2189 /* TODO: Optimize with a hash. */
2190 zns
= zebra_ns_lookup(NS_DEFAULT
);
2191 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2192 tmp_if
= (struct interface
*)rn
->info
;
2196 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2198 if (!if_is_operative(tmp_if
))
2200 vxl
= &zif
->l2info
.vxl
;
2202 if (zif
->brslave_info
.br_if
!= br_if
)
2205 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2214 zvni
= zvni_lookup(vxl
->vni
);
2219 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2220 * neighbor notifications, to see if they are of interest.
2222 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2223 struct interface
*br_if
)
2225 struct zebra_ns
*zns
;
2226 struct route_node
*rn
;
2227 struct interface
*tmp_if
= NULL
;
2228 struct zebra_if
*zif
;
2229 struct zebra_l2info_bridge
*br
;
2230 struct zebra_l2info_vxlan
*vxl
= NULL
;
2231 u_char bridge_vlan_aware
;
2239 /* Make sure the linked interface is a bridge. */
2240 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2243 /* Determine if bridge is VLAN-aware or not */
2246 br
= &zif
->l2info
.br
;
2247 bridge_vlan_aware
= br
->vlan_aware
;
2248 if (bridge_vlan_aware
) {
2249 struct zebra_l2info_vlan
*vl
;
2251 if (!IS_ZEBRA_IF_VLAN(ifp
))
2256 vl
= &zif
->l2info
.vl
;
2260 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2261 /* TODO: Optimize with a hash. */
2262 zns
= zebra_ns_lookup(NS_DEFAULT
);
2263 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2264 tmp_if
= (struct interface
*)rn
->info
;
2268 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2270 if (!if_is_operative(tmp_if
))
2272 vxl
= &zif
->l2info
.vxl
;
2274 if (zif
->brslave_info
.br_if
!= br_if
)
2277 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2286 zvni
= zvni_lookup(vxl
->vni
);
2290 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2292 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2293 * linked to the bridge
2294 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2297 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2299 struct zebra_ns
*zns
;
2300 struct route_node
*rn
;
2301 struct interface
*tmp_if
= NULL
;
2302 struct zebra_if
*zif
;
2303 struct zebra_l2info_bridge
*br
;
2304 struct zebra_l2info_vlan
*vl
;
2305 u_char bridge_vlan_aware
;
2308 /* Defensive check, caller expected to invoke only with valid bridge. */
2312 /* Determine if bridge is VLAN-aware or not */
2315 br
= &zif
->l2info
.br
;
2316 bridge_vlan_aware
= br
->vlan_aware
;
2318 /* Check oper status of the SVI. */
2319 if (!bridge_vlan_aware
)
2320 return if_is_operative(br_if
) ? br_if
: NULL
;
2322 /* Identify corresponding VLAN interface. */
2323 /* TODO: Optimize with a hash. */
2324 zns
= zebra_ns_lookup(NS_DEFAULT
);
2325 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2326 tmp_if
= (struct interface
*)rn
->info
;
2327 /* Check oper status of the SVI. */
2328 if (!tmp_if
|| !if_is_operative(tmp_if
))
2331 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2332 || zif
->link
!= br_if
)
2334 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2336 if (vl
->vid
== vid
) {
2342 return found
? tmp_if
: NULL
;
2346 * Install remote MAC into the kernel.
2348 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2350 struct zebra_if
*zif
;
2351 struct zebra_l2info_vxlan
*vxl
;
2354 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2357 zif
= zvni
->vxlan_if
->info
;
2360 vxl
= &zif
->l2info
.vxl
;
2362 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2364 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2365 mac
->fwd_info
.r_vtep_ip
, sticky
);
2369 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2370 * moves to remote, we have to uninstall any existing local entry first.
2372 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2374 struct zebra_if
*zif
;
2375 struct zebra_l2info_vxlan
*vxl
;
2376 struct in_addr vtep_ip
= {.s_addr
= 0};
2377 struct zebra_ns
*zns
;
2378 struct interface
*ifp
;
2380 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2383 if (!zvni
->vxlan_if
) {
2384 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2389 zif
= zvni
->vxlan_if
->info
;
2392 vxl
= &zif
->l2info
.vxl
;
2395 zns
= zebra_ns_lookup(NS_DEFAULT
);
2396 ifp
= if_lookup_by_index_per_ns(zns
,
2397 mac
->fwd_info
.local
.ifindex
);
2398 if (!ifp
) // unexpected
2401 ifp
= zvni
->vxlan_if
;
2402 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2405 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2410 * Install MAC hash entry - called upon access VLAN change.
2412 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2415 struct mac_walk_ctx
*wctx
= ctxt
;
2417 mac
= (zebra_mac_t
*)backet
->data
;
2421 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2422 zvni_mac_install(wctx
->zvni
, mac
);
2426 * Decrement neighbor refcount of MAC; uninstall and free it if
2429 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2432 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2433 || !list_isempty(mac
->neigh_list
))
2437 zvni_mac_uninstall(zvni
, mac
, 0);
2439 zvni_mac_del(zvni
, mac
);
2443 * Read and populate local MACs and neighbors corresponding to this VNI.
2445 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
2446 struct interface
*ifp
)
2448 struct zebra_ns
*zns
;
2449 struct zebra_if
*zif
;
2450 struct interface
*vlan_if
;
2451 struct zebra_l2info_vxlan
*vxl
;
2452 struct interface
*vrr_if
;
2455 vxl
= &zif
->l2info
.vxl
;
2456 zns
= zebra_ns_lookup(NS_DEFAULT
);
2458 if (IS_ZEBRA_DEBUG_VXLAN
)
2460 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2461 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2462 zif
->brslave_info
.bridge_ifindex
);
2464 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2465 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2468 /* Add SVI MAC-IP */
2469 zvni_add_macip_for_intf(vlan_if
, zvni
);
2471 /* Add VRR MAC-IP - if any*/
2472 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2474 zvni_add_macip_for_intf(vrr_if
, zvni
);
2476 neigh_read_for_vlan(zns
, vlan_if
);
2481 * Hash function for VNI.
2483 static unsigned int vni_hash_keymake(void *p
)
2485 const zebra_vni_t
*zvni
= p
;
2487 return (jhash_1word(zvni
->vni
, 0));
2491 * Compare 2 VNI hash entries.
2493 static int vni_hash_cmp(const void *p1
, const void *p2
)
2495 const zebra_vni_t
*zvni1
= p1
;
2496 const zebra_vni_t
*zvni2
= p2
;
2498 return (zvni1
->vni
== zvni2
->vni
);
2502 * Callback to allocate VNI hash entry.
2504 static void *zvni_alloc(void *p
)
2506 const zebra_vni_t
*tmp_vni
= p
;
2509 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2510 zvni
->vni
= tmp_vni
->vni
;
2511 return ((void *)zvni
);
2515 * Look up VNI hash entry.
2517 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2519 struct zebra_vrf
*zvrf
;
2520 zebra_vni_t tmp_vni
;
2521 zebra_vni_t
*zvni
= NULL
;
2523 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2525 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2527 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2533 * Add VNI hash entry.
2535 static zebra_vni_t
*zvni_add(vni_t vni
)
2537 struct zebra_vrf
*zvrf
;
2538 zebra_vni_t tmp_zvni
;
2539 zebra_vni_t
*zvni
= NULL
;
2541 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2543 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2545 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2548 /* Create hash table for MAC */
2550 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2552 /* Create hash table for neighbors */
2553 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2554 "Zebra VNI Neighbor Table");
2560 * Delete VNI hash entry.
2562 static int zvni_del(zebra_vni_t
*zvni
)
2564 struct zebra_vrf
*zvrf
;
2565 zebra_vni_t
*tmp_zvni
;
2567 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2570 zvni
->vxlan_if
= NULL
;
2572 /* Free the neighbor hash table. */
2573 hash_free(zvni
->neigh_table
);
2574 zvni
->neigh_table
= NULL
;
2576 /* Free the MAC hash table. */
2577 hash_free(zvni
->mac_table
);
2578 zvni
->mac_table
= NULL
;
2580 /* Free the VNI hash entry and allocated memory. */
2581 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2583 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2589 * Inform BGP about local VNI addition.
2591 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2593 struct zserv
*client
;
2596 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2597 /* BGP may not be running. */
2604 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2605 stream_putl(s
, zvni
->vni
);
2606 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2607 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2609 /* Write packet size. */
2610 stream_putw_at(s
, 0, stream_get_endp(s
));
2612 if (IS_ZEBRA_DEBUG_VXLAN
)
2613 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2614 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2615 vrf_id_to_name(zvni
->vrf_id
),
2616 zebra_route_string(client
->proto
));
2618 client
->vniadd_cnt
++;
2619 return zebra_server_send_message(client
);
2623 * Inform BGP about local VNI deletion.
2625 static int zvni_send_del_to_client(vni_t vni
)
2627 struct zserv
*client
;
2630 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2631 /* BGP may not be running. */
2638 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2639 stream_putl(s
, vni
);
2641 /* Write packet size. */
2642 stream_putw_at(s
, 0, stream_get_endp(s
));
2644 if (IS_ZEBRA_DEBUG_VXLAN
)
2645 zlog_debug("Send VNI_DEL %u to %s", vni
,
2646 zebra_route_string(client
->proto
));
2648 client
->vnidel_cnt
++;
2649 return zebra_server_send_message(client
);
2653 * Build the VNI hash table by going over the VxLAN interfaces. This
2654 * is called when EVPN (advertise-all-vni) is enabled.
2656 static void zvni_build_hash_table()
2658 struct zebra_ns
*zns
;
2659 struct route_node
*rn
;
2660 struct interface
*ifp
;
2662 /* Walk VxLAN interfaces and create VNI hash. */
2663 zns
= zebra_ns_lookup(NS_DEFAULT
);
2664 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2666 zebra_vni_t
*zvni
= NULL
;
2667 zebra_l3vni_t
*zl3vni
= NULL
;
2668 struct zebra_if
*zif
;
2669 struct zebra_l2info_vxlan
*vxl
;
2671 ifp
= (struct interface
*)rn
->info
;
2675 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2678 vxl
= &zif
->l2info
.vxl
;
2681 /* L3-VNI and L2-VNI are handled seperately */
2682 zl3vni
= zl3vni_lookup(vni
);
2685 if (IS_ZEBRA_DEBUG_VXLAN
)
2686 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2687 ifp
->name
, ifp
->ifindex
, vni
);
2689 /* associate with vxlan_if */
2690 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2691 zl3vni
->vxlan_if
= ifp
;
2694 * we need to associate with SVI.
2695 * we can associate with svi-if only after association
2696 * with vxlan-intf is complete
2698 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2700 if (is_l3vni_oper_up(zl3vni
))
2701 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2704 struct interface
*vlan_if
= NULL
;
2706 if (IS_ZEBRA_DEBUG_VXLAN
)
2708 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2709 ifp
->name
, ifp
->ifindex
, vni
,
2710 inet_ntoa(vxl
->vtep_ip
));
2712 /* VNI hash entry is not expected to exist. */
2713 zvni
= zvni_lookup(vni
);
2716 "VNI hash already present for IF %s(%u) L2-VNI %u",
2717 ifp
->name
, ifp
->ifindex
, vni
);
2721 zvni
= zvni_add(vni
);
2724 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2725 ifp
->name
, ifp
->ifindex
, vni
);
2729 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2730 zvni
->vxlan_if
= ifp
;
2731 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2732 zif
->brslave_info
.br_if
);
2734 zvni
->vrf_id
= vlan_if
->vrf_id
;
2735 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2737 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2741 /* Inform BGP if intf is up and mapped to bridge. */
2742 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2743 zvni_send_add_to_client(zvni
);
2749 * See if remote VTEP matches with prefix.
2751 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2753 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2757 * Locate remote VTEP in VNI hash table.
2759 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2761 zebra_vtep_t
*zvtep
;
2766 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2767 if (zvni_vtep_match(vtep_ip
, zvtep
))
2775 * Add remote VTEP to VNI hash table.
2777 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2779 zebra_vtep_t
*zvtep
;
2781 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2783 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2787 zvtep
->vtep_ip
= *vtep_ip
;
2790 zvni
->vteps
->prev
= zvtep
;
2791 zvtep
->next
= zvni
->vteps
;
2792 zvni
->vteps
= zvtep
;
2798 * Remove remote VTEP from VNI hash table.
2800 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2803 zvtep
->next
->prev
= zvtep
->prev
;
2805 zvtep
->prev
->next
= zvtep
->next
;
2807 zvni
->vteps
= zvtep
->next
;
2809 zvtep
->prev
= zvtep
->next
= NULL
;
2810 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2816 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2817 * uninstall from kernel if asked to.
2819 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2821 zebra_vtep_t
*zvtep
, *zvtep_next
;
2826 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2827 zvtep_next
= zvtep
->next
;
2829 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2830 zvni_vtep_del(zvni
, zvtep
);
2837 * Install remote VTEP into the kernel.
2839 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2841 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2845 * Uninstall remote VTEP from the kernel.
2847 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2849 if (!zvni
->vxlan_if
) {
2850 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2855 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2859 * Cleanup VNI/VTEP and update kernel
2861 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
2863 zebra_vni_t
*zvni
= NULL
;
2864 zebra_l3vni_t
*zl3vni
= NULL
;
2865 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
2867 zvni
= (zebra_vni_t
*)backet
->data
;
2871 /* remove from l3-vni list */
2873 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
2875 listnode_delete(zl3vni
->l2vnis
, zvni
);
2877 /* Free up all neighbors and MACs, if any. */
2878 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2879 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2881 /* Free up all remote VTEPs, if any. */
2882 zvni_vtep_del_all(zvni
, 1);
2884 /* Delete the hash entry. */
2889 static void zl3vni_cleanup_all(struct hash_backet
*backet
,
2892 zebra_l3vni_t
*zl3vni
= NULL
;
2894 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
2898 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
2901 static int is_host_present_in_host_list(struct list
*list
,
2902 struct prefix
*host
)
2904 struct listnode
*node
= NULL
;
2905 struct prefix
*p
= NULL
;
2907 for (ALL_LIST_ELEMENTS_RO(list
, node
, p
)) {
2908 if (prefix_same(p
, host
))
2914 static void host_list_add_host(struct list
*list
,
2915 struct prefix
*host
)
2917 struct prefix
*p
= NULL
;
2919 p
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct prefix
));
2920 memcpy(p
, host
, sizeof(struct prefix
));
2922 listnode_add_sort(list
, p
);
2925 static void host_list_delete_host(struct list
*list
,
2926 struct prefix
*host
)
2928 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
2929 struct prefix
*p
= NULL
;
2931 for (ALL_LIST_ELEMENTS(list
, node
, nnode
, p
)) {
2932 if (prefix_same(p
, host
)) {
2933 XFREE(MTYPE_HOST_PREFIX
, p
);
2939 list_delete_node(list
, node_to_del
);
2943 * Look up MAC hash entry.
2945 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
2946 struct ethaddr
*rmac
)
2951 memset(&tmp
, 0, sizeof(tmp
));
2952 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
2953 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
2959 * Callback to allocate RMAC hash entry.
2961 static void *zl3vni_rmac_alloc(void *p
)
2963 const zebra_mac_t
*tmp_rmac
= p
;
2966 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2969 return ((void *)zrmac
);
2973 * Add RMAC entry to l3-vni
2975 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
2976 struct ethaddr
*rmac
)
2978 zebra_mac_t tmp_rmac
;
2979 zebra_mac_t
*zrmac
= NULL
;
2981 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
2982 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
2983 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
2986 zrmac
->host_list
= list_new();
2987 zrmac
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
2989 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
2990 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
2998 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
,
3001 zebra_mac_t
*tmp_rmac
;
3003 if (zrmac
->host_list
)
3004 list_delete_and_null(&zrmac
->host_list
);
3005 zrmac
->host_list
= NULL
;
3007 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
3009 XFREE(MTYPE_MAC
, tmp_rmac
);
3015 * Install remote RMAC into the kernel.
3017 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
,
3020 struct zebra_if
*zif
= NULL
;
3021 struct zebra_l2info_vxlan
*vxl
= NULL
;
3023 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
3024 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3027 zif
= zl3vni
->vxlan_if
->info
;
3031 vxl
= &zif
->l2info
.vxl
;
3033 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3035 zrmac
->fwd_info
.r_vtep_ip
, 0);
3039 * Uninstall remote RMAC from the kernel.
3041 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
3044 char buf
[ETHER_ADDR_STRLEN
];
3045 struct zebra_if
*zif
= NULL
;
3046 struct zebra_l2info_vxlan
*vxl
= NULL
;
3048 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
3049 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3052 if (!zl3vni
->vxlan_if
) {
3054 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3055 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3056 zl3vni
->vni
, zl3vni
);
3060 zif
= zl3vni
->vxlan_if
->info
;
3064 vxl
= &zif
->l2info
.vxl
;
3066 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3067 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3070 /* handle rmac add */
3071 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
,
3072 struct ethaddr
*rmac
,
3073 struct ipaddr
*vtep_ip
,
3074 struct prefix
*host_prefix
)
3076 char buf
[ETHER_ADDR_STRLEN
];
3077 char buf1
[INET6_ADDRSTRLEN
];
3078 zebra_mac_t
*zrmac
= NULL
;
3080 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3083 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3086 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3087 prefix_mac2str(rmac
, buf
,
3089 zl3vni
->vni
, ipaddr2str(vtep_ip
, buf1
,
3093 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3094 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3096 /* install rmac in kernel */
3097 zl3vni_rmac_install(zl3vni
, zrmac
);
3100 if (!is_host_present_in_host_list(zrmac
->host_list
, host_prefix
))
3101 host_list_add_host(zrmac
->host_list
, host_prefix
);
3106 /* handle rmac delete */
3107 static int zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
,
3108 struct ethaddr
*rmac
,
3109 struct prefix
*host_prefix
)
3111 zebra_mac_t
*zrmac
= NULL
;
3113 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3117 host_list_delete_host(zrmac
->host_list
, host_prefix
);
3118 if (list_isempty(zrmac
->host_list
)) {
3120 /* uninstall from kernel */
3121 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3123 /* del the rmac entry */
3124 zl3vni_rmac_del(zl3vni
, zrmac
);
3130 * Look up nh hash entry on a l3-vni.
3132 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
3138 memset(&tmp
, 0, sizeof(tmp
));
3139 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3140 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3147 * Callback to allocate NH hash entry on L3-VNI.
3149 static void *zl3vni_nh_alloc(void *p
)
3151 const zebra_neigh_t
*tmp_n
= p
;
3154 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3161 * Add neighbor entry.
3163 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
3165 struct ethaddr
*mac
)
3167 zebra_neigh_t tmp_n
;
3168 zebra_neigh_t
*n
= NULL
;
3170 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3171 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3172 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3175 n
->host_list
= list_new();
3176 n
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
3178 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3179 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3180 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3186 * Delete neighbor entry.
3188 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
,
3191 zebra_neigh_t
*tmp_n
;
3194 list_delete_and_null(&n
->host_list
);
3195 n
->host_list
= NULL
;
3197 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3199 XFREE(MTYPE_NEIGH
, tmp_n
);
3205 * Install remote nh as neigh into the kernel.
3207 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
,
3210 if (!is_l3vni_oper_up(zl3vni
))
3213 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3214 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3217 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3221 * Uninstall remote nh from the kernel.
3223 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
,
3226 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3227 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3230 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3233 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3236 /* add remote vtep as a neigh entry */
3237 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
,
3238 struct ipaddr
*vtep_ip
,
3239 struct ethaddr
*rmac
,
3240 struct prefix
*host_prefix
)
3242 char buf
[ETHER_ADDR_STRLEN
];
3243 char buf1
[INET6_ADDRSTRLEN
];
3244 zebra_neigh_t
*nh
= NULL
;
3246 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3248 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3252 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3253 ipaddr2str(vtep_ip
, buf1
,
3255 prefix_mac2str(rmac
, buf
,
3261 /* install the nh neigh in kernel */
3262 zl3vni_nh_install(zl3vni
, nh
);
3265 if (!is_host_present_in_host_list(nh
->host_list
, host_prefix
))
3266 host_list_add_host(nh
->host_list
, host_prefix
);
3271 /* handle nh neigh delete */
3272 static int zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
,
3273 struct ipaddr
*vtep_ip
,
3274 struct prefix
*host_prefix
)
3276 zebra_neigh_t
*nh
= NULL
;
3278 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3282 host_list_delete_host(nh
->host_list
, host_prefix
);
3283 if (list_isempty(nh
->host_list
)) {
3285 /* uninstall from kernel */
3286 zl3vni_nh_uninstall(zl3vni
, nh
);
3288 /* delete the nh entry */
3289 zl3vni_nh_del(zl3vni
, nh
);
3295 /* handle neigh update from kernel - the only thing of interest is to
3296 * readd stale entries.
3298 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
,
3299 struct ipaddr
*ip
, u_int16_t state
)
3302 zebra_neigh_t
*n
= NULL
;
3304 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3308 /* all next hop neigh are remote and installed by frr.
3309 * If the kernel has aged this entry, re-install.
3311 if (state
& NUD_STALE
)
3312 zl3vni_nh_install(zl3vni
, n
);
3317 /* handle neigh delete from kernel */
3318 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
,
3321 zebra_neigh_t
*n
= NULL
;
3323 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3327 /* all next hop neigh are remote and installed by frr.
3328 * If we get an age out notification for these neigh entries, we have to
3331 zl3vni_nh_install(zl3vni
, n
);
3337 * Hash function for L3 VNI.
3339 static unsigned int l3vni_hash_keymake(void *p
)
3341 const zebra_l3vni_t
*zl3vni
= p
;
3343 return jhash_1word(zl3vni
->vni
, 0);
3347 * Compare 2 L3 VNI hash entries.
3349 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3351 const zebra_l3vni_t
*zl3vni1
= p1
;
3352 const zebra_l3vni_t
*zl3vni2
= p2
;
3354 return (zl3vni1
->vni
== zl3vni2
->vni
);
3358 * Callback to allocate L3 VNI hash entry.
3360 static void *zl3vni_alloc(void *p
)
3362 zebra_l3vni_t
*zl3vni
= NULL
;
3363 const zebra_l3vni_t
*tmp_l3vni
= p
;
3365 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3366 zl3vni
->vni
= tmp_l3vni
->vni
;
3367 return ((void *)zl3vni
);
3371 * Look up L3 VNI hash entry.
3373 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3375 struct zebra_ns
*zns
;
3376 zebra_l3vni_t tmp_l3vni
;
3377 zebra_l3vni_t
*zl3vni
= NULL
;
3379 zns
= zebra_ns_lookup(NS_DEFAULT
);
3381 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3382 tmp_l3vni
.vni
= vni
;
3383 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3389 * Add L3 VNI hash entry.
3391 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3393 zebra_l3vni_t tmp_zl3vni
;
3394 struct zebra_ns
*zns
= NULL
;
3395 zebra_l3vni_t
*zl3vni
= NULL
;
3397 zns
= zebra_ns_lookup(NS_DEFAULT
);
3400 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3401 tmp_zl3vni
.vni
= vni
;
3403 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3406 zl3vni
->vrf_id
= vrf_id
;
3407 zl3vni
->svi_if
= NULL
;
3408 zl3vni
->vxlan_if
= NULL
;
3409 zl3vni
->l2vnis
= list_new();
3410 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3412 /* Create hash table for remote RMAC */
3413 zl3vni
->rmac_table
=
3414 hash_create(mac_hash_keymake
, mac_cmp
,
3415 "Zebra L3-VNI RMAC-Table");
3417 /* Create hash table for neighbors */
3418 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3419 "Zebra L3-VNI next-hop table");
3425 * Delete L3 VNI hash entry.
3427 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3429 struct zebra_ns
*zns
;
3430 zebra_l3vni_t
*tmp_zl3vni
;
3432 zns
= zebra_ns_lookup(NS_DEFAULT
);
3435 /* free the list of l2vnis */
3436 list_delete_and_null(&zl3vni
->l2vnis
);
3437 zl3vni
->l2vnis
= NULL
;
3439 /* Free the rmac table */
3440 hash_free(zl3vni
->rmac_table
);
3441 zl3vni
->rmac_table
= NULL
;
3443 /* Free the nh table */
3444 hash_free(zl3vni
->nh_table
);
3445 zl3vni
->nh_table
= NULL
;
3447 /* Free the VNI hash entry and allocated memory. */
3448 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3450 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3455 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3457 struct zebra_ns
*zns
= NULL
;
3458 struct route_node
*rn
= NULL
;
3459 struct interface
*ifp
= NULL
;
3461 /* loop through all vxlan-interface */
3462 zns
= zebra_ns_lookup(NS_DEFAULT
);
3463 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3465 struct zebra_if
*zif
= NULL
;
3466 struct zebra_l2info_vxlan
*vxl
= NULL
;
3468 ifp
= (struct interface
*)rn
->info
;
3473 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3476 vxl
= &zif
->l2info
.vxl
;
3477 if (vxl
->vni
== zl3vni
->vni
) {
3478 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3486 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3488 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3489 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3494 if (!zl3vni
->vxlan_if
)
3497 zif
= zl3vni
->vxlan_if
->info
;
3501 vxl
= &zif
->l2info
.vxl
;
3503 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3506 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3508 struct zebra_vrf
*zvrf
= NULL
;
3510 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3514 return zl3vni_lookup(zvrf
->l3vni
);
3518 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3519 * neighbor notifications, to see if they are of interest.
3521 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3522 struct interface
*br_if
)
3526 u_char bridge_vlan_aware
= 0;
3527 zebra_l3vni_t
*zl3vni
= NULL
;
3528 struct zebra_ns
*zns
= NULL
;
3529 struct route_node
*rn
= NULL
;
3530 struct zebra_if
*zif
= NULL
;
3531 struct interface
*tmp_if
= NULL
;
3532 struct zebra_l2info_bridge
*br
= NULL
;
3533 struct zebra_l2info_vxlan
*vxl
= NULL
;
3538 /* Make sure the linked interface is a bridge. */
3539 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3542 /* Determine if bridge is VLAN-aware or not */
3545 br
= &zif
->l2info
.br
;
3546 bridge_vlan_aware
= br
->vlan_aware
;
3547 if (bridge_vlan_aware
) {
3548 struct zebra_l2info_vlan
*vl
;
3550 if (!IS_ZEBRA_IF_VLAN(ifp
))
3555 vl
= &zif
->l2info
.vl
;
3559 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3560 /* TODO: Optimize with a hash. */
3561 zns
= zebra_ns_lookup(NS_DEFAULT
);
3562 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3563 tmp_if
= (struct interface
*)rn
->info
;
3567 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3569 if (!if_is_operative(tmp_if
))
3571 vxl
= &zif
->l2info
.vxl
;
3573 if (zif
->brslave_info
.br_if
!= br_if
)
3576 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3585 zl3vni
= zl3vni_lookup(vxl
->vni
);
3590 * Inform BGP about l3-vni.
3592 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3594 struct stream
*s
= NULL
;
3595 struct zserv
*client
= NULL
;
3596 struct ethaddr rmac
;
3597 char buf
[ETHER_ADDR_STRLEN
];
3599 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3600 /* BGP may not be running. */
3605 memset(&rmac
, 0, sizeof(struct ethaddr
));
3606 zl3vni_get_rmac(zl3vni
, &rmac
);
3611 zclient_create_header(s
, ZEBRA_L3VNI_ADD
,
3612 zl3vni_vrf_id(zl3vni
));
3613 stream_putl(s
, zl3vni
->vni
);
3614 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3615 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3617 /* Write packet size. */
3618 stream_putw_at(s
, 0, stream_get_endp(s
));
3620 if (IS_ZEBRA_DEBUG_VXLAN
)
3621 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s to %s",
3622 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3623 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3624 inet_ntoa(zl3vni
->local_vtep_ip
),
3625 zebra_route_string(client
->proto
));
3627 client
->l3vniadd_cnt
++;
3628 return zebra_server_send_message(client
);
3632 * Inform BGP about local l3-VNI deletion.
3634 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3636 struct stream
*s
= NULL
;
3637 struct zserv
*client
= NULL
;
3639 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3640 /* BGP may not be running. */
3647 zclient_create_header(s
, ZEBRA_L3VNI_DEL
,
3648 zl3vni_vrf_id(zl3vni
));
3649 stream_putl(s
, zl3vni
->vni
);
3651 /* Write packet size. */
3652 stream_putw_at(s
, 0, stream_get_endp(s
));
3654 if (IS_ZEBRA_DEBUG_VXLAN
)
3655 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3657 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3658 zebra_route_string(client
->proto
));
3660 client
->l3vnidel_cnt
++;
3661 return zebra_server_send_message(client
);
3664 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3669 if (IS_ZEBRA_DEBUG_VXLAN
)
3670 zlog_debug("L3-VNI %u is UP - send add to BGP",
3673 /* send l3vni add to BGP */
3674 zl3vni_send_add_to_client(zl3vni
);
3677 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3682 if (IS_ZEBRA_DEBUG_VXLAN
)
3683 zlog_debug("L3-VNI %u is Down - Send del to BGP",
3686 /* send l3-vni del to BGP*/
3687 zl3vni_send_del_to_client(zl3vni
);
3690 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
,
3693 zebra_vni_t
*zvni
= (zebra_vni_t
*) backet
->data
;
3694 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*) ctxt
;
3696 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3697 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3701 * handle transition of vni from l2 to l3 and vice versa
3703 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
,
3706 zebra_vni_t
*zvni
= NULL
;
3708 /* There is a possibility that VNI notification was already received
3709 * from kernel and we programmed it as L2-VNI
3710 * In such a case we need to delete this L2-VNI first, so
3711 * that it can be reprogrammed as L3-VNI in the system. It is also
3712 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3713 * interface is still present in kernel. In this case to keep it
3714 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3717 /* Locate hash entry */
3718 zvni
= zvni_lookup(vni
);
3722 if (IS_ZEBRA_DEBUG_VXLAN
)
3723 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3726 /* Delete VNI from BGP. */
3727 zvni_send_del_to_client(zvni
->vni
);
3729 /* Free up all neighbors and MAC, if any. */
3730 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3731 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3733 /* Free up all remote VTEPs, if any. */
3734 zvni_vtep_del_all(zvni
, 0);
3736 /* Delete the hash entry. */
3737 if (zvni_del(zvni
)) {
3738 zlog_err("Failed to del VNI hash %p, VNI %u",
3743 /* TODO_MITESH: This needs to be thought through. We don't have
3744 * enough information at this point to reprogram the vni as
3745 * l2-vni. One way is to store the required info in l3-vni and
3746 * used it solely for this purpose
3753 /* delete and uninstall rmac hash entry */
3754 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
,
3757 zebra_mac_t
*zrmac
= NULL
;
3758 zebra_l3vni_t
*zl3vni
= NULL
;
3760 zrmac
= (zebra_mac_t
*)backet
->data
;
3761 zl3vni
= (zebra_l3vni_t
*)ctx
;
3762 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3763 zl3vni_rmac_del(zl3vni
, zrmac
);
3766 /* delete and uninstall nh hash entry */
3767 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
,
3770 zebra_neigh_t
*n
= NULL
;
3771 zebra_l3vni_t
*zl3vni
= NULL
;
3773 n
= (zebra_neigh_t
*)backet
->data
;
3774 zl3vni
= (zebra_l3vni_t
*)ctx
;
3775 zl3vni_nh_uninstall(zl3vni
, n
);
3776 zl3vni_nh_del(zl3vni
, n
);
3779 static int ip_prefix_send_to_client(vrf_id_t vrf_id
,
3783 struct zserv
*client
= NULL
;
3784 struct stream
*s
= NULL
;
3785 char buf
[PREFIX_STRLEN
];
3787 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3788 /* BGP may not be running. */
3795 zclient_create_header(s
, cmd
, vrf_id
);
3796 stream_put(s
, p
, sizeof(struct prefix
));
3798 /* Write packet size. */
3799 stream_putw_at(s
, 0, stream_get_endp(s
));
3801 if (IS_ZEBRA_DEBUG_VXLAN
)
3803 "Send ip prefix %s %s on vrf %s",
3804 prefix2str(p
, buf
, sizeof(buf
)),
3805 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
3806 vrf_id_to_name(vrf_id
));
3808 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
3809 client
->prefixadd_cnt
++;
3811 client
->prefixdel_cnt
++;
3813 return zebra_server_send_message(client
);
3816 /* re-add remote rmac if needed */
3817 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
3818 struct ethaddr
*rmac
)
3820 char buf
[ETHER_ADDR_STRLEN
];
3821 zebra_mac_t
*zrmac
= NULL
;
3823 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3827 if (IS_ZEBRA_DEBUG_VXLAN
)
3828 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
3829 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3832 zl3vni_rmac_install(zl3vni
, zrmac
);
3836 /* Public functions */
3838 /* handle evpn route in vrf table */
3839 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
,
3840 struct ethaddr
*rmac
,
3841 struct ipaddr
*vtep_ip
,
3842 struct prefix
*host_prefix
)
3844 zebra_l3vni_t
*zl3vni
= NULL
;
3846 zl3vni
= zl3vni_from_vrf(vrf_id
);
3847 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3850 /* add the next hop neighbor */
3851 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
3854 zl3vni_remote_rmac_add(zl3vni
, rmac
, vtep_ip
, host_prefix
);
3857 /* handle evpn vrf route delete */
3858 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
3859 struct ethaddr
*rmac
,
3860 struct ipaddr
*vtep_ip
,
3861 struct prefix
*host_prefix
)
3863 zebra_l3vni_t
*zl3vni
= NULL
;
3865 zl3vni
= zl3vni_from_vrf(vrf_id
);
3869 /* delete the next hop entry */
3870 zl3vni_remote_nh_del(zl3vni
, vtep_ip
, host_prefix
);
3872 /* delete the rmac entry */
3873 zl3vni_remote_rmac_del(zl3vni
, rmac
, host_prefix
);
3876 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
,
3878 struct ethaddr
*rmac
,
3881 zebra_l3vni_t
*zl3vni
= NULL
;
3882 zebra_mac_t
*zrmac
= NULL
;
3883 json_object
*json
= NULL
;
3885 if (!is_evpn_enabled()) {
3887 vty_out(vty
, "{}\n");
3892 json
= json_object_new_object();
3894 zl3vni
= zl3vni_lookup(l3vni
);
3897 vty_out(vty
, "{}\n");
3899 vty_out(vty
, "%% L3-VNI %u doesnt exist\n",
3904 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3907 vty_out(vty
, "{}\n");
3910 "%% Requested RMAC doesnt exist in L3-VNI %u",
3915 zl3vni_print_rmac(zrmac
, vty
, json
);
3918 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3919 json
, JSON_C_TO_STRING_PRETTY
));
3920 json_object_free(json
);
3924 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
,
3928 zebra_l3vni_t
*zl3vni
;
3929 u_int32_t num_rmacs
;
3930 struct rmac_walk_ctx wctx
;
3931 json_object
*json
= NULL
;
3933 if (!is_evpn_enabled())
3936 zl3vni
= zl3vni_lookup(l3vni
);
3939 vty_out(vty
, "{}\n");
3941 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3944 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3949 json
= json_object_new_object();
3951 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3956 "Number of Remote RMACs known for this VNI: %u\n",
3958 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
3960 json_object_int_add(json
, "numRmacs", num_rmacs
);
3962 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3965 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3966 json
, JSON_C_TO_STRING_PRETTY
));
3967 json_object_free(json
);
3971 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
,
3974 struct zebra_ns
*zns
= NULL
;
3975 json_object
*json
= NULL
;
3978 if (!is_evpn_enabled()) {
3980 vty_out(vty
, "{}\n");
3984 zns
= zebra_ns_lookup(NS_DEFAULT
);
3987 vty_out(vty
, "{}\n");
3992 json
= json_object_new_object();
3996 hash_iterate(zns
->l3vni_table
,
3997 (void (*)(struct hash_backet
*,
3998 void *))zl3vni_print_rmac_hash_all_vni
,
4002 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4003 json
, JSON_C_TO_STRING_PRETTY
));
4004 json_object_free(json
);
4008 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
,
4013 zebra_l3vni_t
*zl3vni
= NULL
;
4014 zebra_neigh_t
*n
= NULL
;
4015 json_object
*json
= NULL
;
4017 if (!is_evpn_enabled()) {
4019 vty_out(vty
, "{}\n");
4024 json
= json_object_new_object();
4026 zl3vni
= zl3vni_lookup(l3vni
);
4029 vty_out(vty
, "{}\n");
4031 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4035 n
= zl3vni_nh_lookup(zl3vni
, ip
);
4038 vty_out(vty
, "{}\n");
4041 "%% Requested next-hop not present for L3-VNI %u",
4046 zl3vni_print_nh(n
, vty
, json
);
4049 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4050 json
, JSON_C_TO_STRING_PRETTY
));
4051 json_object_free(json
);
4055 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
,
4060 struct nh_walk_ctx wctx
;
4061 json_object
*json
= NULL
;
4062 zebra_l3vni_t
*zl3vni
= NULL
;
4064 if (!is_evpn_enabled())
4067 zl3vni
= zl3vni_lookup(l3vni
);
4070 vty_out(vty
, "{}\n");
4072 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4076 num_nh
= hashcount(zl3vni
->nh_table
);
4081 json
= json_object_new_object();
4087 "Number of NH Neighbors known for this VNI: %u\n",
4089 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4091 json_object_int_add(json
, "numNextHops", num_nh
);
4093 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4096 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4097 json
, JSON_C_TO_STRING_PRETTY
));
4098 json_object_free(json
);
4102 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
,
4105 struct zebra_ns
*zns
= NULL
;
4106 json_object
*json
= NULL
;
4109 if (!is_evpn_enabled()) {
4111 vty_out(vty
, "{}\n");
4115 zns
= zebra_ns_lookup(NS_DEFAULT
);
4120 json
= json_object_new_object();
4124 hash_iterate(zns
->l3vni_table
,
4125 (void (*)(struct hash_backet
*,
4126 void *))zl3vni_print_nh_hash_all_vni
,
4130 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4131 json
, JSON_C_TO_STRING_PRETTY
));
4132 json_object_free(json
);
4138 * Display L3 VNI information (VTY command handler).
4140 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
4143 json_object
*json
= NULL
;
4144 zebra_l3vni_t
*zl3vni
= NULL
;
4146 if (!is_evpn_enabled()) {
4148 vty_out(vty
, "{}\n");
4152 zl3vni
= zl3vni_lookup(vni
);
4155 vty_out(vty
, "{}\n");
4157 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4162 json
= json_object_new_object();
4166 zl3vni_print(zl3vni
, (void *)args
);
4169 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4170 json
, JSON_C_TO_STRING_PRETTY
));
4171 json_object_free(json
);
4175 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4176 json_object
*json_vrfs
)
4178 char buf
[ETHER_ADDR_STRLEN
];
4179 zebra_l3vni_t
*zl3vni
= NULL
;
4181 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4186 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4189 zl3vni_vxlan_if_name(zl3vni
),
4190 zl3vni_svi_if_name(zl3vni
),
4191 zl3vni_state2str(zl3vni
),
4192 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4194 json_object
*json_vrf
= NULL
;
4195 json_vrf
= json_object_new_object();
4196 json_object_string_add(json_vrf
, "vrf",
4198 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4199 json_object_string_add(json_vrf
, "vxlanIntf",
4200 zl3vni_vxlan_if_name(zl3vni
));
4201 json_object_string_add(json_vrf
, "sviIntf",
4202 zl3vni_svi_if_name(zl3vni
));
4203 json_object_string_add(json_vrf
, "state",
4204 zl3vni_state2str(zl3vni
));
4205 json_object_string_add(json_vrf
, "routerMac",
4206 zl3vni_rmac2str(zl3vni
, buf
,
4208 json_object_array_add(json_vrfs
, json_vrf
);
4213 * Display Neighbors for a VNI (VTY command handler).
4215 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4216 vni_t vni
, u_char use_json
)
4219 u_int32_t num_neigh
;
4220 struct neigh_walk_ctx wctx
;
4221 json_object
*json
= NULL
;
4223 if (!is_evpn_enabled())
4225 zvni
= zvni_lookup(vni
);
4228 vty_out(vty
, "{}\n");
4230 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4233 num_neigh
= hashcount(zvni
->neigh_table
);
4238 json
= json_object_new_object();
4240 /* Since we have IPv6 addresses to deal with which can vary widely in
4241 * size, we try to be a bit more elegant in display by first computing
4242 * the maximum width.
4244 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4247 wctx
.addr_width
= 15;
4249 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4253 "Number of ARPs (local and remote) known for this VNI: %u\n",
4255 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
4256 "Type", "MAC", "Remote VTEP");
4258 json_object_int_add(json
, "numArpNd", num_neigh
);
4260 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4262 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4263 json
, JSON_C_TO_STRING_PRETTY
));
4264 json_object_free(json
);
4269 * Display neighbors across all VNIs (VTY command handler).
4271 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4274 json_object
*json
= NULL
;
4277 if (!is_evpn_enabled())
4281 json
= json_object_new_object();
4285 hash_iterate(zvrf
->vni_table
,
4286 (void (*)(struct hash_backet
*,
4287 void *))zvni_print_neigh_hash_all_vni
,
4290 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4291 json
, JSON_C_TO_STRING_PRETTY
));
4292 json_object_free(json
);
4297 * Display specific neighbor for a VNI, if present (VTY command handler).
4299 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4300 struct zebra_vrf
*zvrf
, vni_t vni
,
4301 struct ipaddr
*ip
, u_char use_json
)
4305 json_object
*json
= NULL
;
4307 if (!is_evpn_enabled())
4309 zvni
= zvni_lookup(vni
);
4312 vty_out(vty
, "{}\n");
4314 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4317 n
= zvni_neigh_lookup(zvni
, ip
);
4321 "%% Requested neighbor does not exist in VNI %u\n",
4326 json
= json_object_new_object();
4328 zvni_print_neigh(n
, vty
, json
);
4331 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4332 json
, JSON_C_TO_STRING_PRETTY
));
4333 json_object_free(json
);
4338 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4339 * By definition, these are remote neighbors.
4341 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4342 vni_t vni
, struct in_addr vtep_ip
,
4346 u_int32_t num_neigh
;
4347 struct neigh_walk_ctx wctx
;
4348 json_object
*json
= NULL
;
4350 if (!is_evpn_enabled())
4352 zvni
= zvni_lookup(vni
);
4355 vty_out(vty
, "{}\n");
4357 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4360 num_neigh
= hashcount(zvni
->neigh_table
);
4364 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4367 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4368 wctx
.r_vtep_ip
= vtep_ip
;
4370 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4373 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4374 json
, JSON_C_TO_STRING_PRETTY
));
4375 json_object_free(json
);
4380 * Display MACs for a VNI (VTY command handler).
4382 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4383 vni_t vni
, u_char use_json
)
4387 struct mac_walk_ctx wctx
;
4388 json_object
*json
= NULL
;
4389 json_object
*json_mac
= NULL
;
4391 if (!is_evpn_enabled())
4393 zvni
= zvni_lookup(vni
);
4396 vty_out(vty
, "{}\n");
4398 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4401 num_macs
= num_valid_macs(zvni
);
4406 json
= json_object_new_object();
4407 json_mac
= json_object_new_object();
4410 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4413 wctx
.json
= json_mac
;
4417 "Number of MACs (local and remote) known for this VNI: %u\n",
4419 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4420 "Intf/Remote VTEP", "VLAN");
4422 json_object_int_add(json
, "numMacs", num_macs
);
4424 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4427 json_object_object_add(json
, "macs", json_mac
);
4428 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4429 json
, JSON_C_TO_STRING_PRETTY
));
4430 json_object_free(json
);
4435 * Display MACs for all VNIs (VTY command handler).
4437 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4440 struct mac_walk_ctx wctx
;
4441 json_object
*json
= NULL
;
4443 if (!is_evpn_enabled()) {
4445 vty_out(vty
, "{}\n");
4449 json
= json_object_new_object();
4451 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4454 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4457 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4458 json
, JSON_C_TO_STRING_PRETTY
));
4459 json_object_free(json
);
4464 * Display MACs for all VNIs (VTY command handler).
4466 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4467 struct zebra_vrf
*zvrf
,
4468 struct in_addr vtep_ip
,
4471 struct mac_walk_ctx wctx
;
4472 json_object
*json
= NULL
;
4474 if (!is_evpn_enabled())
4478 json
= json_object_new_object();
4480 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4482 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4483 wctx
.r_vtep_ip
= vtep_ip
;
4485 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4488 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4489 json
, JSON_C_TO_STRING_PRETTY
));
4490 json_object_free(json
);
4495 * Display specific MAC for a VNI, if present (VTY command handler).
4497 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4498 vni_t vni
, struct ethaddr
*macaddr
)
4503 if (!is_evpn_enabled())
4505 zvni
= zvni_lookup(vni
);
4507 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4510 mac
= zvni_mac_lookup(zvni
, macaddr
);
4512 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4517 zvni_print_mac(mac
, vty
);
4521 * Display MACs for a VNI from specific VTEP (VTY command handler).
4523 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4524 vni_t vni
, struct in_addr vtep_ip
,
4529 struct mac_walk_ctx wctx
;
4530 json_object
*json
= NULL
;
4531 json_object
*json_mac
= NULL
;
4533 if (!is_evpn_enabled())
4535 zvni
= zvni_lookup(vni
);
4538 vty_out(vty
, "{}\n");
4540 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4543 num_macs
= num_valid_macs(zvni
);
4548 json
= json_object_new_object();
4549 json_mac
= json_object_new_object();
4552 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4555 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4556 wctx
.r_vtep_ip
= vtep_ip
;
4557 wctx
.json
= json_mac
;
4558 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4561 json_object_int_add(json
, "numMacs", wctx
.count
);
4563 json_object_object_add(json
, "macs", json_mac
);
4564 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4565 json
, JSON_C_TO_STRING_PRETTY
));
4566 json_object_free(json
);
4572 * Display VNI information (VTY command handler).
4574 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4577 json_object
*json
= NULL
;
4579 zebra_l3vni_t
*zl3vni
= NULL
;
4580 zebra_vni_t
*zvni
= NULL
;
4582 if (!is_evpn_enabled())
4586 json
= json_object_new_object();
4590 zl3vni
= zl3vni_lookup(vni
);
4592 zl3vni_print(zl3vni
, (void *)args
);
4594 zvni
= zvni_lookup(vni
);
4597 vty_out(vty
, "{}\n");
4599 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4603 zvni_print(zvni
, (void *)args
);
4607 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4608 json
, JSON_C_TO_STRING_PRETTY
));
4609 json_object_free(json
);
4613 /* Display all global details for EVPN */
4614 void zebra_vxlan_print_evpn(struct vty
*vty
, u_char uj
)
4619 json_object
*json
= NULL
;
4620 struct zebra_ns
*zns
= NULL
;
4621 struct zebra_vrf
*zvrf
= NULL
;
4623 if (!is_evpn_enabled())
4626 zns
= zebra_ns_lookup(NS_DEFAULT
);
4630 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
4634 num_l3vnis
= hashcount(zns
->l3vni_table
);
4635 num_l2vnis
= hashcount(zvrf
->vni_table
);
4636 num_vnis
= num_l2vnis
+ num_l3vnis
;
4639 json
= json_object_new_object();
4640 json_object_string_add(json
, "advertiseGatewayMacip",
4641 zvrf
->advertise_gw_macip
? "Yes" : "No");
4642 json_object_int_add(json
, "numVnis", num_vnis
);
4643 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
4644 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
4646 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
4647 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
4648 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4649 zvrf
->advertise_gw_macip
? "Yes" : "No");
4653 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4654 json
, JSON_C_TO_STRING_PRETTY
));
4655 json_object_free(json
);
4660 * Display VNI hash table (VTY command handler).
4662 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4665 json_object
*json
= NULL
;
4666 struct zebra_ns
*zns
= NULL
;
4669 if (!is_evpn_enabled())
4672 zns
= zebra_ns_lookup(NS_DEFAULT
);
4678 json
= json_object_new_object();
4681 "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n",
4682 "VNI", "Type", "VxLAN IF", "# MACs",
4683 "# ARPs", "# Remote VTEPs", "Tenant VRF");
4688 /* Display all L2-VNIs */
4689 hash_iterate(zvrf
->vni_table
,
4690 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4693 /* Display all L3-VNIs */
4694 hash_iterate(zns
->l3vni_table
,
4695 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
4699 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4700 json
, JSON_C_TO_STRING_PRETTY
));
4701 json_object_free(json
);
4706 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4707 * kernel. This may result in either the neighbor getting deleted from
4708 * our database or being re-added to the kernel (if it is a valid
4711 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4712 struct interface
*link_if
, struct ipaddr
*ip
)
4714 char buf
[INET6_ADDRSTRLEN
];
4715 char buf2
[ETHER_ADDR_STRLEN
];
4716 zebra_neigh_t
*n
= NULL
;
4717 zebra_vni_t
*zvni
= NULL
;
4718 zebra_mac_t
*zmac
= NULL
;
4719 zebra_l3vni_t
*zl3vni
= NULL
;
4721 /* check if this is a remote neigh entry corresponding to remote
4724 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4726 return zl3vni_local_nh_del(zl3vni
, ip
);
4728 /* We are only interested in neighbors on an SVI that resides on top
4729 * of a VxLAN bridge.
4731 zvni
= zvni_from_svi(ifp
, link_if
);
4735 if (!zvni
->vxlan_if
) {
4737 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4742 if (IS_ZEBRA_DEBUG_VXLAN
)
4743 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4744 ipaddr2str(ip
, buf
, sizeof(buf
)),
4745 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4747 /* If entry doesn't exist, nothing to do. */
4748 n
= zvni_neigh_lookup(zvni
, ip
);
4752 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4754 if (IS_ZEBRA_DEBUG_VXLAN
)
4756 "Trying to del a neigh %s without a mac %s on VNI %u",
4757 ipaddr2str(ip
, buf
, sizeof(buf
)),
4758 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4764 /* If it is a remote entry, the kernel has aged this out or someone has
4765 * deleted it, it needs to be re-installed as Quagga is the owner.
4767 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4768 zvni_neigh_install(zvni
, n
);
4772 /* Remove neighbor from BGP. */
4773 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4774 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
4777 /* Delete this neighbor entry. */
4778 zvni_neigh_del(zvni
, n
);
4780 /* see if the AUTO mac needs to be deleted */
4781 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4782 && !listcount(zmac
->neigh_list
))
4783 zvni_mac_del(zvni
, zmac
);
4789 * Handle neighbor add or update (on a VLAN device / L3 interface)
4792 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4793 struct interface
*link_if
,
4795 struct ethaddr
*macaddr
, u_int16_t state
,
4798 char buf
[ETHER_ADDR_STRLEN
];
4799 char buf2
[INET6_ADDRSTRLEN
];
4800 zebra_vni_t
*zvni
= NULL
;
4801 zebra_neigh_t
*n
= NULL
;
4802 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4803 zebra_l3vni_t
*zl3vni
= NULL
;
4805 /* check if this is a remote neigh entry corresponding to remote
4808 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4810 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
4812 /* We are only interested in neighbors on an SVI that resides on top
4813 * of a VxLAN bridge.
4815 zvni
= zvni_from_svi(ifp
, link_if
);
4819 if (IS_ZEBRA_DEBUG_VXLAN
)
4821 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4822 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4823 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4824 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4827 /* create a dummy MAC if the MAC is not already present */
4828 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4830 if (IS_ZEBRA_DEBUG_VXLAN
)
4832 "AUTO MAC %s created for neigh %s on VNI %u",
4833 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4834 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
4836 zmac
= zvni_mac_add(zvni
, macaddr
);
4838 zlog_warn("Failed to add MAC %s VNI %u",
4839 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4844 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4845 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4846 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4849 /* If same entry already exists, it might be a change or it might be a
4850 * move from remote to local.
4852 n
= zvni_neigh_lookup(zvni
, ip
);
4854 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4855 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
4858 /* Update any params and return - client doesn't
4859 * care about a purely local change.
4861 n
->ifindex
= ifp
->ifindex
;
4865 /* If the MAC has changed,
4866 * need to issue a delete first
4867 * as this means a different MACIP route.
4868 * Also, need to do some unlinking/relinking.
4870 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4872 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4874 listnode_delete(old_zmac
->neigh_list
, n
);
4875 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4878 /* Set "local" forwarding info. */
4879 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4880 n
->ifindex
= ifp
->ifindex
;
4881 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4883 /* Link to new MAC */
4884 listnode_add_sort(zmac
->neigh_list
, n
);
4885 } else if (ext_learned
)
4886 /* The neighbor is remote and that is the notification we got.
4889 /* TODO: Evaluate if we need to do anything here. */
4892 /* Neighbor has moved from remote to local. */
4894 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4895 n
->r_vtep_ip
.s_addr
= 0;
4896 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4897 n
->ifindex
= ifp
->ifindex
;
4900 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4903 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4904 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4905 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4906 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4909 /* Set "local" forwarding info. */
4910 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4911 n
->ifindex
= ifp
->ifindex
;
4914 /* Before we program this in BGP, we need to check if MAC is locally
4916 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4917 if (IS_ZEBRA_DEBUG_VXLAN
)
4919 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4920 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4921 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4928 if (IS_ZEBRA_DEBUG_VXLAN
)
4929 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
4930 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4931 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4933 ZEBRA_NEIGH_SET_ACTIVE(n
);
4935 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, n
->flags
);
4940 * Handle message from client to delete a remote MACIP for a VNI.
4942 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
4943 struct zebra_vrf
*zvrf
)
4947 struct ethaddr macaddr
;
4949 struct in_addr vtep_ip
;
4953 u_short l
= 0, ipa_len
;
4954 char buf
[ETHER_ADDR_STRLEN
];
4955 char buf1
[INET6_ADDRSTRLEN
];
4956 struct interface
*ifp
= NULL
;
4957 struct zebra_if
*zif
= NULL
;
4959 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4960 memset(&ip
, 0, sizeof(struct ipaddr
));
4961 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4965 while (l
< length
) {
4966 /* Obtain each remote MACIP and process. */
4967 /* Message contains VNI, followed by MAC followed by IP (if any)
4968 * followed by remote VTEP IP.
4972 memset(&ip
, 0, sizeof(ip
));
4973 STREAM_GETL(s
, vni
);
4974 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4975 STREAM_GETL(s
, ipa_len
);
4977 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4979 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4981 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4982 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4983 l
+= IPV4_MAX_BYTELEN
;
4985 if (IS_ZEBRA_DEBUG_VXLAN
)
4987 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4988 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4989 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4991 zebra_route_string(client
->proto
));
4993 /* Locate VNI hash entry - expected to exist. */
4994 zvni
= zvni_lookup(vni
);
4996 if (IS_ZEBRA_DEBUG_VXLAN
)
4998 "Failed to locate VNI hash upon remote MACIP DEL, "
5003 ifp
= zvni
->vxlan_if
;
5006 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
5012 /* If down or not mapped to a bridge, we're done. */
5013 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5016 /* The remote VTEP specified is normally expected to exist, but
5018 * possible that the peer may delete the VTEP before deleting
5020 * referring to the VTEP, in which case the handler (see
5022 * would have already deleted the MACs.
5024 if (!zvni_vtep_find(zvni
, &vtep_ip
))
5027 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5029 n
= zvni_neigh_lookup(zvni
, &ip
);
5033 "Failed to locate MAC %s for neigh %s VNI %u",
5034 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5035 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
5039 /* If the remote mac or neighbor doesn't exist there is nothing
5041 * to do. Otherwise, uninstall the entry and then remove it.
5046 /* Ignore the delete if this mac is a gateway mac-ip */
5047 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
) &&
5048 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
5049 zlog_err("%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway",
5051 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5052 ipaddr2str(&ip
, buf1
, sizeof(buf1
)),
5057 /* Uninstall remote neighbor or MAC. */
5059 /* When the MAC changes for an IP, it is possible the
5061 * update the new MAC before trying to delete the "old"
5063 * (as these are two different MACIP routes). Do the
5065 * if the MAC matches.
5067 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5068 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
5071 zvni_neigh_uninstall(zvni
, n
);
5072 zvni_neigh_del(zvni
, n
);
5073 zvni_deref_ip2mac(zvni
, mac
, 1);
5076 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5077 zvni_process_neigh_on_remote_mac_del(zvni
,
5080 if (list_isempty(mac
->neigh_list
)) {
5081 zvni_mac_uninstall(zvni
, mac
, 0);
5082 zvni_mac_del(zvni
, mac
);
5084 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5094 * Handle message from client to add a remote MACIP for a VNI. This
5095 * could be just the add of a MAC address or the add of a neighbor
5098 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
5099 struct zebra_vrf
*zvrf
)
5103 struct ethaddr macaddr
;
5105 struct in_addr vtep_ip
;
5107 zebra_vtep_t
*zvtep
;
5108 zebra_mac_t
*mac
, *old_mac
;
5110 u_short l
= 0, ipa_len
;
5111 int update_mac
= 0, update_neigh
= 0;
5112 char buf
[ETHER_ADDR_STRLEN
];
5113 char buf1
[INET6_ADDRSTRLEN
];
5116 struct interface
*ifp
= NULL
;
5117 struct zebra_if
*zif
= NULL
;
5119 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5120 memset(&ip
, 0, sizeof(struct ipaddr
));
5121 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5123 if (!EVPN_ENABLED(zvrf
)) {
5124 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
5125 __PRETTY_FUNCTION__
);
5131 while (l
< length
) {
5132 /* Obtain each remote MACIP and process. */
5133 /* Message contains VNI, followed by MAC followed by IP (if any)
5134 * followed by remote VTEP IP.
5136 update_mac
= update_neigh
= 0;
5139 memset(&ip
, 0, sizeof(ip
));
5140 STREAM_GETL(s
, vni
);
5141 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5142 STREAM_GETL(s
, ipa_len
);
5144 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5146 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5148 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5149 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5150 l
+= IPV4_MAX_BYTELEN
;
5152 /* Get flags - sticky mac and/or gateway mac */
5153 flags
= stream_getc(s
);
5154 sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
5157 if (IS_ZEBRA_DEBUG_VXLAN
)
5159 "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
5160 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5161 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
5162 inet_ntoa(vtep_ip
), flags
,
5163 zebra_route_string(client
->proto
));
5165 /* Locate VNI hash entry - expected to exist. */
5166 zvni
= zvni_lookup(vni
);
5169 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
5173 ifp
= zvni
->vxlan_if
;
5176 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5182 /* If down or not mapped to a bridge, we're done. */
5183 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5186 /* The remote VTEP specified should normally exist, but it is
5188 * that when peering comes up, peer may advertise MACIP routes
5190 * advertising type-3 routes.
5192 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5194 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5196 "Failed to add remote VTEP, VNI %u zvni %p",
5201 zvni_vtep_install(zvni
, &vtep_ip
);
5204 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5206 /* Ignore the update if the mac is already present
5208 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
) &&
5209 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
5210 if (IS_ZEBRA_DEBUG_VXLAN
)
5211 zlog_debug("%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
5213 prefix_mac2str(&macaddr
,
5215 ipaddr2str(&ip
, buf1
,
5216 sizeof(buf1
)), vni
);
5220 /* check if the remote MAC is unknown or has a change.
5221 * If so, that needs to be updated first. Note that client could
5222 * install MAC and MACIP separately or just install the latter.
5224 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
5225 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
5227 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
5232 mac
= zvni_mac_add(zvni
, &macaddr
);
5235 "Failed to add MAC %s VNI %u Remote VTEP %s",
5236 prefix_mac2str(&macaddr
, buf
,
5238 vni
, inet_ntoa(vtep_ip
));
5242 /* Is this MAC created for a MACIP? */
5244 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5247 /* Set "auto" and "remote" forwarding info. */
5248 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5249 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5250 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5251 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
5254 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5256 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5258 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
5260 /* Install the entry. */
5261 zvni_mac_install(zvni
, mac
);
5264 /* If there is no IP, continue - after clearing AUTO flag of
5267 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5271 /* Check if the remote neighbor itself is unknown or has a
5273 * If so, create or update and then install the entry.
5275 n
= zvni_neigh_lookup(zvni
, &ip
);
5276 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5277 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
5278 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
5283 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
5286 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5287 ipaddr2str(&ip
, buf1
,
5289 prefix_mac2str(&macaddr
, buf
,
5291 vni
, inet_ntoa(vtep_ip
));
5295 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
5297 /* MAC change, update neigh list for old and new
5299 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
5301 listnode_delete(old_mac
->neigh_list
, n
);
5302 zvni_deref_ip2mac(zvni
, old_mac
, 1);
5304 listnode_add_sort(mac
->neigh_list
, n
);
5305 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
5308 /* Set "remote" forwarding info. */
5309 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
5310 /* TODO: Handle MAC change. */
5311 n
->r_vtep_ip
= vtep_ip
;
5312 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
5314 /* Install the entry. */
5315 zvni_neigh_install(zvni
, n
);
5324 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5325 * us, this must involve a multihoming scenario. Treat this as implicit delete
5326 * of any prior local MAC.
5328 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5329 struct interface
*br_if
,
5330 struct ethaddr
*macaddr
, vlanid_t vid
)
5332 struct zebra_if
*zif
;
5333 struct zebra_l2info_vxlan
*vxl
;
5337 char buf
[ETHER_ADDR_STRLEN
];
5341 vxl
= &zif
->l2info
.vxl
;
5344 /* Check if EVPN is enabled. */
5345 if (!is_evpn_enabled())
5348 /* Locate hash entry; it is expected to exist. */
5349 zvni
= zvni_lookup(vni
);
5353 /* If entry doesn't exist, nothing to do. */
5354 mac
= zvni_mac_lookup(zvni
, macaddr
);
5358 /* Is it a local entry? */
5359 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5362 if (IS_ZEBRA_DEBUG_VXLAN
)
5364 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5365 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5366 ifp
->name
, ifp
->ifindex
, vni
);
5368 /* Remove MAC from BGP. */
5369 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5372 * If there are no neigh associated with the mac delete the mac
5373 * else mark it as AUTO for forward reference
5375 if (!listcount(mac
->neigh_list
)) {
5376 zvni_mac_del(zvni
, mac
);
5378 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5379 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5386 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5387 * This can happen because the remote MAC entries are also added as "dynamic",
5388 * so the kernel can ageout the entry.
5390 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5391 struct interface
*br_if
,
5392 struct ethaddr
*macaddr
, vlanid_t vid
)
5394 struct zebra_if
*zif
= NULL
;
5395 struct zebra_l2info_vxlan
*vxl
= NULL
;
5397 zebra_vni_t
*zvni
= NULL
;
5398 zebra_l3vni_t
*zl3vni
= NULL
;
5399 zebra_mac_t
*mac
= NULL
;
5400 char buf
[ETHER_ADDR_STRLEN
];
5404 vxl
= &zif
->l2info
.vxl
;
5407 /* Check if EVPN is enabled. */
5408 if (!is_evpn_enabled())
5411 /* check if this is a remote RMAC and readd simillar to remote macs */
5412 zl3vni
= zl3vni_lookup(vni
);
5414 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5416 /* Locate hash entry; it is expected to exist. */
5417 zvni
= zvni_lookup(vni
);
5421 /* If entry doesn't exist, nothing to do. */
5422 mac
= zvni_mac_lookup(zvni
, macaddr
);
5426 /* Is it a remote entry? */
5427 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5430 if (IS_ZEBRA_DEBUG_VXLAN
)
5431 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5432 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5435 zvni_mac_install(zvni
, mac
);
5440 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5442 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5443 struct ethaddr
*macaddr
, vlanid_t vid
)
5447 char buf
[ETHER_ADDR_STRLEN
];
5449 /* We are interested in MACs only on ports or (port, VLAN) that
5452 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5455 if (!zvni
->vxlan_if
) {
5456 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5461 if (IS_ZEBRA_DEBUG_VXLAN
)
5462 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5463 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5464 ifp
->ifindex
, vid
, zvni
->vni
);
5466 /* If entry doesn't exist, nothing to do. */
5467 mac
= zvni_mac_lookup(zvni
, macaddr
);
5471 /* Is it a local entry? */
5472 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5475 /* Remove MAC from BGP. */
5476 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5478 /* Update all the neigh entries associated with this mac */
5479 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5482 * If there are no neigh associated with the mac delete the mac
5483 * else mark it as AUTO for forward reference
5485 if (!listcount(mac
->neigh_list
)) {
5486 zvni_mac_del(zvni
, mac
);
5488 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5489 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5496 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5498 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5499 struct interface
*br_if
,
5500 struct ethaddr
*macaddr
, vlanid_t vid
,
5505 char buf
[ETHER_ADDR_STRLEN
];
5509 /* We are interested in MACs only on ports or (port, VLAN) that
5512 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5514 if (IS_ZEBRA_DEBUG_VXLAN
)
5516 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5517 sticky
? "sticky " : "",
5518 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5519 ifp
->name
, ifp
->ifindex
, vid
);
5523 if (!zvni
->vxlan_if
) {
5524 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5529 if (IS_ZEBRA_DEBUG_VXLAN
)
5531 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5532 sticky
? "sticky " : "",
5533 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5534 ifp
->ifindex
, vid
, zvni
->vni
);
5536 /* If same entry already exists, nothing to do. */
5537 mac
= zvni_mac_lookup(zvni
, macaddr
);
5539 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5540 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5546 * return if nothing has changed.
5547 * inform bgp if sticky flag has changed
5548 * update locally and do not inform bgp if local
5549 * parameters like interface has changed
5551 if (mac_sticky
== sticky
5552 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5553 && mac
->fwd_info
.local
.vid
== vid
) {
5554 if (IS_ZEBRA_DEBUG_VXLAN
)
5556 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5557 "entry exists and has not changed ",
5558 sticky
? "sticky " : "",
5559 prefix_mac2str(macaddr
, buf
,
5561 ifp
->name
, ifp
->ifindex
, vid
,
5564 } else if (mac_sticky
!= sticky
) {
5567 add
= 0; /* This is an update of local
5570 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5572 * If we have already learned the MAC as a remote sticky
5574 * this is a operator error and we must log a warning
5576 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5578 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5579 prefix_mac2str(macaddr
, buf
,
5581 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5589 mac
= zvni_mac_add(zvni
, macaddr
);
5591 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5592 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5593 ifp
->name
, ifp
->ifindex
, vid
);
5598 /* Set "local" forwarding info. */
5599 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5600 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5601 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5602 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5603 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5604 mac
->fwd_info
.local
.vid
= vid
;
5607 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5609 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5611 /* Inform BGP if required. */
5613 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5614 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5622 * Handle message from client to delete a remote VTEP for a VNI.
5624 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
5625 struct zebra_vrf
*zvrf
)
5630 struct in_addr vtep_ip
;
5632 zebra_vtep_t
*zvtep
;
5633 struct interface
*ifp
;
5634 struct zebra_if
*zif
;
5636 if (!is_evpn_enabled()) {
5637 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5638 __PRETTY_FUNCTION__
);
5642 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5643 zlog_err("Recv MACIP DEL for non-default VRF %u",
5650 while (l
< length
) {
5651 /* Obtain each remote VTEP and process. */
5652 STREAM_GETL(s
, vni
);
5654 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5655 l
+= IPV4_MAX_BYTELEN
;
5657 if (IS_ZEBRA_DEBUG_VXLAN
)
5658 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5659 inet_ntoa(vtep_ip
), vni
,
5660 zebra_route_string(client
->proto
));
5662 /* Locate VNI hash entry - expected to exist. */
5663 zvni
= zvni_lookup(vni
);
5665 if (IS_ZEBRA_DEBUG_VXLAN
)
5667 "Failed to locate VNI hash upon remote VTEP DEL, "
5673 ifp
= zvni
->vxlan_if
;
5676 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5682 /* If down or not mapped to a bridge, we're done. */
5683 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5686 /* If the remote VTEP does not exist, there's nothing more to
5688 * Otherwise, uninstall any remote MACs pointing to this VTEP
5690 * then, the VTEP entry itself and remove it.
5692 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5696 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5697 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5698 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5699 zvni_vtep_del(zvni
, zvtep
);
5707 * Handle message from client to add a remote VTEP for a VNI.
5709 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
5710 struct zebra_vrf
*zvrf
)
5715 struct in_addr vtep_ip
;
5717 struct interface
*ifp
;
5718 struct zebra_if
*zif
;
5720 if (!is_evpn_enabled()) {
5721 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5722 __PRETTY_FUNCTION__
);
5726 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5727 zlog_err("Recv MACIP ADD for non-default VRF %u",
5734 while (l
< length
) {
5735 /* Obtain each remote VTEP and process. */
5736 STREAM_GETL(s
, vni
);
5738 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5739 l
+= IPV4_MAX_BYTELEN
;
5741 if (IS_ZEBRA_DEBUG_VXLAN
)
5742 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5743 inet_ntoa(vtep_ip
), vni
,
5744 zebra_route_string(client
->proto
));
5746 /* Locate VNI hash entry - expected to exist. */
5747 zvni
= zvni_lookup(vni
);
5750 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5755 ifp
= zvni
->vxlan_if
;
5758 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5765 /* If down or not mapped to a bridge, we're done. */
5766 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5769 /* If the remote VTEP already exists,
5770 there's nothing more to do. */
5771 if (zvni_vtep_find(zvni
, &vtep_ip
))
5774 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5776 "Failed to add remote VTEP, VNI %u zvni %p",
5781 zvni_vtep_install(zvni
, &vtep_ip
);
5789 * Add/Del gateway macip to evpn
5791 * 1. SVI interface on a vlan aware bridge
5792 * 2. SVI interface on a vlan unaware bridge
5793 * 3. vrr interface (MACVLAN) associated to a SVI
5794 * We advertise macip routes for an interface if it is associated to VxLan vlan
5796 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5800 struct ethaddr macaddr
;
5801 zebra_vni_t
*zvni
= NULL
;
5803 memset(&ip
, 0, sizeof(struct ipaddr
));
5804 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5806 /* Check if EVPN is enabled. */
5807 if (!is_evpn_enabled())
5810 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5811 struct interface
*svi_if
=
5812 NULL
; /* SVI corresponding to the MACVLAN */
5813 struct zebra_if
*ifp_zif
=
5814 NULL
; /* Zebra daemon specific info for MACVLAN */
5815 struct zebra_if
*svi_if_zif
=
5816 NULL
; /* Zebra daemon specific info for SVI*/
5818 ifp_zif
= ifp
->info
;
5823 * for a MACVLAN interface the link represents the svi_if
5825 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5826 ifp_zif
->link_ifindex
);
5828 zlog_err("MACVLAN %s(%u) without link information",
5829 ifp
->name
, ifp
->ifindex
);
5833 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5835 * If it is a vlan aware bridge then the link gives the
5836 * bridge information
5838 struct interface
*svi_if_link
= NULL
;
5840 svi_if_zif
= svi_if
->info
;
5842 svi_if_link
= if_lookup_by_index_per_ns(
5843 zebra_ns_lookup(NS_DEFAULT
),
5844 svi_if_zif
->link_ifindex
);
5845 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5847 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5849 * If it is a vlan unaware bridge then svi is the bridge
5852 zvni
= zvni_from_svi(svi_if
, svi_if
);
5854 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5855 struct zebra_if
*svi_if_zif
=
5856 NULL
; /* Zebra daemon specific info for SVI */
5857 struct interface
*svi_if_link
=
5858 NULL
; /* link info for the SVI = bridge info */
5860 svi_if_zif
= ifp
->info
;
5861 svi_if_link
= if_lookup_by_index_per_ns(
5862 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5863 if (svi_if_zif
&& svi_if_link
)
5864 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5865 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5866 zvni
= zvni_from_svi(ifp
, ifp
);
5872 if (!zvni
->vxlan_if
) {
5873 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5879 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5881 if (p
->family
== AF_INET
) {
5882 ip
.ipa_type
= IPADDR_V4
;
5883 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5884 sizeof(struct in_addr
));
5885 } else if (p
->family
== AF_INET6
) {
5886 ip
.ipa_type
= IPADDR_V6
;
5887 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5888 sizeof(struct in6_addr
));
5893 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5895 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5901 * Handle SVI interface going down.
5902 * SVI can be associated to either L3-VNI or L2-VNI.
5903 * For L2-VNI: At this point, this is a NOP since
5904 * the kernel deletes the neighbor entries on this SVI (if any).
5905 * We only need to update the vrf corresponding to zvni.
5906 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5909 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5911 zebra_l3vni_t
*zl3vni
= NULL
;
5913 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5916 /* process l3-vni down */
5917 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5919 /* remove association with svi-if */
5920 zl3vni
->svi_if
= NULL
;
5922 zebra_vni_t
*zvni
= NULL
;
5924 /* since we dont have svi corresponding to zvni, we associate it
5925 * to default vrf. Note: the corresponding neigh entries on the
5926 * SVI would have already been deleted */
5927 zvni
= zvni_from_svi(ifp
, link_if
);
5929 zvni
->vrf_id
= VRF_DEFAULT
;
5931 /* update the tenant vrf in BGP */
5932 zvni_send_add_to_client(zvni
);
5939 * Handle SVI interface coming up.
5940 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5942 * For L2-VNI: we need to install any remote neighbors entried (used for
5944 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5946 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5948 zebra_vni_t
*zvni
= NULL
;
5949 zebra_l3vni_t
*zl3vni
= NULL
;
5951 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5954 /* associate with svi */
5955 zl3vni
->svi_if
= ifp
;
5957 /* process oper-up */
5958 if (is_l3vni_oper_up(zl3vni
))
5959 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5962 /* process SVI up for l2-vni */
5963 struct neigh_walk_ctx n_wctx
;
5965 zvni
= zvni_from_svi(ifp
, link_if
);
5969 if (!zvni
->vxlan_if
) {
5970 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5975 if (IS_ZEBRA_DEBUG_VXLAN
)
5976 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5977 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5978 vrf_id_to_name(ifp
->vrf_id
));
5980 /* update the vrf information for l2-vni and inform bgp */
5981 zvni
->vrf_id
= ifp
->vrf_id
;
5982 zvni_send_add_to_client(zvni
);
5984 /* Install any remote neighbors for this VNI. */
5985 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5987 hash_iterate(zvni
->neigh_table
,
5988 zvni_install_neigh_hash
,
5996 * Handle VxLAN interface down
5998 int zebra_vxlan_if_down(struct interface
*ifp
)
6001 struct zebra_if
*zif
= NULL
;
6002 struct zebra_l2info_vxlan
*vxl
= NULL
;
6003 zebra_l3vni_t
*zl3vni
= NULL
;
6006 /* Check if EVPN is enabled. */
6007 if (!is_evpn_enabled())
6012 vxl
= &zif
->l2info
.vxl
;
6015 zl3vni
= zl3vni_lookup(vni
);
6017 /* process-if-down for l3-vni */
6018 if (IS_ZEBRA_DEBUG_VXLAN
)
6019 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
6020 ifp
->name
, ifp
->ifindex
, vni
);
6022 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6024 /* process if-down for l2-vni */
6025 if (IS_ZEBRA_DEBUG_VXLAN
)
6026 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
6027 ifp
->name
, ifp
->ifindex
, vni
);
6029 /* Locate hash entry; it is expected to exist. */
6030 zvni
= zvni_lookup(vni
);
6033 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6034 ifp
->name
, ifp
->ifindex
, vni
);
6038 assert(zvni
->vxlan_if
== ifp
);
6040 /* Delete this VNI from BGP. */
6041 zvni_send_del_to_client(zvni
->vni
);
6043 /* Free up all neighbors and MACs, if any. */
6044 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6045 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6047 /* Free up all remote VTEPs, if any. */
6048 zvni_vtep_del_all(zvni
, 1);
6054 * Handle VxLAN interface up - update BGP if required.
6056 int zebra_vxlan_if_up(struct interface
*ifp
)
6059 struct zebra_if
*zif
= NULL
;
6060 struct zebra_l2info_vxlan
*vxl
= NULL
;
6061 zebra_vni_t
*zvni
= NULL
;
6062 zebra_l3vni_t
*zl3vni
= NULL
;
6064 /* Check if EVPN is enabled. */
6065 if (!is_evpn_enabled())
6070 vxl
= &zif
->l2info
.vxl
;
6073 zl3vni
= zl3vni_lookup(vni
);
6076 if (IS_ZEBRA_DEBUG_VXLAN
)
6077 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
6078 ifp
->name
, ifp
->ifindex
, vni
);
6080 /* we need to associate with SVI, if any, we can associate with
6081 * svi-if only after association with vxlan-intf is complete
6083 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6085 if (is_l3vni_oper_up(zl3vni
))
6086 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6088 /* Handle L2-VNI add */
6089 struct interface
*vlan_if
= NULL
;
6091 if (IS_ZEBRA_DEBUG_VXLAN
)
6092 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
6093 ifp
->name
, ifp
->ifindex
, vni
);
6095 /* Locate hash entry; it is expected to exist. */
6096 zvni
= zvni_lookup(vni
);
6099 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6100 ifp
->name
, ifp
->ifindex
, vni
);
6104 assert(zvni
->vxlan_if
== ifp
);
6105 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6106 zif
->brslave_info
.br_if
);
6108 zvni
->vrf_id
= vlan_if
->vrf_id
;
6109 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6111 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6114 /* If part of a bridge, inform BGP about this VNI. */
6115 /* Also, read and populate local MACs and neighbors. */
6116 if (zif
->brslave_info
.br_if
) {
6117 zvni_send_add_to_client(zvni
);
6118 zvni_read_mac_neigh(zvni
, ifp
);
6126 * Handle VxLAN interface delete. Locate and remove entry in hash table
6127 * and update BGP, if required.
6129 int zebra_vxlan_if_del(struct interface
*ifp
)
6132 struct zebra_if
*zif
= NULL
;
6133 struct zebra_l2info_vxlan
*vxl
= NULL
;
6134 zebra_vni_t
*zvni
= NULL
;
6135 zebra_l3vni_t
*zl3vni
= NULL
;
6137 /* Check if EVPN is enabled. */
6138 if (!is_evpn_enabled())
6143 vxl
= &zif
->l2info
.vxl
;
6146 zl3vni
= zl3vni_lookup(vni
);
6149 if (IS_ZEBRA_DEBUG_VXLAN
)
6150 zlog_debug("Del L3-VNI %u intf %s(%u)",
6151 vni
, ifp
->name
, ifp
->ifindex
);
6153 /* process oper-down for l3-vni */
6154 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6156 /* remove the association with vxlan_if */
6157 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6158 zl3vni
->vxlan_if
= NULL
;
6161 /* process if-del for l2-vni*/
6162 if (IS_ZEBRA_DEBUG_VXLAN
)
6163 zlog_debug("Del L2-VNI %u intf %s(%u)",
6164 vni
, ifp
->name
, ifp
->ifindex
);
6166 /* Locate hash entry; it is expected to exist. */
6167 zvni
= zvni_lookup(vni
);
6170 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6171 ifp
->name
, ifp
->ifindex
, vni
);
6175 /* remove from l3-vni list */
6176 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6178 listnode_delete(zl3vni
->l2vnis
, zvni
);
6180 /* Delete VNI from BGP. */
6181 zvni_send_del_to_client(zvni
->vni
);
6183 /* Free up all neighbors and MAC, if any. */
6184 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6185 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6187 /* Free up all remote VTEPs, if any. */
6188 zvni_vtep_del_all(zvni
, 0);
6190 /* Delete the hash entry. */
6191 if (zvni_del(zvni
)) {
6192 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6193 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6201 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6203 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
6206 struct zebra_if
*zif
= NULL
;
6207 struct zebra_l2info_vxlan
*vxl
= NULL
;
6208 zebra_vni_t
*zvni
= NULL
;
6209 zebra_l3vni_t
*zl3vni
= NULL
;
6211 /* Check if EVPN is enabled. */
6212 if (!is_evpn_enabled())
6217 vxl
= &zif
->l2info
.vxl
;
6220 zl3vni
= zl3vni_lookup(vni
);
6223 if (IS_ZEBRA_DEBUG_VXLAN
)
6225 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6226 vni
, ifp
->name
, ifp
->ifindex
,
6227 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6228 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6230 /* Removed from bridge? Cleanup and return */
6231 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6232 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6233 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6237 /* access-vlan change - process oper down, associate with new
6238 * svi_if and then process oper up again
6240 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6241 if (if_is_operative(ifp
)) {
6242 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6243 zl3vni
->svi_if
= NULL
;
6244 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6245 if (is_l3vni_oper_up(zl3vni
))
6246 zebra_vxlan_process_l3vni_oper_up(
6251 /* if we have a valid new master, process l3-vni oper up */
6252 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6253 if (is_l3vni_oper_up(zl3vni
))
6254 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6258 /* Update VNI hash. */
6259 zvni
= zvni_lookup(vni
);
6262 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6263 ifp
->name
, ifp
->ifindex
, vni
);
6267 if (IS_ZEBRA_DEBUG_VXLAN
)
6269 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6270 vni
, ifp
->name
, ifp
->ifindex
,
6271 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6272 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6274 /* Removed from bridge? Cleanup and return */
6275 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6276 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6277 /* Delete from client, remove all remote VTEPs */
6278 /* Also, free up all MACs and neighbors. */
6279 zvni_send_del_to_client(zvni
->vni
);
6280 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6281 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6282 zvni_vtep_del_all(zvni
, 1);
6286 /* Handle other changes. */
6287 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6288 /* Remove all existing local neigh and MACs for this VNI
6289 * (including from BGP)
6291 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6292 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6295 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6296 zvni
->vxlan_if
= ifp
;
6298 /* Take further actions needed.
6299 * Note that if we are here, there is a change of interest.
6301 /* If down or not mapped to a bridge, we're done. */
6302 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6305 /* Inform BGP, if there is a change of interest. */
6307 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6308 zvni_send_add_to_client(zvni
);
6310 /* If there is a valid new master or a VLAN mapping change,
6311 * read and populate local MACs and neighbors.
6312 * Also, reinstall any remote MACs and neighbors
6313 * for this VNI (based on new VLAN).
6315 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6316 zvni_read_mac_neigh(zvni
, ifp
);
6317 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6318 struct mac_walk_ctx m_wctx
;
6319 struct neigh_walk_ctx n_wctx
;
6321 zvni_read_mac_neigh(zvni
, ifp
);
6323 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6325 hash_iterate(zvni
->mac_table
,
6326 zvni_install_mac_hash
,
6329 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6331 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6340 * Handle VxLAN interface add.
6342 int zebra_vxlan_if_add(struct interface
*ifp
)
6345 struct zebra_if
*zif
= NULL
;
6346 struct zebra_l2info_vxlan
*vxl
= NULL
;
6347 zebra_vni_t
*zvni
= NULL
;
6348 zebra_l3vni_t
*zl3vni
= NULL
;
6350 /* Check if EVPN is enabled. */
6351 if (!is_evpn_enabled())
6356 vxl
= &zif
->l2info
.vxl
;
6359 zl3vni
= zl3vni_lookup(vni
);
6362 /* process if-add for l3-vni*/
6363 if (IS_ZEBRA_DEBUG_VXLAN
)
6365 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6366 vni
, ifp
->name
, ifp
->ifindex
,
6367 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6368 zif
->brslave_info
.bridge_ifindex
);
6370 /* associate with vxlan_if */
6371 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6372 zl3vni
->vxlan_if
= ifp
;
6374 /* Associate with SVI, if any. We can associate with svi-if only
6375 * after association with vxlan_if is complete */
6376 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6378 if (is_l3vni_oper_up(zl3vni
))
6379 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6382 /* process if-add for l2-vni */
6383 struct interface
*vlan_if
= NULL
;
6385 /* Create or update VNI hash. */
6386 zvni
= zvni_lookup(vni
);
6388 zvni
= zvni_add(vni
);
6391 "Failed to add VNI hash, IF %s(%u) VNI %u",
6392 ifp
->name
, ifp
->ifindex
, vni
);
6397 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6398 zvni
->vxlan_if
= ifp
;
6399 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6400 zif
->brslave_info
.br_if
);
6402 zvni
->vrf_id
= vlan_if
->vrf_id
;
6403 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6405 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6408 if (IS_ZEBRA_DEBUG_VXLAN
)
6410 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6412 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
) :
6414 ifp
->name
, ifp
->ifindex
,
6415 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6416 zif
->brslave_info
.bridge_ifindex
);
6418 /* If down or not mapped to a bridge, we're done. */
6419 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6423 zvni_send_add_to_client(zvni
);
6425 /* Read and populate local MACs and neighbors */
6426 zvni_read_mac_neigh(zvni
, ifp
);
6432 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
,
6434 char *err
, int err_str_sz
,
6437 zebra_l3vni_t
*zl3vni
= NULL
;
6438 struct zebra_vrf
*zvrf_default
= NULL
;
6440 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6444 if (IS_ZEBRA_DEBUG_VXLAN
)
6445 zlog_debug("vrf %s vni %u %s",
6448 add
? "ADD" : "DEL");
6452 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6454 /* check if the vni is already present under zvrf */
6456 snprintf(err
, err_str_sz
,
6457 "VNI is already configured under the vrf");
6461 /* check if this VNI is already present in the system */
6462 zl3vni
= zl3vni_lookup(vni
);
6464 snprintf(err
, err_str_sz
,
6465 "VNI is already configured as L3-VNI");
6469 /* add the L3-VNI to the global table */
6470 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6472 snprintf(err
, err_str_sz
,
6473 "Could not add L3-VNI");
6477 /* associate the vrf with vni */
6480 /* associate with vxlan-intf;
6481 * we need to associate with the vxlan-intf first
6483 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6485 /* associate with corresponding SVI interface, we can associate
6486 * with svi-if only after vxlan interface association is
6489 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6491 /* formulate l2vni list */
6492 hash_iterate(zvrf_default
->vni_table
,
6493 zvni_add_to_l3vni_list
, zl3vni
);
6495 if (is_l3vni_oper_up(zl3vni
))
6496 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6499 zl3vni
= zl3vni_lookup(vni
);
6501 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6505 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6507 /* delete and uninstall all rmacs */
6508 hash_iterate(zl3vni
->rmac_table
,
6509 zl3vni_del_rmac_hash_entry
,
6512 /* delete and uninstall all next-hops */
6513 hash_iterate(zl3vni
->nh_table
,
6514 zl3vni_del_nh_hash_entry
,
6520 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6525 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6527 zebra_l3vni_t
*zl3vni
= NULL
;
6530 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6534 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6535 if (is_l3vni_oper_up(zl3vni
))
6536 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6540 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6542 zebra_l3vni_t
*zl3vni
= NULL
;
6545 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6549 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6550 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6554 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6556 zebra_l3vni_t
*zl3vni
= NULL
;
6560 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6566 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6572 * Handle message from client to enable/disable advertisement of g/w macip
6575 int zebra_vxlan_advertise_subnet(struct zserv
*client
, u_short length
,
6576 struct zebra_vrf
*zvrf
)
6581 zebra_vni_t
*zvni
= NULL
;
6582 struct interface
*ifp
= NULL
;
6583 struct zebra_if
*zif
= NULL
;
6584 struct zebra_l2info_vxlan zl2_info
;
6585 struct interface
*vlan_if
= NULL
;
6587 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6588 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6594 advertise
= stream_getc(s
);
6595 vni
= stream_get3(s
);
6597 zvni
= zvni_lookup(vni
);
6601 if (zvni
->advertise_subnet
== advertise
)
6604 if (IS_ZEBRA_DEBUG_VXLAN
)
6606 "EVPN subnet Adv %s on VNI %d , currently %s",
6607 advertise
? "enabled" : "disabled", vni
,
6608 zvni
->advertise_subnet
? "enabled" : "disabled");
6611 zvni
->advertise_subnet
= advertise
;
6613 ifp
= zvni
->vxlan_if
;
6619 /* If down or not mapped to a bridge, we're done. */
6620 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6623 zl2_info
= zif
->l2info
.vxl
;
6625 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6626 zif
->brslave_info
.br_if
);
6630 if (zvni
->advertise_subnet
)
6631 zvni_advertise_subnet(zvni
, vlan_if
, 1);
6633 zvni_advertise_subnet(zvni
, vlan_if
, 0);
6639 * Handle message from client to enable/disable advertisement of g/w macip
6642 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
6643 struct zebra_vrf
*zvrf
)
6648 zebra_vni_t
*zvni
= NULL
;
6649 struct interface
*ifp
= NULL
;
6651 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6652 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6658 STREAM_GETC(s
, advertise
);
6659 STREAM_GET(&vni
, s
, 3);
6662 if (IS_ZEBRA_DEBUG_VXLAN
)
6663 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6664 advertise
? "enabled" : "disabled",
6665 advertise_gw_macip_enabled(NULL
)
6669 if (zvrf
->advertise_gw_macip
== advertise
)
6672 zvrf
->advertise_gw_macip
= advertise
;
6674 if (advertise_gw_macip_enabled(zvni
))
6675 hash_iterate(zvrf
->vni_table
,
6676 zvni_gw_macip_add_for_vni_hash
, NULL
);
6678 hash_iterate(zvrf
->vni_table
,
6679 zvni_gw_macip_del_for_vni_hash
, NULL
);
6682 struct zebra_if
*zif
= NULL
;
6683 struct zebra_l2info_vxlan zl2_info
;
6684 struct interface
*vlan_if
= NULL
;
6685 struct interface
*vrr_if
= NULL
;
6687 if (IS_ZEBRA_DEBUG_VXLAN
)
6689 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6690 advertise
? "enabled" : "disabled", vni
,
6691 advertise_gw_macip_enabled(zvni
)
6695 zvni
= zvni_lookup(vni
);
6699 if (zvni
->advertise_gw_macip
== advertise
)
6702 zvni
->advertise_gw_macip
= advertise
;
6704 ifp
= zvni
->vxlan_if
;
6710 /* If down or not mapped to a bridge, we're done. */
6711 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6714 zl2_info
= zif
->l2info
.vxl
;
6716 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6717 zif
->brslave_info
.br_if
);
6721 if (advertise_gw_macip_enabled(zvni
)) {
6722 /* Add primary SVI MAC-IP */
6723 zvni_add_macip_for_intf(vlan_if
, zvni
);
6725 /* Add VRR MAC-IP - if any*/
6726 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6728 zvni_add_macip_for_intf(vrr_if
, zvni
);
6730 /* Del primary MAC-IP */
6731 zvni_del_macip_for_intf(vlan_if
, zvni
);
6733 /* Del VRR MAC-IP - if any*/
6734 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6736 zvni_del_macip_for_intf(vrr_if
, zvni
);
6746 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6747 * When enabled, the VNI hash table will be built and MAC FDB table read;
6748 * when disabled, the entries should be deleted and remote VTEPs and MACs
6749 * uninstalled from the kernel.
6751 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
6752 u_short length
, struct zebra_vrf
*zvrf
)
6754 struct stream
*s
= NULL
;
6756 struct zebra_ns
*zns
= NULL
;
6758 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6759 zlog_err("EVPN VNI Adv for non-default VRF %u",
6765 STREAM_GETC(s
, advertise
);
6767 if (IS_ZEBRA_DEBUG_VXLAN
)
6768 zlog_debug("EVPN VNI Adv %s, currently %s",
6769 advertise
? "enabled" : "disabled",
6770 is_evpn_enabled() ? "enabled" : "disabled");
6772 if (zvrf
->advertise_all_vni
== advertise
)
6775 zvrf
->advertise_all_vni
= advertise
;
6776 if (is_evpn_enabled()) {
6777 /* Build VNI hash table and inform BGP. */
6778 zvni_build_hash_table();
6780 /* Add all SVI (L3 GW) MACs to BGP*/
6781 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6784 /* Read the MAC FDB */
6785 macfdb_read(zvrf
->zns
);
6787 /* Read neighbors */
6788 neigh_read(zvrf
->zns
);
6790 /* Cleanup VTEPs for all VNIs - uninstall from
6791 * kernel and free entries.
6793 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6795 /* cleanup all l3vnis */
6796 zns
= zebra_ns_lookup(NS_DEFAULT
);
6800 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
6808 * Allocate VNI hash table for this VRF and do other initialization.
6809 * NOTE: Currently supported only for default VRF.
6811 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6815 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6816 "Zebra VRF VNI Table");
6819 /* Cleanup VNI info, but don't free the table. */
6820 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
6824 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6827 /* Close all VNI handling */
6828 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6832 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6833 hash_free(zvrf
->vni_table
);
6836 /* init the l3vni table */
6837 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6839 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6840 "Zebra VRF L3 VNI table");
6843 /* free l3vni table */
6844 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6846 hash_free(zns
->l3vni_table
);
6849 /* get the l3vni svi ifindex */
6850 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6852 zebra_l3vni_t
*zl3vni
= NULL
;
6854 zl3vni
= zl3vni_from_vrf(vrf_id
);
6855 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6858 return zl3vni
->svi_if
->ifindex
;