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
)
211 zlog_debug("%s: Unexpected family type: %d",
212 __PRETTY_FUNCTION__
, hle1
->p
.family
);
216 RB_GENERATE(host_rb_tree_entry
, host_rb_entry
, hl_entry
, host_rb_entry_compare
);
218 static uint32_t rb_host_count(struct host_rb_tree_entry
*hrbe
)
220 struct host_rb_entry
*hle
;
223 RB_FOREACH (hle
, host_rb_tree_entry
, hrbe
)
230 * Return number of valid MACs in a VNI's MAC hash table - all
231 * remote MACs and non-internal (auto) local MACs count.
233 static uint32_t num_valid_macs(zebra_vni_t
*zvni
)
236 uint32_t num_macs
= 0;
238 struct hash_backet
*hb
;
241 hash
= zvni
->mac_table
;
244 for (i
= 0; i
< hash
->size
; i
++) {
245 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
246 mac
= (zebra_mac_t
*)hb
->data
;
247 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
248 || CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
249 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
257 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
259 struct zebra_vrf
*zvrf
;
261 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
262 if (zvrf
&& zvrf
->advertise_gw_macip
)
265 if (zvni
&& zvni
->advertise_gw_macip
)
272 * Helper function to determine maximum width of neighbor IP address for
273 * display - just because we're dealing with IPv6 addresses that can
276 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
279 char buf
[INET6_ADDRSTRLEN
];
280 struct neigh_walk_ctx
*wctx
= ctxt
;
283 n
= (zebra_neigh_t
*)backet
->data
;
285 ipaddr2str(&n
->ip
, buf
, sizeof(buf
)), width
= strlen(buf
);
286 if (width
> wctx
->addr_width
)
287 wctx
->addr_width
= width
;
292 * Print a specific neighbor entry.
294 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
297 char buf1
[ETHER_ADDR_STRLEN
];
298 char buf2
[INET6_ADDRSTRLEN
];
299 const char *type_str
;
300 const char *state_str
;
301 bool flags_present
= false;
303 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
304 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
305 type_str
= CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) ?
307 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
308 vty
= (struct vty
*)ctxt
;
310 vty_out(vty
, "IP: %s\n",
311 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
312 vty_out(vty
, " Type: %s\n", type_str
);
313 vty_out(vty
, " State: %s\n", state_str
);
314 vty_out(vty
, " MAC: %s\n",
315 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
317 json_object_string_add(json
, "ip", buf2
);
318 json_object_string_add(json
, "type", type_str
);
319 json_object_string_add(json
, "state", state_str
);
320 json_object_string_add(json
, "mac", buf1
);
322 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
324 vty_out(vty
, " Remote VTEP: %s\n",
325 inet_ntoa(n
->r_vtep_ip
));
327 json_object_string_add(json
, "remoteVtep",
328 inet_ntoa(n
->r_vtep_ip
));
330 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
332 vty_out(vty
, " Flags: Default-gateway");
333 flags_present
= true;
335 json_object_boolean_true_add(json
, "defaultGateway");
337 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)) {
340 flags_present
? " ,Router" : " Flags: Router");
341 flags_present
= true;
347 vty_out(vty
, " Local Seq: %u Remote Seq: %u\n",
348 n
->loc_seq
, n
->rem_seq
);
350 json_object_int_add(json
, "localSequence", n
->loc_seq
);
351 json_object_int_add(json
, "remoteSequence", n
->rem_seq
);
356 * Print neighbor hash entry - called for display of all neighbors.
358 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
361 json_object
*json_vni
= NULL
, *json_row
= NULL
;
363 char buf1
[ETHER_ADDR_STRLEN
];
364 char buf2
[INET6_ADDRSTRLEN
];
365 struct neigh_walk_ctx
*wctx
= ctxt
;
366 const char *state_str
;
369 json_vni
= wctx
->json
;
370 n
= (zebra_neigh_t
*)backet
->data
;
373 json_row
= json_object_new_object();
375 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
376 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
377 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
378 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
379 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)
382 if (json_vni
== NULL
) {
383 vty_out(vty
, "%*s %-6s %-8s %-17s\n",
384 -wctx
->addr_width
, buf2
, "local",
387 json_object_string_add(json_row
, "type", "local");
388 json_object_string_add(json_row
, "state", state_str
);
389 json_object_string_add(json_row
, "mac", buf1
);
390 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
391 json_object_boolean_true_add(
392 json_row
, "defaultGateway");
393 json_object_int_add(json_row
, "localSequence",
395 json_object_int_add(json_row
, "remoteSequence",
399 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
400 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
401 !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))
404 if (json_vni
== NULL
) {
405 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
408 "%*s %-6s %-8s %-17s %-21s\n",
409 -wctx
->addr_width
, "Neighbor", "Type",
410 "State", "MAC", "Remote VTEP");
411 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
412 -wctx
->addr_width
, buf2
, "remote", state_str
,
413 buf1
, inet_ntoa(n
->r_vtep_ip
));
415 json_object_string_add(json_row
, "type", "remote");
416 json_object_string_add(json_row
, "state", state_str
);
417 json_object_string_add(json_row
, "mac", buf1
);
418 json_object_string_add(json_row
, "remoteVtep",
419 inet_ntoa(n
->r_vtep_ip
));
420 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
421 json_object_boolean_true_add(json_row
,
423 json_object_int_add(json_row
, "localSequence",
425 json_object_int_add(json_row
, "remoteSequence",
432 json_object_object_add(json_vni
, buf2
, json_row
);
436 * Print neighbors for all VNI.
438 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
442 json_object
*json
= NULL
, *json_vni
= NULL
;
445 struct neigh_walk_ctx wctx
;
446 char vni_str
[VNI_STR_LEN
];
448 vty
= (struct vty
*)args
[0];
449 json
= (json_object
*)args
[1];
451 zvni
= (zebra_vni_t
*)backet
->data
;
453 num_neigh
= hashcount(zvni
->neigh_table
);
456 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
457 zvni
->vni
, num_neigh
);
459 json_vni
= json_object_new_object();
460 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
461 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
465 json_object_object_add(json
, vni_str
, json_vni
);
469 /* Since we have IPv6 addresses to deal with which can vary widely in
470 * size, we try to be a bit more elegant in display by first computing
473 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
476 wctx
.addr_width
= 15;
477 wctx
.json
= json_vni
;
478 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
481 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
482 -wctx
.addr_width
, "IP", "Type",
483 "State", "MAC", "Remote VTEP");
485 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
488 json_object_object_add(json
, vni_str
, json_vni
);
491 /* print a specific next hop for an l3vni */
492 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
495 char buf1
[ETHER_ADDR_STRLEN
];
496 char buf2
[INET6_ADDRSTRLEN
];
497 json_object
*json_hosts
= NULL
;
498 struct host_rb_entry
*hle
;
501 vty_out(vty
, "Ip: %s\n",
502 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
503 vty_out(vty
, " RMAC: %s\n",
504 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
505 vty_out(vty
, " Refcount: %d\n",
506 rb_host_count(&n
->host_rb
));
507 vty_out(vty
, " Prefixes:\n");
508 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
509 vty_out(vty
, " %s\n",
510 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
512 json_hosts
= json_object_new_array();
513 json_object_string_add(
514 json
, "ip", ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)));
515 json_object_string_add(
517 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)));
518 json_object_int_add(json
, "refCount",
519 rb_host_count(&n
->host_rb
));
520 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
521 json_object_array_add(json_hosts
,
522 json_object_new_string(prefix2str(
523 &hle
->p
, buf2
, sizeof(buf2
))));
524 json_object_object_add(json
, "prefixList", json_hosts
);
528 /* Print a specific RMAC entry */
529 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
532 char buf1
[ETHER_ADDR_STRLEN
];
533 char buf2
[PREFIX_STRLEN
];
534 json_object
*json_hosts
= NULL
;
535 struct host_rb_entry
*hle
;
538 vty_out(vty
, "MAC: %s\n",
539 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
540 vty_out(vty
, " Remote VTEP: %s\n",
541 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
542 vty_out(vty
, " Refcount: %d\n", rb_host_count(&zrmac
->host_rb
));
543 vty_out(vty
, " Prefixes:\n");
544 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
545 vty_out(vty
, " %s\n",
546 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
548 json_hosts
= json_object_new_array();
549 json_object_string_add(
551 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
552 json_object_string_add(json
, "vtepIp",
553 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
554 json_object_int_add(json
, "refCount",
555 rb_host_count(&zrmac
->host_rb
));
556 json_object_int_add(json
, "localSequence", zrmac
->loc_seq
);
557 json_object_int_add(json
, "remoteSequence", zrmac
->rem_seq
);
558 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
559 json_object_array_add(
561 json_object_new_string(prefix2str(
562 &hle
->p
, buf2
, sizeof(buf2
))));
563 json_object_object_add(json
, "prefixList", json_hosts
);
568 * Print a specific MAC entry.
570 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
573 zebra_neigh_t
*n
= NULL
;
574 struct listnode
*node
= NULL
;
576 char buf2
[INET6_ADDRSTRLEN
];
578 vty
= (struct vty
*)ctxt
;
579 vty_out(vty
, "MAC: %s",
580 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
581 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
582 struct zebra_ns
*zns
;
583 struct interface
*ifp
;
586 ifindex
= mac
->fwd_info
.local
.ifindex
;
587 zns
= zebra_ns_lookup(NS_DEFAULT
);
588 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
589 if (!ifp
) // unexpected
591 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
592 if (mac
->fwd_info
.local
.vid
)
593 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
594 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
595 vty_out(vty
, " Remote VTEP: %s",
596 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
597 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
598 vty_out(vty
, " Auto Mac ");
601 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
602 vty_out(vty
, " Sticky Mac ");
604 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
605 vty_out(vty
, " Default-gateway Mac ");
607 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
))
608 vty_out(vty
, " Remote-gateway Mac ");
611 vty_out(vty
, " Local Seq: %u Remote Seq: %u",
612 mac
->loc_seq
, mac
->rem_seq
);
615 /* print all the associated neigh */
616 vty_out(vty
, " Neighbors:\n");
617 if (!listcount(mac
->neigh_list
))
618 vty_out(vty
, " No Neighbors\n");
620 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
621 vty_out(vty
, " %s %s\n",
622 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
623 (IS_ZEBRA_NEIGH_ACTIVE(n
)
624 ? "Active" : "Inactive"));
632 * Print MAC hash entry - called for display of all MACs.
634 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
637 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
640 struct mac_walk_ctx
*wctx
= ctxt
;
643 json_mac_hdr
= wctx
->json
;
644 mac
= (zebra_mac_t
*)backet
->data
;
646 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
649 json_mac
= json_object_new_object();
651 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
652 struct zebra_ns
*zns
;
654 struct interface
*ifp
;
657 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)
660 zns
= zebra_ns_lookup(NS_DEFAULT
);
661 ifindex
= mac
->fwd_info
.local
.ifindex
;
662 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
663 if (!ifp
) // unexpected
665 vid
= mac
->fwd_info
.local
.vid
;
666 if (json_mac_hdr
== NULL
)
667 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
670 json_object_string_add(json_mac
, "type", "local");
671 json_object_string_add(json_mac
, "intf", ifp
->name
);
674 if (json_mac_hdr
== NULL
)
675 vty_out(vty
, " %-5u", vid
);
677 json_object_int_add(json_mac
, "vlan", vid
);
679 if (json_mac_hdr
== NULL
) {
682 json_object_int_add(json_mac
, "localSequence",
684 json_object_int_add(json_mac
, "remoteSequence",
686 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
691 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
693 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
694 !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
698 if (json_mac_hdr
== NULL
) {
699 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
700 (wctx
->count
== 0)) {
701 vty_out(vty
, "\nVNI %u\n\n", wctx
->zvni
->vni
);
702 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC",
703 "Type", "Intf/Remote VTEP", "VLAN");
705 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
, "remote",
706 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
708 json_object_string_add(json_mac
, "type", "remote");
709 json_object_string_add(json_mac
, "remoteVtep",
710 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
711 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
712 json_object_int_add(json_mac
, "localSequence",
714 json_object_int_add(json_mac
, "remoteSequence",
723 * Print MACs for all VNI.
725 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
728 json_object
*json
= NULL
, *json_vni
= NULL
;
729 json_object
*json_mac
= NULL
;
732 struct mac_walk_ctx
*wctx
= ctxt
;
733 char vni_str
[VNI_STR_LEN
];
735 vty
= (struct vty
*)wctx
->vty
;
736 json
= (struct json_object
*)wctx
->json
;
738 zvni
= (zebra_vni_t
*)backet
->data
;
741 /*We are iterating over a new VNI, set the count to 0*/
744 num_macs
= num_valid_macs(zvni
);
749 json_vni
= json_object_new_object();
750 json_mac
= json_object_new_object();
751 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
754 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
756 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
757 zvni
->vni
, num_macs
);
758 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
759 "Intf/Remote VTEP", "VLAN");
761 json_object_int_add(json_vni
, "numMacs", num_macs
);
763 /* assign per-vni to wctx->json object to fill macs
764 * under the vni. Re-assign primary json object to fill
765 * next vni information.
767 wctx
->json
= json_mac
;
768 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
772 json_object_object_add(json_vni
, "macs", json_mac
);
773 json_object_object_add(json
, vni_str
, json_vni
);
777 static void zl3vni_print_nh_hash(struct hash_backet
*backet
, void *ctx
)
779 struct nh_walk_ctx
*wctx
= NULL
;
780 struct vty
*vty
= NULL
;
781 struct json_object
*json_vni
= NULL
;
782 struct json_object
*json_nh
= NULL
;
783 zebra_neigh_t
*n
= NULL
;
784 char buf1
[ETHER_ADDR_STRLEN
];
785 char buf2
[INET6_ADDRSTRLEN
];
787 wctx
= (struct nh_walk_ctx
*)ctx
;
789 json_vni
= wctx
->json
;
791 json_nh
= json_object_new_object();
792 n
= (zebra_neigh_t
*)backet
->data
;
795 vty_out(vty
, "%-15s %-17s\n",
796 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
797 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
799 json_object_string_add(json_nh
, "nexthopIp",
800 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
801 json_object_string_add(
802 json_nh
, "routerMac",
803 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
804 json_object_object_add(json_vni
,
805 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
810 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
813 struct vty
*vty
= NULL
;
814 json_object
*json
= NULL
;
815 json_object
*json_vni
= NULL
;
816 zebra_l3vni_t
*zl3vni
= NULL
;
818 struct nh_walk_ctx wctx
;
819 char vni_str
[VNI_STR_LEN
];
821 vty
= (struct vty
*)args
[0];
822 json
= (struct json_object
*)args
[1];
824 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
826 num_nh
= hashcount(zl3vni
->nh_table
);
831 json_vni
= json_object_new_object();
832 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
836 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n", zl3vni
->vni
, num_nh
);
837 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
839 json_object_int_add(json_vni
, "numNextHops", num_nh
);
841 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
843 wctx
.json
= json_vni
;
844 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
846 json_object_object_add(json
, vni_str
, json_vni
);
849 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
852 struct vty
*vty
= NULL
;
853 json_object
*json
= NULL
;
854 json_object
*json_vni
= NULL
;
855 zebra_l3vni_t
*zl3vni
= NULL
;
857 struct rmac_walk_ctx wctx
;
858 char vni_str
[VNI_STR_LEN
];
860 vty
= (struct vty
*)args
[0];
861 json
= (struct json_object
*)args
[1];
863 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
865 num_rmacs
= hashcount(zl3vni
->rmac_table
);
870 json_vni
= json_object_new_object();
871 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
875 vty_out(vty
, "\nVNI %u #RMACs %u\n\n", zl3vni
->vni
, num_rmacs
);
876 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
878 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
880 /* assign per-vni to wctx->json object to fill macs
881 * under the vni. Re-assign primary json object to fill
882 * next vni information.
884 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
886 wctx
.json
= json_vni
;
887 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
889 json_object_object_add(json
, vni_str
, json_vni
);
892 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
, void *ctx
)
894 zebra_mac_t
*zrmac
= NULL
;
895 struct rmac_walk_ctx
*wctx
= NULL
;
896 struct vty
*vty
= NULL
;
897 struct json_object
*json
= NULL
;
898 struct json_object
*json_rmac
= NULL
;
899 char buf
[ETHER_ADDR_STRLEN
];
901 wctx
= (struct rmac_walk_ctx
*)ctx
;
905 json_rmac
= json_object_new_object();
906 zrmac
= (zebra_mac_t
*)backet
->data
;
909 vty_out(vty
, "%-17s %-21s\n",
910 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
911 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
913 json_object_string_add(
914 json_rmac
, "routerMac",
915 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)));
916 json_object_string_add(json_rmac
, "vtepIp",
917 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
918 json_object_object_add(
919 json
, prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
924 /* print a specific L3 VNI entry */
925 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
927 char buf
[ETHER_ADDR_STRLEN
];
928 struct vty
*vty
= NULL
;
929 json_object
*json
= NULL
;
930 zebra_vni_t
*zvni
= NULL
;
931 json_object
*json_vni_list
= NULL
;
932 struct listnode
*node
= NULL
, *nnode
= NULL
;
938 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
939 vty_out(vty
, " Type: %s\n", "L3");
940 vty_out(vty
, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni
));
941 vty_out(vty
, " Local Vtep Ip: %s\n",
942 inet_ntoa(zl3vni
->local_vtep_ip
));
943 vty_out(vty
, " Vxlan-Intf: %s\n",
944 zl3vni_vxlan_if_name(zl3vni
));
945 vty_out(vty
, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni
));
946 vty_out(vty
, " State: %s\n", zl3vni_state2str(zl3vni
));
947 vty_out(vty
, " VNI Filter: %s\n",
948 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
949 ? "prefix-routes-only"
951 vty_out(vty
, " Router MAC: %s\n",
952 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
953 vty_out(vty
, " L2 VNIs: ");
954 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
955 vty_out(vty
, "%u ", zvni
->vni
);
958 json_vni_list
= json_object_new_array();
959 json_object_int_add(json
, "vni", zl3vni
->vni
);
960 json_object_string_add(json
, "type", "L3");
961 json_object_string_add(json
, "localVtepIp",
962 inet_ntoa(zl3vni
->local_vtep_ip
));
963 json_object_string_add(json
, "vxlanIntf",
964 zl3vni_vxlan_if_name(zl3vni
));
965 json_object_string_add(json
, "sviIntf",
966 zl3vni_svi_if_name(zl3vni
));
967 json_object_string_add(json
, "state", zl3vni_state2str(zl3vni
));
968 json_object_string_add(json
, "vrf", zl3vni_vrf_name(zl3vni
));
969 json_object_string_add(
971 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
972 json_object_string_add(
974 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
975 ? "prefix-routes-only"
977 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
978 json_object_array_add(json_vni_list
,
979 json_object_new_int(zvni
->vni
));
981 json_object_object_add(json
, "l2Vnis", json_vni_list
);
986 * Print a specific VNI entry.
988 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
994 json_object
*json
= NULL
;
995 json_object
*json_vtep_list
= NULL
;
996 json_object
*json_ip_str
= NULL
;
1002 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
1003 vty_out(vty
, " Type: %s\n", "L2");
1004 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
1006 json_object_int_add(json
, "vni", zvni
->vni
);
1007 json_object_string_add(json
, "type", "L2");
1008 json_object_string_add(json
, "vrf",
1009 vrf_id_to_name(zvni
->vrf_id
));
1012 if (!zvni
->vxlan_if
) { // unexpected
1014 vty_out(vty
, " VxLAN interface: unknown\n");
1017 num_macs
= num_valid_macs(zvni
);
1018 num_neigh
= hashcount(zvni
->neigh_table
);
1020 vty_out(vty
, " VxLAN interface: %s\n", zvni
->vxlan_if
->name
);
1021 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
1022 vty_out(vty
, " Local VTEP IP: %s\n",
1023 inet_ntoa(zvni
->local_vtep_ip
));
1025 json_object_string_add(json
, "vxlanInterface",
1026 zvni
->vxlan_if
->name
);
1027 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
1028 json_object_string_add(json
, "vtepIp",
1029 inet_ntoa(zvni
->local_vtep_ip
));
1030 json_object_string_add(json
, "advertiseGatewayMacip",
1031 zvni
->advertise_gw_macip
? "Yes" : "No");
1032 json_object_int_add(json
, "numMacs", num_macs
);
1033 json_object_int_add(json
, "numArpNd", num_neigh
);
1037 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1040 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1042 json_vtep_list
= json_object_new_array();
1043 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1045 vty_out(vty
, " %s\n",
1046 inet_ntoa(zvtep
->vtep_ip
));
1048 json_ip_str
= json_object_new_string(
1049 inet_ntoa(zvtep
->vtep_ip
));
1050 json_object_array_add(json_vtep_list
,
1055 json_object_object_add(json
, "numRemoteVteps",
1060 " Number of MACs (local and remote) known for this VNI: %u\n",
1063 " Number of ARPs (IPv4 and IPv6, local and remote) "
1064 "known for this VNI: %u\n",
1066 vty_out(vty
, " Advertise-gw-macip: %s\n",
1067 zvni
->advertise_gw_macip
? "Yes" : "No");
1071 /* print a L3 VNI hash entry */
1072 static void zl3vni_print_hash(struct hash_backet
*backet
, void *ctx
[])
1074 struct vty
*vty
= NULL
;
1075 json_object
*json
= NULL
;
1076 json_object
*json_vni
= NULL
;
1077 zebra_l3vni_t
*zl3vni
= NULL
;
1079 vty
= (struct vty
*)ctx
[0];
1080 json
= (json_object
*)ctx
[1];
1082 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1085 vty_out(vty
, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1086 zl3vni
->vni
, "L3", zl3vni_vxlan_if_name(zl3vni
),
1087 hashcount(zl3vni
->rmac_table
),
1088 hashcount(zl3vni
->nh_table
), "n/a",
1089 zl3vni_vrf_name(zl3vni
));
1091 char vni_str
[VNI_STR_LEN
];
1093 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1094 json_vni
= json_object_new_object();
1095 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1096 json_object_string_add(json_vni
, "vxlanIf",
1097 zl3vni_vxlan_if_name(zl3vni
));
1098 json_object_int_add(json_vni
, "numMacs",
1099 hashcount(zl3vni
->rmac_table
));
1100 json_object_int_add(json_vni
, "numArpNd",
1101 hashcount(zl3vni
->nh_table
));
1102 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1103 json_object_string_add(json_vni
, "type", "L3");
1104 json_object_string_add(json_vni
, "tenantVrf",
1105 zl3vni_vrf_name(zl3vni
));
1106 json_object_object_add(json
, vni_str
, json_vni
);
1111 * Print a VNI hash entry - called for display of all VNIs.
1113 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1117 zebra_vtep_t
*zvtep
;
1118 uint32_t num_vteps
= 0;
1119 uint32_t num_macs
= 0;
1120 uint32_t num_neigh
= 0;
1121 json_object
*json
= NULL
;
1122 json_object
*json_vni
= NULL
;
1123 json_object
*json_ip_str
= NULL
;
1124 json_object
*json_vtep_list
= NULL
;
1129 zvni
= (zebra_vni_t
*)backet
->data
;
1131 zvtep
= zvni
->vteps
;
1134 zvtep
= zvtep
->next
;
1137 num_macs
= num_valid_macs(zvni
);
1138 num_neigh
= hashcount(zvni
->neigh_table
);
1140 vty_out(vty
, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1142 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1143 num_macs
, num_neigh
, num_vteps
,
1144 vrf_id_to_name(zvni
->vrf_id
));
1146 char vni_str
[VNI_STR_LEN
];
1147 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1148 json_vni
= json_object_new_object();
1149 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1150 json_object_string_add(json_vni
, "type", "L2");
1151 json_object_string_add(json_vni
, "vxlanIf",
1152 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1154 json_object_int_add(json_vni
, "numMacs", num_macs
);
1155 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1156 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1157 json_object_string_add(json_vni
, "tenantVrf",
1158 vrf_id_to_name(zvni
->vrf_id
));
1160 json_vtep_list
= json_object_new_array();
1161 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1162 json_ip_str
= json_object_new_string(
1163 inet_ntoa(zvtep
->vtep_ip
));
1164 json_object_array_add(json_vtep_list
,
1167 json_object_object_add(json_vni
, "remoteVteps",
1170 json_object_object_add(json
, vni_str
, json_vni
);
1175 * Inform BGP about local MACIP.
1177 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
1178 struct ipaddr
*ip
, uint8_t flags
,
1179 uint32_t seq
, uint16_t cmd
)
1181 char buf
[ETHER_ADDR_STRLEN
];
1182 char buf2
[INET6_ADDRSTRLEN
];
1184 struct zserv
*client
= NULL
;
1185 struct stream
*s
= NULL
;
1187 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
1188 /* BGP may not be running. */
1192 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
1194 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1195 stream_putl(s
, vni
);
1196 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1199 if (IS_IPADDR_V4(ip
))
1200 ipa_len
= IPV4_MAX_BYTELEN
;
1201 else if (IS_IPADDR_V6(ip
))
1202 ipa_len
= IPV6_MAX_BYTELEN
;
1204 stream_putl(s
, ipa_len
); /* IP address length */
1206 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1208 stream_putl(s
, 0); /* Just MAC. */
1210 if (cmd
== ZEBRA_MACIP_ADD
) {
1211 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1212 stream_putl(s
, seq
); /* sequence number */
1216 /* Write packet size. */
1217 stream_putw_at(s
, 0, stream_get_endp(s
));
1219 if (IS_ZEBRA_DEBUG_VXLAN
)
1221 "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s",
1222 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del", flags
,
1223 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1224 ipaddr2str(ip
, buf2
, sizeof(buf2
)), seq
, vni
,
1225 zebra_route_string(client
->proto
));
1227 if (cmd
== ZEBRA_MACIP_ADD
)
1228 client
->macipadd_cnt
++;
1230 client
->macipdel_cnt
++;
1232 return zserv_send_message(client
, s
);
1236 * Make hash key for neighbors.
1238 static unsigned int neigh_hash_keymake(void *p
)
1240 zebra_neigh_t
*n
= p
;
1241 struct ipaddr
*ip
= &n
->ip
;
1243 if (IS_IPADDR_V4(ip
))
1244 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1246 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1247 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1251 * Compare two neighbor hash structures.
1253 static int neigh_cmp(const void *p1
, const void *p2
)
1255 const zebra_neigh_t
*n1
= p1
;
1256 const zebra_neigh_t
*n2
= p2
;
1258 if (n1
== NULL
&& n2
== NULL
)
1261 if (n1
== NULL
|| n2
== NULL
)
1264 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1268 * Callback to allocate neighbor hash entry.
1270 static void *zvni_neigh_alloc(void *p
)
1272 const zebra_neigh_t
*tmp_n
= p
;
1275 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1282 * Add neighbor entry.
1284 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1285 struct ethaddr
*mac
)
1287 zebra_neigh_t tmp_n
;
1288 zebra_neigh_t
*n
= NULL
;
1289 zebra_mac_t
*zmac
= NULL
;
1291 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1292 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1293 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1296 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1297 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1299 /* Associate the neigh to mac */
1300 zmac
= zvni_mac_lookup(zvni
, mac
);
1302 listnode_add_sort(zmac
->neigh_list
, n
);
1308 * Delete neighbor entry.
1310 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1312 zebra_neigh_t
*tmp_n
;
1313 zebra_mac_t
*zmac
= NULL
;
1315 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1317 listnode_delete(zmac
->neigh_list
, n
);
1319 /* Free the VNI hash entry and allocated memory. */
1320 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1322 XFREE(MTYPE_NEIGH
, tmp_n
);
1328 * Free neighbor hash entry (callback)
1330 static void zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1332 struct neigh_walk_ctx
*wctx
= arg
;
1333 zebra_neigh_t
*n
= backet
->data
;
1335 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1336 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1337 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1338 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1339 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1340 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1341 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1342 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1345 if (wctx
->uninstall
)
1346 zvni_neigh_uninstall(wctx
->zvni
, n
);
1348 zvni_neigh_del(wctx
->zvni
, n
);
1355 * Delete all neighbor entries from specific VTEP for a particular VNI.
1357 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1358 struct in_addr
*r_vtep_ip
)
1360 struct neigh_walk_ctx wctx
;
1362 if (!zvni
->neigh_table
)
1365 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1367 wctx
.uninstall
= uninstall
;
1368 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1369 wctx
.r_vtep_ip
= *r_vtep_ip
;
1371 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1375 * Delete all neighbor entries for this VNI.
1377 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
1380 struct neigh_walk_ctx wctx
;
1382 if (!zvni
->neigh_table
)
1385 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1387 wctx
.uninstall
= uninstall
;
1388 wctx
.upd_client
= upd_client
;
1391 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1395 * Look up neighbor hash entry.
1397 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1402 memset(&tmp
, 0, sizeof(tmp
));
1403 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1404 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1410 * Process all neighbors associated with a MAC upon the MAC being learnt
1411 * locally or undergoing any other change (such as sequence number).
1413 static void zvni_process_neigh_on_local_mac_change(zebra_vni_t
*zvni
,
1417 zebra_neigh_t
*n
= NULL
;
1418 struct listnode
*node
= NULL
;
1419 char buf
[ETHER_ADDR_STRLEN
];
1421 if (IS_ZEBRA_DEBUG_VXLAN
)
1422 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
1423 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1424 seq_change
? "CHANGE" : "ADD", zvni
->vni
);
1426 /* Walk all neighbors and mark any inactive local neighbors as
1427 * active and/or update sequence number upon a move, and inform BGP.
1428 * The action for remote neighbors is TBD.
1429 * NOTE: We can't simply uninstall remote neighbors as the kernel may
1430 * accidentally end up deleting a just-learnt local neighbor.
1432 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1433 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1434 if (IS_ZEBRA_NEIGH_INACTIVE(n
) || seq_change
) {
1435 ZEBRA_NEIGH_SET_ACTIVE(n
);
1436 n
->loc_seq
= zmac
->loc_seq
;
1437 zvni_neigh_send_add_to_client(
1438 zvni
->vni
, &n
->ip
, &n
->emac
,
1439 n
->flags
, n
->loc_seq
);
1446 * Process all neighbors associated with a local MAC upon the MAC being
1449 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1452 zebra_neigh_t
*n
= NULL
;
1453 struct listnode
*node
= NULL
;
1454 char buf
[ETHER_ADDR_STRLEN
];
1456 if (IS_ZEBRA_DEBUG_VXLAN
)
1457 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
1458 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1461 /* Walk all local neighbors and mark as inactive and inform
1463 * TBD: There is currently no handling for remote neighbors. We
1464 * don't expect them to exist, if they do, do we install the MAC
1465 * as a remote MAC and the neighbor as remote?
1467 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1468 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1469 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1470 ZEBRA_NEIGH_SET_INACTIVE(n
);
1472 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1480 * Process all neighbors associated with a MAC upon the MAC being remotely
1483 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1486 zebra_neigh_t
*n
= NULL
;
1487 struct listnode
*node
= NULL
;
1488 char buf
[ETHER_ADDR_STRLEN
];
1490 if (IS_ZEBRA_DEBUG_VXLAN
)
1491 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
1492 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1495 /* Walk all local neighbors and mark as inactive and inform
1498 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1499 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1500 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1501 ZEBRA_NEIGH_SET_INACTIVE(n
);
1503 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1511 * Process all neighbors associated with a remote MAC upon the MAC being
1514 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1517 /* NOTE: Currently a NO-OP. */
1521 * Inform BGP about local neighbor addition.
1523 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
1524 struct ethaddr
*macaddr
,
1525 uint8_t neigh_flags
,
1530 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1531 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1532 /* Set router flag (R-bit) based on local neigh entry add */
1533 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_ROUTER_FLAG
))
1534 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
1536 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1537 seq
, ZEBRA_MACIP_ADD
);
1541 * Inform BGP about local neighbor deletion.
1543 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
1544 struct ethaddr
*macaddr
, uint8_t flags
)
1546 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1547 0, ZEBRA_MACIP_DEL
);
1551 * Install remote neighbor into the kernel.
1553 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1555 struct zebra_if
*zif
;
1556 struct zebra_l2info_vxlan
*vxl
;
1557 struct interface
*vlan_if
;
1563 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1566 zif
= zvni
->vxlan_if
->info
;
1569 vxl
= &zif
->l2info
.vxl
;
1571 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1575 flags
= NTF_EXT_LEARNED
;
1576 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
1577 flags
|= NTF_ROUTER
;
1578 ZEBRA_NEIGH_SET_ACTIVE(n
);
1579 ret
= kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
, flags
);
1585 * Uninstall remote neighbor from the kernel.
1587 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1589 struct zebra_if
*zif
;
1590 struct zebra_l2info_vxlan
*vxl
;
1591 struct interface
*vlan_if
;
1593 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1596 if (!zvni
->vxlan_if
) {
1597 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
1602 zif
= zvni
->vxlan_if
->info
;
1605 vxl
= &zif
->l2info
.vxl
;
1606 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1610 ZEBRA_NEIGH_SET_INACTIVE(n
);
1612 return kernel_del_neigh(vlan_if
, &n
->ip
);
1616 * Install neighbor hash entry - called upon access VLAN change.
1618 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1621 struct neigh_walk_ctx
*wctx
= ctxt
;
1623 n
= (zebra_neigh_t
*)backet
->data
;
1625 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1626 zvni_neigh_install(wctx
->zvni
, n
);
1629 /* Get the VRR interface for SVI if any */
1630 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1632 struct zebra_vrf
*zvrf
= NULL
;
1633 struct interface
*tmp_if
= NULL
;
1634 struct zebra_if
*zif
= NULL
;
1636 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1639 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1644 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1647 if (zif
->link
== ifp
)
1654 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1656 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1657 struct connected
*c
= NULL
;
1658 struct ethaddr macaddr
;
1660 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1662 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1665 memset(&ip
, 0, sizeof(struct ipaddr
));
1666 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1669 if (c
->address
->family
== AF_INET
) {
1670 ip
.ipa_type
= IPADDR_V4
;
1671 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1672 sizeof(struct in_addr
));
1673 } else if (c
->address
->family
== AF_INET6
) {
1674 ip
.ipa_type
= IPADDR_V6
;
1675 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1676 sizeof(struct in6_addr
));
1681 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1687 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1689 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1690 struct connected
*c
= NULL
;
1691 struct ethaddr macaddr
;
1693 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1695 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1698 memset(&ip
, 0, sizeof(struct ipaddr
));
1699 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1702 if (c
->address
->family
== AF_INET
) {
1703 ip
.ipa_type
= IPADDR_V4
;
1704 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1705 sizeof(struct in_addr
));
1706 } else if (c
->address
->family
== AF_INET6
) {
1707 ip
.ipa_type
= IPADDR_V6
;
1708 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1709 sizeof(struct in6_addr
));
1714 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1720 static int zvni_advertise_subnet(zebra_vni_t
*zvni
, struct interface
*ifp
,
1723 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1724 struct connected
*c
= NULL
;
1725 struct ethaddr macaddr
;
1727 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1729 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1732 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1734 /* skip link local address */
1735 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1740 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1741 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1743 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1744 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1750 * zvni_gw_macip_add_to_client
1752 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1753 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1755 char buf
[ETHER_ADDR_STRLEN
];
1756 char buf2
[INET6_ADDRSTRLEN
];
1757 zebra_neigh_t
*n
= NULL
;
1758 zebra_mac_t
*mac
= NULL
;
1759 struct zebra_if
*zif
= NULL
;
1760 struct zebra_l2info_vxlan
*vxl
= NULL
;
1762 zif
= zvni
->vxlan_if
->info
;
1766 vxl
= &zif
->l2info
.vxl
;
1768 mac
= zvni_mac_lookup(zvni
, macaddr
);
1770 mac
= zvni_mac_add(zvni
, macaddr
);
1772 flog_err(ZEBRA_ERR_MAC_ADD_FAILED
,
1773 "Failed to add MAC %s intf %s(%u) VID %u",
1774 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1775 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1780 /* Set "local" forwarding info. */
1781 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1782 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1783 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1784 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1785 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1786 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1788 n
= zvni_neigh_lookup(zvni
, ip
);
1790 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1793 ZEBRA_ERR_MAC_ADD_FAILED
,
1794 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1795 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1796 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1797 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1802 /* Set "local" forwarding info. */
1803 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1804 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1805 ZEBRA_NEIGH_SET_ACTIVE(n
);
1806 /* Set Router flag (R-bit) */
1807 if (ip
->ipa_type
== IPADDR_V6
)
1808 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
1809 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1810 n
->ifindex
= ifp
->ifindex
;
1812 /* Only advertise in BGP if the knob is enabled */
1813 if (!advertise_gw_macip_enabled(zvni
))
1816 if (IS_ZEBRA_DEBUG_VXLAN
)
1818 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
1819 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1820 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1821 ipaddr2str(ip
, buf2
, sizeof(buf2
)), n
->flags
);
1823 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1824 n
->flags
, n
->loc_seq
);
1830 * zvni_gw_macip_del_from_client
1832 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1835 char buf1
[ETHER_ADDR_STRLEN
];
1836 char buf2
[INET6_ADDRSTRLEN
];
1837 zebra_neigh_t
*n
= NULL
;
1838 zebra_mac_t
*mac
= NULL
;
1840 /* If the neigh entry is not present nothing to do*/
1841 n
= zvni_neigh_lookup(zvni
, ip
);
1845 /* mac entry should be present */
1846 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1848 zlog_debug("MAC %s doesnt exists for neigh %s on VNI %u",
1849 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1850 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1854 /* If the entry is not local nothing to do*/
1855 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1858 /* only need to delete the entry from bgp if we sent it before */
1859 if (IS_ZEBRA_DEBUG_VXLAN
)
1861 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1862 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1863 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1864 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1866 /* Remove neighbor from BGP. */
1867 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1868 ZEBRA_MACIP_TYPE_GW
);
1870 /* Delete this neighbor entry. */
1871 zvni_neigh_del(zvni
, n
);
1873 /* see if the mac needs to be deleted as well*/
1875 zvni_deref_ip2mac(zvni
, mac
, 0);
1880 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1883 zebra_vni_t
*zvni
= NULL
;
1884 struct zebra_if
*zif
= NULL
;
1885 struct zebra_l2info_vxlan zl2_info
;
1886 struct interface
*vlan_if
= NULL
;
1887 struct interface
*vrr_if
= NULL
;
1888 struct interface
*ifp
;
1890 /* Add primary SVI MAC*/
1891 zvni
= (zebra_vni_t
*)backet
->data
;
1893 ifp
= zvni
->vxlan_if
;
1898 /* If down or not mapped to a bridge, we're done. */
1899 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1902 zl2_info
= zif
->l2info
.vxl
;
1905 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1909 /* Del primary MAC-IP */
1910 zvni_del_macip_for_intf(vlan_if
, zvni
);
1912 /* Del VRR MAC-IP - if any*/
1913 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1915 zvni_del_macip_for_intf(vrr_if
, zvni
);
1920 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1923 zebra_vni_t
*zvni
= NULL
;
1924 struct zebra_if
*zif
= NULL
;
1925 struct zebra_l2info_vxlan zl2_info
;
1926 struct interface
*vlan_if
= NULL
;
1927 struct interface
*vrr_if
= NULL
;
1928 struct interface
*ifp
= NULL
;
1930 zvni
= (zebra_vni_t
*)backet
->data
;
1932 ifp
= zvni
->vxlan_if
;
1937 /* If down or not mapped to a bridge, we're done. */
1938 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1940 zl2_info
= zif
->l2info
.vxl
;
1943 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1947 /* Add primary SVI MAC-IP */
1948 zvni_add_macip_for_intf(vlan_if
, zvni
);
1950 /* Add VRR MAC-IP - if any*/
1951 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1953 zvni_add_macip_for_intf(vrr_if
, zvni
);
1958 static int zvni_local_neigh_update(zebra_vni_t
*zvni
,
1959 struct interface
*ifp
,
1961 struct ethaddr
*macaddr
,
1962 uint8_t router_flag
)
1964 char buf
[ETHER_ADDR_STRLEN
];
1965 char buf2
[INET6_ADDRSTRLEN
];
1966 zebra_neigh_t
*n
= NULL
;
1967 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
1968 uint32_t old_mac_seq
= 0, mac_new_seq
= 0;
1969 bool upd_mac_seq
= false;
1970 bool neigh_mac_change
= false;
1971 bool check_rbit
= false;
1973 /* Check if the MAC exists. */
1974 zmac
= zvni_mac_lookup(zvni
, macaddr
);
1976 /* create a dummy MAC if the MAC is not already present */
1977 if (IS_ZEBRA_DEBUG_VXLAN
)
1979 "AUTO MAC %s created for neigh %s on VNI %u",
1980 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1981 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1983 zmac
= zvni_mac_add(zvni
, macaddr
);
1985 zlog_debug("Failed to add MAC %s VNI %u",
1986 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1991 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
1992 memset(&zmac
->flags
, 0, sizeof(uint32_t));
1993 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
1995 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
1997 * We don't change the MAC to local upon a neighbor
1998 * learn event, we wait for the explicit local MAC
1999 * learn. However, we have to compute its sequence
2000 * number in preparation for when it actually turns
2007 /* Check if the neighbor exists. */
2008 n
= zvni_neigh_lookup(zvni
, ip
);
2010 /* New neighbor - create */
2011 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2014 ZEBRA_ERR_MAC_ADD_FAILED
,
2015 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2016 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2017 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2018 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2021 /* Set "local" forwarding info. */
2022 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2023 n
->ifindex
= ifp
->ifindex
;
2026 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2027 /* If there is no MAC change, BGP isn't interested. */
2029 (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)
2033 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2035 /* Update any params and return - client doesn't
2036 * care about a purely local change.
2038 n
->ifindex
= ifp
->ifindex
;
2041 /* If the MAC has changed, need to issue a
2042 * delete first as this means a different
2043 * MACIP route. Also, need to do some
2044 * unlinking/relinking. We also need to
2045 * update the MAC's sequence number
2046 * in different situations.
2048 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2049 zvni_neigh_send_del_to_client(
2050 zvni
->vni
, &n
->ip
, &n
->emac
, 0);
2051 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2054 CHECK_FLAG(old_zmac
->flags
,
2058 neigh_mac_change
= upd_mac_seq
= true;
2060 old_zmac
->neigh_list
, n
);
2061 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2064 /* Update the forwarding info. */
2065 n
->ifindex
= ifp
->ifindex
;
2066 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2068 /* Link to new MAC */
2069 listnode_add_sort(zmac
->neigh_list
, n
);
2072 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2074 * Neighbor has moved from remote to local. Its
2075 * MAC could have also changed as part of the move.
2077 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2079 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2081 old_mac_seq
= CHECK_FLAG(
2086 neigh_mac_change
= upd_mac_seq
= true;
2087 listnode_delete(old_zmac
->neigh_list
,
2089 zvni_deref_ip2mac(zvni
, old_zmac
, 0);
2092 /* Link to new MAC */
2093 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2094 listnode_add_sort(zmac
->neigh_list
, n
);
2097 /* Mark appropriately */
2098 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2099 n
->r_vtep_ip
.s_addr
= 0;
2100 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2101 n
->ifindex
= ifp
->ifindex
;
2106 /* If MAC was previously remote, or the neighbor had a different
2107 * MAC earlier, recompute the sequence number.
2110 uint32_t seq1
, seq2
;
2112 seq1
= CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
) ?
2113 zmac
->rem_seq
+ 1 : zmac
->loc_seq
;
2114 seq2
= neigh_mac_change
? old_mac_seq
+ 1 : 0;
2115 mac_new_seq
= zmac
->loc_seq
< MAX(seq1
, seq2
) ?
2116 MAX(seq1
, seq2
) : zmac
->loc_seq
;
2119 /*Mark Router flag (R-bit) */
2121 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2123 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2125 /* Before we program this in BGP, we need to check if MAC is locally
2126 * learnt. If not, force neighbor to be inactive and reset its seq.
2128 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
2129 ZEBRA_NEIGH_SET_INACTIVE(n
);
2131 zmac
->loc_seq
= mac_new_seq
;
2138 /* If the MAC's sequence number has changed, inform the MAC and all
2139 * neighbors associated with the MAC to BGP, else just inform this
2142 if (upd_mac_seq
&& zmac
->loc_seq
!= mac_new_seq
) {
2143 if (IS_ZEBRA_DEBUG_VXLAN
)
2144 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
2145 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2146 zvni
->vni
, zmac
->loc_seq
, mac_new_seq
);
2147 zmac
->loc_seq
= mac_new_seq
;
2148 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
2149 zmac
->flags
, zmac
->loc_seq
))
2151 zvni_process_neigh_on_local_mac_change(zvni
, zmac
, 1);
2155 ZEBRA_NEIGH_SET_ACTIVE(n
);
2156 n
->loc_seq
= zmac
->loc_seq
;
2158 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
2159 n
->flags
, n
->loc_seq
);
2162 static int zvni_remote_neigh_update(zebra_vni_t
*zvni
,
2163 struct interface
*ifp
,
2165 struct ethaddr
*macaddr
,
2168 char buf
[ETHER_ADDR_STRLEN
];
2169 char buf2
[INET6_ADDRSTRLEN
];
2170 zebra_neigh_t
*n
= NULL
;
2171 zebra_mac_t
*zmac
= NULL
;
2173 /* If the neighbor is unknown, there is no further action. */
2174 n
= zvni_neigh_lookup(zvni
, ip
);
2178 /* If a remote entry, see if it needs to be refreshed */
2179 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2181 if (state
& NUD_STALE
)
2182 zvni_neigh_install(zvni
, n
);
2185 /* We got a "remote" neighbor notification for an entry
2186 * we think is local. This can happen in a multihoming
2187 * scenario - but only if the MAC is already "remote".
2188 * Just mark our entry as "remote".
2190 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2191 if (!zmac
|| !CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2193 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
2194 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
2195 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2200 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2201 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2202 n
->r_vtep_ip
= zmac
->fwd_info
.r_vtep_ip
;
2209 * Make hash key for MAC.
2211 static unsigned int mac_hash_keymake(void *p
)
2213 zebra_mac_t
*pmac
= p
;
2214 const void *pnt
= (void *)pmac
->macaddr
.octet
;
2216 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
2220 * Compare two MAC addresses.
2222 static int mac_cmp(const void *p1
, const void *p2
)
2224 const zebra_mac_t
*pmac1
= p1
;
2225 const zebra_mac_t
*pmac2
= p2
;
2227 if (pmac1
== NULL
&& pmac2
== NULL
)
2230 if (pmac1
== NULL
|| pmac2
== NULL
)
2233 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
, ETH_ALEN
)
2238 * Callback to allocate MAC hash entry.
2240 static void *zvni_mac_alloc(void *p
)
2242 const zebra_mac_t
*tmp_mac
= p
;
2245 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2248 return ((void *)mac
);
2254 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
2256 zebra_mac_t tmp_mac
;
2257 zebra_mac_t
*mac
= NULL
;
2259 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
2260 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
2261 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
2264 mac
->neigh_list
= list_new();
2265 mac
->neigh_list
->cmp
= (int (*)(void *, void *))neigh_cmp
;
2273 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2275 zebra_mac_t
*tmp_mac
;
2277 list_delete_and_null(&mac
->neigh_list
);
2279 /* Free the VNI hash entry and allocated memory. */
2280 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2282 XFREE(MTYPE_MAC
, tmp_mac
);
2288 * Free MAC hash entry (callback)
2290 static void zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2292 struct mac_walk_ctx
*wctx
= arg
;
2293 zebra_mac_t
*mac
= backet
->data
;
2295 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2296 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2297 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2298 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2299 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2300 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2301 &wctx
->r_vtep_ip
))) {
2302 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2303 zvni_mac_send_del_to_client(wctx
->zvni
->vni
,
2304 &mac
->macaddr
, mac
->flags
);
2307 if (wctx
->uninstall
)
2308 zvni_mac_uninstall(wctx
->zvni
, mac
, 0);
2310 zvni_mac_del(wctx
->zvni
, mac
);
2317 * Delete all MAC entries from specific VTEP for a particular VNI.
2319 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2320 struct in_addr
*r_vtep_ip
)
2322 struct mac_walk_ctx wctx
;
2324 if (!zvni
->mac_table
)
2327 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2329 wctx
.uninstall
= uninstall
;
2330 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2331 wctx
.r_vtep_ip
= *r_vtep_ip
;
2333 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2337 * Delete all MAC entries for this VNI.
2339 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
2342 struct mac_walk_ctx wctx
;
2344 if (!zvni
->mac_table
)
2347 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2349 wctx
.uninstall
= uninstall
;
2350 wctx
.upd_client
= upd_client
;
2353 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2357 * Look up MAC hash entry.
2359 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2364 memset(&tmp
, 0, sizeof(tmp
));
2365 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2366 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2372 * Inform BGP about local MAC addition.
2374 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2375 uint8_t mac_flags
, uint32_t seq
)
2379 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2380 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2381 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2382 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2384 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2385 seq
, ZEBRA_MACIP_ADD
);
2389 * Inform BGP about local MAC deletion.
2391 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2396 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2397 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2398 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2399 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2401 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2402 0, ZEBRA_MACIP_DEL
);
2406 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2407 * notifications, to see if they are of interest.
2409 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2410 struct interface
*br_if
, vlanid_t vid
)
2412 struct zebra_ns
*zns
;
2413 struct route_node
*rn
;
2414 struct interface
*tmp_if
= NULL
;
2415 struct zebra_if
*zif
;
2416 struct zebra_l2info_bridge
*br
;
2417 struct zebra_l2info_vxlan
*vxl
= NULL
;
2418 uint8_t bridge_vlan_aware
;
2422 /* Determine if bridge is VLAN-aware or not */
2425 br
= &zif
->l2info
.br
;
2426 bridge_vlan_aware
= br
->vlan_aware
;
2428 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2429 /* TODO: Optimize with a hash. */
2430 zns
= zebra_ns_lookup(NS_DEFAULT
);
2431 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2432 tmp_if
= (struct interface
*)rn
->info
;
2436 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2438 if (!if_is_operative(tmp_if
))
2440 vxl
= &zif
->l2info
.vxl
;
2442 if (zif
->brslave_info
.br_if
!= br_if
)
2445 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2454 zvni
= zvni_lookup(vxl
->vni
);
2459 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2460 * neighbor notifications, to see if they are of interest.
2462 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2463 struct interface
*br_if
)
2465 struct zebra_ns
*zns
;
2466 struct route_node
*rn
;
2467 struct interface
*tmp_if
= NULL
;
2468 struct zebra_if
*zif
;
2469 struct zebra_l2info_bridge
*br
;
2470 struct zebra_l2info_vxlan
*vxl
= NULL
;
2471 uint8_t bridge_vlan_aware
;
2479 /* Make sure the linked interface is a bridge. */
2480 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2483 /* Determine if bridge is VLAN-aware or not */
2486 br
= &zif
->l2info
.br
;
2487 bridge_vlan_aware
= br
->vlan_aware
;
2488 if (bridge_vlan_aware
) {
2489 struct zebra_l2info_vlan
*vl
;
2491 if (!IS_ZEBRA_IF_VLAN(ifp
))
2496 vl
= &zif
->l2info
.vl
;
2500 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2501 /* TODO: Optimize with a hash. */
2502 zns
= zebra_ns_lookup(NS_DEFAULT
);
2503 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2504 tmp_if
= (struct interface
*)rn
->info
;
2508 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2510 if (!if_is_operative(tmp_if
))
2512 vxl
= &zif
->l2info
.vxl
;
2514 if (zif
->brslave_info
.br_if
!= br_if
)
2517 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2526 zvni
= zvni_lookup(vxl
->vni
);
2530 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2532 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2533 * linked to the bridge
2534 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2537 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2539 struct zebra_ns
*zns
;
2540 struct route_node
*rn
;
2541 struct interface
*tmp_if
= NULL
;
2542 struct zebra_if
*zif
;
2543 struct zebra_l2info_bridge
*br
;
2544 struct zebra_l2info_vlan
*vl
;
2545 uint8_t bridge_vlan_aware
;
2548 /* Defensive check, caller expected to invoke only with valid bridge. */
2552 /* Determine if bridge is VLAN-aware or not */
2555 br
= &zif
->l2info
.br
;
2556 bridge_vlan_aware
= br
->vlan_aware
;
2558 /* Check oper status of the SVI. */
2559 if (!bridge_vlan_aware
)
2560 return if_is_operative(br_if
) ? br_if
: NULL
;
2562 /* Identify corresponding VLAN interface. */
2563 /* TODO: Optimize with a hash. */
2564 zns
= zebra_ns_lookup(NS_DEFAULT
);
2565 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2566 tmp_if
= (struct interface
*)rn
->info
;
2567 /* Check oper status of the SVI. */
2568 if (!tmp_if
|| !if_is_operative(tmp_if
))
2571 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2572 || zif
->link
!= br_if
)
2574 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2576 if (vl
->vid
== vid
) {
2582 return found
? tmp_if
: NULL
;
2586 * Install remote MAC into the kernel.
2588 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2590 struct zebra_if
*zif
;
2591 struct zebra_l2info_vxlan
*vxl
;
2594 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2597 zif
= zvni
->vxlan_if
->info
;
2600 vxl
= &zif
->l2info
.vxl
;
2602 sticky
= CHECK_FLAG(mac
->flags
,
2603 (ZEBRA_MAC_STICKY
| ZEBRA_MAC_REMOTE_DEF_GW
)) ? 1 : 0;
2605 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2606 mac
->fwd_info
.r_vtep_ip
, sticky
);
2610 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2611 * moves to remote, we have to uninstall any existing local entry first.
2613 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
, int local
)
2615 struct zebra_if
*zif
;
2616 struct zebra_l2info_vxlan
*vxl
;
2617 struct in_addr vtep_ip
= {.s_addr
= 0};
2618 struct zebra_ns
*zns
;
2619 struct interface
*ifp
;
2621 if (!local
&& !(mac
->flags
& ZEBRA_MAC_REMOTE
))
2624 if (!zvni
->vxlan_if
) {
2625 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2630 zif
= zvni
->vxlan_if
->info
;
2633 vxl
= &zif
->l2info
.vxl
;
2636 zns
= zebra_ns_lookup(NS_DEFAULT
);
2637 ifp
= if_lookup_by_index_per_ns(zns
,
2638 mac
->fwd_info
.local
.ifindex
);
2639 if (!ifp
) // unexpected
2642 ifp
= zvni
->vxlan_if
;
2643 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2646 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
,
2651 * Install MAC hash entry - called upon access VLAN change.
2653 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2656 struct mac_walk_ctx
*wctx
= ctxt
;
2658 mac
= (zebra_mac_t
*)backet
->data
;
2660 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2661 zvni_mac_install(wctx
->zvni
, mac
);
2665 * Decrement neighbor refcount of MAC; uninstall and free it if
2668 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
,
2671 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)
2672 || !list_isempty(mac
->neigh_list
))
2676 zvni_mac_uninstall(zvni
, mac
, 0);
2678 zvni_mac_del(zvni
, mac
);
2682 * Read and populate local MACs and neighbors corresponding to this VNI.
2684 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
, struct interface
*ifp
)
2686 struct zebra_ns
*zns
;
2687 struct zebra_if
*zif
;
2688 struct interface
*vlan_if
;
2689 struct zebra_l2info_vxlan
*vxl
;
2690 struct interface
*vrr_if
;
2693 vxl
= &zif
->l2info
.vxl
;
2694 zns
= zebra_ns_lookup(NS_DEFAULT
);
2696 if (IS_ZEBRA_DEBUG_VXLAN
)
2698 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2699 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2700 zif
->brslave_info
.bridge_ifindex
);
2702 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2703 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2706 /* Add SVI MAC-IP */
2707 zvni_add_macip_for_intf(vlan_if
, zvni
);
2709 /* Add VRR MAC-IP - if any*/
2710 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2712 zvni_add_macip_for_intf(vrr_if
, zvni
);
2714 neigh_read_for_vlan(zns
, vlan_if
);
2719 * Hash function for VNI.
2721 static unsigned int vni_hash_keymake(void *p
)
2723 const zebra_vni_t
*zvni
= p
;
2725 return (jhash_1word(zvni
->vni
, 0));
2729 * Compare 2 VNI hash entries.
2731 static int vni_hash_cmp(const void *p1
, const void *p2
)
2733 const zebra_vni_t
*zvni1
= p1
;
2734 const zebra_vni_t
*zvni2
= p2
;
2736 return (zvni1
->vni
== zvni2
->vni
);
2740 * Callback to allocate VNI hash entry.
2742 static void *zvni_alloc(void *p
)
2744 const zebra_vni_t
*tmp_vni
= p
;
2747 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2748 zvni
->vni
= tmp_vni
->vni
;
2749 return ((void *)zvni
);
2753 * Look up VNI hash entry.
2755 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2757 struct zebra_vrf
*zvrf
;
2758 zebra_vni_t tmp_vni
;
2759 zebra_vni_t
*zvni
= NULL
;
2761 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2763 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2765 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2771 * Add VNI hash entry.
2773 static zebra_vni_t
*zvni_add(vni_t vni
)
2775 struct zebra_vrf
*zvrf
;
2776 zebra_vni_t tmp_zvni
;
2777 zebra_vni_t
*zvni
= NULL
;
2779 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2781 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2783 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2786 /* Create hash table for MAC */
2788 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2790 /* Create hash table for neighbors */
2791 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2792 "Zebra VNI Neighbor Table");
2798 * Delete VNI hash entry.
2800 static int zvni_del(zebra_vni_t
*zvni
)
2802 struct zebra_vrf
*zvrf
;
2803 zebra_vni_t
*tmp_zvni
;
2805 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2808 zvni
->vxlan_if
= NULL
;
2810 /* Free the neighbor hash table. */
2811 hash_free(zvni
->neigh_table
);
2812 zvni
->neigh_table
= NULL
;
2814 /* Free the MAC hash table. */
2815 hash_free(zvni
->mac_table
);
2816 zvni
->mac_table
= NULL
;
2818 /* Free the VNI hash entry and allocated memory. */
2819 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2821 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2827 * Inform BGP about local VNI addition.
2829 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2831 struct zserv
*client
;
2834 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2835 /* BGP may not be running. */
2839 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2841 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2842 stream_putl(s
, zvni
->vni
);
2843 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2844 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2846 /* Write packet size. */
2847 stream_putw_at(s
, 0, stream_get_endp(s
));
2849 if (IS_ZEBRA_DEBUG_VXLAN
)
2850 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni
->vni
,
2851 inet_ntoa(zvni
->local_vtep_ip
),
2852 vrf_id_to_name(zvni
->vrf_id
),
2853 zebra_route_string(client
->proto
));
2855 client
->vniadd_cnt
++;
2856 return zserv_send_message(client
, s
);
2860 * Inform BGP about local VNI deletion.
2862 static int zvni_send_del_to_client(vni_t vni
)
2864 struct zserv
*client
;
2867 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2868 /* BGP may not be running. */
2872 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2875 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2876 stream_putl(s
, vni
);
2878 /* Write packet size. */
2879 stream_putw_at(s
, 0, stream_get_endp(s
));
2881 if (IS_ZEBRA_DEBUG_VXLAN
)
2882 zlog_debug("Send VNI_DEL %u to %s", vni
,
2883 zebra_route_string(client
->proto
));
2885 client
->vnidel_cnt
++;
2886 return zserv_send_message(client
, s
);
2890 * Build the VNI hash table by going over the VxLAN interfaces. This
2891 * is called when EVPN (advertise-all-vni) is enabled.
2893 static void zvni_build_hash_table()
2895 struct zebra_ns
*zns
;
2896 struct route_node
*rn
;
2897 struct interface
*ifp
;
2899 /* Walk VxLAN interfaces and create VNI hash. */
2900 zns
= zebra_ns_lookup(NS_DEFAULT
);
2901 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2903 zebra_vni_t
*zvni
= NULL
;
2904 zebra_l3vni_t
*zl3vni
= NULL
;
2905 struct zebra_if
*zif
;
2906 struct zebra_l2info_vxlan
*vxl
;
2908 ifp
= (struct interface
*)rn
->info
;
2912 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2915 vxl
= &zif
->l2info
.vxl
;
2918 /* L3-VNI and L2-VNI are handled seperately */
2919 zl3vni
= zl3vni_lookup(vni
);
2922 if (IS_ZEBRA_DEBUG_VXLAN
)
2924 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2925 ifp
->name
, ifp
->ifindex
, vni
);
2927 /* associate with vxlan_if */
2928 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2929 zl3vni
->vxlan_if
= ifp
;
2932 * we need to associate with SVI.
2933 * we can associate with svi-if only after association
2934 * with vxlan-intf is complete
2936 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2938 if (is_l3vni_oper_up(zl3vni
))
2939 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2942 struct interface
*vlan_if
= NULL
;
2944 if (IS_ZEBRA_DEBUG_VXLAN
)
2946 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2947 ifp
->name
, ifp
->ifindex
, vni
,
2948 inet_ntoa(vxl
->vtep_ip
));
2950 /* VNI hash entry is not expected to exist. */
2951 zvni
= zvni_lookup(vni
);
2954 "VNI hash already present for IF %s(%u) L2-VNI %u",
2955 ifp
->name
, ifp
->ifindex
, vni
);
2959 zvni
= zvni_add(vni
);
2962 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2963 ifp
->name
, ifp
->ifindex
, vni
);
2967 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
2968 zvni
->vxlan_if
= ifp
;
2969 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
2970 zif
->brslave_info
.br_if
);
2972 zvni
->vrf_id
= vlan_if
->vrf_id
;
2973 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
2975 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
2979 /* Inform BGP if intf is up and mapped to bridge. */
2980 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
2981 zvni_send_add_to_client(zvni
);
2987 * See if remote VTEP matches with prefix.
2989 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
2991 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
2995 * Locate remote VTEP in VNI hash table.
2997 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
2999 zebra_vtep_t
*zvtep
;
3004 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
3005 if (zvni_vtep_match(vtep_ip
, zvtep
))
3013 * Add remote VTEP to VNI hash table.
3015 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3017 zebra_vtep_t
*zvtep
;
3019 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
3021 zvtep
->vtep_ip
= *vtep_ip
;
3024 zvni
->vteps
->prev
= zvtep
;
3025 zvtep
->next
= zvni
->vteps
;
3026 zvni
->vteps
= zvtep
;
3032 * Remove remote VTEP from VNI hash table.
3034 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
3037 zvtep
->next
->prev
= zvtep
->prev
;
3039 zvtep
->prev
->next
= zvtep
->next
;
3041 zvni
->vteps
= zvtep
->next
;
3043 zvtep
->prev
= zvtep
->next
= NULL
;
3044 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
3050 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
3051 * uninstall from kernel if asked to.
3053 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
3055 zebra_vtep_t
*zvtep
, *zvtep_next
;
3060 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
3061 zvtep_next
= zvtep
->next
;
3063 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
3064 zvni_vtep_del(zvni
, zvtep
);
3071 * Install remote VTEP into the kernel.
3073 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3075 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3079 * Uninstall remote VTEP from the kernel.
3081 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3083 if (!zvni
->vxlan_if
) {
3084 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3089 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3093 * Cleanup VNI/VTEP and update kernel
3095 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
3097 zebra_vni_t
*zvni
= NULL
;
3098 zebra_l3vni_t
*zl3vni
= NULL
;
3099 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
3101 zvni
= (zebra_vni_t
*)backet
->data
;
3103 /* remove from l3-vni list */
3105 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
3107 listnode_delete(zl3vni
->l2vnis
, zvni
);
3109 /* Free up all neighbors and MACs, if any. */
3110 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
3111 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
3113 /* Free up all remote VTEPs, if any. */
3114 zvni_vtep_del_all(zvni
, 1);
3116 /* Delete the hash entry. */
3121 static void zl3vni_cleanup_all(struct hash_backet
*backet
, void *args
)
3123 zebra_l3vni_t
*zl3vni
= NULL
;
3125 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
3127 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
3130 static void rb_find_or_add_host(struct host_rb_tree_entry
*hrbe
,
3131 struct prefix
*host
)
3133 struct host_rb_entry lookup
;
3134 struct host_rb_entry
*hle
;
3136 memset(&lookup
, 0, sizeof(lookup
));
3137 memcpy(&lookup
.p
, host
, sizeof(*host
));
3139 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3143 hle
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct host_rb_entry
));
3144 memcpy(hle
, &lookup
, sizeof(lookup
));
3146 RB_INSERT(host_rb_tree_entry
, hrbe
, hle
);
3149 static void rb_delete_host(struct host_rb_tree_entry
*hrbe
, struct prefix
*host
)
3151 struct host_rb_entry lookup
;
3152 struct host_rb_entry
*hle
;
3154 memset(&lookup
, 0, sizeof(lookup
));
3155 memcpy(&lookup
.p
, host
, sizeof(*host
));
3157 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3159 RB_REMOVE(host_rb_tree_entry
, hrbe
, hle
);
3160 XFREE(MTYPE_HOST_PREFIX
, hle
);
3167 * Look up MAC hash entry.
3169 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
3170 struct ethaddr
*rmac
)
3175 memset(&tmp
, 0, sizeof(tmp
));
3176 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
3177 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
3183 * Callback to allocate RMAC hash entry.
3185 static void *zl3vni_rmac_alloc(void *p
)
3187 const zebra_mac_t
*tmp_rmac
= p
;
3190 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
3193 return ((void *)zrmac
);
3197 * Add RMAC entry to l3-vni
3199 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
)
3201 zebra_mac_t tmp_rmac
;
3202 zebra_mac_t
*zrmac
= NULL
;
3204 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
3205 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
3206 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
3209 RB_INIT(host_rb_tree_entry
, &zrmac
->host_rb
);
3211 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
3212 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
3220 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3222 zebra_mac_t
*tmp_rmac
;
3223 struct host_rb_entry
*hle
;
3225 while (!RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3226 hle
= RB_ROOT(host_rb_tree_entry
, &zrmac
->host_rb
);
3228 RB_REMOVE(host_rb_tree_entry
, &zrmac
->host_rb
, hle
);
3229 XFREE(MTYPE_HOST_PREFIX
, hle
);
3232 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
3234 XFREE(MTYPE_MAC
, tmp_rmac
);
3240 * Install remote RMAC into the kernel.
3242 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3244 struct zebra_if
*zif
= NULL
;
3245 struct zebra_l2info_vxlan
*vxl
= NULL
;
3247 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3248 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3251 zif
= zl3vni
->vxlan_if
->info
;
3255 vxl
= &zif
->l2info
.vxl
;
3257 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3258 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3262 * Uninstall remote RMAC from the kernel.
3264 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3266 char buf
[ETHER_ADDR_STRLEN
];
3267 struct zebra_if
*zif
= NULL
;
3268 struct zebra_l2info_vxlan
*vxl
= NULL
;
3270 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3271 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3274 if (!zl3vni
->vxlan_if
) {
3276 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3277 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3278 zl3vni
->vni
, zl3vni
);
3282 zif
= zl3vni
->vxlan_if
->info
;
3286 vxl
= &zif
->l2info
.vxl
;
3288 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3289 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3292 /* handle rmac add */
3293 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3294 struct ipaddr
*vtep_ip
,
3295 struct prefix
*host_prefix
)
3297 char buf
[ETHER_ADDR_STRLEN
];
3298 char buf1
[INET6_ADDRSTRLEN
];
3299 zebra_mac_t
*zrmac
= NULL
;
3301 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3304 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3307 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3308 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3310 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)));
3313 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3314 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3316 /* install rmac in kernel */
3317 zl3vni_rmac_install(zl3vni
, zrmac
);
3320 rb_find_or_add_host(&zrmac
->host_rb
, host_prefix
);
3326 /* handle rmac delete */
3327 static void zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
,
3328 struct prefix
*host_prefix
)
3330 rb_delete_host(&zrmac
->host_rb
, host_prefix
);
3332 if (RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3333 /* uninstall from kernel */
3334 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3336 /* del the rmac entry */
3337 zl3vni_rmac_del(zl3vni
, zrmac
);
3342 * Look up nh hash entry on a l3-vni.
3344 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3349 memset(&tmp
, 0, sizeof(tmp
));
3350 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3351 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3358 * Callback to allocate NH hash entry on L3-VNI.
3360 static void *zl3vni_nh_alloc(void *p
)
3362 const zebra_neigh_t
*tmp_n
= p
;
3365 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3372 * Add neighbor entry.
3374 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3375 struct ethaddr
*mac
)
3377 zebra_neigh_t tmp_n
;
3378 zebra_neigh_t
*n
= NULL
;
3380 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3381 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3382 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3385 RB_INIT(host_rb_tree_entry
, &n
->host_rb
);
3387 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3388 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3389 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3395 * Delete neighbor entry.
3397 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3399 zebra_neigh_t
*tmp_n
;
3400 struct host_rb_entry
*hle
;
3402 while (!RB_EMPTY(host_rb_tree_entry
, &n
->host_rb
)) {
3403 hle
= RB_ROOT(host_rb_tree_entry
, &n
->host_rb
);
3405 RB_REMOVE(host_rb_tree_entry
, &n
->host_rb
, hle
);
3406 XFREE(MTYPE_HOST_PREFIX
, hle
);
3409 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3411 XFREE(MTYPE_NEIGH
, tmp_n
);
3417 * Install remote nh as neigh into the kernel.
3419 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3426 if (!is_l3vni_oper_up(zl3vni
))
3429 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3430 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3433 flags
= NTF_EXT_LEARNED
;
3434 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
3435 flags
|= NTF_ROUTER
;
3436 ret
= kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
, flags
);
3442 * Uninstall remote nh from the kernel.
3444 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3446 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3447 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3450 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3453 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3456 /* add remote vtep as a neigh entry */
3457 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3458 struct ethaddr
*rmac
,
3459 struct prefix
*host_prefix
)
3461 char buf
[ETHER_ADDR_STRLEN
];
3462 char buf1
[INET6_ADDRSTRLEN
];
3463 zebra_neigh_t
*nh
= NULL
;
3465 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3467 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3471 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3472 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)),
3473 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3478 /* install the nh neigh in kernel */
3479 zl3vni_nh_install(zl3vni
, nh
);
3482 rb_find_or_add_host(&nh
->host_rb
, host_prefix
);
3487 /* handle nh neigh delete */
3488 static void zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*nh
,
3489 struct prefix
*host_prefix
)
3491 rb_delete_host(&nh
->host_rb
, host_prefix
);
3493 if (RB_EMPTY(host_rb_tree_entry
, &nh
->host_rb
)) {
3494 /* uninstall from kernel */
3495 zl3vni_nh_uninstall(zl3vni
, nh
);
3497 /* delete the nh entry */
3498 zl3vni_nh_del(zl3vni
, nh
);
3502 /* handle neigh update from kernel - the only thing of interest is to
3503 * readd stale entries.
3505 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3509 zebra_neigh_t
*n
= NULL
;
3511 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3515 /* all next hop neigh are remote and installed by frr.
3516 * If the kernel has aged this entry, re-install.
3518 if (state
& NUD_STALE
)
3519 zl3vni_nh_install(zl3vni
, n
);
3524 /* handle neigh delete from kernel */
3525 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3527 zebra_neigh_t
*n
= NULL
;
3529 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3533 /* all next hop neigh are remote and installed by frr.
3534 * If we get an age out notification for these neigh entries, we have to
3537 zl3vni_nh_install(zl3vni
, n
);
3543 * Hash function for L3 VNI.
3545 static unsigned int l3vni_hash_keymake(void *p
)
3547 const zebra_l3vni_t
*zl3vni
= p
;
3549 return jhash_1word(zl3vni
->vni
, 0);
3553 * Compare 2 L3 VNI hash entries.
3555 static int l3vni_hash_cmp(const void *p1
, const void *p2
)
3557 const zebra_l3vni_t
*zl3vni1
= p1
;
3558 const zebra_l3vni_t
*zl3vni2
= p2
;
3560 return (zl3vni1
->vni
== zl3vni2
->vni
);
3564 * Callback to allocate L3 VNI hash entry.
3566 static void *zl3vni_alloc(void *p
)
3568 zebra_l3vni_t
*zl3vni
= NULL
;
3569 const zebra_l3vni_t
*tmp_l3vni
= p
;
3571 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3572 zl3vni
->vni
= tmp_l3vni
->vni
;
3573 return ((void *)zl3vni
);
3577 * Look up L3 VNI hash entry.
3579 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3581 struct zebra_ns
*zns
;
3582 zebra_l3vni_t tmp_l3vni
;
3583 zebra_l3vni_t
*zl3vni
= NULL
;
3585 zns
= zebra_ns_lookup(NS_DEFAULT
);
3587 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3588 tmp_l3vni
.vni
= vni
;
3589 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3595 * Add L3 VNI hash entry.
3597 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3599 zebra_l3vni_t tmp_zl3vni
;
3600 struct zebra_ns
*zns
= NULL
;
3601 zebra_l3vni_t
*zl3vni
= NULL
;
3603 zns
= zebra_ns_lookup(NS_DEFAULT
);
3606 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3607 tmp_zl3vni
.vni
= vni
;
3609 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3612 zl3vni
->vrf_id
= vrf_id
;
3613 zl3vni
->svi_if
= NULL
;
3614 zl3vni
->vxlan_if
= NULL
;
3615 zl3vni
->l2vnis
= list_new();
3616 zl3vni
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
3618 /* Create hash table for remote RMAC */
3619 zl3vni
->rmac_table
= hash_create(mac_hash_keymake
, mac_cmp
,
3620 "Zebra L3-VNI RMAC-Table");
3622 /* Create hash table for neighbors */
3623 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3624 "Zebra L3-VNI next-hop table");
3630 * Delete L3 VNI hash entry.
3632 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3634 struct zebra_ns
*zns
;
3635 zebra_l3vni_t
*tmp_zl3vni
;
3637 zns
= zebra_ns_lookup(NS_DEFAULT
);
3640 /* free the list of l2vnis */
3641 list_delete_and_null(&zl3vni
->l2vnis
);
3642 zl3vni
->l2vnis
= NULL
;
3644 /* Free the rmac table */
3645 hash_free(zl3vni
->rmac_table
);
3646 zl3vni
->rmac_table
= NULL
;
3648 /* Free the nh table */
3649 hash_free(zl3vni
->nh_table
);
3650 zl3vni
->nh_table
= NULL
;
3652 /* Free the VNI hash entry and allocated memory. */
3653 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3655 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3660 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3662 struct zebra_ns
*zns
= NULL
;
3663 struct route_node
*rn
= NULL
;
3664 struct interface
*ifp
= NULL
;
3666 /* loop through all vxlan-interface */
3667 zns
= zebra_ns_lookup(NS_DEFAULT
);
3668 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3670 struct zebra_if
*zif
= NULL
;
3671 struct zebra_l2info_vxlan
*vxl
= NULL
;
3673 ifp
= (struct interface
*)rn
->info
;
3678 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3681 vxl
= &zif
->l2info
.vxl
;
3682 if (vxl
->vni
== zl3vni
->vni
) {
3683 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3691 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3693 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3694 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3699 if (!zl3vni
->vxlan_if
)
3702 zif
= zl3vni
->vxlan_if
->info
;
3706 vxl
= &zif
->l2info
.vxl
;
3708 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3711 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3713 struct zebra_vrf
*zvrf
= NULL
;
3715 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3719 return zl3vni_lookup(zvrf
->l3vni
);
3723 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3724 * neighbor notifications, to see if they are of interest.
3726 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3727 struct interface
*br_if
)
3731 uint8_t bridge_vlan_aware
= 0;
3732 zebra_l3vni_t
*zl3vni
= NULL
;
3733 struct zebra_ns
*zns
= NULL
;
3734 struct route_node
*rn
= NULL
;
3735 struct zebra_if
*zif
= NULL
;
3736 struct interface
*tmp_if
= NULL
;
3737 struct zebra_l2info_bridge
*br
= NULL
;
3738 struct zebra_l2info_vxlan
*vxl
= NULL
;
3743 /* Make sure the linked interface is a bridge. */
3744 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3747 /* Determine if bridge is VLAN-aware or not */
3750 br
= &zif
->l2info
.br
;
3751 bridge_vlan_aware
= br
->vlan_aware
;
3752 if (bridge_vlan_aware
) {
3753 struct zebra_l2info_vlan
*vl
;
3755 if (!IS_ZEBRA_IF_VLAN(ifp
))
3760 vl
= &zif
->l2info
.vl
;
3764 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3765 /* TODO: Optimize with a hash. */
3766 zns
= zebra_ns_lookup(NS_DEFAULT
);
3767 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3768 tmp_if
= (struct interface
*)rn
->info
;
3772 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3774 if (!if_is_operative(tmp_if
))
3776 vxl
= &zif
->l2info
.vxl
;
3778 if (zif
->brslave_info
.br_if
!= br_if
)
3781 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3790 zl3vni
= zl3vni_lookup(vxl
->vni
);
3795 * Inform BGP about l3-vni.
3797 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3799 struct stream
*s
= NULL
;
3800 struct zserv
*client
= NULL
;
3801 struct ethaddr rmac
;
3802 char buf
[ETHER_ADDR_STRLEN
];
3804 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3805 /* BGP may not be running. */
3810 memset(&rmac
, 0, sizeof(struct ethaddr
));
3811 zl3vni_get_rmac(zl3vni
, &rmac
);
3813 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3815 zclient_create_header(s
, ZEBRA_L3VNI_ADD
, zl3vni_vrf_id(zl3vni
));
3816 stream_putl(s
, zl3vni
->vni
);
3817 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3818 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3819 stream_put(s
, &zl3vni
->filter
, sizeof(int));
3821 /* Write packet size. */
3822 stream_putw_at(s
, 0, stream_get_endp(s
));
3824 if (IS_ZEBRA_DEBUG_VXLAN
)
3826 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3827 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3828 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3829 inet_ntoa(zl3vni
->local_vtep_ip
),
3830 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
3831 ? "prefix-routes-only"
3833 zebra_route_string(client
->proto
));
3835 client
->l3vniadd_cnt
++;
3836 return zserv_send_message(client
, s
);
3840 * Inform BGP about local l3-VNI deletion.
3842 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3844 struct stream
*s
= NULL
;
3845 struct zserv
*client
= NULL
;
3847 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3848 /* BGP may not be running. */
3852 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3854 zclient_create_header(s
, ZEBRA_L3VNI_DEL
, zl3vni_vrf_id(zl3vni
));
3855 stream_putl(s
, zl3vni
->vni
);
3857 /* Write packet size. */
3858 stream_putw_at(s
, 0, stream_get_endp(s
));
3860 if (IS_ZEBRA_DEBUG_VXLAN
)
3861 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni
->vni
,
3862 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3863 zebra_route_string(client
->proto
));
3865 client
->l3vnidel_cnt
++;
3866 return zserv_send_message(client
, s
);
3869 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3874 /* send l3vni add to BGP */
3875 zl3vni_send_add_to_client(zl3vni
);
3878 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3883 /* send l3-vni del to BGP*/
3884 zl3vni_send_del_to_client(zl3vni
);
3887 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
, void *ctxt
)
3889 zebra_vni_t
*zvni
= (zebra_vni_t
*)backet
->data
;
3890 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*)ctxt
;
3892 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3893 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3897 * handle transition of vni from l2 to l3 and vice versa
3899 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
, vni_t vni
,
3902 zebra_vni_t
*zvni
= NULL
;
3904 /* There is a possibility that VNI notification was already received
3905 * from kernel and we programmed it as L2-VNI
3906 * In such a case we need to delete this L2-VNI first, so
3907 * that it can be reprogrammed as L3-VNI in the system. It is also
3908 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3909 * interface is still present in kernel. In this case to keep it
3910 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3913 /* Locate hash entry */
3914 zvni
= zvni_lookup(vni
);
3918 if (IS_ZEBRA_DEBUG_VXLAN
)
3919 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni
);
3921 /* Delete VNI from BGP. */
3922 zvni_send_del_to_client(zvni
->vni
);
3924 /* Free up all neighbors and MAC, if any. */
3925 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3926 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3928 /* Free up all remote VTEPs, if any. */
3929 zvni_vtep_del_all(zvni
, 0);
3931 /* Delete the hash entry. */
3932 if (zvni_del(zvni
)) {
3933 flog_err(ZEBRA_ERR_VNI_DEL_FAILED
,
3934 "Failed to del VNI hash %p, VNI %u", zvni
,
3939 /* TODO_MITESH: This needs to be thought through. We don't have
3940 * enough information at this point to reprogram the vni as
3941 * l2-vni. One way is to store the required info in l3-vni and
3942 * used it solely for this purpose
3949 /* delete and uninstall rmac hash entry */
3950 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
, void *ctx
)
3952 zebra_mac_t
*zrmac
= NULL
;
3953 zebra_l3vni_t
*zl3vni
= NULL
;
3955 zrmac
= (zebra_mac_t
*)backet
->data
;
3956 zl3vni
= (zebra_l3vni_t
*)ctx
;
3957 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3958 zl3vni_rmac_del(zl3vni
, zrmac
);
3961 /* delete and uninstall nh hash entry */
3962 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
, void *ctx
)
3964 zebra_neigh_t
*n
= NULL
;
3965 zebra_l3vni_t
*zl3vni
= NULL
;
3967 n
= (zebra_neigh_t
*)backet
->data
;
3968 zl3vni
= (zebra_l3vni_t
*)ctx
;
3969 zl3vni_nh_uninstall(zl3vni
, n
);
3970 zl3vni_nh_del(zl3vni
, n
);
3973 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
3976 struct zserv
*client
= NULL
;
3977 struct stream
*s
= NULL
;
3978 char buf
[PREFIX_STRLEN
];
3980 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3981 /* BGP may not be running. */
3985 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3987 zclient_create_header(s
, cmd
, vrf_id
);
3988 stream_put(s
, p
, sizeof(struct prefix
));
3990 /* Write packet size. */
3991 stream_putw_at(s
, 0, stream_get_endp(s
));
3993 if (IS_ZEBRA_DEBUG_VXLAN
)
3994 zlog_debug("Send ip prefix %s %s on vrf %s",
3995 prefix2str(p
, buf
, sizeof(buf
)),
3996 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
3997 vrf_id_to_name(vrf_id
));
3999 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
4000 client
->prefixadd_cnt
++;
4002 client
->prefixdel_cnt
++;
4004 return zserv_send_message(client
, s
);
4007 /* re-add remote rmac if needed */
4008 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
4009 struct ethaddr
*rmac
)
4011 char buf
[ETHER_ADDR_STRLEN
];
4012 zebra_mac_t
*zrmac
= NULL
;
4014 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4018 if (IS_ZEBRA_DEBUG_VXLAN
)
4019 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
4020 prefix_mac2str(rmac
, buf
, sizeof(buf
)), zl3vni
->vni
);
4022 zl3vni_rmac_install(zl3vni
, zrmac
);
4026 /* Process a remote MACIP add from BGP. */
4027 static void process_remote_macip_add(vni_t vni
,
4028 struct ethaddr
*macaddr
,
4030 struct ipaddr
*ipaddr
,
4033 struct in_addr vtep_ip
)
4036 zebra_vtep_t
*zvtep
;
4037 zebra_mac_t
*mac
, *old_mac
;
4038 zebra_neigh_t
*n
= NULL
;
4039 int update_mac
= 0, update_neigh
= 0;
4040 char buf
[ETHER_ADDR_STRLEN
];
4041 char buf1
[INET6_ADDRSTRLEN
];
4042 struct interface
*ifp
= NULL
;
4043 struct zebra_if
*zif
= NULL
;
4046 uint8_t remote_gw
= 0;
4047 uint8_t router_flag
= 0;
4049 /* Locate VNI hash entry - expected to exist. */
4050 zvni
= zvni_lookup(vni
);
4052 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni
);
4056 ifp
= zvni
->vxlan_if
;
4060 !if_is_operative(ifp
) ||
4062 !zif
->brslave_info
.br_if
) {
4063 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
4068 /* The remote VTEP specified should normally exist, but it is
4069 * possible that when peering comes up, peer may advertise MACIP
4070 * routes before advertising type-3 routes.
4072 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4074 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4076 ZEBRA_ERR_VTEP_ADD_FAILED
,
4077 "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
4082 zvni_vtep_install(zvni
, &vtep_ip
);
4085 sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
4086 remote_gw
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
4087 router_flag
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
4089 mac
= zvni_mac_lookup(zvni
, macaddr
);
4091 /* Ignore if the mac is already present as a gateway mac */
4093 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
) &&
4094 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
4095 if (IS_ZEBRA_DEBUG_VXLAN
)
4096 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4098 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4099 ipa_len
? " IP " : "",
4101 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4105 /* check if the remote MAC is unknown or has a change.
4106 * If so, that needs to be updated first. Note that client could
4107 * install MAC and MACIP separately or just install the latter.
4110 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4111 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
) ? 1 : 0) != sticky
4112 || (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
) ? 1 : 0)
4114 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
)
4115 || seq
!= mac
->rem_seq
)
4120 mac
= zvni_mac_add(zvni
, macaddr
);
4123 "Failed to add MAC %s VNI %u Remote VTEP %s",
4124 prefix_mac2str(macaddr
, buf
,
4126 vni
, inet_ntoa(vtep_ip
));
4130 /* Is this MAC created for a MACIP? */
4132 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4134 const char *mac_type
;
4136 /* When host moves but changes its (MAC,IP)
4137 * binding, BGP may install a MACIP entry that
4138 * corresponds to "older" location of the host
4139 * in transient situations (because {IP1,M1}
4140 * is a different route from {IP1,M2}). Check
4141 * the sequence number and ignore this update
4144 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
4145 tmp_seq
= mac
->loc_seq
;
4148 tmp_seq
= mac
->rem_seq
;
4149 mac_type
= "remote";
4151 if (seq
< tmp_seq
) {
4152 if (IS_ZEBRA_DEBUG_VXLAN
)
4153 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
4155 prefix_mac2str(macaddr
,
4157 ipa_len
? " IP " : "",
4160 buf1
, sizeof(buf1
)) : "",
4167 /* Set "auto" and "remote" forwarding info. */
4168 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4169 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4170 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4171 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4174 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4176 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4179 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4181 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4183 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
4185 /* Install the entry. */
4186 zvni_mac_install(zvni
, mac
);
4189 /* Update seq number. */
4192 /* If there is no IP, return after clearing AUTO flag of MAC. */
4194 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4198 /* Check if the remote neighbor itself is unknown or has a
4199 * change. If so, create or update and then install the entry.
4201 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4203 || !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4204 || (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0)
4205 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
)
4206 || ((CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
) ? 1 : 0)
4208 || seq
!= n
->rem_seq
)
4213 n
= zvni_neigh_add(zvni
, ipaddr
, macaddr
);
4216 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
4217 ipaddr2str(ipaddr
, buf1
,
4219 prefix_mac2str(macaddr
, buf
,
4221 vni
, inet_ntoa(vtep_ip
));
4228 /* When host moves but changes its (MAC,IP)
4229 * binding, BGP may install a MACIP entry that
4230 * corresponds to "older" location of the host
4231 * in transient situations (because {IP1,M1}
4232 * is a different route from {IP1,M2}). Check
4233 * the sequence number and ignore this update
4236 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4237 tmp_seq
= n
->loc_seq
;
4240 tmp_seq
= n
->rem_seq
;
4243 if (seq
< tmp_seq
) {
4244 if (IS_ZEBRA_DEBUG_VXLAN
)
4245 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
4247 prefix_mac2str(macaddr
,
4249 ipa_len
? " IP " : "",
4252 buf1
, sizeof(buf1
)) : "",
4257 if (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0) {
4258 /* MAC change, send a delete for old
4259 * neigh if learnt locally.
4261 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) &&
4262 IS_ZEBRA_NEIGH_ACTIVE(n
))
4263 zvni_neigh_send_del_to_client(
4267 /* update neigh list for macs */
4268 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
4270 listnode_delete(old_mac
->neigh_list
, n
);
4271 zvni_deref_ip2mac(zvni
, old_mac
, 1);
4273 listnode_add_sort(mac
->neigh_list
, n
);
4274 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4278 /* Set "remote" forwarding info. */
4279 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4280 n
->r_vtep_ip
= vtep_ip
;
4281 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4283 /* Set router flag (R-bit) to this Neighbor entry */
4284 if (CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
))
4285 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4287 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4289 /* Install the entry. */
4290 zvni_neigh_install(zvni
, n
);
4293 /* Update seq number. */
4297 /* Process a remote MACIP delete from BGP. */
4298 static void process_remote_macip_del(vni_t vni
,
4299 struct ethaddr
*macaddr
,
4301 struct ipaddr
*ipaddr
,
4302 struct in_addr vtep_ip
)
4305 zebra_mac_t
*mac
= NULL
;
4306 zebra_neigh_t
*n
= NULL
;
4307 struct interface
*ifp
= NULL
;
4308 struct zebra_if
*zif
= NULL
;
4309 char buf
[ETHER_ADDR_STRLEN
];
4310 char buf1
[INET6_ADDRSTRLEN
];
4312 /* Locate VNI hash entry - expected to exist. */
4313 zvni
= zvni_lookup(vni
);
4315 if (IS_ZEBRA_DEBUG_VXLAN
)
4316 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni
);
4320 ifp
= zvni
->vxlan_if
;
4324 !if_is_operative(ifp
) ||
4326 !zif
->brslave_info
.br_if
) {
4327 if (IS_ZEBRA_DEBUG_VXLAN
)
4328 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
4333 /* The remote VTEP specified is normally expected to exist, but
4334 * it is possible that the peer may delete the VTEP before deleting
4335 * any MACs referring to the VTEP, in which case the handler (see
4336 * remote_vtep_del) would have already deleted the MACs.
4338 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4341 mac
= zvni_mac_lookup(zvni
, macaddr
);
4343 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4346 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
4347 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4348 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)), vni
);
4352 /* If the remote mac or neighbor doesn't exist there is nothing
4353 * more to do. Otherwise, uninstall the entry and then remove it.
4358 /* Ignore the delete if this mac is a gateway mac-ip */
4360 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
4361 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
4363 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4365 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4366 ipa_len
? " IP " : "",
4368 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4372 /* Uninstall remote neighbor or MAC. */
4374 /* When the MAC changes for an IP, it is possible the
4375 * client may update the new MAC before trying to delete the
4376 * "old" neighbor (as these are two different MACIP routes).
4377 * Do the delete only if the MAC matches.
4379 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4380 && (memcmp(n
->emac
.octet
, macaddr
->octet
, ETH_ALEN
) == 0)) {
4381 zvni_neigh_uninstall(zvni
, n
);
4382 zvni_neigh_del(zvni
, n
);
4383 zvni_deref_ip2mac(zvni
, mac
, 1);
4386 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4387 zvni_process_neigh_on_remote_mac_del(zvni
, mac
);
4389 if (list_isempty(mac
->neigh_list
)) {
4390 zvni_mac_uninstall(zvni
, mac
, 0);
4391 zvni_mac_del(zvni
, mac
);
4393 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4399 /* Public functions */
4401 int is_l3vni_for_prefix_routes_only(vni_t vni
)
4403 zebra_l3vni_t
*zl3vni
= NULL
;
4405 zl3vni
= zl3vni_lookup(vni
);
4409 return CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
) ? 1 : 0;
4412 /* handle evpn route in vrf table */
4413 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
4414 struct ipaddr
*vtep_ip
,
4415 struct prefix
*host_prefix
)
4417 zebra_l3vni_t
*zl3vni
= NULL
;
4418 struct ipaddr ipv4_vtep
;
4420 zl3vni
= zl3vni_from_vrf(vrf_id
);
4421 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
4425 * add the next hop neighbor -
4426 * neigh to be installed is the ipv6 nexthop neigh
4428 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
4431 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
4432 * address. Rmac is programmed against the ipv4 vtep because we only
4433 * support ipv4 tunnels in the h/w right now
4435 memset(&ipv4_vtep
, 0, sizeof(struct ipaddr
));
4436 ipv4_vtep
.ipa_type
= IPADDR_V4
;
4437 if (vtep_ip
->ipa_type
== IPADDR_V6
)
4438 ipv4_mapped_ipv6_to_ipv4(&vtep_ip
->ipaddr_v6
,
4439 &(ipv4_vtep
.ipaddr_v4
));
4441 memcpy(&(ipv4_vtep
.ipaddr_v4
), &vtep_ip
->ipaddr_v4
,
4442 sizeof(struct in_addr
));
4445 * add the rmac - remote rmac to be installed is against the ipv4
4448 zl3vni_remote_rmac_add(zl3vni
, rmac
, &ipv4_vtep
, host_prefix
);
4451 /* handle evpn vrf route delete */
4452 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
4453 struct ipaddr
*vtep_ip
,
4454 struct prefix
*host_prefix
)
4456 zebra_l3vni_t
*zl3vni
= NULL
;
4457 zebra_neigh_t
*nh
= NULL
;
4458 zebra_mac_t
*zrmac
= NULL
;
4460 zl3vni
= zl3vni_from_vrf(vrf_id
);
4464 /* find the next hop entry and rmac entry */
4465 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
4468 zrmac
= zl3vni_rmac_lookup(zl3vni
, &nh
->emac
);
4470 /* delete the next hop entry */
4471 zl3vni_remote_nh_del(zl3vni
, nh
, host_prefix
);
4473 /* delete the rmac entry */
4475 zl3vni_remote_rmac_del(zl3vni
, zrmac
, host_prefix
);
4479 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
, vni_t l3vni
,
4480 struct ethaddr
*rmac
, bool use_json
)
4482 zebra_l3vni_t
*zl3vni
= NULL
;
4483 zebra_mac_t
*zrmac
= NULL
;
4484 json_object
*json
= NULL
;
4486 if (!is_evpn_enabled()) {
4488 vty_out(vty
, "{}\n");
4493 json
= json_object_new_object();
4495 zl3vni
= zl3vni_lookup(l3vni
);
4498 vty_out(vty
, "{}\n");
4500 vty_out(vty
, "%% L3-VNI %u doesnt exist\n", l3vni
);
4504 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4507 vty_out(vty
, "{}\n");
4510 "%% Requested RMAC doesnt exist in L3-VNI %u",
4515 zl3vni_print_rmac(zrmac
, vty
, json
);
4518 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4519 json
, JSON_C_TO_STRING_PRETTY
));
4520 json_object_free(json
);
4524 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4526 zebra_l3vni_t
*zl3vni
;
4528 struct rmac_walk_ctx wctx
;
4529 json_object
*json
= NULL
;
4531 if (!is_evpn_enabled())
4534 zl3vni
= zl3vni_lookup(l3vni
);
4537 vty_out(vty
, "{}\n");
4539 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4542 num_rmacs
= hashcount(zl3vni
->rmac_table
);
4547 json
= json_object_new_object();
4549 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
4553 vty_out(vty
, "Number of Remote RMACs known for this VNI: %u\n",
4555 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
4557 json_object_int_add(json
, "numRmacs", num_rmacs
);
4559 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
4562 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4563 json
, JSON_C_TO_STRING_PRETTY
));
4564 json_object_free(json
);
4568 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
, bool use_json
)
4570 struct zebra_ns
*zns
= NULL
;
4571 json_object
*json
= NULL
;
4574 if (!is_evpn_enabled()) {
4576 vty_out(vty
, "{}\n");
4580 zns
= zebra_ns_lookup(NS_DEFAULT
);
4583 vty_out(vty
, "{}\n");
4588 json
= json_object_new_object();
4592 hash_iterate(zns
->l3vni_table
,
4593 (void (*)(struct hash_backet
*,
4594 void *))zl3vni_print_rmac_hash_all_vni
,
4598 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4599 json
, JSON_C_TO_STRING_PRETTY
));
4600 json_object_free(json
);
4604 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
, vni_t l3vni
,
4605 struct ipaddr
*ip
, bool use_json
)
4607 zebra_l3vni_t
*zl3vni
= NULL
;
4608 zebra_neigh_t
*n
= NULL
;
4609 json_object
*json
= NULL
;
4611 if (!is_evpn_enabled()) {
4613 vty_out(vty
, "{}\n");
4618 json
= json_object_new_object();
4620 zl3vni
= zl3vni_lookup(l3vni
);
4623 vty_out(vty
, "{}\n");
4625 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4629 n
= zl3vni_nh_lookup(zl3vni
, ip
);
4632 vty_out(vty
, "{}\n");
4635 "%% Requested next-hop not present for L3-VNI %u",
4640 zl3vni_print_nh(n
, vty
, json
);
4643 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4644 json
, JSON_C_TO_STRING_PRETTY
));
4645 json_object_free(json
);
4649 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4652 struct nh_walk_ctx wctx
;
4653 json_object
*json
= NULL
;
4654 zebra_l3vni_t
*zl3vni
= NULL
;
4656 if (!is_evpn_enabled())
4659 zl3vni
= zl3vni_lookup(l3vni
);
4662 vty_out(vty
, "{}\n");
4664 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4668 num_nh
= hashcount(zl3vni
->nh_table
);
4673 json
= json_object_new_object();
4678 vty_out(vty
, "Number of NH Neighbors known for this VNI: %u\n",
4680 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4682 json_object_int_add(json
, "numNextHops", num_nh
);
4684 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4687 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4688 json
, JSON_C_TO_STRING_PRETTY
));
4689 json_object_free(json
);
4693 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
, bool use_json
)
4695 struct zebra_ns
*zns
= NULL
;
4696 json_object
*json
= NULL
;
4699 if (!is_evpn_enabled()) {
4701 vty_out(vty
, "{}\n");
4705 zns
= zebra_ns_lookup(NS_DEFAULT
);
4710 json
= json_object_new_object();
4714 hash_iterate(zns
->l3vni_table
,
4715 (void (*)(struct hash_backet
*,
4716 void *))zl3vni_print_nh_hash_all_vni
,
4720 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4721 json
, JSON_C_TO_STRING_PRETTY
));
4722 json_object_free(json
);
4727 * Display L3 VNI information (VTY command handler).
4729 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, bool use_json
)
4732 json_object
*json
= NULL
;
4733 zebra_l3vni_t
*zl3vni
= NULL
;
4735 if (!is_evpn_enabled()) {
4737 vty_out(vty
, "{}\n");
4741 zl3vni
= zl3vni_lookup(vni
);
4744 vty_out(vty
, "{}\n");
4746 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4751 json
= json_object_new_object();
4755 zl3vni_print(zl3vni
, (void *)args
);
4758 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4759 json
, JSON_C_TO_STRING_PRETTY
));
4760 json_object_free(json
);
4764 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4765 json_object
*json_vrfs
)
4767 char buf
[ETHER_ADDR_STRLEN
];
4768 zebra_l3vni_t
*zl3vni
= NULL
;
4770 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4775 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4776 zvrf_name(zvrf
), zl3vni
->vni
,
4777 zl3vni_vxlan_if_name(zl3vni
),
4778 zl3vni_svi_if_name(zl3vni
), zl3vni_state2str(zl3vni
),
4779 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4781 json_object
*json_vrf
= NULL
;
4783 json_vrf
= json_object_new_object();
4784 json_object_string_add(json_vrf
, "vrf", zvrf_name(zvrf
));
4785 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4786 json_object_string_add(json_vrf
, "vxlanIntf",
4787 zl3vni_vxlan_if_name(zl3vni
));
4788 json_object_string_add(json_vrf
, "sviIntf",
4789 zl3vni_svi_if_name(zl3vni
));
4790 json_object_string_add(json_vrf
, "state",
4791 zl3vni_state2str(zl3vni
));
4792 json_object_string_add(
4793 json_vrf
, "routerMac",
4794 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4795 json_object_array_add(json_vrfs
, json_vrf
);
4800 * Display Neighbors for a VNI (VTY command handler).
4802 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4803 vni_t vni
, bool use_json
)
4807 struct neigh_walk_ctx wctx
;
4808 json_object
*json
= NULL
;
4810 if (!is_evpn_enabled())
4812 zvni
= zvni_lookup(vni
);
4815 vty_out(vty
, "{}\n");
4817 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4820 num_neigh
= hashcount(zvni
->neigh_table
);
4825 json
= json_object_new_object();
4827 /* Since we have IPv6 addresses to deal with which can vary widely in
4828 * size, we try to be a bit more elegant in display by first computing
4829 * the maximum width.
4831 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4834 wctx
.addr_width
= 15;
4836 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4840 "Number of ARPs (local and remote) known for this VNI: %u\n",
4842 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
4843 -wctx
.addr_width
, "IP", "Type",
4844 "State", "MAC", "Remote VTEP");
4846 json_object_int_add(json
, "numArpNd", num_neigh
);
4848 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4850 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4851 json
, JSON_C_TO_STRING_PRETTY
));
4852 json_object_free(json
);
4857 * Display neighbors across all VNIs (VTY command handler).
4859 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4862 json_object
*json
= NULL
;
4865 if (!is_evpn_enabled())
4869 json
= json_object_new_object();
4873 hash_iterate(zvrf
->vni_table
,
4874 (void (*)(struct hash_backet
*,
4875 void *))zvni_print_neigh_hash_all_vni
,
4878 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4879 json
, JSON_C_TO_STRING_PRETTY
));
4880 json_object_free(json
);
4885 * Display specific neighbor for a VNI, if present (VTY command handler).
4887 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4888 struct zebra_vrf
*zvrf
, vni_t vni
,
4889 struct ipaddr
*ip
, bool use_json
)
4893 json_object
*json
= NULL
;
4895 if (!is_evpn_enabled())
4897 zvni
= zvni_lookup(vni
);
4900 vty_out(vty
, "{}\n");
4902 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4905 n
= zvni_neigh_lookup(zvni
, ip
);
4909 "%% Requested neighbor does not exist in VNI %u\n",
4914 json
= json_object_new_object();
4916 zvni_print_neigh(n
, vty
, json
);
4919 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4920 json
, JSON_C_TO_STRING_PRETTY
));
4921 json_object_free(json
);
4926 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4927 * By definition, these are remote neighbors.
4929 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4930 vni_t vni
, struct in_addr vtep_ip
,
4935 struct neigh_walk_ctx wctx
;
4936 json_object
*json
= NULL
;
4938 if (!is_evpn_enabled())
4940 zvni
= zvni_lookup(vni
);
4943 vty_out(vty
, "{}\n");
4945 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4948 num_neigh
= hashcount(zvni
->neigh_table
);
4952 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4955 wctx
.addr_width
= 15;
4956 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
4957 wctx
.r_vtep_ip
= vtep_ip
;
4959 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4960 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4963 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4964 json
, JSON_C_TO_STRING_PRETTY
));
4965 json_object_free(json
);
4970 * Display MACs for a VNI (VTY command handler).
4972 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4973 vni_t vni
, bool use_json
)
4977 struct mac_walk_ctx wctx
;
4978 json_object
*json
= NULL
;
4979 json_object
*json_mac
= NULL
;
4981 if (!is_evpn_enabled())
4983 zvni
= zvni_lookup(vni
);
4986 vty_out(vty
, "{}\n");
4988 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4991 num_macs
= num_valid_macs(zvni
);
4996 json
= json_object_new_object();
4997 json_mac
= json_object_new_object();
5000 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5003 wctx
.json
= json_mac
;
5007 "Number of MACs (local and remote) known for this VNI: %u\n",
5009 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
5010 "Intf/Remote VTEP", "VLAN");
5012 json_object_int_add(json
, "numMacs", num_macs
);
5014 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5017 json_object_object_add(json
, "macs", json_mac
);
5018 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5019 json
, JSON_C_TO_STRING_PRETTY
));
5020 json_object_free(json
);
5025 * Display MACs for all VNIs (VTY command handler).
5027 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5030 struct mac_walk_ctx wctx
;
5031 json_object
*json
= NULL
;
5033 if (!is_evpn_enabled()) {
5035 vty_out(vty
, "{}\n");
5039 json
= json_object_new_object();
5041 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5044 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5047 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5048 json
, JSON_C_TO_STRING_PRETTY
));
5049 json_object_free(json
);
5054 * Display MACs for all VNIs (VTY command handler).
5056 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
5057 struct zebra_vrf
*zvrf
,
5058 struct in_addr vtep_ip
, bool use_json
)
5060 struct mac_walk_ctx wctx
;
5061 json_object
*json
= NULL
;
5063 if (!is_evpn_enabled())
5067 json
= json_object_new_object();
5069 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5071 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5072 wctx
.r_vtep_ip
= vtep_ip
;
5074 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5077 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5078 json
, JSON_C_TO_STRING_PRETTY
));
5079 json_object_free(json
);
5084 * Display specific MAC for a VNI, if present (VTY command handler).
5086 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5087 vni_t vni
, struct ethaddr
*macaddr
)
5092 if (!is_evpn_enabled())
5094 zvni
= zvni_lookup(vni
);
5096 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5099 mac
= zvni_mac_lookup(zvni
, macaddr
);
5101 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
5106 zvni_print_mac(mac
, vty
);
5110 * Display MACs for a VNI from specific VTEP (VTY command handler).
5112 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5113 vni_t vni
, struct in_addr vtep_ip
,
5118 struct mac_walk_ctx wctx
;
5119 json_object
*json
= NULL
;
5120 json_object
*json_mac
= NULL
;
5122 if (!is_evpn_enabled())
5124 zvni
= zvni_lookup(vni
);
5127 vty_out(vty
, "{}\n");
5129 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5132 num_macs
= num_valid_macs(zvni
);
5137 json
= json_object_new_object();
5138 json_mac
= json_object_new_object();
5141 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5144 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5145 wctx
.r_vtep_ip
= vtep_ip
;
5146 wctx
.json
= json_mac
;
5147 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5150 json_object_int_add(json
, "numMacs", wctx
.count
);
5152 json_object_object_add(json
, "macs", json_mac
);
5153 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5154 json
, JSON_C_TO_STRING_PRETTY
));
5155 json_object_free(json
);
5161 * Display VNI information (VTY command handler).
5163 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
5166 json_object
*json
= NULL
;
5168 zebra_l3vni_t
*zl3vni
= NULL
;
5169 zebra_vni_t
*zvni
= NULL
;
5171 if (!is_evpn_enabled())
5175 json
= json_object_new_object();
5179 zl3vni
= zl3vni_lookup(vni
);
5181 zl3vni_print(zl3vni
, (void *)args
);
5183 zvni
= zvni_lookup(vni
);
5186 vty_out(vty
, "{}\n");
5188 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5192 zvni_print(zvni
, (void *)args
);
5196 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5197 json
, JSON_C_TO_STRING_PRETTY
));
5198 json_object_free(json
);
5202 /* Display all global details for EVPN */
5203 void zebra_vxlan_print_evpn(struct vty
*vty
, bool uj
)
5208 json_object
*json
= NULL
;
5209 struct zebra_ns
*zns
= NULL
;
5210 struct zebra_vrf
*zvrf
= NULL
;
5212 if (!is_evpn_enabled())
5215 zns
= zebra_ns_lookup(NS_DEFAULT
);
5219 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
5223 num_l3vnis
= hashcount(zns
->l3vni_table
);
5224 num_l2vnis
= hashcount(zvrf
->vni_table
);
5225 num_vnis
= num_l2vnis
+ num_l3vnis
;
5228 json
= json_object_new_object();
5229 json_object_string_add(json
, "advertiseGatewayMacip",
5230 zvrf
->advertise_gw_macip
? "Yes" : "No");
5231 json_object_int_add(json
, "numVnis", num_vnis
);
5232 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
5233 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
5235 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
5236 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
5237 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
5238 zvrf
->advertise_gw_macip
? "Yes" : "No");
5242 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5243 json
, JSON_C_TO_STRING_PRETTY
));
5244 json_object_free(json
);
5249 * Display VNI hash table (VTY command handler).
5251 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5254 json_object
*json
= NULL
;
5255 struct zebra_ns
*zns
= NULL
;
5258 if (!is_evpn_enabled())
5261 zns
= zebra_ns_lookup(NS_DEFAULT
);
5267 json
= json_object_new_object();
5269 vty_out(vty
, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
5270 "Type", "VxLAN IF", "# MACs", "# ARPs",
5271 "# Remote VTEPs", "Tenant VRF");
5276 /* Display all L2-VNIs */
5277 hash_iterate(zvrf
->vni_table
,
5278 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
5281 /* Display all L3-VNIs */
5282 hash_iterate(zns
->l3vni_table
,
5283 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
5287 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5288 json
, JSON_C_TO_STRING_PRETTY
));
5289 json_object_free(json
);
5294 * Handle neighbor delete notification from the kernel (on a VLAN device
5295 * / L3 interface). This may result in either the neighbor getting deleted
5296 * from our database or being re-added to the kernel (if it is a valid
5299 int zebra_vxlan_handle_kernel_neigh_del(struct interface
*ifp
,
5300 struct interface
*link_if
,
5303 char buf
[INET6_ADDRSTRLEN
];
5304 char buf2
[ETHER_ADDR_STRLEN
];
5305 zebra_neigh_t
*n
= NULL
;
5306 zebra_vni_t
*zvni
= NULL
;
5307 zebra_mac_t
*zmac
= NULL
;
5308 zebra_l3vni_t
*zl3vni
= NULL
;
5310 /* check if this is a remote neigh entry corresponding to remote
5313 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5315 return zl3vni_local_nh_del(zl3vni
, ip
);
5317 /* We are only interested in neighbors on an SVI that resides on top
5318 * of a VxLAN bridge.
5320 zvni
= zvni_from_svi(ifp
, link_if
);
5324 if (!zvni
->vxlan_if
) {
5326 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
5331 if (IS_ZEBRA_DEBUG_VXLAN
)
5332 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
5333 ipaddr2str(ip
, buf
, sizeof(buf
)), ifp
->name
,
5334 ifp
->ifindex
, zvni
->vni
);
5336 /* If entry doesn't exist, nothing to do. */
5337 n
= zvni_neigh_lookup(zvni
, ip
);
5341 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
5343 if (IS_ZEBRA_DEBUG_VXLAN
)
5345 "Trying to del a neigh %s without a mac %s on VNI %u",
5346 ipaddr2str(ip
, buf
, sizeof(buf
)),
5347 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
5353 /* If it is a remote entry, the kernel has aged this out or someone has
5354 * deleted it, it needs to be re-installed as Quagga is the owner.
5356 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
5357 zvni_neigh_install(zvni
, n
);
5361 /* Remove neighbor from BGP. */
5362 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
5363 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
, 0);
5365 /* Delete this neighbor entry. */
5366 zvni_neigh_del(zvni
, n
);
5368 /* see if the AUTO mac needs to be deleted */
5369 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
5370 && !listcount(zmac
->neigh_list
))
5371 zvni_mac_del(zvni
, zmac
);
5377 * Handle neighbor add or update notification from the kernel (on a VLAN
5378 * device / L3 interface). This is typically for a local neighbor but can
5379 * also be for a remote neighbor (e.g., ageout notification). It could
5380 * also be a "move" scenario.
5382 int zebra_vxlan_handle_kernel_neigh_update(struct interface
*ifp
,
5383 struct interface
*link_if
,
5385 struct ethaddr
*macaddr
,
5387 uint8_t ext_learned
,
5388 uint8_t router_flag
)
5390 char buf
[ETHER_ADDR_STRLEN
];
5391 char buf2
[INET6_ADDRSTRLEN
];
5392 zebra_vni_t
*zvni
= NULL
;
5393 zebra_l3vni_t
*zl3vni
= NULL
;
5395 /* check if this is a remote neigh entry corresponding to remote
5398 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5400 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
5402 /* We are only interested in neighbors on an SVI that resides on top
5403 * of a VxLAN bridge.
5405 zvni
= zvni_from_svi(ifp
, link_if
);
5409 if (IS_ZEBRA_DEBUG_VXLAN
)
5411 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
5412 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
5413 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5414 ifp
->ifindex
, state
, ext_learned
? "ext-learned " : "",
5415 router_flag
? "router " : "",
5418 /* Is this about a local neighbor or a remote one? */
5420 return zvni_local_neigh_update(zvni
, ifp
, ip
, macaddr
,
5423 return zvni_remote_neigh_update(zvni
, ifp
, ip
, macaddr
, state
);
5428 * Handle message from client to delete a remote MACIP for a VNI.
5430 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS
)
5434 struct ethaddr macaddr
;
5436 struct in_addr vtep_ip
;
5437 uint16_t l
= 0, ipa_len
;
5438 char buf
[ETHER_ADDR_STRLEN
];
5439 char buf1
[INET6_ADDRSTRLEN
];
5441 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5442 memset(&ip
, 0, sizeof(struct ipaddr
));
5443 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5447 while (l
< hdr
->length
) {
5448 /* Obtain each remote MACIP and process. */
5449 /* Message contains VNI, followed by MAC followed by IP (if any)
5450 * followed by remote VTEP IP.
5452 memset(&ip
, 0, sizeof(ip
));
5453 STREAM_GETL(s
, vni
);
5454 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5455 STREAM_GETL(s
, ipa_len
);
5457 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5459 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5461 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5462 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5463 l
+= IPV4_MAX_BYTELEN
;
5465 if (IS_ZEBRA_DEBUG_VXLAN
)
5467 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
5469 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5470 ipa_len
? " IP " : "",
5472 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5474 zebra_route_string(client
->proto
));
5476 process_remote_macip_del(vni
, &macaddr
, ipa_len
, &ip
, vtep_ip
);
5484 * Handle message from client to add a remote MACIP for a VNI. This
5485 * could be just the add of a MAC address or the add of a neighbor
5488 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS
)
5492 struct ethaddr macaddr
;
5494 struct in_addr vtep_ip
;
5495 uint16_t l
= 0, ipa_len
;
5498 char buf
[ETHER_ADDR_STRLEN
];
5499 char buf1
[INET6_ADDRSTRLEN
];
5501 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5502 memset(&ip
, 0, sizeof(struct ipaddr
));
5503 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5505 if (!EVPN_ENABLED(zvrf
)) {
5506 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
5512 while (l
< hdr
->length
) {
5513 /* Obtain each remote MACIP and process. */
5514 /* Message contains VNI, followed by MAC followed by IP (if any)
5515 * followed by remote VTEP IP.
5517 memset(&ip
, 0, sizeof(ip
));
5518 STREAM_GETL(s
, vni
);
5519 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5520 STREAM_GETL(s
, ipa_len
);
5522 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5524 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5526 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5527 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5528 l
+= IPV4_MAX_BYTELEN
;
5530 /* Get flags - sticky mac and/or gateway mac */
5531 STREAM_GETC(s
, flags
);
5533 STREAM_GETL(s
, seq
);
5536 if (IS_ZEBRA_DEBUG_VXLAN
)
5538 "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
5540 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5541 ipa_len
? " IP " : "",
5543 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5544 flags
, seq
, inet_ntoa(vtep_ip
),
5545 zebra_route_string(client
->proto
));
5547 process_remote_macip_add(vni
, &macaddr
, ipa_len
, &ip
,
5548 flags
, seq
, vtep_ip
);
5556 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5557 * us, this must involve a multihoming scenario. Treat this as implicit delete
5558 * of any prior local MAC.
5560 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5561 struct interface
*br_if
,
5562 struct ethaddr
*macaddr
, vlanid_t vid
)
5564 struct zebra_if
*zif
;
5565 struct zebra_l2info_vxlan
*vxl
;
5569 char buf
[ETHER_ADDR_STRLEN
];
5573 vxl
= &zif
->l2info
.vxl
;
5576 /* Check if EVPN is enabled. */
5577 if (!is_evpn_enabled())
5580 /* Locate hash entry; it is expected to exist. */
5581 zvni
= zvni_lookup(vni
);
5585 /* If entry doesn't exist, nothing to do. */
5586 mac
= zvni_mac_lookup(zvni
, macaddr
);
5590 /* Is it a local entry? */
5591 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5594 if (IS_ZEBRA_DEBUG_VXLAN
)
5596 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5597 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5600 /* Remove MAC from BGP. */
5601 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5604 * If there are no neigh associated with the mac delete the mac
5605 * else mark it as AUTO for forward reference
5607 if (!listcount(mac
->neigh_list
)) {
5608 zvni_mac_del(zvni
, mac
);
5610 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5611 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5618 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5619 * This can happen because the remote MAC entries are also added as "dynamic",
5620 * so the kernel can ageout the entry.
5622 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5623 struct interface
*br_if
,
5624 struct ethaddr
*macaddr
, vlanid_t vid
)
5626 struct zebra_if
*zif
= NULL
;
5627 struct zebra_l2info_vxlan
*vxl
= NULL
;
5629 zebra_vni_t
*zvni
= NULL
;
5630 zebra_l3vni_t
*zl3vni
= NULL
;
5631 zebra_mac_t
*mac
= NULL
;
5632 char buf
[ETHER_ADDR_STRLEN
];
5636 vxl
= &zif
->l2info
.vxl
;
5639 /* Check if EVPN is enabled. */
5640 if (!is_evpn_enabled())
5643 /* check if this is a remote RMAC and readd simillar to remote macs */
5644 zl3vni
= zl3vni_lookup(vni
);
5646 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5648 /* Locate hash entry; it is expected to exist. */
5649 zvni
= zvni_lookup(vni
);
5653 /* If entry doesn't exist, nothing to do. */
5654 mac
= zvni_mac_lookup(zvni
, macaddr
);
5658 /* Is it a remote entry? */
5659 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5662 if (IS_ZEBRA_DEBUG_VXLAN
)
5663 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5664 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5667 zvni_mac_install(zvni
, mac
);
5672 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5674 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5675 struct ethaddr
*macaddr
, vlanid_t vid
)
5679 char buf
[ETHER_ADDR_STRLEN
];
5681 /* We are interested in MACs only on ports or (port, VLAN) that
5684 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5687 if (!zvni
->vxlan_if
) {
5689 "VNI %u hash %p doesn't have intf upon local MAC DEL",
5694 if (IS_ZEBRA_DEBUG_VXLAN
)
5695 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u",
5696 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5697 ifp
->ifindex
, vid
, zvni
->vni
);
5699 /* If entry doesn't exist, nothing to do. */
5700 mac
= zvni_mac_lookup(zvni
, macaddr
);
5704 /* Is it a local entry? */
5705 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5708 /* Update all the neigh entries associated with this mac */
5709 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5711 /* Remove MAC from BGP. */
5712 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5715 * If there are no neigh associated with the mac delete the mac
5716 * else mark it as AUTO for forward reference
5718 if (!listcount(mac
->neigh_list
)) {
5719 zvni_mac_del(zvni
, mac
);
5721 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5722 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5729 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5731 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5732 struct interface
*br_if
,
5733 struct ethaddr
*macaddr
, vlanid_t vid
,
5738 char buf
[ETHER_ADDR_STRLEN
];
5739 bool mac_sticky
= false;
5740 bool inform_client
= false;
5741 bool upd_neigh
= false;
5743 /* We are interested in MACs only on ports or (port, VLAN) that
5746 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5748 if (IS_ZEBRA_DEBUG_VXLAN
)
5750 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5751 sticky
? "sticky " : "",
5752 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5753 ifp
->name
, ifp
->ifindex
, vid
);
5757 if (!zvni
->vxlan_if
) {
5759 "VNI %u hash %p doesn't have intf upon local MAC ADD",
5764 /* Check if we need to create or update or it is a NO-OP. */
5765 mac
= zvni_mac_lookup(zvni
, macaddr
);
5767 if (IS_ZEBRA_DEBUG_VXLAN
)
5769 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
5770 sticky
? "sticky " : "",
5771 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5772 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5774 mac
= zvni_mac_add(zvni
, macaddr
);
5777 ZEBRA_ERR_MAC_ADD_FAILED
,
5778 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
5779 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5780 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5783 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5784 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5785 mac
->fwd_info
.local
.vid
= vid
;
5787 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5788 inform_client
= true;
5791 if (IS_ZEBRA_DEBUG_VXLAN
)
5793 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
5794 sticky
? "sticky " : "",
5795 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5796 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
,
5799 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5800 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
5804 * Update any changes and if changes are relevant to
5807 if (mac_sticky
== sticky
5808 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5809 && mac
->fwd_info
.local
.vid
== vid
) {
5810 if (IS_ZEBRA_DEBUG_VXLAN
)
5812 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5813 "entry exists and has not changed ",
5814 sticky
? "sticky " : "",
5815 prefix_mac2str(macaddr
, buf
,
5817 ifp
->name
, ifp
->ifindex
, vid
,
5821 if (mac_sticky
!= sticky
) {
5823 SET_FLAG(mac
->flags
,
5826 UNSET_FLAG(mac
->flags
,
5828 inform_client
= true;
5831 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5832 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5833 mac
->fwd_info
.local
.vid
= vid
;
5835 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
) ||
5836 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
5839 * MAC has either moved or was "internally" created due
5840 * to a neighbor learn and is now actually learnt. If
5841 * it was learnt as a remote sticky MAC, this is an
5844 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5846 ZEBRA_ERR_STICKY_MAC_ALREADY_LEARNT
,
5847 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
5848 prefix_mac2str(macaddr
, buf
,
5850 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5855 /* If an actual move, compute MAC's seq number */
5856 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5857 mac
->loc_seq
= MAX(mac
->rem_seq
+ 1,
5859 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5860 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5861 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5862 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5863 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5864 mac
->fwd_info
.local
.vid
= vid
;
5866 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5868 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5870 * We have to inform BGP of this MAC as well as process
5873 inform_client
= true;
5878 /* Inform BGP if required. */
5879 if (inform_client
) {
5880 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5881 mac
->flags
, mac
->loc_seq
))
5885 /* Process all neighbors associated with this MAC, if required. */
5887 zvni_process_neigh_on_local_mac_change(zvni
, mac
, 0);
5893 * Handle message from client to delete a remote VTEP for a VNI.
5895 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS
)
5898 unsigned short l
= 0;
5900 struct in_addr vtep_ip
;
5902 zebra_vtep_t
*zvtep
;
5903 struct interface
*ifp
;
5904 struct zebra_if
*zif
;
5906 if (!is_evpn_enabled()) {
5908 "%s: EVPN is not enabled yet we have received a vtep del command",
5909 __PRETTY_FUNCTION__
);
5913 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5914 zlog_debug("Recv MACIP DEL for non-default VRF %u",
5921 while (l
< hdr
->length
) {
5922 /* Obtain each remote VTEP and process. */
5923 STREAM_GETL(s
, vni
);
5925 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5926 l
+= IPV4_MAX_BYTELEN
;
5928 if (IS_ZEBRA_DEBUG_VXLAN
)
5929 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5930 inet_ntoa(vtep_ip
), vni
,
5931 zebra_route_string(client
->proto
));
5933 /* Locate VNI hash entry - expected to exist. */
5934 zvni
= zvni_lookup(vni
);
5936 if (IS_ZEBRA_DEBUG_VXLAN
)
5938 "Failed to locate VNI hash upon remote VTEP DEL, "
5944 ifp
= zvni
->vxlan_if
;
5947 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5953 /* If down or not mapped to a bridge, we're done. */
5954 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
5957 /* If the remote VTEP does not exist, there's nothing more to
5959 * Otherwise, uninstall any remote MACs pointing to this VTEP
5961 * then, the VTEP entry itself and remove it.
5963 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
5967 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
5968 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
5969 zvni_vtep_uninstall(zvni
, &vtep_ip
);
5970 zvni_vtep_del(zvni
, zvtep
);
5978 * Handle message from client to add a remote VTEP for a VNI.
5980 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS
)
5983 unsigned short l
= 0;
5985 struct in_addr vtep_ip
;
5987 struct interface
*ifp
;
5988 struct zebra_if
*zif
;
5990 if (!is_evpn_enabled()) {
5992 "%s: EVPN not enabled yet we received a vtep_add zapi call",
5993 __PRETTY_FUNCTION__
);
5997 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5998 zlog_debug("Recv MACIP ADD for non-default VRF %u",
6005 while (l
< hdr
->length
) {
6006 /* Obtain each remote VTEP and process. */
6007 STREAM_GETL(s
, vni
);
6009 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
6010 l
+= IPV4_MAX_BYTELEN
;
6012 if (IS_ZEBRA_DEBUG_VXLAN
)
6013 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
6014 inet_ntoa(vtep_ip
), vni
,
6015 zebra_route_string(client
->proto
));
6017 /* Locate VNI hash entry - expected to exist. */
6018 zvni
= zvni_lookup(vni
);
6021 ZEBRA_ERR_VTEP_ADD_FAILED
,
6022 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
6027 ifp
= zvni
->vxlan_if
;
6030 ZEBRA_ERR_VTEP_ADD_FAILED
,
6031 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
6038 /* If down or not mapped to a bridge, we're done. */
6039 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6042 /* If the remote VTEP already exists,
6043 there's nothing more to do. */
6044 if (zvni_vtep_find(zvni
, &vtep_ip
))
6047 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
6048 flog_err(ZEBRA_ERR_VTEP_ADD_FAILED
,
6049 "Failed to add remote VTEP, VNI %u zvni %p",
6054 zvni_vtep_install(zvni
, &vtep_ip
);
6062 * Add/Del gateway macip to evpn
6064 * 1. SVI interface on a vlan aware bridge
6065 * 2. SVI interface on a vlan unaware bridge
6066 * 3. vrr interface (MACVLAN) associated to a SVI
6067 * We advertise macip routes for an interface if it is associated to VxLan vlan
6069 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
6073 struct ethaddr macaddr
;
6074 zebra_vni_t
*zvni
= NULL
;
6076 memset(&ip
, 0, sizeof(struct ipaddr
));
6077 memset(&macaddr
, 0, sizeof(struct ethaddr
));
6079 /* Check if EVPN is enabled. */
6080 if (!is_evpn_enabled())
6083 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
6084 struct interface
*svi_if
=
6085 NULL
; /* SVI corresponding to the MACVLAN */
6086 struct zebra_if
*ifp_zif
=
6087 NULL
; /* Zebra daemon specific info for MACVLAN */
6088 struct zebra_if
*svi_if_zif
=
6089 NULL
; /* Zebra daemon specific info for SVI*/
6091 ifp_zif
= ifp
->info
;
6096 * for a MACVLAN interface the link represents the svi_if
6098 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
6099 ifp_zif
->link_ifindex
);
6101 zlog_debug("MACVLAN %s(%u) without link information",
6102 ifp
->name
, ifp
->ifindex
);
6106 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
6108 * If it is a vlan aware bridge then the link gives the
6109 * bridge information
6111 struct interface
*svi_if_link
= NULL
;
6113 svi_if_zif
= svi_if
->info
;
6115 svi_if_link
= if_lookup_by_index_per_ns(
6116 zebra_ns_lookup(NS_DEFAULT
),
6117 svi_if_zif
->link_ifindex
);
6118 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
6120 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
6122 * If it is a vlan unaware bridge then svi is the bridge
6125 zvni
= zvni_from_svi(svi_if
, svi_if
);
6127 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
6128 struct zebra_if
*svi_if_zif
=
6129 NULL
; /* Zebra daemon specific info for SVI */
6130 struct interface
*svi_if_link
=
6131 NULL
; /* link info for the SVI = bridge info */
6133 svi_if_zif
= ifp
->info
;
6135 svi_if_link
= if_lookup_by_index_per_ns(
6136 zebra_ns_lookup(NS_DEFAULT
),
6137 svi_if_zif
->link_ifindex
);
6139 zvni
= zvni_from_svi(ifp
, svi_if_link
);
6141 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
6142 zvni
= zvni_from_svi(ifp
, ifp
);
6148 if (!zvni
->vxlan_if
) {
6149 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
6155 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
6157 if (p
->family
== AF_INET
) {
6158 ip
.ipa_type
= IPADDR_V4
;
6159 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
6160 sizeof(struct in_addr
));
6161 } else if (p
->family
== AF_INET6
) {
6162 ip
.ipa_type
= IPADDR_V6
;
6163 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
6164 sizeof(struct in6_addr
));
6169 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
6171 zvni_gw_macip_del(ifp
, zvni
, &ip
);
6177 * Handle SVI interface going down.
6178 * SVI can be associated to either L3-VNI or L2-VNI.
6179 * For L2-VNI: At this point, this is a NOP since
6180 * the kernel deletes the neighbor entries on this SVI (if any).
6181 * We only need to update the vrf corresponding to zvni.
6182 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
6185 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
6187 zebra_l3vni_t
*zl3vni
= NULL
;
6189 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6192 /* process l3-vni down */
6193 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6195 /* remove association with svi-if */
6196 zl3vni
->svi_if
= NULL
;
6198 zebra_vni_t
*zvni
= NULL
;
6200 /* since we dont have svi corresponding to zvni, we associate it
6201 * to default vrf. Note: the corresponding neigh entries on the
6202 * SVI would have already been deleted */
6203 zvni
= zvni_from_svi(ifp
, link_if
);
6205 zvni
->vrf_id
= VRF_DEFAULT
;
6207 /* update the tenant vrf in BGP */
6208 zvni_send_add_to_client(zvni
);
6215 * Handle SVI interface coming up.
6216 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
6218 * For L2-VNI: we need to install any remote neighbors entried (used for
6220 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
6222 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
6224 zebra_vni_t
*zvni
= NULL
;
6225 zebra_l3vni_t
*zl3vni
= NULL
;
6227 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6230 /* associate with svi */
6231 zl3vni
->svi_if
= ifp
;
6233 /* process oper-up */
6234 if (is_l3vni_oper_up(zl3vni
))
6235 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6238 /* process SVI up for l2-vni */
6239 struct neigh_walk_ctx n_wctx
;
6241 zvni
= zvni_from_svi(ifp
, link_if
);
6245 if (!zvni
->vxlan_if
) {
6247 "VNI %u hash %p doesn't have intf upon SVI up",
6252 if (IS_ZEBRA_DEBUG_VXLAN
)
6254 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
6255 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
6256 vrf_id_to_name(ifp
->vrf_id
));
6258 /* update the vrf information for l2-vni and inform bgp */
6259 zvni
->vrf_id
= ifp
->vrf_id
;
6260 zvni_send_add_to_client(zvni
);
6262 /* Install any remote neighbors for this VNI. */
6263 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6265 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6273 * Handle VxLAN interface down
6275 int zebra_vxlan_if_down(struct interface
*ifp
)
6278 struct zebra_if
*zif
= NULL
;
6279 struct zebra_l2info_vxlan
*vxl
= NULL
;
6280 zebra_l3vni_t
*zl3vni
= NULL
;
6283 /* Check if EVPN is enabled. */
6284 if (!is_evpn_enabled())
6289 vxl
= &zif
->l2info
.vxl
;
6292 zl3vni
= zl3vni_lookup(vni
);
6294 /* process-if-down for l3-vni */
6295 if (IS_ZEBRA_DEBUG_VXLAN
)
6296 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
6299 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6301 /* process if-down for l2-vni */
6302 if (IS_ZEBRA_DEBUG_VXLAN
)
6303 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
6306 /* Locate hash entry; it is expected to exist. */
6307 zvni
= zvni_lookup(vni
);
6310 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6311 ifp
->name
, ifp
->ifindex
, vni
);
6315 assert(zvni
->vxlan_if
== ifp
);
6317 /* Delete this VNI from BGP. */
6318 zvni_send_del_to_client(zvni
->vni
);
6320 /* Free up all neighbors and MACs, if any. */
6321 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6322 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6324 /* Free up all remote VTEPs, if any. */
6325 zvni_vtep_del_all(zvni
, 1);
6331 * Handle VxLAN interface up - update BGP if required.
6333 int zebra_vxlan_if_up(struct interface
*ifp
)
6336 struct zebra_if
*zif
= NULL
;
6337 struct zebra_l2info_vxlan
*vxl
= NULL
;
6338 zebra_vni_t
*zvni
= NULL
;
6339 zebra_l3vni_t
*zl3vni
= NULL
;
6341 /* Check if EVPN is enabled. */
6342 if (!is_evpn_enabled())
6347 vxl
= &zif
->l2info
.vxl
;
6350 zl3vni
= zl3vni_lookup(vni
);
6353 if (IS_ZEBRA_DEBUG_VXLAN
)
6354 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp
->name
,
6357 /* we need to associate with SVI, if any, we can associate with
6358 * svi-if only after association with vxlan-intf is complete
6360 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6362 if (is_l3vni_oper_up(zl3vni
))
6363 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6365 /* Handle L2-VNI add */
6366 struct interface
*vlan_if
= NULL
;
6368 if (IS_ZEBRA_DEBUG_VXLAN
)
6369 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
6372 /* Locate hash entry; it is expected to exist. */
6373 zvni
= zvni_lookup(vni
);
6376 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6377 ifp
->name
, ifp
->ifindex
, vni
);
6381 assert(zvni
->vxlan_if
== ifp
);
6382 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6383 zif
->brslave_info
.br_if
);
6385 zvni
->vrf_id
= vlan_if
->vrf_id
;
6386 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6388 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6391 /* If part of a bridge, inform BGP about this VNI. */
6392 /* Also, read and populate local MACs and neighbors. */
6393 if (zif
->brslave_info
.br_if
) {
6394 zvni_send_add_to_client(zvni
);
6395 zvni_read_mac_neigh(zvni
, ifp
);
6403 * Handle VxLAN interface delete. Locate and remove entry in hash table
6404 * and update BGP, if required.
6406 int zebra_vxlan_if_del(struct interface
*ifp
)
6409 struct zebra_if
*zif
= NULL
;
6410 struct zebra_l2info_vxlan
*vxl
= NULL
;
6411 zebra_vni_t
*zvni
= NULL
;
6412 zebra_l3vni_t
*zl3vni
= NULL
;
6414 /* Check if EVPN is enabled. */
6415 if (!is_evpn_enabled())
6420 vxl
= &zif
->l2info
.vxl
;
6423 zl3vni
= zl3vni_lookup(vni
);
6426 if (IS_ZEBRA_DEBUG_VXLAN
)
6427 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
6430 /* process oper-down for l3-vni */
6431 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6433 /* remove the association with vxlan_if */
6434 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6435 zl3vni
->vxlan_if
= NULL
;
6438 /* process if-del for l2-vni*/
6439 if (IS_ZEBRA_DEBUG_VXLAN
)
6440 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
6443 /* Locate hash entry; it is expected to exist. */
6444 zvni
= zvni_lookup(vni
);
6447 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6448 ifp
->name
, ifp
->ifindex
, vni
);
6452 /* remove from l3-vni list */
6453 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6455 listnode_delete(zl3vni
->l2vnis
, zvni
);
6457 /* Delete VNI from BGP. */
6458 zvni_send_del_to_client(zvni
->vni
);
6460 /* Free up all neighbors and MAC, if any. */
6461 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6462 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6464 /* Free up all remote VTEPs, if any. */
6465 zvni_vtep_del_all(zvni
, 0);
6467 /* Delete the hash entry. */
6468 if (zvni_del(zvni
)) {
6469 flog_err(ZEBRA_ERR_VNI_DEL_FAILED
,
6470 "Failed to del VNI hash %p, IF %s(%u) VNI %u",
6471 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6479 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6481 int zebra_vxlan_if_update(struct interface
*ifp
, uint16_t chgflags
)
6484 struct zebra_if
*zif
= NULL
;
6485 struct zebra_l2info_vxlan
*vxl
= NULL
;
6486 zebra_vni_t
*zvni
= NULL
;
6487 zebra_l3vni_t
*zl3vni
= NULL
;
6489 /* Check if EVPN is enabled. */
6490 if (!is_evpn_enabled())
6495 vxl
= &zif
->l2info
.vxl
;
6498 zl3vni
= zl3vni_lookup(vni
);
6501 if (IS_ZEBRA_DEBUG_VXLAN
)
6503 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6504 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6505 inet_ntoa(vxl
->vtep_ip
),
6506 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6508 /* Removed from bridge? Cleanup and return */
6509 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6510 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6511 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6515 /* access-vlan change - process oper down, associate with new
6516 * svi_if and then process oper up again
6518 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6519 if (if_is_operative(ifp
)) {
6520 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6521 zl3vni
->svi_if
= NULL
;
6522 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6523 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6524 if (is_l3vni_oper_up(zl3vni
))
6525 zebra_vxlan_process_l3vni_oper_up(
6531 * local-ip change - process oper down, associate with new
6532 * local-ip and then process oper up again
6534 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
6535 if (if_is_operative(ifp
)) {
6536 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6537 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6538 if (is_l3vni_oper_up(zl3vni
))
6539 zebra_vxlan_process_l3vni_oper_up(
6544 /* Update local tunnel IP. */
6545 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6547 /* if we have a valid new master, process l3-vni oper up */
6548 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6549 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
6550 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6554 /* Update VNI hash. */
6555 zvni
= zvni_lookup(vni
);
6558 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6559 ifp
->name
, ifp
->ifindex
, vni
);
6563 if (IS_ZEBRA_DEBUG_VXLAN
)
6565 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6566 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6567 inet_ntoa(vxl
->vtep_ip
),
6568 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6570 /* Removed from bridge? Cleanup and return */
6571 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6572 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6573 /* Delete from client, remove all remote VTEPs */
6574 /* Also, free up all MACs and neighbors. */
6575 zvni_send_del_to_client(zvni
->vni
);
6576 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6577 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6578 zvni_vtep_del_all(zvni
, 1);
6582 /* Handle other changes. */
6583 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6584 /* Remove all existing local neigh and MACs for this VNI
6585 * (including from BGP)
6587 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6588 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6591 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6592 zvni
->vxlan_if
= ifp
;
6594 /* Take further actions needed.
6595 * Note that if we are here, there is a change of interest.
6597 /* If down or not mapped to a bridge, we're done. */
6598 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6601 /* Inform BGP, if there is a change of interest. */
6603 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6604 zvni_send_add_to_client(zvni
);
6606 /* If there is a valid new master or a VLAN mapping change,
6607 * read and populate local MACs and neighbors.
6608 * Also, reinstall any remote MACs and neighbors
6609 * for this VNI (based on new VLAN).
6611 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6612 zvni_read_mac_neigh(zvni
, ifp
);
6613 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6614 struct mac_walk_ctx m_wctx
;
6615 struct neigh_walk_ctx n_wctx
;
6617 zvni_read_mac_neigh(zvni
, ifp
);
6619 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6621 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
,
6624 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6626 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6635 * Handle VxLAN interface add.
6637 int zebra_vxlan_if_add(struct interface
*ifp
)
6640 struct zebra_if
*zif
= NULL
;
6641 struct zebra_l2info_vxlan
*vxl
= NULL
;
6642 zebra_vni_t
*zvni
= NULL
;
6643 zebra_l3vni_t
*zl3vni
= NULL
;
6645 /* Check if EVPN is enabled. */
6646 if (!is_evpn_enabled())
6651 vxl
= &zif
->l2info
.vxl
;
6654 zl3vni
= zl3vni_lookup(vni
);
6657 /* process if-add for l3-vni*/
6658 if (IS_ZEBRA_DEBUG_VXLAN
)
6660 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6661 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6662 inet_ntoa(vxl
->vtep_ip
),
6663 zif
->brslave_info
.bridge_ifindex
);
6665 /* associate with vxlan_if */
6666 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6667 zl3vni
->vxlan_if
= ifp
;
6669 /* Associate with SVI, if any. We can associate with svi-if only
6670 * after association with vxlan_if is complete */
6671 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6673 if (is_l3vni_oper_up(zl3vni
))
6674 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6677 /* process if-add for l2-vni */
6678 struct interface
*vlan_if
= NULL
;
6680 /* Create or update VNI hash. */
6681 zvni
= zvni_lookup(vni
);
6683 zvni
= zvni_add(vni
);
6686 ZEBRA_ERR_VNI_ADD_FAILED
,
6687 "Failed to add VNI hash, IF %s(%u) VNI %u",
6688 ifp
->name
, ifp
->ifindex
, vni
);
6693 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6694 zvni
->vxlan_if
= ifp
;
6695 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6696 zif
->brslave_info
.br_if
);
6698 zvni
->vrf_id
= vlan_if
->vrf_id
;
6699 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6701 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6704 if (IS_ZEBRA_DEBUG_VXLAN
)
6706 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6708 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
)
6710 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6711 inet_ntoa(vxl
->vtep_ip
),
6712 zif
->brslave_info
.bridge_ifindex
);
6714 /* If down or not mapped to a bridge, we're done. */
6715 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6719 zvni_send_add_to_client(zvni
);
6721 /* Read and populate local MACs and neighbors */
6722 zvni_read_mac_neigh(zvni
, ifp
);
6728 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
, vni_t vni
,
6729 char *err
, int err_str_sz
, int filter
,
6732 zebra_l3vni_t
*zl3vni
= NULL
;
6733 struct zebra_vrf
*zvrf_default
= NULL
;
6735 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6739 if (IS_ZEBRA_DEBUG_VXLAN
)
6740 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf
), vni
,
6741 add
? "ADD" : "DEL");
6745 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6747 /* check if the vni is already present under zvrf */
6749 snprintf(err
, err_str_sz
,
6750 "VNI is already configured under the vrf");
6754 /* check if this VNI is already present in the system */
6755 zl3vni
= zl3vni_lookup(vni
);
6757 snprintf(err
, err_str_sz
,
6758 "VNI is already configured as L3-VNI");
6762 /* add the L3-VNI to the global table */
6763 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6765 snprintf(err
, err_str_sz
, "Could not add L3-VNI");
6769 /* associate the vrf with vni */
6772 /* set the filter in l3vni to denote if we are using l3vni only
6776 SET_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
);
6778 /* associate with vxlan-intf;
6779 * we need to associate with the vxlan-intf first
6781 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6783 /* associate with corresponding SVI interface, we can associate
6784 * with svi-if only after vxlan interface association is
6787 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6789 /* formulate l2vni list */
6790 hash_iterate(zvrf_default
->vni_table
, zvni_add_to_l3vni_list
,
6793 if (is_l3vni_oper_up(zl3vni
))
6794 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6797 zl3vni
= zl3vni_lookup(vni
);
6799 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6803 if (filter
&& !CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)) {
6804 snprintf(err
, ERR_STR_SZ
,
6805 "prefix-routes-only is not set for the vni");
6809 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6811 /* delete and uninstall all rmacs */
6812 hash_iterate(zl3vni
->rmac_table
, zl3vni_del_rmac_hash_entry
,
6815 /* delete and uninstall all next-hops */
6816 hash_iterate(zl3vni
->nh_table
, zl3vni_del_nh_hash_entry
,
6822 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6827 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6829 zebra_l3vni_t
*zl3vni
= NULL
;
6832 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6836 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6837 if (is_l3vni_oper_up(zl3vni
))
6838 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6842 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6844 zebra_l3vni_t
*zl3vni
= NULL
;
6847 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6851 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6852 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6856 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6858 zebra_l3vni_t
*zl3vni
= NULL
;
6862 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6868 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6874 * Handle message from client to enable/disable advertisement of g/w macip
6877 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS
)
6882 zebra_vni_t
*zvni
= NULL
;
6883 struct interface
*ifp
= NULL
;
6884 struct zebra_if
*zif
= NULL
;
6885 struct zebra_l2info_vxlan zl2_info
;
6886 struct interface
*vlan_if
= NULL
;
6888 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6889 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
6895 STREAM_GETC(s
, advertise
);
6896 vni
= stream_get3(s
);
6898 zvni
= zvni_lookup(vni
);
6902 if (zvni
->advertise_subnet
== advertise
)
6905 if (IS_ZEBRA_DEBUG_VXLAN
)
6906 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
6907 advertise
? "enabled" : "disabled", vni
,
6908 zvni
->advertise_subnet
? "enabled" : "disabled");
6911 zvni
->advertise_subnet
= advertise
;
6913 ifp
= zvni
->vxlan_if
;
6919 /* If down or not mapped to a bridge, we're done. */
6920 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6923 zl2_info
= zif
->l2info
.vxl
;
6926 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
6930 if (zvni
->advertise_subnet
)
6931 zvni_advertise_subnet(zvni
, vlan_if
, 1);
6933 zvni_advertise_subnet(zvni
, vlan_if
, 0);
6940 * Handle message from client to enable/disable advertisement of g/w macip
6943 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS
)
6948 zebra_vni_t
*zvni
= NULL
;
6949 struct interface
*ifp
= NULL
;
6951 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6952 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
6958 STREAM_GETC(s
, advertise
);
6959 STREAM_GETL(s
, vni
);
6962 if (IS_ZEBRA_DEBUG_VXLAN
)
6963 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6964 advertise
? "enabled" : "disabled",
6965 advertise_gw_macip_enabled(NULL
)
6969 if (zvrf
->advertise_gw_macip
== advertise
)
6972 zvrf
->advertise_gw_macip
= advertise
;
6974 if (advertise_gw_macip_enabled(zvni
))
6975 hash_iterate(zvrf
->vni_table
,
6976 zvni_gw_macip_add_for_vni_hash
, NULL
);
6978 hash_iterate(zvrf
->vni_table
,
6979 zvni_gw_macip_del_for_vni_hash
, NULL
);
6982 struct zebra_if
*zif
= NULL
;
6983 struct zebra_l2info_vxlan zl2_info
;
6984 struct interface
*vlan_if
= NULL
;
6985 struct interface
*vrr_if
= NULL
;
6987 zvni
= zvni_lookup(vni
);
6991 if (IS_ZEBRA_DEBUG_VXLAN
)
6993 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6994 advertise
? "enabled" : "disabled", vni
,
6995 advertise_gw_macip_enabled(zvni
) ? "enabled"
6998 if (zvni
->advertise_gw_macip
== advertise
)
7001 zvni
->advertise_gw_macip
= advertise
;
7003 ifp
= zvni
->vxlan_if
;
7009 /* If down or not mapped to a bridge, we're done. */
7010 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
7013 zl2_info
= zif
->l2info
.vxl
;
7015 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
7016 zif
->brslave_info
.br_if
);
7020 if (advertise_gw_macip_enabled(zvni
)) {
7021 /* Add primary SVI MAC-IP */
7022 zvni_add_macip_for_intf(vlan_if
, zvni
);
7024 /* Add VRR MAC-IP - if any*/
7025 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7027 zvni_add_macip_for_intf(vrr_if
, zvni
);
7029 /* Del primary MAC-IP */
7030 zvni_del_macip_for_intf(vlan_if
, zvni
);
7032 /* Del VRR MAC-IP - if any*/
7033 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7035 zvni_del_macip_for_intf(vrr_if
, zvni
);
7045 * Handle message from client to learn (or stop learning) about VNIs and MACs.
7046 * When enabled, the VNI hash table will be built and MAC FDB table read;
7047 * when disabled, the entries should be deleted and remote VTEPs and MACs
7048 * uninstalled from the kernel.
7050 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS
)
7052 struct stream
*s
= NULL
;
7054 struct zebra_ns
*zns
= NULL
;
7056 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
7057 zlog_debug("EVPN VNI Adv for non-default VRF %u",
7063 STREAM_GETC(s
, advertise
);
7065 if (IS_ZEBRA_DEBUG_VXLAN
)
7066 zlog_debug("EVPN VNI Adv %s, currently %s",
7067 advertise
? "enabled" : "disabled",
7068 is_evpn_enabled() ? "enabled" : "disabled");
7070 if (zvrf
->advertise_all_vni
== advertise
)
7073 zvrf
->advertise_all_vni
= advertise
;
7074 if (is_evpn_enabled()) {
7075 /* Build VNI hash table and inform BGP. */
7076 zvni_build_hash_table();
7078 /* Add all SVI (L3 GW) MACs to BGP*/
7079 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
7082 /* Read the MAC FDB */
7083 macfdb_read(zvrf
->zns
);
7085 /* Read neighbors */
7086 neigh_read(zvrf
->zns
);
7088 /* Cleanup VTEPs for all VNIs - uninstall from
7089 * kernel and free entries.
7091 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7093 /* cleanup all l3vnis */
7094 zns
= zebra_ns_lookup(NS_DEFAULT
);
7098 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
7106 * Allocate VNI hash table for this VRF and do other initialization.
7107 * NOTE: Currently supported only for default VRF.
7109 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
7113 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
7114 "Zebra VRF VNI Table");
7117 /* Cleanup VNI info, but don't free the table. */
7118 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
7122 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7125 /* Close all VNI handling */
7126 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
7130 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7131 hash_free(zvrf
->vni_table
);
7134 /* init the l3vni table */
7135 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
7137 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
7138 "Zebra VRF L3 VNI table");
7141 /* free l3vni table */
7142 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
7144 hash_free(zns
->l3vni_table
);
7147 /* get the l3vni svi ifindex */
7148 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
7150 zebra_l3vni_t
*zl3vni
= NULL
;
7152 zl3vni
= zl3vni_from_vrf(vrf_id
);
7153 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
7156 return zl3vni
->svi_if
->ifindex
;