2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 #include "zebra/rib.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
51 DEFINE_MTYPE_STATIC(ZEBRA
, HOST_PREFIX
, "host prefix");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
54 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
55 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
56 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
61 /* static function declarations */
62 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
63 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
64 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
66 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
68 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
70 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
71 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
72 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
73 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
74 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
76 static int zvni_macip_send_msg_to_client(vni_t vni
,
77 struct ethaddr
*macaddr
,
78 struct ipaddr
*ip
, u_char flags
,
80 static unsigned int neigh_hash_keymake(void *p
);
81 static int neigh_cmp(const void *p1
, const void *p2
);
82 static void *zvni_neigh_alloc(void *p
);
83 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
85 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
86 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
87 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
88 struct in_addr
*r_vtep_ip
);
89 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
90 int uninstall
, int upd_client
, u_int32_t flags
);
91 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
92 static int zvni_neigh_send_add_to_client(vni_t vni
,
94 struct ethaddr
*macaddr
, u_char flags
);
95 static int zvni_neigh_send_del_to_client(vni_t vni
,
97 struct ethaddr
*macaddr
, u_char flags
);
98 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
99 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
100 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
101 struct interface
*br_if
);
102 static struct interface
*zvni_map_to_svi(vlanid_t vid
,
103 struct interface
*br_if
);
105 /* l3-vni next-hop neigh related APIs */
106 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
108 static void *zl3vni_nh_alloc(void *p
);
109 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
110 struct ipaddr
*vtep_ip
,
111 struct ethaddr
*rmac
);
112 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
113 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
114 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
116 /* l3-vni rmac related APIs */
117 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
118 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
119 struct ethaddr
*rmac
);
120 static void *zl3vni_rmac_alloc(void *p
);
121 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
122 struct ethaddr
*rmac
);
123 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
124 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
125 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
128 /* l3-vni related APIs*/
129 static int is_vni_l3(vni_t
);
130 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
131 static void *zl3vni_alloc(void *p
);
132 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
133 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
134 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
135 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
136 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
137 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
138 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
140 static unsigned int mac_hash_keymake(void *p
);
141 static int mac_cmp(const void *p1
, const void *p2
);
142 static void *zvni_mac_alloc(void *p
);
143 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
144 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
145 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
146 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
147 struct in_addr
*r_vtep_ip
);
148 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
149 int uninstall
, int upd_client
, u_int32_t flags
);
150 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
151 static int zvni_mac_send_add_to_client(vni_t vni
,
152 struct ethaddr
*macaddr
, u_char flags
);
153 static int zvni_mac_send_del_to_client(vni_t vni
,
154 struct ethaddr
*macaddr
, u_char flags
);
155 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
156 struct interface
*br_if
, vlanid_t vid
);
157 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
158 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
159 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
161 static unsigned int vni_hash_keymake(void *p
);
162 static int vni_hash_cmp(const void *p1
, const void *p2
);
163 static void *zvni_alloc(void *p
);
164 static zebra_vni_t
*zvni_lookup(vni_t vni
);
165 static zebra_vni_t
*zvni_add(vni_t vni
);
166 static int zvni_del(zebra_vni_t
*zvni
);
167 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
168 static int zvni_send_del_to_client(vni_t vni
);
169 static void zvni_build_hash_table();
170 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
171 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
172 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
173 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
174 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
175 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
176 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
177 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
178 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
179 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
180 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
181 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
183 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
184 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
185 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
188 /* Private functions */
191 * Return number of valid MACs in a VNI's MAC hash table - all
192 * remote MACs and non-internal (auto) local MACs count.
194 static u_int32_t
num_valid_macs(zebra_vni_t
*zvni
)
197 u_int32_t num_macs
= 0;
199 struct hash_backet
*hb
;
202 hash
= zvni
->mac_table
;
205 for (i
= 0; i
< hash
->size
; i
++) {
206 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
207 mac
= (zebra_mac_t
*)hb
->data
;
208 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
209 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
217 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
219 struct zebra_vrf
*zvrf
;
221 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
222 if (zvrf
&& zvrf
->advertise_gw_macip
)
225 if (zvni
&& zvni
->advertise_gw_macip
)
232 * Helper function to determine maximum width of neighbor IP address for
233 * display - just because we're dealing with IPv6 addresses that can
236 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
239 char buf
[INET6_ADDRSTRLEN
];
240 struct neigh_walk_ctx
*wctx
= ctxt
;
243 n
= (zebra_neigh_t
*)backet
->data
;
247 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
248 if (width
> wctx
->addr_width
)
249 wctx
->addr_width
= width
;
253 * Print a specific neighbor entry.
255 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
258 char buf1
[ETHER_ADDR_STRLEN
];
259 char buf2
[INET6_ADDRSTRLEN
];
261 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
262 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
263 vty
= (struct vty
*)ctxt
;
265 vty_out(vty
, "IP: %s\n",
266 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
267 vty_out(vty
, " MAC: %s",
268 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
270 json_object_string_add(json
, "ip", buf2
);
271 json_object_string_add(json
, "mac", buf1
);
273 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
275 vty_out(vty
, " Remote VTEP: %s",
276 inet_ntoa(n
->r_vtep_ip
));
278 json_object_string_add(json
, "remoteVtep",
279 inet_ntoa(n
->r_vtep_ip
));
281 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
284 vty_out(vty
, " State: %s",
285 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
294 * Print neighbor hash entry - called for display of all neighbors.
296 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
299 json_object
*json_vni
= NULL
, *json_row
= NULL
;
301 char buf1
[ETHER_ADDR_STRLEN
];
302 char buf2
[INET6_ADDRSTRLEN
];
303 struct neigh_walk_ctx
*wctx
= ctxt
;
306 json_vni
= wctx
->json
;
307 n
= (zebra_neigh_t
*)backet
->data
;
312 json_row
= json_object_new_object();
314 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
315 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
316 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
317 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
318 if (json_vni
== NULL
) {
319 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
320 buf2
, "local", buf1
);
322 json_object_string_add(json_row
, "type", "local");
323 json_object_string_add(json_row
, "mac", buf1
);
327 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
328 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
329 if (json_vni
== NULL
) {
330 if (wctx
->count
== 0)
332 "%*s %-6s %-17s %-21s\n",
335 "MAC", "Remote VTEP");
336 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
337 -wctx
->addr_width
, buf2
,
339 inet_ntoa(n
->r_vtep_ip
));
341 json_object_string_add(json_row
, "type",
343 json_object_string_add(json_row
, "mac",
345 json_object_string_add(
346 json_row
, "remoteVtep",
347 inet_ntoa(n
->r_vtep_ip
));
352 if (json_vni
== NULL
) {
353 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
354 -wctx
->addr_width
, buf2
, "remote", buf1
,
355 inet_ntoa(n
->r_vtep_ip
));
357 json_object_string_add(json_row
, "type",
359 json_object_string_add(json_row
, "mac", buf1
);
360 json_object_string_add(json_row
, "remoteVtep",
361 inet_ntoa(n
->r_vtep_ip
));
368 json_object_object_add(json_vni
, buf2
, json_row
);
372 * Print neighbors for all VNI.
374 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
378 json_object
*json
= NULL
, *json_vni
= NULL
;
381 struct neigh_walk_ctx wctx
;
382 char vni_str
[VNI_STR_LEN
];
384 vty
= (struct vty
*)args
[0];
385 json
= (json_object
*)args
[1];
387 zvni
= (zebra_vni_t
*)backet
->data
;
390 vty_out(vty
, "{}\n");
393 num_neigh
= hashcount(zvni
->neigh_table
);
396 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
397 zvni
->vni
, num_neigh
);
399 json_vni
= json_object_new_object();
400 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
401 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
405 json_object_object_add(json
, vni_str
, json_vni
);
409 /* Since we have IPv6 addresses to deal with which can vary widely in
410 * size, we try to be a bit more elegant in display by first computing
413 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
416 wctx
.addr_width
= 15;
417 wctx
.json
= json_vni
;
418 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
421 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
422 "Type", "MAC", "Remote VTEP");
423 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
426 json_object_object_add(json
, vni_str
, json_vni
);
429 /* print a specific next hop for an l3vni */
430 static void zl3vni_print_nh(zebra_neigh_t
*n
,
434 char buf1
[ETHER_ADDR_STRLEN
];
435 char buf2
[INET6_ADDRSTRLEN
];
436 struct listnode
*node
= NULL
;
437 struct prefix
*p
= NULL
;
438 json_object
*json_hosts
= NULL
;
441 vty_out(vty
, "Ip: %s\n",
442 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
443 vty_out(vty
, " RMAC: %s\n",
444 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
445 vty_out(vty
, " Host-List:\n");
446 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
447 vty_out(vty
, " %s\n",
448 prefix2str(p
, buf2
, sizeof(buf2
)));
450 json_hosts
= json_object_new_array();
451 json_object_string_add(json
, "ip",
452 ipaddr2str(&(n
->ip
), buf2
,
454 json_object_string_add(json
, "rmac",
455 prefix_mac2str(&n
->emac
, buf2
,
457 for (ALL_LIST_ELEMENTS_RO(n
->host_list
, node
, p
))
458 json_object_array_add(json_hosts
,
459 json_object_new_string(
462 json_object_object_add(json
, "hosts", json_hosts
);
466 /* Print a specific RMAC entry */
467 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
,
471 char buf1
[ETHER_ADDR_STRLEN
];
472 char buf2
[PREFIX_STRLEN
];
473 struct listnode
*node
= NULL
;
474 struct prefix
*p
= NULL
;
475 json_object
*json_hosts
= NULL
;
478 vty_out(vty
, "MAC: %s\n",
479 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
480 vty_out(vty
, " Remote VTEP: %s\n",
481 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
482 vty_out(vty
, " Host-List:\n");
483 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
484 vty_out(vty
, " %s\n",
485 prefix2str(p
, buf2
, sizeof(buf2
)));
487 json_hosts
= json_object_new_array();
488 json_object_string_add(json
, "Rmac",
489 prefix_mac2str(&zrmac
->macaddr
,
492 json_object_string_add(json
, "vtep-ip",
493 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
494 for (ALL_LIST_ELEMENTS_RO(zrmac
->host_list
, node
, p
))
495 json_object_array_add(json_hosts
,
496 json_object_new_string(
499 json_object_object_add(json
, "hosts", json_hosts
);
504 * Print a specific MAC entry.
506 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
509 zebra_neigh_t
*n
= NULL
;
510 struct listnode
*node
= NULL
;
512 char buf2
[INET6_ADDRSTRLEN
];
514 vty
= (struct vty
*)ctxt
;
515 vty_out(vty
, "MAC: %s",
516 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
517 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
518 struct zebra_ns
*zns
;
519 struct interface
*ifp
;
522 ifindex
= mac
->fwd_info
.local
.ifindex
;
523 zns
= zebra_ns_lookup(NS_DEFAULT
);
524 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
525 if (!ifp
) // unexpected
527 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
528 if (mac
->fwd_info
.local
.vid
)
529 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
530 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
531 vty_out(vty
, " Remote VTEP: %s",
532 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
533 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
534 vty_out(vty
, " Auto Mac ");
538 /* print all the associated neigh */
539 vty_out(vty
, " Neighbors:\n");
540 if (!listcount(mac
->neigh_list
))
541 vty_out(vty
, " No Neighbors\n");
543 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
544 vty_out(vty
, " %s %s\n",
545 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
546 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
547 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
558 * Print MAC hash entry - called for display of all MACs.
560 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
563 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
566 struct mac_walk_ctx
*wctx
= ctxt
;
569 json_mac_hdr
= wctx
->json
;
570 mac
= (zebra_mac_t
*)backet
->data
;
574 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
577 json_mac
= json_object_new_object();
579 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
580 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
581 struct zebra_ns
*zns
;
583 struct interface
*ifp
;
586 zns
= zebra_ns_lookup(NS_DEFAULT
);
587 ifindex
= mac
->fwd_info
.local
.ifindex
;
588 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
589 if (!ifp
) // unexpected
591 vid
= mac
->fwd_info
.local
.vid
;
592 if (json_mac_hdr
== NULL
)
593 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
596 json_object_string_add(json_mac
, "type", "local");
597 json_object_string_add(json_mac
, "intf", ifp
->name
);
600 if (json_mac_hdr
== NULL
)
601 vty_out(vty
, " %-5u", vid
);
603 json_object_int_add(json_mac
, "vlan", vid
);
605 if (json_mac_hdr
== NULL
)
608 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
610 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
611 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
612 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
614 if (wctx
->count
== 0) {
615 if (json_mac_hdr
== NULL
) {
616 vty_out(vty
, "\nVNI %u\n\n",
619 "%-17s %-6s %-21s %-5s\n",
625 if (json_mac_hdr
== NULL
)
626 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
628 inet_ntoa(mac
->fwd_info
631 json_object_string_add(json_mac
, "type",
633 json_object_string_add(
634 json_mac
, "remoteVtep",
635 inet_ntoa(mac
->fwd_info
637 json_object_object_add(json_mac_hdr
,
643 if (json_mac_hdr
== NULL
)
644 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
646 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
648 json_object_string_add(json_mac
, "type",
650 json_object_string_add(
651 json_mac
, "remoteVtep",
652 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
653 json_object_object_add(json_mac_hdr
, buf1
,
662 * Print MACs for all VNI.
664 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
667 json_object
*json
= NULL
, *json_vni
= NULL
;
668 json_object
*json_mac
= NULL
;
671 struct mac_walk_ctx
*wctx
= ctxt
;
672 char vni_str
[VNI_STR_LEN
];
674 vty
= (struct vty
*)wctx
->vty
;
675 json
= (struct json_object
*)wctx
->json
;
677 zvni
= (zebra_vni_t
*)backet
->data
;
680 vty_out(vty
, "{}\n");
685 /*We are iterating over a new VNI, set the count to 0*/
688 num_macs
= num_valid_macs(zvni
);
693 json_vni
= json_object_new_object();
694 json_mac
= json_object_new_object();
695 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
698 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
700 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
701 zvni
->vni
, num_macs
);
702 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
703 "Intf/Remote VTEP", "VLAN");
705 json_object_int_add(json_vni
, "numMacs", num_macs
);
707 /* assign per-vni to wctx->json object to fill macs
708 * under the vni. Re-assign primary json object to fill
709 * next vni information.
711 wctx
->json
= json_mac
;
712 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
716 json_object_object_add(json_vni
, "macs", json_mac
);
717 json_object_object_add(json
, vni_str
, json_vni
);
721 static void zl3vni_print_nh_hash(struct hash_backet
*backet
,
724 struct nh_walk_ctx
*wctx
= NULL
;
725 struct vty
*vty
= NULL
;
726 struct json_object
*json_vni
= NULL
;
727 struct json_object
*json_nh
= NULL
;
728 zebra_neigh_t
*n
= NULL
;
729 char buf1
[ETHER_ADDR_STRLEN
];
730 char buf2
[INET6_ADDRSTRLEN
];
732 wctx
= (struct nh_walk_ctx
*)ctx
;
734 json_vni
= wctx
->json
;
736 json_nh
= json_object_new_object();
737 n
= (zebra_neigh_t
*)backet
->data
;
742 vty_out(vty
, "%-15s %-17s %6d\n",
743 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
744 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
745 listcount(n
->host_list
));
747 json_object_string_add(json_nh
, "nexthop-ip",
748 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
749 json_object_string_add(json_nh
, "rmac",
750 prefix_mac2str(&n
->emac
, buf1
,
752 json_object_int_add(json_nh
, "refCnt", listcount(n
->host_list
));
753 json_object_object_add(json_vni
,
754 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
759 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
762 struct vty
*vty
= NULL
;
763 json_object
*json
= NULL
;
764 json_object
*json_vni
= NULL
;
765 zebra_l3vni_t
*zl3vni
= NULL
;
767 struct nh_walk_ctx wctx
;
768 char vni_str
[VNI_STR_LEN
];
770 vty
= (struct vty
*)args
[0];
771 json
= (struct json_object
*)args
[1];
773 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
776 vty_out(vty
, "{}\n");
780 num_nh
= hashcount(zl3vni
->nh_table
);
785 json_vni
= json_object_new_object();
786 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
790 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n",
791 zl3vni
->vni
, num_nh
);
792 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
795 json_object_int_add(json_vni
, "numNh", num_nh
);
797 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
799 wctx
.json
= json_vni
;
800 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
802 json_object_object_add(json
, vni_str
, json_vni
);
805 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
808 struct vty
*vty
= NULL
;
809 json_object
*json
= NULL
;
810 json_object
*json_vni
= NULL
;
811 zebra_l3vni_t
*zl3vni
= NULL
;
813 struct rmac_walk_ctx wctx
;
814 char vni_str
[VNI_STR_LEN
];
816 vty
= (struct vty
*)args
[0];
817 json
= (struct json_object
*)args
[1];
819 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
822 vty_out(vty
, "{}\n");
826 num_rmacs
= hashcount(zl3vni
->rmac_table
);
831 json_vni
= json_object_new_object();
832 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
836 vty_out(vty
, "\nVNI %u #MACs %u\n\n",
837 zl3vni
->vni
, num_rmacs
);
838 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
839 "Remote VTEP", "Refcnt");
841 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
843 /* assign per-vni to wctx->json object to fill macs
844 * under the vni. Re-assign primary json object to fill
845 * next vni information.
847 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
849 wctx
.json
= json_vni
;
850 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
852 json_object_object_add(json
, vni_str
, json_vni
);
855 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
,
858 zebra_mac_t
*zrmac
= NULL
;
859 struct rmac_walk_ctx
*wctx
= NULL
;
860 struct vty
*vty
= NULL
;
861 struct json_object
*json
= NULL
;
862 struct json_object
*json_rmac
= NULL
;
863 char buf
[ETHER_ADDR_STRLEN
];
865 wctx
= (struct rmac_walk_ctx
*)ctx
;
869 json_rmac
= json_object_new_object();
870 zrmac
= (zebra_mac_t
*)backet
->data
;
875 vty_out(vty
, "%-17s %-21s %-6d\n",
876 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
877 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
),
878 listcount(zrmac
->host_list
));
880 json_object_string_add(json_rmac
, "rmac",
881 prefix_mac2str(&zrmac
->macaddr
, buf
,
883 json_object_string_add(json_rmac
, "vtep-ip",
884 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
885 json_object_int_add(json_rmac
, "refcnt",
886 listcount(zrmac
->host_list
));
887 json_object_object_add(json
,
888 prefix_mac2str(&zrmac
->macaddr
, buf
,
894 /* print a specific L3 VNI entry */
895 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
897 char buf
[ETHER_ADDR_STRLEN
];
898 struct vty
*vty
= NULL
;
899 json_object
*json
= NULL
;
900 zebra_vni_t
*zvni
= NULL
;
901 json_object
*json_vni_list
= NULL
;
902 struct listnode
*node
= NULL
, *nnode
= NULL
;
908 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
909 vty_out(vty
, " Local Vtep Ip: %s",
910 inet_ntoa(zl3vni
->local_vtep_ip
));
911 vty_out(vty
, " Vxlan-Intf: %s\n",
912 zl3vni_vxlan_if_name(zl3vni
));
913 vty_out(vty
, " SVI-If: %s\n",
914 zl3vni_svi_if_name(zl3vni
));
915 vty_out(vty
, " State: %s\n",
916 zl3vni_state2str(zl3vni
));
917 vty_out(vty
, " Vrf: %s\n",
918 zl3vni_vrf_name(zl3vni
));
919 vty_out(vty
, " Rmac: %s\n",
920 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
921 vty_out(vty
, " L2-VNIs: ");
922 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
923 vty_out(vty
, "%u ", zvni
->vni
);
926 json_vni_list
= json_object_new_array();
927 json_object_int_add(json
, "vni", zl3vni
->vni
);
928 json_object_string_add(json
, "local-vtep-ip",
929 inet_ntoa(zl3vni
->local_vtep_ip
));
930 json_object_string_add(json
, "vxlan-intf",
931 zl3vni_vxlan_if_name(zl3vni
));
932 json_object_string_add(json
, "svi-if",
933 zl3vni_svi_if_name(zl3vni
));
934 json_object_string_add(json
, "state",
935 zl3vni_state2str(zl3vni
));
936 json_object_string_add(json
, "vrf",
937 zl3vni_vrf_name(zl3vni
));
938 json_object_string_add(json
, "rmac",
939 zl3vni_rmac2str(zl3vni
, buf
,
941 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
942 json_object_array_add(json_vni_list
,
943 json_object_new_int(zvni
->vni
));
945 json_object_object_add(json
, "l2-vnis", json_vni_list
);
950 * Print a specific VNI entry.
952 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
958 json_object
*json
= NULL
;
959 json_object
*json_vtep_list
= NULL
;
960 json_object
*json_ip_str
= NULL
;
966 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
967 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
969 json_object_int_add(json
, "vni", zvni
->vni
);
970 json_object_string_add(json
, "vrf",
971 vrf_id_to_name(zvni
->vrf_id
));
974 if (!zvni
->vxlan_if
) { // unexpected
976 vty_out(vty
, " VxLAN interface: unknown\n");
979 num_macs
= num_valid_macs(zvni
);
980 num_neigh
= hashcount(zvni
->neigh_table
);
982 vty_out(vty
, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
983 zvni
->vxlan_if
->name
, zvni
->vxlan_if
->ifindex
,
984 inet_ntoa(zvni
->local_vtep_ip
));
986 json_object_string_add(json
, "vxlanInterface",
987 zvni
->vxlan_if
->name
);
988 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
989 json_object_string_add(json
, "vtepIp",
990 inet_ntoa(zvni
->local_vtep_ip
));
991 json_object_string_add(json
, "advertiseGatewayMacip",
992 zvni
->advertise_gw_macip
? "Yes" : "No");
993 json_object_int_add(json
, "numMacs", num_macs
);
994 json_object_int_add(json
, "numArpNd", num_neigh
);
998 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1001 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1003 json_vtep_list
= json_object_new_array();
1004 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1006 vty_out(vty
, " %s\n",
1007 inet_ntoa(zvtep
->vtep_ip
));
1009 json_ip_str
= json_object_new_string(
1010 inet_ntoa(zvtep
->vtep_ip
));
1011 json_object_array_add(json_vtep_list
,
1016 json_object_object_add(json
, "numRemoteVteps",
1021 " Number of MACs (local and remote) known for this VNI: %u\n",
1024 " Number of ARPs (IPv4 and IPv6, local and remote) "
1025 "known for this VNI: %u\n",
1027 vty_out(vty
, " Advertise-gw-macip: %s\n",
1028 zvni
->advertise_gw_macip
? "Yes" : "No");
1032 /* print a L3 VNI hash entry */
1033 static void zl3vni_print_hash(struct hash_backet
*backet
,
1036 char buf
[ETHER_ADDR_STRLEN
];
1037 struct vty
*vty
= NULL
;
1038 json_object
*json
= NULL
;
1039 json_object
*json_vni
= NULL
;
1040 zebra_l3vni_t
*zl3vni
= NULL
;
1042 vty
= (struct vty
*)ctx
[0];
1043 json
= (json_object
*)ctx
[1];
1045 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1050 vty_out(vty
, "%-10u %-15s %-20s %-20s %-5s %-37s %-18s\n",
1052 inet_ntoa(zl3vni
->local_vtep_ip
),
1053 zl3vni_vxlan_if_name(zl3vni
),
1054 zl3vni_svi_if_name(zl3vni
),
1055 zl3vni_state2str(zl3vni
),
1056 zl3vni_vrf_name(zl3vni
),
1057 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
1059 char vni_str
[VNI_STR_LEN
];
1061 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1062 json_vni
= json_object_new_object();
1063 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1064 json_object_string_add(json_vni
, "local-ip",
1065 inet_ntoa(zl3vni
->local_vtep_ip
));
1066 json_object_string_add(json_vni
, "vxlan-if",
1067 zl3vni_vxlan_if_name(zl3vni
));
1068 json_object_string_add(json_vni
, "svi-if",
1069 zl3vni_svi_if_name(zl3vni
));
1070 json_object_string_add(json_vni
, "state",
1071 zl3vni_state2str(zl3vni
));
1072 json_object_string_add(json_vni
, "vrf",
1073 zl3vni_vrf_name(zl3vni
));
1074 json_object_string_add(json_vni
, "rmac",
1075 zl3vni_rmac2str(zl3vni
, buf
,
1077 json_object_object_add(json
, vni_str
, json_vni
);
1083 * Print a VNI hash entry - called for display of all VNIs.
1085 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1089 zebra_vtep_t
*zvtep
;
1090 u_int32_t num_vteps
= 0;
1091 u_int32_t num_macs
= 0;
1092 u_int32_t num_neigh
= 0;
1093 json_object
*json
= NULL
;
1094 json_object
*json_vni
= NULL
;
1095 json_object
*json_ip_str
= NULL
;
1096 json_object
*json_vtep_list
= NULL
;
1101 zvni
= (zebra_vni_t
*)backet
->data
;
1105 zvtep
= zvni
->vteps
;
1108 zvtep
= zvtep
->next
;
1111 num_macs
= num_valid_macs(zvni
);
1112 num_neigh
= hashcount(zvni
->neigh_table
);
1114 vty_out(vty
, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
1116 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1117 inet_ntoa(zvni
->local_vtep_ip
), num_macs
, num_neigh
,
1119 vrf_id_to_name(zvni
->vrf_id
));
1121 char vni_str
[VNI_STR_LEN
];
1122 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1123 json_vni
= json_object_new_object();
1124 json_object_string_add(json_vni
, "vxlanIf",
1125 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1127 json_object_string_add(json_vni
, "vtepIp",
1128 inet_ntoa(zvni
->local_vtep_ip
));
1129 json_object_int_add(json_vni
, "numMacs", num_macs
);
1130 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1131 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1133 json_vtep_list
= json_object_new_array();
1134 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1135 json_ip_str
= json_object_new_string(
1136 inet_ntoa(zvtep
->vtep_ip
));
1137 json_object_array_add(json_vtep_list
,
1140 json_object_object_add(json_vni
, "remoteVteps",
1143 json_object_object_add(json
, vni_str
, json_vni
);
1148 * Inform BGP about local MACIP.
1150 static int zvni_macip_send_msg_to_client(vni_t vni
,
1151 struct ethaddr
*macaddr
,
1152 struct ipaddr
*ip
, u_char flags
,
1155 char buf
[ETHER_ADDR_STRLEN
];
1156 char buf2
[INET6_ADDRSTRLEN
];
1158 struct zserv
*client
= NULL
;
1159 struct stream
*s
= NULL
;
1161 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1162 /* BGP may not be running. */
1169 zserv_create_header(s
, cmd
, VRF_DEFAULT
);
1170 stream_putl(s
, vni
);
1171 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1174 if (IS_IPADDR_V4(ip
))
1175 ipa_len
= IPV4_MAX_BYTELEN
;
1176 else if (IS_IPADDR_V6(ip
))
1177 ipa_len
= IPV6_MAX_BYTELEN
;
1179 stream_putl(s
, ipa_len
); /* IP address length */
1181 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1183 stream_putl(s
, 0); /* Just MAC. */
1185 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1188 /* Write packet size. */
1189 stream_putw_at(s
, 0, stream_get_endp(s
));
1191 if (IS_ZEBRA_DEBUG_VXLAN
)
1193 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1194 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del",
1195 flags
, prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1196 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1197 zebra_route_string(client
->proto
));
1199 if (cmd
== ZEBRA_MACIP_ADD
)
1200 client
->macipadd_cnt
++;
1202 client
->macipdel_cnt
++;
1204 return zebra_server_send_message(client
);
1208 * Make hash key for neighbors.
1210 static unsigned int neigh_hash_keymake(void *p
)
1212 zebra_neigh_t
*n
= p
;
1213 struct ipaddr
*ip
= &n
->ip
;
1215 if (IS_IPADDR_V4(ip
))
1216 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1218 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1219 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1223 * Compare two neighbor hash structures.
1225 static int neigh_cmp(const void *p1
, const void *p2
)
1227 const zebra_neigh_t
*n1
= p1
;
1228 const zebra_neigh_t
*n2
= p2
;
1230 if (n1
== NULL
&& n2
== NULL
)
1233 if (n1
== NULL
|| n2
== NULL
)
1236 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1240 * Callback to allocate neighbor hash entry.
1242 static void *zvni_neigh_alloc(void *p
)
1244 const zebra_neigh_t
*tmp_n
= p
;
1247 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1254 * Add neighbor entry.
1256 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1257 struct ethaddr
*mac
)
1259 zebra_neigh_t tmp_n
;
1260 zebra_neigh_t
*n
= NULL
;
1261 zebra_mac_t
*zmac
= NULL
;
1263 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1264 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1265 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1268 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1269 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1271 /* Associate the neigh to mac */
1272 zmac
= zvni_mac_lookup(zvni
, mac
);
1274 listnode_add_sort(zmac
->neigh_list
, n
);
1280 * Delete neighbor entry.
1282 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1284 zebra_neigh_t
*tmp_n
;
1285 zebra_mac_t
*zmac
= NULL
;
1287 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1289 listnode_delete(zmac
->neigh_list
, n
);
1291 /* Free the VNI hash entry and allocated memory. */
1292 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1294 XFREE(MTYPE_NEIGH
, tmp_n
);
1300 * Free neighbor hash entry (callback)
1302 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1304 struct neigh_walk_ctx
*wctx
= arg
;
1305 zebra_neigh_t
*n
= backet
->data
;
1307 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1308 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1309 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1310 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1311 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1312 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1313 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1314 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1317 if (wctx
->uninstall
)
1318 zvni_neigh_uninstall(wctx
->zvni
, n
);
1320 return zvni_neigh_del(wctx
->zvni
, n
);
1327 * Delete all neighbor entries from specific VTEP for a particular VNI.
1329 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1330 struct in_addr
*r_vtep_ip
)
1332 struct neigh_walk_ctx wctx
;
1334 if (!zvni
->neigh_table
)
1337 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1339 wctx
.uninstall
= uninstall
;
1340 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1341 wctx
.r_vtep_ip
= *r_vtep_ip
;
1343 hash_iterate(zvni
->neigh_table
,
1344 (void (*)(struct hash_backet
*,
1345 void *))zvni_neigh_del_hash_entry
,
1350 * Delete all neighbor entries for this VNI.
1352 static void zvni_neigh_del_all(zebra_vni_t
*zvni
,
1353 int uninstall
, int upd_client
, u_int32_t flags
)
1355 struct neigh_walk_ctx wctx
;
1357 if (!zvni
->neigh_table
)
1360 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1362 wctx
.uninstall
= uninstall
;
1363 wctx
.upd_client
= upd_client
;
1366 hash_iterate(zvni
->neigh_table
,
1367 (void (*)(struct hash_backet
*,
1368 void *))zvni_neigh_del_hash_entry
,
1373 * Look up neighbor hash entry.
1375 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1380 memset(&tmp
, 0, sizeof(tmp
));
1381 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1382 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1387 /* Process all neigh associated to a mac upon local mac add event */
1388 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1391 zebra_neigh_t
*n
= NULL
;
1392 struct listnode
*node
= NULL
;
1393 char buf
[ETHER_ADDR_STRLEN
];
1394 char buf2
[INET6_ADDRSTRLEN
];
1396 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1397 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1398 /* MAC is learnt locally, program all inactive neigh
1399 * pointing to this mac */
1400 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1401 if (IS_ZEBRA_DEBUG_VXLAN
)
1403 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1404 ipaddr2str(&n
->ip
, buf2
,
1406 prefix_mac2str(&n
->emac
, buf
,
1410 ZEBRA_NEIGH_SET_ACTIVE(n
);
1411 zvni_neigh_send_add_to_client(
1412 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1414 if (IS_ZEBRA_DEBUG_VXLAN
)
1416 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1417 ipaddr2str(&n
->ip
, buf2
,
1419 prefix_mac2str(&n
->emac
, buf
,
1423 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1424 /* TODO: assume the neigh has moved too ?? */
1429 /* Process all neigh associated to a mac upon local mac del event */
1430 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1433 zebra_neigh_t
*n
= NULL
;
1434 struct listnode
*node
= NULL
;
1435 char buf
[ETHER_ADDR_STRLEN
];
1436 char buf2
[INET6_ADDRSTRLEN
];
1438 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1439 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1440 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1441 if (IS_ZEBRA_DEBUG_VXLAN
)
1443 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1444 ipaddr2str(&n
->ip
, buf2
,
1446 prefix_mac2str(&n
->emac
, buf
,
1450 ZEBRA_NEIGH_SET_INACTIVE(n
);
1451 zvni_neigh_send_del_to_client(
1452 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1454 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1455 if (IS_ZEBRA_DEBUG_VXLAN
)
1457 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1458 prefix_mac2str(&n
->emac
, buf
,
1461 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1466 /* process all neigh associated to a mac entry upon remote mac add */
1467 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1470 zebra_neigh_t
*n
= NULL
;
1471 struct listnode
*node
= NULL
;
1472 char buf
[ETHER_ADDR_STRLEN
];
1473 char buf2
[INET6_ADDRSTRLEN
];
1475 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1476 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1477 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1478 if (IS_ZEBRA_DEBUG_VXLAN
)
1480 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1481 ipaddr2str(&n
->ip
, buf2
,
1483 prefix_mac2str(&n
->emac
, buf
,
1487 ZEBRA_NEIGH_SET_INACTIVE(n
);
1488 zvni_neigh_send_del_to_client(
1489 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
1495 /* process all neigh associated to mac entry upon remote mac del */
1496 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1499 zebra_neigh_t
*n
= NULL
;
1500 struct listnode
*node
= NULL
;
1501 char buf
[ETHER_ADDR_STRLEN
];
1502 char buf2
[INET6_ADDRSTRLEN
];
1504 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1505 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1506 if (IS_ZEBRA_DEBUG_VXLAN
)
1508 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1509 prefix_mac2str(&n
->emac
, buf
,
1512 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1518 * Inform BGP about local neighbor addition.
1520 static int zvni_neigh_send_add_to_client(vni_t vni
,
1522 struct ethaddr
*macaddr
, u_char flags
)
1524 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1529 * Inform BGP about local neighbor deletion.
1531 static int zvni_neigh_send_del_to_client(vni_t vni
,
1533 struct ethaddr
*macaddr
, u_char flags
)
1535 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1540 * Install remote neighbor into the kernel.
1542 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1544 struct zebra_if
*zif
;
1545 struct zebra_l2info_vxlan
*vxl
;
1546 struct interface
*vlan_if
;
1548 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1551 zif
= zvni
->vxlan_if
->info
;
1554 vxl
= &zif
->l2info
.vxl
;
1556 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1560 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1564 * Uninstall remote neighbor from the kernel.
1566 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1568 struct zebra_if
*zif
;
1569 struct zebra_l2info_vxlan
*vxl
;
1570 struct interface
*vlan_if
;
1572 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1575 if (!zvni
->vxlan_if
) {
1576 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1581 zif
= zvni
->vxlan_if
->info
;
1584 vxl
= &zif
->l2info
.vxl
;
1585 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1589 return kernel_del_neigh(vlan_if
, &n
->ip
);
1593 * Install neighbor hash entry - called upon access VLAN change.
1595 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1598 struct neigh_walk_ctx
*wctx
= ctxt
;
1600 n
= (zebra_neigh_t
*)backet
->data
;
1604 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1605 zvni_neigh_install(wctx
->zvni
, n
);
1608 /* Get the VRR interface for SVI if any */
1609 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1611 struct zebra_vrf
*zvrf
= NULL
;
1612 struct interface
*tmp_if
= NULL
;
1613 struct zebra_if
*zif
= NULL
;
1615 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1618 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1623 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1626 if (zif
->link
== ifp
)
1633 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1635 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1636 struct connected
*c
= NULL
;
1637 struct ethaddr macaddr
;
1639 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1641 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1644 memset(&ip
, 0, sizeof(struct ipaddr
));
1645 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1648 if (c
->address
->family
== AF_INET
) {
1649 ip
.ipa_type
= IPADDR_V4
;
1650 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1651 sizeof(struct in_addr
));
1652 } else if (c
->address
->family
== AF_INET6
) {
1653 ip
.ipa_type
= IPADDR_V6
;
1654 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1655 sizeof(struct in6_addr
));
1660 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1666 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1668 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1669 struct connected
*c
= NULL
;
1670 struct ethaddr macaddr
;
1672 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1674 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1677 memset(&ip
, 0, sizeof(struct ipaddr
));
1678 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1681 if (c
->address
->family
== AF_INET
) {
1682 ip
.ipa_type
= IPADDR_V4
;
1683 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1684 sizeof(struct in_addr
));
1685 } else if (c
->address
->family
== AF_INET6
) {
1686 ip
.ipa_type
= IPADDR_V6
;
1687 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1688 sizeof(struct in6_addr
));
1693 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1700 * zvni_gw_macip_add_to_client
1702 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1703 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1705 char buf
[ETHER_ADDR_STRLEN
];
1706 char buf2
[INET6_ADDRSTRLEN
];
1707 zebra_neigh_t
*n
= NULL
;
1708 zebra_mac_t
*mac
= NULL
;
1709 struct zebra_if
*zif
= NULL
;
1710 struct zebra_l2info_vxlan
*vxl
= NULL
;
1712 zif
= zvni
->vxlan_if
->info
;
1716 vxl
= &zif
->l2info
.vxl
;
1718 mac
= zvni_mac_lookup(zvni
, macaddr
);
1720 mac
= zvni_mac_add(zvni
, macaddr
);
1722 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1723 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1724 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1729 /* Set "local" forwarding info. */
1730 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1731 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1732 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1733 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1734 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1736 n
= zvni_neigh_lookup(zvni
, ip
);
1738 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1741 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1742 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1743 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1744 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1749 /* Set "local" forwarding info. */
1750 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1751 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1752 n
->ifindex
= ifp
->ifindex
;
1754 if (IS_ZEBRA_DEBUG_VXLAN
)
1756 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1757 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1758 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1759 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1761 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1768 * zvni_gw_macip_del_from_client
1770 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1773 char buf1
[ETHER_ADDR_STRLEN
];
1774 char buf2
[INET6_ADDRSTRLEN
];
1775 zebra_neigh_t
*n
= NULL
;
1776 zebra_mac_t
*mac
= NULL
;
1778 /* If the neigh entry is not present nothing to do*/
1779 n
= zvni_neigh_lookup(zvni
, ip
);
1783 /* mac entry should be present */
1784 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1786 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1787 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1788 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1792 /* If the entry is not local nothing to do*/
1793 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1796 if (IS_ZEBRA_DEBUG_VXLAN
)
1798 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s del to BGP",
1799 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1800 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1801 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1803 /* Remove neighbor from BGP. */
1804 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1807 /* Delete this neighbor entry. */
1808 zvni_neigh_del(zvni
, n
);
1810 /* see if the mac needs to be deleted as well*/
1812 zvni_deref_ip2mac(zvni
, mac
, 0);
1817 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1820 zebra_vni_t
*zvni
= NULL
;
1821 struct zebra_if
*zif
= NULL
;
1822 struct zebra_l2info_vxlan zl2_info
;
1823 struct interface
*vlan_if
= NULL
;
1824 struct interface
*vrr_if
= NULL
;
1825 struct interface
*ifp
;
1827 /* Add primary SVI MAC*/
1828 zvni
= (zebra_vni_t
*)backet
->data
;
1832 ifp
= zvni
->vxlan_if
;
1837 /* If down or not mapped to a bridge, we're done. */
1838 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1841 zl2_info
= zif
->l2info
.vxl
;
1843 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1847 /* Del primary MAC-IP */
1848 zvni_del_macip_for_intf(vlan_if
, zvni
);
1850 /* Del VRR MAC-IP - if any*/
1851 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1853 zvni_del_macip_for_intf(vrr_if
, zvni
);
1858 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1861 zebra_vni_t
*zvni
= NULL
;
1862 struct zebra_if
*zif
= NULL
;
1863 struct zebra_l2info_vxlan zl2_info
;
1864 struct interface
*vlan_if
= NULL
;
1865 struct interface
*vrr_if
= NULL
;
1866 struct interface
*ifp
= NULL
;
1868 zvni
= (zebra_vni_t
*)backet
->data
;
1872 if (!advertise_gw_macip_enabled(zvni
))
1875 ifp
= zvni
->vxlan_if
;
1880 /* If down or not mapped to a bridge, we're done. */
1881 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1883 zl2_info
= zif
->l2info
.vxl
;
1885 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
1886 zif
->brslave_info
.br_if
);
1890 /* Add primary SVI MAC-IP */
1891 zvni_add_macip_for_intf(vlan_if
, zvni
);
1893 /* Add VRR MAC-IP - if any*/
1894 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1896 zvni_add_macip_for_intf(vrr_if
, zvni
);
1902 * Make hash key for MAC.
1904 static unsigned int mac_hash_keymake(void *p
)
1906 zebra_mac_t
*pmac
= p
;
1907 const void *pnt
= (void *)pmac
->macaddr
.octet
;
1909 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
1913 * Compare two MAC addresses.
1915 static int mac_cmp(const void *p1
, const void *p2
)
1917 const zebra_mac_t
*pmac1
= p1
;
1918 const zebra_mac_t
*pmac2
= p2
;
1920 if (pmac1
== NULL
&& pmac2
== NULL
)
1923 if (pmac1
== NULL
|| pmac2
== NULL
)
1926 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
,
1932 * Callback to allocate MAC hash entry.
1934 static void *zvni_mac_alloc(void *p
)
1936 const zebra_mac_t
*tmp_mac
= p
;
1939 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
1942 return ((void *)mac
);
1948 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
1950 zebra_mac_t tmp_mac
;
1951 zebra_mac_t
*mac
= NULL
;
1953 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
1954 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
1955 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
1958 mac
->neigh_list
= list_new();
1959 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
1967 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
1969 zebra_mac_t
*tmp_mac
;
1971 list_delete_and_null(&mac
->neigh_list
);
1973 /* Free the VNI hash entry and allocated memory. */
1974 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
1976 XFREE(MTYPE_MAC
, tmp_mac
);
1982 * Free MAC hash entry (callback)
1984 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1986 struct mac_walk_ctx
*wctx
= arg
;
1987 zebra_mac_t
*mac
= backet
->data
;
1990 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
1991 || ((wctx
->flags
& DEL_REMOTE_MAC
)
1992 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
1993 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
1994 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
1995 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
1996 &wctx
->r_vtep_ip
))) {
1997 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
1998 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1
2000 zvni_mac_send_del_to_client(
2001 wctx
->zvni
->vni
, &mac
->macaddr
,
2002 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
2005 if (wctx
->uninstall
)
2006 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2008 return zvni_mac_del(wctx
->zvni
, mac
);
2015 * Delete all MAC entries from specific VTEP for a particular VNI.
2017 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2018 struct in_addr
*r_vtep_ip
)
2020 struct mac_walk_ctx wctx
;
2022 if (!zvni
->mac_table
)
2025 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2027 wctx
.uninstall
= uninstall
;
2028 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2029 wctx
.r_vtep_ip
= *r_vtep_ip
;
2031 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2032 void *))zvni_mac_del_hash_entry
,
2037 * Delete all MAC entries for this VNI.
2039 static void zvni_mac_del_all(zebra_vni_t
*zvni
,
2040 int uninstall
, int upd_client
, u_int32_t flags
)
2042 struct mac_walk_ctx wctx
;
2044 if (!zvni
->mac_table
)
2047 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2049 wctx
.uninstall
= uninstall
;
2050 wctx
.upd_client
= upd_client
;
2053 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2054 void *))zvni_mac_del_hash_entry
,
2059 * Look up MAC hash entry.
2061 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2066 memset(&tmp
, 0, sizeof(tmp
));
2067 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2068 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2074 * Inform BGP about local MAC addition.
2076 static int zvni_mac_send_add_to_client(vni_t vni
,
2077 struct ethaddr
*macaddr
, u_char flags
)
2079 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2084 * Inform BGP about local MAC deletion.
2086 static int zvni_mac_send_del_to_client(vni_t vni
,
2087 struct ethaddr
*macaddr
, u_char flags
)
2089 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2094 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2095 * notifications, to see if they are of interest.
2097 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2098 struct interface
*br_if
, vlanid_t vid
)
2100 struct zebra_ns
*zns
;
2101 struct route_node
*rn
;
2102 struct interface
*tmp_if
= NULL
;
2103 struct zebra_if
*zif
;
2104 struct zebra_l2info_bridge
*br
;
2105 struct zebra_l2info_vxlan
*vxl
= NULL
;
2106 u_char bridge_vlan_aware
;
2110 /* Determine if bridge is VLAN-aware or not */
2113 br
= &zif
->l2info
.br
;
2114 bridge_vlan_aware
= br
->vlan_aware
;
2116 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2117 /* TODO: Optimize with a hash. */
2118 zns
= zebra_ns_lookup(NS_DEFAULT
);
2119 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2120 tmp_if
= (struct interface
*)rn
->info
;
2124 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2126 if (!if_is_operative(tmp_if
))
2128 vxl
= &zif
->l2info
.vxl
;
2130 if (zif
->brslave_info
.br_if
!= br_if
)
2133 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2142 zvni
= zvni_lookup(vxl
->vni
);
2147 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2148 * neighbor notifications, to see if they are of interest.
2150 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2151 struct interface
*br_if
)
2153 struct zebra_ns
*zns
;
2154 struct route_node
*rn
;
2155 struct interface
*tmp_if
= NULL
;
2156 struct zebra_if
*zif
;
2157 struct zebra_l2info_bridge
*br
;
2158 struct zebra_l2info_vxlan
*vxl
= NULL
;
2159 u_char bridge_vlan_aware
;
2167 /* Make sure the linked interface is a bridge. */
2168 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2171 /* Determine if bridge is VLAN-aware or not */
2174 br
= &zif
->l2info
.br
;
2175 bridge_vlan_aware
= br
->vlan_aware
;
2176 if (bridge_vlan_aware
) {
2177 struct zebra_l2info_vlan
*vl
;
2179 if (!IS_ZEBRA_IF_VLAN(ifp
))
2184 vl
= &zif
->l2info
.vl
;
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
);
2218 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2220 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2221 * linked to the bridge
2222 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2225 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2227 struct zebra_ns
*zns
;
2228 struct route_node
*rn
;
2229 struct interface
*tmp_if
= NULL
;
2230 struct zebra_if
*zif
;
2231 struct zebra_l2info_bridge
*br
;
2232 struct zebra_l2info_vlan
*vl
;
2233 u_char bridge_vlan_aware
;
2236 /* Defensive check, caller expected to invoke only with valid bridge. */
2240 /* Determine if bridge is VLAN-aware or not */
2243 br
= &zif
->l2info
.br
;
2244 bridge_vlan_aware
= br
->vlan_aware
;
2246 /* Check oper status of the SVI. */
2247 if (!bridge_vlan_aware
)
2248 return if_is_operative(br_if
) ? br_if
: NULL
;
2250 /* Identify corresponding VLAN interface. */
2251 /* TODO: Optimize with a hash. */
2252 zns
= zebra_ns_lookup(NS_DEFAULT
);
2253 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2254 tmp_if
= (struct interface
*)rn
->info
;
2255 /* Check oper status of the SVI. */
2256 if (!tmp_if
|| !if_is_operative(tmp_if
))
2259 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2260 || zif
->link
!= br_if
)
2262 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2264 if (vl
->vid
== vid
) {
2270 return found
? tmp_if
: NULL
;
2274 * Install remote MAC into the kernel.
2276 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2278 struct zebra_if
*zif
;
2279 struct zebra_l2info_vxlan
*vxl
;
2282 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2285 zif
= zvni
->vxlan_if
->info
;
2288 vxl
= &zif
->l2info
.vxl
;
2290 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2292 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2293 mac
->fwd_info
.r_vtep_ip
, sticky
);
2297 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2298 * moves to remote, we have to uninstall any existing local entry first.
2300 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2302 struct zebra_if
*zif
;
2303 struct zebra_l2info_vxlan
*vxl
;
2304 struct in_addr vtep_ip
= {.s_addr
= 0};
2305 struct zebra_ns
*zns
;
2306 struct interface
*ifp
;
2308 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2311 if (!zvni
->vxlan_if
) {
2312 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2317 zif
= zvni
->vxlan_if
->info
;
2320 vxl
= &zif
->l2info
.vxl
;
2323 zns
= zebra_ns_lookup(NS_DEFAULT
);
2324 ifp
= if_lookup_by_index_per_ns(zns
,
2325 mac
->fwd_info
.local
.ifindex
);
2326 if (!ifp
) // unexpected
2329 ifp
= zvni
->vxlan_if
;
2330 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2333 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2338 * Install MAC hash entry - called upon access VLAN change.
2340 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2343 struct mac_walk_ctx
*wctx
= ctxt
;
2345 mac
= (zebra_mac_t
*)backet
->data
;
2349 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2350 zvni_mac_install(wctx
->zvni
, mac
);
2354 * Decrement neighbor refcount of MAC; uninstall and free it if
2357 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2360 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2361 || !list_isempty(mac
->neigh_list
))
2365 zvni_mac_uninstall(zvni
, mac
, 0);
2367 zvni_mac_del(zvni
, mac
);
2371 * Read and populate local MACs and neighbors corresponding to this VNI.
2373 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
,
2374 struct interface
*ifp
)
2376 struct zebra_ns
*zns
;
2377 struct zebra_if
*zif
;
2378 struct interface
*vlan_if
;
2379 struct zebra_l2info_vxlan
*vxl
;
2380 struct interface
*vrr_if
;
2383 vxl
= &zif
->l2info
.vxl
;
2384 zns
= zebra_ns_lookup(NS_DEFAULT
);
2386 if (IS_ZEBRA_DEBUG_VXLAN
)
2388 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2389 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2390 zif
->brslave_info
.bridge_ifindex
);
2392 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2393 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2396 if (advertise_gw_macip_enabled(zvni
)) {
2397 /* Add SVI MAC-IP */
2398 zvni_add_macip_for_intf(vlan_if
, zvni
);
2400 /* Add VRR MAC-IP - if any*/
2401 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2403 zvni_add_macip_for_intf(vrr_if
, zvni
);
2406 neigh_read_for_vlan(zns
, vlan_if
);
2411 * Hash function for VNI.
2413 static unsigned int vni_hash_keymake(void *p
)
2415 const zebra_vni_t
*zvni
= p
;
2417 return (jhash_1word(zvni
->vni
, 0));
2421 * Compare 2 VNI hash entries.
2423 static int vni_hash_cmp(const void *p1
, const void *p2
)
2425 const zebra_vni_t
*zvni1
= p1
;
2426 const zebra_vni_t
*zvni2
= p2
;
2428 return (zvni1
->vni
== zvni2
->vni
);
2432 * Callback to allocate VNI hash entry.
2434 static void *zvni_alloc(void *p
)
2436 const zebra_vni_t
*tmp_vni
= p
;
2439 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2440 zvni
->vni
= tmp_vni
->vni
;
2441 return ((void *)zvni
);
2445 * Look up VNI hash entry.
2447 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2449 struct zebra_vrf
*zvrf
;
2450 zebra_vni_t tmp_vni
;
2451 zebra_vni_t
*zvni
= NULL
;
2453 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2455 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2457 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2463 * Add VNI hash entry.
2465 static zebra_vni_t
*zvni_add(vni_t vni
)
2467 struct zebra_vrf
*zvrf
;
2468 zebra_vni_t tmp_zvni
;
2469 zebra_vni_t
*zvni
= NULL
;
2471 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2473 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2475 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2478 /* Create hash table for MAC */
2480 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2482 /* Create hash table for neighbors */
2483 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2484 "Zebra VNI Neighbor Table");
2490 * Delete VNI hash entry.
2492 static int zvni_del(zebra_vni_t
*zvni
)
2494 struct zebra_vrf
*zvrf
;
2495 zebra_vni_t
*tmp_zvni
;
2497 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2500 zvni
->vxlan_if
= NULL
;
2502 /* Free the neighbor hash table. */
2503 hash_free(zvni
->neigh_table
);
2504 zvni
->neigh_table
= NULL
;
2506 /* Free the MAC hash table. */
2507 hash_free(zvni
->mac_table
);
2508 zvni
->mac_table
= NULL
;
2510 /* Free the VNI hash entry and allocated memory. */
2511 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2513 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2519 * Inform BGP about local VNI addition.
2521 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2523 struct zserv
*client
;
2526 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2527 /* BGP may not be running. */
2534 zserv_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2535 stream_putl(s
, zvni
->vni
);
2536 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2537 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2539 /* Write packet size. */
2540 stream_putw_at(s
, 0, stream_get_endp(s
));
2542 if (IS_ZEBRA_DEBUG_VXLAN
)
2543 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2544 zvni
->vni
, inet_ntoa(zvni
->local_vtep_ip
),
2545 vrf_id_to_name(zvni
->vrf_id
),
2546 zebra_route_string(client
->proto
));
2548 client
->vniadd_cnt
++;
2549 return zebra_server_send_message(client
);
2553 * Inform BGP about local VNI deletion.
2555 static int zvni_send_del_to_client(vni_t vni
)
2557 struct zserv
*client
;
2560 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2561 /* BGP may not be running. */
2568 zserv_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2569 stream_putl(s
, vni
);
2571 /* Write packet size. */
2572 stream_putw_at(s
, 0, stream_get_endp(s
));
2574 if (IS_ZEBRA_DEBUG_VXLAN
)
2575 zlog_debug("Send VNI_DEL %u to %s", vni
,
2576 zebra_route_string(client
->proto
));
2578 client
->vnidel_cnt
++;
2579 return zebra_server_send_message(client
);
2583 * Build the VNI hash table by going over the VxLAN interfaces. This
2584 * is called when EVPN (advertise-all-vni) is enabled.
2586 static void zvni_build_hash_table()
2588 struct zebra_ns
*zns
;
2589 struct route_node
*rn
;
2590 struct interface
*ifp
;
2592 /* Walk VxLAN interfaces and create VNI hash. */
2593 zns
= zebra_ns_lookup(NS_DEFAULT
);
2594 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2596 struct zebra_if
*zif
;
2597 struct zebra_l2info_vxlan
*vxl
;
2599 ifp
= (struct interface
*)rn
->info
;
2603 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2606 vxl
= &zif
->l2info
.vxl
;
2609 if (is_vni_l3(vni
)) {
2610 zebra_l3vni_t
*zl3vni
= NULL
;
2612 if (IS_ZEBRA_DEBUG_VXLAN
)
2613 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2614 ifp
->name
, ifp
->ifindex
, vni
);
2616 zl3vni
= zl3vni_lookup(vni
);
2619 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
2620 ifp
->name
, ifp
->ifindex
, vni
);
2624 /* associate with vxlan_if */
2625 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2626 zl3vni
->vxlan_if
= ifp
;
2629 * we need to associate with SVI.
2630 * we can associate with svi-if only after association
2631 * with vxlan-intf is complete
2633 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2635 if (is_l3vni_oper_up(zl3vni
))
2636 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2639 zebra_vni_t
*zvni
= NULL
;
2640 zebra_l3vni_t
*zl3vni
= NULL
;
2641 struct interface
*vlan_if
= NULL
;
2643 if (IS_ZEBRA_DEBUG_VXLAN
)
2645 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2646 ifp
->name
, ifp
->ifindex
, vni
,
2647 inet_ntoa(vxl
->vtep_ip
));
2649 /* VNI hash entry is not expected to exist. */
2650 zvni
= zvni_lookup(vni
);
2653 "VNI hash already present for IF %s(%u) L2-VNI %u",
2654 ifp
->name
, ifp
->ifindex
, vni
);
2658 zvni
= zvni_add(vni
);
2661 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2662 ifp
->name
, ifp
->ifindex
, vni
);
2666 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2667 zvni
->vxlan_if
= ifp
;
2668 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2669 zif
->brslave_info
.br_if
);
2671 zvni
->vrf_id
= vlan_if
->vrf_id
;
2672 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2674 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2678 /* Inform BGP if intf is up and mapped to bridge. */
2679 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2680 zvni_send_add_to_client(zvni
);
2686 * See if remote VTEP matches with prefix.
2688 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2690 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2694 * Locate remote VTEP in VNI hash table.
2696 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2698 zebra_vtep_t
*zvtep
;
2703 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2704 if (zvni_vtep_match(vtep_ip
, zvtep
))
2712 * Add remote VTEP to VNI hash table.
2714 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2716 zebra_vtep_t
*zvtep
;
2718 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2720 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2724 zvtep
->vtep_ip
= *vtep_ip
;
2727 zvni
->vteps
->prev
= zvtep
;
2728 zvtep
->next
= zvni
->vteps
;
2729 zvni
->vteps
= zvtep
;
2735 * Remove remote VTEP from VNI hash table.
2737 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2740 zvtep
->next
->prev
= zvtep
->prev
;
2742 zvtep
->prev
->next
= zvtep
->next
;
2744 zvni
->vteps
= zvtep
->next
;
2746 zvtep
->prev
= zvtep
->next
= NULL
;
2747 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
2753 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2754 * uninstall from kernel if asked to.
2756 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
2758 zebra_vtep_t
*zvtep
, *zvtep_next
;
2763 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
2764 zvtep_next
= zvtep
->next
;
2766 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
2767 zvni_vtep_del(zvni
, zvtep
);
2774 * Install remote VTEP into the kernel.
2776 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2778 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2782 * Uninstall remote VTEP from the kernel.
2784 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2786 if (!zvni
->vxlan_if
) {
2787 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2792 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
2796 * Cleanup VNI/VTEP and update kernel
2798 static void zvni_cleanup_all(struct hash_backet
*backet
, void *zvrf
)
2800 zebra_vni_t
*zvni
= NULL
;
2801 zebra_l3vni_t
*zl3vni
= NULL
;
2803 zvni
= (zebra_vni_t
*)backet
->data
;
2807 /* remove from l3-vni list */
2808 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
2810 listnode_delete(zl3vni
->l2vnis
, zvni
);
2812 /* Free up all neighbors and MACs, if any. */
2813 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
2814 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
2816 /* Free up all remote VTEPs, if any. */
2817 zvni_vtep_del_all(zvni
, 1);
2819 /* Delete the hash entry. */
2824 static void zl3vni_cleanup_all(struct hash_backet
*backet
,
2827 zebra_l3vni_t
*zl3vni
= NULL
;
2829 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
2833 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
2836 static int is_host_present_in_host_list(struct list
*list
,
2837 struct prefix
*host
)
2839 struct listnode
*node
= NULL
;
2840 struct prefix
*p
= NULL
;
2842 for (ALL_LIST_ELEMENTS_RO(list
, node
, p
)) {
2843 if (prefix_same(p
, host
))
2849 static void host_list_add_host(struct list
*list
,
2850 struct prefix
*host
)
2852 struct prefix
*p
= NULL
;
2854 p
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct prefix
));
2855 memcpy(p
, host
, sizeof(struct prefix
));
2857 listnode_add_sort(list
, p
);
2860 static void host_list_delete_host(struct list
*list
,
2861 struct prefix
*host
)
2863 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
2864 struct prefix
*p
= NULL
;
2866 for (ALL_LIST_ELEMENTS(list
, node
, nnode
, p
)) {
2867 if (prefix_same(p
, host
)) {
2868 XFREE(MTYPE_HOST_PREFIX
, p
);
2874 list_delete_node(list
, node_to_del
);
2878 * Look up MAC hash entry.
2880 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
2881 struct ethaddr
*rmac
)
2886 memset(&tmp
, 0, sizeof(tmp
));
2887 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
2888 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
2894 * Callback to allocate RMAC hash entry.
2896 static void *zl3vni_rmac_alloc(void *p
)
2898 const zebra_mac_t
*tmp_rmac
= p
;
2901 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2904 return ((void *)zrmac
);
2908 * Add RMAC entry to l3-vni
2910 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
2911 struct ethaddr
*rmac
)
2913 zebra_mac_t tmp_rmac
;
2914 zebra_mac_t
*zrmac
= NULL
;
2916 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
2917 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
2918 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
2921 zrmac
->host_list
= list_new();
2922 zrmac
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
2924 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
2925 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
2933 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
,
2936 zebra_mac_t
*tmp_rmac
;
2938 if (zrmac
->host_list
)
2939 list_delete_and_null(&zrmac
->host_list
);
2940 zrmac
->host_list
= NULL
;
2942 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
2944 XFREE(MTYPE_MAC
, tmp_rmac
);
2950 * Install remote RMAC into the kernel.
2952 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
,
2955 struct zebra_if
*zif
= NULL
;
2956 struct zebra_l2info_vxlan
*vxl
= NULL
;
2958 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2959 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2962 zif
= zl3vni
->vxlan_if
->info
;
2966 vxl
= &zif
->l2info
.vxl
;
2968 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
2970 zrmac
->fwd_info
.r_vtep_ip
, 0);
2974 * Uninstall remote RMAC from the kernel.
2976 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
,
2979 char buf
[ETHER_ADDR_STRLEN
];
2980 struct zebra_if
*zif
= NULL
;
2981 struct zebra_l2info_vxlan
*vxl
= NULL
;
2983 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
)) ||
2984 !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
2987 if (!zl3vni
->vxlan_if
) {
2989 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
2990 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
2991 zl3vni
->vni
, zl3vni
);
2995 zif
= zl3vni
->vxlan_if
->info
;
2999 vxl
= &zif
->l2info
.vxl
;
3001 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3002 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3005 /* handle rmac add */
3006 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
,
3007 struct ethaddr
*rmac
,
3008 struct ipaddr
*vtep_ip
,
3009 struct prefix
*host_prefix
)
3011 char buf
[ETHER_ADDR_STRLEN
];
3012 char buf1
[INET6_ADDRSTRLEN
];
3013 zebra_mac_t
*zrmac
= NULL
;
3015 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3018 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3021 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3022 prefix_mac2str(rmac
, buf
,
3024 zl3vni
->vni
, ipaddr2str(vtep_ip
, buf1
,
3028 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3029 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3031 /* install rmac in kernel */
3032 zl3vni_rmac_install(zl3vni
, zrmac
);
3035 if (!is_host_present_in_host_list(zrmac
->host_list
, host_prefix
))
3036 host_list_add_host(zrmac
->host_list
, host_prefix
);
3041 /* handle rmac delete */
3042 static int zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
,
3043 struct ethaddr
*rmac
,
3044 struct prefix
*host_prefix
)
3046 zebra_mac_t
*zrmac
= NULL
;
3048 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3052 host_list_delete_host(zrmac
->host_list
, host_prefix
);
3053 if (list_isempty(zrmac
->host_list
)) {
3055 /* uninstall from kernel */
3056 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3058 /* del the rmac entry */
3059 zl3vni_rmac_del(zl3vni
, zrmac
);
3065 * Look up nh hash entry on a l3-vni.
3067 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
3073 memset(&tmp
, 0, sizeof(tmp
));
3074 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3075 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3082 * Callback to allocate NH hash entry on L3-VNI.
3084 static void *zl3vni_nh_alloc(void *p
)
3086 const zebra_neigh_t
*tmp_n
= p
;
3089 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3096 * Add neighbor entry.
3098 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
3100 struct ethaddr
*mac
)
3102 zebra_neigh_t tmp_n
;
3103 zebra_neigh_t
*n
= NULL
;
3105 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3106 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3107 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3110 n
->host_list
= list_new();
3111 n
->host_list
->cmp
= (int (*)(void *, void *))prefix_cmp
;
3113 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3114 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3115 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3121 * Delete neighbor entry.
3123 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
,
3126 zebra_neigh_t
*tmp_n
;
3129 list_delete_and_null(&n
->host_list
);
3130 n
->host_list
= NULL
;
3132 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3134 XFREE(MTYPE_NEIGH
, tmp_n
);
3140 * Install remote nh as neigh into the kernel.
3142 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
,
3145 if (!is_l3vni_oper_up(zl3vni
))
3148 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3149 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3152 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3156 * Uninstall remote nh from the kernel.
3158 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
,
3161 if (!is_l3vni_oper_up(zl3vni
))
3164 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
) ||
3165 !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3168 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3171 /* add remote vtep as a neigh entry */
3172 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
,
3173 struct ipaddr
*vtep_ip
,
3174 struct ethaddr
*rmac
,
3175 struct prefix
*host_prefix
)
3177 char buf
[ETHER_ADDR_STRLEN
];
3178 char buf1
[INET6_ADDRSTRLEN
];
3179 zebra_neigh_t
*nh
= NULL
;
3181 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3183 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3187 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3188 ipaddr2str(vtep_ip
, buf1
,
3190 prefix_mac2str(rmac
, buf
,
3196 /* install the nh neigh in kernel */
3197 zl3vni_nh_install(zl3vni
, nh
);
3200 if (!is_host_present_in_host_list(nh
->host_list
, host_prefix
))
3201 host_list_add_host(nh
->host_list
, host_prefix
);
3206 /* handle nh neigh delete */
3207 static int zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
,
3208 struct ipaddr
*vtep_ip
,
3209 struct prefix
*host_prefix
)
3211 zebra_neigh_t
*nh
= NULL
;
3213 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3217 host_list_delete_host(nh
->host_list
, host_prefix
);
3218 if (list_isempty(nh
->host_list
)) {
3220 /* uninstall from kernel */
3221 zl3vni_nh_uninstall(zl3vni
, nh
);
3223 /* delete the nh entry */
3224 zl3vni_nh_del(zl3vni
, nh
);
3230 /* handle neigh update from kernel - the only thing of interest is to
3231 * readd stale entries.
3233 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
,
3234 struct ipaddr
*ip
, u_int16_t state
)
3237 zebra_neigh_t
*n
= NULL
;
3239 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3243 /* all next hop neigh are remote and installed by frr.
3244 * If the kernel has aged this entry, re-install.
3246 if (state
& NUD_STALE
)
3247 zl3vni_nh_install(zl3vni
, n
);
3252 /* handle neigh delete from kernel */
3253 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
,
3256 zebra_neigh_t
*n
= NULL
;
3258 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3262 /* all next hop neigh are remote and installed by frr.
3263 * If we get an age out notification for these neigh entries, we have to
3266 zl3vni_nh_install(zl3vni
, n
);
3272 * Hash function for L3 VNI.
3274 static unsigned int l3vni_hash_keymake(void *p
)
3276 const zebra_l3vni_t
*zl3vni
= p
;
3278 return jhash_1word(zl3vni
->vni
, 0);
3282 * Compare 2 L3 VNI hash entries.
3284 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3286 const zebra_l3vni_t
*zl3vni1
= p1
;
3287 const zebra_l3vni_t
*zl3vni2
= p2
;
3289 return (zl3vni1
->vni
== zl3vni2
->vni
);
3293 * Callback to allocate L3 VNI hash entry.
3295 static void *zl3vni_alloc(void *p
)
3297 zebra_l3vni_t
*zl3vni
= NULL
;
3298 const zebra_l3vni_t
*tmp_l3vni
= p
;
3300 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3301 zl3vni
->vni
= tmp_l3vni
->vni
;
3302 return ((void *)zl3vni
);
3306 * Look up L3 VNI hash entry.
3308 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3310 struct zebra_ns
*zns
;
3311 zebra_l3vni_t tmp_l3vni
;
3312 zebra_l3vni_t
*zl3vni
= NULL
;
3314 zns
= zebra_ns_lookup(NS_DEFAULT
);
3316 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3317 tmp_l3vni
.vni
= vni
;
3318 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3324 * Add L3 VNI hash entry.
3326 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3328 zebra_l3vni_t tmp_zl3vni
;
3329 struct zebra_ns
*zns
= NULL
;
3330 zebra_l3vni_t
*zl3vni
= NULL
;
3332 zns
= zebra_ns_lookup(NS_DEFAULT
);
3335 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3336 tmp_zl3vni
.vni
= vni
;
3338 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3341 zl3vni
->vrf_id
= vrf_id
;
3342 zl3vni
->svi_if
= NULL
;
3343 zl3vni
->vxlan_if
= NULL
;
3344 zl3vni
->l2vnis
= list_new();
3345 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3347 /* Create hash table for remote RMAC */
3348 zl3vni
->rmac_table
=
3349 hash_create(mac_hash_keymake
, mac_cmp
,
3350 "Zebra L3-VNI RMAC-Table");
3352 /* Create hash table for neighbors */
3353 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3354 "Zebra L3-VNI next-hop table");
3360 * Delete L3 VNI hash entry.
3362 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3364 struct zebra_ns
*zns
;
3365 zebra_l3vni_t
*tmp_zl3vni
;
3367 zns
= zebra_ns_lookup(NS_DEFAULT
);
3370 /* free the list of l2vnis */
3371 list_delete_and_null(&zl3vni
->l2vnis
);
3372 zl3vni
->l2vnis
= NULL
;
3374 /* Free the rmac table */
3375 hash_free(zl3vni
->rmac_table
);
3376 zl3vni
->rmac_table
= NULL
;
3378 /* Free the nh table */
3379 hash_free(zl3vni
->nh_table
);
3380 zl3vni
->nh_table
= NULL
;
3382 /* Free the VNI hash entry and allocated memory. */
3383 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3385 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3390 static int is_vni_l3(vni_t vni
)
3392 zebra_l3vni_t
*zl3vni
= NULL
;
3394 zl3vni
= zl3vni_lookup(vni
);
3400 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3402 struct zebra_ns
*zns
= NULL
;
3403 struct route_node
*rn
= NULL
;
3404 struct interface
*ifp
= NULL
;
3406 /* loop through all vxlan-interface */
3407 zns
= zebra_ns_lookup(NS_DEFAULT
);
3408 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3410 struct zebra_if
*zif
= NULL
;
3411 struct zebra_l2info_vxlan
*vxl
= NULL
;
3413 ifp
= (struct interface
*)rn
->info
;
3418 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3421 vxl
= &zif
->l2info
.vxl
;
3422 if (vxl
->vni
== zl3vni
->vni
) {
3423 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3431 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3433 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3434 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3436 if (!zl3vni
->vxlan_if
)
3439 zif
= zl3vni
->vxlan_if
->info
;
3443 vxl
= &zif
->l2info
.vxl
;
3445 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3448 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3450 struct zebra_vrf
*zvrf
= NULL
;
3452 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3456 return zl3vni_lookup(zvrf
->l3vni
);
3460 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3461 * neighbor notifications, to see if they are of interest.
3463 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3464 struct interface
*br_if
)
3468 u_char bridge_vlan_aware
= 0;
3469 zebra_l3vni_t
*zl3vni
= NULL
;
3470 struct zebra_ns
*zns
= NULL
;
3471 struct route_node
*rn
= NULL
;
3472 struct zebra_if
*zif
= NULL
;
3473 struct interface
*tmp_if
= NULL
;
3474 struct zebra_l2info_bridge
*br
= NULL
;
3475 struct zebra_l2info_vxlan
*vxl
= NULL
;
3480 /* Make sure the linked interface is a bridge. */
3481 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3484 /* Determine if bridge is VLAN-aware or not */
3487 br
= &zif
->l2info
.br
;
3488 bridge_vlan_aware
= br
->vlan_aware
;
3489 if (bridge_vlan_aware
) {
3490 struct zebra_l2info_vlan
*vl
;
3492 if (!IS_ZEBRA_IF_VLAN(ifp
))
3497 vl
= &zif
->l2info
.vl
;
3501 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3502 /* TODO: Optimize with a hash. */
3503 zns
= zebra_ns_lookup(NS_DEFAULT
);
3504 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3505 tmp_if
= (struct interface
*)rn
->info
;
3509 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3511 if (!if_is_operative(tmp_if
))
3513 vxl
= &zif
->l2info
.vxl
;
3515 if (zif
->brslave_info
.br_if
!= br_if
)
3518 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3527 zl3vni
= zl3vni_lookup(vxl
->vni
);
3532 * Inform BGP about l3-vni.
3534 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3536 struct stream
*s
= NULL
;
3537 struct zserv
*client
= NULL
;
3538 struct ethaddr rmac
;
3539 char buf
[ETHER_ADDR_STRLEN
];
3541 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3542 /* BGP may not be running. */
3547 memset(&rmac
, 0, sizeof(struct ethaddr
));
3548 zl3vni_get_rmac(zl3vni
, &rmac
);
3553 zserv_create_header(s
, ZEBRA_L3VNI_ADD
,
3554 zl3vni_vrf_id(zl3vni
));
3555 stream_putl(s
, zl3vni
->vni
);
3556 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3557 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3559 /* Write packet size. */
3560 stream_putw_at(s
, 0, stream_get_endp(s
));
3562 if (IS_ZEBRA_DEBUG_VXLAN
)
3563 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s to %s",
3564 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3565 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3566 inet_ntoa(zl3vni
->local_vtep_ip
),
3567 zebra_route_string(client
->proto
));
3569 client
->l3vniadd_cnt
++;
3570 return zebra_server_send_message(client
);
3574 * Inform BGP about local l3-VNI deletion.
3576 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3578 struct stream
*s
= NULL
;
3579 struct zserv
*client
= NULL
;
3581 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3582 /* BGP may not be running. */
3589 zserv_create_header(s
, ZEBRA_L3VNI_DEL
,
3590 zl3vni_vrf_id(zl3vni
));
3591 stream_putl(s
, zl3vni
->vni
);
3593 /* Write packet size. */
3594 stream_putw_at(s
, 0, stream_get_endp(s
));
3596 if (IS_ZEBRA_DEBUG_VXLAN
)
3597 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3599 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3600 zebra_route_string(client
->proto
));
3602 client
->l3vnidel_cnt
++;
3603 return zebra_server_send_message(client
);
3606 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3608 if (IS_ZEBRA_DEBUG_VXLAN
)
3609 zlog_debug("L3-VNI %u is UP - send add to BGP",
3612 /* send l3vni add to BGP */
3613 zl3vni_send_add_to_client(zl3vni
);
3616 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3618 if (IS_ZEBRA_DEBUG_VXLAN
)
3619 zlog_debug("L3-VNI %u is Down - Send del to BGP",
3622 /* send l3-vni del to BGP*/
3623 zl3vni_send_del_to_client(zl3vni
);
3626 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
,
3629 zebra_vni_t
*zvni
= (zebra_vni_t
*) backet
->data
;
3630 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*) ctxt
;
3632 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3633 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3637 * handle transition of vni from l2 to l3 and vice versa
3639 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
,
3642 zebra_vni_t
*zvni
= NULL
;
3644 /* There is a possibility that VNI notification was already received
3645 * from kernel and we programmed it as L2-VNI
3646 * In such a case we need to delete this L2-VNI first, so
3647 * that it can be reprogrammed as L3-VNI in the system. It is also
3648 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3649 * interface is still present in kernel. In this case to keep it
3650 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3653 /* Locate hash entry */
3654 zvni
= zvni_lookup(vni
);
3658 if (IS_ZEBRA_DEBUG_VXLAN
)
3659 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3662 /* Delete VNI from BGP. */
3663 zvni_send_del_to_client(zvni
->vni
);
3665 /* Free up all neighbors and MAC, if any. */
3666 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3667 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3669 /* Free up all remote VTEPs, if any. */
3670 zvni_vtep_del_all(zvni
, 0);
3672 /* Delete the hash entry. */
3673 if (zvni_del(zvni
)) {
3674 zlog_err("Failed to del VNI hash %p, VNI %u",
3679 /* TODO_MITESH: This needs to be thought through. We don't have
3680 * enough information at this point to reprogram the vni as
3681 * l2-vni. One way is to store the required info in l3-vni and
3682 * used it solely for this purpose
3689 /* delete and uninstall rmac hash entry */
3690 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
,
3693 zebra_mac_t
*zrmac
= NULL
;
3694 zebra_l3vni_t
*zl3vni
= NULL
;
3696 zrmac
= (zebra_mac_t
*)backet
->data
;
3697 zl3vni
= (zebra_l3vni_t
*)ctx
;
3698 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3699 zl3vni_rmac_del(zl3vni
, zrmac
);
3702 /* delete and uninstall nh hash entry */
3703 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
,
3706 zebra_neigh_t
*n
= NULL
;
3707 zebra_l3vni_t
*zl3vni
= NULL
;
3709 n
= (zebra_neigh_t
*)backet
->data
;
3710 zl3vni
= (zebra_l3vni_t
*)ctx
;
3711 zl3vni_nh_uninstall(zl3vni
, n
);
3712 zl3vni_nh_del(zl3vni
, n
);
3715 /* Public functions */
3717 /* handle evpn route in vrf table */
3718 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
,
3719 struct ethaddr
*rmac
,
3720 struct ipaddr
*vtep_ip
,
3721 struct prefix
*host_prefix
)
3723 zebra_l3vni_t
*zl3vni
= NULL
;
3725 zl3vni
= zl3vni_from_vrf(vrf_id
);
3726 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3729 /* add the next hop neighbor */
3730 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
3733 zl3vni_remote_rmac_add(zl3vni
, rmac
, vtep_ip
, host_prefix
);
3736 /* handle evpn vrf route delete */
3737 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
3738 struct ethaddr
*rmac
,
3739 struct ipaddr
*vtep_ip
,
3740 struct prefix
*host_prefix
)
3742 zebra_l3vni_t
*zl3vni
= NULL
;
3744 zl3vni
= zl3vni_from_vrf(vrf_id
);
3748 /* delete the next hop entry */
3749 zl3vni_remote_nh_del(zl3vni
, vtep_ip
, host_prefix
);
3751 /* delete the rmac entry */
3752 zl3vni_remote_rmac_del(zl3vni
, rmac
, host_prefix
);
3755 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
,
3757 struct ethaddr
*rmac
,
3760 zebra_l3vni_t
*zl3vni
= NULL
;
3761 zebra_mac_t
*zrmac
= NULL
;
3762 json_object
*json
= NULL
;
3764 if (!is_evpn_enabled()) {
3766 vty_out(vty
, "{}\n");
3771 json
= json_object_new_object();
3773 zl3vni
= zl3vni_lookup(l3vni
);
3776 vty_out(vty
, "{}\n");
3778 vty_out(vty
, "%% L3-VNI %u doesnt exist\n",
3783 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3786 vty_out(vty
, "{}\n");
3789 "%% Requested RMAC doesnt exist in L3-VNI %u",
3794 zl3vni_print_rmac(zrmac
, vty
, json
);
3797 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3798 json
, JSON_C_TO_STRING_PRETTY
));
3799 json_object_free(json
);
3803 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
,
3807 zebra_l3vni_t
*zl3vni
;
3808 u_int32_t num_rmacs
;
3809 struct rmac_walk_ctx wctx
;
3810 json_object
*json
= NULL
;
3812 if (!is_evpn_enabled())
3815 zl3vni
= zl3vni_lookup(l3vni
);
3818 vty_out(vty
, "{}\n");
3820 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3823 num_rmacs
= hashcount(zl3vni
->rmac_table
);
3828 json
= json_object_new_object();
3830 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
3835 "Number of Remote RMACs known for this VNI: %u\n",
3837 vty_out(vty
, "%-17s %-21s %-6s\n", "MAC",
3838 "Remote VTEP", "Refcnt");
3840 json_object_int_add(json
, "numRmacs", num_rmacs
);
3842 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
3845 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3846 json
, JSON_C_TO_STRING_PRETTY
));
3847 json_object_free(json
);
3851 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
,
3854 struct zebra_ns
*zns
= NULL
;
3855 json_object
*json
= NULL
;
3858 if (!is_evpn_enabled()) {
3860 vty_out(vty
, "{}\n");
3864 zns
= zebra_ns_lookup(NS_DEFAULT
);
3867 vty_out(vty
, "{}\n");
3872 json
= json_object_new_object();
3876 hash_iterate(zns
->l3vni_table
,
3877 (void (*)(struct hash_backet
*,
3878 void *))zl3vni_print_rmac_hash_all_vni
,
3882 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3883 json
, JSON_C_TO_STRING_PRETTY
));
3884 json_object_free(json
);
3888 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
,
3893 zebra_l3vni_t
*zl3vni
= NULL
;
3894 zebra_neigh_t
*n
= NULL
;
3895 json_object
*json
= NULL
;
3897 if (!is_evpn_enabled()) {
3899 vty_out(vty
, "{}\n");
3904 json
= json_object_new_object();
3906 zl3vni
= zl3vni_lookup(l3vni
);
3909 vty_out(vty
, "{}\n");
3911 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3915 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3918 vty_out(vty
, "{}\n");
3921 "%% Requested next-hop not present for L3-VNI %u",
3926 zl3vni_print_nh(n
, vty
, json
);
3929 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3930 json
, JSON_C_TO_STRING_PRETTY
));
3931 json_object_free(json
);
3935 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
,
3940 struct nh_walk_ctx wctx
;
3941 json_object
*json
= NULL
;
3942 zebra_l3vni_t
*zl3vni
= NULL
;
3944 if (!is_evpn_enabled())
3947 zl3vni
= zl3vni_lookup(l3vni
);
3950 vty_out(vty
, "{}\n");
3952 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
3956 num_nh
= hashcount(zl3vni
->nh_table
);
3961 json
= json_object_new_object();
3967 "Number of NH Neighbors known for this VNI: %u\n",
3969 vty_out(vty
, "%-15s %-17s %6s\n", "IP",
3972 json_object_int_add(json
, "numNh", num_nh
);
3974 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
3977 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3978 json
, JSON_C_TO_STRING_PRETTY
));
3979 json_object_free(json
);
3983 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
,
3986 struct zebra_ns
*zns
= NULL
;
3987 json_object
*json
= NULL
;
3990 if (!is_evpn_enabled()) {
3992 vty_out(vty
, "{}\n");
3996 zns
= zebra_ns_lookup(NS_DEFAULT
);
4001 json
= json_object_new_object();
4005 hash_iterate(zns
->l3vni_table
,
4006 (void (*)(struct hash_backet
*,
4007 void *))zl3vni_print_nh_hash_all_vni
,
4011 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4012 json
, JSON_C_TO_STRING_PRETTY
));
4013 json_object_free(json
);
4019 * Display L3 VNI information (VTY command handler).
4021 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, u_char use_json
)
4024 json_object
*json
= NULL
;
4025 zebra_l3vni_t
*zl3vni
= NULL
;
4027 if (!is_evpn_enabled()) {
4029 vty_out(vty
, "{}\n");
4033 zl3vni
= zl3vni_lookup(vni
);
4036 vty_out(vty
, "{}\n");
4038 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4043 json
= json_object_new_object();
4047 zl3vni_print(zl3vni
, (void *)args
);
4050 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4051 json
, JSON_C_TO_STRING_PRETTY
));
4052 json_object_free(json
);
4057 * Display L3 VNI hash table (VTY command handler).
4059 void zebra_vxlan_print_l3vnis(struct vty
*vty
, u_char use_json
)
4063 json_object
*json
= NULL
;
4064 struct zebra_ns
*zns
= NULL
;
4066 if (!is_evpn_enabled()) {
4068 vty_out(vty
, "{}\n");
4072 zns
= zebra_ns_lookup(NS_DEFAULT
);
4075 num_vnis
= hashcount(zns
->l3vni_table
);
4078 vty_out(vty
, "{}\n");
4083 json
= json_object_new_object();
4084 json_object_int_add(json
, "numVnis", num_vnis
);
4086 vty_out(vty
, "Number of L3 VNIs: %u\n", num_vnis
);
4087 vty_out(vty
, "%-10s %-15s %-20s %-20s %-5s %-37s %-18s\n",
4088 "VNI", "Local-ip", "Vx-intf", "L3-SVI", "State",
4094 hash_iterate(zns
->l3vni_table
,
4095 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
4099 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4100 json
, JSON_C_TO_STRING_PRETTY
));
4101 json_object_free(json
);
4106 * Display Neighbors for a VNI (VTY command handler).
4108 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4109 vni_t vni
, u_char use_json
)
4112 u_int32_t num_neigh
;
4113 struct neigh_walk_ctx wctx
;
4114 json_object
*json
= NULL
;
4116 if (!is_evpn_enabled())
4118 zvni
= zvni_lookup(vni
);
4121 vty_out(vty
, "{}\n");
4123 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4126 num_neigh
= hashcount(zvni
->neigh_table
);
4131 json
= json_object_new_object();
4133 /* Since we have IPv6 addresses to deal with which can vary widely in
4134 * size, we try to be a bit more elegant in display by first computing
4135 * the maximum width.
4137 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4140 wctx
.addr_width
= 15;
4142 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4146 "Number of ARPs (local and remote) known for this VNI: %u\n",
4148 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
4149 "Type", "MAC", "Remote VTEP");
4151 json_object_int_add(json
, "numArpNd", num_neigh
);
4153 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4155 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4156 json
, JSON_C_TO_STRING_PRETTY
));
4157 json_object_free(json
);
4162 * Display neighbors across all VNIs (VTY command handler).
4164 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4167 json_object
*json
= NULL
;
4170 if (!is_evpn_enabled())
4174 json
= json_object_new_object();
4178 hash_iterate(zvrf
->vni_table
,
4179 (void (*)(struct hash_backet
*,
4180 void *))zvni_print_neigh_hash_all_vni
,
4183 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4184 json
, JSON_C_TO_STRING_PRETTY
));
4185 json_object_free(json
);
4190 * Display specific neighbor for a VNI, if present (VTY command handler).
4192 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4193 struct zebra_vrf
*zvrf
, vni_t vni
,
4194 struct ipaddr
*ip
, u_char use_json
)
4198 json_object
*json
= NULL
;
4200 if (!is_evpn_enabled())
4202 zvni
= zvni_lookup(vni
);
4205 vty_out(vty
, "{}\n");
4207 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4210 n
= zvni_neigh_lookup(zvni
, ip
);
4214 "%% Requested neighbor does not exist in VNI %u\n",
4219 json
= json_object_new_object();
4221 zvni_print_neigh(n
, vty
, json
);
4224 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4225 json
, JSON_C_TO_STRING_PRETTY
));
4226 json_object_free(json
);
4231 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4232 * By definition, these are remote neighbors.
4234 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4235 vni_t vni
, struct in_addr vtep_ip
,
4239 u_int32_t num_neigh
;
4240 struct neigh_walk_ctx wctx
;
4241 json_object
*json
= NULL
;
4243 if (!is_evpn_enabled())
4245 zvni
= zvni_lookup(vni
);
4248 vty_out(vty
, "{}\n");
4250 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4253 num_neigh
= hashcount(zvni
->neigh_table
);
4257 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4260 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4261 wctx
.r_vtep_ip
= vtep_ip
;
4263 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4266 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4267 json
, JSON_C_TO_STRING_PRETTY
));
4268 json_object_free(json
);
4273 * Display MACs for a VNI (VTY command handler).
4275 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4276 vni_t vni
, u_char use_json
)
4280 struct mac_walk_ctx wctx
;
4281 json_object
*json
= NULL
;
4282 json_object
*json_mac
= NULL
;
4284 if (!is_evpn_enabled())
4286 zvni
= zvni_lookup(vni
);
4289 vty_out(vty
, "{}\n");
4291 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4294 num_macs
= num_valid_macs(zvni
);
4299 json
= json_object_new_object();
4300 json_mac
= json_object_new_object();
4303 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4306 wctx
.json
= json_mac
;
4310 "Number of MACs (local and remote) known for this VNI: %u\n",
4312 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4313 "Intf/Remote VTEP", "VLAN");
4315 json_object_int_add(json
, "numMacs", num_macs
);
4317 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4320 json_object_object_add(json
, "macs", json_mac
);
4321 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4322 json
, JSON_C_TO_STRING_PRETTY
));
4323 json_object_free(json
);
4328 * Display MACs for all VNIs (VTY command handler).
4330 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4333 struct mac_walk_ctx wctx
;
4334 json_object
*json
= NULL
;
4336 if (!is_evpn_enabled()) {
4338 vty_out(vty
, "{}\n");
4342 json
= json_object_new_object();
4344 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4347 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4350 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4351 json
, JSON_C_TO_STRING_PRETTY
));
4352 json_object_free(json
);
4357 * Display MACs for all VNIs (VTY command handler).
4359 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4360 struct zebra_vrf
*zvrf
,
4361 struct in_addr vtep_ip
,
4364 struct mac_walk_ctx wctx
;
4365 json_object
*json
= NULL
;
4367 if (!is_evpn_enabled())
4371 json
= json_object_new_object();
4373 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4375 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4376 wctx
.r_vtep_ip
= vtep_ip
;
4378 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4381 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4382 json
, JSON_C_TO_STRING_PRETTY
));
4383 json_object_free(json
);
4388 * Display specific MAC for a VNI, if present (VTY command handler).
4390 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4391 vni_t vni
, struct ethaddr
*macaddr
)
4396 if (!is_evpn_enabled())
4398 zvni
= zvni_lookup(vni
);
4400 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4403 mac
= zvni_mac_lookup(zvni
, macaddr
);
4405 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4410 zvni_print_mac(mac
, vty
);
4414 * Display MACs for a VNI from specific VTEP (VTY command handler).
4416 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4417 vni_t vni
, struct in_addr vtep_ip
,
4422 struct mac_walk_ctx wctx
;
4423 json_object
*json
= NULL
;
4424 json_object
*json_mac
= NULL
;
4426 if (!is_evpn_enabled())
4428 zvni
= zvni_lookup(vni
);
4431 vty_out(vty
, "{}\n");
4433 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4436 num_macs
= num_valid_macs(zvni
);
4441 json
= json_object_new_object();
4442 json_mac
= json_object_new_object();
4445 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4448 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4449 wctx
.r_vtep_ip
= vtep_ip
;
4450 wctx
.json
= json_mac
;
4451 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4454 json_object_int_add(json
, "numMacs", wctx
.count
);
4456 json_object_object_add(json
, "macs", json_mac
);
4457 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4458 json
, JSON_C_TO_STRING_PRETTY
));
4459 json_object_free(json
);
4465 * Display VNI information (VTY command handler).
4467 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4471 json_object
*json
= NULL
;
4474 if (!is_evpn_enabled())
4476 zvni
= zvni_lookup(vni
);
4479 vty_out(vty
, "{}\n");
4481 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4485 json
= json_object_new_object();
4488 zvni_print(zvni
, (void *)args
);
4490 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4491 json
, JSON_C_TO_STRING_PRETTY
));
4492 json_object_free(json
);
4497 * Display VNI hash table (VTY command handler).
4499 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4503 json_object
*json
= NULL
;
4506 if (!is_evpn_enabled())
4508 num_vnis
= hashcount(zvrf
->vni_table
);
4511 vty_out(vty
, "{}\n");
4515 json
= json_object_new_object();
4516 json_object_string_add(json
, "advertiseGatewayMacip",
4517 zvrf
->advertise_gw_macip
? "Yes" : "No");
4518 json_object_int_add(json
, "numVnis", num_vnis
);
4520 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4521 zvrf
->advertise_gw_macip
? "Yes" : "No");
4522 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
4523 vty_out(vty
, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
4524 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
4525 "# Remote VTEPs", "VRF");
4530 hash_iterate(zvrf
->vni_table
,
4531 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4535 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4536 json
, JSON_C_TO_STRING_PRETTY
));
4537 json_object_free(json
);
4542 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4543 * kernel. This may result in either the neighbor getting deleted from
4544 * our database or being re-added to the kernel (if it is a valid
4547 int zebra_vxlan_local_neigh_del(struct interface
*ifp
,
4548 struct interface
*link_if
, struct ipaddr
*ip
)
4550 char buf
[INET6_ADDRSTRLEN
];
4551 char buf2
[ETHER_ADDR_STRLEN
];
4552 zebra_neigh_t
*n
= NULL
;
4553 zebra_vni_t
*zvni
= NULL
;
4554 zebra_mac_t
*zmac
= NULL
;
4555 zebra_l3vni_t
*zl3vni
= NULL
;
4557 /* check if this is a remote neigh entry corresponding to remote
4560 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4562 return zl3vni_local_nh_del(zl3vni
, ip
);
4564 /* We are only interested in neighbors on an SVI that resides on top
4565 * of a VxLAN bridge.
4567 zvni
= zvni_from_svi(ifp
, link_if
);
4571 if (!zvni
->vxlan_if
) {
4573 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4578 if (IS_ZEBRA_DEBUG_VXLAN
)
4579 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4580 ipaddr2str(ip
, buf
, sizeof(buf
)),
4581 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4583 /* If entry doesn't exist, nothing to do. */
4584 n
= zvni_neigh_lookup(zvni
, ip
);
4588 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4590 if (IS_ZEBRA_DEBUG_VXLAN
)
4592 "Trying to del a neigh %s without a mac %s on VNI %u",
4593 ipaddr2str(ip
, buf
, sizeof(buf
)),
4594 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4600 /* If it is a remote entry, the kernel has aged this out or someone has
4601 * deleted it, it needs to be re-installed as Quagga is the owner.
4603 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4604 zvni_neigh_install(zvni
, n
);
4608 /* Remove neighbor from BGP. */
4609 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4610 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
4613 /* Delete this neighbor entry. */
4614 zvni_neigh_del(zvni
, n
);
4616 /* see if the AUTO mac needs to be deleted */
4617 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4618 && !listcount(zmac
->neigh_list
))
4619 zvni_mac_del(zvni
, zmac
);
4625 * Handle neighbor add or update (on a VLAN device / L3 interface)
4628 int zebra_vxlan_local_neigh_add_update(struct interface
*ifp
,
4629 struct interface
*link_if
,
4631 struct ethaddr
*macaddr
, u_int16_t state
,
4634 char buf
[ETHER_ADDR_STRLEN
];
4635 char buf2
[INET6_ADDRSTRLEN
];
4636 zebra_vni_t
*zvni
= NULL
;
4637 zebra_neigh_t
*n
= NULL
;
4638 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
4639 zebra_l3vni_t
*zl3vni
= NULL
;
4641 /* check if this is a remote neigh entry corresponding to remote
4644 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4646 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
4648 /* We are only interested in neighbors on an SVI that resides on top
4649 * of a VxLAN bridge.
4651 zvni
= zvni_from_svi(ifp
, link_if
);
4655 if (IS_ZEBRA_DEBUG_VXLAN
)
4657 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4658 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4659 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4660 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4663 /* create a dummy MAC if the MAC is not already present */
4664 zmac
= zvni_mac_lookup(zvni
, macaddr
);
4666 if (IS_ZEBRA_DEBUG_VXLAN
)
4668 "AUTO MAC %s created for neigh %s on VNI %u",
4669 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4670 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
4672 zmac
= zvni_mac_add(zvni
, macaddr
);
4674 zlog_warn("Failed to add MAC %s VNI %u",
4675 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4680 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
4681 memset(&zmac
->flags
, 0, sizeof(u_int32_t
));
4682 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
4685 /* If same entry already exists, it might be a change or it might be a
4686 * move from remote to local.
4688 n
= zvni_neigh_lookup(zvni
, ip
);
4690 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4691 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
4694 /* Update any params and return - client doesn't
4695 * care about a purely local change.
4697 n
->ifindex
= ifp
->ifindex
;
4701 /* If the MAC has changed,
4702 * need to issue a delete first
4703 * as this means a different MACIP route.
4704 * Also, need to do some unlinking/relinking.
4706 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
4708 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4710 listnode_delete(old_zmac
->neigh_list
, n
);
4711 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
4714 /* Set "local" forwarding info. */
4715 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4716 n
->ifindex
= ifp
->ifindex
;
4717 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4719 /* Link to new MAC */
4720 listnode_add_sort(zmac
->neigh_list
, n
);
4721 } else if (ext_learned
)
4722 /* The neighbor is remote and that is the notification we got.
4725 /* TODO: Evaluate if we need to do anything here. */
4728 /* Neighbor has moved from remote to local. */
4730 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4731 n
->r_vtep_ip
.s_addr
= 0;
4732 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4733 n
->ifindex
= ifp
->ifindex
;
4736 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
4739 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4740 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4741 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4742 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
4745 /* Set "local" forwarding info. */
4746 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4747 n
->ifindex
= ifp
->ifindex
;
4750 /* Before we program this in BGP, we need to check if MAC is locally
4752 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
4753 if (IS_ZEBRA_DEBUG_VXLAN
)
4755 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4756 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4757 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4764 if (IS_ZEBRA_DEBUG_VXLAN
)
4765 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
4766 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4767 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4769 ZEBRA_NEIGH_SET_ACTIVE(n
);
4771 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
4776 * Handle message from client to delete a remote MACIP for a VNI.
4778 int zebra_vxlan_remote_macip_del(struct zserv
*client
, u_short length
,
4779 struct zebra_vrf
*zvrf
)
4783 struct ethaddr macaddr
;
4785 struct in_addr vtep_ip
;
4789 u_short l
= 0, ipa_len
;
4790 char buf
[ETHER_ADDR_STRLEN
];
4791 char buf1
[INET6_ADDRSTRLEN
];
4792 struct interface
*ifp
= NULL
;
4793 struct zebra_if
*zif
= NULL
;
4795 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4796 memset(&ip
, 0, sizeof(struct ipaddr
));
4797 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4801 while (l
< length
) {
4802 /* Obtain each remote MACIP and process. */
4803 /* Message contains VNI, followed by MAC followed by IP (if any)
4804 * followed by remote VTEP IP.
4808 memset(&ip
, 0, sizeof(ip
));
4809 STREAM_GETL(s
, vni
);
4810 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4811 STREAM_GETL(s
, ipa_len
);
4813 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4815 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4817 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4818 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4819 l
+= IPV4_MAX_BYTELEN
;
4821 if (IS_ZEBRA_DEBUG_VXLAN
)
4823 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4824 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4825 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4827 zebra_route_string(client
->proto
));
4829 /* Locate VNI hash entry - expected to exist. */
4830 zvni
= zvni_lookup(vni
);
4832 if (IS_ZEBRA_DEBUG_VXLAN
)
4834 "Failed to locate VNI hash upon remote MACIP DEL, "
4839 ifp
= zvni
->vxlan_if
;
4842 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4848 /* If down or not mapped to a bridge, we're done. */
4849 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
4852 /* The remote VTEP specified is normally expected to exist, but
4854 * possible that the peer may delete the VTEP before deleting
4856 * referring to the VTEP, in which case the handler (see
4858 * would have already deleted the MACs.
4860 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4863 mac
= zvni_mac_lookup(zvni
, &macaddr
);
4865 n
= zvni_neigh_lookup(zvni
, &ip
);
4869 "Failed to locate MAC %s for neigh %s VNI %u",
4870 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4871 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
4875 /* If the remote mac or neighbor doesn't exist there is nothing
4877 * to do. Otherwise, uninstall the entry and then remove it.
4882 /* Uninstall remote neighbor or MAC. */
4884 /* When the MAC changes for an IP, it is possible the
4886 * update the new MAC before trying to delete the "old"
4888 * (as these are two different MACIP routes). Do the
4890 * if the MAC matches.
4892 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4893 && (memcmp(n
->emac
.octet
, macaddr
.octet
,
4896 zvni_neigh_uninstall(zvni
, n
);
4897 zvni_neigh_del(zvni
, n
);
4898 zvni_deref_ip2mac(zvni
, mac
, 1);
4901 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4902 zvni_process_neigh_on_remote_mac_del(zvni
,
4905 if (list_isempty(mac
->neigh_list
)) {
4906 zvni_mac_uninstall(zvni
, mac
, 0);
4907 zvni_mac_del(zvni
, mac
);
4909 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4919 * Handle message from client to add a remote MACIP for a VNI. This
4920 * could be just the add of a MAC address or the add of a neighbor
4923 int zebra_vxlan_remote_macip_add(struct zserv
*client
, u_short length
,
4924 struct zebra_vrf
*zvrf
)
4928 struct ethaddr macaddr
;
4930 struct in_addr vtep_ip
;
4932 zebra_vtep_t
*zvtep
;
4933 zebra_mac_t
*mac
, *old_mac
;
4935 u_short l
= 0, ipa_len
;
4936 int update_mac
= 0, update_neigh
= 0;
4937 char buf
[ETHER_ADDR_STRLEN
];
4938 char buf1
[INET6_ADDRSTRLEN
];
4940 struct interface
*ifp
= NULL
;
4941 struct zebra_if
*zif
= NULL
;
4943 memset(&macaddr
, 0, sizeof(struct ethaddr
));
4944 memset(&ip
, 0, sizeof(struct ipaddr
));
4945 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
4947 if (!EVPN_ENABLED(zvrf
)) {
4948 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
4949 __PRETTY_FUNCTION__
);
4955 while (l
< length
) {
4956 /* Obtain each remote MACIP and process. */
4957 /* Message contains VNI, followed by MAC followed by IP (if any)
4958 * followed by remote VTEP IP.
4960 update_mac
= update_neigh
= 0;
4963 memset(&ip
, 0, sizeof(ip
));
4964 STREAM_GETL(s
, vni
);
4965 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
4966 STREAM_GETL(s
, ipa_len
);
4968 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
4970 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
4972 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
4973 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
4974 l
+= IPV4_MAX_BYTELEN
;
4976 /* Get 'sticky' flag. */
4977 STREAM_GETC(s
, sticky
);
4980 if (IS_ZEBRA_DEBUG_VXLAN
)
4982 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
4983 sticky
? "sticky " : "",
4984 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
4985 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
4987 zebra_route_string(client
->proto
));
4989 /* Locate VNI hash entry - expected to exist. */
4990 zvni
= zvni_lookup(vni
);
4993 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
4997 ifp
= zvni
->vxlan_if
;
5000 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5006 /* If down or not mapped to a bridge, we're done. */
5007 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5010 /* The remote VTEP specified should normally exist, but it is
5012 * that when peering comes up, peer may advertise MACIP routes
5014 * advertising type-3 routes.
5016 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5018 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5020 "Failed to add remote VTEP, VNI %u zvni %p",
5025 zvni_vtep_install(zvni
, &vtep_ip
);
5028 /* First, check if the remote MAC is unknown or has a change. If
5030 * that needs to be updated first. Note that client could
5032 * MAC and MACIP separately or just install the latter.
5034 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5035 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
5036 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
5038 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
5043 mac
= zvni_mac_add(zvni
, &macaddr
);
5046 "Failed to add MAC %s VNI %u Remote VTEP %s",
5047 prefix_mac2str(&macaddr
, buf
,
5049 vni
, inet_ntoa(vtep_ip
));
5053 /* Is this MAC created for a MACIP? */
5055 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5058 /* Set "auto" and "remote" forwarding info. */
5059 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5060 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5061 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5062 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
5065 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5067 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5069 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
5071 /* Install the entry. */
5072 zvni_mac_install(zvni
, mac
);
5075 /* If there is no IP, continue - after clearing AUTO flag of
5078 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5082 /* Check if the remote neighbor itself is unknown or has a
5084 * If so, create or update and then install the entry.
5086 n
= zvni_neigh_lookup(zvni
, &ip
);
5087 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5088 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
5089 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
5094 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
5097 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5098 ipaddr2str(&ip
, buf1
,
5100 prefix_mac2str(&macaddr
, buf
,
5102 vni
, inet_ntoa(vtep_ip
));
5106 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
5108 /* MAC change, update neigh list for old and new
5110 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
5112 listnode_delete(old_mac
->neigh_list
, n
);
5113 zvni_deref_ip2mac(zvni
, old_mac
, 1);
5115 listnode_add_sort(mac
->neigh_list
, n
);
5116 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
5119 /* Set "remote" forwarding info. */
5120 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
5121 /* TODO: Handle MAC change. */
5122 n
->r_vtep_ip
= vtep_ip
;
5123 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
5125 /* Install the entry. */
5126 zvni_neigh_install(zvni
, n
);
5135 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5136 * us, this must involve a multihoming scenario. Treat this as implicit delete
5137 * of any prior local MAC.
5139 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5140 struct interface
*br_if
,
5141 struct ethaddr
*macaddr
, vlanid_t vid
)
5143 struct zebra_if
*zif
;
5144 struct zebra_l2info_vxlan
*vxl
;
5148 char buf
[ETHER_ADDR_STRLEN
];
5153 vxl
= &zif
->l2info
.vxl
;
5156 /* Check if EVPN is enabled. */
5157 if (!is_evpn_enabled())
5160 /* Locate hash entry; it is expected to exist. */
5161 zvni
= zvni_lookup(vni
);
5165 /* If entry doesn't exist, nothing to do. */
5166 mac
= zvni_mac_lookup(zvni
, macaddr
);
5170 /* Is it a local entry? */
5171 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5174 if (IS_ZEBRA_DEBUG_VXLAN
)
5176 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5177 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5178 ifp
->name
, ifp
->ifindex
, vni
);
5180 /* Remove MAC from BGP. */
5181 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
5182 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
5183 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
5186 * If there are no neigh associated with the mac delete the mac
5187 * else mark it as AUTO for forward reference
5189 if (!listcount(mac
->neigh_list
)) {
5190 zvni_mac_del(zvni
, mac
);
5192 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5193 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5200 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5201 * This can happen because the remote MAC entries are also added as "dynamic",
5202 * so the kernel can ageout the entry.
5204 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5205 struct interface
*br_if
,
5206 struct ethaddr
*macaddr
, vlanid_t vid
)
5208 struct zebra_if
*zif
;
5209 struct zebra_l2info_vxlan
*vxl
;
5213 char buf
[ETHER_ADDR_STRLEN
];
5217 vxl
= &zif
->l2info
.vxl
;
5220 /* Check if EVPN is enabled. */
5221 if (!is_evpn_enabled())
5224 /* Locate hash entry; it is expected to exist. */
5225 zvni
= zvni_lookup(vni
);
5229 /* If entry doesn't exist, nothing to do. */
5230 mac
= zvni_mac_lookup(zvni
, macaddr
);
5234 /* Is it a remote entry? */
5235 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5238 if (IS_ZEBRA_DEBUG_VXLAN
)
5239 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5240 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5243 zvni_mac_install(zvni
, mac
);
5248 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5250 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5251 struct ethaddr
*macaddr
, vlanid_t vid
)
5255 char buf
[ETHER_ADDR_STRLEN
];
5258 /* We are interested in MACs only on ports or (port, VLAN) that
5261 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5264 if (!zvni
->vxlan_if
) {
5265 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5270 if (IS_ZEBRA_DEBUG_VXLAN
)
5271 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5272 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5273 ifp
->ifindex
, vid
, zvni
->vni
);
5275 /* If entry doesn't exist, nothing to do. */
5276 mac
= zvni_mac_lookup(zvni
, macaddr
);
5280 /* Is it a local entry? */
5281 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5284 /* Remove MAC from BGP. */
5285 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
5286 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
,
5287 (sticky
? ZEBRA_MAC_TYPE_STICKY
: 0));
5289 /* Update all the neigh entries associated with this mac */
5290 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5293 * If there are no neigh associated with the mac delete the mac
5294 * else mark it as AUTO for forward reference
5296 if (!listcount(mac
->neigh_list
)) {
5297 zvni_mac_del(zvni
, mac
);
5299 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5300 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5307 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5309 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5310 struct interface
*br_if
,
5311 struct ethaddr
*macaddr
, vlanid_t vid
,
5316 char buf
[ETHER_ADDR_STRLEN
];
5320 /* We are interested in MACs only on ports or (port, VLAN) that
5323 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5325 if (IS_ZEBRA_DEBUG_VXLAN
)
5327 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5328 sticky
? "sticky " : "",
5329 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5330 ifp
->name
, ifp
->ifindex
, vid
);
5334 if (!zvni
->vxlan_if
) {
5335 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5340 if (IS_ZEBRA_DEBUG_VXLAN
)
5342 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5343 sticky
? "sticky " : "",
5344 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5345 ifp
->ifindex
, vid
, zvni
->vni
);
5347 /* If same entry already exists, nothing to do. */
5348 mac
= zvni_mac_lookup(zvni
, macaddr
);
5350 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5351 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5357 * return if nothing has changed.
5358 * inform bgp if sticky flag has changed
5359 * update locally and do not inform bgp if local
5360 * parameters like interface has changed
5362 if (mac_sticky
== sticky
5363 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5364 && mac
->fwd_info
.local
.vid
== vid
) {
5365 if (IS_ZEBRA_DEBUG_VXLAN
)
5367 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5368 "entry exists and has not changed ",
5369 sticky
? "sticky " : "",
5370 prefix_mac2str(macaddr
, buf
,
5372 ifp
->name
, ifp
->ifindex
, vid
,
5375 } else if (mac_sticky
!= sticky
) {
5378 add
= 0; /* This is an update of local
5381 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5383 * If we have already learned the MAC as a remote sticky
5385 * this is a operator error and we must log a warning
5387 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5389 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5390 prefix_mac2str(macaddr
, buf
,
5392 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5400 mac
= zvni_mac_add(zvni
, macaddr
);
5402 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5403 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5404 ifp
->name
, ifp
->ifindex
, vid
);
5409 /* Set "local" forwarding info. */
5410 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5411 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5412 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5413 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5414 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5415 mac
->fwd_info
.local
.vid
= vid
;
5418 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5420 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5422 /* Inform BGP if required. */
5424 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5425 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5433 * Handle message from client to delete a remote VTEP for a VNI.
5435 int zebra_vxlan_remote_vtep_del(struct zserv
*client
, u_short length
,
5436 struct zebra_vrf
*zvrf
)
5441 struct in_addr vtep_ip
;
5443 zebra_vtep_t
*zvtep
;
5444 struct interface
*ifp
;
5445 struct zebra_if
*zif
;
5447 if (!is_evpn_enabled()) {
5448 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5449 __PRETTY_FUNCTION__
);
5453 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5454 zlog_err("Recv MACIP DEL for non-default VRF %u",
5461 while (l
< length
) {
5462 /* Obtain each remote VTEP and process. */
5463 STREAM_GETL(s
, vni
);
5465 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5466 l
+= IPV4_MAX_BYTELEN
;
5468 if (IS_ZEBRA_DEBUG_VXLAN
)
5469 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5470 inet_ntoa(vtep_ip
), vni
,
5471 zebra_route_string(client
->proto
));
5473 /* Locate VNI hash entry - expected to exist. */
5474 zvni
= zvni_lookup(vni
);
5476 if (IS_ZEBRA_DEBUG_VXLAN
)
5478 "Failed to locate VNI hash upon remote VTEP DEL, "
5484 ifp
= zvni
->vxlan_if
;
5487 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5493 /* If down or not mapped to a bridge, we're done. */
5494 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5497 /* If the remote VTEP does not exist, there's nothing more to
5499 * Otherwise, uninstall any remote MACs pointing to this VTEP
5501 * then, the VTEP entry itself and remove it.
5503 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5507 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5508 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5509 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5510 zvni_vtep_del(zvni
, zvtep
);
5518 * Handle message from client to add a remote VTEP for a VNI.
5520 int zebra_vxlan_remote_vtep_add(struct zserv
*client
, u_short length
,
5521 struct zebra_vrf
*zvrf
)
5526 struct in_addr vtep_ip
;
5528 struct interface
*ifp
;
5529 struct zebra_if
*zif
;
5531 if (!is_evpn_enabled()) {
5532 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5533 __PRETTY_FUNCTION__
);
5537 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5538 zlog_err("Recv MACIP ADD for non-default VRF %u",
5545 while (l
< length
) {
5546 /* Obtain each remote VTEP and process. */
5547 STREAM_GETL(s
, vni
);
5549 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5550 l
+= IPV4_MAX_BYTELEN
;
5552 if (IS_ZEBRA_DEBUG_VXLAN
)
5553 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5554 inet_ntoa(vtep_ip
), vni
,
5555 zebra_route_string(client
->proto
));
5557 /* Locate VNI hash entry - expected to exist. */
5558 zvni
= zvni_lookup(vni
);
5561 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5566 ifp
= zvni
->vxlan_if
;
5569 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5576 /* If down or not mapped to a bridge, we're done. */
5577 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5580 /* If the remote VTEP already exists,
5581 there's nothing more to do. */
5582 if (zvni_vtep_find(zvni
, &vtep_ip
))
5585 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5587 "Failed to add remote VTEP, VNI %u zvni %p",
5592 zvni_vtep_install(zvni
, &vtep_ip
);
5600 * Add/Del gateway macip to evpn
5602 * 1. SVI interface on a vlan aware bridge
5603 * 2. SVI interface on a vlan unaware bridge
5604 * 3. vrr interface (MACVLAN) associated to a SVI
5605 * We advertise macip routes for an interface if it is associated to VxLan vlan
5607 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5611 struct ethaddr macaddr
;
5612 zebra_vni_t
*zvni
= NULL
;
5614 memset(&ip
, 0, sizeof(struct ipaddr
));
5615 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5617 /* Check if EVPN is enabled. */
5618 if (!is_evpn_enabled())
5621 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5622 struct interface
*svi_if
=
5623 NULL
; /* SVI corresponding to the MACVLAN */
5624 struct zebra_if
*ifp_zif
=
5625 NULL
; /* Zebra daemon specific info for MACVLAN */
5626 struct zebra_if
*svi_if_zif
=
5627 NULL
; /* Zebra daemon specific info for SVI*/
5629 ifp_zif
= ifp
->info
;
5634 * for a MACVLAN interface the link represents the svi_if
5636 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5637 ifp_zif
->link_ifindex
);
5639 zlog_err("MACVLAN %s(%u) without link information",
5640 ifp
->name
, ifp
->ifindex
);
5644 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5646 * If it is a vlan aware bridge then the link gives the
5647 * bridge information
5649 struct interface
*svi_if_link
= NULL
;
5651 svi_if_zif
= svi_if
->info
;
5653 svi_if_link
= if_lookup_by_index_per_ns(
5654 zebra_ns_lookup(NS_DEFAULT
),
5655 svi_if_zif
->link_ifindex
);
5656 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5658 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5660 * If it is a vlan unaware bridge then svi is the bridge
5663 zvni
= zvni_from_svi(svi_if
, svi_if
);
5665 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5666 struct zebra_if
*svi_if_zif
=
5667 NULL
; /* Zebra daemon specific info for SVI */
5668 struct interface
*svi_if_link
=
5669 NULL
; /* link info for the SVI = bridge info */
5671 svi_if_zif
= ifp
->info
;
5672 svi_if_link
= if_lookup_by_index_per_ns(
5673 zebra_ns_lookup(NS_DEFAULT
), svi_if_zif
->link_ifindex
);
5674 if (svi_if_zif
&& svi_if_link
)
5675 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5676 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5677 zvni
= zvni_from_svi(ifp
, ifp
);
5683 if (!zvni
->vxlan_if
) {
5684 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5690 /* check if we are advertising gw macip routes */
5691 if (!advertise_gw_macip_enabled(zvni
))
5694 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5696 if (p
->family
== AF_INET
) {
5697 ip
.ipa_type
= IPADDR_V4
;
5698 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5699 sizeof(struct in_addr
));
5700 } else if (p
->family
== AF_INET6
) {
5701 ip
.ipa_type
= IPADDR_V6
;
5702 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5703 sizeof(struct in6_addr
));
5708 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5710 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5716 * Handle SVI interface going down.
5717 * SVI can be associated to either L3-VNI or L2-VNI.
5718 * For L2-VNI: At this point, this is a NOP since
5719 * the kernel deletes the neighbor entries on this SVI (if any).
5720 * We only need to update the vrf corresponding to zvni.
5721 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5724 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5726 zebra_l3vni_t
*zl3vni
= NULL
;
5728 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5731 /* process l3-vni down */
5732 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5734 /* remove association with svi-if */
5735 zl3vni
->svi_if
= NULL
;
5737 zebra_vni_t
*zvni
= NULL
;
5739 /* since we dont have svi corresponding to zvni, we associate it
5740 * to default vrf. Note: the corresponding neigh entries on the
5741 * SVI would have already been deleted */
5742 zvni
= zvni_from_svi(ifp
, link_if
);
5744 zvni
->vrf_id
= VRF_DEFAULT
;
5746 /* update the tenant vrf in BGP */
5747 zvni_send_add_to_client(zvni
);
5754 * Handle SVI interface coming up.
5755 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5757 * For L2-VNI: we need to install any remote neighbors entried (used for
5759 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5761 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
5763 zebra_vni_t
*zvni
= NULL
;
5764 zebra_l3vni_t
*zl3vni
= NULL
;
5766 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5769 /* associate with svi */
5770 zl3vni
->svi_if
= ifp
;
5772 /* process oper-up */
5773 if (is_l3vni_oper_up(zl3vni
))
5774 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5777 /* process SVI up for l2-vni */
5778 struct neigh_walk_ctx n_wctx
;
5780 zvni
= zvni_from_svi(ifp
, link_if
);
5784 if (!zvni
->vxlan_if
) {
5785 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5790 if (IS_ZEBRA_DEBUG_VXLAN
)
5791 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5792 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
5793 vrf_id_to_name(ifp
->vrf_id
));
5795 /* update the vrf information for l2-vni and inform bgp */
5796 zvni
->vrf_id
= ifp
->vrf_id
;
5797 zvni_send_add_to_client(zvni
);
5799 /* Install any remote neighbors for this VNI. */
5800 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
5802 hash_iterate(zvni
->neigh_table
,
5803 zvni_install_neigh_hash
,
5811 * Handle VxLAN interface down
5813 int zebra_vxlan_if_down(struct interface
*ifp
)
5816 struct zebra_if
*zif
= NULL
;
5817 struct zebra_l2info_vxlan
*vxl
= NULL
;
5819 /* Check if EVPN is enabled. */
5820 if (!is_evpn_enabled())
5825 vxl
= &zif
->l2info
.vxl
;
5829 if (is_vni_l3(vni
)) {
5831 /* process-if-down for l3-vni */
5832 zebra_l3vni_t
*zl3vni
= NULL
;
5834 if (IS_ZEBRA_DEBUG_VXLAN
)
5835 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
5836 ifp
->name
, ifp
->ifindex
, vni
);
5838 zl3vni
= zl3vni_lookup(vni
);
5841 "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
5842 ifp
->name
, ifp
->ifindex
, vni
);
5846 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5849 /* process if-down for l2-vni */
5852 if (IS_ZEBRA_DEBUG_VXLAN
)
5853 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
5854 ifp
->name
, ifp
->ifindex
, vni
);
5856 /* Locate hash entry; it is expected to exist. */
5857 zvni
= zvni_lookup(vni
);
5860 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5861 ifp
->name
, ifp
->ifindex
, vni
);
5865 assert(zvni
->vxlan_if
== ifp
);
5867 /* Delete this VNI from BGP. */
5868 zvni_send_del_to_client(zvni
->vni
);
5870 /* Free up all neighbors and MACs, if any. */
5871 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
5872 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
5874 /* Free up all remote VTEPs, if any. */
5875 zvni_vtep_del_all(zvni
, 1);
5881 * Handle VxLAN interface up - update BGP if required.
5883 int zebra_vxlan_if_up(struct interface
*ifp
)
5886 struct zebra_if
*zif
= NULL
;
5887 struct zebra_l2info_vxlan
*vxl
= NULL
;
5889 /* Check if EVPN is enabled. */
5890 if (!is_evpn_enabled())
5895 vxl
= &zif
->l2info
.vxl
;
5898 if (is_vni_l3(vni
)) {
5900 /* Handle L3-VNI add */
5901 zebra_l3vni_t
*zl3vni
= NULL
;
5903 if (IS_ZEBRA_DEBUG_VXLAN
)
5904 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
5905 ifp
->name
, ifp
->ifindex
, vni
);
5907 zl3vni
= zl3vni_lookup(vni
);
5910 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
5911 ifp
->name
, ifp
->ifindex
, vni
);
5915 /* we need to associate with SVI, if any, we can associate with
5916 * svi-if only after association with vxlan-intf is complete
5918 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
5920 if (is_l3vni_oper_up(zl3vni
))
5921 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
5923 /* Handle L2-VNI add */
5925 zebra_vni_t
*zvni
= NULL
;
5926 zebra_l3vni_t
*zl3vni
= NULL
;
5927 struct interface
*vlan_if
= NULL
;
5929 if (IS_ZEBRA_DEBUG_VXLAN
)
5930 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
5931 ifp
->name
, ifp
->ifindex
, vni
);
5933 /* Locate hash entry; it is expected to exist. */
5934 zvni
= zvni_lookup(vni
);
5937 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
5938 ifp
->name
, ifp
->ifindex
, vni
);
5942 assert(zvni
->vxlan_if
== ifp
);
5943 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
5944 zif
->brslave_info
.br_if
);
5946 zvni
->vrf_id
= vlan_if
->vrf_id
;
5947 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
5949 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
5952 /* If part of a bridge, inform BGP about this VNI. */
5953 /* Also, read and populate local MACs and neighbors. */
5954 if (zif
->brslave_info
.br_if
) {
5955 zvni_send_add_to_client(zvni
);
5956 zvni_read_mac_neigh(zvni
, ifp
);
5964 * Handle VxLAN interface delete. Locate and remove entry in hash table
5965 * and update BGP, if required.
5967 int zebra_vxlan_if_del(struct interface
*ifp
)
5970 struct zebra_if
*zif
= NULL
;
5971 struct zebra_l2info_vxlan
*vxl
= NULL
;
5973 /* Check if EVPN is enabled. */
5974 if (!is_evpn_enabled())
5979 vxl
= &zif
->l2info
.vxl
;
5982 if (is_vni_l3(vni
)) {
5984 /* process if-del for l3-vni */
5985 zebra_l3vni_t
*zl3vni
= NULL
;
5987 if (IS_ZEBRA_DEBUG_VXLAN
)
5988 zlog_debug("Del L3-VNI %u intf %s(%u)",
5989 vni
, ifp
->name
, ifp
->ifindex
);
5991 zl3vni
= zl3vni_lookup(vni
);
5994 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5995 ifp
->name
, ifp
->ifindex
, vni
);
5999 /* process oper-down for l3-vni */
6000 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6002 /* remove the association with vxlan_if */
6003 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6004 zl3vni
->vxlan_if
= NULL
;
6007 /* process if-del for l2-vni*/
6008 zebra_vni_t
*zvni
= NULL
;
6009 zebra_l3vni_t
*zl3vni
= NULL
;
6011 if (IS_ZEBRA_DEBUG_VXLAN
)
6012 zlog_debug("Del L2-VNI %u intf %s(%u)",
6013 vni
, ifp
->name
, ifp
->ifindex
);
6015 /* Locate hash entry; it is expected to exist. */
6016 zvni
= zvni_lookup(vni
);
6019 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6020 ifp
->name
, ifp
->ifindex
, vni
);
6024 /* remove from l3-vni list */
6025 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6027 listnode_delete(zl3vni
->l2vnis
, zvni
);
6029 /* Delete VNI from BGP. */
6030 zvni_send_del_to_client(zvni
->vni
);
6032 /* Free up all neighbors and MAC, if any. */
6033 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6034 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6036 /* Free up all remote VTEPs, if any. */
6037 zvni_vtep_del_all(zvni
, 0);
6039 /* Delete the hash entry. */
6040 if (zvni_del(zvni
)) {
6041 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6042 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6051 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6053 int zebra_vxlan_if_update(struct interface
*ifp
, u_int16_t chgflags
)
6056 struct zebra_if
*zif
= NULL
;
6057 struct zebra_l2info_vxlan
*vxl
= NULL
;
6059 /* Check if EVPN is enabled. */
6060 if (!is_evpn_enabled())
6065 vxl
= &zif
->l2info
.vxl
;
6068 if (is_vni_l3(vni
)) {
6069 zebra_l3vni_t
*zl3vni
= NULL
;
6071 zl3vni
= zl3vni_lookup(vni
);
6074 "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
6075 ifp
->name
, ifp
->ifindex
, vni
);
6079 if (IS_ZEBRA_DEBUG_VXLAN
)
6081 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6082 vni
, ifp
->name
, ifp
->ifindex
,
6083 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6084 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6086 /* Removed from bridge? Cleanup and return */
6087 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6088 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6089 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6093 /* access-vlan change - process oper down, associate with new
6094 * svi_if and then process oper up again
6096 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6097 if (if_is_operative(ifp
)) {
6098 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6099 zl3vni
->svi_if
= NULL
;
6100 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6101 if (is_l3vni_oper_up(zl3vni
))
6102 zebra_vxlan_process_l3vni_oper_up(
6107 /* if we have a valid new master, process l3-vni oper up */
6108 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6109 if (is_l3vni_oper_up(zl3vni
))
6110 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6113 zebra_vni_t
*zvni
= NULL
;
6115 /* Update VNI hash. */
6116 zvni
= zvni_lookup(vni
);
6119 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6120 ifp
->name
, ifp
->ifindex
, vni
);
6124 if (IS_ZEBRA_DEBUG_VXLAN
)
6126 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6127 vni
, ifp
->name
, ifp
->ifindex
,
6128 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6129 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6131 /* Removed from bridge? Cleanup and return */
6132 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6133 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6134 /* Delete from client, remove all remote VTEPs */
6135 /* Also, free up all MACs and neighbors. */
6136 zvni_send_del_to_client(zvni
->vni
);
6137 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6138 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6139 zvni_vtep_del_all(zvni
, 1);
6143 /* Handle other changes. */
6144 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6145 /* Remove all existing local neigh and MACs for this VNI
6146 * (including from BGP)
6148 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6149 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6152 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6153 zvni
->vxlan_if
= ifp
;
6155 /* Take further actions needed.
6156 * Note that if we are here, there is a change of interest.
6158 /* If down or not mapped to a bridge, we're done. */
6159 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6162 /* Inform BGP, if there is a change of interest. */
6164 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6165 zvni_send_add_to_client(zvni
);
6167 /* If there is a valid new master or a VLAN mapping change,
6168 * read and populate local MACs and neighbors.
6169 * Also, reinstall any remote MACs and neighbors
6170 * for this VNI (based on new VLAN).
6172 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6173 zvni_read_mac_neigh(zvni
, ifp
);
6174 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6175 struct mac_walk_ctx m_wctx
;
6176 struct neigh_walk_ctx n_wctx
;
6178 zvni_read_mac_neigh(zvni
, ifp
);
6180 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6182 hash_iterate(zvni
->mac_table
,
6183 zvni_install_mac_hash
,
6186 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6188 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6197 * Handle VxLAN interface add.
6199 int zebra_vxlan_if_add(struct interface
*ifp
)
6202 struct zebra_if
*zif
= NULL
;
6203 struct zebra_l2info_vxlan
*vxl
= NULL
;
6205 /* Check if EVPN is enabled. */
6206 if (!is_evpn_enabled())
6211 vxl
= &zif
->l2info
.vxl
;
6214 if (is_vni_l3(vni
)) {
6216 /* process if-add for l3-vni*/
6217 zebra_l3vni_t
*zl3vni
= NULL
;
6219 if (IS_ZEBRA_DEBUG_VXLAN
)
6221 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6222 vni
, ifp
->name
, ifp
->ifindex
,
6223 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6224 zif
->brslave_info
.bridge_ifindex
);
6227 * we expect the l3-vni has entry to be present here.
6228 * The only place l3-vni is created in zebra is vrf-vni mapping
6229 * command. This might change when we have the switchd support
6230 * for l3-vxlan interface.
6232 zl3vni
= zl3vni_lookup(vni
);
6235 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
6236 ifp
->name
, ifp
->ifindex
, vni
);
6240 /* associate with vxlan_if */
6241 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6242 zl3vni
->vxlan_if
= ifp
;
6244 /* Associate with SVI, if any. We can associate with svi-if only
6245 * after association with vxlan_if is complete */
6246 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6248 if (is_l3vni_oper_up(zl3vni
))
6249 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6252 /* process if-add for l2-vni */
6253 zebra_vni_t
*zvni
= NULL
;
6254 zebra_l3vni_t
*zl3vni
= NULL
;
6255 struct interface
*vlan_if
= NULL
;
6257 /* Create or update VNI hash. */
6258 zvni
= zvni_lookup(vni
);
6260 zvni
= zvni_add(vni
);
6263 "Failed to add VNI hash, IF %s(%u) VNI %u",
6264 ifp
->name
, ifp
->ifindex
, vni
);
6269 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6270 zvni
->vxlan_if
= ifp
;
6271 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6272 zif
->brslave_info
.br_if
);
6274 zvni
->vrf_id
= vlan_if
->vrf_id
;
6275 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6277 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6280 if (IS_ZEBRA_DEBUG_VXLAN
)
6282 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6284 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
) :
6286 ifp
->name
, ifp
->ifindex
,
6287 vxl
->access_vlan
, inet_ntoa(vxl
->vtep_ip
),
6288 zif
->brslave_info
.bridge_ifindex
);
6290 /* If down or not mapped to a bridge, we're done. */
6291 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6295 zvni_send_add_to_client(zvni
);
6297 /* Read and populate local MACs and neighbors */
6298 zvni_read_mac_neigh(zvni
, ifp
);
6304 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
,
6306 char *err
, int err_str_sz
,
6309 zebra_l3vni_t
*zl3vni
= NULL
;
6310 struct zebra_vrf
*zvrf_default
= NULL
;
6312 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6316 if (IS_ZEBRA_DEBUG_VXLAN
)
6317 zlog_debug("vrf %s vni %u %s",
6320 add
? "ADD" : "DEL");
6324 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6326 /* check if the vni is already present under zvrf */
6328 snprintf(err
, err_str_sz
,
6329 "VNI is already configured under the vrf");
6333 /* check if this VNI is already present in the system */
6334 zl3vni
= zl3vni_lookup(vni
);
6336 snprintf(err
, err_str_sz
,
6337 "VNI is already configured as L3-VNI");
6341 /* add the L3-VNI to the global table */
6342 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6344 snprintf(err
, err_str_sz
,
6345 "Could not add L3-VNI");
6349 /* associate the vrf with vni */
6352 /* associate with vxlan-intf;
6353 * we need to associate with the vxlan-intf first
6355 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6357 /* associate with corresponding SVI interface, we can associate
6358 * with svi-if only after vxlan interface association is
6361 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6363 /* formulate l2vni list */
6364 hash_iterate(zvrf_default
->vni_table
,
6365 zvni_add_to_l3vni_list
, zl3vni
);
6367 if (is_l3vni_oper_up(zl3vni
))
6368 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6371 zl3vni
= zl3vni_lookup(vni
);
6373 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6377 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6379 /* delete and uninstall all rmacs */
6380 hash_iterate(zl3vni
->rmac_table
,
6381 zl3vni_del_rmac_hash_entry
,
6384 /* delete and uninstall all next-hops */
6385 hash_iterate(zl3vni
->nh_table
,
6386 zl3vni_del_nh_hash_entry
,
6392 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6397 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6399 zebra_l3vni_t
*zl3vni
= NULL
;
6401 zl3vni
= zl3vni_from_vrf(zvrf_id(zvrf
));
6405 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6407 zebra_vxlan_handle_vni_transition(zvrf
, zl3vni
->vni
, 0);
6413 * Handle message from client to enable/disable advertisement of g/w macip
6416 int zebra_vxlan_advertise_gw_macip(struct zserv
*client
, u_short length
,
6417 struct zebra_vrf
*zvrf
)
6422 zebra_vni_t
*zvni
= NULL
;
6423 struct interface
*ifp
= NULL
;
6425 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6426 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6432 STREAM_GETC(s
, advertise
);
6433 STREAM_GET(&vni
, s
, 3);
6436 if (IS_ZEBRA_DEBUG_VXLAN
)
6437 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6438 advertise
? "enabled" : "disabled",
6439 advertise_gw_macip_enabled(NULL
)
6443 if (zvrf
->advertise_gw_macip
== advertise
)
6446 zvrf
->advertise_gw_macip
= advertise
;
6448 if (advertise_gw_macip_enabled(zvni
))
6449 hash_iterate(zvrf
->vni_table
,
6450 zvni_gw_macip_add_for_vni_hash
, NULL
);
6452 hash_iterate(zvrf
->vni_table
,
6453 zvni_gw_macip_del_for_vni_hash
, NULL
);
6456 struct zebra_if
*zif
= NULL
;
6457 struct zebra_l2info_vxlan zl2_info
;
6458 struct interface
*vlan_if
= NULL
;
6459 struct interface
*vrr_if
= NULL
;
6461 if (IS_ZEBRA_DEBUG_VXLAN
)
6463 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6464 advertise
? "enabled" : "disabled", vni
,
6465 advertise_gw_macip_enabled(zvni
)
6469 zvni
= zvni_lookup(vni
);
6473 if (zvni
->advertise_gw_macip
== advertise
)
6476 zvni
->advertise_gw_macip
= advertise
;
6478 ifp
= zvni
->vxlan_if
;
6484 /* If down or not mapped to a bridge, we're done. */
6485 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6488 zl2_info
= zif
->l2info
.vxl
;
6490 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6491 zif
->brslave_info
.br_if
);
6495 if (advertise_gw_macip_enabled(zvni
)) {
6496 /* Add primary SVI MAC-IP */
6497 zvni_add_macip_for_intf(vlan_if
, zvni
);
6499 /* Add VRR MAC-IP - if any*/
6500 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6502 zvni_add_macip_for_intf(vrr_if
, zvni
);
6504 /* Del primary MAC-IP */
6505 zvni_del_macip_for_intf(vlan_if
, zvni
);
6507 /* Del VRR MAC-IP - if any*/
6508 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6510 zvni_del_macip_for_intf(vrr_if
, zvni
);
6520 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6521 * When enabled, the VNI hash table will be built and MAC FDB table read;
6522 * when disabled, the entries should be deleted and remote VTEPs and MACs
6523 * uninstalled from the kernel.
6525 int zebra_vxlan_advertise_all_vni(struct zserv
*client
,
6526 u_short length
, struct zebra_vrf
*zvrf
)
6528 struct stream
*s
= NULL
;
6530 struct zebra_ns
*zns
= NULL
;
6532 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6533 zlog_err("EVPN VNI Adv for non-default VRF %u",
6539 STREAM_GETC(s
, advertise
);
6541 if (IS_ZEBRA_DEBUG_VXLAN
)
6542 zlog_debug("EVPN VNI Adv %s, currently %s",
6543 advertise
? "enabled" : "disabled",
6544 is_evpn_enabled() ? "enabled" : "disabled");
6546 if (zvrf
->advertise_all_vni
== advertise
)
6549 zvrf
->advertise_all_vni
= advertise
;
6550 if (is_evpn_enabled()) {
6551 /* Build VNI hash table and inform BGP. */
6552 zvni_build_hash_table();
6554 /* Add all SVI (L3 GW) MACs to BGP*/
6555 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6558 /* Read the MAC FDB */
6559 macfdb_read(zvrf
->zns
);
6561 /* Read neighbors */
6562 neigh_read(zvrf
->zns
);
6564 /* Cleanup VTEPs for all VNIs - uninstall from
6565 * kernel and free entries.
6567 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6569 /* cleanup all l3vnis */
6570 zns
= zebra_ns_lookup(NS_DEFAULT
);
6574 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
6582 * Allocate VNI hash table for this VRF and do other initialization.
6583 * NOTE: Currently supported only for default VRF.
6585 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6589 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6590 "Zebra VRF VNI Table");
6593 /* Close all VNI handling */
6594 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6598 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6599 hash_free(zvrf
->vni_table
);
6602 /* init the l3vni table */
6603 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6605 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6606 "Zebra VRF L3 VNI table");
6609 /* free l3vni table */
6610 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6612 hash_free(zns
->l3vni_table
);
6615 /* get the l3vni svi ifindex */
6616 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6618 zebra_l3vni_t
*zl3vni
= NULL
;
6620 zl3vni
= zl3vni_from_vrf(vrf_id
);
6621 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6624 return zl3vni
->svi_if
->ifindex
;