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 <linux/neighbour.h>
40 #include "zebra/debug.h"
41 #include "zebra/interface.h"
42 #include "zebra/rib.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/zebra_errors.h"
46 #include "zebra/zebra_l2.h"
47 #include "zebra/zebra_memory.h"
48 #include "zebra/zebra_ns.h"
49 #include "zebra/zebra_vrf.h"
50 #include "zebra/zebra_vxlan.h"
51 #include "zebra/zebra_vxlan_private.h"
52 #include "zebra/zserv.h"
54 DEFINE_MTYPE_STATIC(ZEBRA
, HOST_PREFIX
, "host prefix");
55 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI
, "VNI hash");
56 DEFINE_MTYPE_STATIC(ZEBRA
, ZL3VNI
, "L3 VNI hash");
57 DEFINE_MTYPE_STATIC(ZEBRA
, ZVNI_VTEP
, "VNI remote VTEP");
58 DEFINE_MTYPE_STATIC(ZEBRA
, MAC
, "VNI MAC");
59 DEFINE_MTYPE_STATIC(ZEBRA
, NEIGH
, "VNI Neighbor");
63 /* static function declarations */
64 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
66 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
);
67 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
);
68 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
70 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
72 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
74 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
);
75 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
);
76 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
);
77 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
);
78 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[]);
80 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
81 struct ipaddr
*ip
, uint8_t flags
,
82 uint32_t seq
, uint16_t cmd
);
83 static unsigned int neigh_hash_keymake(void *p
);
84 static int neigh_cmp(const void *p1
, const void *p2
);
85 static void *zvni_neigh_alloc(void *p
);
86 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
88 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
89 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
90 struct in_addr
*r_vtep_ip
);
91 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
93 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
94 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
95 struct ethaddr
*macaddr
,
96 uint8_t flags
, uint32_t seq
);
97 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
98 struct ethaddr
*macaddr
,
100 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
101 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
102 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
103 struct interface
*br_if
);
104 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
);
106 /* l3-vni next-hop neigh related APIs */
107 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
109 static void *zl3vni_nh_alloc(void *p
);
110 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
111 struct ipaddr
*vtep_ip
,
112 struct ethaddr
*rmac
);
113 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
114 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
115 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
117 /* l3-vni rmac related APIs */
118 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
119 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
120 struct ethaddr
*rmac
);
121 static void *zl3vni_rmac_alloc(void *p
);
122 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
123 struct ethaddr
*rmac
);
124 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
125 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
126 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
128 /* l3-vni related APIs*/
129 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
130 static void *zl3vni_alloc(void *p
);
131 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
132 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
133 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
134 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
135 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
136 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
137 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
139 static unsigned int mac_hash_keymake(void *p
);
140 static int mac_cmp(const void *p1
, const void *p2
);
141 static void *zvni_mac_alloc(void *p
);
142 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
143 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
144 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
145 struct in_addr
*r_vtep_ip
);
146 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
148 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
149 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
150 uint8_t flags
, uint32_t seq
);
151 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
153 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
154 struct interface
*br_if
, vlanid_t vid
);
155 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
156 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
);
157 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
159 static unsigned int vni_hash_keymake(void *p
);
160 static int vni_hash_cmp(const void *p1
, const void *p2
);
161 static void *zvni_alloc(void *p
);
162 static zebra_vni_t
*zvni_lookup(vni_t vni
);
163 static zebra_vni_t
*zvni_add(vni_t vni
);
164 static int zvni_del(zebra_vni_t
*zvni
);
165 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
166 static int zvni_send_del_to_client(vni_t vni
);
167 static void zvni_build_hash_table();
168 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
169 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
170 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
171 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
172 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
173 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
174 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
175 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
176 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
177 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
178 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
179 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
181 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
182 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
183 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
186 /* Private functions */
187 static int host_rb_entry_compare(const struct host_rb_entry
*hle1
,
188 const struct host_rb_entry
*hle2
)
190 if (hle1
->p
.family
< hle2
->p
.family
)
193 if (hle1
->p
.family
> hle2
->p
.family
)
196 if (hle1
->p
.prefixlen
< hle2
->p
.prefixlen
)
199 if (hle1
->p
.prefixlen
> hle2
->p
.prefixlen
)
202 if (hle1
->p
.family
== AF_INET
) {
203 if (hle1
->p
.u
.prefix4
.s_addr
< hle2
->p
.u
.prefix4
.s_addr
)
206 if (hle1
->p
.u
.prefix4
.s_addr
> hle2
->p
.u
.prefix4
.s_addr
)
210 } else if (hle1
->p
.family
== AF_INET6
) {
211 return memcmp(&hle1
->p
.u
.prefix6
, &hle2
->p
.u
.prefix6
,
214 zlog_debug("%s: Unexpected family type: %d",
215 __PRETTY_FUNCTION__
, hle1
->p
.family
);
219 RB_GENERATE(host_rb_tree_entry
, host_rb_entry
, hl_entry
, host_rb_entry_compare
);
221 static uint32_t rb_host_count(struct host_rb_tree_entry
*hrbe
)
223 struct host_rb_entry
*hle
;
226 RB_FOREACH (hle
, host_rb_tree_entry
, hrbe
)
233 * Return number of valid MACs in a VNI's MAC hash table - all
234 * remote MACs and non-internal (auto) local MACs count.
236 static uint32_t num_valid_macs(zebra_vni_t
*zvni
)
239 uint32_t num_macs
= 0;
241 struct hash_backet
*hb
;
244 hash
= zvni
->mac_table
;
247 for (i
= 0; i
< hash
->size
; i
++) {
248 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
249 mac
= (zebra_mac_t
*)hb
->data
;
250 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
251 || CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
252 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
260 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
262 struct zebra_vrf
*zvrf
;
264 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
265 if (zvrf
&& zvrf
->advertise_gw_macip
)
268 if (zvni
&& zvni
->advertise_gw_macip
)
275 * Helper function to determine maximum width of neighbor IP address for
276 * display - just because we're dealing with IPv6 addresses that can
279 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
282 char buf
[INET6_ADDRSTRLEN
];
283 struct neigh_walk_ctx
*wctx
= ctxt
;
286 n
= (zebra_neigh_t
*)backet
->data
;
288 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
289 if (width
> wctx
->addr_width
)
290 wctx
->addr_width
= width
;
295 * Print a specific neighbor entry.
297 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
300 char buf1
[ETHER_ADDR_STRLEN
];
301 char buf2
[INET6_ADDRSTRLEN
];
302 const char *type_str
;
303 const char *state_str
;
304 bool flags_present
= false;
306 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
307 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
308 type_str
= CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) ?
310 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
311 vty
= (struct vty
*)ctxt
;
313 vty_out(vty
, "IP: %s\n",
314 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
315 vty_out(vty
, " Type: %s\n", type_str
);
316 vty_out(vty
, " State: %s\n", state_str
);
317 vty_out(vty
, " MAC: %s\n",
318 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
320 json_object_string_add(json
, "ip", buf2
);
321 json_object_string_add(json
, "type", type_str
);
322 json_object_string_add(json
, "state", state_str
);
323 json_object_string_add(json
, "mac", buf1
);
325 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
327 vty_out(vty
, " Remote VTEP: %s\n",
328 inet_ntoa(n
->r_vtep_ip
));
330 json_object_string_add(json
, "remoteVtep",
331 inet_ntoa(n
->r_vtep_ip
));
333 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
335 vty_out(vty
, " Flags: Default-gateway");
336 flags_present
= true;
338 json_object_boolean_true_add(json
, "defaultGateway");
340 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)) {
343 flags_present
? " ,Router" : " Flags: Router");
344 flags_present
= true;
350 vty_out(vty
, " Local Seq: %u Remote Seq: %u\n",
351 n
->loc_seq
, n
->rem_seq
);
353 json_object_int_add(json
, "localSequence", n
->loc_seq
);
354 json_object_int_add(json
, "remoteSequence", n
->rem_seq
);
359 * Print neighbor hash entry - called for display of all neighbors.
361 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
364 json_object
*json_vni
= NULL
, *json_row
= NULL
;
366 char buf1
[ETHER_ADDR_STRLEN
];
367 char buf2
[INET6_ADDRSTRLEN
];
368 struct neigh_walk_ctx
*wctx
= ctxt
;
369 const char *state_str
;
372 json_vni
= wctx
->json
;
373 n
= (zebra_neigh_t
*)backet
->data
;
376 json_row
= json_object_new_object();
378 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
379 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
380 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
381 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
382 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)
385 if (json_vni
== NULL
) {
386 vty_out(vty
, "%*s %-6s %-8s %-17s\n",
387 -wctx
->addr_width
, buf2
, "local",
390 json_object_string_add(json_row
, "type", "local");
391 json_object_string_add(json_row
, "state", state_str
);
392 json_object_string_add(json_row
, "mac", buf1
);
393 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
394 json_object_boolean_true_add(
395 json_row
, "defaultGateway");
396 json_object_int_add(json_row
, "localSequence",
398 json_object_int_add(json_row
, "remoteSequence",
402 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
403 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
404 !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))
407 if (json_vni
== NULL
) {
408 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
411 "%*s %-6s %-8s %-17s %-21s\n",
412 -wctx
->addr_width
, "Neighbor", "Type",
413 "State", "MAC", "Remote VTEP");
414 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
415 -wctx
->addr_width
, buf2
, "remote", state_str
,
416 buf1
, inet_ntoa(n
->r_vtep_ip
));
418 json_object_string_add(json_row
, "type", "remote");
419 json_object_string_add(json_row
, "state", state_str
);
420 json_object_string_add(json_row
, "mac", buf1
);
421 json_object_string_add(json_row
, "remoteVtep",
422 inet_ntoa(n
->r_vtep_ip
));
423 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
424 json_object_boolean_true_add(json_row
,
426 json_object_int_add(json_row
, "localSequence",
428 json_object_int_add(json_row
, "remoteSequence",
435 json_object_object_add(json_vni
, buf2
, json_row
);
439 * Print neighbors for all VNI.
441 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
445 json_object
*json
= NULL
, *json_vni
= NULL
;
448 struct neigh_walk_ctx wctx
;
449 char vni_str
[VNI_STR_LEN
];
451 vty
= (struct vty
*)args
[0];
452 json
= (json_object
*)args
[1];
454 zvni
= (zebra_vni_t
*)backet
->data
;
456 num_neigh
= hashcount(zvni
->neigh_table
);
459 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
460 zvni
->vni
, num_neigh
);
462 json_vni
= json_object_new_object();
463 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
464 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
468 json_object_object_add(json
, vni_str
, json_vni
);
472 /* Since we have IPv6 addresses to deal with which can vary widely in
473 * size, we try to be a bit more elegant in display by first computing
476 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
479 wctx
.addr_width
= 15;
480 wctx
.json
= json_vni
;
481 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
484 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
485 -wctx
.addr_width
, "IP", "Type",
486 "State", "MAC", "Remote VTEP");
488 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
491 json_object_object_add(json
, vni_str
, json_vni
);
494 /* print a specific next hop for an l3vni */
495 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
498 char buf1
[ETHER_ADDR_STRLEN
];
499 char buf2
[INET6_ADDRSTRLEN
];
500 json_object
*json_hosts
= NULL
;
501 struct host_rb_entry
*hle
;
504 vty_out(vty
, "Ip: %s\n",
505 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
506 vty_out(vty
, " RMAC: %s\n",
507 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
508 vty_out(vty
, " Refcount: %d\n",
509 rb_host_count(&n
->host_rb
));
510 vty_out(vty
, " Prefixes:\n");
511 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
512 vty_out(vty
, " %s\n",
513 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
515 json_hosts
= json_object_new_array();
516 json_object_string_add(
517 json
, "ip", ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)));
518 json_object_string_add(
520 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)));
521 json_object_int_add(json
, "refCount",
522 rb_host_count(&n
->host_rb
));
523 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
524 json_object_array_add(json_hosts
,
525 json_object_new_string(prefix2str(
526 &hle
->p
, buf2
, sizeof(buf2
))));
527 json_object_object_add(json
, "prefixList", json_hosts
);
531 /* Print a specific RMAC entry */
532 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
535 char buf1
[ETHER_ADDR_STRLEN
];
536 char buf2
[PREFIX_STRLEN
];
537 json_object
*json_hosts
= NULL
;
538 struct host_rb_entry
*hle
;
541 vty_out(vty
, "MAC: %s\n",
542 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
543 vty_out(vty
, " Remote VTEP: %s\n",
544 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
545 vty_out(vty
, " Refcount: %d\n", rb_host_count(&zrmac
->host_rb
));
546 vty_out(vty
, " Prefixes:\n");
547 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
548 vty_out(vty
, " %s\n",
549 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
551 json_hosts
= json_object_new_array();
552 json_object_string_add(
554 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
555 json_object_string_add(json
, "vtepIp",
556 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
557 json_object_int_add(json
, "refCount",
558 rb_host_count(&zrmac
->host_rb
));
559 json_object_int_add(json
, "localSequence", zrmac
->loc_seq
);
560 json_object_int_add(json
, "remoteSequence", zrmac
->rem_seq
);
561 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
562 json_object_array_add(
564 json_object_new_string(prefix2str(
565 &hle
->p
, buf2
, sizeof(buf2
))));
566 json_object_object_add(json
, "prefixList", json_hosts
);
571 * Print a specific MAC entry.
573 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
576 zebra_neigh_t
*n
= NULL
;
577 struct listnode
*node
= NULL
;
579 char buf2
[INET6_ADDRSTRLEN
];
581 vty
= (struct vty
*)ctxt
;
582 vty_out(vty
, "MAC: %s",
583 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
584 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
585 struct zebra_ns
*zns
;
586 struct interface
*ifp
;
589 ifindex
= mac
->fwd_info
.local
.ifindex
;
590 zns
= zebra_ns_lookup(NS_DEFAULT
);
591 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
592 if (!ifp
) // unexpected
594 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
595 if (mac
->fwd_info
.local
.vid
)
596 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
597 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
598 vty_out(vty
, " Remote VTEP: %s",
599 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
600 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
601 vty_out(vty
, " Auto Mac ");
604 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
605 vty_out(vty
, " Sticky Mac ");
607 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
608 vty_out(vty
, " Default-gateway Mac ");
610 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
))
611 vty_out(vty
, " Remote-gateway Mac ");
614 vty_out(vty
, " Local Seq: %u Remote Seq: %u",
615 mac
->loc_seq
, mac
->rem_seq
);
618 /* print all the associated neigh */
619 vty_out(vty
, " Neighbors:\n");
620 if (!listcount(mac
->neigh_list
))
621 vty_out(vty
, " No Neighbors\n");
623 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
624 vty_out(vty
, " %s %s\n",
625 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
626 (IS_ZEBRA_NEIGH_ACTIVE(n
)
627 ? "Active" : "Inactive"));
635 * Print MAC hash entry - called for display of all MACs.
637 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
640 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
643 struct mac_walk_ctx
*wctx
= ctxt
;
646 json_mac_hdr
= wctx
->json
;
647 mac
= (zebra_mac_t
*)backet
->data
;
649 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
652 json_mac
= json_object_new_object();
654 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
655 struct zebra_ns
*zns
;
657 struct interface
*ifp
;
660 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)
663 zns
= zebra_ns_lookup(NS_DEFAULT
);
664 ifindex
= mac
->fwd_info
.local
.ifindex
;
665 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
666 if (!ifp
) // unexpected
668 vid
= mac
->fwd_info
.local
.vid
;
669 if (json_mac_hdr
== NULL
)
670 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
673 json_object_string_add(json_mac
, "type", "local");
674 json_object_string_add(json_mac
, "intf", ifp
->name
);
677 if (json_mac_hdr
== NULL
)
678 vty_out(vty
, " %-5u", vid
);
680 json_object_int_add(json_mac
, "vlan", vid
);
682 if (json_mac_hdr
== NULL
) {
685 json_object_int_add(json_mac
, "localSequence",
687 json_object_int_add(json_mac
, "remoteSequence",
689 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
694 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
696 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
697 !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
701 if (json_mac_hdr
== NULL
) {
702 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
703 (wctx
->count
== 0)) {
704 vty_out(vty
, "\nVNI %u\n\n", wctx
->zvni
->vni
);
705 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC",
706 "Type", "Intf/Remote VTEP", "VLAN");
708 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
, "remote",
709 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
711 json_object_string_add(json_mac
, "type", "remote");
712 json_object_string_add(json_mac
, "remoteVtep",
713 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
714 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
715 json_object_int_add(json_mac
, "localSequence",
717 json_object_int_add(json_mac
, "remoteSequence",
726 * Print MACs for all VNI.
728 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
731 json_object
*json
= NULL
, *json_vni
= NULL
;
732 json_object
*json_mac
= NULL
;
735 struct mac_walk_ctx
*wctx
= ctxt
;
736 char vni_str
[VNI_STR_LEN
];
738 vty
= (struct vty
*)wctx
->vty
;
739 json
= (struct json_object
*)wctx
->json
;
741 zvni
= (zebra_vni_t
*)backet
->data
;
744 /*We are iterating over a new VNI, set the count to 0*/
747 num_macs
= num_valid_macs(zvni
);
752 json_vni
= json_object_new_object();
753 json_mac
= json_object_new_object();
754 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
757 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
759 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
760 zvni
->vni
, num_macs
);
761 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
762 "Intf/Remote VTEP", "VLAN");
764 json_object_int_add(json_vni
, "numMacs", num_macs
);
766 /* assign per-vni to wctx->json object to fill macs
767 * under the vni. Re-assign primary json object to fill
768 * next vni information.
770 wctx
->json
= json_mac
;
771 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
775 json_object_object_add(json_vni
, "macs", json_mac
);
776 json_object_object_add(json
, vni_str
, json_vni
);
780 static void zl3vni_print_nh_hash(struct hash_backet
*backet
, void *ctx
)
782 struct nh_walk_ctx
*wctx
= NULL
;
783 struct vty
*vty
= NULL
;
784 struct json_object
*json_vni
= NULL
;
785 struct json_object
*json_nh
= NULL
;
786 zebra_neigh_t
*n
= NULL
;
787 char buf1
[ETHER_ADDR_STRLEN
];
788 char buf2
[INET6_ADDRSTRLEN
];
790 wctx
= (struct nh_walk_ctx
*)ctx
;
792 json_vni
= wctx
->json
;
794 json_nh
= json_object_new_object();
795 n
= (zebra_neigh_t
*)backet
->data
;
798 vty_out(vty
, "%-15s %-17s\n",
799 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
800 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
802 json_object_string_add(json_nh
, "nexthopIp",
803 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
804 json_object_string_add(
805 json_nh
, "routerMac",
806 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
807 json_object_object_add(json_vni
,
808 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
813 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
816 struct vty
*vty
= NULL
;
817 json_object
*json
= NULL
;
818 json_object
*json_vni
= NULL
;
819 zebra_l3vni_t
*zl3vni
= NULL
;
821 struct nh_walk_ctx wctx
;
822 char vni_str
[VNI_STR_LEN
];
824 vty
= (struct vty
*)args
[0];
825 json
= (struct json_object
*)args
[1];
827 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
829 num_nh
= hashcount(zl3vni
->nh_table
);
834 json_vni
= json_object_new_object();
835 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
839 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n", zl3vni
->vni
, num_nh
);
840 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
842 json_object_int_add(json_vni
, "numNextHops", num_nh
);
844 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
846 wctx
.json
= json_vni
;
847 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
849 json_object_object_add(json
, vni_str
, json_vni
);
852 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
855 struct vty
*vty
= NULL
;
856 json_object
*json
= NULL
;
857 json_object
*json_vni
= NULL
;
858 zebra_l3vni_t
*zl3vni
= NULL
;
860 struct rmac_walk_ctx wctx
;
861 char vni_str
[VNI_STR_LEN
];
863 vty
= (struct vty
*)args
[0];
864 json
= (struct json_object
*)args
[1];
866 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
868 num_rmacs
= hashcount(zl3vni
->rmac_table
);
873 json_vni
= json_object_new_object();
874 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
878 vty_out(vty
, "\nVNI %u #RMACs %u\n\n", zl3vni
->vni
, num_rmacs
);
879 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
881 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
883 /* assign per-vni to wctx->json object to fill macs
884 * under the vni. Re-assign primary json object to fill
885 * next vni information.
887 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
889 wctx
.json
= json_vni
;
890 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
892 json_object_object_add(json
, vni_str
, json_vni
);
895 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
, void *ctx
)
897 zebra_mac_t
*zrmac
= NULL
;
898 struct rmac_walk_ctx
*wctx
= NULL
;
899 struct vty
*vty
= NULL
;
900 struct json_object
*json
= NULL
;
901 struct json_object
*json_rmac
= NULL
;
902 char buf
[ETHER_ADDR_STRLEN
];
904 wctx
= (struct rmac_walk_ctx
*)ctx
;
908 json_rmac
= json_object_new_object();
909 zrmac
= (zebra_mac_t
*)backet
->data
;
912 vty_out(vty
, "%-17s %-21s\n",
913 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
914 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
916 json_object_string_add(
917 json_rmac
, "routerMac",
918 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)));
919 json_object_string_add(json_rmac
, "vtepIp",
920 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
921 json_object_object_add(
922 json
, prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
927 /* print a specific L3 VNI entry */
928 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
930 char buf
[ETHER_ADDR_STRLEN
];
931 struct vty
*vty
= NULL
;
932 json_object
*json
= NULL
;
933 zebra_vni_t
*zvni
= NULL
;
934 json_object
*json_vni_list
= NULL
;
935 struct listnode
*node
= NULL
, *nnode
= NULL
;
941 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
942 vty_out(vty
, " Type: %s\n", "L3");
943 vty_out(vty
, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni
));
944 vty_out(vty
, " Local Vtep Ip: %s\n",
945 inet_ntoa(zl3vni
->local_vtep_ip
));
946 vty_out(vty
, " Vxlan-Intf: %s\n",
947 zl3vni_vxlan_if_name(zl3vni
));
948 vty_out(vty
, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni
));
949 vty_out(vty
, " State: %s\n", zl3vni_state2str(zl3vni
));
950 vty_out(vty
, " VNI Filter: %s\n",
951 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
952 ? "prefix-routes-only"
954 vty_out(vty
, " Router MAC: %s\n",
955 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
956 vty_out(vty
, " L2 VNIs: ");
957 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
958 vty_out(vty
, "%u ", zvni
->vni
);
961 json_vni_list
= json_object_new_array();
962 json_object_int_add(json
, "vni", zl3vni
->vni
);
963 json_object_string_add(json
, "type", "L3");
964 json_object_string_add(json
, "localVtepIp",
965 inet_ntoa(zl3vni
->local_vtep_ip
));
966 json_object_string_add(json
, "vxlanIntf",
967 zl3vni_vxlan_if_name(zl3vni
));
968 json_object_string_add(json
, "sviIntf",
969 zl3vni_svi_if_name(zl3vni
));
970 json_object_string_add(json
, "state", zl3vni_state2str(zl3vni
));
971 json_object_string_add(json
, "vrf", zl3vni_vrf_name(zl3vni
));
972 json_object_string_add(
974 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
975 json_object_string_add(
977 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
978 ? "prefix-routes-only"
980 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
981 json_object_array_add(json_vni_list
,
982 json_object_new_int(zvni
->vni
));
984 json_object_object_add(json
, "l2Vnis", json_vni_list
);
989 * Print a specific VNI entry.
991 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
997 json_object
*json
= NULL
;
998 json_object
*json_vtep_list
= NULL
;
999 json_object
*json_ip_str
= NULL
;
1005 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
1006 vty_out(vty
, " Type: %s\n", "L2");
1007 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
1009 json_object_int_add(json
, "vni", zvni
->vni
);
1010 json_object_string_add(json
, "type", "L2");
1011 json_object_string_add(json
, "vrf",
1012 vrf_id_to_name(zvni
->vrf_id
));
1015 if (!zvni
->vxlan_if
) { // unexpected
1017 vty_out(vty
, " VxLAN interface: unknown\n");
1020 num_macs
= num_valid_macs(zvni
);
1021 num_neigh
= hashcount(zvni
->neigh_table
);
1023 vty_out(vty
, " VxLAN interface: %s\n", zvni
->vxlan_if
->name
);
1024 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
1025 vty_out(vty
, " Local VTEP IP: %s\n",
1026 inet_ntoa(zvni
->local_vtep_ip
));
1028 json_object_string_add(json
, "vxlanInterface",
1029 zvni
->vxlan_if
->name
);
1030 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
1031 json_object_string_add(json
, "vtepIp",
1032 inet_ntoa(zvni
->local_vtep_ip
));
1033 json_object_string_add(json
, "advertiseGatewayMacip",
1034 zvni
->advertise_gw_macip
? "Yes" : "No");
1035 json_object_int_add(json
, "numMacs", num_macs
);
1036 json_object_int_add(json
, "numArpNd", num_neigh
);
1040 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1043 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1045 json_vtep_list
= json_object_new_array();
1046 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1048 vty_out(vty
, " %s\n",
1049 inet_ntoa(zvtep
->vtep_ip
));
1051 json_ip_str
= json_object_new_string(
1052 inet_ntoa(zvtep
->vtep_ip
));
1053 json_object_array_add(json_vtep_list
,
1058 json_object_object_add(json
, "numRemoteVteps",
1063 " Number of MACs (local and remote) known for this VNI: %u\n",
1066 " Number of ARPs (IPv4 and IPv6, local and remote) "
1067 "known for this VNI: %u\n",
1069 vty_out(vty
, " Advertise-gw-macip: %s\n",
1070 zvni
->advertise_gw_macip
? "Yes" : "No");
1074 /* print a L3 VNI hash entry */
1075 static void zl3vni_print_hash(struct hash_backet
*backet
, void *ctx
[])
1077 struct vty
*vty
= NULL
;
1078 json_object
*json
= NULL
;
1079 json_object
*json_vni
= NULL
;
1080 zebra_l3vni_t
*zl3vni
= NULL
;
1082 vty
= (struct vty
*)ctx
[0];
1083 json
= (json_object
*)ctx
[1];
1085 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1088 vty_out(vty
, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1089 zl3vni
->vni
, "L3", zl3vni_vxlan_if_name(zl3vni
),
1090 hashcount(zl3vni
->rmac_table
),
1091 hashcount(zl3vni
->nh_table
), "n/a",
1092 zl3vni_vrf_name(zl3vni
));
1094 char vni_str
[VNI_STR_LEN
];
1096 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1097 json_vni
= json_object_new_object();
1098 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1099 json_object_string_add(json_vni
, "vxlanIf",
1100 zl3vni_vxlan_if_name(zl3vni
));
1101 json_object_int_add(json_vni
, "numMacs",
1102 hashcount(zl3vni
->rmac_table
));
1103 json_object_int_add(json_vni
, "numArpNd",
1104 hashcount(zl3vni
->nh_table
));
1105 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1106 json_object_string_add(json_vni
, "type", "L3");
1107 json_object_string_add(json_vni
, "tenantVrf",
1108 zl3vni_vrf_name(zl3vni
));
1109 json_object_object_add(json
, vni_str
, json_vni
);
1114 * Print a VNI hash entry - called for display of all VNIs.
1116 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1120 zebra_vtep_t
*zvtep
;
1121 uint32_t num_vteps
= 0;
1122 uint32_t num_macs
= 0;
1123 uint32_t num_neigh
= 0;
1124 json_object
*json
= NULL
;
1125 json_object
*json_vni
= NULL
;
1126 json_object
*json_ip_str
= NULL
;
1127 json_object
*json_vtep_list
= NULL
;
1132 zvni
= (zebra_vni_t
*)backet
->data
;
1134 zvtep
= zvni
->vteps
;
1137 zvtep
= zvtep
->next
;
1140 num_macs
= num_valid_macs(zvni
);
1141 num_neigh
= hashcount(zvni
->neigh_table
);
1143 vty_out(vty
, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1145 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1146 num_macs
, num_neigh
, num_vteps
,
1147 vrf_id_to_name(zvni
->vrf_id
));
1149 char vni_str
[VNI_STR_LEN
];
1150 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1151 json_vni
= json_object_new_object();
1152 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1153 json_object_string_add(json_vni
, "type", "L2");
1154 json_object_string_add(json_vni
, "vxlanIf",
1155 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1157 json_object_int_add(json_vni
, "numMacs", num_macs
);
1158 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1159 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1160 json_object_string_add(json_vni
, "tenantVrf",
1161 vrf_id_to_name(zvni
->vrf_id
));
1163 json_vtep_list
= json_object_new_array();
1164 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1165 json_ip_str
= json_object_new_string(
1166 inet_ntoa(zvtep
->vtep_ip
));
1167 json_object_array_add(json_vtep_list
,
1170 json_object_object_add(json_vni
, "remoteVteps",
1173 json_object_object_add(json
, vni_str
, json_vni
);
1178 * Inform BGP about local MACIP.
1180 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
1181 struct ipaddr
*ip
, uint8_t flags
,
1182 uint32_t seq
, uint16_t cmd
)
1184 char buf
[ETHER_ADDR_STRLEN
];
1185 char buf2
[INET6_ADDRSTRLEN
];
1187 struct zserv
*client
= NULL
;
1188 struct stream
*s
= NULL
;
1190 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
1191 /* BGP may not be running. */
1195 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
1197 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1198 stream_putl(s
, vni
);
1199 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1202 if (IS_IPADDR_V4(ip
))
1203 ipa_len
= IPV4_MAX_BYTELEN
;
1204 else if (IS_IPADDR_V6(ip
))
1205 ipa_len
= IPV6_MAX_BYTELEN
;
1207 stream_putl(s
, ipa_len
); /* IP address length */
1209 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1211 stream_putl(s
, 0); /* Just MAC. */
1213 if (cmd
== ZEBRA_MACIP_ADD
) {
1214 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1215 stream_putl(s
, seq
); /* sequence number */
1219 /* Write packet size. */
1220 stream_putw_at(s
, 0, stream_get_endp(s
));
1222 if (IS_ZEBRA_DEBUG_VXLAN
)
1224 "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s",
1225 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del", flags
,
1226 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1227 ipaddr2str(ip
, buf2
, sizeof(buf2
)), seq
, vni
,
1228 zebra_route_string(client
->proto
));
1230 if (cmd
== ZEBRA_MACIP_ADD
)
1231 client
->macipadd_cnt
++;
1233 client
->macipdel_cnt
++;
1235 return zserv_send_message(client
, s
);
1239 * Make hash key for neighbors.
1241 static unsigned int neigh_hash_keymake(void *p
)
1243 zebra_neigh_t
*n
= p
;
1244 struct ipaddr
*ip
= &n
->ip
;
1246 if (IS_IPADDR_V4(ip
))
1247 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1249 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1250 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1254 * Compare two neighbor hash structures.
1256 static int neigh_cmp(const void *p1
, const void *p2
)
1258 const zebra_neigh_t
*n1
= p1
;
1259 const zebra_neigh_t
*n2
= p2
;
1261 if (n1
== NULL
&& n2
== NULL
)
1264 if (n1
== NULL
|| n2
== NULL
)
1267 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1271 * Callback to allocate neighbor hash entry.
1273 static void *zvni_neigh_alloc(void *p
)
1275 const zebra_neigh_t
*tmp_n
= p
;
1278 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1285 * Add neighbor entry.
1287 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1288 struct ethaddr
*mac
)
1290 zebra_neigh_t tmp_n
;
1291 zebra_neigh_t
*n
= NULL
;
1292 zebra_mac_t
*zmac
= NULL
;
1294 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1295 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1296 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1299 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1300 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1302 /* Associate the neigh to mac */
1303 zmac
= zvni_mac_lookup(zvni
, mac
);
1305 listnode_add_sort(zmac
->neigh_list
, n
);
1311 * Delete neighbor entry.
1313 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1315 zebra_neigh_t
*tmp_n
;
1316 zebra_mac_t
*zmac
= NULL
;
1318 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1320 listnode_delete(zmac
->neigh_list
, n
);
1322 /* Free the VNI hash entry and allocated memory. */
1323 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1325 XFREE(MTYPE_NEIGH
, tmp_n
);
1331 * Free neighbor hash entry (callback)
1333 static void zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1335 struct neigh_walk_ctx
*wctx
= arg
;
1336 zebra_neigh_t
*n
= backet
->data
;
1338 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1339 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1340 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1341 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1342 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1343 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1344 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1345 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1348 if (wctx
->uninstall
)
1349 zvni_neigh_uninstall(wctx
->zvni
, n
);
1351 zvni_neigh_del(wctx
->zvni
, n
);
1358 * Delete all neighbor entries from specific VTEP for a particular VNI.
1360 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1361 struct in_addr
*r_vtep_ip
)
1363 struct neigh_walk_ctx wctx
;
1365 if (!zvni
->neigh_table
)
1368 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1370 wctx
.uninstall
= uninstall
;
1371 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1372 wctx
.r_vtep_ip
= *r_vtep_ip
;
1374 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1378 * Delete all neighbor entries for this VNI.
1380 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
1383 struct neigh_walk_ctx wctx
;
1385 if (!zvni
->neigh_table
)
1388 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1390 wctx
.uninstall
= uninstall
;
1391 wctx
.upd_client
= upd_client
;
1394 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1398 * Look up neighbor hash entry.
1400 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1405 memset(&tmp
, 0, sizeof(tmp
));
1406 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1407 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1413 * Process all neighbors associated with a MAC upon the MAC being learnt
1414 * locally or undergoing any other change (such as sequence number).
1416 static void zvni_process_neigh_on_local_mac_change(zebra_vni_t
*zvni
,
1420 zebra_neigh_t
*n
= NULL
;
1421 struct listnode
*node
= NULL
;
1422 char buf
[ETHER_ADDR_STRLEN
];
1424 if (IS_ZEBRA_DEBUG_VXLAN
)
1425 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
1426 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1427 seq_change
? "CHANGE" : "ADD", zvni
->vni
);
1429 /* Walk all neighbors and mark any inactive local neighbors as
1430 * active and/or update sequence number upon a move, and inform BGP.
1431 * The action for remote neighbors is TBD.
1432 * NOTE: We can't simply uninstall remote neighbors as the kernel may
1433 * accidentally end up deleting a just-learnt local neighbor.
1435 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1436 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1437 if (IS_ZEBRA_NEIGH_INACTIVE(n
) || seq_change
) {
1438 ZEBRA_NEIGH_SET_ACTIVE(n
);
1439 n
->loc_seq
= zmac
->loc_seq
;
1440 zvni_neigh_send_add_to_client(
1441 zvni
->vni
, &n
->ip
, &n
->emac
,
1442 n
->flags
, n
->loc_seq
);
1449 * Process all neighbors associated with a local MAC upon the MAC being
1452 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1455 zebra_neigh_t
*n
= NULL
;
1456 struct listnode
*node
= NULL
;
1457 char buf
[ETHER_ADDR_STRLEN
];
1459 if (IS_ZEBRA_DEBUG_VXLAN
)
1460 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
1461 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1464 /* Walk all local neighbors and mark as inactive and inform
1466 * TBD: There is currently no handling for remote neighbors. We
1467 * don't expect them to exist, if they do, do we install the MAC
1468 * as a remote MAC and the neighbor as remote?
1470 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1471 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1472 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1473 ZEBRA_NEIGH_SET_INACTIVE(n
);
1475 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1483 * Process all neighbors associated with a MAC upon the MAC being remotely
1486 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1489 zebra_neigh_t
*n
= NULL
;
1490 struct listnode
*node
= NULL
;
1491 char buf
[ETHER_ADDR_STRLEN
];
1493 if (IS_ZEBRA_DEBUG_VXLAN
)
1494 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
1495 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1498 /* Walk all local neighbors and mark as inactive and inform
1501 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1502 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1503 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1504 ZEBRA_NEIGH_SET_INACTIVE(n
);
1506 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1514 * Process all neighbors associated with a remote MAC upon the MAC being
1517 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1520 /* NOTE: Currently a NO-OP. */
1524 * Inform BGP about local neighbor addition.
1526 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
1527 struct ethaddr
*macaddr
,
1528 uint8_t neigh_flags
,
1533 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1534 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1535 /* Set router flag (R-bit) based on local neigh entry add */
1536 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_ROUTER_FLAG
))
1537 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
1539 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1540 seq
, ZEBRA_MACIP_ADD
);
1544 * Inform BGP about local neighbor deletion.
1546 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
1547 struct ethaddr
*macaddr
, uint8_t flags
)
1549 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1550 0, ZEBRA_MACIP_DEL
);
1554 * Install remote neighbor into the kernel.
1556 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1558 struct zebra_if
*zif
;
1559 struct zebra_l2info_vxlan
*vxl
;
1560 struct interface
*vlan_if
;
1566 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1569 zif
= zvni
->vxlan_if
->info
;
1572 vxl
= &zif
->l2info
.vxl
;
1574 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1578 flags
= NTF_EXT_LEARNED
;
1579 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
1580 flags
|= NTF_ROUTER
;
1581 ZEBRA_NEIGH_SET_ACTIVE(n
);
1582 ret
= kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
, flags
);
1588 * Uninstall remote neighbor from the kernel.
1590 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1592 struct zebra_if
*zif
;
1593 struct zebra_l2info_vxlan
*vxl
;
1594 struct interface
*vlan_if
;
1596 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1599 if (!zvni
->vxlan_if
) {
1600 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
1605 zif
= zvni
->vxlan_if
->info
;
1608 vxl
= &zif
->l2info
.vxl
;
1609 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1613 ZEBRA_NEIGH_SET_INACTIVE(n
);
1615 return kernel_del_neigh(vlan_if
, &n
->ip
);
1619 * Install neighbor hash entry - called upon access VLAN change.
1621 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1624 struct neigh_walk_ctx
*wctx
= ctxt
;
1626 n
= (zebra_neigh_t
*)backet
->data
;
1628 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1629 zvni_neigh_install(wctx
->zvni
, n
);
1632 /* Get the VRR interface for SVI if any */
1633 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1635 struct zebra_vrf
*zvrf
= NULL
;
1636 struct interface
*tmp_if
= NULL
;
1637 struct zebra_if
*zif
= NULL
;
1639 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1642 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1647 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1650 if (zif
->link
== ifp
)
1657 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1659 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1660 struct connected
*c
= NULL
;
1661 struct ethaddr macaddr
;
1663 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1665 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1668 memset(&ip
, 0, sizeof(struct ipaddr
));
1669 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1672 if (c
->address
->family
== AF_INET
) {
1673 ip
.ipa_type
= IPADDR_V4
;
1674 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1675 sizeof(struct in_addr
));
1676 } else if (c
->address
->family
== AF_INET6
) {
1677 ip
.ipa_type
= IPADDR_V6
;
1678 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1679 sizeof(struct in6_addr
));
1684 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1690 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1692 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1693 struct connected
*c
= NULL
;
1694 struct ethaddr macaddr
;
1696 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1698 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1701 memset(&ip
, 0, sizeof(struct ipaddr
));
1702 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1705 if (c
->address
->family
== AF_INET
) {
1706 ip
.ipa_type
= IPADDR_V4
;
1707 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1708 sizeof(struct in_addr
));
1709 } else if (c
->address
->family
== AF_INET6
) {
1710 ip
.ipa_type
= IPADDR_V6
;
1711 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1712 sizeof(struct in6_addr
));
1717 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1723 static int zvni_advertise_subnet(zebra_vni_t
*zvni
, struct interface
*ifp
,
1726 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1727 struct connected
*c
= NULL
;
1728 struct ethaddr macaddr
;
1730 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1732 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1735 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1737 /* skip link local address */
1738 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1743 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1744 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1746 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1747 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1753 * zvni_gw_macip_add_to_client
1755 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1756 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1758 char buf
[ETHER_ADDR_STRLEN
];
1759 char buf2
[INET6_ADDRSTRLEN
];
1760 zebra_neigh_t
*n
= NULL
;
1761 zebra_mac_t
*mac
= NULL
;
1762 struct zebra_if
*zif
= NULL
;
1763 struct zebra_l2info_vxlan
*vxl
= NULL
;
1765 zif
= zvni
->vxlan_if
->info
;
1769 vxl
= &zif
->l2info
.vxl
;
1771 mac
= zvni_mac_lookup(zvni
, macaddr
);
1773 mac
= zvni_mac_add(zvni
, macaddr
);
1775 flog_err(ZEBRA_ERR_MAC_ADD_FAILED
,
1776 "Failed to add MAC %s intf %s(%u) VID %u",
1777 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1778 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1783 /* Set "local" forwarding info. */
1784 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1785 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1786 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1787 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1788 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1789 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1791 n
= zvni_neigh_lookup(zvni
, ip
);
1793 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1796 ZEBRA_ERR_MAC_ADD_FAILED
,
1797 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1798 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1799 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1800 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1805 /* Set "local" forwarding info. */
1806 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1807 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1808 ZEBRA_NEIGH_SET_ACTIVE(n
);
1809 /* Set Router flag (R-bit) */
1810 if (ip
->ipa_type
== IPADDR_V6
)
1811 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
1812 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1813 n
->ifindex
= ifp
->ifindex
;
1815 /* Only advertise in BGP if the knob is enabled */
1816 if (!advertise_gw_macip_enabled(zvni
))
1819 if (IS_ZEBRA_DEBUG_VXLAN
)
1821 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
1822 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1823 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1824 ipaddr2str(ip
, buf2
, sizeof(buf2
)), n
->flags
);
1826 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1827 n
->flags
, n
->loc_seq
);
1833 * zvni_gw_macip_del_from_client
1835 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1838 char buf1
[ETHER_ADDR_STRLEN
];
1839 char buf2
[INET6_ADDRSTRLEN
];
1840 zebra_neigh_t
*n
= NULL
;
1841 zebra_mac_t
*mac
= NULL
;
1843 /* If the neigh entry is not present nothing to do*/
1844 n
= zvni_neigh_lookup(zvni
, ip
);
1848 /* mac entry should be present */
1849 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1851 zlog_debug("MAC %s doesnt exists for neigh %s on VNI %u",
1852 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1853 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1857 /* If the entry is not local nothing to do*/
1858 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1861 /* only need to delete the entry from bgp if we sent it before */
1862 if (IS_ZEBRA_DEBUG_VXLAN
)
1864 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1865 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1866 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1867 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1869 /* Remove neighbor from BGP. */
1870 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1871 ZEBRA_MACIP_TYPE_GW
);
1873 /* Delete this neighbor entry. */
1874 zvni_neigh_del(zvni
, n
);
1876 /* see if the mac needs to be deleted as well*/
1878 zvni_deref_ip2mac(zvni
, mac
, 0);
1883 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1886 zebra_vni_t
*zvni
= NULL
;
1887 struct zebra_if
*zif
= NULL
;
1888 struct zebra_l2info_vxlan zl2_info
;
1889 struct interface
*vlan_if
= NULL
;
1890 struct interface
*vrr_if
= NULL
;
1891 struct interface
*ifp
;
1893 /* Add primary SVI MAC*/
1894 zvni
= (zebra_vni_t
*)backet
->data
;
1896 ifp
= zvni
->vxlan_if
;
1901 /* If down or not mapped to a bridge, we're done. */
1902 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1905 zl2_info
= zif
->l2info
.vxl
;
1908 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1912 /* Del primary MAC-IP */
1913 zvni_del_macip_for_intf(vlan_if
, zvni
);
1915 /* Del VRR MAC-IP - if any*/
1916 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1918 zvni_del_macip_for_intf(vrr_if
, zvni
);
1923 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1926 zebra_vni_t
*zvni
= NULL
;
1927 struct zebra_if
*zif
= NULL
;
1928 struct zebra_l2info_vxlan zl2_info
;
1929 struct interface
*vlan_if
= NULL
;
1930 struct interface
*vrr_if
= NULL
;
1931 struct interface
*ifp
= NULL
;
1933 zvni
= (zebra_vni_t
*)backet
->data
;
1935 ifp
= zvni
->vxlan_if
;
1940 /* If down or not mapped to a bridge, we're done. */
1941 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1943 zl2_info
= zif
->l2info
.vxl
;
1946 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1950 /* Add primary SVI MAC-IP */
1951 zvni_add_macip_for_intf(vlan_if
, zvni
);
1953 /* Add VRR MAC-IP - if any*/
1954 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1956 zvni_add_macip_for_intf(vrr_if
, zvni
);
1961 static int zvni_local_neigh_update(zebra_vni_t
*zvni
,
1962 struct interface
*ifp
,
1964 struct ethaddr
*macaddr
,
1965 uint8_t router_flag
)
1967 char buf
[ETHER_ADDR_STRLEN
];
1968 char buf2
[INET6_ADDRSTRLEN
];
1969 zebra_neigh_t
*n
= NULL
;
1970 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
1971 uint32_t old_mac_seq
= 0, mac_new_seq
= 0;
1972 bool upd_mac_seq
= false;
1973 bool neigh_mac_change
= false;
1974 bool check_rbit
= false;
1976 /* Check if the MAC exists. */
1977 zmac
= zvni_mac_lookup(zvni
, macaddr
);
1979 /* create a dummy MAC if the MAC is not already present */
1980 if (IS_ZEBRA_DEBUG_VXLAN
)
1982 "AUTO MAC %s created for neigh %s on VNI %u",
1983 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1984 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1986 zmac
= zvni_mac_add(zvni
, macaddr
);
1988 zlog_debug("Failed to add MAC %s VNI %u",
1989 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1994 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
1995 memset(&zmac
->flags
, 0, sizeof(uint32_t));
1996 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
1998 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2000 * We don't change the MAC to local upon a neighbor
2001 * learn event, we wait for the explicit local MAC
2002 * learn. However, we have to compute its sequence
2003 * number in preparation for when it actually turns
2010 /* Check if the neighbor exists. */
2011 n
= zvni_neigh_lookup(zvni
, ip
);
2013 /* New neighbor - create */
2014 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2017 ZEBRA_ERR_MAC_ADD_FAILED
,
2018 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2019 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2020 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2021 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2024 /* Set "local" forwarding info. */
2025 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2026 n
->ifindex
= ifp
->ifindex
;
2029 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2030 /* If there is no MAC change, BGP isn't interested. */
2032 (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)
2036 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2038 /* Update any params and return - client doesn't
2039 * care about a purely local change.
2041 n
->ifindex
= ifp
->ifindex
;
2044 /* If the MAC has changed, need to issue a
2045 * delete first as this means a different
2046 * MACIP route. Also, need to do some
2047 * unlinking/relinking. We also need to
2048 * update the MAC's sequence number
2049 * in different situations.
2051 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2052 zvni_neigh_send_del_to_client(
2053 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
2054 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2057 CHECK_FLAG(old_zmac
->flags
,
2061 neigh_mac_change
= upd_mac_seq
= true;
2063 old_zmac
->neigh_list
, n
);
2064 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2067 /* Update the forwarding info. */
2068 n
->ifindex
= ifp
->ifindex
;
2069 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2071 /* Link to new MAC */
2072 listnode_add_sort(zmac
->neigh_list
, n
);
2075 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2077 * Neighbor has moved from remote to local. Its
2078 * MAC could have also changed as part of the move.
2080 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2082 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2084 old_mac_seq
= CHECK_FLAG(
2089 neigh_mac_change
= upd_mac_seq
= true;
2090 listnode_delete(old_zmac
->neigh_list
,
2092 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2095 /* Link to new MAC */
2096 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2097 listnode_add_sort(zmac
->neigh_list
, n
);
2100 /* Mark appropriately */
2101 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2102 n
->r_vtep_ip
.s_addr
= 0;
2103 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2104 n
->ifindex
= ifp
->ifindex
;
2109 /* If MAC was previously remote, or the neighbor had a different
2110 * MAC earlier, recompute the sequence number.
2113 uint32_t seq1
, seq2
;
2115 seq1
= CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
) ?
2116 zmac
->rem_seq
+ 1 : zmac
->loc_seq
;
2117 seq2
= neigh_mac_change
? old_mac_seq
+ 1 : 0;
2118 mac_new_seq
= zmac
->loc_seq
< MAX(seq1
, seq2
) ?
2119 MAX(seq1
, seq2
) : zmac
->loc_seq
;
2122 /*Mark Router flag (R-bit) */
2124 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2126 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2128 /* Before we program this in BGP, we need to check if MAC is locally
2129 * learnt. If not, force neighbor to be inactive and reset its seq.
2131 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
2132 ZEBRA_NEIGH_SET_INACTIVE(n
);
2134 zmac
->loc_seq
= mac_new_seq
;
2141 /* If the MAC's sequence number has changed, inform the MAC and all
2142 * neighbors associated with the MAC to BGP, else just inform this
2145 if (upd_mac_seq
&& zmac
->loc_seq
!= mac_new_seq
) {
2146 if (IS_ZEBRA_DEBUG_VXLAN
)
2147 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
2148 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2149 zvni
->vni
, zmac
->loc_seq
, mac_new_seq
);
2150 zmac
->loc_seq
= mac_new_seq
;
2151 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
2152 zmac
->flags
, zmac
->loc_seq
))
2154 zvni_process_neigh_on_local_mac_change(zvni
, zmac
, 1);
2158 ZEBRA_NEIGH_SET_ACTIVE(n
);
2159 n
->loc_seq
= zmac
->loc_seq
;
2161 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
2162 n
->flags
, n
->loc_seq
);
2165 static int zvni_remote_neigh_update(zebra_vni_t
*zvni
,
2166 struct interface
*ifp
,
2168 struct ethaddr
*macaddr
,
2171 char buf
[ETHER_ADDR_STRLEN
];
2172 char buf2
[INET6_ADDRSTRLEN
];
2173 zebra_neigh_t
*n
= NULL
;
2174 zebra_mac_t
*zmac
= NULL
;
2176 /* If the neighbor is unknown, there is no further action. */
2177 n
= zvni_neigh_lookup(zvni
, ip
);
2181 /* If a remote entry, see if it needs to be refreshed */
2182 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2184 if (state
& NUD_STALE
)
2185 zvni_neigh_install(zvni
, n
);
2188 /* We got a "remote" neighbor notification for an entry
2189 * we think is local. This can happen in a multihoming
2190 * scenario - but only if the MAC is already "remote".
2191 * Just mark our entry as "remote".
2193 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2194 if (!zmac
|| !CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2196 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
2197 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
2198 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2203 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2204 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2205 n
->r_vtep_ip
= zmac
->fwd_info
.r_vtep_ip
;
2212 * Make hash key for MAC.
2214 static unsigned int mac_hash_keymake(void *p
)
2216 zebra_mac_t
*pmac
= p
;
2217 const void *pnt
= (void *)pmac
->macaddr
.octet
;
2219 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
2223 * Compare two MAC addresses.
2225 static int mac_cmp(const void *p1
, const void *p2
)
2227 const zebra_mac_t
*pmac1
= p1
;
2228 const zebra_mac_t
*pmac2
= p2
;
2230 if (pmac1
== NULL
&& pmac2
== NULL
)
2233 if (pmac1
== NULL
|| pmac2
== NULL
)
2236 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
, ETH_ALEN
)
2241 * Callback to allocate MAC hash entry.
2243 static void *zvni_mac_alloc(void *p
)
2245 const zebra_mac_t
*tmp_mac
= p
;
2248 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2251 return ((void *)mac
);
2257 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
2259 zebra_mac_t tmp_mac
;
2260 zebra_mac_t
*mac
= NULL
;
2262 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
2263 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
2264 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
2267 mac
->neigh_list
= list_new();
2268 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
2276 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2278 zebra_mac_t
*tmp_mac
;
2280 list_delete_and_null(&mac
->neigh_list
);
2282 /* Free the VNI hash entry and allocated memory. */
2283 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2285 XFREE(MTYPE_MAC
, tmp_mac
);
2291 * Free MAC hash entry (callback)
2293 static void zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2295 struct mac_walk_ctx
*wctx
= arg
;
2296 zebra_mac_t
*mac
= backet
->data
;
2298 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2299 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2300 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2301 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2302 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2303 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2304 &wctx
->r_vtep_ip
))) {
2305 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2306 zvni_mac_send_del_to_client(wctx
->zvni
->vni
,
2307 &mac
->macaddr
, mac
->flags
);
2310 if (wctx
->uninstall
)
2311 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2313 zvni_mac_del(wctx
->zvni
, mac
);
2320 * Delete all MAC entries from specific VTEP for a particular VNI.
2322 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2323 struct in_addr
*r_vtep_ip
)
2325 struct mac_walk_ctx wctx
;
2327 if (!zvni
->mac_table
)
2330 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2332 wctx
.uninstall
= uninstall
;
2333 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2334 wctx
.r_vtep_ip
= *r_vtep_ip
;
2336 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2340 * Delete all MAC entries for this VNI.
2342 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
2345 struct mac_walk_ctx wctx
;
2347 if (!zvni
->mac_table
)
2350 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2352 wctx
.uninstall
= uninstall
;
2353 wctx
.upd_client
= upd_client
;
2356 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2360 * Look up MAC hash entry.
2362 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2367 memset(&tmp
, 0, sizeof(tmp
));
2368 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2369 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2375 * Inform BGP about local MAC addition.
2377 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2378 uint8_t mac_flags
, uint32_t seq
)
2382 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2383 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2384 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2385 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2387 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2388 seq
, ZEBRA_MACIP_ADD
);
2392 * Inform BGP about local MAC deletion.
2394 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2399 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2400 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2401 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2402 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2404 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2405 0, ZEBRA_MACIP_DEL
);
2409 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2410 * notifications, to see if they are of interest.
2412 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2413 struct interface
*br_if
, vlanid_t vid
)
2415 struct zebra_ns
*zns
;
2416 struct route_node
*rn
;
2417 struct interface
*tmp_if
= NULL
;
2418 struct zebra_if
*zif
;
2419 struct zebra_l2info_bridge
*br
;
2420 struct zebra_l2info_vxlan
*vxl
= NULL
;
2421 uint8_t bridge_vlan_aware
;
2425 /* Determine if bridge is VLAN-aware or not */
2428 br
= &zif
->l2info
.br
;
2429 bridge_vlan_aware
= br
->vlan_aware
;
2431 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2432 /* TODO: Optimize with a hash. */
2433 zns
= zebra_ns_lookup(NS_DEFAULT
);
2434 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2435 tmp_if
= (struct interface
*)rn
->info
;
2439 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2441 if (!if_is_operative(tmp_if
))
2443 vxl
= &zif
->l2info
.vxl
;
2445 if (zif
->brslave_info
.br_if
!= br_if
)
2448 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2457 zvni
= zvni_lookup(vxl
->vni
);
2462 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2463 * neighbor notifications, to see if they are of interest.
2465 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2466 struct interface
*br_if
)
2468 struct zebra_ns
*zns
;
2469 struct route_node
*rn
;
2470 struct interface
*tmp_if
= NULL
;
2471 struct zebra_if
*zif
;
2472 struct zebra_l2info_bridge
*br
;
2473 struct zebra_l2info_vxlan
*vxl
= NULL
;
2474 uint8_t bridge_vlan_aware
;
2482 /* Make sure the linked interface is a bridge. */
2483 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2486 /* Determine if bridge is VLAN-aware or not */
2489 br
= &zif
->l2info
.br
;
2490 bridge_vlan_aware
= br
->vlan_aware
;
2491 if (bridge_vlan_aware
) {
2492 struct zebra_l2info_vlan
*vl
;
2494 if (!IS_ZEBRA_IF_VLAN(ifp
))
2499 vl
= &zif
->l2info
.vl
;
2503 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2504 /* TODO: Optimize with a hash. */
2505 zns
= zebra_ns_lookup(NS_DEFAULT
);
2506 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2507 tmp_if
= (struct interface
*)rn
->info
;
2511 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2513 if (!if_is_operative(tmp_if
))
2515 vxl
= &zif
->l2info
.vxl
;
2517 if (zif
->brslave_info
.br_if
!= br_if
)
2520 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2529 zvni
= zvni_lookup(vxl
->vni
);
2533 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2535 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2536 * linked to the bridge
2537 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2540 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2542 struct zebra_ns
*zns
;
2543 struct route_node
*rn
;
2544 struct interface
*tmp_if
= NULL
;
2545 struct zebra_if
*zif
;
2546 struct zebra_l2info_bridge
*br
;
2547 struct zebra_l2info_vlan
*vl
;
2548 uint8_t bridge_vlan_aware
;
2551 /* Defensive check, caller expected to invoke only with valid bridge. */
2555 /* Determine if bridge is VLAN-aware or not */
2558 br
= &zif
->l2info
.br
;
2559 bridge_vlan_aware
= br
->vlan_aware
;
2561 /* Check oper status of the SVI. */
2562 if (!bridge_vlan_aware
)
2563 return if_is_operative(br_if
) ? br_if
: NULL
;
2565 /* Identify corresponding VLAN interface. */
2566 /* TODO: Optimize with a hash. */
2567 zns
= zebra_ns_lookup(NS_DEFAULT
);
2568 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2569 tmp_if
= (struct interface
*)rn
->info
;
2570 /* Check oper status of the SVI. */
2571 if (!tmp_if
|| !if_is_operative(tmp_if
))
2574 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2575 || zif
->link
!= br_if
)
2577 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2579 if (vl
->vid
== vid
) {
2585 return found
? tmp_if
: NULL
;
2589 * Install remote MAC into the kernel.
2591 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2593 struct zebra_if
*zif
;
2594 struct zebra_l2info_vxlan
*vxl
;
2597 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2600 zif
= zvni
->vxlan_if
->info
;
2603 vxl
= &zif
->l2info
.vxl
;
2605 sticky
= CHECK_FLAG(mac
->flags
,
2606 (ZEBRA_MAC_STICKY
| ZEBRA_MAC_REMOTE_DEF_GW
)) ? 1 : 0;
2608 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2609 mac
->fwd_info
.r_vtep_ip
, sticky
);
2613 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2614 * moves to remote, we have to uninstall any existing local entry first.
2616 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2618 struct zebra_if
*zif
;
2619 struct zebra_l2info_vxlan
*vxl
;
2620 struct in_addr vtep_ip
= {.s_addr
= 0};
2621 struct zebra_ns
*zns
;
2622 struct interface
*ifp
;
2624 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2627 if (!zvni
->vxlan_if
) {
2628 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2633 zif
= zvni
->vxlan_if
->info
;
2636 vxl
= &zif
->l2info
.vxl
;
2639 zns
= zebra_ns_lookup(NS_DEFAULT
);
2640 ifp
= if_lookup_by_index_per_ns(zns
,
2641 mac
->fwd_info
.local
.ifindex
);
2642 if (!ifp
) // unexpected
2645 ifp
= zvni
->vxlan_if
;
2646 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2649 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2654 * Install MAC hash entry - called upon access VLAN change.
2656 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2659 struct mac_walk_ctx
*wctx
= ctxt
;
2661 mac
= (zebra_mac_t
*)backet
->data
;
2663 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2664 zvni_mac_install(wctx
->zvni
, mac
);
2668 * Decrement neighbor refcount of MAC; uninstall and free it if
2671 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2674 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2675 || !list_isempty(mac
->neigh_list
))
2679 zvni_mac_uninstall(zvni
, mac
, 0);
2681 zvni_mac_del(zvni
, mac
);
2685 * Read and populate local MACs and neighbors corresponding to this VNI.
2687 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
, struct interface
*ifp
)
2689 struct zebra_ns
*zns
;
2690 struct zebra_if
*zif
;
2691 struct interface
*vlan_if
;
2692 struct zebra_l2info_vxlan
*vxl
;
2693 struct interface
*vrr_if
;
2696 vxl
= &zif
->l2info
.vxl
;
2697 zns
= zebra_ns_lookup(NS_DEFAULT
);
2699 if (IS_ZEBRA_DEBUG_VXLAN
)
2701 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2702 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2703 zif
->brslave_info
.bridge_ifindex
);
2705 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2706 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2709 /* Add SVI MAC-IP */
2710 zvni_add_macip_for_intf(vlan_if
, zvni
);
2712 /* Add VRR MAC-IP - if any*/
2713 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2715 zvni_add_macip_for_intf(vrr_if
, zvni
);
2717 neigh_read_for_vlan(zns
, vlan_if
);
2722 * Hash function for VNI.
2724 static unsigned int vni_hash_keymake(void *p
)
2726 const zebra_vni_t
*zvni
= p
;
2728 return (jhash_1word(zvni
->vni
, 0));
2732 * Compare 2 VNI hash entries.
2734 static int vni_hash_cmp(const void *p1
, const void *p2
)
2736 const zebra_vni_t
*zvni1
= p1
;
2737 const zebra_vni_t
*zvni2
= p2
;
2739 return (zvni1
->vni
== zvni2
->vni
);
2743 * Callback to allocate VNI hash entry.
2745 static void *zvni_alloc(void *p
)
2747 const zebra_vni_t
*tmp_vni
= p
;
2750 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2751 zvni
->vni
= tmp_vni
->vni
;
2752 return ((void *)zvni
);
2756 * Look up VNI hash entry.
2758 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2760 struct zebra_vrf
*zvrf
;
2761 zebra_vni_t tmp_vni
;
2762 zebra_vni_t
*zvni
= NULL
;
2764 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2766 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2768 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2774 * Add VNI hash entry.
2776 static zebra_vni_t
*zvni_add(vni_t vni
)
2778 struct zebra_vrf
*zvrf
;
2779 zebra_vni_t tmp_zvni
;
2780 zebra_vni_t
*zvni
= NULL
;
2782 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2784 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2786 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2789 /* Create hash table for MAC */
2791 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2793 /* Create hash table for neighbors */
2794 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2795 "Zebra VNI Neighbor Table");
2801 * Delete VNI hash entry.
2803 static int zvni_del(zebra_vni_t
*zvni
)
2805 struct zebra_vrf
*zvrf
;
2806 zebra_vni_t
*tmp_zvni
;
2808 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2811 zvni
->vxlan_if
= NULL
;
2813 /* Free the neighbor hash table. */
2814 hash_free(zvni
->neigh_table
);
2815 zvni
->neigh_table
= NULL
;
2817 /* Free the MAC hash table. */
2818 hash_free(zvni
->mac_table
);
2819 zvni
->mac_table
= NULL
;
2821 /* Free the VNI hash entry and allocated memory. */
2822 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2824 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2830 * Inform BGP about local VNI addition.
2832 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2834 struct zserv
*client
;
2837 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2838 /* BGP may not be running. */
2842 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2844 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2845 stream_putl(s
, zvni
->vni
);
2846 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2847 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2849 /* Write packet size. */
2850 stream_putw_at(s
, 0, stream_get_endp(s
));
2852 if (IS_ZEBRA_DEBUG_VXLAN
)
2853 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni
->vni
,
2854 inet_ntoa(zvni
->local_vtep_ip
),
2855 vrf_id_to_name(zvni
->vrf_id
),
2856 zebra_route_string(client
->proto
));
2858 client
->vniadd_cnt
++;
2859 return zserv_send_message(client
, s
);
2863 * Inform BGP about local VNI deletion.
2865 static int zvni_send_del_to_client(vni_t vni
)
2867 struct zserv
*client
;
2870 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2871 /* BGP may not be running. */
2875 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2878 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2879 stream_putl(s
, vni
);
2881 /* Write packet size. */
2882 stream_putw_at(s
, 0, stream_get_endp(s
));
2884 if (IS_ZEBRA_DEBUG_VXLAN
)
2885 zlog_debug("Send VNI_DEL %u to %s", vni
,
2886 zebra_route_string(client
->proto
));
2888 client
->vnidel_cnt
++;
2889 return zserv_send_message(client
, s
);
2893 * Build the VNI hash table by going over the VxLAN interfaces. This
2894 * is called when EVPN (advertise-all-vni) is enabled.
2896 static void zvni_build_hash_table()
2898 struct zebra_ns
*zns
;
2899 struct route_node
*rn
;
2900 struct interface
*ifp
;
2902 /* Walk VxLAN interfaces and create VNI hash. */
2903 zns
= zebra_ns_lookup(NS_DEFAULT
);
2904 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2906 zebra_vni_t
*zvni
= NULL
;
2907 zebra_l3vni_t
*zl3vni
= NULL
;
2908 struct zebra_if
*zif
;
2909 struct zebra_l2info_vxlan
*vxl
;
2911 ifp
= (struct interface
*)rn
->info
;
2915 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2918 vxl
= &zif
->l2info
.vxl
;
2921 /* L3-VNI and L2-VNI are handled seperately */
2922 zl3vni
= zl3vni_lookup(vni
);
2925 if (IS_ZEBRA_DEBUG_VXLAN
)
2927 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2928 ifp
->name
, ifp
->ifindex
, vni
);
2930 /* associate with vxlan_if */
2931 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2932 zl3vni
->vxlan_if
= ifp
;
2935 * we need to associate with SVI.
2936 * we can associate with svi-if only after association
2937 * with vxlan-intf is complete
2939 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2941 if (is_l3vni_oper_up(zl3vni
))
2942 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2945 struct interface
*vlan_if
= NULL
;
2947 if (IS_ZEBRA_DEBUG_VXLAN
)
2949 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2950 ifp
->name
, ifp
->ifindex
, vni
,
2951 inet_ntoa(vxl
->vtep_ip
));
2953 /* VNI hash entry is not expected to exist. */
2954 zvni
= zvni_lookup(vni
);
2957 "VNI hash already present for IF %s(%u) L2-VNI %u",
2958 ifp
->name
, ifp
->ifindex
, vni
);
2962 zvni
= zvni_add(vni
);
2965 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2966 ifp
->name
, ifp
->ifindex
, vni
);
2970 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2971 zvni
->vxlan_if
= ifp
;
2972 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2973 zif
->brslave_info
.br_if
);
2975 zvni
->vrf_id
= vlan_if
->vrf_id
;
2976 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2978 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2982 /* Inform BGP if intf is up and mapped to bridge. */
2983 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2984 zvni_send_add_to_client(zvni
);
2990 * See if remote VTEP matches with prefix.
2992 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2994 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2998 * Locate remote VTEP in VNI hash table.
3000 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3002 zebra_vtep_t
*zvtep
;
3007 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
3008 if (zvni_vtep_match(vtep_ip
, zvtep
))
3016 * Add remote VTEP to VNI hash table.
3018 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3020 zebra_vtep_t
*zvtep
;
3022 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
3024 zvtep
->vtep_ip
= *vtep_ip
;
3027 zvni
->vteps
->prev
= zvtep
;
3028 zvtep
->next
= zvni
->vteps
;
3029 zvni
->vteps
= zvtep
;
3035 * Remove remote VTEP from VNI hash table.
3037 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
3040 zvtep
->next
->prev
= zvtep
->prev
;
3042 zvtep
->prev
->next
= zvtep
->next
;
3044 zvni
->vteps
= zvtep
->next
;
3046 zvtep
->prev
= zvtep
->next
= NULL
;
3047 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
3053 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
3054 * uninstall from kernel if asked to.
3056 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
3058 zebra_vtep_t
*zvtep
, *zvtep_next
;
3063 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
3064 zvtep_next
= zvtep
->next
;
3066 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
3067 zvni_vtep_del(zvni
, zvtep
);
3074 * Install remote VTEP into the kernel.
3076 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3078 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3082 * Uninstall remote VTEP from the kernel.
3084 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3086 if (!zvni
->vxlan_if
) {
3087 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3092 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3096 * Cleanup VNI/VTEP and update kernel
3098 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
3100 zebra_vni_t
*zvni
= NULL
;
3101 zebra_l3vni_t
*zl3vni
= NULL
;
3102 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
3104 zvni
= (zebra_vni_t
*)backet
->data
;
3106 /* remove from l3-vni list */
3108 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
3110 listnode_delete(zl3vni
->l2vnis
, zvni
);
3112 /* Free up all neighbors and MACs, if any. */
3113 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
3114 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
3116 /* Free up all remote VTEPs, if any. */
3117 zvni_vtep_del_all(zvni
, 1);
3119 /* Delete the hash entry. */
3124 static void zl3vni_cleanup_all(struct hash_backet
*backet
, void *args
)
3126 zebra_l3vni_t
*zl3vni
= NULL
;
3128 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
3130 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
3133 static void rb_find_or_add_host(struct host_rb_tree_entry
*hrbe
,
3134 struct prefix
*host
)
3136 struct host_rb_entry lookup
;
3137 struct host_rb_entry
*hle
;
3139 memset(&lookup
, 0, sizeof(lookup
));
3140 memcpy(&lookup
.p
, host
, sizeof(*host
));
3142 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3146 hle
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct host_rb_entry
));
3147 memcpy(hle
, &lookup
, sizeof(lookup
));
3149 RB_INSERT(host_rb_tree_entry
, hrbe
, hle
);
3152 static void rb_delete_host(struct host_rb_tree_entry
*hrbe
, struct prefix
*host
)
3154 struct host_rb_entry lookup
;
3155 struct host_rb_entry
*hle
;
3157 memset(&lookup
, 0, sizeof(lookup
));
3158 memcpy(&lookup
.p
, host
, sizeof(*host
));
3160 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3162 RB_REMOVE(host_rb_tree_entry
, hrbe
, hle
);
3163 XFREE(MTYPE_HOST_PREFIX
, hle
);
3170 * Look up MAC hash entry.
3172 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
3173 struct ethaddr
*rmac
)
3178 memset(&tmp
, 0, sizeof(tmp
));
3179 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
3180 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
3186 * Callback to allocate RMAC hash entry.
3188 static void *zl3vni_rmac_alloc(void *p
)
3190 const zebra_mac_t
*tmp_rmac
= p
;
3193 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
3196 return ((void *)zrmac
);
3200 * Add RMAC entry to l3-vni
3202 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
)
3204 zebra_mac_t tmp_rmac
;
3205 zebra_mac_t
*zrmac
= NULL
;
3207 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
3208 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
3209 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
3212 RB_INIT(host_rb_tree_entry
, &zrmac
->host_rb
);
3214 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
3215 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
3223 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3225 zebra_mac_t
*tmp_rmac
;
3226 struct host_rb_entry
*hle
;
3228 while (!RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3229 hle
= RB_ROOT(host_rb_tree_entry
, &zrmac
->host_rb
);
3231 RB_REMOVE(host_rb_tree_entry
, &zrmac
->host_rb
, hle
);
3232 XFREE(MTYPE_HOST_PREFIX
, hle
);
3235 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
3237 XFREE(MTYPE_MAC
, tmp_rmac
);
3243 * Install remote RMAC into the kernel.
3245 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3247 struct zebra_if
*zif
= NULL
;
3248 struct zebra_l2info_vxlan
*vxl
= NULL
;
3250 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3251 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3254 zif
= zl3vni
->vxlan_if
->info
;
3258 vxl
= &zif
->l2info
.vxl
;
3260 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3261 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3265 * Uninstall remote RMAC from the kernel.
3267 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3269 char buf
[ETHER_ADDR_STRLEN
];
3270 struct zebra_if
*zif
= NULL
;
3271 struct zebra_l2info_vxlan
*vxl
= NULL
;
3273 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3274 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3277 if (!zl3vni
->vxlan_if
) {
3279 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3280 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3281 zl3vni
->vni
, zl3vni
);
3285 zif
= zl3vni
->vxlan_if
->info
;
3289 vxl
= &zif
->l2info
.vxl
;
3291 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3292 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3295 /* handle rmac add */
3296 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3297 struct ipaddr
*vtep_ip
,
3298 struct prefix
*host_prefix
)
3300 char buf
[ETHER_ADDR_STRLEN
];
3301 char buf1
[INET6_ADDRSTRLEN
];
3302 zebra_mac_t
*zrmac
= NULL
;
3304 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3307 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3310 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3311 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3313 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)));
3316 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3317 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3319 /* install rmac in kernel */
3320 zl3vni_rmac_install(zl3vni
, zrmac
);
3323 rb_find_or_add_host(&zrmac
->host_rb
, host_prefix
);
3329 /* handle rmac delete */
3330 static void zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
,
3331 struct prefix
*host_prefix
)
3333 rb_delete_host(&zrmac
->host_rb
, host_prefix
);
3335 if (RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3336 /* uninstall from kernel */
3337 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3339 /* del the rmac entry */
3340 zl3vni_rmac_del(zl3vni
, zrmac
);
3345 * Look up nh hash entry on a l3-vni.
3347 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3352 memset(&tmp
, 0, sizeof(tmp
));
3353 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3354 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3361 * Callback to allocate NH hash entry on L3-VNI.
3363 static void *zl3vni_nh_alloc(void *p
)
3365 const zebra_neigh_t
*tmp_n
= p
;
3368 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3375 * Add neighbor entry.
3377 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3378 struct ethaddr
*mac
)
3380 zebra_neigh_t tmp_n
;
3381 zebra_neigh_t
*n
= NULL
;
3383 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3384 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3385 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3388 RB_INIT(host_rb_tree_entry
, &n
->host_rb
);
3390 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3391 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3392 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3398 * Delete neighbor entry.
3400 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3402 zebra_neigh_t
*tmp_n
;
3403 struct host_rb_entry
*hle
;
3405 while (!RB_EMPTY(host_rb_tree_entry
, &n
->host_rb
)) {
3406 hle
= RB_ROOT(host_rb_tree_entry
, &n
->host_rb
);
3408 RB_REMOVE(host_rb_tree_entry
, &n
->host_rb
, hle
);
3409 XFREE(MTYPE_HOST_PREFIX
, hle
);
3412 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3414 XFREE(MTYPE_NEIGH
, tmp_n
);
3420 * Install remote nh as neigh into the kernel.
3422 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3429 if (!is_l3vni_oper_up(zl3vni
))
3432 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3433 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3436 flags
= NTF_EXT_LEARNED
;
3437 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
3438 flags
|= NTF_ROUTER
;
3439 ret
= kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
, flags
);
3445 * Uninstall remote nh from the kernel.
3447 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3449 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3450 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3453 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3456 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3459 /* add remote vtep as a neigh entry */
3460 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3461 struct ethaddr
*rmac
,
3462 struct prefix
*host_prefix
)
3464 char buf
[ETHER_ADDR_STRLEN
];
3465 char buf1
[INET6_ADDRSTRLEN
];
3466 zebra_neigh_t
*nh
= NULL
;
3468 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3470 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3474 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3475 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)),
3476 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3481 /* install the nh neigh in kernel */
3482 zl3vni_nh_install(zl3vni
, nh
);
3485 rb_find_or_add_host(&nh
->host_rb
, host_prefix
);
3490 /* handle nh neigh delete */
3491 static void zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*nh
,
3492 struct prefix
*host_prefix
)
3494 rb_delete_host(&nh
->host_rb
, host_prefix
);
3496 if (RB_EMPTY(host_rb_tree_entry
, &nh
->host_rb
)) {
3497 /* uninstall from kernel */
3498 zl3vni_nh_uninstall(zl3vni
, nh
);
3500 /* delete the nh entry */
3501 zl3vni_nh_del(zl3vni
, nh
);
3505 /* handle neigh update from kernel - the only thing of interest is to
3506 * readd stale entries.
3508 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3512 zebra_neigh_t
*n
= NULL
;
3514 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3518 /* all next hop neigh are remote and installed by frr.
3519 * If the kernel has aged this entry, re-install.
3521 if (state
& NUD_STALE
)
3522 zl3vni_nh_install(zl3vni
, n
);
3527 /* handle neigh delete from kernel */
3528 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3530 zebra_neigh_t
*n
= NULL
;
3532 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3536 /* all next hop neigh are remote and installed by frr.
3537 * If we get an age out notification for these neigh entries, we have to
3540 zl3vni_nh_install(zl3vni
, n
);
3546 * Hash function for L3 VNI.
3548 static unsigned int l3vni_hash_keymake(void *p
)
3550 const zebra_l3vni_t
*zl3vni
= p
;
3552 return jhash_1word(zl3vni
->vni
, 0);
3556 * Compare 2 L3 VNI hash entries.
3558 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3560 const zebra_l3vni_t
*zl3vni1
= p1
;
3561 const zebra_l3vni_t
*zl3vni2
= p2
;
3563 return (zl3vni1
->vni
== zl3vni2
->vni
);
3567 * Callback to allocate L3 VNI hash entry.
3569 static void *zl3vni_alloc(void *p
)
3571 zebra_l3vni_t
*zl3vni
= NULL
;
3572 const zebra_l3vni_t
*tmp_l3vni
= p
;
3574 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3575 zl3vni
->vni
= tmp_l3vni
->vni
;
3576 return ((void *)zl3vni
);
3580 * Look up L3 VNI hash entry.
3582 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3584 struct zebra_ns
*zns
;
3585 zebra_l3vni_t tmp_l3vni
;
3586 zebra_l3vni_t
*zl3vni
= NULL
;
3588 zns
= zebra_ns_lookup(NS_DEFAULT
);
3590 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3591 tmp_l3vni
.vni
= vni
;
3592 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3598 * Add L3 VNI hash entry.
3600 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3602 zebra_l3vni_t tmp_zl3vni
;
3603 struct zebra_ns
*zns
= NULL
;
3604 zebra_l3vni_t
*zl3vni
= NULL
;
3606 zns
= zebra_ns_lookup(NS_DEFAULT
);
3609 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3610 tmp_zl3vni
.vni
= vni
;
3612 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3615 zl3vni
->vrf_id
= vrf_id
;
3616 zl3vni
->svi_if
= NULL
;
3617 zl3vni
->vxlan_if
= NULL
;
3618 zl3vni
->l2vnis
= list_new();
3619 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3621 /* Create hash table for remote RMAC */
3622 zl3vni
->rmac_table
= hash_create(mac_hash_keymake
, mac_cmp
,
3623 "Zebra L3-VNI RMAC-Table");
3625 /* Create hash table for neighbors */
3626 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3627 "Zebra L3-VNI next-hop table");
3633 * Delete L3 VNI hash entry.
3635 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3637 struct zebra_ns
*zns
;
3638 zebra_l3vni_t
*tmp_zl3vni
;
3640 zns
= zebra_ns_lookup(NS_DEFAULT
);
3643 /* free the list of l2vnis */
3644 list_delete_and_null(&zl3vni
->l2vnis
);
3645 zl3vni
->l2vnis
= NULL
;
3647 /* Free the rmac table */
3648 hash_free(zl3vni
->rmac_table
);
3649 zl3vni
->rmac_table
= NULL
;
3651 /* Free the nh table */
3652 hash_free(zl3vni
->nh_table
);
3653 zl3vni
->nh_table
= NULL
;
3655 /* Free the VNI hash entry and allocated memory. */
3656 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3658 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3663 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3665 struct zebra_ns
*zns
= NULL
;
3666 struct route_node
*rn
= NULL
;
3667 struct interface
*ifp
= NULL
;
3669 /* loop through all vxlan-interface */
3670 zns
= zebra_ns_lookup(NS_DEFAULT
);
3671 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3673 struct zebra_if
*zif
= NULL
;
3674 struct zebra_l2info_vxlan
*vxl
= NULL
;
3676 ifp
= (struct interface
*)rn
->info
;
3681 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3684 vxl
= &zif
->l2info
.vxl
;
3685 if (vxl
->vni
== zl3vni
->vni
) {
3686 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3694 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3696 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3697 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3702 if (!zl3vni
->vxlan_if
)
3705 zif
= zl3vni
->vxlan_if
->info
;
3709 vxl
= &zif
->l2info
.vxl
;
3711 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3714 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3716 struct zebra_vrf
*zvrf
= NULL
;
3718 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3722 return zl3vni_lookup(zvrf
->l3vni
);
3726 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3727 * neighbor notifications, to see if they are of interest.
3729 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3730 struct interface
*br_if
)
3734 uint8_t bridge_vlan_aware
= 0;
3735 zebra_l3vni_t
*zl3vni
= NULL
;
3736 struct zebra_ns
*zns
= NULL
;
3737 struct route_node
*rn
= NULL
;
3738 struct zebra_if
*zif
= NULL
;
3739 struct interface
*tmp_if
= NULL
;
3740 struct zebra_l2info_bridge
*br
= NULL
;
3741 struct zebra_l2info_vxlan
*vxl
= NULL
;
3746 /* Make sure the linked interface is a bridge. */
3747 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3750 /* Determine if bridge is VLAN-aware or not */
3753 br
= &zif
->l2info
.br
;
3754 bridge_vlan_aware
= br
->vlan_aware
;
3755 if (bridge_vlan_aware
) {
3756 struct zebra_l2info_vlan
*vl
;
3758 if (!IS_ZEBRA_IF_VLAN(ifp
))
3763 vl
= &zif
->l2info
.vl
;
3767 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3768 /* TODO: Optimize with a hash. */
3769 zns
= zebra_ns_lookup(NS_DEFAULT
);
3770 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3771 tmp_if
= (struct interface
*)rn
->info
;
3775 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3777 if (!if_is_operative(tmp_if
))
3779 vxl
= &zif
->l2info
.vxl
;
3781 if (zif
->brslave_info
.br_if
!= br_if
)
3784 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3793 zl3vni
= zl3vni_lookup(vxl
->vni
);
3798 * Inform BGP about l3-vni.
3800 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3802 struct stream
*s
= NULL
;
3803 struct zserv
*client
= NULL
;
3804 struct ethaddr rmac
;
3805 char buf
[ETHER_ADDR_STRLEN
];
3807 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3808 /* BGP may not be running. */
3813 memset(&rmac
, 0, sizeof(struct ethaddr
));
3814 zl3vni_get_rmac(zl3vni
, &rmac
);
3816 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3818 zclient_create_header(s
, ZEBRA_L3VNI_ADD
, zl3vni_vrf_id(zl3vni
));
3819 stream_putl(s
, zl3vni
->vni
);
3820 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3821 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3822 stream_put(s
, &zl3vni
->filter
, sizeof(int));
3824 /* Write packet size. */
3825 stream_putw_at(s
, 0, stream_get_endp(s
));
3827 if (IS_ZEBRA_DEBUG_VXLAN
)
3829 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3830 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3831 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3832 inet_ntoa(zl3vni
->local_vtep_ip
),
3833 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
3834 ? "prefix-routes-only"
3836 zebra_route_string(client
->proto
));
3838 client
->l3vniadd_cnt
++;
3839 return zserv_send_message(client
, s
);
3843 * Inform BGP about local l3-VNI deletion.
3845 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3847 struct stream
*s
= NULL
;
3848 struct zserv
*client
= NULL
;
3850 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3851 /* BGP may not be running. */
3855 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3857 zclient_create_header(s
, ZEBRA_L3VNI_DEL
, zl3vni_vrf_id(zl3vni
));
3858 stream_putl(s
, zl3vni
->vni
);
3860 /* Write packet size. */
3861 stream_putw_at(s
, 0, stream_get_endp(s
));
3863 if (IS_ZEBRA_DEBUG_VXLAN
)
3864 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni
->vni
,
3865 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3866 zebra_route_string(client
->proto
));
3868 client
->l3vnidel_cnt
++;
3869 return zserv_send_message(client
, s
);
3872 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3877 /* send l3vni add to BGP */
3878 zl3vni_send_add_to_client(zl3vni
);
3881 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3886 /* send l3-vni del to BGP*/
3887 zl3vni_send_del_to_client(zl3vni
);
3890 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
, void *ctxt
)
3892 zebra_vni_t
*zvni
= (zebra_vni_t
*)backet
->data
;
3893 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*)ctxt
;
3895 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3896 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3900 * handle transition of vni from l2 to l3 and vice versa
3902 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
, vni_t vni
,
3905 zebra_vni_t
*zvni
= NULL
;
3907 /* There is a possibility that VNI notification was already received
3908 * from kernel and we programmed it as L2-VNI
3909 * In such a case we need to delete this L2-VNI first, so
3910 * that it can be reprogrammed as L3-VNI in the system. It is also
3911 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3912 * interface is still present in kernel. In this case to keep it
3913 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3916 /* Locate hash entry */
3917 zvni
= zvni_lookup(vni
);
3921 if (IS_ZEBRA_DEBUG_VXLAN
)
3922 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni
);
3924 /* Delete VNI from BGP. */
3925 zvni_send_del_to_client(zvni
->vni
);
3927 /* Free up all neighbors and MAC, if any. */
3928 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3929 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3931 /* Free up all remote VTEPs, if any. */
3932 zvni_vtep_del_all(zvni
, 0);
3934 /* Delete the hash entry. */
3935 if (zvni_del(zvni
)) {
3936 flog_err(ZEBRA_ERR_VNI_DEL_FAILED
,
3937 "Failed to del VNI hash %p, VNI %u", zvni
,
3942 /* TODO_MITESH: This needs to be thought through. We don't have
3943 * enough information at this point to reprogram the vni as
3944 * l2-vni. One way is to store the required info in l3-vni and
3945 * used it solely for this purpose
3952 /* delete and uninstall rmac hash entry */
3953 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
, void *ctx
)
3955 zebra_mac_t
*zrmac
= NULL
;
3956 zebra_l3vni_t
*zl3vni
= NULL
;
3958 zrmac
= (zebra_mac_t
*)backet
->data
;
3959 zl3vni
= (zebra_l3vni_t
*)ctx
;
3960 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3961 zl3vni_rmac_del(zl3vni
, zrmac
);
3964 /* delete and uninstall nh hash entry */
3965 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
, void *ctx
)
3967 zebra_neigh_t
*n
= NULL
;
3968 zebra_l3vni_t
*zl3vni
= NULL
;
3970 n
= (zebra_neigh_t
*)backet
->data
;
3971 zl3vni
= (zebra_l3vni_t
*)ctx
;
3972 zl3vni_nh_uninstall(zl3vni
, n
);
3973 zl3vni_nh_del(zl3vni
, n
);
3976 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
3979 struct zserv
*client
= NULL
;
3980 struct stream
*s
= NULL
;
3981 char buf
[PREFIX_STRLEN
];
3983 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3984 /* BGP may not be running. */
3988 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3990 zclient_create_header(s
, cmd
, vrf_id
);
3991 stream_put(s
, p
, sizeof(struct prefix
));
3993 /* Write packet size. */
3994 stream_putw_at(s
, 0, stream_get_endp(s
));
3996 if (IS_ZEBRA_DEBUG_VXLAN
)
3997 zlog_debug("Send ip prefix %s %s on vrf %s",
3998 prefix2str(p
, buf
, sizeof(buf
)),
3999 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
4000 vrf_id_to_name(vrf_id
));
4002 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
4003 client
->prefixadd_cnt
++;
4005 client
->prefixdel_cnt
++;
4007 return zserv_send_message(client
, s
);
4010 /* re-add remote rmac if needed */
4011 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
4012 struct ethaddr
*rmac
)
4014 char buf
[ETHER_ADDR_STRLEN
];
4015 zebra_mac_t
*zrmac
= NULL
;
4017 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4021 if (IS_ZEBRA_DEBUG_VXLAN
)
4022 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
4023 prefix_mac2str(rmac
, buf
, sizeof(buf
)), zl3vni
->vni
);
4025 zl3vni_rmac_install(zl3vni
, zrmac
);
4029 /* Process a remote MACIP add from BGP. */
4030 static void process_remote_macip_add(vni_t vni
,
4031 struct ethaddr
*macaddr
,
4033 struct ipaddr
*ipaddr
,
4036 struct in_addr vtep_ip
)
4039 zebra_vtep_t
*zvtep
;
4040 zebra_mac_t
*mac
, *old_mac
;
4041 zebra_neigh_t
*n
= NULL
;
4042 int update_mac
= 0, update_neigh
= 0;
4043 char buf
[ETHER_ADDR_STRLEN
];
4044 char buf1
[INET6_ADDRSTRLEN
];
4045 struct interface
*ifp
= NULL
;
4046 struct zebra_if
*zif
= NULL
;
4049 uint8_t remote_gw
= 0;
4050 uint8_t router_flag
= 0;
4052 /* Locate VNI hash entry - expected to exist. */
4053 zvni
= zvni_lookup(vni
);
4055 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni
);
4059 ifp
= zvni
->vxlan_if
;
4063 !if_is_operative(ifp
) ||
4065 !zif
->brslave_info
.br_if
) {
4066 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
4071 /* The remote VTEP specified should normally exist, but it is
4072 * possible that when peering comes up, peer may advertise MACIP
4073 * routes before advertising type-3 routes.
4075 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4077 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4079 ZEBRA_ERR_VTEP_ADD_FAILED
,
4080 "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
4085 zvni_vtep_install(zvni
, &vtep_ip
);
4088 sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
4089 remote_gw
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
4090 router_flag
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
4092 mac
= zvni_mac_lookup(zvni
, macaddr
);
4094 /* Ignore if the mac is already present as a gateway mac */
4096 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
) &&
4097 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
4098 if (IS_ZEBRA_DEBUG_VXLAN
)
4099 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4101 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4102 ipa_len
? " IP " : "",
4104 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4108 /* check if the remote MAC is unknown or has a change.
4109 * If so, that needs to be updated first. Note that client could
4110 * install MAC and MACIP separately or just install the latter.
4113 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4114 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0) != sticky
4115 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
) ? 1 : 0)
4117 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
)
4118 || seq
!= mac
->rem_seq
)
4123 mac
= zvni_mac_add(zvni
, macaddr
);
4126 "Failed to add MAC %s VNI %u Remote VTEP %s",
4127 prefix_mac2str(macaddr
, buf
,
4129 vni
, inet_ntoa(vtep_ip
));
4133 /* Is this MAC created for a MACIP? */
4135 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4137 const char *mac_type
;
4139 /* When host moves but changes its (MAC,IP)
4140 * binding, BGP may install a MACIP entry that
4141 * corresponds to "older" location of the host
4142 * in transient situations (because {IP1,M1}
4143 * is a different route from {IP1,M2}). Check
4144 * the sequence number and ignore this update
4147 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
4148 tmp_seq
= mac
->loc_seq
;
4151 tmp_seq
= mac
->rem_seq
;
4152 mac_type
= "remote";
4154 if (seq
< tmp_seq
) {
4155 if (IS_ZEBRA_DEBUG_VXLAN
)
4156 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
4158 prefix_mac2str(macaddr
,
4160 ipa_len
? " IP " : "",
4163 buf1
, sizeof(buf1
)) : "",
4170 /* Set "auto" and "remote" forwarding info. */
4171 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4172 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4173 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4174 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4177 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4179 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4182 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4184 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4186 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
4188 /* Install the entry. */
4189 zvni_mac_install(zvni
, mac
);
4192 /* Update seq number. */
4195 /* If there is no IP, return after clearing AUTO flag of MAC. */
4197 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4201 /* Check if the remote neighbor itself is unknown or has a
4202 * change. If so, create or update and then install the entry.
4204 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4206 || !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4207 || (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0)
4208 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
)
4209 || ((CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
) ? 1 : 0)
4211 || seq
!= n
->rem_seq
)
4216 n
= zvni_neigh_add(zvni
, ipaddr
, macaddr
);
4219 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
4220 ipaddr2str(ipaddr
, buf1
,
4222 prefix_mac2str(macaddr
, buf
,
4224 vni
, inet_ntoa(vtep_ip
));
4231 /* When host moves but changes its (MAC,IP)
4232 * binding, BGP may install a MACIP entry that
4233 * corresponds to "older" location of the host
4234 * in transient situations (because {IP1,M1}
4235 * is a different route from {IP1,M2}). Check
4236 * the sequence number and ignore this update
4239 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4240 tmp_seq
= n
->loc_seq
;
4243 tmp_seq
= n
->rem_seq
;
4246 if (seq
< tmp_seq
) {
4247 if (IS_ZEBRA_DEBUG_VXLAN
)
4248 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
4250 prefix_mac2str(macaddr
,
4252 ipa_len
? " IP " : "",
4255 buf1
, sizeof(buf1
)) : "",
4260 if (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0) {
4261 /* MAC change, send a delete for old
4262 * neigh if learnt locally.
4264 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) &&
4265 IS_ZEBRA_NEIGH_ACTIVE(n
))
4266 zvni_neigh_send_del_to_client(
4270 /* update neigh list for macs */
4271 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
4273 listnode_delete(old_mac
->neigh_list
, n
);
4274 zvni_deref_ip2mac(zvni
, old_mac
, 1);
4276 listnode_add_sort(mac
->neigh_list
, n
);
4277 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4281 /* Set "remote" forwarding info. */
4282 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4283 n
->r_vtep_ip
= vtep_ip
;
4284 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4286 /* Set router flag (R-bit) to this Neighbor entry */
4287 if (CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
))
4288 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4290 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4292 /* Install the entry. */
4293 zvni_neigh_install(zvni
, n
);
4296 /* Update seq number. */
4300 /* Process a remote MACIP delete from BGP. */
4301 static void process_remote_macip_del(vni_t vni
,
4302 struct ethaddr
*macaddr
,
4304 struct ipaddr
*ipaddr
,
4305 struct in_addr vtep_ip
)
4308 zebra_mac_t
*mac
= NULL
;
4309 zebra_neigh_t
*n
= NULL
;
4310 struct interface
*ifp
= NULL
;
4311 struct zebra_if
*zif
= NULL
;
4312 char buf
[ETHER_ADDR_STRLEN
];
4313 char buf1
[INET6_ADDRSTRLEN
];
4315 /* Locate VNI hash entry - expected to exist. */
4316 zvni
= zvni_lookup(vni
);
4318 if (IS_ZEBRA_DEBUG_VXLAN
)
4319 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni
);
4323 ifp
= zvni
->vxlan_if
;
4327 !if_is_operative(ifp
) ||
4329 !zif
->brslave_info
.br_if
) {
4330 if (IS_ZEBRA_DEBUG_VXLAN
)
4331 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
4336 /* The remote VTEP specified is normally expected to exist, but
4337 * it is possible that the peer may delete the VTEP before deleting
4338 * any MACs referring to the VTEP, in which case the handler (see
4339 * remote_vtep_del) would have already deleted the MACs.
4341 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4344 mac
= zvni_mac_lookup(zvni
, macaddr
);
4346 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4349 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
4350 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4351 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)), vni
);
4355 /* If the remote mac or neighbor doesn't exist there is nothing
4356 * more to do. Otherwise, uninstall the entry and then remove it.
4361 /* Ignore the delete if this mac is a gateway mac-ip */
4363 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
4364 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
4366 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4368 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4369 ipa_len
? " IP " : "",
4371 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4375 /* Uninstall remote neighbor or MAC. */
4377 /* When the MAC changes for an IP, it is possible the
4378 * client may update the new MAC before trying to delete the
4379 * "old" neighbor (as these are two different MACIP routes).
4380 * Do the delete only if the MAC matches.
4382 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4383 && (memcmp(n
->emac
.octet
, macaddr
->octet
, ETH_ALEN
) == 0)) {
4384 zvni_neigh_uninstall(zvni
, n
);
4385 zvni_neigh_del(zvni
, n
);
4386 zvni_deref_ip2mac(zvni
, mac
, 1);
4389 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4390 zvni_process_neigh_on_remote_mac_del(zvni
, mac
);
4392 if (list_isempty(mac
->neigh_list
)) {
4393 zvni_mac_uninstall(zvni
, mac
, 0);
4394 zvni_mac_del(zvni
, mac
);
4396 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4402 /* Public functions */
4404 int is_l3vni_for_prefix_routes_only(vni_t vni
)
4406 zebra_l3vni_t
*zl3vni
= NULL
;
4408 zl3vni
= zl3vni_lookup(vni
);
4412 return CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
) ? 1 : 0;
4415 /* handle evpn route in vrf table */
4416 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
4417 struct ipaddr
*vtep_ip
,
4418 struct prefix
*host_prefix
)
4420 zebra_l3vni_t
*zl3vni
= NULL
;
4421 struct ipaddr ipv4_vtep
;
4423 zl3vni
= zl3vni_from_vrf(vrf_id
);
4424 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
4428 * add the next hop neighbor -
4429 * neigh to be installed is the ipv6 nexthop neigh
4431 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
4434 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
4435 * address. Rmac is programmed against the ipv4 vtep because we only
4436 * support ipv4 tunnels in the h/w right now
4438 memset(&ipv4_vtep
, 0, sizeof(struct ipaddr
));
4439 ipv4_vtep
.ipa_type
= IPADDR_V4
;
4440 if (vtep_ip
->ipa_type
== IPADDR_V6
)
4441 ipv4_mapped_ipv6_to_ipv4(&vtep_ip
->ipaddr_v6
,
4442 &(ipv4_vtep
.ipaddr_v4
));
4444 memcpy(&(ipv4_vtep
.ipaddr_v4
), &vtep_ip
->ipaddr_v4
,
4445 sizeof(struct in_addr
));
4448 * add the rmac - remote rmac to be installed is against the ipv4
4451 zl3vni_remote_rmac_add(zl3vni
, rmac
, &ipv4_vtep
, host_prefix
);
4454 /* handle evpn vrf route delete */
4455 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
4456 struct ipaddr
*vtep_ip
,
4457 struct prefix
*host_prefix
)
4459 zebra_l3vni_t
*zl3vni
= NULL
;
4460 zebra_neigh_t
*nh
= NULL
;
4461 zebra_mac_t
*zrmac
= NULL
;
4463 zl3vni
= zl3vni_from_vrf(vrf_id
);
4467 /* find the next hop entry and rmac entry */
4468 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
4471 zrmac
= zl3vni_rmac_lookup(zl3vni
, &nh
->emac
);
4473 /* delete the next hop entry */
4474 zl3vni_remote_nh_del(zl3vni
, nh
, host_prefix
);
4476 /* delete the rmac entry */
4478 zl3vni_remote_rmac_del(zl3vni
, zrmac
, host_prefix
);
4482 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
, vni_t l3vni
,
4483 struct ethaddr
*rmac
, bool use_json
)
4485 zebra_l3vni_t
*zl3vni
= NULL
;
4486 zebra_mac_t
*zrmac
= NULL
;
4487 json_object
*json
= NULL
;
4489 if (!is_evpn_enabled()) {
4491 vty_out(vty
, "{}\n");
4496 json
= json_object_new_object();
4498 zl3vni
= zl3vni_lookup(l3vni
);
4501 vty_out(vty
, "{}\n");
4503 vty_out(vty
, "%% L3-VNI %u doesnt exist\n", l3vni
);
4507 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4510 vty_out(vty
, "{}\n");
4513 "%% Requested RMAC doesnt exist in L3-VNI %u",
4518 zl3vni_print_rmac(zrmac
, vty
, json
);
4521 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4522 json
, JSON_C_TO_STRING_PRETTY
));
4523 json_object_free(json
);
4527 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4529 zebra_l3vni_t
*zl3vni
;
4531 struct rmac_walk_ctx wctx
;
4532 json_object
*json
= NULL
;
4534 if (!is_evpn_enabled())
4537 zl3vni
= zl3vni_lookup(l3vni
);
4540 vty_out(vty
, "{}\n");
4542 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4545 num_rmacs
= hashcount(zl3vni
->rmac_table
);
4550 json
= json_object_new_object();
4552 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
4556 vty_out(vty
, "Number of Remote RMACs known for this VNI: %u\n",
4558 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
4560 json_object_int_add(json
, "numRmacs", num_rmacs
);
4562 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
4565 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4566 json
, JSON_C_TO_STRING_PRETTY
));
4567 json_object_free(json
);
4571 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
, bool use_json
)
4573 struct zebra_ns
*zns
= NULL
;
4574 json_object
*json
= NULL
;
4577 if (!is_evpn_enabled()) {
4579 vty_out(vty
, "{}\n");
4583 zns
= zebra_ns_lookup(NS_DEFAULT
);
4586 vty_out(vty
, "{}\n");
4591 json
= json_object_new_object();
4595 hash_iterate(zns
->l3vni_table
,
4596 (void (*)(struct hash_backet
*,
4597 void *))zl3vni_print_rmac_hash_all_vni
,
4601 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4602 json
, JSON_C_TO_STRING_PRETTY
));
4603 json_object_free(json
);
4607 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
, vni_t l3vni
,
4608 struct ipaddr
*ip
, bool use_json
)
4610 zebra_l3vni_t
*zl3vni
= NULL
;
4611 zebra_neigh_t
*n
= NULL
;
4612 json_object
*json
= NULL
;
4614 if (!is_evpn_enabled()) {
4616 vty_out(vty
, "{}\n");
4621 json
= json_object_new_object();
4623 zl3vni
= zl3vni_lookup(l3vni
);
4626 vty_out(vty
, "{}\n");
4628 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4632 n
= zl3vni_nh_lookup(zl3vni
, ip
);
4635 vty_out(vty
, "{}\n");
4638 "%% Requested next-hop not present for L3-VNI %u",
4643 zl3vni_print_nh(n
, vty
, json
);
4646 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4647 json
, JSON_C_TO_STRING_PRETTY
));
4648 json_object_free(json
);
4652 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4655 struct nh_walk_ctx wctx
;
4656 json_object
*json
= NULL
;
4657 zebra_l3vni_t
*zl3vni
= NULL
;
4659 if (!is_evpn_enabled())
4662 zl3vni
= zl3vni_lookup(l3vni
);
4665 vty_out(vty
, "{}\n");
4667 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4671 num_nh
= hashcount(zl3vni
->nh_table
);
4676 json
= json_object_new_object();
4681 vty_out(vty
, "Number of NH Neighbors known for this VNI: %u\n",
4683 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4685 json_object_int_add(json
, "numNextHops", num_nh
);
4687 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4690 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4691 json
, JSON_C_TO_STRING_PRETTY
));
4692 json_object_free(json
);
4696 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
, bool use_json
)
4698 struct zebra_ns
*zns
= NULL
;
4699 json_object
*json
= NULL
;
4702 if (!is_evpn_enabled()) {
4704 vty_out(vty
, "{}\n");
4708 zns
= zebra_ns_lookup(NS_DEFAULT
);
4713 json
= json_object_new_object();
4717 hash_iterate(zns
->l3vni_table
,
4718 (void (*)(struct hash_backet
*,
4719 void *))zl3vni_print_nh_hash_all_vni
,
4723 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4724 json
, JSON_C_TO_STRING_PRETTY
));
4725 json_object_free(json
);
4730 * Display L3 VNI information (VTY command handler).
4732 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, bool use_json
)
4735 json_object
*json
= NULL
;
4736 zebra_l3vni_t
*zl3vni
= NULL
;
4738 if (!is_evpn_enabled()) {
4740 vty_out(vty
, "{}\n");
4744 zl3vni
= zl3vni_lookup(vni
);
4747 vty_out(vty
, "{}\n");
4749 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4754 json
= json_object_new_object();
4758 zl3vni_print(zl3vni
, (void *)args
);
4761 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4762 json
, JSON_C_TO_STRING_PRETTY
));
4763 json_object_free(json
);
4767 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4768 json_object
*json_vrfs
)
4770 char buf
[ETHER_ADDR_STRLEN
];
4771 zebra_l3vni_t
*zl3vni
= NULL
;
4773 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4778 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4779 zvrf_name(zvrf
), zl3vni
->vni
,
4780 zl3vni_vxlan_if_name(zl3vni
),
4781 zl3vni_svi_if_name(zl3vni
), zl3vni_state2str(zl3vni
),
4782 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4784 json_object
*json_vrf
= NULL
;
4786 json_vrf
= json_object_new_object();
4787 json_object_string_add(json_vrf
, "vrf", zvrf_name(zvrf
));
4788 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4789 json_object_string_add(json_vrf
, "vxlanIntf",
4790 zl3vni_vxlan_if_name(zl3vni
));
4791 json_object_string_add(json_vrf
, "sviIntf",
4792 zl3vni_svi_if_name(zl3vni
));
4793 json_object_string_add(json_vrf
, "state",
4794 zl3vni_state2str(zl3vni
));
4795 json_object_string_add(
4796 json_vrf
, "routerMac",
4797 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4798 json_object_array_add(json_vrfs
, json_vrf
);
4803 * Display Neighbors for a VNI (VTY command handler).
4805 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4806 vni_t vni
, bool use_json
)
4810 struct neigh_walk_ctx wctx
;
4811 json_object
*json
= NULL
;
4813 if (!is_evpn_enabled())
4815 zvni
= zvni_lookup(vni
);
4818 vty_out(vty
, "{}\n");
4820 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4823 num_neigh
= hashcount(zvni
->neigh_table
);
4828 json
= json_object_new_object();
4830 /* Since we have IPv6 addresses to deal with which can vary widely in
4831 * size, we try to be a bit more elegant in display by first computing
4832 * the maximum width.
4834 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4837 wctx
.addr_width
= 15;
4839 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4843 "Number of ARPs (local and remote) known for this VNI: %u\n",
4845 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
4846 -wctx
.addr_width
, "IP", "Type",
4847 "State", "MAC", "Remote VTEP");
4849 json_object_int_add(json
, "numArpNd", num_neigh
);
4851 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4853 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4854 json
, JSON_C_TO_STRING_PRETTY
));
4855 json_object_free(json
);
4860 * Display neighbors across all VNIs (VTY command handler).
4862 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4865 json_object
*json
= NULL
;
4868 if (!is_evpn_enabled())
4872 json
= json_object_new_object();
4876 hash_iterate(zvrf
->vni_table
,
4877 (void (*)(struct hash_backet
*,
4878 void *))zvni_print_neigh_hash_all_vni
,
4881 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4882 json
, JSON_C_TO_STRING_PRETTY
));
4883 json_object_free(json
);
4888 * Display specific neighbor for a VNI, if present (VTY command handler).
4890 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4891 struct zebra_vrf
*zvrf
, vni_t vni
,
4892 struct ipaddr
*ip
, bool use_json
)
4896 json_object
*json
= NULL
;
4898 if (!is_evpn_enabled())
4900 zvni
= zvni_lookup(vni
);
4903 vty_out(vty
, "{}\n");
4905 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4908 n
= zvni_neigh_lookup(zvni
, ip
);
4912 "%% Requested neighbor does not exist in VNI %u\n",
4917 json
= json_object_new_object();
4919 zvni_print_neigh(n
, vty
, json
);
4922 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4923 json
, JSON_C_TO_STRING_PRETTY
));
4924 json_object_free(json
);
4929 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4930 * By definition, these are remote neighbors.
4932 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4933 vni_t vni
, struct in_addr vtep_ip
,
4938 struct neigh_walk_ctx wctx
;
4939 json_object
*json
= NULL
;
4941 if (!is_evpn_enabled())
4943 zvni
= zvni_lookup(vni
);
4946 vty_out(vty
, "{}\n");
4948 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4951 num_neigh
= hashcount(zvni
->neigh_table
);
4955 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4958 wctx
.addr_width
= 15;
4959 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4960 wctx
.r_vtep_ip
= vtep_ip
;
4962 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4963 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4966 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4967 json
, JSON_C_TO_STRING_PRETTY
));
4968 json_object_free(json
);
4973 * Display MACs for a VNI (VTY command handler).
4975 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4976 vni_t vni
, bool use_json
)
4980 struct mac_walk_ctx wctx
;
4981 json_object
*json
= NULL
;
4982 json_object
*json_mac
= NULL
;
4984 if (!is_evpn_enabled())
4986 zvni
= zvni_lookup(vni
);
4989 vty_out(vty
, "{}\n");
4991 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4994 num_macs
= num_valid_macs(zvni
);
4999 json
= json_object_new_object();
5000 json_mac
= json_object_new_object();
5003 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5006 wctx
.json
= json_mac
;
5010 "Number of MACs (local and remote) known for this VNI: %u\n",
5012 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
5013 "Intf/Remote VTEP", "VLAN");
5015 json_object_int_add(json
, "numMacs", num_macs
);
5017 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5020 json_object_object_add(json
, "macs", json_mac
);
5021 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5022 json
, JSON_C_TO_STRING_PRETTY
));
5023 json_object_free(json
);
5028 * Display MACs for all VNIs (VTY command handler).
5030 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5033 struct mac_walk_ctx wctx
;
5034 json_object
*json
= NULL
;
5036 if (!is_evpn_enabled()) {
5038 vty_out(vty
, "{}\n");
5042 json
= json_object_new_object();
5044 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5047 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5050 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5051 json
, JSON_C_TO_STRING_PRETTY
));
5052 json_object_free(json
);
5057 * Display MACs for all VNIs (VTY command handler).
5059 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
5060 struct zebra_vrf
*zvrf
,
5061 struct in_addr vtep_ip
, bool use_json
)
5063 struct mac_walk_ctx wctx
;
5064 json_object
*json
= NULL
;
5066 if (!is_evpn_enabled())
5070 json
= json_object_new_object();
5072 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5074 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5075 wctx
.r_vtep_ip
= vtep_ip
;
5077 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5080 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5081 json
, JSON_C_TO_STRING_PRETTY
));
5082 json_object_free(json
);
5087 * Display specific MAC for a VNI, if present (VTY command handler).
5089 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5090 vni_t vni
, struct ethaddr
*macaddr
)
5095 if (!is_evpn_enabled())
5097 zvni
= zvni_lookup(vni
);
5099 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5102 mac
= zvni_mac_lookup(zvni
, macaddr
);
5104 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
5109 zvni_print_mac(mac
, vty
);
5113 * Display MACs for a VNI from specific VTEP (VTY command handler).
5115 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5116 vni_t vni
, struct in_addr vtep_ip
,
5121 struct mac_walk_ctx wctx
;
5122 json_object
*json
= NULL
;
5123 json_object
*json_mac
= NULL
;
5125 if (!is_evpn_enabled())
5127 zvni
= zvni_lookup(vni
);
5130 vty_out(vty
, "{}\n");
5132 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5135 num_macs
= num_valid_macs(zvni
);
5140 json
= json_object_new_object();
5141 json_mac
= json_object_new_object();
5144 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5147 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5148 wctx
.r_vtep_ip
= vtep_ip
;
5149 wctx
.json
= json_mac
;
5150 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5153 json_object_int_add(json
, "numMacs", wctx
.count
);
5155 json_object_object_add(json
, "macs", json_mac
);
5156 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5157 json
, JSON_C_TO_STRING_PRETTY
));
5158 json_object_free(json
);
5164 * Display VNI information (VTY command handler).
5166 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
5169 json_object
*json
= NULL
;
5171 zebra_l3vni_t
*zl3vni
= NULL
;
5172 zebra_vni_t
*zvni
= NULL
;
5174 if (!is_evpn_enabled())
5178 json
= json_object_new_object();
5182 zl3vni
= zl3vni_lookup(vni
);
5184 zl3vni_print(zl3vni
, (void *)args
);
5186 zvni
= zvni_lookup(vni
);
5189 vty_out(vty
, "{}\n");
5191 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5195 zvni_print(zvni
, (void *)args
);
5199 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5200 json
, JSON_C_TO_STRING_PRETTY
));
5201 json_object_free(json
);
5205 /* Display all global details for EVPN */
5206 void zebra_vxlan_print_evpn(struct vty
*vty
, bool uj
)
5211 json_object
*json
= NULL
;
5212 struct zebra_ns
*zns
= NULL
;
5213 struct zebra_vrf
*zvrf
= NULL
;
5215 if (!is_evpn_enabled())
5218 zns
= zebra_ns_lookup(NS_DEFAULT
);
5222 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
5226 num_l3vnis
= hashcount(zns
->l3vni_table
);
5227 num_l2vnis
= hashcount(zvrf
->vni_table
);
5228 num_vnis
= num_l2vnis
+ num_l3vnis
;
5231 json
= json_object_new_object();
5232 json_object_string_add(json
, "advertiseGatewayMacip",
5233 zvrf
->advertise_gw_macip
? "Yes" : "No");
5234 json_object_int_add(json
, "numVnis", num_vnis
);
5235 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
5236 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
5238 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
5239 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
5240 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
5241 zvrf
->advertise_gw_macip
? "Yes" : "No");
5245 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5246 json
, JSON_C_TO_STRING_PRETTY
));
5247 json_object_free(json
);
5252 * Display VNI hash table (VTY command handler).
5254 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5257 json_object
*json
= NULL
;
5258 struct zebra_ns
*zns
= NULL
;
5261 if (!is_evpn_enabled())
5264 zns
= zebra_ns_lookup(NS_DEFAULT
);
5270 json
= json_object_new_object();
5272 vty_out(vty
, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
5273 "Type", "VxLAN IF", "# MACs", "# ARPs",
5274 "# Remote VTEPs", "Tenant VRF");
5279 /* Display all L2-VNIs */
5280 hash_iterate(zvrf
->vni_table
,
5281 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
5284 /* Display all L3-VNIs */
5285 hash_iterate(zns
->l3vni_table
,
5286 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
5290 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5291 json
, JSON_C_TO_STRING_PRETTY
));
5292 json_object_free(json
);
5297 * Handle neighbor delete notification from the kernel (on a VLAN device
5298 * / L3 interface). This may result in either the neighbor getting deleted
5299 * from our database or being re-added to the kernel (if it is a valid
5302 int zebra_vxlan_handle_kernel_neigh_del(struct interface
*ifp
,
5303 struct interface
*link_if
,
5306 char buf
[INET6_ADDRSTRLEN
];
5307 char buf2
[ETHER_ADDR_STRLEN
];
5308 zebra_neigh_t
*n
= NULL
;
5309 zebra_vni_t
*zvni
= NULL
;
5310 zebra_mac_t
*zmac
= NULL
;
5311 zebra_l3vni_t
*zl3vni
= NULL
;
5313 /* check if this is a remote neigh entry corresponding to remote
5316 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5318 return zl3vni_local_nh_del(zl3vni
, ip
);
5320 /* We are only interested in neighbors on an SVI that resides on top
5321 * of a VxLAN bridge.
5323 zvni
= zvni_from_svi(ifp
, link_if
);
5327 if (!zvni
->vxlan_if
) {
5329 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
5334 if (IS_ZEBRA_DEBUG_VXLAN
)
5335 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
5336 ipaddr2str(ip
, buf
, sizeof(buf
)), ifp
->name
,
5337 ifp
->ifindex
, zvni
->vni
);
5339 /* If entry doesn't exist, nothing to do. */
5340 n
= zvni_neigh_lookup(zvni
, ip
);
5344 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
5346 if (IS_ZEBRA_DEBUG_VXLAN
)
5348 "Trying to del a neigh %s without a mac %s on VNI %u",
5349 ipaddr2str(ip
, buf
, sizeof(buf
)),
5350 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
5356 /* If it is a remote entry, the kernel has aged this out or someone has
5357 * deleted it, it needs to be re-installed as Quagga is the owner.
5359 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
5360 zvni_neigh_install(zvni
, n
);
5364 /* Remove neighbor from BGP. */
5365 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
5366 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
, 0);
5368 /* Delete this neighbor entry. */
5369 zvni_neigh_del(zvni
, n
);
5371 /* see if the AUTO mac needs to be deleted */
5372 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
5373 && !listcount(zmac
->neigh_list
))
5374 zvni_mac_del(zvni
, zmac
);
5380 * Handle neighbor add or update notification from the kernel (on a VLAN
5381 * device / L3 interface). This is typically for a local neighbor but can
5382 * also be for a remote neighbor (e.g., ageout notification). It could
5383 * also be a "move" scenario.
5385 int zebra_vxlan_handle_kernel_neigh_update(struct interface
*ifp
,
5386 struct interface
*link_if
,
5388 struct ethaddr
*macaddr
,
5390 uint8_t ext_learned
,
5391 uint8_t router_flag
)
5393 char buf
[ETHER_ADDR_STRLEN
];
5394 char buf2
[INET6_ADDRSTRLEN
];
5395 zebra_vni_t
*zvni
= NULL
;
5396 zebra_l3vni_t
*zl3vni
= NULL
;
5398 /* check if this is a remote neigh entry corresponding to remote
5401 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5403 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
5405 /* We are only interested in neighbors on an SVI that resides on top
5406 * of a VxLAN bridge.
5408 zvni
= zvni_from_svi(ifp
, link_if
);
5412 if (IS_ZEBRA_DEBUG_VXLAN
)
5414 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
5415 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
5416 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5417 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
5418 router_flag
? "router " : "",
5421 /* Is this about a local neighbor or a remote one? */
5423 return zvni_local_neigh_update(zvni
, ifp
, ip
, macaddr
,
5426 return zvni_remote_neigh_update(zvni
, ifp
, ip
, macaddr
, state
);
5431 * Handle message from client to delete a remote MACIP for a VNI.
5433 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS
)
5437 struct ethaddr macaddr
;
5439 struct in_addr vtep_ip
;
5440 uint16_t l
= 0, ipa_len
;
5441 char buf
[ETHER_ADDR_STRLEN
];
5442 char buf1
[INET6_ADDRSTRLEN
];
5444 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5445 memset(&ip
, 0, sizeof(struct ipaddr
));
5446 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5450 while (l
< hdr
->length
) {
5451 /* Obtain each remote MACIP and process. */
5452 /* Message contains VNI, followed by MAC followed by IP (if any)
5453 * followed by remote VTEP IP.
5455 memset(&ip
, 0, sizeof(ip
));
5456 STREAM_GETL(s
, vni
);
5457 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5458 STREAM_GETL(s
, ipa_len
);
5460 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5462 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5464 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5465 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5466 l
+= IPV4_MAX_BYTELEN
;
5468 if (IS_ZEBRA_DEBUG_VXLAN
)
5470 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
5472 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5473 ipa_len
? " IP " : "",
5475 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5477 zebra_route_string(client
->proto
));
5479 process_remote_macip_del(vni
, &macaddr
, ipa_len
, &ip
, vtep_ip
);
5487 * Handle message from client to add a remote MACIP for a VNI. This
5488 * could be just the add of a MAC address or the add of a neighbor
5491 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS
)
5495 struct ethaddr macaddr
;
5497 struct in_addr vtep_ip
;
5498 uint16_t l
= 0, ipa_len
;
5501 char buf
[ETHER_ADDR_STRLEN
];
5502 char buf1
[INET6_ADDRSTRLEN
];
5504 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5505 memset(&ip
, 0, sizeof(struct ipaddr
));
5506 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5508 if (!EVPN_ENABLED(zvrf
)) {
5509 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
5515 while (l
< hdr
->length
) {
5516 /* Obtain each remote MACIP and process. */
5517 /* Message contains VNI, followed by MAC followed by IP (if any)
5518 * followed by remote VTEP IP.
5520 memset(&ip
, 0, sizeof(ip
));
5521 STREAM_GETL(s
, vni
);
5522 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5523 STREAM_GETL(s
, ipa_len
);
5525 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5527 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5529 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5530 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5531 l
+= IPV4_MAX_BYTELEN
;
5533 /* Get flags - sticky mac and/or gateway mac */
5534 STREAM_GETC(s
, flags
);
5536 STREAM_GETL(s
, seq
);
5539 if (IS_ZEBRA_DEBUG_VXLAN
)
5541 "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
5543 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5544 ipa_len
? " IP " : "",
5546 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5547 flags
, seq
, inet_ntoa(vtep_ip
),
5548 zebra_route_string(client
->proto
));
5550 process_remote_macip_add(vni
, &macaddr
, ipa_len
, &ip
,
5551 flags
, seq
, vtep_ip
);
5559 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5560 * us, this must involve a multihoming scenario. Treat this as implicit delete
5561 * of any prior local MAC.
5563 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5564 struct interface
*br_if
,
5565 struct ethaddr
*macaddr
, vlanid_t vid
)
5567 struct zebra_if
*zif
;
5568 struct zebra_l2info_vxlan
*vxl
;
5572 char buf
[ETHER_ADDR_STRLEN
];
5576 vxl
= &zif
->l2info
.vxl
;
5579 /* Check if EVPN is enabled. */
5580 if (!is_evpn_enabled())
5583 /* Locate hash entry; it is expected to exist. */
5584 zvni
= zvni_lookup(vni
);
5588 /* If entry doesn't exist, nothing to do. */
5589 mac
= zvni_mac_lookup(zvni
, macaddr
);
5593 /* Is it a local entry? */
5594 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5597 if (IS_ZEBRA_DEBUG_VXLAN
)
5599 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5600 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5603 /* Remove MAC from BGP. */
5604 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5607 * If there are no neigh associated with the mac delete the mac
5608 * else mark it as AUTO for forward reference
5610 if (!listcount(mac
->neigh_list
)) {
5611 zvni_mac_del(zvni
, mac
);
5613 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5614 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5621 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5622 * This can happen because the remote MAC entries are also added as "dynamic",
5623 * so the kernel can ageout the entry.
5625 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5626 struct interface
*br_if
,
5627 struct ethaddr
*macaddr
, vlanid_t vid
)
5629 struct zebra_if
*zif
= NULL
;
5630 struct zebra_l2info_vxlan
*vxl
= NULL
;
5632 zebra_vni_t
*zvni
= NULL
;
5633 zebra_l3vni_t
*zl3vni
= NULL
;
5634 zebra_mac_t
*mac
= NULL
;
5635 char buf
[ETHER_ADDR_STRLEN
];
5639 vxl
= &zif
->l2info
.vxl
;
5642 /* Check if EVPN is enabled. */
5643 if (!is_evpn_enabled())
5646 /* check if this is a remote RMAC and readd simillar to remote macs */
5647 zl3vni
= zl3vni_lookup(vni
);
5649 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5651 /* Locate hash entry; it is expected to exist. */
5652 zvni
= zvni_lookup(vni
);
5656 /* If entry doesn't exist, nothing to do. */
5657 mac
= zvni_mac_lookup(zvni
, macaddr
);
5661 /* Is it a remote entry? */
5662 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5665 if (IS_ZEBRA_DEBUG_VXLAN
)
5666 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5667 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5670 zvni_mac_install(zvni
, mac
);
5675 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5677 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5678 struct ethaddr
*macaddr
, vlanid_t vid
)
5682 char buf
[ETHER_ADDR_STRLEN
];
5684 /* We are interested in MACs only on ports or (port, VLAN) that
5687 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5690 if (!zvni
->vxlan_if
) {
5692 "VNI %u hash %p doesn't have intf upon local MAC DEL",
5697 if (IS_ZEBRA_DEBUG_VXLAN
)
5698 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u",
5699 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5700 ifp
->ifindex
, vid
, zvni
->vni
);
5702 /* If entry doesn't exist, nothing to do. */
5703 mac
= zvni_mac_lookup(zvni
, macaddr
);
5707 /* Is it a local entry? */
5708 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5711 /* Update all the neigh entries associated with this mac */
5712 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5714 /* Remove MAC from BGP. */
5715 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5718 * If there are no neigh associated with the mac delete the mac
5719 * else mark it as AUTO for forward reference
5721 if (!listcount(mac
->neigh_list
)) {
5722 zvni_mac_del(zvni
, mac
);
5724 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5725 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5732 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5734 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5735 struct interface
*br_if
,
5736 struct ethaddr
*macaddr
, vlanid_t vid
,
5741 char buf
[ETHER_ADDR_STRLEN
];
5742 bool mac_sticky
= false;
5743 bool inform_client
= false;
5744 bool upd_neigh
= false;
5746 /* We are interested in MACs only on ports or (port, VLAN) that
5749 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5751 if (IS_ZEBRA_DEBUG_VXLAN
)
5753 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5754 sticky
? "sticky " : "",
5755 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5756 ifp
->name
, ifp
->ifindex
, vid
);
5760 if (!zvni
->vxlan_if
) {
5762 "VNI %u hash %p doesn't have intf upon local MAC ADD",
5767 /* Check if we need to create or update or it is a NO-OP. */
5768 mac
= zvni_mac_lookup(zvni
, macaddr
);
5770 if (IS_ZEBRA_DEBUG_VXLAN
)
5772 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
5773 sticky
? "sticky " : "",
5774 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5775 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5777 mac
= zvni_mac_add(zvni
, macaddr
);
5780 ZEBRA_ERR_MAC_ADD_FAILED
,
5781 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
5782 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5783 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5786 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5787 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5788 mac
->fwd_info
.local
.vid
= vid
;
5790 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5791 inform_client
= true;
5794 if (IS_ZEBRA_DEBUG_VXLAN
)
5796 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
5797 sticky
? "sticky " : "",
5798 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5799 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
,
5802 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5803 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
5807 * Update any changes and if changes are relevant to
5810 if (mac_sticky
== sticky
5811 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5812 && mac
->fwd_info
.local
.vid
== vid
) {
5813 if (IS_ZEBRA_DEBUG_VXLAN
)
5815 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5816 "entry exists and has not changed ",
5817 sticky
? "sticky " : "",
5818 prefix_mac2str(macaddr
, buf
,
5820 ifp
->name
, ifp
->ifindex
, vid
,
5824 if (mac_sticky
!= sticky
) {
5826 SET_FLAG(mac
->flags
,
5829 UNSET_FLAG(mac
->flags
,
5831 inform_client
= true;
5834 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5835 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5836 mac
->fwd_info
.local
.vid
= vid
;
5838 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
) ||
5839 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
5842 * MAC has either moved or was "internally" created due
5843 * to a neighbor learn and is now actually learnt. If
5844 * it was learnt as a remote sticky MAC, this is an
5847 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5849 ZEBRA_ERR_STICKY_MAC_ALREADY_LEARNT
,
5850 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
5851 prefix_mac2str(macaddr
, buf
,
5853 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5858 /* If an actual move, compute MAC's seq number */
5859 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5860 mac
->loc_seq
= MAX(mac
->rem_seq
+ 1,
5862 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5863 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5864 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5865 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5866 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5867 mac
->fwd_info
.local
.vid
= vid
;
5869 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5871 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5873 * We have to inform BGP of this MAC as well as process
5876 inform_client
= true;
5881 /* Inform BGP if required. */
5882 if (inform_client
) {
5883 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5884 mac
->flags
, mac
->loc_seq
))
5888 /* Process all neighbors associated with this MAC, if required. */
5890 zvni_process_neigh_on_local_mac_change(zvni
, mac
, 0);
5896 * Handle message from client to delete a remote VTEP for a VNI.
5898 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS
)
5901 unsigned short l
= 0;
5903 struct in_addr vtep_ip
;
5905 zebra_vtep_t
*zvtep
;
5906 struct interface
*ifp
;
5907 struct zebra_if
*zif
;
5909 if (!is_evpn_enabled()) {
5911 "%s: EVPN is not enabled yet we have received a vtep del command",
5912 __PRETTY_FUNCTION__
);
5916 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5917 zlog_debug("Recv MACIP DEL for non-default VRF %u",
5924 while (l
< hdr
->length
) {
5925 /* Obtain each remote VTEP and process. */
5926 STREAM_GETL(s
, vni
);
5928 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5929 l
+= IPV4_MAX_BYTELEN
;
5931 if (IS_ZEBRA_DEBUG_VXLAN
)
5932 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5933 inet_ntoa(vtep_ip
), vni
,
5934 zebra_route_string(client
->proto
));
5936 /* Locate VNI hash entry - expected to exist. */
5937 zvni
= zvni_lookup(vni
);
5939 if (IS_ZEBRA_DEBUG_VXLAN
)
5941 "Failed to locate VNI hash upon remote VTEP DEL, "
5947 ifp
= zvni
->vxlan_if
;
5950 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5956 /* If down or not mapped to a bridge, we're done. */
5957 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5960 /* If the remote VTEP does not exist, there's nothing more to
5962 * Otherwise, uninstall any remote MACs pointing to this VTEP
5964 * then, the VTEP entry itself and remove it.
5966 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5970 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5971 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5972 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5973 zvni_vtep_del(zvni
, zvtep
);
5981 * Handle message from client to add a remote VTEP for a VNI.
5983 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS
)
5986 unsigned short l
= 0;
5988 struct in_addr vtep_ip
;
5990 struct interface
*ifp
;
5991 struct zebra_if
*zif
;
5993 if (!is_evpn_enabled()) {
5995 "%s: EVPN not enabled yet we received a vtep_add zapi call",
5996 __PRETTY_FUNCTION__
);
6000 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6001 zlog_debug("Recv MACIP ADD for non-default VRF %u",
6008 while (l
< hdr
->length
) {
6009 /* Obtain each remote VTEP and process. */
6010 STREAM_GETL(s
, vni
);
6012 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
6013 l
+= IPV4_MAX_BYTELEN
;
6015 if (IS_ZEBRA_DEBUG_VXLAN
)
6016 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
6017 inet_ntoa(vtep_ip
), vni
,
6018 zebra_route_string(client
->proto
));
6020 /* Locate VNI hash entry - expected to exist. */
6021 zvni
= zvni_lookup(vni
);
6024 ZEBRA_ERR_VTEP_ADD_FAILED
,
6025 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
6030 ifp
= zvni
->vxlan_if
;
6033 ZEBRA_ERR_VTEP_ADD_FAILED
,
6034 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
6041 /* If down or not mapped to a bridge, we're done. */
6042 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6045 /* If the remote VTEP already exists,
6046 there's nothing more to do. */
6047 if (zvni_vtep_find(zvni
, &vtep_ip
))
6050 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
6051 flog_err(ZEBRA_ERR_VTEP_ADD_FAILED
,
6052 "Failed to add remote VTEP, VNI %u zvni %p",
6057 zvni_vtep_install(zvni
, &vtep_ip
);
6065 * Add/Del gateway macip to evpn
6067 * 1. SVI interface on a vlan aware bridge
6068 * 2. SVI interface on a vlan unaware bridge
6069 * 3. vrr interface (MACVLAN) associated to a SVI
6070 * We advertise macip routes for an interface if it is associated to VxLan vlan
6072 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
6076 struct ethaddr macaddr
;
6077 zebra_vni_t
*zvni
= NULL
;
6079 memset(&ip
, 0, sizeof(struct ipaddr
));
6080 memset(&macaddr
, 0, sizeof(struct ethaddr
));
6082 /* Check if EVPN is enabled. */
6083 if (!is_evpn_enabled())
6086 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
6087 struct interface
*svi_if
=
6088 NULL
; /* SVI corresponding to the MACVLAN */
6089 struct zebra_if
*ifp_zif
=
6090 NULL
; /* Zebra daemon specific info for MACVLAN */
6091 struct zebra_if
*svi_if_zif
=
6092 NULL
; /* Zebra daemon specific info for SVI*/
6094 ifp_zif
= ifp
->info
;
6099 * for a MACVLAN interface the link represents the svi_if
6101 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
6102 ifp_zif
->link_ifindex
);
6104 zlog_debug("MACVLAN %s(%u) without link information",
6105 ifp
->name
, ifp
->ifindex
);
6109 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
6111 * If it is a vlan aware bridge then the link gives the
6112 * bridge information
6114 struct interface
*svi_if_link
= NULL
;
6116 svi_if_zif
= svi_if
->info
;
6118 svi_if_link
= if_lookup_by_index_per_ns(
6119 zebra_ns_lookup(NS_DEFAULT
),
6120 svi_if_zif
->link_ifindex
);
6121 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
6123 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
6125 * If it is a vlan unaware bridge then svi is the bridge
6128 zvni
= zvni_from_svi(svi_if
, svi_if
);
6130 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
6131 struct zebra_if
*svi_if_zif
=
6132 NULL
; /* Zebra daemon specific info for SVI */
6133 struct interface
*svi_if_link
=
6134 NULL
; /* link info for the SVI = bridge info */
6136 svi_if_zif
= ifp
->info
;
6138 svi_if_link
= if_lookup_by_index_per_ns(
6139 zebra_ns_lookup(NS_DEFAULT
),
6140 svi_if_zif
->link_ifindex
);
6142 zvni
= zvni_from_svi(ifp
, svi_if_link
);
6144 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
6145 zvni
= zvni_from_svi(ifp
, ifp
);
6151 if (!zvni
->vxlan_if
) {
6152 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
6158 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
6160 if (p
->family
== AF_INET
) {
6161 ip
.ipa_type
= IPADDR_V4
;
6162 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
6163 sizeof(struct in_addr
));
6164 } else if (p
->family
== AF_INET6
) {
6165 ip
.ipa_type
= IPADDR_V6
;
6166 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
6167 sizeof(struct in6_addr
));
6172 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
6174 zvni_gw_macip_del(ifp
, zvni
, &ip
);
6180 * Handle SVI interface going down.
6181 * SVI can be associated to either L3-VNI or L2-VNI.
6182 * For L2-VNI: At this point, this is a NOP since
6183 * the kernel deletes the neighbor entries on this SVI (if any).
6184 * We only need to update the vrf corresponding to zvni.
6185 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
6188 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
6190 zebra_l3vni_t
*zl3vni
= NULL
;
6192 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6195 /* process l3-vni down */
6196 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6198 /* remove association with svi-if */
6199 zl3vni
->svi_if
= NULL
;
6201 zebra_vni_t
*zvni
= NULL
;
6203 /* since we dont have svi corresponding to zvni, we associate it
6204 * to default vrf. Note: the corresponding neigh entries on the
6205 * SVI would have already been deleted */
6206 zvni
= zvni_from_svi(ifp
, link_if
);
6208 zvni
->vrf_id
= VRF_DEFAULT
;
6210 /* update the tenant vrf in BGP */
6211 zvni_send_add_to_client(zvni
);
6218 * Handle SVI interface coming up.
6219 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
6221 * For L2-VNI: we need to install any remote neighbors entried (used for
6223 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
6225 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
6227 zebra_vni_t
*zvni
= NULL
;
6228 zebra_l3vni_t
*zl3vni
= NULL
;
6230 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6233 /* associate with svi */
6234 zl3vni
->svi_if
= ifp
;
6236 /* process oper-up */
6237 if (is_l3vni_oper_up(zl3vni
))
6238 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6241 /* process SVI up for l2-vni */
6242 struct neigh_walk_ctx n_wctx
;
6244 zvni
= zvni_from_svi(ifp
, link_if
);
6248 if (!zvni
->vxlan_if
) {
6250 "VNI %u hash %p doesn't have intf upon SVI up",
6255 if (IS_ZEBRA_DEBUG_VXLAN
)
6257 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
6258 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
6259 vrf_id_to_name(ifp
->vrf_id
));
6261 /* update the vrf information for l2-vni and inform bgp */
6262 zvni
->vrf_id
= ifp
->vrf_id
;
6263 zvni_send_add_to_client(zvni
);
6265 /* Install any remote neighbors for this VNI. */
6266 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6268 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6276 * Handle VxLAN interface down
6278 int zebra_vxlan_if_down(struct interface
*ifp
)
6281 struct zebra_if
*zif
= NULL
;
6282 struct zebra_l2info_vxlan
*vxl
= NULL
;
6283 zebra_l3vni_t
*zl3vni
= NULL
;
6286 /* Check if EVPN is enabled. */
6287 if (!is_evpn_enabled())
6292 vxl
= &zif
->l2info
.vxl
;
6295 zl3vni
= zl3vni_lookup(vni
);
6297 /* process-if-down for l3-vni */
6298 if (IS_ZEBRA_DEBUG_VXLAN
)
6299 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
6302 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6304 /* process if-down for l2-vni */
6305 if (IS_ZEBRA_DEBUG_VXLAN
)
6306 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
6309 /* Locate hash entry; it is expected to exist. */
6310 zvni
= zvni_lookup(vni
);
6313 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6314 ifp
->name
, ifp
->ifindex
, vni
);
6318 assert(zvni
->vxlan_if
== ifp
);
6320 /* Delete this VNI from BGP. */
6321 zvni_send_del_to_client(zvni
->vni
);
6323 /* Free up all neighbors and MACs, if any. */
6324 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6325 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6327 /* Free up all remote VTEPs, if any. */
6328 zvni_vtep_del_all(zvni
, 1);
6334 * Handle VxLAN interface up - update BGP if required.
6336 int zebra_vxlan_if_up(struct interface
*ifp
)
6339 struct zebra_if
*zif
= NULL
;
6340 struct zebra_l2info_vxlan
*vxl
= NULL
;
6341 zebra_vni_t
*zvni
= NULL
;
6342 zebra_l3vni_t
*zl3vni
= NULL
;
6344 /* Check if EVPN is enabled. */
6345 if (!is_evpn_enabled())
6350 vxl
= &zif
->l2info
.vxl
;
6353 zl3vni
= zl3vni_lookup(vni
);
6356 if (IS_ZEBRA_DEBUG_VXLAN
)
6357 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp
->name
,
6360 /* we need to associate with SVI, if any, we can associate with
6361 * svi-if only after association with vxlan-intf is complete
6363 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6365 if (is_l3vni_oper_up(zl3vni
))
6366 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6368 /* Handle L2-VNI add */
6369 struct interface
*vlan_if
= NULL
;
6371 if (IS_ZEBRA_DEBUG_VXLAN
)
6372 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
6375 /* Locate hash entry; it is expected to exist. */
6376 zvni
= zvni_lookup(vni
);
6379 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6380 ifp
->name
, ifp
->ifindex
, vni
);
6384 assert(zvni
->vxlan_if
== ifp
);
6385 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6386 zif
->brslave_info
.br_if
);
6388 zvni
->vrf_id
= vlan_if
->vrf_id
;
6389 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6391 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6394 /* If part of a bridge, inform BGP about this VNI. */
6395 /* Also, read and populate local MACs and neighbors. */
6396 if (zif
->brslave_info
.br_if
) {
6397 zvni_send_add_to_client(zvni
);
6398 zvni_read_mac_neigh(zvni
, ifp
);
6406 * Handle VxLAN interface delete. Locate and remove entry in hash table
6407 * and update BGP, if required.
6409 int zebra_vxlan_if_del(struct interface
*ifp
)
6412 struct zebra_if
*zif
= NULL
;
6413 struct zebra_l2info_vxlan
*vxl
= NULL
;
6414 zebra_vni_t
*zvni
= NULL
;
6415 zebra_l3vni_t
*zl3vni
= NULL
;
6417 /* Check if EVPN is enabled. */
6418 if (!is_evpn_enabled())
6423 vxl
= &zif
->l2info
.vxl
;
6426 zl3vni
= zl3vni_lookup(vni
);
6429 if (IS_ZEBRA_DEBUG_VXLAN
)
6430 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
6433 /* process oper-down for l3-vni */
6434 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6436 /* remove the association with vxlan_if */
6437 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6438 zl3vni
->vxlan_if
= NULL
;
6441 /* process if-del for l2-vni*/
6442 if (IS_ZEBRA_DEBUG_VXLAN
)
6443 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
6446 /* Locate hash entry; it is expected to exist. */
6447 zvni
= zvni_lookup(vni
);
6450 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6451 ifp
->name
, ifp
->ifindex
, vni
);
6455 /* remove from l3-vni list */
6456 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6458 listnode_delete(zl3vni
->l2vnis
, zvni
);
6460 /* Delete VNI from BGP. */
6461 zvni_send_del_to_client(zvni
->vni
);
6463 /* Free up all neighbors and MAC, if any. */
6464 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6465 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6467 /* Free up all remote VTEPs, if any. */
6468 zvni_vtep_del_all(zvni
, 0);
6470 /* Delete the hash entry. */
6471 if (zvni_del(zvni
)) {
6472 flog_err(ZEBRA_ERR_VNI_DEL_FAILED
,
6473 "Failed to del VNI hash %p, IF %s(%u) VNI %u",
6474 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6482 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6484 int zebra_vxlan_if_update(struct interface
*ifp
, uint16_t chgflags
)
6487 struct zebra_if
*zif
= NULL
;
6488 struct zebra_l2info_vxlan
*vxl
= NULL
;
6489 zebra_vni_t
*zvni
= NULL
;
6490 zebra_l3vni_t
*zl3vni
= NULL
;
6492 /* Check if EVPN is enabled. */
6493 if (!is_evpn_enabled())
6498 vxl
= &zif
->l2info
.vxl
;
6501 zl3vni
= zl3vni_lookup(vni
);
6504 if (IS_ZEBRA_DEBUG_VXLAN
)
6506 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6507 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6508 inet_ntoa(vxl
->vtep_ip
),
6509 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6511 /* Removed from bridge? Cleanup and return */
6512 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6513 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6514 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6518 /* access-vlan change - process oper down, associate with new
6519 * svi_if and then process oper up again
6521 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6522 if (if_is_operative(ifp
)) {
6523 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6524 zl3vni
->svi_if
= NULL
;
6525 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6526 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6527 if (is_l3vni_oper_up(zl3vni
))
6528 zebra_vxlan_process_l3vni_oper_up(
6534 * local-ip change - process oper down, associate with new
6535 * local-ip and then process oper up again
6537 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
6538 if (if_is_operative(ifp
)) {
6539 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6540 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6541 if (is_l3vni_oper_up(zl3vni
))
6542 zebra_vxlan_process_l3vni_oper_up(
6547 /* Update local tunnel IP. */
6548 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6550 /* if we have a valid new master, process l3-vni oper up */
6551 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6552 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
6553 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6557 /* Update VNI hash. */
6558 zvni
= zvni_lookup(vni
);
6561 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6562 ifp
->name
, ifp
->ifindex
, vni
);
6566 if (IS_ZEBRA_DEBUG_VXLAN
)
6568 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6569 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6570 inet_ntoa(vxl
->vtep_ip
),
6571 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6573 /* Removed from bridge? Cleanup and return */
6574 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6575 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6576 /* Delete from client, remove all remote VTEPs */
6577 /* Also, free up all MACs and neighbors. */
6578 zvni_send_del_to_client(zvni
->vni
);
6579 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6580 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6581 zvni_vtep_del_all(zvni
, 1);
6585 /* Handle other changes. */
6586 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6587 /* Remove all existing local neigh and MACs for this VNI
6588 * (including from BGP)
6590 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6591 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6594 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6595 zvni
->vxlan_if
= ifp
;
6597 /* Take further actions needed.
6598 * Note that if we are here, there is a change of interest.
6600 /* If down or not mapped to a bridge, we're done. */
6601 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6604 /* Inform BGP, if there is a change of interest. */
6606 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6607 zvni_send_add_to_client(zvni
);
6609 /* If there is a valid new master or a VLAN mapping change,
6610 * read and populate local MACs and neighbors.
6611 * Also, reinstall any remote MACs and neighbors
6612 * for this VNI (based on new VLAN).
6614 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6615 zvni_read_mac_neigh(zvni
, ifp
);
6616 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6617 struct mac_walk_ctx m_wctx
;
6618 struct neigh_walk_ctx n_wctx
;
6620 zvni_read_mac_neigh(zvni
, ifp
);
6622 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6624 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
,
6627 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6629 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6638 * Handle VxLAN interface add.
6640 int zebra_vxlan_if_add(struct interface
*ifp
)
6643 struct zebra_if
*zif
= NULL
;
6644 struct zebra_l2info_vxlan
*vxl
= NULL
;
6645 zebra_vni_t
*zvni
= NULL
;
6646 zebra_l3vni_t
*zl3vni
= NULL
;
6648 /* Check if EVPN is enabled. */
6649 if (!is_evpn_enabled())
6654 vxl
= &zif
->l2info
.vxl
;
6657 zl3vni
= zl3vni_lookup(vni
);
6660 /* process if-add for l3-vni*/
6661 if (IS_ZEBRA_DEBUG_VXLAN
)
6663 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6664 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6665 inet_ntoa(vxl
->vtep_ip
),
6666 zif
->brslave_info
.bridge_ifindex
);
6668 /* associate with vxlan_if */
6669 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6670 zl3vni
->vxlan_if
= ifp
;
6672 /* Associate with SVI, if any. We can associate with svi-if only
6673 * after association with vxlan_if is complete */
6674 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6676 if (is_l3vni_oper_up(zl3vni
))
6677 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6680 /* process if-add for l2-vni */
6681 struct interface
*vlan_if
= NULL
;
6683 /* Create or update VNI hash. */
6684 zvni
= zvni_lookup(vni
);
6686 zvni
= zvni_add(vni
);
6689 ZEBRA_ERR_VNI_ADD_FAILED
,
6690 "Failed to add VNI hash, IF %s(%u) VNI %u",
6691 ifp
->name
, ifp
->ifindex
, vni
);
6696 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6697 zvni
->vxlan_if
= ifp
;
6698 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6699 zif
->brslave_info
.br_if
);
6701 zvni
->vrf_id
= vlan_if
->vrf_id
;
6702 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6704 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6707 if (IS_ZEBRA_DEBUG_VXLAN
)
6709 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6711 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
)
6713 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6714 inet_ntoa(vxl
->vtep_ip
),
6715 zif
->brslave_info
.bridge_ifindex
);
6717 /* If down or not mapped to a bridge, we're done. */
6718 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6722 zvni_send_add_to_client(zvni
);
6724 /* Read and populate local MACs and neighbors */
6725 zvni_read_mac_neigh(zvni
, ifp
);
6731 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
, vni_t vni
,
6732 char *err
, int err_str_sz
, int filter
,
6735 zebra_l3vni_t
*zl3vni
= NULL
;
6736 struct zebra_vrf
*zvrf_default
= NULL
;
6738 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6742 if (IS_ZEBRA_DEBUG_VXLAN
)
6743 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf
), vni
,
6744 add
? "ADD" : "DEL");
6748 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6750 /* check if the vni is already present under zvrf */
6752 snprintf(err
, err_str_sz
,
6753 "VNI is already configured under the vrf");
6757 /* check if this VNI is already present in the system */
6758 zl3vni
= zl3vni_lookup(vni
);
6760 snprintf(err
, err_str_sz
,
6761 "VNI is already configured as L3-VNI");
6765 /* add the L3-VNI to the global table */
6766 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6768 snprintf(err
, err_str_sz
, "Could not add L3-VNI");
6772 /* associate the vrf with vni */
6775 /* set the filter in l3vni to denote if we are using l3vni only
6779 SET_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
);
6781 /* associate with vxlan-intf;
6782 * we need to associate with the vxlan-intf first
6784 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6786 /* associate with corresponding SVI interface, we can associate
6787 * with svi-if only after vxlan interface association is
6790 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6792 /* formulate l2vni list */
6793 hash_iterate(zvrf_default
->vni_table
, zvni_add_to_l3vni_list
,
6796 if (is_l3vni_oper_up(zl3vni
))
6797 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6800 zl3vni
= zl3vni_lookup(vni
);
6802 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6806 if (filter
&& !CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)) {
6807 snprintf(err
, ERR_STR_SZ
,
6808 "prefix-routes-only is not set for the vni");
6812 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6814 /* delete and uninstall all rmacs */
6815 hash_iterate(zl3vni
->rmac_table
, zl3vni_del_rmac_hash_entry
,
6818 /* delete and uninstall all next-hops */
6819 hash_iterate(zl3vni
->nh_table
, zl3vni_del_nh_hash_entry
,
6825 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6830 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6832 zebra_l3vni_t
*zl3vni
= NULL
;
6835 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6839 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6840 if (is_l3vni_oper_up(zl3vni
))
6841 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6845 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6847 zebra_l3vni_t
*zl3vni
= NULL
;
6850 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6854 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6855 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6859 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6861 zebra_l3vni_t
*zl3vni
= NULL
;
6865 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6871 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6877 * Handle message from client to enable/disable advertisement of g/w macip
6880 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS
)
6885 zebra_vni_t
*zvni
= NULL
;
6886 struct interface
*ifp
= NULL
;
6887 struct zebra_if
*zif
= NULL
;
6888 struct zebra_l2info_vxlan zl2_info
;
6889 struct interface
*vlan_if
= NULL
;
6891 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6892 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
6898 STREAM_GETC(s
, advertise
);
6899 vni
= stream_get3(s
);
6901 zvni
= zvni_lookup(vni
);
6905 if (zvni
->advertise_subnet
== advertise
)
6908 if (IS_ZEBRA_DEBUG_VXLAN
)
6909 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
6910 advertise
? "enabled" : "disabled", vni
,
6911 zvni
->advertise_subnet
? "enabled" : "disabled");
6914 zvni
->advertise_subnet
= advertise
;
6916 ifp
= zvni
->vxlan_if
;
6922 /* If down or not mapped to a bridge, we're done. */
6923 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6926 zl2_info
= zif
->l2info
.vxl
;
6929 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
6933 if (zvni
->advertise_subnet
)
6934 zvni_advertise_subnet(zvni
, vlan_if
, 1);
6936 zvni_advertise_subnet(zvni
, vlan_if
, 0);
6943 * Handle message from client to enable/disable advertisement of g/w macip
6946 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS
)
6951 zebra_vni_t
*zvni
= NULL
;
6952 struct interface
*ifp
= NULL
;
6954 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6955 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
6961 STREAM_GETC(s
, advertise
);
6962 STREAM_GETL(s
, vni
);
6965 if (IS_ZEBRA_DEBUG_VXLAN
)
6966 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6967 advertise
? "enabled" : "disabled",
6968 advertise_gw_macip_enabled(NULL
)
6972 if (zvrf
->advertise_gw_macip
== advertise
)
6975 zvrf
->advertise_gw_macip
= advertise
;
6977 if (advertise_gw_macip_enabled(zvni
))
6978 hash_iterate(zvrf
->vni_table
,
6979 zvni_gw_macip_add_for_vni_hash
, NULL
);
6981 hash_iterate(zvrf
->vni_table
,
6982 zvni_gw_macip_del_for_vni_hash
, NULL
);
6985 struct zebra_if
*zif
= NULL
;
6986 struct zebra_l2info_vxlan zl2_info
;
6987 struct interface
*vlan_if
= NULL
;
6988 struct interface
*vrr_if
= NULL
;
6990 zvni
= zvni_lookup(vni
);
6994 if (IS_ZEBRA_DEBUG_VXLAN
)
6996 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6997 advertise
? "enabled" : "disabled", vni
,
6998 advertise_gw_macip_enabled(zvni
) ? "enabled"
7001 if (zvni
->advertise_gw_macip
== advertise
)
7004 zvni
->advertise_gw_macip
= advertise
;
7006 ifp
= zvni
->vxlan_if
;
7012 /* If down or not mapped to a bridge, we're done. */
7013 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
7016 zl2_info
= zif
->l2info
.vxl
;
7018 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
7019 zif
->brslave_info
.br_if
);
7023 if (advertise_gw_macip_enabled(zvni
)) {
7024 /* Add primary SVI MAC-IP */
7025 zvni_add_macip_for_intf(vlan_if
, zvni
);
7027 /* Add VRR MAC-IP - if any*/
7028 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7030 zvni_add_macip_for_intf(vrr_if
, zvni
);
7032 /* Del primary MAC-IP */
7033 zvni_del_macip_for_intf(vlan_if
, zvni
);
7035 /* Del VRR MAC-IP - if any*/
7036 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7038 zvni_del_macip_for_intf(vrr_if
, zvni
);
7048 * Handle message from client to learn (or stop learning) about VNIs and MACs.
7049 * When enabled, the VNI hash table will be built and MAC FDB table read;
7050 * when disabled, the entries should be deleted and remote VTEPs and MACs
7051 * uninstalled from the kernel.
7053 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS
)
7055 struct stream
*s
= NULL
;
7057 struct zebra_ns
*zns
= NULL
;
7059 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
7060 zlog_debug("EVPN VNI Adv for non-default VRF %u",
7066 STREAM_GETC(s
, advertise
);
7068 if (IS_ZEBRA_DEBUG_VXLAN
)
7069 zlog_debug("EVPN VNI Adv %s, currently %s",
7070 advertise
? "enabled" : "disabled",
7071 is_evpn_enabled() ? "enabled" : "disabled");
7073 if (zvrf
->advertise_all_vni
== advertise
)
7076 zvrf
->advertise_all_vni
= advertise
;
7077 if (is_evpn_enabled()) {
7078 /* Build VNI hash table and inform BGP. */
7079 zvni_build_hash_table();
7081 /* Add all SVI (L3 GW) MACs to BGP*/
7082 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
7085 /* Read the MAC FDB */
7086 macfdb_read(zvrf
->zns
);
7088 /* Read neighbors */
7089 neigh_read(zvrf
->zns
);
7091 /* Cleanup VTEPs for all VNIs - uninstall from
7092 * kernel and free entries.
7094 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7096 /* cleanup all l3vnis */
7097 zns
= zebra_ns_lookup(NS_DEFAULT
);
7101 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
7109 * Allocate VNI hash table for this VRF and do other initialization.
7110 * NOTE: Currently supported only for default VRF.
7112 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
7116 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
7117 "Zebra VRF VNI Table");
7120 /* Cleanup VNI info, but don't free the table. */
7121 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
7125 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7128 /* Close all VNI handling */
7129 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
7133 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7134 hash_free(zvrf
->vni_table
);
7137 /* init the l3vni table */
7138 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
7140 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
7141 "Zebra VRF L3 VNI table");
7144 /* free l3vni table */
7145 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
7147 hash_free(zns
->l3vni_table
);
7150 /* get the l3vni svi ifindex */
7151 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
7153 zebra_l3vni_t
*zl3vni
= NULL
;
7155 zl3vni
= zl3vni_from_vrf(vrf_id
);
7156 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
7159 return zl3vni
->svi_if
->ifindex
;