2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 #include "zebra/rib.h"
39 #include "zebra/zebra_ns.h"
40 #include "zebra/zserv.h"
41 #include "zebra/debug.h"
42 #include "zebra/interface.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_vxlan_private.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_l2.h"
50 DEFINE_MTYPE_STATIC(ZEBRA
, HOST_PREFIX
, "host prefix");
51 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
54 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
55 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
59 /* static function declarations */
60 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
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
, struct ethaddr
*macaddr
,
77 struct ipaddr
*ip
, uint8_t flags
,
79 static unsigned int neigh_hash_keymake(void *p
);
80 static int neigh_cmp(const void *p1
, const void *p2
);
81 static void *zvni_neigh_alloc(void *p
);
82 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
84 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
85 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
);
86 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
87 struct in_addr
*r_vtep_ip
);
88 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
90 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
91 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
92 struct ethaddr
*macaddr
,
94 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
95 struct ethaddr
*macaddr
,
97 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
98 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
99 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
100 struct interface
*br_if
);
101 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
);
103 /* l3-vni next-hop neigh related APIs */
104 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
106 static void *zl3vni_nh_alloc(void *p
);
107 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
108 struct ipaddr
*vtep_ip
,
109 struct ethaddr
*rmac
);
110 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
111 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
112 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
114 /* l3-vni rmac related APIs */
115 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
116 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
117 struct ethaddr
*rmac
);
118 static void *zl3vni_rmac_alloc(void *p
);
119 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
120 struct ethaddr
*rmac
);
121 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
122 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
123 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
125 /* l3-vni related APIs*/
126 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
127 static void *zl3vni_alloc(void *p
);
128 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
129 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
130 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
131 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
132 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
133 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
134 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
136 static unsigned int mac_hash_keymake(void *p
);
137 static int mac_cmp(const void *p1
, const void *p2
);
138 static void *zvni_mac_alloc(void *p
);
139 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
140 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
141 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
);
142 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
143 struct in_addr
*r_vtep_ip
);
144 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
146 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
147 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
149 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
151 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
152 struct interface
*br_if
, vlanid_t vid
);
153 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
154 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
155 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
157 static unsigned int vni_hash_keymake(void *p
);
158 static int vni_hash_cmp(const void *p1
, const void *p2
);
159 static void *zvni_alloc(void *p
);
160 static zebra_vni_t
*zvni_lookup(vni_t vni
);
161 static zebra_vni_t
*zvni_add(vni_t vni
);
162 static int zvni_del(zebra_vni_t
*zvni
);
163 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
164 static int zvni_send_del_to_client(vni_t vni
);
165 static void zvni_build_hash_table();
166 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
167 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
168 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
169 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
170 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
171 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
172 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
173 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
174 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
175 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
176 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
177 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
179 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
180 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
181 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
184 /* Private functions */
185 static int host_rb_entry_compare(const struct host_rb_entry
*hle1
,
186 const struct host_rb_entry
*hle2
)
188 if (hle1
->p
.family
< hle2
->p
.family
)
191 if (hle1
->p
.family
> hle2
->p
.family
)
194 if (hle1
->p
.prefixlen
< hle2
->p
.prefixlen
)
197 if (hle1
->p
.prefixlen
> hle2
->p
.prefixlen
)
200 if (hle1
->p
.family
== AF_INET
) {
201 if (hle1
->p
.u
.prefix4
.s_addr
< hle2
->p
.u
.prefix4
.s_addr
)
204 if (hle1
->p
.u
.prefix4
.s_addr
> hle2
->p
.u
.prefix4
.s_addr
)
209 zlog_warn("%s: Unexpected family type: %d", __PRETTY_FUNCTION__
,
214 RB_GENERATE(host_rb_tree_entry
, host_rb_entry
, hl_entry
, host_rb_entry_compare
);
216 static uint32_t rb_host_count(struct host_rb_tree_entry
*hrbe
)
218 struct host_rb_entry
*hle
;
221 RB_FOREACH (hle
, host_rb_tree_entry
, hrbe
)
228 * Return number of valid MACs in a VNI's MAC hash table - all
229 * remote MACs and non-internal (auto) local MACs count.
231 static uint32_t num_valid_macs(zebra_vni_t
*zvni
)
234 uint32_t num_macs
= 0;
236 struct hash_backet
*hb
;
239 hash
= zvni
->mac_table
;
242 for (i
= 0; i
< hash
->size
; i
++) {
243 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
244 mac
= (zebra_mac_t
*)hb
->data
;
245 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
246 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
254 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
256 struct zebra_vrf
*zvrf
;
258 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
259 if (zvrf
&& zvrf
->advertise_gw_macip
)
262 if (zvni
&& zvni
->advertise_gw_macip
)
269 * Helper function to determine maximum width of neighbor IP address for
270 * display - just because we're dealing with IPv6 addresses that can
273 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
276 char buf
[INET6_ADDRSTRLEN
];
277 struct neigh_walk_ctx
*wctx
= ctxt
;
280 n
= (zebra_neigh_t
*)backet
->data
;
284 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
285 if (width
> wctx
->addr_width
)
286 wctx
->addr_width
= width
;
290 * Print a specific neighbor entry.
292 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
295 char buf1
[ETHER_ADDR_STRLEN
];
296 char buf2
[INET6_ADDRSTRLEN
];
298 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
299 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
300 vty
= (struct vty
*)ctxt
;
302 vty_out(vty
, "IP: %s\n",
303 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
304 vty_out(vty
, " MAC: %s",
305 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
307 json_object_string_add(json
, "ip", buf2
);
308 json_object_string_add(json
, "mac", buf1
);
310 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
312 vty_out(vty
, " Remote VTEP: %s",
313 inet_ntoa(n
->r_vtep_ip
));
315 json_object_string_add(json
, "remoteVtep",
316 inet_ntoa(n
->r_vtep_ip
));
318 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
321 vty_out(vty
, " State: %s",
322 IS_ZEBRA_NEIGH_ACTIVE(n
) ? "Active"
326 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
328 vty_out(vty
, " Default-gateway");
330 json_object_boolean_true_add(json
, "defaultGateway");
337 * Print neighbor hash entry - called for display of all neighbors.
339 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
342 json_object
*json_vni
= NULL
, *json_row
= NULL
;
344 char buf1
[ETHER_ADDR_STRLEN
];
345 char buf2
[INET6_ADDRSTRLEN
];
346 struct neigh_walk_ctx
*wctx
= ctxt
;
349 json_vni
= wctx
->json
;
350 n
= (zebra_neigh_t
*)backet
->data
;
355 json_row
= json_object_new_object();
357 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
358 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
359 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)
360 && !(wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)) {
361 if (json_vni
== NULL
) {
362 vty_out(vty
, "%*s %-6s %-17s\n", -wctx
->addr_width
,
363 buf2
, "local", buf1
);
365 json_object_string_add(json_row
, "type", "local");
366 json_object_string_add(json_row
, "mac", buf1
);
370 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) {
371 if (IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
)) {
372 if (json_vni
== NULL
) {
373 if (wctx
->count
== 0)
375 "%*s %-6s %-17s %-21s\n",
378 "MAC", "Remote VTEP");
379 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
380 -wctx
->addr_width
, buf2
,
382 inet_ntoa(n
->r_vtep_ip
));
384 json_object_string_add(json_row
, "type",
386 json_object_string_add(json_row
, "mac",
388 json_object_string_add(
389 json_row
, "remoteVtep",
390 inet_ntoa(n
->r_vtep_ip
));
395 if (json_vni
== NULL
) {
396 vty_out(vty
, "%*s %-6s %-17s %-21s\n",
397 -wctx
->addr_width
, buf2
, "remote", buf1
,
398 inet_ntoa(n
->r_vtep_ip
));
400 json_object_string_add(json_row
, "type",
402 json_object_string_add(json_row
, "mac", buf1
);
403 json_object_string_add(json_row
, "remoteVtep",
404 inet_ntoa(n
->r_vtep_ip
));
411 json_object_object_add(json_vni
, buf2
, json_row
);
415 * Print neighbors for all VNI.
417 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
421 json_object
*json
= NULL
, *json_vni
= NULL
;
424 struct neigh_walk_ctx wctx
;
425 char vni_str
[VNI_STR_LEN
];
427 vty
= (struct vty
*)args
[0];
428 json
= (json_object
*)args
[1];
430 zvni
= (zebra_vni_t
*)backet
->data
;
433 vty_out(vty
, "{}\n");
436 num_neigh
= hashcount(zvni
->neigh_table
);
439 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
440 zvni
->vni
, num_neigh
);
442 json_vni
= json_object_new_object();
443 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
444 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
448 json_object_object_add(json
, vni_str
, json_vni
);
452 /* Since we have IPv6 addresses to deal with which can vary widely in
453 * size, we try to be a bit more elegant in display by first computing
456 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
459 wctx
.addr_width
= 15;
460 wctx
.json
= json_vni
;
461 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
464 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
465 "Type", "MAC", "Remote VTEP");
466 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
469 json_object_object_add(json
, vni_str
, json_vni
);
472 /* print a specific next hop for an l3vni */
473 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
476 char buf1
[ETHER_ADDR_STRLEN
];
477 char buf2
[INET6_ADDRSTRLEN
];
478 json_object
*json_hosts
= NULL
;
479 struct host_rb_entry
*hle
;
482 vty_out(vty
, "Ip: %s\n",
483 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
484 vty_out(vty
, " RMAC: %s\n",
485 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
486 vty_out(vty
, " Refcount: %d\n",
487 rb_host_count(&n
->host_rb
));
488 vty_out(vty
, " Prefixes:\n");
489 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
490 vty_out(vty
, " %s\n",
491 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
493 json_hosts
= json_object_new_array();
494 json_object_string_add(
495 json
, "ip", ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)));
496 json_object_string_add(
498 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)));
499 json_object_int_add(json
, "refCount",
500 rb_host_count(&n
->host_rb
));
501 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
502 json_object_array_add(json_hosts
,
503 json_object_new_string(prefix2str(
504 &hle
->p
, buf2
, sizeof(buf2
))));
505 json_object_object_add(json
, "prefixList", json_hosts
);
509 /* Print a specific RMAC entry */
510 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
513 char buf1
[ETHER_ADDR_STRLEN
];
514 char buf2
[PREFIX_STRLEN
];
515 json_object
*json_hosts
= NULL
;
516 struct host_rb_entry
*hle
;
519 vty_out(vty
, "MAC: %s\n",
520 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
521 vty_out(vty
, " Remote VTEP: %s\n",
522 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
523 vty_out(vty
, " Refcount: %d\n", rb_host_count(&zrmac
->host_rb
));
524 vty_out(vty
, " Prefixes:\n");
525 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
526 vty_out(vty
, " %s\n",
527 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
529 json_hosts
= json_object_new_array();
530 json_object_string_add(
532 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
533 json_object_string_add(json
, "vtepIp",
534 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
535 json_object_int_add(json
, "refCount",
536 rb_host_count(&zrmac
->host_rb
));
537 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
538 json_object_array_add(
540 json_object_new_string(prefix2str(
541 &hle
->p
, buf2
, sizeof(buf2
))));
542 json_object_object_add(json
, "prefixList", json_hosts
);
547 * Print a specific MAC entry.
549 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
552 zebra_neigh_t
*n
= NULL
;
553 struct listnode
*node
= NULL
;
555 char buf2
[INET6_ADDRSTRLEN
];
557 vty
= (struct vty
*)ctxt
;
558 vty_out(vty
, "MAC: %s",
559 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
560 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
561 struct zebra_ns
*zns
;
562 struct interface
*ifp
;
565 ifindex
= mac
->fwd_info
.local
.ifindex
;
566 zns
= zebra_ns_lookup(NS_DEFAULT
);
567 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
568 if (!ifp
) // unexpected
570 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
571 if (mac
->fwd_info
.local
.vid
)
572 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
573 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
574 vty_out(vty
, " Remote VTEP: %s",
575 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
576 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
577 vty_out(vty
, " Auto Mac ");
580 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
581 vty_out(vty
, " Sticky Mac ");
583 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
584 vty_out(vty
, " Default-gateway Mac ");
587 /* print all the associated neigh */
588 vty_out(vty
, " Neighbors:\n");
589 if (!listcount(mac
->neigh_list
))
590 vty_out(vty
, " No Neighbors\n");
592 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
593 vty_out(vty
, " %s %s\n",
594 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
595 CHECK_FLAG(n
->flags
, ZEBRA_MAC_LOCAL
)
596 ? (IS_ZEBRA_NEIGH_ACTIVE(n
)
607 * Print MAC hash entry - called for display of all MACs.
609 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
612 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
615 struct mac_walk_ctx
*wctx
= ctxt
;
618 json_mac_hdr
= wctx
->json
;
619 mac
= (zebra_mac_t
*)backet
->data
;
623 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
626 json_mac
= json_object_new_object();
628 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
629 && !(wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)) {
630 struct zebra_ns
*zns
;
632 struct interface
*ifp
;
635 zns
= zebra_ns_lookup(NS_DEFAULT
);
636 ifindex
= mac
->fwd_info
.local
.ifindex
;
637 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
638 if (!ifp
) // unexpected
640 vid
= mac
->fwd_info
.local
.vid
;
641 if (json_mac_hdr
== NULL
)
642 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
645 json_object_string_add(json_mac
, "type", "local");
646 json_object_string_add(json_mac
, "intf", ifp
->name
);
649 if (json_mac_hdr
== NULL
)
650 vty_out(vty
, " %-5u", vid
);
652 json_object_int_add(json_mac
, "vlan", vid
);
654 if (json_mac_hdr
== NULL
)
657 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
659 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
660 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) {
661 if (IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
663 if (wctx
->count
== 0) {
664 if (json_mac_hdr
== NULL
) {
665 vty_out(vty
, "\nVNI %u\n\n",
668 "%-17s %-6s %-21s %-5s\n",
674 if (json_mac_hdr
== NULL
)
675 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
677 inet_ntoa(mac
->fwd_info
680 json_object_string_add(json_mac
, "type",
682 json_object_string_add(
683 json_mac
, "remoteVtep",
684 inet_ntoa(mac
->fwd_info
686 json_object_object_add(json_mac_hdr
,
692 if (json_mac_hdr
== NULL
)
693 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
,
695 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
697 json_object_string_add(json_mac
, "type",
699 json_object_string_add(
700 json_mac
, "remoteVtep",
701 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
702 json_object_object_add(json_mac_hdr
, buf1
,
711 * Print MACs for all VNI.
713 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
716 json_object
*json
= NULL
, *json_vni
= NULL
;
717 json_object
*json_mac
= NULL
;
720 struct mac_walk_ctx
*wctx
= ctxt
;
721 char vni_str
[VNI_STR_LEN
];
723 vty
= (struct vty
*)wctx
->vty
;
724 json
= (struct json_object
*)wctx
->json
;
726 zvni
= (zebra_vni_t
*)backet
->data
;
729 vty_out(vty
, "{}\n");
734 /*We are iterating over a new VNI, set the count to 0*/
737 num_macs
= num_valid_macs(zvni
);
742 json_vni
= json_object_new_object();
743 json_mac
= json_object_new_object();
744 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
747 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
749 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
750 zvni
->vni
, num_macs
);
751 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
752 "Intf/Remote VTEP", "VLAN");
754 json_object_int_add(json_vni
, "numMacs", num_macs
);
756 /* assign per-vni to wctx->json object to fill macs
757 * under the vni. Re-assign primary json object to fill
758 * next vni information.
760 wctx
->json
= json_mac
;
761 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
765 json_object_object_add(json_vni
, "macs", json_mac
);
766 json_object_object_add(json
, vni_str
, json_vni
);
770 static void zl3vni_print_nh_hash(struct hash_backet
*backet
, void *ctx
)
772 struct nh_walk_ctx
*wctx
= NULL
;
773 struct vty
*vty
= NULL
;
774 struct json_object
*json_vni
= NULL
;
775 struct json_object
*json_nh
= NULL
;
776 zebra_neigh_t
*n
= NULL
;
777 char buf1
[ETHER_ADDR_STRLEN
];
778 char buf2
[INET6_ADDRSTRLEN
];
780 wctx
= (struct nh_walk_ctx
*)ctx
;
782 json_vni
= wctx
->json
;
784 json_nh
= json_object_new_object();
785 n
= (zebra_neigh_t
*)backet
->data
;
790 vty_out(vty
, "%-15s %-17s\n",
791 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
792 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
794 json_object_string_add(json_nh
, "nexthopIp",
795 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
796 json_object_string_add(
797 json_nh
, "routerMac",
798 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
799 json_object_object_add(json_vni
,
800 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
805 static void zl3vni_print_nh_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 nh_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_nh
= hashcount(zl3vni
->nh_table
);
831 json_vni
= json_object_new_object();
832 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
836 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n", zl3vni
->vni
, num_nh
);
837 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
839 json_object_int_add(json_vni
, "numNextHops", num_nh
);
841 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
843 wctx
.json
= json_vni
;
844 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
846 json_object_object_add(json
, vni_str
, json_vni
);
849 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
852 struct vty
*vty
= NULL
;
853 json_object
*json
= NULL
;
854 json_object
*json_vni
= NULL
;
855 zebra_l3vni_t
*zl3vni
= NULL
;
857 struct rmac_walk_ctx wctx
;
858 char vni_str
[VNI_STR_LEN
];
860 vty
= (struct vty
*)args
[0];
861 json
= (struct json_object
*)args
[1];
863 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
866 vty_out(vty
, "{}\n");
870 num_rmacs
= hashcount(zl3vni
->rmac_table
);
875 json_vni
= json_object_new_object();
876 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
880 vty_out(vty
, "\nVNI %u #RMACs %u\n\n", zl3vni
->vni
, num_rmacs
);
881 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
883 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
885 /* assign per-vni to wctx->json object to fill macs
886 * under the vni. Re-assign primary json object to fill
887 * next vni information.
889 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
891 wctx
.json
= json_vni
;
892 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
894 json_object_object_add(json
, vni_str
, json_vni
);
897 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
, void *ctx
)
899 zebra_mac_t
*zrmac
= NULL
;
900 struct rmac_walk_ctx
*wctx
= NULL
;
901 struct vty
*vty
= NULL
;
902 struct json_object
*json
= NULL
;
903 struct json_object
*json_rmac
= NULL
;
904 char buf
[ETHER_ADDR_STRLEN
];
906 wctx
= (struct rmac_walk_ctx
*)ctx
;
910 json_rmac
= json_object_new_object();
911 zrmac
= (zebra_mac_t
*)backet
->data
;
916 vty_out(vty
, "%-17s %-21s\n",
917 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
918 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
920 json_object_string_add(
921 json_rmac
, "routerMac",
922 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)));
923 json_object_string_add(json_rmac
, "vtepIp",
924 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
925 json_object_object_add(
926 json
, prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
931 /* print a specific L3 VNI entry */
932 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
934 char buf
[ETHER_ADDR_STRLEN
];
935 struct vty
*vty
= NULL
;
936 json_object
*json
= NULL
;
937 zebra_vni_t
*zvni
= NULL
;
938 json_object
*json_vni_list
= NULL
;
939 struct listnode
*node
= NULL
, *nnode
= NULL
;
945 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
946 vty_out(vty
, " Type: %s\n", "L3");
947 vty_out(vty
, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni
));
948 vty_out(vty
, " Local Vtep Ip: %s\n",
949 inet_ntoa(zl3vni
->local_vtep_ip
));
950 vty_out(vty
, " Vxlan-Intf: %s\n",
951 zl3vni_vxlan_if_name(zl3vni
));
952 vty_out(vty
, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni
));
953 vty_out(vty
, " State: %s\n", zl3vni_state2str(zl3vni
));
954 vty_out(vty
, " VNI Filter: %s\n",
955 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
956 ? "prefix-routes-only"
958 vty_out(vty
, " Router MAC: %s\n",
959 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
960 vty_out(vty
, " L2 VNIs: ");
961 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
962 vty_out(vty
, "%u ", zvni
->vni
);
965 json_vni_list
= json_object_new_array();
966 json_object_int_add(json
, "vni", zl3vni
->vni
);
967 json_object_string_add(json
, "type", "L3");
968 json_object_string_add(json
, "localVtepIp",
969 inet_ntoa(zl3vni
->local_vtep_ip
));
970 json_object_string_add(json
, "vxlanIntf",
971 zl3vni_vxlan_if_name(zl3vni
));
972 json_object_string_add(json
, "sviIntf",
973 zl3vni_svi_if_name(zl3vni
));
974 json_object_string_add(json
, "state", zl3vni_state2str(zl3vni
));
975 json_object_string_add(json
, "vrf", zl3vni_vrf_name(zl3vni
));
976 json_object_string_add(
978 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
979 json_object_string_add(
981 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
982 ? "prefix-routes-only"
984 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
985 json_object_array_add(json_vni_list
,
986 json_object_new_int(zvni
->vni
));
988 json_object_object_add(json
, "l2Vnis", json_vni_list
);
993 * Print a specific VNI entry.
995 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
1001 json_object
*json
= NULL
;
1002 json_object
*json_vtep_list
= NULL
;
1003 json_object
*json_ip_str
= NULL
;
1009 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
1010 vty_out(vty
, " Type: %s\n", "L2");
1011 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
1013 json_object_int_add(json
, "vni", zvni
->vni
);
1014 json_object_string_add(json
, "type", "L2");
1015 json_object_string_add(json
, "vrf",
1016 vrf_id_to_name(zvni
->vrf_id
));
1019 if (!zvni
->vxlan_if
) { // unexpected
1021 vty_out(vty
, " VxLAN interface: unknown\n");
1024 num_macs
= num_valid_macs(zvni
);
1025 num_neigh
= hashcount(zvni
->neigh_table
);
1027 vty_out(vty
, " VxLAN interface: %s\n", zvni
->vxlan_if
->name
);
1028 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
1029 vty_out(vty
, " Local VTEP IP: %s\n",
1030 inet_ntoa(zvni
->local_vtep_ip
));
1032 json_object_string_add(json
, "vxlanInterface",
1033 zvni
->vxlan_if
->name
);
1034 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
1035 json_object_string_add(json
, "vtepIp",
1036 inet_ntoa(zvni
->local_vtep_ip
));
1037 json_object_string_add(json
, "advertiseGatewayMacip",
1038 zvni
->advertise_gw_macip
? "Yes" : "No");
1039 json_object_int_add(json
, "numMacs", num_macs
);
1040 json_object_int_add(json
, "numArpNd", num_neigh
);
1044 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1047 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1049 json_vtep_list
= json_object_new_array();
1050 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1052 vty_out(vty
, " %s\n",
1053 inet_ntoa(zvtep
->vtep_ip
));
1055 json_ip_str
= json_object_new_string(
1056 inet_ntoa(zvtep
->vtep_ip
));
1057 json_object_array_add(json_vtep_list
,
1062 json_object_object_add(json
, "numRemoteVteps",
1067 " Number of MACs (local and remote) known for this VNI: %u\n",
1070 " Number of ARPs (IPv4 and IPv6, local and remote) "
1071 "known for this VNI: %u\n",
1073 vty_out(vty
, " Advertise-gw-macip: %s\n",
1074 zvni
->advertise_gw_macip
? "Yes" : "No");
1078 /* print a L3 VNI hash entry */
1079 static void zl3vni_print_hash(struct hash_backet
*backet
, void *ctx
[])
1081 struct vty
*vty
= NULL
;
1082 json_object
*json
= NULL
;
1083 json_object
*json_vni
= NULL
;
1084 zebra_l3vni_t
*zl3vni
= NULL
;
1086 vty
= (struct vty
*)ctx
[0];
1087 json
= (json_object
*)ctx
[1];
1089 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1094 vty_out(vty
, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1095 zl3vni
->vni
, "L3", zl3vni_vxlan_if_name(zl3vni
),
1096 hashcount(zl3vni
->rmac_table
),
1097 hashcount(zl3vni
->nh_table
), "n/a",
1098 zl3vni_vrf_name(zl3vni
));
1100 char vni_str
[VNI_STR_LEN
];
1102 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1103 json_vni
= json_object_new_object();
1104 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1105 json_object_string_add(json_vni
, "vxlanIf",
1106 zl3vni_vxlan_if_name(zl3vni
));
1107 json_object_int_add(json_vni
, "numMacs",
1108 hashcount(zl3vni
->rmac_table
));
1109 json_object_int_add(json_vni
, "numArpNd",
1110 hashcount(zl3vni
->nh_table
));
1111 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1112 json_object_string_add(json_vni
, "type", "L3");
1113 json_object_string_add(json_vni
, "tenantVrf",
1114 zl3vni_vrf_name(zl3vni
));
1115 json_object_object_add(json
, vni_str
, json_vni
);
1120 * Print a VNI hash entry - called for display of all VNIs.
1122 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1126 zebra_vtep_t
*zvtep
;
1127 uint32_t num_vteps
= 0;
1128 uint32_t num_macs
= 0;
1129 uint32_t num_neigh
= 0;
1130 json_object
*json
= NULL
;
1131 json_object
*json_vni
= NULL
;
1132 json_object
*json_ip_str
= NULL
;
1133 json_object
*json_vtep_list
= NULL
;
1138 zvni
= (zebra_vni_t
*)backet
->data
;
1142 zvtep
= zvni
->vteps
;
1145 zvtep
= zvtep
->next
;
1148 num_macs
= num_valid_macs(zvni
);
1149 num_neigh
= hashcount(zvni
->neigh_table
);
1151 vty_out(vty
, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1153 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1154 num_macs
, num_neigh
, num_vteps
,
1155 vrf_id_to_name(zvni
->vrf_id
));
1157 char vni_str
[VNI_STR_LEN
];
1158 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1159 json_vni
= json_object_new_object();
1160 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1161 json_object_string_add(json_vni
, "type", "L2");
1162 json_object_string_add(json_vni
, "vxlanIf",
1163 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1165 json_object_int_add(json_vni
, "numMacs", num_macs
);
1166 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1167 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1168 json_object_string_add(json_vni
, "tenantVrf",
1169 vrf_id_to_name(zvni
->vrf_id
));
1171 json_vtep_list
= json_object_new_array();
1172 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1173 json_ip_str
= json_object_new_string(
1174 inet_ntoa(zvtep
->vtep_ip
));
1175 json_object_array_add(json_vtep_list
,
1178 json_object_object_add(json_vni
, "remoteVteps",
1181 json_object_object_add(json
, vni_str
, json_vni
);
1186 * Inform BGP about local MACIP.
1188 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
1189 struct ipaddr
*ip
, uint8_t flags
,
1192 char buf
[ETHER_ADDR_STRLEN
];
1193 char buf2
[INET6_ADDRSTRLEN
];
1195 struct zserv
*client
= NULL
;
1196 struct stream
*s
= NULL
;
1198 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
1199 /* BGP may not be running. */
1203 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
1205 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1206 stream_putl(s
, vni
);
1207 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1210 if (IS_IPADDR_V4(ip
))
1211 ipa_len
= IPV4_MAX_BYTELEN
;
1212 else if (IS_IPADDR_V6(ip
))
1213 ipa_len
= IPV6_MAX_BYTELEN
;
1215 stream_putl(s
, ipa_len
); /* IP address length */
1217 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1219 stream_putl(s
, 0); /* Just MAC. */
1221 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1224 /* Write packet size. */
1225 stream_putw_at(s
, 0, stream_get_endp(s
));
1227 if (IS_ZEBRA_DEBUG_VXLAN
)
1229 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1230 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del", flags
,
1231 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1232 ipaddr2str(ip
, buf2
, sizeof(buf2
)), vni
,
1233 zebra_route_string(client
->proto
));
1235 if (cmd
== ZEBRA_MACIP_ADD
)
1236 client
->macipadd_cnt
++;
1238 client
->macipdel_cnt
++;
1240 return zebra_server_send_message(client
, s
);
1244 * Make hash key for neighbors.
1246 static unsigned int neigh_hash_keymake(void *p
)
1248 zebra_neigh_t
*n
= p
;
1249 struct ipaddr
*ip
= &n
->ip
;
1251 if (IS_IPADDR_V4(ip
))
1252 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1254 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1255 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1259 * Compare two neighbor hash structures.
1261 static int neigh_cmp(const void *p1
, const void *p2
)
1263 const zebra_neigh_t
*n1
= p1
;
1264 const zebra_neigh_t
*n2
= p2
;
1266 if (n1
== NULL
&& n2
== NULL
)
1269 if (n1
== NULL
|| n2
== NULL
)
1272 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1276 * Callback to allocate neighbor hash entry.
1278 static void *zvni_neigh_alloc(void *p
)
1280 const zebra_neigh_t
*tmp_n
= p
;
1283 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1290 * Add neighbor entry.
1292 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1293 struct ethaddr
*mac
)
1295 zebra_neigh_t tmp_n
;
1296 zebra_neigh_t
*n
= NULL
;
1297 zebra_mac_t
*zmac
= NULL
;
1299 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1300 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1301 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1304 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1305 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1307 /* Associate the neigh to mac */
1308 zmac
= zvni_mac_lookup(zvni
, mac
);
1310 listnode_add_sort(zmac
->neigh_list
, n
);
1316 * Delete neighbor entry.
1318 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1320 zebra_neigh_t
*tmp_n
;
1321 zebra_mac_t
*zmac
= NULL
;
1323 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1325 listnode_delete(zmac
->neigh_list
, n
);
1327 /* Free the VNI hash entry and allocated memory. */
1328 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1330 XFREE(MTYPE_NEIGH
, tmp_n
);
1336 * Free neighbor hash entry (callback)
1338 static int zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1340 struct neigh_walk_ctx
*wctx
= arg
;
1341 zebra_neigh_t
*n
= backet
->data
;
1343 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1344 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1345 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1346 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1347 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1348 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1349 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1350 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1353 if (wctx
->uninstall
)
1354 zvni_neigh_uninstall(wctx
->zvni
, n
);
1356 return zvni_neigh_del(wctx
->zvni
, n
);
1363 * Delete all neighbor entries from specific VTEP for a particular VNI.
1365 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1366 struct in_addr
*r_vtep_ip
)
1368 struct neigh_walk_ctx wctx
;
1370 if (!zvni
->neigh_table
)
1373 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1375 wctx
.uninstall
= uninstall
;
1376 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1377 wctx
.r_vtep_ip
= *r_vtep_ip
;
1379 hash_iterate(zvni
->neigh_table
,
1380 (void (*)(struct hash_backet
*,
1381 void *))zvni_neigh_del_hash_entry
,
1386 * Delete all neighbor entries for this VNI.
1388 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
1391 struct neigh_walk_ctx wctx
;
1393 if (!zvni
->neigh_table
)
1396 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1398 wctx
.uninstall
= uninstall
;
1399 wctx
.upd_client
= upd_client
;
1402 hash_iterate(zvni
->neigh_table
,
1403 (void (*)(struct hash_backet
*,
1404 void *))zvni_neigh_del_hash_entry
,
1409 * Look up neighbor hash entry.
1411 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1416 memset(&tmp
, 0, sizeof(tmp
));
1417 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1418 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1423 /* Process all neigh associated to a mac upon local mac add event */
1424 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t
*zvni
,
1427 zebra_neigh_t
*n
= NULL
;
1428 struct listnode
*node
= NULL
;
1429 char buf
[ETHER_ADDR_STRLEN
];
1430 char buf2
[INET6_ADDRSTRLEN
];
1432 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1433 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1434 /* MAC is learnt locally, program all inactive neigh
1435 * pointing to this mac */
1436 if (IS_ZEBRA_NEIGH_INACTIVE(n
)) {
1437 if (IS_ZEBRA_DEBUG_VXLAN
)
1439 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1440 ipaddr2str(&n
->ip
, buf2
,
1442 prefix_mac2str(&n
->emac
, buf
,
1446 ZEBRA_NEIGH_SET_ACTIVE(n
);
1447 zvni_neigh_send_add_to_client(
1448 zvni
->vni
, &n
->ip
, &n
->emac
, n
->flags
);
1450 if (IS_ZEBRA_DEBUG_VXLAN
)
1452 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1453 ipaddr2str(&n
->ip
, buf2
,
1455 prefix_mac2str(&n
->emac
, buf
,
1459 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1460 /* TODO: assume the neigh has moved too ?? */
1465 /* Process all neigh associated to a mac upon local mac del event */
1466 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1469 zebra_neigh_t
*n
= NULL
;
1470 struct listnode
*node
= NULL
;
1471 char buf
[ETHER_ADDR_STRLEN
];
1472 char buf2
[INET6_ADDRSTRLEN
];
1474 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1475 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1476 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1477 if (IS_ZEBRA_DEBUG_VXLAN
)
1479 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1480 ipaddr2str(&n
->ip
, buf2
,
1482 prefix_mac2str(&n
->emac
, buf
,
1486 ZEBRA_NEIGH_SET_INACTIVE(n
);
1487 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1490 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
1491 if (IS_ZEBRA_DEBUG_VXLAN
)
1493 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1494 prefix_mac2str(&n
->emac
, buf
,
1497 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1502 /* process all neigh associated to a mac entry upon remote mac add */
1503 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1506 zebra_neigh_t
*n
= NULL
;
1507 struct listnode
*node
= NULL
;
1508 char buf
[ETHER_ADDR_STRLEN
];
1509 char buf2
[INET6_ADDRSTRLEN
];
1511 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1512 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1513 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1514 if (IS_ZEBRA_DEBUG_VXLAN
)
1516 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1517 ipaddr2str(&n
->ip
, buf2
,
1519 prefix_mac2str(&n
->emac
, buf
,
1523 ZEBRA_NEIGH_SET_INACTIVE(n
);
1524 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1531 /* process all neigh associated to mac entry upon remote mac del */
1532 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1535 zebra_neigh_t
*n
= NULL
;
1536 struct listnode
*node
= NULL
;
1537 char buf
[ETHER_ADDR_STRLEN
];
1538 char buf2
[INET6_ADDRSTRLEN
];
1540 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1541 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1542 if (IS_ZEBRA_DEBUG_VXLAN
)
1544 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1545 prefix_mac2str(&n
->emac
, buf
,
1548 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
1554 * Inform BGP about local neighbor addition.
1556 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
1557 struct ethaddr
*macaddr
,
1558 uint8_t neigh_flags
)
1562 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1563 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1565 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1570 * Inform BGP about local neighbor deletion.
1572 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
1573 struct ethaddr
*macaddr
, uint8_t flags
)
1575 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1580 * Install remote neighbor into the kernel.
1582 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1584 struct zebra_if
*zif
;
1585 struct zebra_l2info_vxlan
*vxl
;
1586 struct interface
*vlan_if
;
1588 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1591 zif
= zvni
->vxlan_if
->info
;
1594 vxl
= &zif
->l2info
.vxl
;
1596 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1600 return kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
);
1604 * Uninstall remote neighbor from the kernel.
1606 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1608 struct zebra_if
*zif
;
1609 struct zebra_l2info_vxlan
*vxl
;
1610 struct interface
*vlan_if
;
1612 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1615 if (!zvni
->vxlan_if
) {
1616 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1621 zif
= zvni
->vxlan_if
->info
;
1624 vxl
= &zif
->l2info
.vxl
;
1625 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1629 return kernel_del_neigh(vlan_if
, &n
->ip
);
1633 * Install neighbor hash entry - called upon access VLAN change.
1635 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1638 struct neigh_walk_ctx
*wctx
= ctxt
;
1640 n
= (zebra_neigh_t
*)backet
->data
;
1644 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1645 zvni_neigh_install(wctx
->zvni
, n
);
1648 /* Get the VRR interface for SVI if any */
1649 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1651 struct zebra_vrf
*zvrf
= NULL
;
1652 struct interface
*tmp_if
= NULL
;
1653 struct zebra_if
*zif
= NULL
;
1655 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1658 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1663 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1666 if (zif
->link
== ifp
)
1673 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1675 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1676 struct connected
*c
= NULL
;
1677 struct ethaddr macaddr
;
1679 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1681 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1684 memset(&ip
, 0, sizeof(struct ipaddr
));
1685 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1688 if (c
->address
->family
== AF_INET
) {
1689 ip
.ipa_type
= IPADDR_V4
;
1690 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1691 sizeof(struct in_addr
));
1692 } else if (c
->address
->family
== AF_INET6
) {
1693 ip
.ipa_type
= IPADDR_V6
;
1694 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1695 sizeof(struct in6_addr
));
1700 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1706 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1708 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1709 struct connected
*c
= NULL
;
1710 struct ethaddr macaddr
;
1712 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1714 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1717 memset(&ip
, 0, sizeof(struct ipaddr
));
1718 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1721 if (c
->address
->family
== AF_INET
) {
1722 ip
.ipa_type
= IPADDR_V4
;
1723 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1724 sizeof(struct in_addr
));
1725 } else if (c
->address
->family
== AF_INET6
) {
1726 ip
.ipa_type
= IPADDR_V6
;
1727 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1728 sizeof(struct in6_addr
));
1733 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1739 static int zvni_advertise_subnet(zebra_vni_t
*zvni
, struct interface
*ifp
,
1742 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1743 struct connected
*c
= NULL
;
1744 struct ethaddr macaddr
;
1746 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1748 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1751 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1753 /* skip link local address */
1754 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1759 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1760 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1762 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1763 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1769 * zvni_gw_macip_add_to_client
1771 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1772 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1774 char buf
[ETHER_ADDR_STRLEN
];
1775 char buf2
[INET6_ADDRSTRLEN
];
1776 zebra_neigh_t
*n
= NULL
;
1777 zebra_mac_t
*mac
= NULL
;
1778 struct zebra_if
*zif
= NULL
;
1779 struct zebra_l2info_vxlan
*vxl
= NULL
;
1781 zif
= zvni
->vxlan_if
->info
;
1785 vxl
= &zif
->l2info
.vxl
;
1787 mac
= zvni_mac_lookup(zvni
, macaddr
);
1789 mac
= zvni_mac_add(zvni
, macaddr
);
1791 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1792 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1793 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1798 /* Set "local" forwarding info. */
1799 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1800 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1801 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1802 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1803 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1804 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1806 n
= zvni_neigh_lookup(zvni
, ip
);
1808 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1811 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1812 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1813 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1814 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1819 /* Set "local" forwarding info. */
1820 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1821 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1822 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1823 n
->ifindex
= ifp
->ifindex
;
1825 /* Only advertise in BGP if the knob is enabled */
1826 if (!advertise_gw_macip_enabled(zvni
))
1829 if (IS_ZEBRA_DEBUG_VXLAN
)
1831 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1832 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1833 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1834 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1836 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, n
->flags
);
1842 * zvni_gw_macip_del_from_client
1844 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1847 char buf1
[ETHER_ADDR_STRLEN
];
1848 char buf2
[INET6_ADDRSTRLEN
];
1849 zebra_neigh_t
*n
= NULL
;
1850 zebra_mac_t
*mac
= NULL
;
1852 /* If the neigh entry is not present nothing to do*/
1853 n
= zvni_neigh_lookup(zvni
, ip
);
1857 /* mac entry should be present */
1858 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1860 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1861 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1862 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1866 /* If the entry is not local nothing to do*/
1867 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1870 /* only need to delete the entry from bgp if we sent it before */
1871 if (IS_ZEBRA_DEBUG_VXLAN
)
1873 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1874 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1875 prefix_mac2str(&(n
->emac
), NULL
, ETHER_ADDR_STRLEN
),
1876 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1878 /* Remove neighbor from BGP. */
1879 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1880 ZEBRA_MACIP_TYPE_GW
);
1882 /* Delete this neighbor entry. */
1883 zvni_neigh_del(zvni
, n
);
1885 /* see if the mac needs to be deleted as well*/
1887 zvni_deref_ip2mac(zvni
, mac
, 0);
1892 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1895 zebra_vni_t
*zvni
= NULL
;
1896 struct zebra_if
*zif
= NULL
;
1897 struct zebra_l2info_vxlan zl2_info
;
1898 struct interface
*vlan_if
= NULL
;
1899 struct interface
*vrr_if
= NULL
;
1900 struct interface
*ifp
;
1902 /* Add primary SVI MAC*/
1903 zvni
= (zebra_vni_t
*)backet
->data
;
1907 ifp
= zvni
->vxlan_if
;
1912 /* If down or not mapped to a bridge, we're done. */
1913 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1916 zl2_info
= zif
->l2info
.vxl
;
1919 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1923 /* Del primary MAC-IP */
1924 zvni_del_macip_for_intf(vlan_if
, zvni
);
1926 /* Del VRR MAC-IP - if any*/
1927 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1929 zvni_del_macip_for_intf(vrr_if
, zvni
);
1934 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1937 zebra_vni_t
*zvni
= NULL
;
1938 struct zebra_if
*zif
= NULL
;
1939 struct zebra_l2info_vxlan zl2_info
;
1940 struct interface
*vlan_if
= NULL
;
1941 struct interface
*vrr_if
= NULL
;
1942 struct interface
*ifp
= NULL
;
1944 zvni
= (zebra_vni_t
*)backet
->data
;
1948 ifp
= zvni
->vxlan_if
;
1953 /* If down or not mapped to a bridge, we're done. */
1954 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1956 zl2_info
= zif
->l2info
.vxl
;
1959 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1963 /* Add primary SVI MAC-IP */
1964 zvni_add_macip_for_intf(vlan_if
, zvni
);
1966 /* Add VRR MAC-IP - if any*/
1967 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1969 zvni_add_macip_for_intf(vrr_if
, zvni
);
1974 static int zvni_local_neigh_update(zebra_vni_t
*zvni
,
1975 struct interface
*ifp
,
1977 struct ethaddr
*macaddr
)
1979 char buf
[ETHER_ADDR_STRLEN
];
1980 char buf2
[INET6_ADDRSTRLEN
];
1981 zebra_neigh_t
*n
= NULL
;
1982 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
1984 /* create a dummy MAC if the MAC is not already present */
1985 zmac
= zvni_mac_lookup(zvni
, macaddr
);
1987 if (IS_ZEBRA_DEBUG_VXLAN
)
1989 "AUTO MAC %s created for neigh %s on VNI %u",
1990 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1991 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1993 zmac
= zvni_mac_add(zvni
, macaddr
);
1995 zlog_warn("Failed to add MAC %s VNI %u",
1996 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2001 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
2002 memset(&zmac
->flags
, 0, sizeof(uint32_t));
2003 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
2006 /* If same entry already exists, it might be a change or it might be a
2007 * move from remote to local.
2009 n
= zvni_neigh_lookup(zvni
, ip
);
2011 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2012 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2014 /* Update any params and return - client doesn't
2015 * care about a purely local change.
2017 n
->ifindex
= ifp
->ifindex
;
2021 /* If the MAC has changed,
2022 * need to issue a delete first
2023 * as this means a different MACIP route.
2024 * Also, need to do some unlinking/relinking.
2026 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
2028 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2030 listnode_delete(old_zmac
->neigh_list
, n
);
2031 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2034 /* Update the forwarding info. */
2035 n
->ifindex
= ifp
->ifindex
;
2036 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2038 /* Link to new MAC */
2039 listnode_add_sort(zmac
->neigh_list
, n
);
2042 /* Neighbor has moved from remote to local. */
2044 /* If MAC has changed, do the unlink/link */
2045 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2047 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2049 listnode_delete(old_zmac
->neigh_list
,
2051 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2054 /* Link to new MAC */
2055 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2056 listnode_add_sort(zmac
->neigh_list
, n
);
2059 /* Mark appropriately */
2060 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2061 n
->r_vtep_ip
.s_addr
= 0;
2062 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2063 n
->ifindex
= ifp
->ifindex
;
2066 /* New neighbor - create */
2067 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2070 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2071 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2072 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2073 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2076 /* Set "local" forwarding info. */
2077 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2078 n
->ifindex
= ifp
->ifindex
;
2081 /* Before we program this in BGP, we need to check if MAC is locally
2084 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
2085 if (IS_ZEBRA_DEBUG_VXLAN
)
2087 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
2088 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2089 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2096 if (IS_ZEBRA_DEBUG_VXLAN
)
2097 zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
2098 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2099 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2101 ZEBRA_NEIGH_SET_ACTIVE(n
);
2103 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
, 0);
2106 static int zvni_remote_neigh_update(zebra_vni_t
*zvni
,
2107 struct interface
*ifp
,
2109 struct ethaddr
*macaddr
,
2112 char buf
[ETHER_ADDR_STRLEN
];
2113 char buf2
[INET6_ADDRSTRLEN
];
2114 zebra_neigh_t
*n
= NULL
;
2115 zebra_mac_t
*zmac
= NULL
;
2117 /* If the neighbor is unknown, there is no further action. */
2118 n
= zvni_neigh_lookup(zvni
, ip
);
2122 /* If a remote entry, see if it needs to be refreshed */
2123 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2125 if (state
& NUD_STALE
)
2126 zvni_neigh_install(zvni
, n
);
2129 /* We got a "remote" neighbor notification for an entry
2130 * we think is local. This can happen in a multihoming
2131 * scenario - but only if the MAC is already "remote".
2132 * Just mark our entry as "remote".
2134 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2135 if (!zmac
|| !CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2136 zlog_err("Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
2137 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
2138 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2143 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2144 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2145 n
->r_vtep_ip
= zmac
->fwd_info
.r_vtep_ip
;
2152 * Make hash key for MAC.
2154 static unsigned int mac_hash_keymake(void *p
)
2156 zebra_mac_t
*pmac
= p
;
2157 const void *pnt
= (void *)pmac
->macaddr
.octet
;
2159 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
2163 * Compare two MAC addresses.
2165 static int mac_cmp(const void *p1
, const void *p2
)
2167 const zebra_mac_t
*pmac1
= p1
;
2168 const zebra_mac_t
*pmac2
= p2
;
2170 if (pmac1
== NULL
&& pmac2
== NULL
)
2173 if (pmac1
== NULL
|| pmac2
== NULL
)
2176 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
, ETH_ALEN
)
2181 * Callback to allocate MAC hash entry.
2183 static void *zvni_mac_alloc(void *p
)
2185 const zebra_mac_t
*tmp_mac
= p
;
2188 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2191 return ((void *)mac
);
2197 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
2199 zebra_mac_t tmp_mac
;
2200 zebra_mac_t
*mac
= NULL
;
2202 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
2203 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
2204 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
2207 mac
->neigh_list
= list_new();
2208 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
2216 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2218 zebra_mac_t
*tmp_mac
;
2220 list_delete_and_null(&mac
->neigh_list
);
2222 /* Free the VNI hash entry and allocated memory. */
2223 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2225 XFREE(MTYPE_MAC
, tmp_mac
);
2231 * Free MAC hash entry (callback)
2233 static int zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2235 struct mac_walk_ctx
*wctx
= arg
;
2236 zebra_mac_t
*mac
= backet
->data
;
2238 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2239 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2240 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2241 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2242 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2243 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2244 &wctx
->r_vtep_ip
))) {
2245 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2246 zvni_mac_send_del_to_client(wctx
->zvni
->vni
,
2247 &mac
->macaddr
, mac
->flags
);
2250 if (wctx
->uninstall
)
2251 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2253 return zvni_mac_del(wctx
->zvni
, mac
);
2260 * Delete all MAC entries from specific VTEP for a particular VNI.
2262 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2263 struct in_addr
*r_vtep_ip
)
2265 struct mac_walk_ctx wctx
;
2267 if (!zvni
->mac_table
)
2270 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2272 wctx
.uninstall
= uninstall
;
2273 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2274 wctx
.r_vtep_ip
= *r_vtep_ip
;
2276 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2277 void *))zvni_mac_del_hash_entry
,
2282 * Delete all MAC entries for this VNI.
2284 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
2287 struct mac_walk_ctx wctx
;
2289 if (!zvni
->mac_table
)
2292 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2294 wctx
.uninstall
= uninstall
;
2295 wctx
.upd_client
= upd_client
;
2298 hash_iterate(zvni
->mac_table
, (void (*)(struct hash_backet
*,
2299 void *))zvni_mac_del_hash_entry
,
2304 * Look up MAC hash entry.
2306 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2311 memset(&tmp
, 0, sizeof(tmp
));
2312 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2313 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2319 * Inform BGP about local MAC addition.
2321 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2326 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2327 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2328 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2329 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2331 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2336 * Inform BGP about local MAC deletion.
2338 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2343 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2344 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2345 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2346 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2348 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2353 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2354 * notifications, to see if they are of interest.
2356 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2357 struct interface
*br_if
, vlanid_t vid
)
2359 struct zebra_ns
*zns
;
2360 struct route_node
*rn
;
2361 struct interface
*tmp_if
= NULL
;
2362 struct zebra_if
*zif
;
2363 struct zebra_l2info_bridge
*br
;
2364 struct zebra_l2info_vxlan
*vxl
= NULL
;
2365 uint8_t bridge_vlan_aware
;
2369 /* Determine if bridge is VLAN-aware or not */
2372 br
= &zif
->l2info
.br
;
2373 bridge_vlan_aware
= br
->vlan_aware
;
2375 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2376 /* TODO: Optimize with a hash. */
2377 zns
= zebra_ns_lookup(NS_DEFAULT
);
2378 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2379 tmp_if
= (struct interface
*)rn
->info
;
2383 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2385 if (!if_is_operative(tmp_if
))
2387 vxl
= &zif
->l2info
.vxl
;
2389 if (zif
->brslave_info
.br_if
!= br_if
)
2392 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2401 zvni
= zvni_lookup(vxl
->vni
);
2406 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2407 * neighbor notifications, to see if they are of interest.
2409 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2410 struct interface
*br_if
)
2412 struct zebra_ns
*zns
;
2413 struct route_node
*rn
;
2414 struct interface
*tmp_if
= NULL
;
2415 struct zebra_if
*zif
;
2416 struct zebra_l2info_bridge
*br
;
2417 struct zebra_l2info_vxlan
*vxl
= NULL
;
2418 uint8_t bridge_vlan_aware
;
2426 /* Make sure the linked interface is a bridge. */
2427 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2430 /* Determine if bridge is VLAN-aware or not */
2433 br
= &zif
->l2info
.br
;
2434 bridge_vlan_aware
= br
->vlan_aware
;
2435 if (bridge_vlan_aware
) {
2436 struct zebra_l2info_vlan
*vl
;
2438 if (!IS_ZEBRA_IF_VLAN(ifp
))
2443 vl
= &zif
->l2info
.vl
;
2447 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2448 /* TODO: Optimize with a hash. */
2449 zns
= zebra_ns_lookup(NS_DEFAULT
);
2450 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2451 tmp_if
= (struct interface
*)rn
->info
;
2455 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2457 if (!if_is_operative(tmp_if
))
2459 vxl
= &zif
->l2info
.vxl
;
2461 if (zif
->brslave_info
.br_if
!= br_if
)
2464 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2473 zvni
= zvni_lookup(vxl
->vni
);
2477 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2479 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2480 * linked to the bridge
2481 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2484 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2486 struct zebra_ns
*zns
;
2487 struct route_node
*rn
;
2488 struct interface
*tmp_if
= NULL
;
2489 struct zebra_if
*zif
;
2490 struct zebra_l2info_bridge
*br
;
2491 struct zebra_l2info_vlan
*vl
;
2492 uint8_t bridge_vlan_aware
;
2495 /* Defensive check, caller expected to invoke only with valid bridge. */
2499 /* Determine if bridge is VLAN-aware or not */
2502 br
= &zif
->l2info
.br
;
2503 bridge_vlan_aware
= br
->vlan_aware
;
2505 /* Check oper status of the SVI. */
2506 if (!bridge_vlan_aware
)
2507 return if_is_operative(br_if
) ? br_if
: NULL
;
2509 /* Identify corresponding VLAN interface. */
2510 /* TODO: Optimize with a hash. */
2511 zns
= zebra_ns_lookup(NS_DEFAULT
);
2512 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2513 tmp_if
= (struct interface
*)rn
->info
;
2514 /* Check oper status of the SVI. */
2515 if (!tmp_if
|| !if_is_operative(tmp_if
))
2518 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2519 || zif
->link
!= br_if
)
2521 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2523 if (vl
->vid
== vid
) {
2529 return found
? tmp_if
: NULL
;
2533 * Install remote MAC into the kernel.
2535 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2537 struct zebra_if
*zif
;
2538 struct zebra_l2info_vxlan
*vxl
;
2541 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2544 zif
= zvni
->vxlan_if
->info
;
2547 vxl
= &zif
->l2info
.vxl
;
2549 sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0;
2551 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2552 mac
->fwd_info
.r_vtep_ip
, sticky
);
2556 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2557 * moves to remote, we have to uninstall any existing local entry first.
2559 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2561 struct zebra_if
*zif
;
2562 struct zebra_l2info_vxlan
*vxl
;
2563 struct in_addr vtep_ip
= {.s_addr
= 0};
2564 struct zebra_ns
*zns
;
2565 struct interface
*ifp
;
2567 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2570 if (!zvni
->vxlan_if
) {
2571 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2576 zif
= zvni
->vxlan_if
->info
;
2579 vxl
= &zif
->l2info
.vxl
;
2582 zns
= zebra_ns_lookup(NS_DEFAULT
);
2583 ifp
= if_lookup_by_index_per_ns(zns
,
2584 mac
->fwd_info
.local
.ifindex
);
2585 if (!ifp
) // unexpected
2588 ifp
= zvni
->vxlan_if
;
2589 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2592 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2597 * Install MAC hash entry - called upon access VLAN change.
2599 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2602 struct mac_walk_ctx
*wctx
= ctxt
;
2604 mac
= (zebra_mac_t
*)backet
->data
;
2608 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2609 zvni_mac_install(wctx
->zvni
, mac
);
2613 * Decrement neighbor refcount of MAC; uninstall and free it if
2616 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2619 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2620 || !list_isempty(mac
->neigh_list
))
2624 zvni_mac_uninstall(zvni
, mac
, 0);
2626 zvni_mac_del(zvni
, mac
);
2630 * Read and populate local MACs and neighbors corresponding to this VNI.
2632 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
, struct interface
*ifp
)
2634 struct zebra_ns
*zns
;
2635 struct zebra_if
*zif
;
2636 struct interface
*vlan_if
;
2637 struct zebra_l2info_vxlan
*vxl
;
2638 struct interface
*vrr_if
;
2641 vxl
= &zif
->l2info
.vxl
;
2642 zns
= zebra_ns_lookup(NS_DEFAULT
);
2644 if (IS_ZEBRA_DEBUG_VXLAN
)
2646 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2647 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2648 zif
->brslave_info
.bridge_ifindex
);
2650 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2651 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2654 /* Add SVI MAC-IP */
2655 zvni_add_macip_for_intf(vlan_if
, zvni
);
2657 /* Add VRR MAC-IP - if any*/
2658 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2660 zvni_add_macip_for_intf(vrr_if
, zvni
);
2662 neigh_read_for_vlan(zns
, vlan_if
);
2667 * Hash function for VNI.
2669 static unsigned int vni_hash_keymake(void *p
)
2671 const zebra_vni_t
*zvni
= p
;
2673 return (jhash_1word(zvni
->vni
, 0));
2677 * Compare 2 VNI hash entries.
2679 static int vni_hash_cmp(const void *p1
, const void *p2
)
2681 const zebra_vni_t
*zvni1
= p1
;
2682 const zebra_vni_t
*zvni2
= p2
;
2684 return (zvni1
->vni
== zvni2
->vni
);
2688 * Callback to allocate VNI hash entry.
2690 static void *zvni_alloc(void *p
)
2692 const zebra_vni_t
*tmp_vni
= p
;
2695 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2696 zvni
->vni
= tmp_vni
->vni
;
2697 return ((void *)zvni
);
2701 * Look up VNI hash entry.
2703 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2705 struct zebra_vrf
*zvrf
;
2706 zebra_vni_t tmp_vni
;
2707 zebra_vni_t
*zvni
= NULL
;
2709 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2711 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2713 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2719 * Add VNI hash entry.
2721 static zebra_vni_t
*zvni_add(vni_t vni
)
2723 struct zebra_vrf
*zvrf
;
2724 zebra_vni_t tmp_zvni
;
2725 zebra_vni_t
*zvni
= NULL
;
2727 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2729 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2731 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2734 /* Create hash table for MAC */
2736 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2738 /* Create hash table for neighbors */
2739 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2740 "Zebra VNI Neighbor Table");
2746 * Delete VNI hash entry.
2748 static int zvni_del(zebra_vni_t
*zvni
)
2750 struct zebra_vrf
*zvrf
;
2751 zebra_vni_t
*tmp_zvni
;
2753 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2756 zvni
->vxlan_if
= NULL
;
2758 /* Free the neighbor hash table. */
2759 hash_free(zvni
->neigh_table
);
2760 zvni
->neigh_table
= NULL
;
2762 /* Free the MAC hash table. */
2763 hash_free(zvni
->mac_table
);
2764 zvni
->mac_table
= NULL
;
2766 /* Free the VNI hash entry and allocated memory. */
2767 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2769 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2775 * Inform BGP about local VNI addition.
2777 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2779 struct zserv
*client
;
2782 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2783 /* BGP may not be running. */
2787 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2789 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2790 stream_putl(s
, zvni
->vni
);
2791 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2792 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2794 /* Write packet size. */
2795 stream_putw_at(s
, 0, stream_get_endp(s
));
2797 if (IS_ZEBRA_DEBUG_VXLAN
)
2798 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni
->vni
,
2799 inet_ntoa(zvni
->local_vtep_ip
),
2800 vrf_id_to_name(zvni
->vrf_id
),
2801 zebra_route_string(client
->proto
));
2803 client
->vniadd_cnt
++;
2804 return zebra_server_send_message(client
, s
);
2808 * Inform BGP about local VNI deletion.
2810 static int zvni_send_del_to_client(vni_t vni
)
2812 struct zserv
*client
;
2815 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
2816 /* BGP may not be running. */
2820 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2823 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2824 stream_putl(s
, vni
);
2826 /* Write packet size. */
2827 stream_putw_at(s
, 0, stream_get_endp(s
));
2829 if (IS_ZEBRA_DEBUG_VXLAN
)
2830 zlog_debug("Send VNI_DEL %u to %s", vni
,
2831 zebra_route_string(client
->proto
));
2833 client
->vnidel_cnt
++;
2834 return zebra_server_send_message(client
, s
);
2838 * Build the VNI hash table by going over the VxLAN interfaces. This
2839 * is called when EVPN (advertise-all-vni) is enabled.
2841 static void zvni_build_hash_table()
2843 struct zebra_ns
*zns
;
2844 struct route_node
*rn
;
2845 struct interface
*ifp
;
2847 /* Walk VxLAN interfaces and create VNI hash. */
2848 zns
= zebra_ns_lookup(NS_DEFAULT
);
2849 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2851 zebra_vni_t
*zvni
= NULL
;
2852 zebra_l3vni_t
*zl3vni
= NULL
;
2853 struct zebra_if
*zif
;
2854 struct zebra_l2info_vxlan
*vxl
;
2856 ifp
= (struct interface
*)rn
->info
;
2860 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2863 vxl
= &zif
->l2info
.vxl
;
2866 /* L3-VNI and L2-VNI are handled seperately */
2867 zl3vni
= zl3vni_lookup(vni
);
2870 if (IS_ZEBRA_DEBUG_VXLAN
)
2872 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2873 ifp
->name
, ifp
->ifindex
, vni
);
2875 /* associate with vxlan_if */
2876 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2877 zl3vni
->vxlan_if
= ifp
;
2880 * we need to associate with SVI.
2881 * we can associate with svi-if only after association
2882 * with vxlan-intf is complete
2884 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2886 if (is_l3vni_oper_up(zl3vni
))
2887 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2890 struct interface
*vlan_if
= NULL
;
2892 if (IS_ZEBRA_DEBUG_VXLAN
)
2894 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2895 ifp
->name
, ifp
->ifindex
, vni
,
2896 inet_ntoa(vxl
->vtep_ip
));
2898 /* VNI hash entry is not expected to exist. */
2899 zvni
= zvni_lookup(vni
);
2902 "VNI hash already present for IF %s(%u) L2-VNI %u",
2903 ifp
->name
, ifp
->ifindex
, vni
);
2907 zvni
= zvni_add(vni
);
2910 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2911 ifp
->name
, ifp
->ifindex
, vni
);
2915 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2916 zvni
->vxlan_if
= ifp
;
2917 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2918 zif
->brslave_info
.br_if
);
2920 zvni
->vrf_id
= vlan_if
->vrf_id
;
2921 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2923 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2927 /* Inform BGP if intf is up and mapped to bridge. */
2928 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2929 zvni_send_add_to_client(zvni
);
2935 * See if remote VTEP matches with prefix.
2937 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2939 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2943 * Locate remote VTEP in VNI hash table.
2945 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2947 zebra_vtep_t
*zvtep
;
2952 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
2953 if (zvni_vtep_match(vtep_ip
, zvtep
))
2961 * Add remote VTEP to VNI hash table.
2963 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2965 zebra_vtep_t
*zvtep
;
2967 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
2969 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni
->vni
);
2973 zvtep
->vtep_ip
= *vtep_ip
;
2976 zvni
->vteps
->prev
= zvtep
;
2977 zvtep
->next
= zvni
->vteps
;
2978 zvni
->vteps
= zvtep
;
2984 * Remove remote VTEP from VNI hash table.
2986 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
2989 zvtep
->next
->prev
= zvtep
->prev
;
2991 zvtep
->prev
->next
= zvtep
->next
;
2993 zvni
->vteps
= zvtep
->next
;
2995 zvtep
->prev
= zvtep
->next
= NULL
;
2996 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
3002 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
3003 * uninstall from kernel if asked to.
3005 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
3007 zebra_vtep_t
*zvtep
, *zvtep_next
;
3012 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
3013 zvtep_next
= zvtep
->next
;
3015 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
3016 zvni_vtep_del(zvni
, zvtep
);
3023 * Install remote VTEP into the kernel.
3025 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3027 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3031 * Uninstall remote VTEP from the kernel.
3033 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3035 if (!zvni
->vxlan_if
) {
3036 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
3041 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3045 * Cleanup VNI/VTEP and update kernel
3047 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
3049 zebra_vni_t
*zvni
= NULL
;
3050 zebra_l3vni_t
*zl3vni
= NULL
;
3051 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
3053 zvni
= (zebra_vni_t
*)backet
->data
;
3057 /* remove from l3-vni list */
3059 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
3061 listnode_delete(zl3vni
->l2vnis
, zvni
);
3063 /* Free up all neighbors and MACs, if any. */
3064 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
3065 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
3067 /* Free up all remote VTEPs, if any. */
3068 zvni_vtep_del_all(zvni
, 1);
3070 /* Delete the hash entry. */
3075 static void zl3vni_cleanup_all(struct hash_backet
*backet
, void *args
)
3077 zebra_l3vni_t
*zl3vni
= NULL
;
3079 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
3083 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
3086 static void rb_find_or_add_host(struct host_rb_tree_entry
*hrbe
,
3087 struct prefix
*host
)
3089 struct host_rb_entry lookup
;
3090 struct host_rb_entry
*hle
;
3092 memset(&lookup
, 0, sizeof(lookup
));
3093 memcpy(&lookup
.p
, host
, sizeof(*host
));
3095 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3099 hle
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct host_rb_entry
));
3100 memcpy(hle
, &lookup
, sizeof(lookup
));
3102 RB_INSERT(host_rb_tree_entry
, hrbe
, hle
);
3105 static void rb_delete_host(struct host_rb_tree_entry
*hrbe
, struct prefix
*host
)
3107 struct host_rb_entry lookup
;
3108 struct host_rb_entry
*hle
;
3110 memset(&lookup
, 0, sizeof(lookup
));
3111 memcpy(&lookup
.p
, host
, sizeof(*host
));
3113 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3115 RB_REMOVE(host_rb_tree_entry
, hrbe
, hle
);
3121 * Look up MAC hash entry.
3123 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
3124 struct ethaddr
*rmac
)
3129 memset(&tmp
, 0, sizeof(tmp
));
3130 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
3131 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
3137 * Callback to allocate RMAC hash entry.
3139 static void *zl3vni_rmac_alloc(void *p
)
3141 const zebra_mac_t
*tmp_rmac
= p
;
3144 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
3147 return ((void *)zrmac
);
3151 * Add RMAC entry to l3-vni
3153 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
)
3155 zebra_mac_t tmp_rmac
;
3156 zebra_mac_t
*zrmac
= NULL
;
3158 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
3159 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
3160 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
3163 RB_INIT(host_rb_tree_entry
, &zrmac
->host_rb
);
3165 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
3166 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
3174 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3176 zebra_mac_t
*tmp_rmac
;
3177 struct host_rb_entry
*hle
;
3179 while (!RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3180 hle
= RB_ROOT(host_rb_tree_entry
, &zrmac
->host_rb
);
3182 RB_REMOVE(host_rb_tree_entry
, &zrmac
->host_rb
, hle
);
3183 XFREE(MTYPE_HOST_PREFIX
, hle
);
3186 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
3188 XFREE(MTYPE_MAC
, tmp_rmac
);
3194 * Install remote RMAC into the kernel.
3196 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3198 struct zebra_if
*zif
= NULL
;
3199 struct zebra_l2info_vxlan
*vxl
= NULL
;
3201 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3202 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3205 zif
= zl3vni
->vxlan_if
->info
;
3209 vxl
= &zif
->l2info
.vxl
;
3211 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3212 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3216 * Uninstall remote RMAC from the kernel.
3218 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3220 char buf
[ETHER_ADDR_STRLEN
];
3221 struct zebra_if
*zif
= NULL
;
3222 struct zebra_l2info_vxlan
*vxl
= NULL
;
3224 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3225 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3228 if (!zl3vni
->vxlan_if
) {
3230 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3231 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3232 zl3vni
->vni
, zl3vni
);
3236 zif
= zl3vni
->vxlan_if
->info
;
3240 vxl
= &zif
->l2info
.vxl
;
3242 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3243 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3246 /* handle rmac add */
3247 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3248 struct ipaddr
*vtep_ip
,
3249 struct prefix
*host_prefix
)
3251 char buf
[ETHER_ADDR_STRLEN
];
3252 char buf1
[INET6_ADDRSTRLEN
];
3253 zebra_mac_t
*zrmac
= NULL
;
3255 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3258 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3261 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3262 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3264 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)));
3267 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3268 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3270 /* install rmac in kernel */
3271 zl3vni_rmac_install(zl3vni
, zrmac
);
3274 rb_find_or_add_host(&zrmac
->host_rb
, host_prefix
);
3280 /* handle rmac delete */
3281 static void zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
,
3282 struct prefix
*host_prefix
)
3284 rb_delete_host(&zrmac
->host_rb
, host_prefix
);
3286 if (RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3287 /* uninstall from kernel */
3288 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3290 /* del the rmac entry */
3291 zl3vni_rmac_del(zl3vni
, zrmac
);
3296 * Look up nh hash entry on a l3-vni.
3298 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3303 memset(&tmp
, 0, sizeof(tmp
));
3304 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3305 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3312 * Callback to allocate NH hash entry on L3-VNI.
3314 static void *zl3vni_nh_alloc(void *p
)
3316 const zebra_neigh_t
*tmp_n
= p
;
3319 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3326 * Add neighbor entry.
3328 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3329 struct ethaddr
*mac
)
3331 zebra_neigh_t tmp_n
;
3332 zebra_neigh_t
*n
= NULL
;
3334 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3335 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3336 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3339 RB_INIT(host_rb_tree_entry
, &n
->host_rb
);
3341 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3342 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3343 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3349 * Delete neighbor entry.
3351 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3353 zebra_neigh_t
*tmp_n
;
3354 struct host_rb_entry
*hle
;
3356 while (!RB_EMPTY(host_rb_tree_entry
, &n
->host_rb
)) {
3357 hle
= RB_ROOT(host_rb_tree_entry
, &n
->host_rb
);
3359 RB_REMOVE(host_rb_tree_entry
, &n
->host_rb
, hle
);
3360 XFREE(MTYPE_HOST_PREFIX
, hle
);
3363 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3365 XFREE(MTYPE_NEIGH
, tmp_n
);
3371 * Install remote nh as neigh into the kernel.
3373 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3375 if (!is_l3vni_oper_up(zl3vni
))
3378 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3379 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3382 return kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
);
3386 * Uninstall remote nh from the kernel.
3388 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3390 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3391 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3394 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3397 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3400 /* add remote vtep as a neigh entry */
3401 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3402 struct ethaddr
*rmac
,
3403 struct prefix
*host_prefix
)
3405 char buf
[ETHER_ADDR_STRLEN
];
3406 char buf1
[INET6_ADDRSTRLEN
];
3407 zebra_neigh_t
*nh
= NULL
;
3409 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3411 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3415 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3416 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)),
3417 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3422 /* install the nh neigh in kernel */
3423 zl3vni_nh_install(zl3vni
, nh
);
3426 rb_find_or_add_host(&nh
->host_rb
, host_prefix
);
3431 /* handle nh neigh delete */
3432 static void zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*nh
,
3433 struct prefix
*host_prefix
)
3435 rb_delete_host(&nh
->host_rb
, host_prefix
);
3437 if (RB_EMPTY(host_rb_tree_entry
, &nh
->host_rb
)) {
3438 /* uninstall from kernel */
3439 zl3vni_nh_uninstall(zl3vni
, nh
);
3441 /* delete the nh entry */
3442 zl3vni_nh_del(zl3vni
, nh
);
3446 /* handle neigh update from kernel - the only thing of interest is to
3447 * readd stale entries.
3449 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3453 zebra_neigh_t
*n
= NULL
;
3455 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3459 /* all next hop neigh are remote and installed by frr.
3460 * If the kernel has aged this entry, re-install.
3462 if (state
& NUD_STALE
)
3463 zl3vni_nh_install(zl3vni
, n
);
3468 /* handle neigh delete from kernel */
3469 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3471 zebra_neigh_t
*n
= NULL
;
3473 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3477 /* all next hop neigh are remote and installed by frr.
3478 * If we get an age out notification for these neigh entries, we have to
3481 zl3vni_nh_install(zl3vni
, n
);
3487 * Hash function for L3 VNI.
3489 static unsigned int l3vni_hash_keymake(void *p
)
3491 const zebra_l3vni_t
*zl3vni
= p
;
3493 return jhash_1word(zl3vni
->vni
, 0);
3497 * Compare 2 L3 VNI hash entries.
3499 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3501 const zebra_l3vni_t
*zl3vni1
= p1
;
3502 const zebra_l3vni_t
*zl3vni2
= p2
;
3504 return (zl3vni1
->vni
== zl3vni2
->vni
);
3508 * Callback to allocate L3 VNI hash entry.
3510 static void *zl3vni_alloc(void *p
)
3512 zebra_l3vni_t
*zl3vni
= NULL
;
3513 const zebra_l3vni_t
*tmp_l3vni
= p
;
3515 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3516 zl3vni
->vni
= tmp_l3vni
->vni
;
3517 return ((void *)zl3vni
);
3521 * Look up L3 VNI hash entry.
3523 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3525 struct zebra_ns
*zns
;
3526 zebra_l3vni_t tmp_l3vni
;
3527 zebra_l3vni_t
*zl3vni
= NULL
;
3529 zns
= zebra_ns_lookup(NS_DEFAULT
);
3531 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3532 tmp_l3vni
.vni
= vni
;
3533 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3539 * Add L3 VNI hash entry.
3541 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3543 zebra_l3vni_t tmp_zl3vni
;
3544 struct zebra_ns
*zns
= NULL
;
3545 zebra_l3vni_t
*zl3vni
= NULL
;
3547 zns
= zebra_ns_lookup(NS_DEFAULT
);
3550 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3551 tmp_zl3vni
.vni
= vni
;
3553 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3556 zl3vni
->vrf_id
= vrf_id
;
3557 zl3vni
->svi_if
= NULL
;
3558 zl3vni
->vxlan_if
= NULL
;
3559 zl3vni
->l2vnis
= list_new();
3560 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3562 /* Create hash table for remote RMAC */
3563 zl3vni
->rmac_table
= hash_create(mac_hash_keymake
, mac_cmp
,
3564 "Zebra L3-VNI RMAC-Table");
3566 /* Create hash table for neighbors */
3567 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3568 "Zebra L3-VNI next-hop table");
3574 * Delete L3 VNI hash entry.
3576 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3578 struct zebra_ns
*zns
;
3579 zebra_l3vni_t
*tmp_zl3vni
;
3581 zns
= zebra_ns_lookup(NS_DEFAULT
);
3584 /* free the list of l2vnis */
3585 list_delete_and_null(&zl3vni
->l2vnis
);
3586 zl3vni
->l2vnis
= NULL
;
3588 /* Free the rmac table */
3589 hash_free(zl3vni
->rmac_table
);
3590 zl3vni
->rmac_table
= NULL
;
3592 /* Free the nh table */
3593 hash_free(zl3vni
->nh_table
);
3594 zl3vni
->nh_table
= NULL
;
3596 /* Free the VNI hash entry and allocated memory. */
3597 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3599 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3604 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3606 struct zebra_ns
*zns
= NULL
;
3607 struct route_node
*rn
= NULL
;
3608 struct interface
*ifp
= NULL
;
3610 /* loop through all vxlan-interface */
3611 zns
= zebra_ns_lookup(NS_DEFAULT
);
3612 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3614 struct zebra_if
*zif
= NULL
;
3615 struct zebra_l2info_vxlan
*vxl
= NULL
;
3617 ifp
= (struct interface
*)rn
->info
;
3622 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3625 vxl
= &zif
->l2info
.vxl
;
3626 if (vxl
->vni
== zl3vni
->vni
) {
3627 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3635 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3637 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3638 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3643 if (!zl3vni
->vxlan_if
)
3646 zif
= zl3vni
->vxlan_if
->info
;
3650 vxl
= &zif
->l2info
.vxl
;
3652 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3655 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3657 struct zebra_vrf
*zvrf
= NULL
;
3659 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3663 return zl3vni_lookup(zvrf
->l3vni
);
3667 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3668 * neighbor notifications, to see if they are of interest.
3670 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3671 struct interface
*br_if
)
3675 uint8_t bridge_vlan_aware
= 0;
3676 zebra_l3vni_t
*zl3vni
= NULL
;
3677 struct zebra_ns
*zns
= NULL
;
3678 struct route_node
*rn
= NULL
;
3679 struct zebra_if
*zif
= NULL
;
3680 struct interface
*tmp_if
= NULL
;
3681 struct zebra_l2info_bridge
*br
= NULL
;
3682 struct zebra_l2info_vxlan
*vxl
= NULL
;
3687 /* Make sure the linked interface is a bridge. */
3688 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3691 /* Determine if bridge is VLAN-aware or not */
3694 br
= &zif
->l2info
.br
;
3695 bridge_vlan_aware
= br
->vlan_aware
;
3696 if (bridge_vlan_aware
) {
3697 struct zebra_l2info_vlan
*vl
;
3699 if (!IS_ZEBRA_IF_VLAN(ifp
))
3704 vl
= &zif
->l2info
.vl
;
3708 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3709 /* TODO: Optimize with a hash. */
3710 zns
= zebra_ns_lookup(NS_DEFAULT
);
3711 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3712 tmp_if
= (struct interface
*)rn
->info
;
3716 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3718 if (!if_is_operative(tmp_if
))
3720 vxl
= &zif
->l2info
.vxl
;
3722 if (zif
->brslave_info
.br_if
!= br_if
)
3725 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3734 zl3vni
= zl3vni_lookup(vxl
->vni
);
3739 * Inform BGP about l3-vni.
3741 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3743 struct stream
*s
= NULL
;
3744 struct zserv
*client
= NULL
;
3745 struct ethaddr rmac
;
3746 char buf
[ETHER_ADDR_STRLEN
];
3748 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3749 /* BGP may not be running. */
3754 memset(&rmac
, 0, sizeof(struct ethaddr
));
3755 zl3vni_get_rmac(zl3vni
, &rmac
);
3757 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3759 zclient_create_header(s
, ZEBRA_L3VNI_ADD
, zl3vni_vrf_id(zl3vni
));
3760 stream_putl(s
, zl3vni
->vni
);
3761 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3762 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3763 stream_put(s
, &zl3vni
->filter
, sizeof(int));
3765 /* Write packet size. */
3766 stream_putw_at(s
, 0, stream_get_endp(s
));
3768 if (IS_ZEBRA_DEBUG_VXLAN
)
3770 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3771 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3772 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3773 inet_ntoa(zl3vni
->local_vtep_ip
),
3774 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
3775 ? "prefix-routes-only"
3777 zebra_route_string(client
->proto
));
3779 client
->l3vniadd_cnt
++;
3780 return zebra_server_send_message(client
, s
);
3784 * Inform BGP about local l3-VNI deletion.
3786 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3788 struct stream
*s
= NULL
;
3789 struct zserv
*client
= NULL
;
3791 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3792 /* BGP may not be running. */
3796 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3798 zclient_create_header(s
, ZEBRA_L3VNI_DEL
, zl3vni_vrf_id(zl3vni
));
3799 stream_putl(s
, zl3vni
->vni
);
3801 /* Write packet size. */
3802 stream_putw_at(s
, 0, stream_get_endp(s
));
3804 if (IS_ZEBRA_DEBUG_VXLAN
)
3805 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni
->vni
,
3806 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3807 zebra_route_string(client
->proto
));
3809 client
->l3vnidel_cnt
++;
3810 return zebra_server_send_message(client
, s
);
3813 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3818 /* send l3vni add to BGP */
3819 zl3vni_send_add_to_client(zl3vni
);
3822 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3827 /* send l3-vni del to BGP*/
3828 zl3vni_send_del_to_client(zl3vni
);
3831 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
, void *ctxt
)
3833 zebra_vni_t
*zvni
= (zebra_vni_t
*)backet
->data
;
3834 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*)ctxt
;
3836 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3837 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3841 * handle transition of vni from l2 to l3 and vice versa
3843 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
, vni_t vni
,
3846 zebra_vni_t
*zvni
= NULL
;
3848 /* There is a possibility that VNI notification was already received
3849 * from kernel and we programmed it as L2-VNI
3850 * In such a case we need to delete this L2-VNI first, so
3851 * that it can be reprogrammed as L3-VNI in the system. It is also
3852 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3853 * interface is still present in kernel. In this case to keep it
3854 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3857 /* Locate hash entry */
3858 zvni
= zvni_lookup(vni
);
3862 if (IS_ZEBRA_DEBUG_VXLAN
)
3863 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni
);
3865 /* Delete VNI from BGP. */
3866 zvni_send_del_to_client(zvni
->vni
);
3868 /* Free up all neighbors and MAC, if any. */
3869 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3870 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3872 /* Free up all remote VTEPs, if any. */
3873 zvni_vtep_del_all(zvni
, 0);
3875 /* Delete the hash entry. */
3876 if (zvni_del(zvni
)) {
3877 zlog_err("Failed to del VNI hash %p, VNI %u", zvni
,
3882 /* TODO_MITESH: This needs to be thought through. We don't have
3883 * enough information at this point to reprogram the vni as
3884 * l2-vni. One way is to store the required info in l3-vni and
3885 * used it solely for this purpose
3892 /* delete and uninstall rmac hash entry */
3893 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
, void *ctx
)
3895 zebra_mac_t
*zrmac
= NULL
;
3896 zebra_l3vni_t
*zl3vni
= NULL
;
3898 zrmac
= (zebra_mac_t
*)backet
->data
;
3899 zl3vni
= (zebra_l3vni_t
*)ctx
;
3900 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3901 zl3vni_rmac_del(zl3vni
, zrmac
);
3904 /* delete and uninstall nh hash entry */
3905 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
, void *ctx
)
3907 zebra_neigh_t
*n
= NULL
;
3908 zebra_l3vni_t
*zl3vni
= NULL
;
3910 n
= (zebra_neigh_t
*)backet
->data
;
3911 zl3vni
= (zebra_l3vni_t
*)ctx
;
3912 zl3vni_nh_uninstall(zl3vni
, n
);
3913 zl3vni_nh_del(zl3vni
, n
);
3916 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
3919 struct zserv
*client
= NULL
;
3920 struct stream
*s
= NULL
;
3921 char buf
[PREFIX_STRLEN
];
3923 client
= zebra_find_client(ZEBRA_ROUTE_BGP
, 0);
3924 /* BGP may not be running. */
3928 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3930 zclient_create_header(s
, cmd
, vrf_id
);
3931 stream_put(s
, p
, sizeof(struct prefix
));
3933 /* Write packet size. */
3934 stream_putw_at(s
, 0, stream_get_endp(s
));
3936 if (IS_ZEBRA_DEBUG_VXLAN
)
3937 zlog_debug("Send ip prefix %s %s on vrf %s",
3938 prefix2str(p
, buf
, sizeof(buf
)),
3939 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
3940 vrf_id_to_name(vrf_id
));
3942 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
3943 client
->prefixadd_cnt
++;
3945 client
->prefixdel_cnt
++;
3947 return zebra_server_send_message(client
, s
);
3950 /* re-add remote rmac if needed */
3951 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
3952 struct ethaddr
*rmac
)
3954 char buf
[ETHER_ADDR_STRLEN
];
3955 zebra_mac_t
*zrmac
= NULL
;
3957 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3961 if (IS_ZEBRA_DEBUG_VXLAN
)
3962 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
3963 prefix_mac2str(rmac
, buf
, sizeof(buf
)), zl3vni
->vni
);
3965 zl3vni_rmac_install(zl3vni
, zrmac
);
3969 /* Public functions */
3971 int is_l3vni_for_prefix_routes_only(vni_t vni
)
3973 zebra_l3vni_t
*zl3vni
= NULL
;
3975 zl3vni
= zl3vni_lookup(vni
);
3979 return CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
) ? 1 : 0;
3982 /* handle evpn route in vrf table */
3983 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
3984 struct ipaddr
*vtep_ip
,
3985 struct prefix
*host_prefix
)
3987 zebra_l3vni_t
*zl3vni
= NULL
;
3988 struct ipaddr ipv4_vtep
;
3990 zl3vni
= zl3vni_from_vrf(vrf_id
);
3991 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
3995 * add the next hop neighbor -
3996 * neigh to be installed is the ipv6 nexthop neigh
3998 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
4001 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
4002 * address. Rmac is programmed against the ipv4 vtep because we only
4003 * support ipv4 tunnels in the h/w right now
4005 memset(&ipv4_vtep
, 0, sizeof(struct ipaddr
));
4006 ipv4_vtep
.ipa_type
= IPADDR_V4
;
4007 if (vtep_ip
->ipa_type
== IPADDR_V6
)
4008 ipv4_mapped_ipv6_to_ipv4(&vtep_ip
->ipaddr_v6
,
4009 &(ipv4_vtep
.ipaddr_v4
));
4011 memcpy(&(ipv4_vtep
.ipaddr_v4
), &vtep_ip
->ipaddr_v4
,
4012 sizeof(struct in_addr
));
4015 * add the rmac - remote rmac to be installed is against the ipv4
4018 zl3vni_remote_rmac_add(zl3vni
, rmac
, &ipv4_vtep
, host_prefix
);
4021 /* handle evpn vrf route delete */
4022 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
4023 struct ipaddr
*vtep_ip
,
4024 struct prefix
*host_prefix
)
4026 zebra_l3vni_t
*zl3vni
= NULL
;
4027 zebra_neigh_t
*nh
= NULL
;
4028 zebra_mac_t
*zrmac
= NULL
;
4030 zl3vni
= zl3vni_from_vrf(vrf_id
);
4034 /* find the next hop entry and rmac entry */
4035 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
4038 zrmac
= zl3vni_rmac_lookup(zl3vni
, &nh
->emac
);
4040 /* delete the next hop entry */
4041 zl3vni_remote_nh_del(zl3vni
, nh
, host_prefix
);
4043 /* delete the rmac entry */
4045 zl3vni_remote_rmac_del(zl3vni
, zrmac
, host_prefix
);
4049 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
, vni_t l3vni
,
4050 struct ethaddr
*rmac
,
4053 zebra_l3vni_t
*zl3vni
= NULL
;
4054 zebra_mac_t
*zrmac
= NULL
;
4055 json_object
*json
= NULL
;
4057 if (!is_evpn_enabled()) {
4059 vty_out(vty
, "{}\n");
4064 json
= json_object_new_object();
4066 zl3vni
= zl3vni_lookup(l3vni
);
4069 vty_out(vty
, "{}\n");
4071 vty_out(vty
, "%% L3-VNI %u doesnt exist\n", l3vni
);
4075 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4078 vty_out(vty
, "{}\n");
4081 "%% Requested RMAC doesnt exist in L3-VNI %u",
4086 zl3vni_print_rmac(zrmac
, vty
, json
);
4089 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4090 json
, JSON_C_TO_STRING_PRETTY
));
4091 json_object_free(json
);
4095 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
, vni_t l3vni
,
4098 zebra_l3vni_t
*zl3vni
;
4100 struct rmac_walk_ctx wctx
;
4101 json_object
*json
= NULL
;
4103 if (!is_evpn_enabled())
4106 zl3vni
= zl3vni_lookup(l3vni
);
4109 vty_out(vty
, "{}\n");
4111 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4114 num_rmacs
= hashcount(zl3vni
->rmac_table
);
4119 json
= json_object_new_object();
4121 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
4125 vty_out(vty
, "Number of Remote RMACs known for this VNI: %u\n",
4127 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
4129 json_object_int_add(json
, "numRmacs", num_rmacs
);
4131 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
4134 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4135 json
, JSON_C_TO_STRING_PRETTY
));
4136 json_object_free(json
);
4140 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
, uint8_t use_json
)
4142 struct zebra_ns
*zns
= NULL
;
4143 json_object
*json
= NULL
;
4146 if (!is_evpn_enabled()) {
4148 vty_out(vty
, "{}\n");
4152 zns
= zebra_ns_lookup(NS_DEFAULT
);
4155 vty_out(vty
, "{}\n");
4160 json
= json_object_new_object();
4164 hash_iterate(zns
->l3vni_table
,
4165 (void (*)(struct hash_backet
*,
4166 void *))zl3vni_print_rmac_hash_all_vni
,
4170 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4171 json
, JSON_C_TO_STRING_PRETTY
));
4172 json_object_free(json
);
4176 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
, vni_t l3vni
,
4177 struct ipaddr
*ip
, uint8_t use_json
)
4179 zebra_l3vni_t
*zl3vni
= NULL
;
4180 zebra_neigh_t
*n
= NULL
;
4181 json_object
*json
= NULL
;
4183 if (!is_evpn_enabled()) {
4185 vty_out(vty
, "{}\n");
4190 json
= json_object_new_object();
4192 zl3vni
= zl3vni_lookup(l3vni
);
4195 vty_out(vty
, "{}\n");
4197 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4201 n
= zl3vni_nh_lookup(zl3vni
, ip
);
4204 vty_out(vty
, "{}\n");
4207 "%% Requested next-hop not present for L3-VNI %u",
4212 zl3vni_print_nh(n
, vty
, json
);
4215 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4216 json
, JSON_C_TO_STRING_PRETTY
));
4217 json_object_free(json
);
4221 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
, vni_t l3vni
, uint8_t use_json
)
4224 struct nh_walk_ctx wctx
;
4225 json_object
*json
= NULL
;
4226 zebra_l3vni_t
*zl3vni
= NULL
;
4228 if (!is_evpn_enabled())
4231 zl3vni
= zl3vni_lookup(l3vni
);
4234 vty_out(vty
, "{}\n");
4236 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4240 num_nh
= hashcount(zl3vni
->nh_table
);
4245 json
= json_object_new_object();
4250 vty_out(vty
, "Number of NH Neighbors known for this VNI: %u\n",
4252 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4254 json_object_int_add(json
, "numNextHops", num_nh
);
4256 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4259 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4260 json
, JSON_C_TO_STRING_PRETTY
));
4261 json_object_free(json
);
4265 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
, uint8_t use_json
)
4267 struct zebra_ns
*zns
= NULL
;
4268 json_object
*json
= NULL
;
4271 if (!is_evpn_enabled()) {
4273 vty_out(vty
, "{}\n");
4277 zns
= zebra_ns_lookup(NS_DEFAULT
);
4282 json
= json_object_new_object();
4286 hash_iterate(zns
->l3vni_table
,
4287 (void (*)(struct hash_backet
*,
4288 void *))zl3vni_print_nh_hash_all_vni
,
4292 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4293 json
, JSON_C_TO_STRING_PRETTY
));
4294 json_object_free(json
);
4300 * Display L3 VNI information (VTY command handler).
4302 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, uint8_t use_json
)
4305 json_object
*json
= NULL
;
4306 zebra_l3vni_t
*zl3vni
= NULL
;
4308 if (!is_evpn_enabled()) {
4310 vty_out(vty
, "{}\n");
4314 zl3vni
= zl3vni_lookup(vni
);
4317 vty_out(vty
, "{}\n");
4319 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4324 json
= json_object_new_object();
4328 zl3vni_print(zl3vni
, (void *)args
);
4331 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4332 json
, JSON_C_TO_STRING_PRETTY
));
4333 json_object_free(json
);
4337 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4338 json_object
*json_vrfs
)
4340 char buf
[ETHER_ADDR_STRLEN
];
4341 zebra_l3vni_t
*zl3vni
= NULL
;
4343 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4348 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4349 zvrf_name(zvrf
), zl3vni
->vni
,
4350 zl3vni_vxlan_if_name(zl3vni
),
4351 zl3vni_svi_if_name(zl3vni
), zl3vni_state2str(zl3vni
),
4352 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4354 json_object
*json_vrf
= NULL
;
4355 json_vrf
= json_object_new_object();
4356 json_object_string_add(json_vrf
, "vrf", zvrf_name(zvrf
));
4357 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4358 json_object_string_add(json_vrf
, "vxlanIntf",
4359 zl3vni_vxlan_if_name(zl3vni
));
4360 json_object_string_add(json_vrf
, "sviIntf",
4361 zl3vni_svi_if_name(zl3vni
));
4362 json_object_string_add(json_vrf
, "state",
4363 zl3vni_state2str(zl3vni
));
4364 json_object_string_add(
4365 json_vrf
, "routerMac",
4366 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4367 json_object_array_add(json_vrfs
, json_vrf
);
4372 * Display Neighbors for a VNI (VTY command handler).
4374 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4375 vni_t vni
, uint8_t use_json
)
4379 struct neigh_walk_ctx wctx
;
4380 json_object
*json
= NULL
;
4382 if (!is_evpn_enabled())
4384 zvni
= zvni_lookup(vni
);
4387 vty_out(vty
, "{}\n");
4389 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4392 num_neigh
= hashcount(zvni
->neigh_table
);
4397 json
= json_object_new_object();
4399 /* Since we have IPv6 addresses to deal with which can vary widely in
4400 * size, we try to be a bit more elegant in display by first computing
4401 * the maximum width.
4403 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4406 wctx
.addr_width
= 15;
4408 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4412 "Number of ARPs (local and remote) known for this VNI: %u\n",
4414 vty_out(vty
, "%*s %-6s %-17s %-21s\n", -wctx
.addr_width
, "IP",
4415 "Type", "MAC", "Remote VTEP");
4417 json_object_int_add(json
, "numArpNd", num_neigh
);
4419 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4421 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4422 json
, JSON_C_TO_STRING_PRETTY
));
4423 json_object_free(json
);
4428 * Display neighbors across all VNIs (VTY command handler).
4430 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4433 json_object
*json
= NULL
;
4436 if (!is_evpn_enabled())
4440 json
= json_object_new_object();
4444 hash_iterate(zvrf
->vni_table
,
4445 (void (*)(struct hash_backet
*,
4446 void *))zvni_print_neigh_hash_all_vni
,
4449 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4450 json
, JSON_C_TO_STRING_PRETTY
));
4451 json_object_free(json
);
4456 * Display specific neighbor for a VNI, if present (VTY command handler).
4458 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4459 struct zebra_vrf
*zvrf
, vni_t vni
,
4460 struct ipaddr
*ip
, uint8_t use_json
)
4464 json_object
*json
= NULL
;
4466 if (!is_evpn_enabled())
4468 zvni
= zvni_lookup(vni
);
4471 vty_out(vty
, "{}\n");
4473 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4476 n
= zvni_neigh_lookup(zvni
, ip
);
4480 "%% Requested neighbor does not exist in VNI %u\n",
4485 json
= json_object_new_object();
4487 zvni_print_neigh(n
, vty
, json
);
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 neighbors for a VNI from specific VTEP (VTY command handler).
4498 * By definition, these are remote neighbors.
4500 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4501 vni_t vni
, struct in_addr vtep_ip
,
4506 struct neigh_walk_ctx wctx
;
4507 json_object
*json
= NULL
;
4509 if (!is_evpn_enabled())
4511 zvni
= zvni_lookup(vni
);
4514 vty_out(vty
, "{}\n");
4516 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4519 num_neigh
= hashcount(zvni
->neigh_table
);
4523 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4526 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4527 wctx
.r_vtep_ip
= vtep_ip
;
4529 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4532 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4533 json
, JSON_C_TO_STRING_PRETTY
));
4534 json_object_free(json
);
4539 * Display MACs for a VNI (VTY command handler).
4541 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4542 vni_t vni
, uint8_t use_json
)
4546 struct mac_walk_ctx wctx
;
4547 json_object
*json
= NULL
;
4548 json_object
*json_mac
= NULL
;
4550 if (!is_evpn_enabled())
4552 zvni
= zvni_lookup(vni
);
4555 vty_out(vty
, "{}\n");
4557 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4560 num_macs
= num_valid_macs(zvni
);
4565 json
= json_object_new_object();
4566 json_mac
= json_object_new_object();
4569 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4572 wctx
.json
= json_mac
;
4576 "Number of MACs (local and remote) known for this VNI: %u\n",
4578 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4579 "Intf/Remote VTEP", "VLAN");
4581 json_object_int_add(json
, "numMacs", num_macs
);
4583 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4586 json_object_object_add(json
, "macs", json_mac
);
4587 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4588 json
, JSON_C_TO_STRING_PRETTY
));
4589 json_object_free(json
);
4594 * Display MACs for all VNIs (VTY command handler).
4596 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4599 struct mac_walk_ctx wctx
;
4600 json_object
*json
= NULL
;
4602 if (!is_evpn_enabled()) {
4604 vty_out(vty
, "{}\n");
4608 json
= json_object_new_object();
4610 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4613 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4616 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4617 json
, JSON_C_TO_STRING_PRETTY
));
4618 json_object_free(json
);
4623 * Display MACs for all VNIs (VTY command handler).
4625 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
4626 struct zebra_vrf
*zvrf
,
4627 struct in_addr vtep_ip
,
4630 struct mac_walk_ctx wctx
;
4631 json_object
*json
= NULL
;
4633 if (!is_evpn_enabled())
4637 json
= json_object_new_object();
4639 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4641 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4642 wctx
.r_vtep_ip
= vtep_ip
;
4644 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
4647 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4648 json
, JSON_C_TO_STRING_PRETTY
));
4649 json_object_free(json
);
4654 * Display specific MAC for a VNI, if present (VTY command handler).
4656 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4657 vni_t vni
, struct ethaddr
*macaddr
)
4662 if (!is_evpn_enabled())
4664 zvni
= zvni_lookup(vni
);
4666 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4669 mac
= zvni_mac_lookup(zvni
, macaddr
);
4671 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
4676 zvni_print_mac(mac
, vty
);
4680 * Display MACs for a VNI from specific VTEP (VTY command handler).
4682 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4683 vni_t vni
, struct in_addr vtep_ip
,
4688 struct mac_walk_ctx wctx
;
4689 json_object
*json
= NULL
;
4690 json_object
*json_mac
= NULL
;
4692 if (!is_evpn_enabled())
4694 zvni
= zvni_lookup(vni
);
4697 vty_out(vty
, "{}\n");
4699 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4702 num_macs
= num_valid_macs(zvni
);
4707 json
= json_object_new_object();
4708 json_mac
= json_object_new_object();
4711 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
4714 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
4715 wctx
.r_vtep_ip
= vtep_ip
;
4716 wctx
.json
= json_mac
;
4717 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
4720 json_object_int_add(json
, "numMacs", wctx
.count
);
4722 json_object_object_add(json
, "macs", json_mac
);
4723 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4724 json
, JSON_C_TO_STRING_PRETTY
));
4725 json_object_free(json
);
4731 * Display VNI information (VTY command handler).
4733 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
4736 json_object
*json
= NULL
;
4738 zebra_l3vni_t
*zl3vni
= NULL
;
4739 zebra_vni_t
*zvni
= NULL
;
4741 if (!is_evpn_enabled())
4745 json
= json_object_new_object();
4749 zl3vni
= zl3vni_lookup(vni
);
4751 zl3vni_print(zl3vni
, (void *)args
);
4753 zvni
= zvni_lookup(vni
);
4756 vty_out(vty
, "{}\n");
4758 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4762 zvni_print(zvni
, (void *)args
);
4766 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4767 json
, JSON_C_TO_STRING_PRETTY
));
4768 json_object_free(json
);
4772 /* Display all global details for EVPN */
4773 void zebra_vxlan_print_evpn(struct vty
*vty
, uint8_t uj
)
4778 json_object
*json
= NULL
;
4779 struct zebra_ns
*zns
= NULL
;
4780 struct zebra_vrf
*zvrf
= NULL
;
4782 if (!is_evpn_enabled())
4785 zns
= zebra_ns_lookup(NS_DEFAULT
);
4789 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
4793 num_l3vnis
= hashcount(zns
->l3vni_table
);
4794 num_l2vnis
= hashcount(zvrf
->vni_table
);
4795 num_vnis
= num_l2vnis
+ num_l3vnis
;
4798 json
= json_object_new_object();
4799 json_object_string_add(json
, "advertiseGatewayMacip",
4800 zvrf
->advertise_gw_macip
? "Yes" : "No");
4801 json_object_int_add(json
, "numVnis", num_vnis
);
4802 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
4803 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
4805 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
4806 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
4807 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
4808 zvrf
->advertise_gw_macip
? "Yes" : "No");
4812 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4813 json
, JSON_C_TO_STRING_PRETTY
));
4814 json_object_free(json
);
4819 * Display VNI hash table (VTY command handler).
4821 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4824 json_object
*json
= NULL
;
4825 struct zebra_ns
*zns
= NULL
;
4828 if (!is_evpn_enabled())
4831 zns
= zebra_ns_lookup(NS_DEFAULT
);
4837 json
= json_object_new_object();
4839 vty_out(vty
, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
4840 "Type", "VxLAN IF", "# MACs", "# ARPs",
4841 "# Remote VTEPs", "Tenant VRF");
4846 /* Display all L2-VNIs */
4847 hash_iterate(zvrf
->vni_table
,
4848 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
4851 /* Display all L3-VNIs */
4852 hash_iterate(zns
->l3vni_table
,
4853 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
4857 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4858 json
, JSON_C_TO_STRING_PRETTY
));
4859 json_object_free(json
);
4864 * Handle neighbor delete notification from the kernel (on a VLAN device
4865 * / L3 interface). This may result in either the neighbor getting deleted
4866 * from our database or being re-added to the kernel (if it is a valid
4869 int zebra_vxlan_handle_kernel_neigh_del(struct interface
*ifp
,
4870 struct interface
*link_if
,
4873 char buf
[INET6_ADDRSTRLEN
];
4874 char buf2
[ETHER_ADDR_STRLEN
];
4875 zebra_neigh_t
*n
= NULL
;
4876 zebra_vni_t
*zvni
= NULL
;
4877 zebra_mac_t
*zmac
= NULL
;
4878 zebra_l3vni_t
*zl3vni
= NULL
;
4880 /* check if this is a remote neigh entry corresponding to remote
4883 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4885 return zl3vni_local_nh_del(zl3vni
, ip
);
4887 /* We are only interested in neighbors on an SVI that resides on top
4888 * of a VxLAN bridge.
4890 zvni
= zvni_from_svi(ifp
, link_if
);
4894 if (!zvni
->vxlan_if
) {
4896 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4901 if (IS_ZEBRA_DEBUG_VXLAN
)
4902 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4903 ipaddr2str(ip
, buf
, sizeof(buf
)), ifp
->name
,
4904 ifp
->ifindex
, zvni
->vni
);
4906 /* If entry doesn't exist, nothing to do. */
4907 n
= zvni_neigh_lookup(zvni
, ip
);
4911 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
4913 if (IS_ZEBRA_DEBUG_VXLAN
)
4915 "Trying to del a neigh %s without a mac %s on VNI %u",
4916 ipaddr2str(ip
, buf
, sizeof(buf
)),
4917 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
4923 /* If it is a remote entry, the kernel has aged this out or someone has
4924 * deleted it, it needs to be re-installed as Quagga is the owner.
4926 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
4927 zvni_neigh_install(zvni
, n
);
4931 /* Remove neighbor from BGP. */
4932 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
4933 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
, 0);
4935 /* Delete this neighbor entry. */
4936 zvni_neigh_del(zvni
, n
);
4938 /* see if the AUTO mac needs to be deleted */
4939 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
4940 && !listcount(zmac
->neigh_list
))
4941 zvni_mac_del(zvni
, zmac
);
4947 * Handle neighbor add or update notification from the kernel (on a VLAN
4948 * device / L3 interface). This is typically for a local neighbor but can
4949 * also be for a remote neighbor (e.g., ageout notification). It could
4950 * also be a "move" scenario.
4952 int zebra_vxlan_handle_kernel_neigh_update(struct interface
*ifp
,
4953 struct interface
*link_if
,
4955 struct ethaddr
*macaddr
,
4957 uint8_t ext_learned
)
4959 char buf
[ETHER_ADDR_STRLEN
];
4960 char buf2
[INET6_ADDRSTRLEN
];
4961 zebra_vni_t
*zvni
= NULL
;
4962 zebra_l3vni_t
*zl3vni
= NULL
;
4964 /* check if this is a remote neigh entry corresponding to remote
4967 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
4969 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
4971 /* We are only interested in neighbors on an SVI that resides on top
4972 * of a VxLAN bridge.
4974 zvni
= zvni_from_svi(ifp
, link_if
);
4978 if (IS_ZEBRA_DEBUG_VXLAN
)
4980 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4981 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
4982 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
4983 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
4986 /* Is this about a local neighbor or a remote one? */
4988 return zvni_local_neigh_update(zvni
, ifp
, ip
, macaddr
);
4990 return zvni_remote_neigh_update(zvni
, ifp
, ip
, macaddr
, state
);
4995 * Handle message from client to delete a remote MACIP for a VNI.
4997 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS
)
5001 struct ethaddr macaddr
;
5003 struct in_addr vtep_ip
;
5007 unsigned short l
= 0, ipa_len
;
5008 char buf
[ETHER_ADDR_STRLEN
];
5009 char buf1
[INET6_ADDRSTRLEN
];
5010 struct interface
*ifp
= NULL
;
5011 struct zebra_if
*zif
= NULL
;
5013 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5014 memset(&ip
, 0, sizeof(struct ipaddr
));
5015 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5019 while (l
< hdr
->length
) {
5020 /* Obtain each remote MACIP and process. */
5021 /* Message contains VNI, followed by MAC followed by IP (if any)
5022 * followed by remote VTEP IP.
5026 memset(&ip
, 0, sizeof(ip
));
5027 STREAM_GETL(s
, vni
);
5028 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5029 STREAM_GETL(s
, ipa_len
);
5031 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5033 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5035 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5036 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5037 l
+= IPV4_MAX_BYTELEN
;
5039 if (IS_ZEBRA_DEBUG_VXLAN
)
5041 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
5042 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5043 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
5045 zebra_route_string(client
->proto
));
5047 /* Locate VNI hash entry - expected to exist. */
5048 zvni
= zvni_lookup(vni
);
5050 if (IS_ZEBRA_DEBUG_VXLAN
)
5052 "Failed to locate VNI hash upon remote MACIP DEL, "
5057 ifp
= zvni
->vxlan_if
;
5060 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
5066 /* If down or not mapped to a bridge, we're done. */
5067 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5070 /* The remote VTEP specified is normally expected to exist, but
5072 * possible that the peer may delete the VTEP before deleting
5074 * referring to the VTEP, in which case the handler (see
5076 * would have already deleted the MACs.
5078 if (!zvni_vtep_find(zvni
, &vtep_ip
))
5081 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5083 n
= zvni_neigh_lookup(zvni
, &ip
);
5086 zlog_err("Failed to locate MAC %s for neigh %s VNI %u",
5087 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5088 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
5092 /* If the remote mac or neighbor doesn't exist there is nothing
5094 * to do. Otherwise, uninstall the entry and then remove it.
5099 /* Ignore the delete if this mac is a gateway mac-ip */
5100 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
5101 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
5103 "%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway",
5105 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5106 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
);
5110 /* Uninstall remote neighbor or MAC. */
5112 /* When the MAC changes for an IP, it is possible the
5114 * update the new MAC before trying to delete the "old"
5116 * (as these are two different MACIP routes). Do the
5118 * if the MAC matches.
5120 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5121 && (memcmp(n
->emac
.octet
, macaddr
.octet
, ETH_ALEN
)
5123 zvni_neigh_uninstall(zvni
, n
);
5124 zvni_neigh_del(zvni
, n
);
5125 zvni_deref_ip2mac(zvni
, mac
, 1);
5128 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5129 zvni_process_neigh_on_remote_mac_del(zvni
, mac
);
5131 if (list_isempty(mac
->neigh_list
)) {
5132 zvni_mac_uninstall(zvni
, mac
, 0);
5133 zvni_mac_del(zvni
, mac
);
5135 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5145 * Handle message from client to add a remote MACIP for a VNI. This
5146 * could be just the add of a MAC address or the add of a neighbor
5149 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS
)
5153 struct ethaddr macaddr
;
5155 struct in_addr vtep_ip
;
5157 zebra_vtep_t
*zvtep
;
5158 zebra_mac_t
*mac
, *old_mac
;
5160 unsigned short l
= 0, ipa_len
;
5161 int update_mac
= 0, update_neigh
= 0;
5162 char buf
[ETHER_ADDR_STRLEN
];
5163 char buf1
[INET6_ADDRSTRLEN
];
5166 struct interface
*ifp
= NULL
;
5167 struct zebra_if
*zif
= NULL
;
5169 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5170 memset(&ip
, 0, sizeof(struct ipaddr
));
5171 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5173 if (!EVPN_ENABLED(zvrf
)) {
5175 "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
5176 __PRETTY_FUNCTION__
);
5182 while (l
< hdr
->length
) {
5183 /* Obtain each remote MACIP and process. */
5184 /* Message contains VNI, followed by MAC followed by IP (if any)
5185 * followed by remote VTEP IP.
5187 update_mac
= update_neigh
= 0;
5190 memset(&ip
, 0, sizeof(ip
));
5191 STREAM_GETL(s
, vni
);
5192 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5193 STREAM_GETL(s
, ipa_len
);
5195 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5197 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5199 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5200 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5201 l
+= IPV4_MAX_BYTELEN
;
5203 /* Get flags - sticky mac and/or gateway mac */
5204 STREAM_GETC(s
, flags
);
5205 sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
5208 if (IS_ZEBRA_DEBUG_VXLAN
)
5210 "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
5211 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5212 ipaddr2str(&ip
, buf1
, sizeof(buf1
)), vni
,
5213 inet_ntoa(vtep_ip
), flags
,
5214 zebra_route_string(client
->proto
));
5216 /* Locate VNI hash entry - expected to exist. */
5217 zvni
= zvni_lookup(vni
);
5220 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
5224 ifp
= zvni
->vxlan_if
;
5227 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5233 /* If down or not mapped to a bridge, we're done. */
5234 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5237 /* The remote VTEP specified should normally exist, but it is
5239 * that when peering comes up, peer may advertise MACIP routes
5241 * advertising type-3 routes.
5243 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5245 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5247 "Failed to add remote VTEP, VNI %u zvni %p",
5252 zvni_vtep_install(zvni
, &vtep_ip
);
5255 mac
= zvni_mac_lookup(zvni
, &macaddr
);
5257 /* Ignore the update if the mac is already present
5259 if (mac
&& CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)
5260 && CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
5261 if (IS_ZEBRA_DEBUG_VXLAN
)
5263 "%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
5265 prefix_mac2str(&macaddr
, buf
,
5267 ipaddr2str(&ip
, buf1
, sizeof(buf1
)),
5272 /* check if the remote MAC is unknown or has a change.
5273 * If so, that needs to be updated first. Note that client could
5274 * install MAC and MACIP separately or just install the latter.
5276 if (!mac
|| !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
5277 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0)
5279 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
))
5284 mac
= zvni_mac_add(zvni
, &macaddr
);
5287 "Failed to add MAC %s VNI %u Remote VTEP %s",
5288 prefix_mac2str(&macaddr
, buf
,
5290 vni
, inet_ntoa(vtep_ip
));
5294 /* Is this MAC created for a MACIP? */
5296 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5299 /* Set "auto" and "remote" forwarding info. */
5300 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5301 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5302 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5303 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
5306 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5308 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5310 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
5312 /* Install the entry. */
5313 zvni_mac_install(zvni
, mac
);
5316 /* If there is no IP, continue - after clearing AUTO flag of
5319 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5323 /* Check if the remote neighbor itself is unknown or has a
5325 * If so, create or update and then install the entry.
5327 n
= zvni_neigh_lookup(zvni
, &ip
);
5328 if (!n
|| !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
5329 || (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
)) != 0)
5330 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
))
5335 n
= zvni_neigh_add(zvni
, &ip
, &macaddr
);
5338 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5339 ipaddr2str(&ip
, buf1
,
5341 prefix_mac2str(&macaddr
, buf
,
5343 vni
, inet_ntoa(vtep_ip
));
5347 } else if (memcmp(&n
->emac
, &macaddr
, sizeof(macaddr
))
5349 /* MAC change, update neigh list for old and new
5351 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
5353 listnode_delete(old_mac
->neigh_list
, n
);
5354 zvni_deref_ip2mac(zvni
, old_mac
, 1);
5356 listnode_add_sort(mac
->neigh_list
, n
);
5357 memcpy(&n
->emac
, &macaddr
, ETH_ALEN
);
5360 /* Set "remote" forwarding info. */
5361 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
5362 /* TODO: Handle MAC change. */
5363 n
->r_vtep_ip
= vtep_ip
;
5364 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
5366 /* Install the entry. */
5367 zvni_neigh_install(zvni
, n
);
5376 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5377 * us, this must involve a multihoming scenario. Treat this as implicit delete
5378 * of any prior local MAC.
5380 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5381 struct interface
*br_if
,
5382 struct ethaddr
*macaddr
, vlanid_t vid
)
5384 struct zebra_if
*zif
;
5385 struct zebra_l2info_vxlan
*vxl
;
5389 char buf
[ETHER_ADDR_STRLEN
];
5393 vxl
= &zif
->l2info
.vxl
;
5396 /* Check if EVPN is enabled. */
5397 if (!is_evpn_enabled())
5400 /* Locate hash entry; it is expected to exist. */
5401 zvni
= zvni_lookup(vni
);
5405 /* If entry doesn't exist, nothing to do. */
5406 mac
= zvni_mac_lookup(zvni
, macaddr
);
5410 /* Is it a local entry? */
5411 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5414 if (IS_ZEBRA_DEBUG_VXLAN
)
5416 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5417 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5420 /* Remove MAC from BGP. */
5421 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5424 * If there are no neigh associated with the mac delete the mac
5425 * else mark it as AUTO for forward reference
5427 if (!listcount(mac
->neigh_list
)) {
5428 zvni_mac_del(zvni
, mac
);
5430 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5431 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5438 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5439 * This can happen because the remote MAC entries are also added as "dynamic",
5440 * so the kernel can ageout the entry.
5442 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5443 struct interface
*br_if
,
5444 struct ethaddr
*macaddr
, vlanid_t vid
)
5446 struct zebra_if
*zif
= NULL
;
5447 struct zebra_l2info_vxlan
*vxl
= NULL
;
5449 zebra_vni_t
*zvni
= NULL
;
5450 zebra_l3vni_t
*zl3vni
= NULL
;
5451 zebra_mac_t
*mac
= NULL
;
5452 char buf
[ETHER_ADDR_STRLEN
];
5456 vxl
= &zif
->l2info
.vxl
;
5459 /* Check if EVPN is enabled. */
5460 if (!is_evpn_enabled())
5463 /* check if this is a remote RMAC and readd simillar to remote macs */
5464 zl3vni
= zl3vni_lookup(vni
);
5466 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5468 /* Locate hash entry; it is expected to exist. */
5469 zvni
= zvni_lookup(vni
);
5473 /* If entry doesn't exist, nothing to do. */
5474 mac
= zvni_mac_lookup(zvni
, macaddr
);
5478 /* Is it a remote entry? */
5479 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5482 if (IS_ZEBRA_DEBUG_VXLAN
)
5483 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5484 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5487 zvni_mac_install(zvni
, mac
);
5492 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5494 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5495 struct ethaddr
*macaddr
, vlanid_t vid
)
5499 char buf
[ETHER_ADDR_STRLEN
];
5501 /* We are interested in MACs only on ports or (port, VLAN) that
5504 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5507 if (!zvni
->vxlan_if
) {
5508 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5513 if (IS_ZEBRA_DEBUG_VXLAN
)
5514 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5515 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5516 ifp
->ifindex
, vid
, zvni
->vni
);
5518 /* If entry doesn't exist, nothing to do. */
5519 mac
= zvni_mac_lookup(zvni
, macaddr
);
5523 /* Is it a local entry? */
5524 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5527 /* Remove MAC from BGP. */
5528 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5530 /* Update all the neigh entries associated with this mac */
5531 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5534 * If there are no neigh associated with the mac delete the mac
5535 * else mark it as AUTO for forward reference
5537 if (!listcount(mac
->neigh_list
)) {
5538 zvni_mac_del(zvni
, mac
);
5540 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5541 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5548 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5550 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5551 struct interface
*br_if
,
5552 struct ethaddr
*macaddr
, vlanid_t vid
,
5557 char buf
[ETHER_ADDR_STRLEN
];
5561 /* We are interested in MACs only on ports or (port, VLAN) that
5564 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5566 if (IS_ZEBRA_DEBUG_VXLAN
)
5568 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5569 sticky
? "sticky " : "",
5570 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5571 ifp
->name
, ifp
->ifindex
, vid
);
5575 if (!zvni
->vxlan_if
) {
5576 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5581 if (IS_ZEBRA_DEBUG_VXLAN
)
5582 zlog_debug("Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5583 sticky
? "sticky " : "",
5584 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5585 ifp
->ifindex
, vid
, zvni
->vni
);
5587 /* If same entry already exists, nothing to do. */
5588 mac
= zvni_mac_lookup(zvni
, macaddr
);
5590 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5591 mac_sticky
= CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
5597 * return if nothing has changed.
5598 * inform bgp if sticky flag has changed
5599 * update locally and do not inform bgp if local
5600 * parameters like interface has changed
5602 if (mac_sticky
== sticky
5603 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5604 && mac
->fwd_info
.local
.vid
== vid
) {
5605 if (IS_ZEBRA_DEBUG_VXLAN
)
5607 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5608 "entry exists and has not changed ",
5609 sticky
? "sticky " : "",
5610 prefix_mac2str(macaddr
, buf
,
5612 ifp
->name
, ifp
->ifindex
, vid
,
5615 } else if (mac_sticky
!= sticky
) {
5618 add
= 0; /* This is an update of local
5621 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
5623 * If we have already learned the MAC as a remote sticky
5625 * this is a operator error and we must log a warning
5627 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5629 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5630 prefix_mac2str(macaddr
, buf
,
5632 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5640 mac
= zvni_mac_add(zvni
, macaddr
);
5642 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5643 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5644 ifp
->name
, ifp
->ifindex
, vid
);
5649 /* Set "local" forwarding info. */
5650 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5651 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5652 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5653 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5654 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5655 mac
->fwd_info
.local
.vid
= vid
;
5658 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5660 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5662 /* Inform BGP if required. */
5664 zvni_process_neigh_on_local_mac_add(zvni
, mac
);
5665 return zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5673 * Handle message from client to delete a remote VTEP for a VNI.
5675 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS
)
5678 unsigned short l
= 0;
5680 struct in_addr vtep_ip
;
5682 zebra_vtep_t
*zvtep
;
5683 struct interface
*ifp
;
5684 struct zebra_if
*zif
;
5686 if (!is_evpn_enabled()) {
5688 "%s: EVPN is not enabled yet we have received a vtep del command",
5689 __PRETTY_FUNCTION__
);
5693 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5694 zlog_err("Recv MACIP DEL for non-default VRF %u",
5701 while (l
< hdr
->length
) {
5702 /* Obtain each remote VTEP and process. */
5703 STREAM_GETL(s
, vni
);
5705 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5706 l
+= IPV4_MAX_BYTELEN
;
5708 if (IS_ZEBRA_DEBUG_VXLAN
)
5709 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5710 inet_ntoa(vtep_ip
), vni
,
5711 zebra_route_string(client
->proto
));
5713 /* Locate VNI hash entry - expected to exist. */
5714 zvni
= zvni_lookup(vni
);
5716 if (IS_ZEBRA_DEBUG_VXLAN
)
5718 "Failed to locate VNI hash upon remote VTEP DEL, "
5724 ifp
= zvni
->vxlan_if
;
5727 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5733 /* If down or not mapped to a bridge, we're done. */
5734 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5737 /* If the remote VTEP does not exist, there's nothing more to
5739 * Otherwise, uninstall any remote MACs pointing to this VTEP
5741 * then, the VTEP entry itself and remove it.
5743 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5747 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5748 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5749 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5750 zvni_vtep_del(zvni
, zvtep
);
5758 * Handle message from client to add a remote VTEP for a VNI.
5760 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS
)
5763 unsigned short l
= 0;
5765 struct in_addr vtep_ip
;
5767 struct interface
*ifp
;
5768 struct zebra_if
*zif
;
5770 if (!is_evpn_enabled()) {
5772 "%s: EVPN not enabled yet we received a vtep_add zapi call",
5773 __PRETTY_FUNCTION__
);
5777 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5778 zlog_err("Recv MACIP ADD for non-default VRF %u",
5785 while (l
< hdr
->length
) {
5786 /* Obtain each remote VTEP and process. */
5787 STREAM_GETL(s
, vni
);
5789 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5790 l
+= IPV4_MAX_BYTELEN
;
5792 if (IS_ZEBRA_DEBUG_VXLAN
)
5793 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5794 inet_ntoa(vtep_ip
), vni
,
5795 zebra_route_string(client
->proto
));
5797 /* Locate VNI hash entry - expected to exist. */
5798 zvni
= zvni_lookup(vni
);
5801 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5806 ifp
= zvni
->vxlan_if
;
5809 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5816 /* If down or not mapped to a bridge, we're done. */
5817 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5820 /* If the remote VTEP already exists,
5821 there's nothing more to do. */
5822 if (zvni_vtep_find(zvni
, &vtep_ip
))
5825 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
5826 zlog_err("Failed to add remote VTEP, VNI %u zvni %p",
5831 zvni_vtep_install(zvni
, &vtep_ip
);
5839 * Add/Del gateway macip to evpn
5841 * 1. SVI interface on a vlan aware bridge
5842 * 2. SVI interface on a vlan unaware bridge
5843 * 3. vrr interface (MACVLAN) associated to a SVI
5844 * We advertise macip routes for an interface if it is associated to VxLan vlan
5846 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
5850 struct ethaddr macaddr
;
5851 zebra_vni_t
*zvni
= NULL
;
5853 memset(&ip
, 0, sizeof(struct ipaddr
));
5854 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5856 /* Check if EVPN is enabled. */
5857 if (!is_evpn_enabled())
5860 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
5861 struct interface
*svi_if
=
5862 NULL
; /* SVI corresponding to the MACVLAN */
5863 struct zebra_if
*ifp_zif
=
5864 NULL
; /* Zebra daemon specific info for MACVLAN */
5865 struct zebra_if
*svi_if_zif
=
5866 NULL
; /* Zebra daemon specific info for SVI*/
5868 ifp_zif
= ifp
->info
;
5873 * for a MACVLAN interface the link represents the svi_if
5875 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
5876 ifp_zif
->link_ifindex
);
5878 zlog_err("MACVLAN %s(%u) without link information",
5879 ifp
->name
, ifp
->ifindex
);
5883 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
5885 * If it is a vlan aware bridge then the link gives the
5886 * bridge information
5888 struct interface
*svi_if_link
= NULL
;
5890 svi_if_zif
= svi_if
->info
;
5892 svi_if_link
= if_lookup_by_index_per_ns(
5893 zebra_ns_lookup(NS_DEFAULT
),
5894 svi_if_zif
->link_ifindex
);
5895 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
5897 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
5899 * If it is a vlan unaware bridge then svi is the bridge
5902 zvni
= zvni_from_svi(svi_if
, svi_if
);
5904 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
5905 struct zebra_if
*svi_if_zif
=
5906 NULL
; /* Zebra daemon specific info for SVI */
5907 struct interface
*svi_if_link
=
5908 NULL
; /* link info for the SVI = bridge info */
5910 svi_if_zif
= ifp
->info
;
5912 svi_if_link
= if_lookup_by_index_per_ns(
5913 zebra_ns_lookup(NS_DEFAULT
),
5914 svi_if_zif
->link_ifindex
);
5916 zvni
= zvni_from_svi(ifp
, svi_if_link
);
5918 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
5919 zvni
= zvni_from_svi(ifp
, ifp
);
5925 if (!zvni
->vxlan_if
) {
5926 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5932 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
5934 if (p
->family
== AF_INET
) {
5935 ip
.ipa_type
= IPADDR_V4
;
5936 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
5937 sizeof(struct in_addr
));
5938 } else if (p
->family
== AF_INET6
) {
5939 ip
.ipa_type
= IPADDR_V6
;
5940 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
5941 sizeof(struct in6_addr
));
5946 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
5948 zvni_gw_macip_del(ifp
, zvni
, &ip
);
5954 * Handle SVI interface going down.
5955 * SVI can be associated to either L3-VNI or L2-VNI.
5956 * For L2-VNI: At this point, this is a NOP since
5957 * the kernel deletes the neighbor entries on this SVI (if any).
5958 * We only need to update the vrf corresponding to zvni.
5959 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5962 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
5964 zebra_l3vni_t
*zl3vni
= NULL
;
5966 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5969 /* process l3-vni down */
5970 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
5972 /* remove association with svi-if */
5973 zl3vni
->svi_if
= NULL
;
5975 zebra_vni_t
*zvni
= NULL
;
5977 /* since we dont have svi corresponding to zvni, we associate it
5978 * to default vrf. Note: the corresponding neigh entries on the
5979 * SVI would have already been deleted */
5980 zvni
= zvni_from_svi(ifp
, link_if
);
5982 zvni
->vrf_id
= VRF_DEFAULT
;
5984 /* update the tenant vrf in BGP */
5985 zvni_send_add_to_client(zvni
);
5992 * Handle SVI interface coming up.
5993 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5995 * For L2-VNI: we need to install any remote neighbors entried (used for
5997 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5999 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
6001 zebra_vni_t
*zvni
= NULL
;
6002 zebra_l3vni_t
*zl3vni
= NULL
;
6004 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6007 /* associate with svi */
6008 zl3vni
->svi_if
= ifp
;
6010 /* process oper-up */
6011 if (is_l3vni_oper_up(zl3vni
))
6012 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6015 /* process SVI up for l2-vni */
6016 struct neigh_walk_ctx n_wctx
;
6018 zvni
= zvni_from_svi(ifp
, link_if
);
6022 if (!zvni
->vxlan_if
) {
6023 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
6028 if (IS_ZEBRA_DEBUG_VXLAN
)
6030 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
6031 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
6032 vrf_id_to_name(ifp
->vrf_id
));
6034 /* update the vrf information for l2-vni and inform bgp */
6035 zvni
->vrf_id
= ifp
->vrf_id
;
6036 zvni_send_add_to_client(zvni
);
6038 /* Install any remote neighbors for this VNI. */
6039 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6041 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6049 * Handle VxLAN interface down
6051 int zebra_vxlan_if_down(struct interface
*ifp
)
6054 struct zebra_if
*zif
= NULL
;
6055 struct zebra_l2info_vxlan
*vxl
= NULL
;
6056 zebra_l3vni_t
*zl3vni
= NULL
;
6059 /* Check if EVPN is enabled. */
6060 if (!is_evpn_enabled())
6065 vxl
= &zif
->l2info
.vxl
;
6068 zl3vni
= zl3vni_lookup(vni
);
6070 /* process-if-down for l3-vni */
6071 if (IS_ZEBRA_DEBUG_VXLAN
)
6072 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
6075 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6077 /* process if-down for l2-vni */
6078 if (IS_ZEBRA_DEBUG_VXLAN
)
6079 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
6082 /* Locate hash entry; it is expected to exist. */
6083 zvni
= zvni_lookup(vni
);
6086 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6087 ifp
->name
, ifp
->ifindex
, vni
);
6091 assert(zvni
->vxlan_if
== ifp
);
6093 /* Delete this VNI from BGP. */
6094 zvni_send_del_to_client(zvni
->vni
);
6096 /* Free up all neighbors and MACs, if any. */
6097 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6098 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6100 /* Free up all remote VTEPs, if any. */
6101 zvni_vtep_del_all(zvni
, 1);
6107 * Handle VxLAN interface up - update BGP if required.
6109 int zebra_vxlan_if_up(struct interface
*ifp
)
6112 struct zebra_if
*zif
= NULL
;
6113 struct zebra_l2info_vxlan
*vxl
= NULL
;
6114 zebra_vni_t
*zvni
= NULL
;
6115 zebra_l3vni_t
*zl3vni
= NULL
;
6117 /* Check if EVPN is enabled. */
6118 if (!is_evpn_enabled())
6123 vxl
= &zif
->l2info
.vxl
;
6126 zl3vni
= zl3vni_lookup(vni
);
6129 if (IS_ZEBRA_DEBUG_VXLAN
)
6130 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp
->name
,
6133 /* we need to associate with SVI, if any, we can associate with
6134 * svi-if only after association with vxlan-intf is complete
6136 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6138 if (is_l3vni_oper_up(zl3vni
))
6139 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6141 /* Handle L2-VNI add */
6142 struct interface
*vlan_if
= NULL
;
6144 if (IS_ZEBRA_DEBUG_VXLAN
)
6145 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
6148 /* Locate hash entry; it is expected to exist. */
6149 zvni
= zvni_lookup(vni
);
6152 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6153 ifp
->name
, ifp
->ifindex
, vni
);
6157 assert(zvni
->vxlan_if
== ifp
);
6158 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6159 zif
->brslave_info
.br_if
);
6161 zvni
->vrf_id
= vlan_if
->vrf_id
;
6162 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6164 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6167 /* If part of a bridge, inform BGP about this VNI. */
6168 /* Also, read and populate local MACs and neighbors. */
6169 if (zif
->brslave_info
.br_if
) {
6170 zvni_send_add_to_client(zvni
);
6171 zvni_read_mac_neigh(zvni
, ifp
);
6179 * Handle VxLAN interface delete. Locate and remove entry in hash table
6180 * and update BGP, if required.
6182 int zebra_vxlan_if_del(struct interface
*ifp
)
6185 struct zebra_if
*zif
= NULL
;
6186 struct zebra_l2info_vxlan
*vxl
= NULL
;
6187 zebra_vni_t
*zvni
= NULL
;
6188 zebra_l3vni_t
*zl3vni
= NULL
;
6190 /* Check if EVPN is enabled. */
6191 if (!is_evpn_enabled())
6196 vxl
= &zif
->l2info
.vxl
;
6199 zl3vni
= zl3vni_lookup(vni
);
6202 if (IS_ZEBRA_DEBUG_VXLAN
)
6203 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
6206 /* process oper-down for l3-vni */
6207 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6209 /* remove the association with vxlan_if */
6210 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6211 zl3vni
->vxlan_if
= NULL
;
6214 /* process if-del for l2-vni*/
6215 if (IS_ZEBRA_DEBUG_VXLAN
)
6216 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
6219 /* Locate hash entry; it is expected to exist. */
6220 zvni
= zvni_lookup(vni
);
6223 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6224 ifp
->name
, ifp
->ifindex
, vni
);
6228 /* remove from l3-vni list */
6229 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6231 listnode_delete(zl3vni
->l2vnis
, zvni
);
6233 /* Delete VNI from BGP. */
6234 zvni_send_del_to_client(zvni
->vni
);
6236 /* Free up all neighbors and MAC, if any. */
6237 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6238 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6240 /* Free up all remote VTEPs, if any. */
6241 zvni_vtep_del_all(zvni
, 0);
6243 /* Delete the hash entry. */
6244 if (zvni_del(zvni
)) {
6245 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6246 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6254 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6256 int zebra_vxlan_if_update(struct interface
*ifp
, uint16_t chgflags
)
6259 struct zebra_if
*zif
= NULL
;
6260 struct zebra_l2info_vxlan
*vxl
= NULL
;
6261 zebra_vni_t
*zvni
= NULL
;
6262 zebra_l3vni_t
*zl3vni
= NULL
;
6264 /* Check if EVPN is enabled. */
6265 if (!is_evpn_enabled())
6270 vxl
= &zif
->l2info
.vxl
;
6273 zl3vni
= zl3vni_lookup(vni
);
6276 if (IS_ZEBRA_DEBUG_VXLAN
)
6278 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6279 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6280 inet_ntoa(vxl
->vtep_ip
),
6281 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6283 /* Removed from bridge? Cleanup and return */
6284 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6285 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6286 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6290 /* access-vlan change - process oper down, associate with new
6291 * svi_if and then process oper up again
6293 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6294 if (if_is_operative(ifp
)) {
6295 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6296 zl3vni
->svi_if
= NULL
;
6297 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6298 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6299 if (is_l3vni_oper_up(zl3vni
))
6300 zebra_vxlan_process_l3vni_oper_up(
6306 * local-ip change - process oper down, associate with new
6307 * local-ip and then process oper up again
6309 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
6310 if (if_is_operative(ifp
)) {
6311 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6312 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6313 if (is_l3vni_oper_up(zl3vni
))
6314 zebra_vxlan_process_l3vni_oper_up(
6319 /* Update local tunnel IP. */
6320 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6322 /* if we have a valid new master, process l3-vni oper up */
6323 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6324 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
6325 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6329 /* Update VNI hash. */
6330 zvni
= zvni_lookup(vni
);
6333 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6334 ifp
->name
, ifp
->ifindex
, vni
);
6338 if (IS_ZEBRA_DEBUG_VXLAN
)
6340 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6341 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6342 inet_ntoa(vxl
->vtep_ip
),
6343 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6345 /* Removed from bridge? Cleanup and return */
6346 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6347 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6348 /* Delete from client, remove all remote VTEPs */
6349 /* Also, free up all MACs and neighbors. */
6350 zvni_send_del_to_client(zvni
->vni
);
6351 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6352 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6353 zvni_vtep_del_all(zvni
, 1);
6357 /* Handle other changes. */
6358 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6359 /* Remove all existing local neigh and MACs for this VNI
6360 * (including from BGP)
6362 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6363 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6366 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6367 zvni
->vxlan_if
= ifp
;
6369 /* Take further actions needed.
6370 * Note that if we are here, there is a change of interest.
6372 /* If down or not mapped to a bridge, we're done. */
6373 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6376 /* Inform BGP, if there is a change of interest. */
6378 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6379 zvni_send_add_to_client(zvni
);
6381 /* If there is a valid new master or a VLAN mapping change,
6382 * read and populate local MACs and neighbors.
6383 * Also, reinstall any remote MACs and neighbors
6384 * for this VNI (based on new VLAN).
6386 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6387 zvni_read_mac_neigh(zvni
, ifp
);
6388 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6389 struct mac_walk_ctx m_wctx
;
6390 struct neigh_walk_ctx n_wctx
;
6392 zvni_read_mac_neigh(zvni
, ifp
);
6394 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6396 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
,
6399 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6401 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6410 * Handle VxLAN interface add.
6412 int zebra_vxlan_if_add(struct interface
*ifp
)
6415 struct zebra_if
*zif
= NULL
;
6416 struct zebra_l2info_vxlan
*vxl
= NULL
;
6417 zebra_vni_t
*zvni
= NULL
;
6418 zebra_l3vni_t
*zl3vni
= NULL
;
6420 /* Check if EVPN is enabled. */
6421 if (!is_evpn_enabled())
6426 vxl
= &zif
->l2info
.vxl
;
6429 zl3vni
= zl3vni_lookup(vni
);
6432 /* process if-add for l3-vni*/
6433 if (IS_ZEBRA_DEBUG_VXLAN
)
6435 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6436 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6437 inet_ntoa(vxl
->vtep_ip
),
6438 zif
->brslave_info
.bridge_ifindex
);
6440 /* associate with vxlan_if */
6441 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6442 zl3vni
->vxlan_if
= ifp
;
6444 /* Associate with SVI, if any. We can associate with svi-if only
6445 * after association with vxlan_if is complete */
6446 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6448 if (is_l3vni_oper_up(zl3vni
))
6449 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6452 /* process if-add for l2-vni */
6453 struct interface
*vlan_if
= NULL
;
6455 /* Create or update VNI hash. */
6456 zvni
= zvni_lookup(vni
);
6458 zvni
= zvni_add(vni
);
6461 "Failed to add VNI hash, IF %s(%u) VNI %u",
6462 ifp
->name
, ifp
->ifindex
, vni
);
6467 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6468 zvni
->vxlan_if
= ifp
;
6469 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6470 zif
->brslave_info
.br_if
);
6472 zvni
->vrf_id
= vlan_if
->vrf_id
;
6473 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6475 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6478 if (IS_ZEBRA_DEBUG_VXLAN
)
6480 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6482 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
)
6484 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6485 inet_ntoa(vxl
->vtep_ip
),
6486 zif
->brslave_info
.bridge_ifindex
);
6488 /* If down or not mapped to a bridge, we're done. */
6489 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6493 zvni_send_add_to_client(zvni
);
6495 /* Read and populate local MACs and neighbors */
6496 zvni_read_mac_neigh(zvni
, ifp
);
6502 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
, vni_t vni
,
6503 char *err
, int err_str_sz
, int filter
,
6506 zebra_l3vni_t
*zl3vni
= NULL
;
6507 struct zebra_vrf
*zvrf_default
= NULL
;
6509 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6513 if (IS_ZEBRA_DEBUG_VXLAN
)
6514 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf
), vni
,
6515 add
? "ADD" : "DEL");
6519 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6521 /* check if the vni is already present under zvrf */
6523 snprintf(err
, err_str_sz
,
6524 "VNI is already configured under the vrf");
6528 /* check if this VNI is already present in the system */
6529 zl3vni
= zl3vni_lookup(vni
);
6531 snprintf(err
, err_str_sz
,
6532 "VNI is already configured as L3-VNI");
6536 /* add the L3-VNI to the global table */
6537 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6539 snprintf(err
, err_str_sz
, "Could not add L3-VNI");
6543 /* associate the vrf with vni */
6546 /* set the filter in l3vni to denote if we are using l3vni only
6550 SET_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
);
6552 /* associate with vxlan-intf;
6553 * we need to associate with the vxlan-intf first
6555 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6557 /* associate with corresponding SVI interface, we can associate
6558 * with svi-if only after vxlan interface association is
6561 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6563 /* formulate l2vni list */
6564 hash_iterate(zvrf_default
->vni_table
, zvni_add_to_l3vni_list
,
6567 if (is_l3vni_oper_up(zl3vni
))
6568 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6571 zl3vni
= zl3vni_lookup(vni
);
6573 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6577 if (filter
&& !CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)) {
6578 snprintf(err
, ERR_STR_SZ
,
6579 "prefix-routes-only is not set for the vni");
6583 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6585 /* delete and uninstall all rmacs */
6586 hash_iterate(zl3vni
->rmac_table
, zl3vni_del_rmac_hash_entry
,
6589 /* delete and uninstall all next-hops */
6590 hash_iterate(zl3vni
->nh_table
, zl3vni_del_nh_hash_entry
,
6596 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6601 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6603 zebra_l3vni_t
*zl3vni
= NULL
;
6606 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6610 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6611 if (is_l3vni_oper_up(zl3vni
))
6612 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6616 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6618 zebra_l3vni_t
*zl3vni
= NULL
;
6621 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6625 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6626 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6630 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6632 zebra_l3vni_t
*zl3vni
= NULL
;
6636 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6642 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6648 * Handle message from client to enable/disable advertisement of g/w macip
6651 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS
)
6656 zebra_vni_t
*zvni
= NULL
;
6657 struct interface
*ifp
= NULL
;
6658 struct zebra_if
*zif
= NULL
;
6659 struct zebra_l2info_vxlan zl2_info
;
6660 struct interface
*vlan_if
= NULL
;
6662 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6663 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6669 STREAM_GETC(s
, advertise
);
6670 vni
= stream_get3(s
);
6672 zvni
= zvni_lookup(vni
);
6676 if (zvni
->advertise_subnet
== advertise
)
6679 if (IS_ZEBRA_DEBUG_VXLAN
)
6680 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
6681 advertise
? "enabled" : "disabled", vni
,
6682 zvni
->advertise_subnet
? "enabled" : "disabled");
6685 zvni
->advertise_subnet
= advertise
;
6687 ifp
= zvni
->vxlan_if
;
6693 /* If down or not mapped to a bridge, we're done. */
6694 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6697 zl2_info
= zif
->l2info
.vxl
;
6700 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
6704 if (zvni
->advertise_subnet
)
6705 zvni_advertise_subnet(zvni
, vlan_if
, 1);
6707 zvni_advertise_subnet(zvni
, vlan_if
, 0);
6714 * Handle message from client to enable/disable advertisement of g/w macip
6717 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS
)
6722 zebra_vni_t
*zvni
= NULL
;
6723 struct interface
*ifp
= NULL
;
6725 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6726 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6732 STREAM_GETC(s
, advertise
);
6733 STREAM_GETL(s
, vni
);
6736 if (IS_ZEBRA_DEBUG_VXLAN
)
6737 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6738 advertise
? "enabled" : "disabled",
6739 advertise_gw_macip_enabled(NULL
)
6743 if (zvrf
->advertise_gw_macip
== advertise
)
6746 zvrf
->advertise_gw_macip
= advertise
;
6748 if (advertise_gw_macip_enabled(zvni
))
6749 hash_iterate(zvrf
->vni_table
,
6750 zvni_gw_macip_add_for_vni_hash
, NULL
);
6752 hash_iterate(zvrf
->vni_table
,
6753 zvni_gw_macip_del_for_vni_hash
, NULL
);
6756 struct zebra_if
*zif
= NULL
;
6757 struct zebra_l2info_vxlan zl2_info
;
6758 struct interface
*vlan_if
= NULL
;
6759 struct interface
*vrr_if
= NULL
;
6761 zvni
= zvni_lookup(vni
);
6765 if (IS_ZEBRA_DEBUG_VXLAN
)
6767 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6768 advertise
? "enabled" : "disabled", vni
,
6769 advertise_gw_macip_enabled(zvni
) ? "enabled"
6772 if (zvni
->advertise_gw_macip
== advertise
)
6775 zvni
->advertise_gw_macip
= advertise
;
6777 ifp
= zvni
->vxlan_if
;
6783 /* If down or not mapped to a bridge, we're done. */
6784 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6787 zl2_info
= zif
->l2info
.vxl
;
6789 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
6790 zif
->brslave_info
.br_if
);
6794 if (advertise_gw_macip_enabled(zvni
)) {
6795 /* Add primary SVI MAC-IP */
6796 zvni_add_macip_for_intf(vlan_if
, zvni
);
6798 /* Add VRR MAC-IP - if any*/
6799 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6801 zvni_add_macip_for_intf(vrr_if
, zvni
);
6803 /* Del primary MAC-IP */
6804 zvni_del_macip_for_intf(vlan_if
, zvni
);
6806 /* Del VRR MAC-IP - if any*/
6807 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
6809 zvni_del_macip_for_intf(vrr_if
, zvni
);
6819 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6820 * When enabled, the VNI hash table will be built and MAC FDB table read;
6821 * when disabled, the entries should be deleted and remote VTEPs and MACs
6822 * uninstalled from the kernel.
6824 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS
)
6826 struct stream
*s
= NULL
;
6828 struct zebra_ns
*zns
= NULL
;
6830 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6831 zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf
));
6836 STREAM_GETC(s
, advertise
);
6838 if (IS_ZEBRA_DEBUG_VXLAN
)
6839 zlog_debug("EVPN VNI Adv %s, currently %s",
6840 advertise
? "enabled" : "disabled",
6841 is_evpn_enabled() ? "enabled" : "disabled");
6843 if (zvrf
->advertise_all_vni
== advertise
)
6846 zvrf
->advertise_all_vni
= advertise
;
6847 if (is_evpn_enabled()) {
6848 /* Build VNI hash table and inform BGP. */
6849 zvni_build_hash_table();
6851 /* Add all SVI (L3 GW) MACs to BGP*/
6852 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
6855 /* Read the MAC FDB */
6856 macfdb_read(zvrf
->zns
);
6858 /* Read neighbors */
6859 neigh_read(zvrf
->zns
);
6861 /* Cleanup VTEPs for all VNIs - uninstall from
6862 * kernel and free entries.
6864 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6866 /* cleanup all l3vnis */
6867 zns
= zebra_ns_lookup(NS_DEFAULT
);
6871 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
6879 * Allocate VNI hash table for this VRF and do other initialization.
6880 * NOTE: Currently supported only for default VRF.
6882 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
6886 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
6887 "Zebra VRF VNI Table");
6890 /* Cleanup VNI info, but don't free the table. */
6891 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
6895 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6898 /* Close all VNI handling */
6899 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
6903 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
6904 hash_free(zvrf
->vni_table
);
6907 /* init the l3vni table */
6908 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
6910 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
6911 "Zebra VRF L3 VNI table");
6914 /* free l3vni table */
6915 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
6917 hash_free(zns
->l3vni_table
);
6920 /* get the l3vni svi ifindex */
6921 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
6923 zebra_l3vni_t
*zl3vni
= NULL
;
6925 zl3vni
= zl3vni_from_vrf(vrf_id
);
6926 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
6929 return zl3vni
->svi_if
->ifindex
;