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 void *zvni_neigh_alloc(void *p
);
85 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
87 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
88 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
89 struct in_addr
*r_vtep_ip
);
90 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
92 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
);
93 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
94 struct ethaddr
*macaddr
,
95 uint8_t flags
, uint32_t seq
);
96 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
97 struct ethaddr
*macaddr
,
99 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
100 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
);
101 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
102 struct interface
*br_if
);
103 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
);
105 /* l3-vni next-hop neigh related APIs */
106 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
,
108 static void *zl3vni_nh_alloc(void *p
);
109 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
,
110 struct ipaddr
*vtep_ip
,
111 struct ethaddr
*rmac
);
112 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
113 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
114 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
);
116 /* l3-vni rmac related APIs */
117 static void zl3vni_print_rmac_hash(struct hash_backet
*, void *);
118 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
119 struct ethaddr
*rmac
);
120 static void *zl3vni_rmac_alloc(void *p
);
121 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
,
122 struct ethaddr
*rmac
);
123 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
124 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
125 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
);
127 /* l3-vni related APIs*/
128 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
);
129 static void *zl3vni_alloc(void *p
);
130 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
);
131 static int zl3vni_del(zebra_l3vni_t
*zl3vni
);
132 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t
);
133 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
134 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
135 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
);
136 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
);
138 static unsigned int mac_hash_keymake(void *p
);
139 static bool mac_cmp(const void *p1
, const void *p2
);
140 static void *zvni_mac_alloc(void *p
);
141 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
142 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
143 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
144 struct in_addr
*r_vtep_ip
);
145 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
147 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
);
148 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
149 uint8_t flags
, uint32_t seq
);
150 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
152 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
153 struct interface
*br_if
, vlanid_t vid
);
154 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
155 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
156 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
);
158 static unsigned int vni_hash_keymake(void *p
);
159 static void *zvni_alloc(void *p
);
160 static zebra_vni_t
*zvni_lookup(vni_t vni
);
161 static zebra_vni_t
*zvni_add(vni_t vni
);
162 static int zvni_del(zebra_vni_t
*zvni
);
163 static int zvni_send_add_to_client(zebra_vni_t
*zvni
);
164 static int zvni_send_del_to_client(vni_t vni
);
165 static void zvni_build_hash_table();
166 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
);
167 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
168 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
169 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
);
170 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
);
171 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
172 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
);
173 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
174 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
);
175 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
176 struct ethaddr
*macaddr
, struct ipaddr
*ip
);
177 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
179 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
);
180 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
);
181 static int remote_neigh_count(zebra_mac_t
*zmac
);
182 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
);
184 /* Private functions */
185 static int host_rb_entry_compare(const struct host_rb_entry
*hle1
,
186 const struct host_rb_entry
*hle2
)
188 if (hle1
->p
.family
< hle2
->p
.family
)
191 if (hle1
->p
.family
> hle2
->p
.family
)
194 if (hle1
->p
.prefixlen
< hle2
->p
.prefixlen
)
197 if (hle1
->p
.prefixlen
> hle2
->p
.prefixlen
)
200 if (hle1
->p
.family
== AF_INET
) {
201 if (hle1
->p
.u
.prefix4
.s_addr
< hle2
->p
.u
.prefix4
.s_addr
)
204 if (hle1
->p
.u
.prefix4
.s_addr
> hle2
->p
.u
.prefix4
.s_addr
)
208 } else if (hle1
->p
.family
== AF_INET6
) {
209 return memcmp(&hle1
->p
.u
.prefix6
, &hle2
->p
.u
.prefix6
,
212 zlog_debug("%s: Unexpected family type: %d",
213 __PRETTY_FUNCTION__
, hle1
->p
.family
);
217 RB_GENERATE(host_rb_tree_entry
, host_rb_entry
, hl_entry
, host_rb_entry_compare
);
219 static uint32_t rb_host_count(struct host_rb_tree_entry
*hrbe
)
221 struct host_rb_entry
*hle
;
224 RB_FOREACH (hle
, host_rb_tree_entry
, hrbe
)
231 * Return number of valid MACs in a VNI's MAC hash table - all
232 * remote MACs and non-internal (auto) local MACs count.
234 static uint32_t num_valid_macs(zebra_vni_t
*zvni
)
237 uint32_t num_macs
= 0;
239 struct hash_backet
*hb
;
242 hash
= zvni
->mac_table
;
245 for (i
= 0; i
< hash
->size
; i
++) {
246 for (hb
= hash
->index
[i
]; hb
; hb
= hb
->next
) {
247 mac
= (zebra_mac_t
*)hb
->data
;
248 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
249 || CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
250 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
258 static int advertise_gw_macip_enabled(zebra_vni_t
*zvni
)
260 struct zebra_vrf
*zvrf
;
262 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
263 if (zvrf
&& zvrf
->advertise_gw_macip
)
266 if (zvni
&& zvni
->advertise_gw_macip
)
273 * Helper function to determine maximum width of neighbor IP address for
274 * display - just because we're dealing with IPv6 addresses that can
277 static void zvni_find_neigh_addr_width(struct hash_backet
*backet
, void *ctxt
)
280 char buf
[INET6_ADDRSTRLEN
];
281 struct neigh_walk_ctx
*wctx
= ctxt
;
284 n
= (zebra_neigh_t
*)backet
->data
;
286 ipaddr2str(&n
->ip
, buf
, sizeof(buf
));
288 if (width
> wctx
->addr_width
)
289 wctx
->addr_width
= width
;
294 * Print a specific neighbor entry.
296 static void zvni_print_neigh(zebra_neigh_t
*n
, void *ctxt
, json_object
*json
)
299 char buf1
[ETHER_ADDR_STRLEN
];
300 char buf2
[INET6_ADDRSTRLEN
];
301 const char *type_str
;
302 const char *state_str
;
303 bool flags_present
= false;
305 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
306 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
307 type_str
= CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) ?
309 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
310 vty
= (struct vty
*)ctxt
;
312 vty_out(vty
, "IP: %s\n",
313 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
314 vty_out(vty
, " Type: %s\n", type_str
);
315 vty_out(vty
, " State: %s\n", state_str
);
316 vty_out(vty
, " MAC: %s\n",
317 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
319 json_object_string_add(json
, "ip", buf2
);
320 json_object_string_add(json
, "type", type_str
);
321 json_object_string_add(json
, "state", state_str
);
322 json_object_string_add(json
, "mac", buf1
);
324 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
326 vty_out(vty
, " Remote VTEP: %s\n",
327 inet_ntoa(n
->r_vtep_ip
));
329 json_object_string_add(json
, "remoteVtep",
330 inet_ntoa(n
->r_vtep_ip
));
332 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
)) {
334 vty_out(vty
, " Flags: Default-gateway");
335 flags_present
= true;
337 json_object_boolean_true_add(json
, "defaultGateway");
339 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)) {
342 flags_present
? " ,Router" : " Flags: Router");
343 flags_present
= true;
349 vty_out(vty
, " Local Seq: %u Remote Seq: %u\n",
350 n
->loc_seq
, n
->rem_seq
);
352 json_object_int_add(json
, "localSequence", n
->loc_seq
);
353 json_object_int_add(json
, "remoteSequence", n
->rem_seq
);
358 * Print neighbor hash entry - called for display of all neighbors.
360 static void zvni_print_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
363 json_object
*json_vni
= NULL
, *json_row
= NULL
;
365 char buf1
[ETHER_ADDR_STRLEN
];
366 char buf2
[INET6_ADDRSTRLEN
];
367 struct neigh_walk_ctx
*wctx
= ctxt
;
368 const char *state_str
;
371 json_vni
= wctx
->json
;
372 n
= (zebra_neigh_t
*)backet
->data
;
375 json_row
= json_object_new_object();
377 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
));
378 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
));
379 state_str
= IS_ZEBRA_NEIGH_ACTIVE(n
) ? "active" : "inactive";
380 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
381 if (wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
)
384 if (json_vni
== NULL
) {
385 vty_out(vty
, "%*s %-6s %-8s %-17s\n",
386 -wctx
->addr_width
, buf2
, "local",
389 json_object_string_add(json_row
, "type", "local");
390 json_object_string_add(json_row
, "state", state_str
);
391 json_object_string_add(json_row
, "mac", buf1
);
392 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
393 json_object_boolean_true_add(
394 json_row
, "defaultGateway");
395 json_object_int_add(json_row
, "localSequence",
397 json_object_int_add(json_row
, "remoteSequence",
401 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
402 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
403 !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))
406 if (json_vni
== NULL
) {
407 if ((wctx
->flags
& SHOW_REMOTE_NEIGH_FROM_VTEP
) &&
410 "%*s %-6s %-8s %-17s %-21s\n",
411 -wctx
->addr_width
, "Neighbor", "Type",
412 "State", "MAC", "Remote VTEP");
413 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
414 -wctx
->addr_width
, buf2
, "remote", state_str
,
415 buf1
, inet_ntoa(n
->r_vtep_ip
));
417 json_object_string_add(json_row
, "type", "remote");
418 json_object_string_add(json_row
, "state", state_str
);
419 json_object_string_add(json_row
, "mac", buf1
);
420 json_object_string_add(json_row
, "remoteVtep",
421 inet_ntoa(n
->r_vtep_ip
));
422 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
))
423 json_object_boolean_true_add(json_row
,
425 json_object_int_add(json_row
, "localSequence",
427 json_object_int_add(json_row
, "remoteSequence",
434 json_object_object_add(json_vni
, buf2
, json_row
);
438 * Print neighbors for all VNI.
440 static void zvni_print_neigh_hash_all_vni(struct hash_backet
*backet
,
444 json_object
*json
= NULL
, *json_vni
= NULL
;
447 struct neigh_walk_ctx wctx
;
448 char vni_str
[VNI_STR_LEN
];
450 vty
= (struct vty
*)args
[0];
451 json
= (json_object
*)args
[1];
453 zvni
= (zebra_vni_t
*)backet
->data
;
455 num_neigh
= hashcount(zvni
->neigh_table
);
458 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
459 zvni
->vni
, num_neigh
);
461 json_vni
= json_object_new_object();
462 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
463 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
467 json_object_object_add(json
, vni_str
, json_vni
);
471 /* Since we have IPv6 addresses to deal with which can vary widely in
472 * size, we try to be a bit more elegant in display by first computing
475 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
478 wctx
.addr_width
= 15;
479 wctx
.json
= json_vni
;
480 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
483 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
484 -wctx
.addr_width
, "IP", "Type",
485 "State", "MAC", "Remote VTEP");
487 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
490 json_object_object_add(json
, vni_str
, json_vni
);
493 /* print a specific next hop for an l3vni */
494 static void zl3vni_print_nh(zebra_neigh_t
*n
, struct vty
*vty
,
497 char buf1
[ETHER_ADDR_STRLEN
];
498 char buf2
[INET6_ADDRSTRLEN
];
499 json_object
*json_hosts
= NULL
;
500 struct host_rb_entry
*hle
;
503 vty_out(vty
, "Ip: %s\n",
504 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
505 vty_out(vty
, " RMAC: %s\n",
506 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
507 vty_out(vty
, " Refcount: %d\n",
508 rb_host_count(&n
->host_rb
));
509 vty_out(vty
, " Prefixes:\n");
510 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
511 vty_out(vty
, " %s\n",
512 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
514 json_hosts
= json_object_new_array();
515 json_object_string_add(
516 json
, "ip", ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)));
517 json_object_string_add(
519 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)));
520 json_object_int_add(json
, "refCount",
521 rb_host_count(&n
->host_rb
));
522 RB_FOREACH (hle
, host_rb_tree_entry
, &n
->host_rb
)
523 json_object_array_add(json_hosts
,
524 json_object_new_string(prefix2str(
525 &hle
->p
, buf2
, sizeof(buf2
))));
526 json_object_object_add(json
, "prefixList", json_hosts
);
530 /* Print a specific RMAC entry */
531 static void zl3vni_print_rmac(zebra_mac_t
*zrmac
, struct vty
*vty
,
534 char buf1
[ETHER_ADDR_STRLEN
];
535 char buf2
[PREFIX_STRLEN
];
536 json_object
*json_hosts
= NULL
;
537 struct host_rb_entry
*hle
;
540 vty_out(vty
, "MAC: %s\n",
541 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
542 vty_out(vty
, " Remote VTEP: %s\n",
543 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
544 vty_out(vty
, " Refcount: %d\n", rb_host_count(&zrmac
->host_rb
));
545 vty_out(vty
, " Prefixes:\n");
546 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
547 vty_out(vty
, " %s\n",
548 prefix2str(&hle
->p
, buf2
, sizeof(buf2
)));
550 json_hosts
= json_object_new_array();
551 json_object_string_add(
553 prefix_mac2str(&zrmac
->macaddr
, buf1
, sizeof(buf1
)));
554 json_object_string_add(json
, "vtepIp",
555 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
556 json_object_int_add(json
, "refCount",
557 rb_host_count(&zrmac
->host_rb
));
558 json_object_int_add(json
, "localSequence", zrmac
->loc_seq
);
559 json_object_int_add(json
, "remoteSequence", zrmac
->rem_seq
);
560 RB_FOREACH (hle
, host_rb_tree_entry
, &zrmac
->host_rb
)
561 json_object_array_add(
563 json_object_new_string(prefix2str(
564 &hle
->p
, buf2
, sizeof(buf2
))));
565 json_object_object_add(json
, "prefixList", json_hosts
);
570 * Print a specific MAC entry.
572 static void zvni_print_mac(zebra_mac_t
*mac
, void *ctxt
)
575 zebra_neigh_t
*n
= NULL
;
576 struct listnode
*node
= NULL
;
578 char buf2
[INET6_ADDRSTRLEN
];
580 vty
= (struct vty
*)ctxt
;
581 vty_out(vty
, "MAC: %s",
582 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
)));
583 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
584 struct zebra_ns
*zns
;
585 struct interface
*ifp
;
588 ifindex
= mac
->fwd_info
.local
.ifindex
;
589 zns
= zebra_ns_lookup(NS_DEFAULT
);
590 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
591 if (!ifp
) // unexpected
593 vty_out(vty
, " Intf: %s(%u)", ifp
->name
, ifindex
);
594 if (mac
->fwd_info
.local
.vid
)
595 vty_out(vty
, " VLAN: %u", mac
->fwd_info
.local
.vid
);
596 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
597 vty_out(vty
, " Remote VTEP: %s",
598 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
599 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
600 vty_out(vty
, " Auto Mac ");
603 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
604 vty_out(vty
, " Sticky Mac ");
606 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
))
607 vty_out(vty
, " Default-gateway Mac ");
609 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
))
610 vty_out(vty
, " Remote-gateway Mac ");
613 vty_out(vty
, " Local Seq: %u Remote Seq: %u",
614 mac
->loc_seq
, mac
->rem_seq
);
617 /* print all the associated neigh */
618 vty_out(vty
, " Neighbors:\n");
619 if (!listcount(mac
->neigh_list
))
620 vty_out(vty
, " No Neighbors\n");
622 for (ALL_LIST_ELEMENTS_RO(mac
->neigh_list
, node
, n
)) {
623 vty_out(vty
, " %s %s\n",
624 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
625 (IS_ZEBRA_NEIGH_ACTIVE(n
)
626 ? "Active" : "Inactive"));
634 * Print MAC hash entry - called for display of all MACs.
636 static void zvni_print_mac_hash(struct hash_backet
*backet
, void *ctxt
)
639 json_object
*json_mac_hdr
= NULL
, *json_mac
= NULL
;
642 struct mac_walk_ctx
*wctx
= ctxt
;
645 json_mac_hdr
= wctx
->json
;
646 mac
= (zebra_mac_t
*)backet
->data
;
648 prefix_mac2str(&mac
->macaddr
, buf1
, sizeof(buf1
));
651 json_mac
= json_object_new_object();
653 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
654 struct zebra_ns
*zns
;
656 struct interface
*ifp
;
659 if (wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
)
662 zns
= zebra_ns_lookup(NS_DEFAULT
);
663 ifindex
= mac
->fwd_info
.local
.ifindex
;
664 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
665 if (!ifp
) // unexpected
667 vid
= mac
->fwd_info
.local
.vid
;
668 if (json_mac_hdr
== NULL
)
669 vty_out(vty
, "%-17s %-6s %-21s", buf1
, "local",
672 json_object_string_add(json_mac
, "type", "local");
673 json_object_string_add(json_mac
, "intf", ifp
->name
);
676 if (json_mac_hdr
== NULL
)
677 vty_out(vty
, " %-5u", vid
);
679 json_object_int_add(json_mac
, "vlan", vid
);
681 if (json_mac_hdr
== NULL
) {
684 json_object_int_add(json_mac
, "localSequence",
686 json_object_int_add(json_mac
, "remoteSequence",
688 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
693 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
695 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
696 !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
700 if (json_mac_hdr
== NULL
) {
701 if ((wctx
->flags
& SHOW_REMOTE_MAC_FROM_VTEP
) &&
702 (wctx
->count
== 0)) {
703 vty_out(vty
, "\nVNI %u\n\n", wctx
->zvni
->vni
);
704 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC",
705 "Type", "Intf/Remote VTEP", "VLAN");
707 vty_out(vty
, "%-17s %-6s %-21s\n", buf1
, "remote",
708 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
710 json_object_string_add(json_mac
, "type", "remote");
711 json_object_string_add(json_mac
, "remoteVtep",
712 inet_ntoa(mac
->fwd_info
.r_vtep_ip
));
713 json_object_object_add(json_mac_hdr
, buf1
, json_mac
);
714 json_object_int_add(json_mac
, "localSequence",
716 json_object_int_add(json_mac
, "remoteSequence",
725 * Print MACs for all VNI.
727 static void zvni_print_mac_hash_all_vni(struct hash_backet
*backet
, void *ctxt
)
730 json_object
*json
= NULL
, *json_vni
= NULL
;
731 json_object
*json_mac
= NULL
;
734 struct mac_walk_ctx
*wctx
= ctxt
;
735 char vni_str
[VNI_STR_LEN
];
737 vty
= (struct vty
*)wctx
->vty
;
738 json
= (struct json_object
*)wctx
->json
;
740 zvni
= (zebra_vni_t
*)backet
->data
;
743 /*We are iterating over a new VNI, set the count to 0*/
746 num_macs
= num_valid_macs(zvni
);
751 json_vni
= json_object_new_object();
752 json_mac
= json_object_new_object();
753 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
756 if (!CHECK_FLAG(wctx
->flags
, SHOW_REMOTE_MAC_FROM_VTEP
)) {
758 vty_out(vty
, "\nVNI %u #MACs (local and remote) %u\n\n",
759 zvni
->vni
, num_macs
);
760 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
761 "Intf/Remote VTEP", "VLAN");
763 json_object_int_add(json_vni
, "numMacs", num_macs
);
765 /* assign per-vni to wctx->json object to fill macs
766 * under the vni. Re-assign primary json object to fill
767 * next vni information.
769 wctx
->json
= json_mac
;
770 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, wctx
);
774 json_object_object_add(json_vni
, "macs", json_mac
);
775 json_object_object_add(json
, vni_str
, json_vni
);
779 static void zl3vni_print_nh_hash(struct hash_backet
*backet
, void *ctx
)
781 struct nh_walk_ctx
*wctx
= NULL
;
782 struct vty
*vty
= NULL
;
783 struct json_object
*json_vni
= NULL
;
784 struct json_object
*json_nh
= NULL
;
785 zebra_neigh_t
*n
= NULL
;
786 char buf1
[ETHER_ADDR_STRLEN
];
787 char buf2
[INET6_ADDRSTRLEN
];
789 wctx
= (struct nh_walk_ctx
*)ctx
;
791 json_vni
= wctx
->json
;
793 json_nh
= json_object_new_object();
794 n
= (zebra_neigh_t
*)backet
->data
;
797 vty_out(vty
, "%-15s %-17s\n",
798 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
799 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
801 json_object_string_add(json_nh
, "nexthopIp",
802 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)));
803 json_object_string_add(
804 json_nh
, "routerMac",
805 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)));
806 json_object_object_add(json_vni
,
807 ipaddr2str(&(n
->ip
), buf2
, sizeof(buf2
)),
812 static void zl3vni_print_nh_hash_all_vni(struct hash_backet
*backet
,
815 struct vty
*vty
= NULL
;
816 json_object
*json
= NULL
;
817 json_object
*json_vni
= NULL
;
818 zebra_l3vni_t
*zl3vni
= NULL
;
820 struct nh_walk_ctx wctx
;
821 char vni_str
[VNI_STR_LEN
];
823 vty
= (struct vty
*)args
[0];
824 json
= (struct json_object
*)args
[1];
826 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
828 num_nh
= hashcount(zl3vni
->nh_table
);
833 json_vni
= json_object_new_object();
834 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
838 vty_out(vty
, "\nVNI %u #Next-Hops %u\n\n", zl3vni
->vni
, num_nh
);
839 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
841 json_object_int_add(json_vni
, "numNextHops", num_nh
);
843 memset(&wctx
, 0, sizeof(struct nh_walk_ctx
));
845 wctx
.json
= json_vni
;
846 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
848 json_object_object_add(json
, vni_str
, json_vni
);
851 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet
*backet
,
854 struct vty
*vty
= NULL
;
855 json_object
*json
= NULL
;
856 json_object
*json_vni
= NULL
;
857 zebra_l3vni_t
*zl3vni
= NULL
;
859 struct rmac_walk_ctx wctx
;
860 char vni_str
[VNI_STR_LEN
];
862 vty
= (struct vty
*)args
[0];
863 json
= (struct json_object
*)args
[1];
865 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
867 num_rmacs
= hashcount(zl3vni
->rmac_table
);
872 json_vni
= json_object_new_object();
873 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
877 vty_out(vty
, "\nVNI %u #RMACs %u\n\n", zl3vni
->vni
, num_rmacs
);
878 vty_out(vty
, "%-17s %-21s\n", "RMAC", "Remote VTEP");
880 json_object_int_add(json_vni
, "numRmacs", num_rmacs
);
882 /* assign per-vni to wctx->json object to fill macs
883 * under the vni. Re-assign primary json object to fill
884 * next vni information.
886 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
888 wctx
.json
= json_vni
;
889 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
891 json_object_object_add(json
, vni_str
, json_vni
);
894 static void zl3vni_print_rmac_hash(struct hash_backet
*backet
, void *ctx
)
896 zebra_mac_t
*zrmac
= NULL
;
897 struct rmac_walk_ctx
*wctx
= NULL
;
898 struct vty
*vty
= NULL
;
899 struct json_object
*json
= NULL
;
900 struct json_object
*json_rmac
= NULL
;
901 char buf
[ETHER_ADDR_STRLEN
];
903 wctx
= (struct rmac_walk_ctx
*)ctx
;
907 json_rmac
= json_object_new_object();
908 zrmac
= (zebra_mac_t
*)backet
->data
;
911 vty_out(vty
, "%-17s %-21s\n",
912 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
913 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
915 json_object_string_add(
916 json_rmac
, "routerMac",
917 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)));
918 json_object_string_add(json_rmac
, "vtepIp",
919 inet_ntoa(zrmac
->fwd_info
.r_vtep_ip
));
920 json_object_object_add(
921 json
, prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
926 /* print a specific L3 VNI entry */
927 static void zl3vni_print(zebra_l3vni_t
*zl3vni
, void **ctx
)
929 char buf
[ETHER_ADDR_STRLEN
];
930 struct vty
*vty
= NULL
;
931 json_object
*json
= NULL
;
932 zebra_vni_t
*zvni
= NULL
;
933 json_object
*json_vni_list
= NULL
;
934 struct listnode
*node
= NULL
, *nnode
= NULL
;
940 vty_out(vty
, "VNI: %u\n", zl3vni
->vni
);
941 vty_out(vty
, " Type: %s\n", "L3");
942 vty_out(vty
, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni
));
943 vty_out(vty
, " Local Vtep Ip: %s\n",
944 inet_ntoa(zl3vni
->local_vtep_ip
));
945 vty_out(vty
, " Vxlan-Intf: %s\n",
946 zl3vni_vxlan_if_name(zl3vni
));
947 vty_out(vty
, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni
));
948 vty_out(vty
, " State: %s\n", zl3vni_state2str(zl3vni
));
949 vty_out(vty
, " VNI Filter: %s\n",
950 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
951 ? "prefix-routes-only"
953 vty_out(vty
, " Router MAC: %s\n",
954 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
955 vty_out(vty
, " L2 VNIs: ");
956 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
))
957 vty_out(vty
, "%u ", zvni
->vni
);
960 json_vni_list
= json_object_new_array();
961 json_object_int_add(json
, "vni", zl3vni
->vni
);
962 json_object_string_add(json
, "type", "L3");
963 json_object_string_add(json
, "localVtepIp",
964 inet_ntoa(zl3vni
->local_vtep_ip
));
965 json_object_string_add(json
, "vxlanIntf",
966 zl3vni_vxlan_if_name(zl3vni
));
967 json_object_string_add(json
, "sviIntf",
968 zl3vni_svi_if_name(zl3vni
));
969 json_object_string_add(json
, "state", zl3vni_state2str(zl3vni
));
970 json_object_string_add(json
, "vrf", zl3vni_vrf_name(zl3vni
));
971 json_object_string_add(
973 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
974 json_object_string_add(
976 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
977 ? "prefix-routes-only"
979 for (ALL_LIST_ELEMENTS(zl3vni
->l2vnis
, node
, nnode
, zvni
)) {
980 json_object_array_add(json_vni_list
,
981 json_object_new_int(zvni
->vni
));
983 json_object_object_add(json
, "l2Vnis", json_vni_list
);
988 * Print a specific VNI entry.
990 static void zvni_print(zebra_vni_t
*zvni
, void **ctxt
)
996 json_object
*json
= NULL
;
997 json_object
*json_vtep_list
= NULL
;
998 json_object
*json_ip_str
= NULL
;
1004 vty_out(vty
, "VNI: %u\n", zvni
->vni
);
1005 vty_out(vty
, " Type: %s\n", "L2");
1006 vty_out(vty
, " Tenant VRF: %s\n", vrf_id_to_name(zvni
->vrf_id
));
1008 json_object_int_add(json
, "vni", zvni
->vni
);
1009 json_object_string_add(json
, "type", "L2");
1010 json_object_string_add(json
, "vrf",
1011 vrf_id_to_name(zvni
->vrf_id
));
1014 if (!zvni
->vxlan_if
) { // unexpected
1016 vty_out(vty
, " VxLAN interface: unknown\n");
1019 num_macs
= num_valid_macs(zvni
);
1020 num_neigh
= hashcount(zvni
->neigh_table
);
1022 vty_out(vty
, " VxLAN interface: %s\n", zvni
->vxlan_if
->name
);
1023 vty_out(vty
, " VxLAN ifIndex: %u\n", zvni
->vxlan_if
->ifindex
);
1024 vty_out(vty
, " Local VTEP IP: %s\n",
1025 inet_ntoa(zvni
->local_vtep_ip
));
1027 json_object_string_add(json
, "vxlanInterface",
1028 zvni
->vxlan_if
->name
);
1029 json_object_int_add(json
, "ifindex", zvni
->vxlan_if
->ifindex
);
1030 json_object_string_add(json
, "vtepIp",
1031 inet_ntoa(zvni
->local_vtep_ip
));
1032 json_object_string_add(json
, "advertiseGatewayMacip",
1033 zvni
->advertise_gw_macip
? "Yes" : "No");
1034 json_object_int_add(json
, "numMacs", num_macs
);
1035 json_object_int_add(json
, "numArpNd", num_neigh
);
1039 vty_out(vty
, " No remote VTEPs known for this VNI\n");
1042 vty_out(vty
, " Remote VTEPs for this VNI:\n");
1044 json_vtep_list
= json_object_new_array();
1045 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1047 vty_out(vty
, " %s\n",
1048 inet_ntoa(zvtep
->vtep_ip
));
1050 json_ip_str
= json_object_new_string(
1051 inet_ntoa(zvtep
->vtep_ip
));
1052 json_object_array_add(json_vtep_list
,
1057 json_object_object_add(json
, "numRemoteVteps",
1062 " Number of MACs (local and remote) known for this VNI: %u\n",
1065 " Number of ARPs (IPv4 and IPv6, local and remote) "
1066 "known for this VNI: %u\n",
1068 vty_out(vty
, " Advertise-gw-macip: %s\n",
1069 zvni
->advertise_gw_macip
? "Yes" : "No");
1073 /* print a L3 VNI hash entry */
1074 static void zl3vni_print_hash(struct hash_backet
*backet
, void *ctx
[])
1076 struct vty
*vty
= NULL
;
1077 json_object
*json
= NULL
;
1078 json_object
*json_vni
= NULL
;
1079 zebra_l3vni_t
*zl3vni
= NULL
;
1081 vty
= (struct vty
*)ctx
[0];
1082 json
= (json_object
*)ctx
[1];
1084 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
1087 vty_out(vty
, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1088 zl3vni
->vni
, "L3", zl3vni_vxlan_if_name(zl3vni
),
1089 hashcount(zl3vni
->rmac_table
),
1090 hashcount(zl3vni
->nh_table
), "n/a",
1091 zl3vni_vrf_name(zl3vni
));
1093 char vni_str
[VNI_STR_LEN
];
1095 snprintf(vni_str
, VNI_STR_LEN
, "%u", zl3vni
->vni
);
1096 json_vni
= json_object_new_object();
1097 json_object_int_add(json_vni
, "vni", zl3vni
->vni
);
1098 json_object_string_add(json_vni
, "vxlanIf",
1099 zl3vni_vxlan_if_name(zl3vni
));
1100 json_object_int_add(json_vni
, "numMacs",
1101 hashcount(zl3vni
->rmac_table
));
1102 json_object_int_add(json_vni
, "numArpNd",
1103 hashcount(zl3vni
->nh_table
));
1104 json_object_string_add(json_vni
, "numRemoteVteps", "n/a");
1105 json_object_string_add(json_vni
, "type", "L3");
1106 json_object_string_add(json_vni
, "tenantVrf",
1107 zl3vni_vrf_name(zl3vni
));
1108 json_object_object_add(json
, vni_str
, json_vni
);
1113 * Print a VNI hash entry - called for display of all VNIs.
1115 static void zvni_print_hash(struct hash_backet
*backet
, void *ctxt
[])
1119 zebra_vtep_t
*zvtep
;
1120 uint32_t num_vteps
= 0;
1121 uint32_t num_macs
= 0;
1122 uint32_t num_neigh
= 0;
1123 json_object
*json
= NULL
;
1124 json_object
*json_vni
= NULL
;
1125 json_object
*json_ip_str
= NULL
;
1126 json_object
*json_vtep_list
= NULL
;
1131 zvni
= (zebra_vni_t
*)backet
->data
;
1133 zvtep
= zvni
->vteps
;
1136 zvtep
= zvtep
->next
;
1139 num_macs
= num_valid_macs(zvni
);
1140 num_neigh
= hashcount(zvni
->neigh_table
);
1142 vty_out(vty
, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1144 zvni
->vxlan_if
? zvni
->vxlan_if
->name
: "unknown",
1145 num_macs
, num_neigh
, num_vteps
,
1146 vrf_id_to_name(zvni
->vrf_id
));
1148 char vni_str
[VNI_STR_LEN
];
1149 snprintf(vni_str
, VNI_STR_LEN
, "%u", zvni
->vni
);
1150 json_vni
= json_object_new_object();
1151 json_object_int_add(json_vni
, "vni", zvni
->vni
);
1152 json_object_string_add(json_vni
, "type", "L2");
1153 json_object_string_add(json_vni
, "vxlanIf",
1154 zvni
->vxlan_if
? zvni
->vxlan_if
->name
1156 json_object_int_add(json_vni
, "numMacs", num_macs
);
1157 json_object_int_add(json_vni
, "numArpNd", num_neigh
);
1158 json_object_int_add(json_vni
, "numRemoteVteps", num_vteps
);
1159 json_object_string_add(json_vni
, "tenantVrf",
1160 vrf_id_to_name(zvni
->vrf_id
));
1162 json_vtep_list
= json_object_new_array();
1163 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
1164 json_ip_str
= json_object_new_string(
1165 inet_ntoa(zvtep
->vtep_ip
));
1166 json_object_array_add(json_vtep_list
,
1169 json_object_object_add(json_vni
, "remoteVteps",
1172 json_object_object_add(json
, vni_str
, json_vni
);
1177 * Inform BGP about local MACIP.
1179 static int zvni_macip_send_msg_to_client(vni_t vni
, struct ethaddr
*macaddr
,
1180 struct ipaddr
*ip
, uint8_t flags
,
1181 uint32_t seq
, uint16_t cmd
)
1183 char buf
[ETHER_ADDR_STRLEN
];
1184 char buf2
[INET6_ADDRSTRLEN
];
1186 struct zserv
*client
= NULL
;
1187 struct stream
*s
= NULL
;
1189 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
1190 /* BGP may not be running. */
1194 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
1196 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1197 stream_putl(s
, vni
);
1198 stream_put(s
, macaddr
->octet
, ETH_ALEN
);
1201 if (IS_IPADDR_V4(ip
))
1202 ipa_len
= IPV4_MAX_BYTELEN
;
1203 else if (IS_IPADDR_V6(ip
))
1204 ipa_len
= IPV6_MAX_BYTELEN
;
1206 stream_putl(s
, ipa_len
); /* IP address length */
1208 stream_put(s
, &ip
->ip
.addr
, ipa_len
); /* IP address */
1210 stream_putl(s
, 0); /* Just MAC. */
1212 if (cmd
== ZEBRA_MACIP_ADD
) {
1213 stream_putc(s
, flags
); /* sticky mac/gateway mac */
1214 stream_putl(s
, seq
); /* sequence number */
1218 /* Write packet size. */
1219 stream_putw_at(s
, 0, stream_get_endp(s
));
1221 if (IS_ZEBRA_DEBUG_VXLAN
)
1223 "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s",
1224 (cmd
== ZEBRA_MACIP_ADD
) ? "Add" : "Del", flags
,
1225 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1226 ipaddr2str(ip
, buf2
, sizeof(buf2
)), seq
, vni
,
1227 zebra_route_string(client
->proto
));
1229 if (cmd
== ZEBRA_MACIP_ADD
)
1230 client
->macipadd_cnt
++;
1232 client
->macipdel_cnt
++;
1234 return zserv_send_message(client
, s
);
1238 * Make hash key for neighbors.
1240 static unsigned int neigh_hash_keymake(void *p
)
1242 zebra_neigh_t
*n
= p
;
1243 struct ipaddr
*ip
= &n
->ip
;
1245 if (IS_IPADDR_V4(ip
))
1246 return jhash_1word(ip
->ipaddr_v4
.s_addr
, 0);
1248 return jhash2(ip
->ipaddr_v6
.s6_addr32
,
1249 ZEBRA_NUM_OF(ip
->ipaddr_v6
.s6_addr32
), 0);
1253 * Compare two neighbor hash structures.
1255 static bool neigh_cmp(const void *p1
, const void *p2
)
1257 const zebra_neigh_t
*n1
= p1
;
1258 const zebra_neigh_t
*n2
= p2
;
1260 if (n1
== NULL
&& n2
== NULL
)
1263 if (n1
== NULL
|| n2
== NULL
)
1266 return (memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
)) == 0);
1269 static int neigh_list_cmp(void *p1
, void *p2
)
1271 const zebra_neigh_t
*n1
= p1
;
1272 const zebra_neigh_t
*n2
= p2
;
1274 return memcmp(&n1
->ip
, &n2
->ip
, sizeof(struct ipaddr
));
1278 * Callback to allocate neighbor hash entry.
1280 static void *zvni_neigh_alloc(void *p
)
1282 const zebra_neigh_t
*tmp_n
= p
;
1285 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
1292 * Add neighbor entry.
1294 static zebra_neigh_t
*zvni_neigh_add(zebra_vni_t
*zvni
, struct ipaddr
*ip
,
1295 struct ethaddr
*mac
)
1297 zebra_neigh_t tmp_n
;
1298 zebra_neigh_t
*n
= NULL
;
1299 zebra_mac_t
*zmac
= NULL
;
1301 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
1302 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
1303 n
= hash_get(zvni
->neigh_table
, &tmp_n
, zvni_neigh_alloc
);
1306 memcpy(&n
->emac
, mac
, ETH_ALEN
);
1307 n
->state
= ZEBRA_NEIGH_INACTIVE
;
1309 /* Associate the neigh to mac */
1310 zmac
= zvni_mac_lookup(zvni
, mac
);
1312 listnode_add_sort(zmac
->neigh_list
, n
);
1318 * Delete neighbor entry.
1320 static int zvni_neigh_del(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1322 zebra_neigh_t
*tmp_n
;
1323 zebra_mac_t
*zmac
= NULL
;
1325 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
1327 listnode_delete(zmac
->neigh_list
, n
);
1329 /* Free the VNI hash entry and allocated memory. */
1330 tmp_n
= hash_release(zvni
->neigh_table
, n
);
1332 XFREE(MTYPE_NEIGH
, tmp_n
);
1338 * Free neighbor hash entry (callback)
1340 static void zvni_neigh_del_hash_entry(struct hash_backet
*backet
, void *arg
)
1342 struct neigh_walk_ctx
*wctx
= arg
;
1343 zebra_neigh_t
*n
= backet
->data
;
1345 if (((wctx
->flags
& DEL_LOCAL_NEIGH
) && (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1346 || ((wctx
->flags
& DEL_REMOTE_NEIGH
)
1347 && (n
->flags
& ZEBRA_NEIGH_REMOTE
))
1348 || ((wctx
->flags
& DEL_REMOTE_NEIGH_FROM_VTEP
)
1349 && (n
->flags
& ZEBRA_NEIGH_REMOTE
)
1350 && IPV4_ADDR_SAME(&n
->r_vtep_ip
, &wctx
->r_vtep_ip
))) {
1351 if (wctx
->upd_client
&& (n
->flags
& ZEBRA_NEIGH_LOCAL
))
1352 zvni_neigh_send_del_to_client(wctx
->zvni
->vni
, &n
->ip
,
1355 if (wctx
->uninstall
)
1356 zvni_neigh_uninstall(wctx
->zvni
, n
);
1358 zvni_neigh_del(wctx
->zvni
, n
);
1365 * Delete all neighbor entries from specific VTEP for a particular VNI.
1367 static void zvni_neigh_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
1368 struct in_addr
*r_vtep_ip
)
1370 struct neigh_walk_ctx wctx
;
1372 if (!zvni
->neigh_table
)
1375 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1377 wctx
.uninstall
= uninstall
;
1378 wctx
.flags
= DEL_REMOTE_NEIGH_FROM_VTEP
;
1379 wctx
.r_vtep_ip
= *r_vtep_ip
;
1381 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1385 * Delete all neighbor entries for this VNI.
1387 static void zvni_neigh_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
1390 struct neigh_walk_ctx wctx
;
1392 if (!zvni
->neigh_table
)
1395 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
1397 wctx
.uninstall
= uninstall
;
1398 wctx
.upd_client
= upd_client
;
1401 hash_iterate(zvni
->neigh_table
, zvni_neigh_del_hash_entry
, &wctx
);
1405 * Look up neighbor hash entry.
1407 static zebra_neigh_t
*zvni_neigh_lookup(zebra_vni_t
*zvni
, struct ipaddr
*ip
)
1412 memset(&tmp
, 0, sizeof(tmp
));
1413 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
1414 n
= hash_lookup(zvni
->neigh_table
, &tmp
);
1420 * Process all neighbors associated with a MAC upon the MAC being learnt
1421 * locally or undergoing any other change (such as sequence number).
1423 static void zvni_process_neigh_on_local_mac_change(zebra_vni_t
*zvni
,
1427 zebra_neigh_t
*n
= NULL
;
1428 struct listnode
*node
= NULL
;
1429 char buf
[ETHER_ADDR_STRLEN
];
1431 if (IS_ZEBRA_DEBUG_VXLAN
)
1432 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
1433 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1434 seq_change
? "CHANGE" : "ADD", zvni
->vni
);
1436 /* Walk all neighbors and mark any inactive local neighbors as
1437 * active and/or update sequence number upon a move, and inform BGP.
1438 * The action for remote neighbors is TBD.
1439 * NOTE: We can't simply uninstall remote neighbors as the kernel may
1440 * accidentally end up deleting a just-learnt local neighbor.
1442 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1443 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1444 if (IS_ZEBRA_NEIGH_INACTIVE(n
) || seq_change
) {
1445 ZEBRA_NEIGH_SET_ACTIVE(n
);
1446 n
->loc_seq
= zmac
->loc_seq
;
1447 zvni_neigh_send_add_to_client(
1448 zvni
->vni
, &n
->ip
, &n
->emac
,
1449 n
->flags
, n
->loc_seq
);
1456 * Process all neighbors associated with a local MAC upon the MAC being
1459 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t
*zvni
,
1462 zebra_neigh_t
*n
= NULL
;
1463 struct listnode
*node
= NULL
;
1464 char buf
[ETHER_ADDR_STRLEN
];
1466 if (IS_ZEBRA_DEBUG_VXLAN
)
1467 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
1468 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1471 /* Walk all local neighbors and mark as inactive and inform
1473 * TBD: There is currently no handling for remote neighbors. We
1474 * don't expect them to exist, if they do, do we install the MAC
1475 * as a remote MAC and the neighbor as remote?
1477 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1478 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1479 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1480 ZEBRA_NEIGH_SET_INACTIVE(n
);
1482 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1490 * Process all neighbors associated with a MAC upon the MAC being remotely
1493 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t
*zvni
,
1496 zebra_neigh_t
*n
= NULL
;
1497 struct listnode
*node
= NULL
;
1498 char buf
[ETHER_ADDR_STRLEN
];
1500 if (IS_ZEBRA_DEBUG_VXLAN
)
1501 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
1502 prefix_mac2str(&zmac
->macaddr
, buf
, sizeof(buf
)),
1505 /* Walk all local neighbors and mark as inactive and inform
1508 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
1509 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
1510 if (IS_ZEBRA_NEIGH_ACTIVE(n
)) {
1511 ZEBRA_NEIGH_SET_INACTIVE(n
);
1513 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
1521 * Process all neighbors associated with a remote MAC upon the MAC being
1524 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t
*zvni
,
1527 /* NOTE: Currently a NO-OP. */
1531 * Inform BGP about local neighbor addition.
1533 static int zvni_neigh_send_add_to_client(vni_t vni
, struct ipaddr
*ip
,
1534 struct ethaddr
*macaddr
,
1535 uint8_t neigh_flags
,
1540 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_DEF_GW
))
1541 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1542 /* Set router flag (R-bit) based on local neigh entry add */
1543 if (CHECK_FLAG(neigh_flags
, ZEBRA_NEIGH_ROUTER_FLAG
))
1544 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
1546 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1547 seq
, ZEBRA_MACIP_ADD
);
1551 * Inform BGP about local neighbor deletion.
1553 static int zvni_neigh_send_del_to_client(vni_t vni
, struct ipaddr
*ip
,
1554 struct ethaddr
*macaddr
, uint8_t flags
)
1556 return zvni_macip_send_msg_to_client(vni
, macaddr
, ip
, flags
,
1557 0, ZEBRA_MACIP_DEL
);
1561 * Install remote neighbor into the kernel.
1563 static int zvni_neigh_install(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1565 struct zebra_if
*zif
;
1566 struct zebra_l2info_vxlan
*vxl
;
1567 struct interface
*vlan_if
;
1573 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1576 zif
= zvni
->vxlan_if
->info
;
1579 vxl
= &zif
->l2info
.vxl
;
1581 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1585 flags
= NTF_EXT_LEARNED
;
1586 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
1587 flags
|= NTF_ROUTER
;
1588 ZEBRA_NEIGH_SET_ACTIVE(n
);
1589 ret
= kernel_add_neigh(vlan_if
, &n
->ip
, &n
->emac
, flags
);
1595 * Uninstall remote neighbor from the kernel.
1597 static int zvni_neigh_uninstall(zebra_vni_t
*zvni
, zebra_neigh_t
*n
)
1599 struct zebra_if
*zif
;
1600 struct zebra_l2info_vxlan
*vxl
;
1601 struct interface
*vlan_if
;
1603 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
))
1606 if (!zvni
->vxlan_if
) {
1607 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
1612 zif
= zvni
->vxlan_if
->info
;
1615 vxl
= &zif
->l2info
.vxl
;
1616 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
1620 ZEBRA_NEIGH_SET_INACTIVE(n
);
1622 return kernel_del_neigh(vlan_if
, &n
->ip
);
1626 * Install neighbor hash entry - called upon access VLAN change.
1628 static void zvni_install_neigh_hash(struct hash_backet
*backet
, void *ctxt
)
1631 struct neigh_walk_ctx
*wctx
= ctxt
;
1633 n
= (zebra_neigh_t
*)backet
->data
;
1635 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
1636 zvni_neigh_install(wctx
->zvni
, n
);
1639 /* Get the VRR interface for SVI if any */
1640 struct interface
*zebra_get_vrr_intf_for_svi(struct interface
*ifp
)
1642 struct zebra_vrf
*zvrf
= NULL
;
1643 struct interface
*tmp_if
= NULL
;
1644 struct zebra_if
*zif
= NULL
;
1646 zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1649 FOR_ALL_INTERFACES (zvrf
->vrf
, tmp_if
) {
1654 if (!IS_ZEBRA_IF_MACVLAN(tmp_if
))
1657 if (zif
->link
== ifp
)
1664 static int zvni_del_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1666 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1667 struct connected
*c
= NULL
;
1668 struct ethaddr macaddr
;
1670 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1672 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1675 memset(&ip
, 0, sizeof(struct ipaddr
));
1676 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1679 if (c
->address
->family
== AF_INET
) {
1680 ip
.ipa_type
= IPADDR_V4
;
1681 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1682 sizeof(struct in_addr
));
1683 } else if (c
->address
->family
== AF_INET6
) {
1684 ip
.ipa_type
= IPADDR_V6
;
1685 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1686 sizeof(struct in6_addr
));
1691 zvni_gw_macip_del(ifp
, zvni
, &ip
);
1697 static int zvni_add_macip_for_intf(struct interface
*ifp
, zebra_vni_t
*zvni
)
1699 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1700 struct connected
*c
= NULL
;
1701 struct ethaddr macaddr
;
1703 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1705 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1708 memset(&ip
, 0, sizeof(struct ipaddr
));
1709 if (!CHECK_FLAG(c
->conf
, ZEBRA_IFC_REAL
))
1712 if (c
->address
->family
== AF_INET
) {
1713 ip
.ipa_type
= IPADDR_V4
;
1714 memcpy(&(ip
.ipaddr_v4
), &(c
->address
->u
.prefix4
),
1715 sizeof(struct in_addr
));
1716 } else if (c
->address
->family
== AF_INET6
) {
1717 ip
.ipa_type
= IPADDR_V6
;
1718 memcpy(&(ip
.ipaddr_v6
), &(c
->address
->u
.prefix6
),
1719 sizeof(struct in6_addr
));
1724 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
1730 static int zvni_advertise_subnet(zebra_vni_t
*zvni
, struct interface
*ifp
,
1733 struct listnode
*cnode
= NULL
, *cnnode
= NULL
;
1734 struct connected
*c
= NULL
;
1735 struct ethaddr macaddr
;
1737 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
1739 for (ALL_LIST_ELEMENTS(ifp
->connected
, cnode
, cnnode
, c
)) {
1742 memcpy(&p
, c
->address
, sizeof(struct prefix
));
1744 /* skip link local address */
1745 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
1750 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1751 ZEBRA_IP_PREFIX_ROUTE_ADD
);
1753 ip_prefix_send_to_client(ifp
->vrf_id
, &p
,
1754 ZEBRA_IP_PREFIX_ROUTE_DEL
);
1760 * zvni_gw_macip_add_to_client
1762 static int zvni_gw_macip_add(struct interface
*ifp
, zebra_vni_t
*zvni
,
1763 struct ethaddr
*macaddr
, struct ipaddr
*ip
)
1765 char buf
[ETHER_ADDR_STRLEN
];
1766 char buf2
[INET6_ADDRSTRLEN
];
1767 zebra_neigh_t
*n
= NULL
;
1768 zebra_mac_t
*mac
= NULL
;
1769 struct zebra_if
*zif
= NULL
;
1770 struct zebra_l2info_vxlan
*vxl
= NULL
;
1772 zif
= zvni
->vxlan_if
->info
;
1776 vxl
= &zif
->l2info
.vxl
;
1778 mac
= zvni_mac_lookup(zvni
, macaddr
);
1780 mac
= zvni_mac_add(zvni
, macaddr
);
1782 flog_err(EC_ZEBRA_MAC_ADD_FAILED
,
1783 "Failed to add MAC %s intf %s(%u) VID %u",
1784 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1785 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
);
1790 /* Set "local" forwarding info. */
1791 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
1792 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
1793 SET_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
);
1794 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
1795 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
1796 mac
->fwd_info
.local
.vid
= vxl
->access_vlan
;
1798 n
= zvni_neigh_lookup(zvni
, ip
);
1800 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
1803 EC_ZEBRA_MAC_ADD_FAILED
,
1804 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1805 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
1806 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1807 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
1812 /* Set "local" forwarding info. */
1813 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
1814 SET_FLAG(n
->flags
, ZEBRA_NEIGH_DEF_GW
);
1815 ZEBRA_NEIGH_SET_ACTIVE(n
);
1816 /* Set Router flag (R-bit) */
1817 if (ip
->ipa_type
== IPADDR_V6
)
1818 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
1819 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
1820 n
->ifindex
= ifp
->ifindex
;
1822 /* Only advertise in BGP if the knob is enabled */
1823 if (!advertise_gw_macip_enabled(zvni
))
1826 if (IS_ZEBRA_DEBUG_VXLAN
)
1828 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
1829 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1830 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1831 ipaddr2str(ip
, buf2
, sizeof(buf2
)), n
->flags
);
1833 zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
1834 n
->flags
, n
->loc_seq
);
1840 * zvni_gw_macip_del_from_client
1842 static int zvni_gw_macip_del(struct interface
*ifp
, zebra_vni_t
*zvni
,
1845 char buf1
[ETHER_ADDR_STRLEN
];
1846 char buf2
[INET6_ADDRSTRLEN
];
1847 zebra_neigh_t
*n
= NULL
;
1848 zebra_mac_t
*mac
= NULL
;
1850 /* If the neigh entry is not present nothing to do*/
1851 n
= zvni_neigh_lookup(zvni
, ip
);
1855 /* mac entry should be present */
1856 mac
= zvni_mac_lookup(zvni
, &n
->emac
);
1858 zlog_debug("MAC %s doesnt exists for neigh %s on VNI %u",
1859 prefix_mac2str(&n
->emac
, buf1
, sizeof(buf1
)),
1860 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1864 /* If the entry is not local nothing to do*/
1865 if (!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
))
1868 /* only need to delete the entry from bgp if we sent it before */
1869 if (IS_ZEBRA_DEBUG_VXLAN
)
1871 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1872 ifp
->vrf_id
, ifp
->name
, ifp
->ifindex
, zvni
->vni
,
1873 prefix_mac2str(&(n
->emac
), buf1
, sizeof(buf1
)),
1874 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
1876 /* Remove neighbor from BGP. */
1877 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
,
1878 ZEBRA_MACIP_TYPE_GW
);
1880 /* Delete this neighbor entry. */
1881 zvni_neigh_del(zvni
, n
);
1883 /* see if the mac needs to be deleted as well*/
1885 zvni_deref_ip2mac(zvni
, mac
);
1890 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet
*backet
,
1893 zebra_vni_t
*zvni
= NULL
;
1894 struct zebra_if
*zif
= NULL
;
1895 struct zebra_l2info_vxlan zl2_info
;
1896 struct interface
*vlan_if
= NULL
;
1897 struct interface
*vrr_if
= NULL
;
1898 struct interface
*ifp
;
1900 /* Add primary SVI MAC*/
1901 zvni
= (zebra_vni_t
*)backet
->data
;
1903 ifp
= zvni
->vxlan_if
;
1908 /* If down or not mapped to a bridge, we're done. */
1909 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1912 zl2_info
= zif
->l2info
.vxl
;
1915 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1919 /* Del primary MAC-IP */
1920 zvni_del_macip_for_intf(vlan_if
, zvni
);
1922 /* Del VRR MAC-IP - if any*/
1923 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1925 zvni_del_macip_for_intf(vrr_if
, zvni
);
1930 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet
*backet
,
1933 zebra_vni_t
*zvni
= NULL
;
1934 struct zebra_if
*zif
= NULL
;
1935 struct zebra_l2info_vxlan zl2_info
;
1936 struct interface
*vlan_if
= NULL
;
1937 struct interface
*vrr_if
= NULL
;
1938 struct interface
*ifp
= NULL
;
1940 zvni
= (zebra_vni_t
*)backet
->data
;
1942 ifp
= zvni
->vxlan_if
;
1947 /* If down or not mapped to a bridge, we're done. */
1948 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
1950 zl2_info
= zif
->l2info
.vxl
;
1953 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
1957 /* Add primary SVI MAC-IP */
1958 zvni_add_macip_for_intf(vlan_if
, zvni
);
1960 /* Add VRR MAC-IP - if any*/
1961 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
1963 zvni_add_macip_for_intf(vrr_if
, zvni
);
1968 static int zvni_local_neigh_update(zebra_vni_t
*zvni
,
1969 struct interface
*ifp
,
1971 struct ethaddr
*macaddr
,
1974 char buf
[ETHER_ADDR_STRLEN
];
1975 char buf2
[INET6_ADDRSTRLEN
];
1976 zebra_neigh_t
*n
= NULL
;
1977 zebra_mac_t
*zmac
= NULL
, *old_zmac
= NULL
;
1978 uint32_t old_mac_seq
= 0, mac_new_seq
= 0;
1979 bool upd_mac_seq
= false;
1980 bool neigh_mac_change
= false;
1981 bool check_rbit
= false;
1983 /* Check if the MAC exists. */
1984 zmac
= zvni_mac_lookup(zvni
, macaddr
);
1986 /* create a dummy MAC if the MAC is not already present */
1987 if (IS_ZEBRA_DEBUG_VXLAN
)
1989 "AUTO MAC %s created for neigh %s on VNI %u",
1990 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
1991 ipaddr2str(ip
, buf2
, sizeof(buf2
)), zvni
->vni
);
1993 zmac
= zvni_mac_add(zvni
, macaddr
);
1995 zlog_debug("Failed to add MAC %s VNI %u",
1996 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2001 memset(&zmac
->fwd_info
, 0, sizeof(zmac
->fwd_info
));
2002 memset(&zmac
->flags
, 0, sizeof(uint32_t));
2003 SET_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
);
2005 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2007 * We don't change the MAC to local upon a neighbor
2008 * learn event, we wait for the explicit local MAC
2009 * learn. However, we have to compute its sequence
2010 * number in preparation for when it actually turns
2017 /* Check if the neighbor exists. */
2018 n
= zvni_neigh_lookup(zvni
, ip
);
2020 /* New neighbor - create */
2021 n
= zvni_neigh_add(zvni
, ip
, macaddr
);
2024 EC_ZEBRA_MAC_ADD_FAILED
,
2025 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2026 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
2027 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2028 ifp
->name
, ifp
->ifindex
, zvni
->vni
);
2031 /* Set "local" forwarding info. */
2032 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2033 n
->ifindex
= ifp
->ifindex
;
2036 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
2040 /* Note any changes and see if of interest to BGP. */
2041 mac_different
= (memcmp(n
->emac
.octet
,
2042 macaddr
->octet
, ETH_ALEN
) != 0) ? 1 : 0;
2043 cur_is_router
= !!CHECK_FLAG(n
->flags
,
2044 ZEBRA_NEIGH_ROUTER_FLAG
);
2045 if (!mac_different
&& is_router
== cur_is_router
) {
2046 n
->ifindex
= ifp
->ifindex
;
2050 if (!mac_different
) {
2051 /* Only the router flag has changed. */
2054 ZEBRA_NEIGH_ROUTER_FLAG
);
2056 UNSET_FLAG(n
->flags
,
2057 ZEBRA_NEIGH_ROUTER_FLAG
);
2059 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2060 return zvni_neigh_send_add_to_client(
2061 zvni
->vni
, ip
, macaddr
,
2062 n
->flags
, n
->loc_seq
);
2066 /* The MAC has changed, need to issue a delete
2067 * first as this means a different MACIP route.
2068 * Also, need to do some unlinking/relinking.
2069 * We also need to update the MAC's sequence number
2070 * in different situations.
2072 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
2073 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
,
2075 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2077 old_mac_seq
= CHECK_FLAG(old_zmac
->flags
,
2079 old_zmac
->rem_seq
: old_zmac
->loc_seq
;
2080 neigh_mac_change
= upd_mac_seq
= true;
2081 listnode_delete(old_zmac
->neigh_list
, n
);
2082 zvni_deref_ip2mac(zvni
, old_zmac
);
2085 /* Update the forwarding info. */
2086 n
->ifindex
= ifp
->ifindex
;
2087 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2089 /* Link to new MAC */
2090 listnode_add_sort(zmac
->neigh_list
, n
);
2091 } else if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2093 * Neighbor has moved from remote to local. Its
2094 * MAC could have also changed as part of the move.
2096 if (memcmp(n
->emac
.octet
, macaddr
->octet
,
2098 old_zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
2100 old_mac_seq
= CHECK_FLAG(
2105 neigh_mac_change
= upd_mac_seq
= true;
2106 listnode_delete(old_zmac
->neigh_list
,
2108 zvni_deref_ip2mac(zvni
, old_zmac
);
2111 /* Link to new MAC */
2112 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
2113 listnode_add_sort(zmac
->neigh_list
, n
);
2116 /* Mark appropriately */
2117 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2118 n
->r_vtep_ip
.s_addr
= 0;
2119 SET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2120 n
->ifindex
= ifp
->ifindex
;
2125 /* If MAC was previously remote, or the neighbor had a different
2126 * MAC earlier, recompute the sequence number.
2129 uint32_t seq1
, seq2
;
2131 seq1
= CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
) ?
2132 zmac
->rem_seq
+ 1 : zmac
->loc_seq
;
2133 seq2
= neigh_mac_change
? old_mac_seq
+ 1 : 0;
2134 mac_new_seq
= zmac
->loc_seq
< MAX(seq1
, seq2
) ?
2135 MAX(seq1
, seq2
) : zmac
->loc_seq
;
2138 /*Mark Router flag (R-bit) */
2140 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2142 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
2144 /* Before we program this in BGP, we need to check if MAC is locally
2145 * learnt. If not, force neighbor to be inactive and reset its seq.
2147 if (!CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_LOCAL
)) {
2148 ZEBRA_NEIGH_SET_INACTIVE(n
);
2150 zmac
->loc_seq
= mac_new_seq
;
2157 /* If the MAC's sequence number has changed, inform the MAC and all
2158 * neighbors associated with the MAC to BGP, else just inform this
2161 if (upd_mac_seq
&& zmac
->loc_seq
!= mac_new_seq
) {
2162 if (IS_ZEBRA_DEBUG_VXLAN
)
2163 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
2164 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2165 zvni
->vni
, zmac
->loc_seq
, mac_new_seq
);
2166 zmac
->loc_seq
= mac_new_seq
;
2167 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
2168 zmac
->flags
, zmac
->loc_seq
))
2170 zvni_process_neigh_on_local_mac_change(zvni
, zmac
, 1);
2174 ZEBRA_NEIGH_SET_ACTIVE(n
);
2175 n
->loc_seq
= zmac
->loc_seq
;
2177 return zvni_neigh_send_add_to_client(zvni
->vni
, ip
, macaddr
,
2178 n
->flags
, n
->loc_seq
);
2181 static int zvni_remote_neigh_update(zebra_vni_t
*zvni
,
2182 struct interface
*ifp
,
2184 struct ethaddr
*macaddr
,
2187 char buf
[ETHER_ADDR_STRLEN
];
2188 char buf2
[INET6_ADDRSTRLEN
];
2189 zebra_neigh_t
*n
= NULL
;
2190 zebra_mac_t
*zmac
= NULL
;
2192 /* If the neighbor is unknown, there is no further action. */
2193 n
= zvni_neigh_lookup(zvni
, ip
);
2197 /* If a remote entry, see if it needs to be refreshed */
2198 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
2200 if (state
& NUD_STALE
)
2201 zvni_neigh_install(zvni
, n
);
2204 /* We got a "remote" neighbor notification for an entry
2205 * we think is local. This can happen in a multihoming
2206 * scenario - but only if the MAC is already "remote".
2207 * Just mark our entry as "remote".
2209 zmac
= zvni_mac_lookup(zvni
, macaddr
);
2210 if (!zmac
|| !CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_REMOTE
)) {
2212 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
2213 ipaddr2str(&n
->ip
, buf2
, sizeof(buf2
)),
2214 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
2219 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
2220 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
2221 n
->r_vtep_ip
= zmac
->fwd_info
.r_vtep_ip
;
2228 * Make hash key for MAC.
2230 static unsigned int mac_hash_keymake(void *p
)
2232 zebra_mac_t
*pmac
= p
;
2233 const void *pnt
= (void *)pmac
->macaddr
.octet
;
2235 return jhash(pnt
, ETH_ALEN
, 0xa5a5a55a);
2239 * Compare two MAC addresses.
2241 static bool mac_cmp(const void *p1
, const void *p2
)
2243 const zebra_mac_t
*pmac1
= p1
;
2244 const zebra_mac_t
*pmac2
= p2
;
2246 if (pmac1
== NULL
&& pmac2
== NULL
)
2249 if (pmac1
== NULL
|| pmac2
== NULL
)
2252 return (memcmp(pmac1
->macaddr
.octet
, pmac2
->macaddr
.octet
, ETH_ALEN
)
2257 * Callback to allocate MAC hash entry.
2259 static void *zvni_mac_alloc(void *p
)
2261 const zebra_mac_t
*tmp_mac
= p
;
2264 mac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
2267 return ((void *)mac
);
2273 static zebra_mac_t
*zvni_mac_add(zebra_vni_t
*zvni
, struct ethaddr
*macaddr
)
2275 zebra_mac_t tmp_mac
;
2276 zebra_mac_t
*mac
= NULL
;
2278 memset(&tmp_mac
, 0, sizeof(zebra_mac_t
));
2279 memcpy(&tmp_mac
.macaddr
, macaddr
, ETH_ALEN
);
2280 mac
= hash_get(zvni
->mac_table
, &tmp_mac
, zvni_mac_alloc
);
2283 mac
->neigh_list
= list_new();
2284 mac
->neigh_list
->cmp
= neigh_list_cmp
;
2292 static int zvni_mac_del(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2294 zebra_mac_t
*tmp_mac
;
2296 list_delete(&mac
->neigh_list
);
2298 /* Free the VNI hash entry and allocated memory. */
2299 tmp_mac
= hash_release(zvni
->mac_table
, mac
);
2301 XFREE(MTYPE_MAC
, tmp_mac
);
2307 * Free MAC hash entry (callback)
2309 static void zvni_mac_del_hash_entry(struct hash_backet
*backet
, void *arg
)
2311 struct mac_walk_ctx
*wctx
= arg
;
2312 zebra_mac_t
*mac
= backet
->data
;
2314 if (((wctx
->flags
& DEL_LOCAL_MAC
) && (mac
->flags
& ZEBRA_MAC_LOCAL
))
2315 || ((wctx
->flags
& DEL_REMOTE_MAC
)
2316 && (mac
->flags
& ZEBRA_MAC_REMOTE
))
2317 || ((wctx
->flags
& DEL_REMOTE_MAC_FROM_VTEP
)
2318 && (mac
->flags
& ZEBRA_MAC_REMOTE
)
2319 && IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
,
2320 &wctx
->r_vtep_ip
))) {
2321 if (wctx
->upd_client
&& (mac
->flags
& ZEBRA_MAC_LOCAL
)) {
2322 zvni_mac_send_del_to_client(wctx
->zvni
->vni
,
2323 &mac
->macaddr
, mac
->flags
);
2326 if (wctx
->uninstall
)
2327 zvni_mac_uninstall(wctx
->zvni
, mac
);
2329 zvni_mac_del(wctx
->zvni
, mac
);
2336 * Delete all MAC entries from specific VTEP for a particular VNI.
2338 static void zvni_mac_del_from_vtep(zebra_vni_t
*zvni
, int uninstall
,
2339 struct in_addr
*r_vtep_ip
)
2341 struct mac_walk_ctx wctx
;
2343 if (!zvni
->mac_table
)
2346 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2348 wctx
.uninstall
= uninstall
;
2349 wctx
.flags
= DEL_REMOTE_MAC_FROM_VTEP
;
2350 wctx
.r_vtep_ip
= *r_vtep_ip
;
2352 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2356 * Delete all MAC entries for this VNI.
2358 static void zvni_mac_del_all(zebra_vni_t
*zvni
, int uninstall
, int upd_client
,
2361 struct mac_walk_ctx wctx
;
2363 if (!zvni
->mac_table
)
2366 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
2368 wctx
.uninstall
= uninstall
;
2369 wctx
.upd_client
= upd_client
;
2372 hash_iterate(zvni
->mac_table
, zvni_mac_del_hash_entry
, &wctx
);
2376 * Look up MAC hash entry.
2378 static zebra_mac_t
*zvni_mac_lookup(zebra_vni_t
*zvni
, struct ethaddr
*mac
)
2383 memset(&tmp
, 0, sizeof(tmp
));
2384 memcpy(&tmp
.macaddr
, mac
, ETH_ALEN
);
2385 pmac
= hash_lookup(zvni
->mac_table
, &tmp
);
2391 * Inform BGP about local MAC addition.
2393 static int zvni_mac_send_add_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2394 uint8_t mac_flags
, uint32_t seq
)
2398 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2399 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2400 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2401 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2403 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2404 seq
, ZEBRA_MACIP_ADD
);
2408 * Inform BGP about local MAC deletion.
2410 static int zvni_mac_send_del_to_client(vni_t vni
, struct ethaddr
*macaddr
,
2415 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_STICKY
))
2416 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
2417 if (CHECK_FLAG(mac_flags
, ZEBRA_MAC_DEF_GW
))
2418 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
2420 return zvni_macip_send_msg_to_client(vni
, macaddr
, NULL
, flags
,
2421 0, ZEBRA_MACIP_DEL
);
2425 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2426 * notifications, to see if they are of interest.
2428 static zebra_vni_t
*zvni_map_vlan(struct interface
*ifp
,
2429 struct interface
*br_if
, vlanid_t vid
)
2431 struct zebra_ns
*zns
;
2432 struct route_node
*rn
;
2433 struct interface
*tmp_if
= NULL
;
2434 struct zebra_if
*zif
;
2435 struct zebra_l2info_bridge
*br
;
2436 struct zebra_l2info_vxlan
*vxl
= NULL
;
2437 uint8_t bridge_vlan_aware
;
2441 /* Determine if bridge is VLAN-aware or not */
2444 br
= &zif
->l2info
.br
;
2445 bridge_vlan_aware
= br
->vlan_aware
;
2447 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2448 /* TODO: Optimize with a hash. */
2449 zns
= zebra_ns_lookup(NS_DEFAULT
);
2450 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2451 tmp_if
= (struct interface
*)rn
->info
;
2455 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2457 if (!if_is_operative(tmp_if
))
2459 vxl
= &zif
->l2info
.vxl
;
2461 if (zif
->brslave_info
.br_if
!= br_if
)
2464 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2473 zvni
= zvni_lookup(vxl
->vni
);
2478 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2479 * neighbor notifications, to see if they are of interest.
2481 static zebra_vni_t
*zvni_from_svi(struct interface
*ifp
,
2482 struct interface
*br_if
)
2484 struct zebra_ns
*zns
;
2485 struct route_node
*rn
;
2486 struct interface
*tmp_if
= NULL
;
2487 struct zebra_if
*zif
;
2488 struct zebra_l2info_bridge
*br
;
2489 struct zebra_l2info_vxlan
*vxl
= NULL
;
2490 uint8_t bridge_vlan_aware
;
2498 /* Make sure the linked interface is a bridge. */
2499 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
2502 /* Determine if bridge is VLAN-aware or not */
2505 br
= &zif
->l2info
.br
;
2506 bridge_vlan_aware
= br
->vlan_aware
;
2507 if (bridge_vlan_aware
) {
2508 struct zebra_l2info_vlan
*vl
;
2510 if (!IS_ZEBRA_IF_VLAN(ifp
))
2515 vl
= &zif
->l2info
.vl
;
2519 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2520 /* TODO: Optimize with a hash. */
2521 zns
= zebra_ns_lookup(NS_DEFAULT
);
2522 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2523 tmp_if
= (struct interface
*)rn
->info
;
2527 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2529 if (!if_is_operative(tmp_if
))
2531 vxl
= &zif
->l2info
.vxl
;
2533 if (zif
->brslave_info
.br_if
!= br_if
)
2536 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
2545 zvni
= zvni_lookup(vxl
->vni
);
2549 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2551 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2552 * linked to the bridge
2553 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2556 static struct interface
*zvni_map_to_svi(vlanid_t vid
, struct interface
*br_if
)
2558 struct zebra_ns
*zns
;
2559 struct route_node
*rn
;
2560 struct interface
*tmp_if
= NULL
;
2561 struct zebra_if
*zif
;
2562 struct zebra_l2info_bridge
*br
;
2563 struct zebra_l2info_vlan
*vl
;
2564 uint8_t bridge_vlan_aware
;
2567 /* Defensive check, caller expected to invoke only with valid bridge. */
2571 /* Determine if bridge is VLAN-aware or not */
2574 br
= &zif
->l2info
.br
;
2575 bridge_vlan_aware
= br
->vlan_aware
;
2577 /* Check oper status of the SVI. */
2578 if (!bridge_vlan_aware
)
2579 return if_is_operative(br_if
) ? br_if
: NULL
;
2581 /* Identify corresponding VLAN interface. */
2582 /* TODO: Optimize with a hash. */
2583 zns
= zebra_ns_lookup(NS_DEFAULT
);
2584 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2585 tmp_if
= (struct interface
*)rn
->info
;
2586 /* Check oper status of the SVI. */
2587 if (!tmp_if
|| !if_is_operative(tmp_if
))
2590 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VLAN
2591 || zif
->link
!= br_if
)
2593 vl
= (struct zebra_l2info_vlan
*)&zif
->l2info
.vl
;
2595 if (vl
->vid
== vid
) {
2601 return found
? tmp_if
: NULL
;
2605 * Install remote MAC into the kernel.
2607 static int zvni_mac_install(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2609 struct zebra_if
*zif
;
2610 struct zebra_l2info_vxlan
*vxl
;
2613 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2616 zif
= zvni
->vxlan_if
->info
;
2619 vxl
= &zif
->l2info
.vxl
;
2621 sticky
= !!CHECK_FLAG(mac
->flags
,
2622 (ZEBRA_MAC_STICKY
| ZEBRA_MAC_REMOTE_DEF_GW
));
2624 return kernel_add_mac(zvni
->vxlan_if
, vxl
->access_vlan
, &mac
->macaddr
,
2625 mac
->fwd_info
.r_vtep_ip
, sticky
);
2629 * Uninstall remote MAC from the kernel.
2631 static int zvni_mac_uninstall(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2633 struct zebra_if
*zif
;
2634 struct zebra_l2info_vxlan
*vxl
;
2635 struct in_addr vtep_ip
;
2636 struct interface
*ifp
;
2638 if (!(mac
->flags
& ZEBRA_MAC_REMOTE
))
2641 if (!zvni
->vxlan_if
) {
2642 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2647 zif
= zvni
->vxlan_if
->info
;
2650 vxl
= &zif
->l2info
.vxl
;
2652 ifp
= zvni
->vxlan_if
;
2653 vtep_ip
= mac
->fwd_info
.r_vtep_ip
;
2655 return kernel_del_mac(ifp
, vxl
->access_vlan
, &mac
->macaddr
, vtep_ip
);
2659 * Install MAC hash entry - called upon access VLAN change.
2661 static void zvni_install_mac_hash(struct hash_backet
*backet
, void *ctxt
)
2664 struct mac_walk_ctx
*wctx
= ctxt
;
2666 mac
= (zebra_mac_t
*)backet
->data
;
2668 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
2669 zvni_mac_install(wctx
->zvni
, mac
);
2673 * Count of remote neighbors referencing this MAC.
2675 static int remote_neigh_count(zebra_mac_t
*zmac
)
2677 zebra_neigh_t
*n
= NULL
;
2678 struct listnode
*node
= NULL
;
2681 for (ALL_LIST_ELEMENTS_RO(zmac
->neigh_list
, node
, n
)) {
2682 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
))
2690 * Decrement neighbor refcount of MAC; uninstall and free it if
2693 static void zvni_deref_ip2mac(zebra_vni_t
*zvni
, zebra_mac_t
*mac
)
2695 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
))
2698 /* If all remote neighbors referencing a remote MAC go away,
2699 * we need to uninstall the MAC.
2701 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
) &&
2702 remote_neigh_count(mac
) == 0) {
2703 zvni_mac_uninstall(zvni
, mac
);
2704 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
2707 /* If no neighbors, delete the MAC. */
2708 if (list_isempty(mac
->neigh_list
))
2709 zvni_mac_del(zvni
, mac
);
2713 * Read and populate local MACs and neighbors corresponding to this VNI.
2715 static void zvni_read_mac_neigh(zebra_vni_t
*zvni
, struct interface
*ifp
)
2717 struct zebra_ns
*zns
;
2718 struct zebra_if
*zif
;
2719 struct interface
*vlan_if
;
2720 struct zebra_l2info_vxlan
*vxl
;
2721 struct interface
*vrr_if
;
2724 vxl
= &zif
->l2info
.vxl
;
2725 zns
= zebra_ns_lookup(NS_DEFAULT
);
2727 if (IS_ZEBRA_DEBUG_VXLAN
)
2729 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2730 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
2731 zif
->brslave_info
.bridge_ifindex
);
2733 macfdb_read_for_bridge(zns
, ifp
, zif
->brslave_info
.br_if
);
2734 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
2737 /* Add SVI MAC-IP */
2738 zvni_add_macip_for_intf(vlan_if
, zvni
);
2740 /* Add VRR MAC-IP - if any*/
2741 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
2743 zvni_add_macip_for_intf(vrr_if
, zvni
);
2745 neigh_read_for_vlan(zns
, vlan_if
);
2750 * Hash function for VNI.
2752 static unsigned int vni_hash_keymake(void *p
)
2754 const zebra_vni_t
*zvni
= p
;
2756 return (jhash_1word(zvni
->vni
, 0));
2760 * Compare 2 VNI hash entries.
2762 static bool vni_hash_cmp(const void *p1
, const void *p2
)
2764 const zebra_vni_t
*zvni1
= p1
;
2765 const zebra_vni_t
*zvni2
= p2
;
2767 return (zvni1
->vni
== zvni2
->vni
);
2770 static int vni_list_cmp(void *p1
, void *p2
)
2772 const zebra_vni_t
*zvni1
= p1
;
2773 const zebra_vni_t
*zvni2
= p2
;
2775 if (zvni1
->vni
== zvni2
->vni
)
2777 return (zvni1
->vni
< zvni2
->vni
) ? -1 : 1;
2781 * Callback to allocate VNI hash entry.
2783 static void *zvni_alloc(void *p
)
2785 const zebra_vni_t
*tmp_vni
= p
;
2788 zvni
= XCALLOC(MTYPE_ZVNI
, sizeof(zebra_vni_t
));
2789 zvni
->vni
= tmp_vni
->vni
;
2790 return ((void *)zvni
);
2794 * Look up VNI hash entry.
2796 static zebra_vni_t
*zvni_lookup(vni_t vni
)
2798 struct zebra_vrf
*zvrf
;
2799 zebra_vni_t tmp_vni
;
2800 zebra_vni_t
*zvni
= NULL
;
2802 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2804 memset(&tmp_vni
, 0, sizeof(zebra_vni_t
));
2806 zvni
= hash_lookup(zvrf
->vni_table
, &tmp_vni
);
2812 * Add VNI hash entry.
2814 static zebra_vni_t
*zvni_add(vni_t vni
)
2816 struct zebra_vrf
*zvrf
;
2817 zebra_vni_t tmp_zvni
;
2818 zebra_vni_t
*zvni
= NULL
;
2820 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2822 memset(&tmp_zvni
, 0, sizeof(zebra_vni_t
));
2824 zvni
= hash_get(zvrf
->vni_table
, &tmp_zvni
, zvni_alloc
);
2827 /* Create hash table for MAC */
2829 hash_create(mac_hash_keymake
, mac_cmp
, "Zebra VNI MAC Table");
2831 /* Create hash table for neighbors */
2832 zvni
->neigh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
2833 "Zebra VNI Neighbor Table");
2839 * Delete VNI hash entry.
2841 static int zvni_del(zebra_vni_t
*zvni
)
2843 struct zebra_vrf
*zvrf
;
2844 zebra_vni_t
*tmp_zvni
;
2846 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2849 zvni
->vxlan_if
= NULL
;
2851 /* Free the neighbor hash table. */
2852 hash_free(zvni
->neigh_table
);
2853 zvni
->neigh_table
= NULL
;
2855 /* Free the MAC hash table. */
2856 hash_free(zvni
->mac_table
);
2857 zvni
->mac_table
= NULL
;
2859 /* Free the VNI hash entry and allocated memory. */
2860 tmp_zvni
= hash_release(zvrf
->vni_table
, zvni
);
2862 XFREE(MTYPE_ZVNI
, tmp_zvni
);
2868 * Inform BGP about local VNI addition.
2870 static int zvni_send_add_to_client(zebra_vni_t
*zvni
)
2872 struct zserv
*client
;
2875 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2876 /* BGP may not be running. */
2880 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2882 zclient_create_header(s
, ZEBRA_VNI_ADD
, VRF_DEFAULT
);
2883 stream_putl(s
, zvni
->vni
);
2884 stream_put_in_addr(s
, &zvni
->local_vtep_ip
);
2885 stream_put(s
, &zvni
->vrf_id
, sizeof(vrf_id_t
)); /* tenant vrf */
2887 /* Write packet size. */
2888 stream_putw_at(s
, 0, stream_get_endp(s
));
2890 if (IS_ZEBRA_DEBUG_VXLAN
)
2891 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni
->vni
,
2892 inet_ntoa(zvni
->local_vtep_ip
),
2893 vrf_id_to_name(zvni
->vrf_id
),
2894 zebra_route_string(client
->proto
));
2896 client
->vniadd_cnt
++;
2897 return zserv_send_message(client
, s
);
2901 * Inform BGP about local VNI deletion.
2903 static int zvni_send_del_to_client(vni_t vni
)
2905 struct zserv
*client
;
2908 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
2909 /* BGP may not be running. */
2913 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
2916 zclient_create_header(s
, ZEBRA_VNI_DEL
, VRF_DEFAULT
);
2917 stream_putl(s
, vni
);
2919 /* Write packet size. */
2920 stream_putw_at(s
, 0, stream_get_endp(s
));
2922 if (IS_ZEBRA_DEBUG_VXLAN
)
2923 zlog_debug("Send VNI_DEL %u to %s", vni
,
2924 zebra_route_string(client
->proto
));
2926 client
->vnidel_cnt
++;
2927 return zserv_send_message(client
, s
);
2931 * Build the VNI hash table by going over the VxLAN interfaces. This
2932 * is called when EVPN (advertise-all-vni) is enabled.
2934 static void zvni_build_hash_table()
2936 struct zebra_ns
*zns
;
2937 struct route_node
*rn
;
2938 struct interface
*ifp
;
2940 /* Walk VxLAN interfaces and create VNI hash. */
2941 zns
= zebra_ns_lookup(NS_DEFAULT
);
2942 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
2944 zebra_vni_t
*zvni
= NULL
;
2945 zebra_l3vni_t
*zl3vni
= NULL
;
2946 struct zebra_if
*zif
;
2947 struct zebra_l2info_vxlan
*vxl
;
2949 ifp
= (struct interface
*)rn
->info
;
2953 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
2956 vxl
= &zif
->l2info
.vxl
;
2959 /* L3-VNI and L2-VNI are handled seperately */
2960 zl3vni
= zl3vni_lookup(vni
);
2963 if (IS_ZEBRA_DEBUG_VXLAN
)
2965 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2966 ifp
->name
, ifp
->ifindex
, vni
);
2968 /* associate with vxlan_if */
2969 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
2970 zl3vni
->vxlan_if
= ifp
;
2973 * we need to associate with SVI.
2974 * we can associate with svi-if only after association
2975 * with vxlan-intf is complete
2977 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
2979 if (is_l3vni_oper_up(zl3vni
))
2980 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
2983 struct interface
*vlan_if
= NULL
;
2985 if (IS_ZEBRA_DEBUG_VXLAN
)
2987 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2988 ifp
->name
, ifp
->ifindex
, vni
,
2989 inet_ntoa(vxl
->vtep_ip
));
2991 /* VNI hash entry is not expected to exist. */
2992 zvni
= zvni_lookup(vni
);
2995 "VNI hash already present for IF %s(%u) L2-VNI %u",
2996 ifp
->name
, ifp
->ifindex
, vni
);
3000 zvni
= zvni_add(vni
);
3003 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
3004 ifp
->name
, ifp
->ifindex
, vni
);
3008 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
3009 zvni
->vxlan_if
= ifp
;
3010 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
3011 zif
->brslave_info
.br_if
);
3013 zvni
->vrf_id
= vlan_if
->vrf_id
;
3014 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
3016 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3020 /* Inform BGP if intf is up and mapped to bridge. */
3021 if (if_is_operative(ifp
) && zif
->brslave_info
.br_if
)
3022 zvni_send_add_to_client(zvni
);
3028 * See if remote VTEP matches with prefix.
3030 static int zvni_vtep_match(struct in_addr
*vtep_ip
, zebra_vtep_t
*zvtep
)
3032 return (IPV4_ADDR_SAME(vtep_ip
, &zvtep
->vtep_ip
));
3036 * Locate remote VTEP in VNI hash table.
3038 static zebra_vtep_t
*zvni_vtep_find(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3040 zebra_vtep_t
*zvtep
;
3045 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
3046 if (zvni_vtep_match(vtep_ip
, zvtep
))
3054 * Add remote VTEP to VNI hash table.
3056 static zebra_vtep_t
*zvni_vtep_add(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3058 zebra_vtep_t
*zvtep
;
3060 zvtep
= XCALLOC(MTYPE_ZVNI_VTEP
, sizeof(zebra_vtep_t
));
3062 zvtep
->vtep_ip
= *vtep_ip
;
3065 zvni
->vteps
->prev
= zvtep
;
3066 zvtep
->next
= zvni
->vteps
;
3067 zvni
->vteps
= zvtep
;
3073 * Remove remote VTEP from VNI hash table.
3075 static int zvni_vtep_del(zebra_vni_t
*zvni
, zebra_vtep_t
*zvtep
)
3078 zvtep
->next
->prev
= zvtep
->prev
;
3080 zvtep
->prev
->next
= zvtep
->next
;
3082 zvni
->vteps
= zvtep
->next
;
3084 zvtep
->prev
= zvtep
->next
= NULL
;
3085 XFREE(MTYPE_ZVNI_VTEP
, zvtep
);
3091 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
3092 * uninstall from kernel if asked to.
3094 static int zvni_vtep_del_all(zebra_vni_t
*zvni
, int uninstall
)
3096 zebra_vtep_t
*zvtep
, *zvtep_next
;
3101 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep_next
) {
3102 zvtep_next
= zvtep
->next
;
3104 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
3105 zvni_vtep_del(zvni
, zvtep
);
3112 * Install remote VTEP into the kernel.
3114 static int zvni_vtep_install(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3116 if (is_vxlan_flooding_head_end())
3117 return kernel_add_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3122 * Uninstall remote VTEP from the kernel.
3124 static int zvni_vtep_uninstall(zebra_vni_t
*zvni
, struct in_addr
*vtep_ip
)
3126 if (!zvni
->vxlan_if
) {
3127 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3132 return kernel_del_vtep(zvni
->vni
, zvni
->vxlan_if
, vtep_ip
);
3136 * Install or uninstall flood entries in the kernel corresponding to
3137 * remote VTEPs. This is invoked upon change to BUM handling.
3139 static void zvni_handle_flooding_remote_vteps(struct hash_backet
*backet
,
3143 zebra_vtep_t
*zvtep
;
3145 zvni
= (zebra_vni_t
*)backet
->data
;
3149 for (zvtep
= zvni
->vteps
; zvtep
; zvtep
= zvtep
->next
) {
3150 if (is_vxlan_flooding_head_end())
3151 zvni_vtep_install(zvni
, &zvtep
->vtep_ip
);
3153 zvni_vtep_uninstall(zvni
, &zvtep
->vtep_ip
);
3158 * Cleanup VNI/VTEP and update kernel
3160 static void zvni_cleanup_all(struct hash_backet
*backet
, void *arg
)
3162 zebra_vni_t
*zvni
= NULL
;
3163 zebra_l3vni_t
*zl3vni
= NULL
;
3164 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)arg
;
3166 zvni
= (zebra_vni_t
*)backet
->data
;
3168 /* remove from l3-vni list */
3170 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
3172 listnode_delete(zl3vni
->l2vnis
, zvni
);
3174 /* Free up all neighbors and MACs, if any. */
3175 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
3176 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
3178 /* Free up all remote VTEPs, if any. */
3179 zvni_vtep_del_all(zvni
, 1);
3181 /* Delete the hash entry. */
3186 static void zl3vni_cleanup_all(struct hash_backet
*backet
, void *args
)
3188 zebra_l3vni_t
*zl3vni
= NULL
;
3190 zl3vni
= (zebra_l3vni_t
*)backet
->data
;
3192 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
3195 static void rb_find_or_add_host(struct host_rb_tree_entry
*hrbe
,
3196 struct prefix
*host
)
3198 struct host_rb_entry lookup
;
3199 struct host_rb_entry
*hle
;
3201 memset(&lookup
, 0, sizeof(lookup
));
3202 memcpy(&lookup
.p
, host
, sizeof(*host
));
3204 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3208 hle
= XCALLOC(MTYPE_HOST_PREFIX
, sizeof(struct host_rb_entry
));
3209 memcpy(hle
, &lookup
, sizeof(lookup
));
3211 RB_INSERT(host_rb_tree_entry
, hrbe
, hle
);
3214 static void rb_delete_host(struct host_rb_tree_entry
*hrbe
, struct prefix
*host
)
3216 struct host_rb_entry lookup
;
3217 struct host_rb_entry
*hle
;
3219 memset(&lookup
, 0, sizeof(lookup
));
3220 memcpy(&lookup
.p
, host
, sizeof(*host
));
3222 hle
= RB_FIND(host_rb_tree_entry
, hrbe
, &lookup
);
3224 RB_REMOVE(host_rb_tree_entry
, hrbe
, hle
);
3225 XFREE(MTYPE_HOST_PREFIX
, hle
);
3232 * Look up MAC hash entry.
3234 static zebra_mac_t
*zl3vni_rmac_lookup(zebra_l3vni_t
*zl3vni
,
3235 struct ethaddr
*rmac
)
3240 memset(&tmp
, 0, sizeof(tmp
));
3241 memcpy(&tmp
.macaddr
, rmac
, ETH_ALEN
);
3242 pmac
= hash_lookup(zl3vni
->rmac_table
, &tmp
);
3248 * Callback to allocate RMAC hash entry.
3250 static void *zl3vni_rmac_alloc(void *p
)
3252 const zebra_mac_t
*tmp_rmac
= p
;
3255 zrmac
= XCALLOC(MTYPE_MAC
, sizeof(zebra_mac_t
));
3258 return ((void *)zrmac
);
3262 * Add RMAC entry to l3-vni
3264 static zebra_mac_t
*zl3vni_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
)
3266 zebra_mac_t tmp_rmac
;
3267 zebra_mac_t
*zrmac
= NULL
;
3269 memset(&tmp_rmac
, 0, sizeof(zebra_mac_t
));
3270 memcpy(&tmp_rmac
.macaddr
, rmac
, ETH_ALEN
);
3271 zrmac
= hash_get(zl3vni
->rmac_table
, &tmp_rmac
, zl3vni_rmac_alloc
);
3274 RB_INIT(host_rb_tree_entry
, &zrmac
->host_rb
);
3276 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
);
3277 SET_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
);
3285 static int zl3vni_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3287 zebra_mac_t
*tmp_rmac
;
3288 struct host_rb_entry
*hle
;
3290 while (!RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3291 hle
= RB_ROOT(host_rb_tree_entry
, &zrmac
->host_rb
);
3293 RB_REMOVE(host_rb_tree_entry
, &zrmac
->host_rb
, hle
);
3294 XFREE(MTYPE_HOST_PREFIX
, hle
);
3297 tmp_rmac
= hash_release(zl3vni
->rmac_table
, zrmac
);
3299 XFREE(MTYPE_MAC
, tmp_rmac
);
3305 * Install remote RMAC into the kernel.
3307 static int zl3vni_rmac_install(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3309 struct zebra_if
*zif
= NULL
;
3310 struct zebra_l2info_vxlan
*vxl
= NULL
;
3312 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3313 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3316 zif
= zl3vni
->vxlan_if
->info
;
3320 vxl
= &zif
->l2info
.vxl
;
3322 return kernel_add_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3323 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
, 0);
3327 * Uninstall remote RMAC from the kernel.
3329 static int zl3vni_rmac_uninstall(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
)
3331 char buf
[ETHER_ADDR_STRLEN
];
3332 struct zebra_if
*zif
= NULL
;
3333 struct zebra_l2info_vxlan
*vxl
= NULL
;
3335 if (!(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE
))
3336 || !(CHECK_FLAG(zrmac
->flags
, ZEBRA_MAC_REMOTE_RMAC
)))
3339 if (!zl3vni
->vxlan_if
) {
3341 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
3342 prefix_mac2str(&zrmac
->macaddr
, buf
, sizeof(buf
)),
3343 zl3vni
->vni
, zl3vni
);
3347 zif
= zl3vni
->vxlan_if
->info
;
3351 vxl
= &zif
->l2info
.vxl
;
3353 return kernel_del_mac(zl3vni
->vxlan_if
, vxl
->access_vlan
,
3354 &zrmac
->macaddr
, zrmac
->fwd_info
.r_vtep_ip
);
3357 /* handle rmac add */
3358 static int zl3vni_remote_rmac_add(zebra_l3vni_t
*zl3vni
, struct ethaddr
*rmac
,
3359 struct ipaddr
*vtep_ip
,
3360 struct prefix
*host_prefix
)
3362 char buf
[ETHER_ADDR_STRLEN
];
3363 char buf1
[INET6_ADDRSTRLEN
];
3364 zebra_mac_t
*zrmac
= NULL
;
3366 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
3369 zrmac
= zl3vni_rmac_add(zl3vni
, rmac
);
3372 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3373 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3375 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)));
3378 memset(&zrmac
->fwd_info
, 0, sizeof(zrmac
->fwd_info
));
3379 zrmac
->fwd_info
.r_vtep_ip
= vtep_ip
->ipaddr_v4
;
3381 /* install rmac in kernel */
3382 zl3vni_rmac_install(zl3vni
, zrmac
);
3385 rb_find_or_add_host(&zrmac
->host_rb
, host_prefix
);
3391 /* handle rmac delete */
3392 static void zl3vni_remote_rmac_del(zebra_l3vni_t
*zl3vni
, zebra_mac_t
*zrmac
,
3393 struct prefix
*host_prefix
)
3395 rb_delete_host(&zrmac
->host_rb
, host_prefix
);
3397 if (RB_EMPTY(host_rb_tree_entry
, &zrmac
->host_rb
)) {
3398 /* uninstall from kernel */
3399 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
3401 /* del the rmac entry */
3402 zl3vni_rmac_del(zl3vni
, zrmac
);
3407 * Look up nh hash entry on a l3-vni.
3409 static zebra_neigh_t
*zl3vni_nh_lookup(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3414 memset(&tmp
, 0, sizeof(tmp
));
3415 memcpy(&tmp
.ip
, ip
, sizeof(struct ipaddr
));
3416 n
= hash_lookup(zl3vni
->nh_table
, &tmp
);
3423 * Callback to allocate NH hash entry on L3-VNI.
3425 static void *zl3vni_nh_alloc(void *p
)
3427 const zebra_neigh_t
*tmp_n
= p
;
3430 n
= XCALLOC(MTYPE_NEIGH
, sizeof(zebra_neigh_t
));
3437 * Add neighbor entry.
3439 static zebra_neigh_t
*zl3vni_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3440 struct ethaddr
*mac
)
3442 zebra_neigh_t tmp_n
;
3443 zebra_neigh_t
*n
= NULL
;
3445 memset(&tmp_n
, 0, sizeof(zebra_neigh_t
));
3446 memcpy(&tmp_n
.ip
, ip
, sizeof(struct ipaddr
));
3447 n
= hash_get(zl3vni
->nh_table
, &tmp_n
, zl3vni_nh_alloc
);
3450 RB_INIT(host_rb_tree_entry
, &n
->host_rb
);
3452 memcpy(&n
->emac
, mac
, ETH_ALEN
);
3453 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
3454 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE_NH
);
3460 * Delete neighbor entry.
3462 static int zl3vni_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3464 zebra_neigh_t
*tmp_n
;
3465 struct host_rb_entry
*hle
;
3467 while (!RB_EMPTY(host_rb_tree_entry
, &n
->host_rb
)) {
3468 hle
= RB_ROOT(host_rb_tree_entry
, &n
->host_rb
);
3470 RB_REMOVE(host_rb_tree_entry
, &n
->host_rb
, hle
);
3471 XFREE(MTYPE_HOST_PREFIX
, hle
);
3474 tmp_n
= hash_release(zl3vni
->nh_table
, n
);
3476 XFREE(MTYPE_NEIGH
, tmp_n
);
3482 * Install remote nh as neigh into the kernel.
3484 static int zl3vni_nh_install(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3491 if (!is_l3vni_oper_up(zl3vni
))
3494 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3495 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3498 flags
= NTF_EXT_LEARNED
;
3499 if (n
->flags
& ZEBRA_NEIGH_ROUTER_FLAG
)
3500 flags
|= NTF_ROUTER
;
3501 ret
= kernel_add_neigh(zl3vni
->svi_if
, &n
->ip
, &n
->emac
, flags
);
3507 * Uninstall remote nh from the kernel.
3509 static int zl3vni_nh_uninstall(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*n
)
3511 if (!(n
->flags
& ZEBRA_NEIGH_REMOTE
)
3512 || !(n
->flags
& ZEBRA_NEIGH_REMOTE_NH
))
3515 if (!zl3vni
->svi_if
|| !if_is_operative(zl3vni
->svi_if
))
3518 return kernel_del_neigh(zl3vni
->svi_if
, &n
->ip
);
3521 /* add remote vtep as a neigh entry */
3522 static int zl3vni_remote_nh_add(zebra_l3vni_t
*zl3vni
, struct ipaddr
*vtep_ip
,
3523 struct ethaddr
*rmac
,
3524 struct prefix
*host_prefix
)
3526 char buf
[ETHER_ADDR_STRLEN
];
3527 char buf1
[INET6_ADDRSTRLEN
];
3528 zebra_neigh_t
*nh
= NULL
;
3530 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
3532 nh
= zl3vni_nh_add(zl3vni
, vtep_ip
, rmac
);
3536 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3537 ipaddr2str(vtep_ip
, buf1
, sizeof(buf1
)),
3538 prefix_mac2str(rmac
, buf
, sizeof(buf
)),
3543 /* install the nh neigh in kernel */
3544 zl3vni_nh_install(zl3vni
, nh
);
3547 rb_find_or_add_host(&nh
->host_rb
, host_prefix
);
3552 /* handle nh neigh delete */
3553 static void zl3vni_remote_nh_del(zebra_l3vni_t
*zl3vni
, zebra_neigh_t
*nh
,
3554 struct prefix
*host_prefix
)
3556 rb_delete_host(&nh
->host_rb
, host_prefix
);
3558 if (RB_EMPTY(host_rb_tree_entry
, &nh
->host_rb
)) {
3559 /* uninstall from kernel */
3560 zl3vni_nh_uninstall(zl3vni
, nh
);
3562 /* delete the nh entry */
3563 zl3vni_nh_del(zl3vni
, nh
);
3567 /* handle neigh update from kernel - the only thing of interest is to
3568 * readd stale entries.
3570 static int zl3vni_local_nh_add_update(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
,
3574 zebra_neigh_t
*n
= NULL
;
3576 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3580 /* all next hop neigh are remote and installed by frr.
3581 * If the kernel has aged this entry, re-install.
3583 if (state
& NUD_STALE
)
3584 zl3vni_nh_install(zl3vni
, n
);
3589 /* handle neigh delete from kernel */
3590 static int zl3vni_local_nh_del(zebra_l3vni_t
*zl3vni
, struct ipaddr
*ip
)
3592 zebra_neigh_t
*n
= NULL
;
3594 n
= zl3vni_nh_lookup(zl3vni
, ip
);
3598 /* all next hop neigh are remote and installed by frr.
3599 * If we get an age out notification for these neigh entries, we have to
3602 zl3vni_nh_install(zl3vni
, n
);
3608 * Hash function for L3 VNI.
3610 static unsigned int l3vni_hash_keymake(void *p
)
3612 const zebra_l3vni_t
*zl3vni
= p
;
3614 return jhash_1word(zl3vni
->vni
, 0);
3618 * Compare 2 L3 VNI hash entries.
3620 static bool l3vni_hash_cmp(const void *p1
, const void *p2
)
3622 const zebra_l3vni_t
*zl3vni1
= p1
;
3623 const zebra_l3vni_t
*zl3vni2
= p2
;
3625 return (zl3vni1
->vni
== zl3vni2
->vni
);
3629 * Callback to allocate L3 VNI hash entry.
3631 static void *zl3vni_alloc(void *p
)
3633 zebra_l3vni_t
*zl3vni
= NULL
;
3634 const zebra_l3vni_t
*tmp_l3vni
= p
;
3636 zl3vni
= XCALLOC(MTYPE_ZL3VNI
, sizeof(zebra_l3vni_t
));
3637 zl3vni
->vni
= tmp_l3vni
->vni
;
3638 return ((void *)zl3vni
);
3642 * Look up L3 VNI hash entry.
3644 static zebra_l3vni_t
*zl3vni_lookup(vni_t vni
)
3646 struct zebra_ns
*zns
;
3647 zebra_l3vni_t tmp_l3vni
;
3648 zebra_l3vni_t
*zl3vni
= NULL
;
3650 zns
= zebra_ns_lookup(NS_DEFAULT
);
3652 memset(&tmp_l3vni
, 0, sizeof(zebra_l3vni_t
));
3653 tmp_l3vni
.vni
= vni
;
3654 zl3vni
= hash_lookup(zns
->l3vni_table
, &tmp_l3vni
);
3660 * Add L3 VNI hash entry.
3662 static zebra_l3vni_t
*zl3vni_add(vni_t vni
, vrf_id_t vrf_id
)
3664 zebra_l3vni_t tmp_zl3vni
;
3665 struct zebra_ns
*zns
= NULL
;
3666 zebra_l3vni_t
*zl3vni
= NULL
;
3668 zns
= zebra_ns_lookup(NS_DEFAULT
);
3671 memset(&tmp_zl3vni
, 0, sizeof(zebra_l3vni_t
));
3672 tmp_zl3vni
.vni
= vni
;
3674 zl3vni
= hash_get(zns
->l3vni_table
, &tmp_zl3vni
, zl3vni_alloc
);
3677 zl3vni
->vrf_id
= vrf_id
;
3678 zl3vni
->svi_if
= NULL
;
3679 zl3vni
->vxlan_if
= NULL
;
3680 zl3vni
->l2vnis
= list_new();
3681 zl3vni
->l2vnis
->cmp
= vni_list_cmp
;
3683 /* Create hash table for remote RMAC */
3684 zl3vni
->rmac_table
= hash_create(mac_hash_keymake
, mac_cmp
,
3685 "Zebra L3-VNI RMAC-Table");
3687 /* Create hash table for neighbors */
3688 zl3vni
->nh_table
= hash_create(neigh_hash_keymake
, neigh_cmp
,
3689 "Zebra L3-VNI next-hop table");
3695 * Delete L3 VNI hash entry.
3697 static int zl3vni_del(zebra_l3vni_t
*zl3vni
)
3699 struct zebra_ns
*zns
;
3700 zebra_l3vni_t
*tmp_zl3vni
;
3702 zns
= zebra_ns_lookup(NS_DEFAULT
);
3705 /* free the list of l2vnis */
3706 list_delete(&zl3vni
->l2vnis
);
3707 zl3vni
->l2vnis
= NULL
;
3709 /* Free the rmac table */
3710 hash_free(zl3vni
->rmac_table
);
3711 zl3vni
->rmac_table
= NULL
;
3713 /* Free the nh table */
3714 hash_free(zl3vni
->nh_table
);
3715 zl3vni
->nh_table
= NULL
;
3717 /* Free the VNI hash entry and allocated memory. */
3718 tmp_zl3vni
= hash_release(zns
->l3vni_table
, zl3vni
);
3720 XFREE(MTYPE_ZL3VNI
, tmp_zl3vni
);
3725 static struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
)
3727 struct zebra_ns
*zns
= NULL
;
3728 struct route_node
*rn
= NULL
;
3729 struct interface
*ifp
= NULL
;
3731 /* loop through all vxlan-interface */
3732 zns
= zebra_ns_lookup(NS_DEFAULT
);
3733 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3735 struct zebra_if
*zif
= NULL
;
3736 struct zebra_l2info_vxlan
*vxl
= NULL
;
3738 ifp
= (struct interface
*)rn
->info
;
3743 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3746 vxl
= &zif
->l2info
.vxl
;
3747 if (vxl
->vni
== zl3vni
->vni
) {
3748 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
3756 static struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
)
3758 struct zebra_if
*zif
= NULL
; /* zebra_if for vxlan_if */
3759 struct zebra_l2info_vxlan
*vxl
= NULL
; /* l2 info for vxlan_if */
3764 if (!zl3vni
->vxlan_if
)
3767 zif
= zl3vni
->vxlan_if
->info
;
3771 vxl
= &zif
->l2info
.vxl
;
3773 return zvni_map_to_svi(vxl
->access_vlan
, zif
->brslave_info
.br_if
);
3776 static zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
)
3778 struct zebra_vrf
*zvrf
= NULL
;
3780 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
3784 return zl3vni_lookup(zvrf
->l3vni
);
3788 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3789 * neighbor notifications, to see if they are of interest.
3791 static zebra_l3vni_t
*zl3vni_from_svi(struct interface
*ifp
,
3792 struct interface
*br_if
)
3796 uint8_t bridge_vlan_aware
= 0;
3797 zebra_l3vni_t
*zl3vni
= NULL
;
3798 struct zebra_ns
*zns
= NULL
;
3799 struct route_node
*rn
= NULL
;
3800 struct zebra_if
*zif
= NULL
;
3801 struct interface
*tmp_if
= NULL
;
3802 struct zebra_l2info_bridge
*br
= NULL
;
3803 struct zebra_l2info_vxlan
*vxl
= NULL
;
3808 /* Make sure the linked interface is a bridge. */
3809 if (!IS_ZEBRA_IF_BRIDGE(br_if
))
3812 /* Determine if bridge is VLAN-aware or not */
3815 br
= &zif
->l2info
.br
;
3816 bridge_vlan_aware
= br
->vlan_aware
;
3817 if (bridge_vlan_aware
) {
3818 struct zebra_l2info_vlan
*vl
;
3820 if (!IS_ZEBRA_IF_VLAN(ifp
))
3825 vl
= &zif
->l2info
.vl
;
3829 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3830 /* TODO: Optimize with a hash. */
3831 zns
= zebra_ns_lookup(NS_DEFAULT
);
3832 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
3833 tmp_if
= (struct interface
*)rn
->info
;
3837 if (!zif
|| zif
->zif_type
!= ZEBRA_IF_VXLAN
)
3839 if (!if_is_operative(tmp_if
))
3841 vxl
= &zif
->l2info
.vxl
;
3843 if (zif
->brslave_info
.br_if
!= br_if
)
3846 if (!bridge_vlan_aware
|| vxl
->access_vlan
== vid
) {
3855 zl3vni
= zl3vni_lookup(vxl
->vni
);
3860 * Inform BGP about l3-vni.
3862 static int zl3vni_send_add_to_client(zebra_l3vni_t
*zl3vni
)
3864 struct stream
*s
= NULL
;
3865 struct zserv
*client
= NULL
;
3866 struct ethaddr rmac
;
3867 char buf
[ETHER_ADDR_STRLEN
];
3869 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3870 /* BGP may not be running. */
3875 memset(&rmac
, 0, sizeof(struct ethaddr
));
3876 zl3vni_get_rmac(zl3vni
, &rmac
);
3878 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3880 zclient_create_header(s
, ZEBRA_L3VNI_ADD
, zl3vni_vrf_id(zl3vni
));
3881 stream_putl(s
, zl3vni
->vni
);
3882 stream_put(s
, &rmac
, sizeof(struct ethaddr
));
3883 stream_put_in_addr(s
, &zl3vni
->local_vtep_ip
);
3884 stream_put(s
, &zl3vni
->filter
, sizeof(int));
3886 /* Write packet size. */
3887 stream_putw_at(s
, 0, stream_get_endp(s
));
3889 if (IS_ZEBRA_DEBUG_VXLAN
)
3891 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
3892 zl3vni
->vni
, vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3893 prefix_mac2str(&rmac
, buf
, sizeof(buf
)),
3894 inet_ntoa(zl3vni
->local_vtep_ip
),
3895 CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)
3896 ? "prefix-routes-only"
3898 zebra_route_string(client
->proto
));
3900 client
->l3vniadd_cnt
++;
3901 return zserv_send_message(client
, s
);
3905 * Inform BGP about local l3-VNI deletion.
3907 static int zl3vni_send_del_to_client(zebra_l3vni_t
*zl3vni
)
3909 struct stream
*s
= NULL
;
3910 struct zserv
*client
= NULL
;
3912 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
3913 /* BGP may not be running. */
3917 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
3919 zclient_create_header(s
, ZEBRA_L3VNI_DEL
, zl3vni_vrf_id(zl3vni
));
3920 stream_putl(s
, zl3vni
->vni
);
3922 /* Write packet size. */
3923 stream_putw_at(s
, 0, stream_get_endp(s
));
3925 if (IS_ZEBRA_DEBUG_VXLAN
)
3926 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni
->vni
,
3927 vrf_id_to_name(zl3vni_vrf_id(zl3vni
)),
3928 zebra_route_string(client
->proto
));
3930 client
->l3vnidel_cnt
++;
3931 return zserv_send_message(client
, s
);
3934 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
3939 /* send l3vni add to BGP */
3940 zl3vni_send_add_to_client(zl3vni
);
3943 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t
*zl3vni
)
3948 /* send l3-vni del to BGP*/
3949 zl3vni_send_del_to_client(zl3vni
);
3952 static void zvni_add_to_l3vni_list(struct hash_backet
*backet
, void *ctxt
)
3954 zebra_vni_t
*zvni
= (zebra_vni_t
*)backet
->data
;
3955 zebra_l3vni_t
*zl3vni
= (zebra_l3vni_t
*)ctxt
;
3957 if (zvni
->vrf_id
== zl3vni_vrf_id(zl3vni
))
3958 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
3962 * handle transition of vni from l2 to l3 and vice versa
3964 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf
*zvrf
, vni_t vni
,
3967 zebra_vni_t
*zvni
= NULL
;
3969 /* There is a possibility that VNI notification was already received
3970 * from kernel and we programmed it as L2-VNI
3971 * In such a case we need to delete this L2-VNI first, so
3972 * that it can be reprogrammed as L3-VNI in the system. It is also
3973 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3974 * interface is still present in kernel. In this case to keep it
3975 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3978 /* Locate hash entry */
3979 zvni
= zvni_lookup(vni
);
3983 if (IS_ZEBRA_DEBUG_VXLAN
)
3984 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni
);
3986 /* Delete VNI from BGP. */
3987 zvni_send_del_to_client(zvni
->vni
);
3989 /* Free up all neighbors and MAC, if any. */
3990 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
3991 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
3993 /* Free up all remote VTEPs, if any. */
3994 zvni_vtep_del_all(zvni
, 0);
3996 /* Delete the hash entry. */
3997 if (zvni_del(zvni
)) {
3998 flog_err(EC_ZEBRA_VNI_DEL_FAILED
,
3999 "Failed to del VNI hash %p, VNI %u", zvni
,
4004 /* TODO_MITESH: This needs to be thought through. We don't have
4005 * enough information at this point to reprogram the vni as
4006 * l2-vni. One way is to store the required info in l3-vni and
4007 * used it solely for this purpose
4014 /* delete and uninstall rmac hash entry */
4015 static void zl3vni_del_rmac_hash_entry(struct hash_backet
*backet
, void *ctx
)
4017 zebra_mac_t
*zrmac
= NULL
;
4018 zebra_l3vni_t
*zl3vni
= NULL
;
4020 zrmac
= (zebra_mac_t
*)backet
->data
;
4021 zl3vni
= (zebra_l3vni_t
*)ctx
;
4022 zl3vni_rmac_uninstall(zl3vni
, zrmac
);
4023 zl3vni_rmac_del(zl3vni
, zrmac
);
4026 /* delete and uninstall nh hash entry */
4027 static void zl3vni_del_nh_hash_entry(struct hash_backet
*backet
, void *ctx
)
4029 zebra_neigh_t
*n
= NULL
;
4030 zebra_l3vni_t
*zl3vni
= NULL
;
4032 n
= (zebra_neigh_t
*)backet
->data
;
4033 zl3vni
= (zebra_l3vni_t
*)ctx
;
4034 zl3vni_nh_uninstall(zl3vni
, n
);
4035 zl3vni_nh_del(zl3vni
, n
);
4038 static int ip_prefix_send_to_client(vrf_id_t vrf_id
, struct prefix
*p
,
4041 struct zserv
*client
= NULL
;
4042 struct stream
*s
= NULL
;
4043 char buf
[PREFIX_STRLEN
];
4045 client
= zserv_find_client(ZEBRA_ROUTE_BGP
, 0);
4046 /* BGP may not be running. */
4050 s
= stream_new(ZEBRA_MAX_PACKET_SIZ
);
4052 zclient_create_header(s
, cmd
, vrf_id
);
4053 stream_put(s
, p
, sizeof(struct prefix
));
4055 /* Write packet size. */
4056 stream_putw_at(s
, 0, stream_get_endp(s
));
4058 if (IS_ZEBRA_DEBUG_VXLAN
)
4059 zlog_debug("Send ip prefix %s %s on vrf %s",
4060 prefix2str(p
, buf
, sizeof(buf
)),
4061 (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
) ? "ADD" : "DEL",
4062 vrf_id_to_name(vrf_id
));
4064 if (cmd
== ZEBRA_IP_PREFIX_ROUTE_ADD
)
4065 client
->prefixadd_cnt
++;
4067 client
->prefixdel_cnt
++;
4069 return zserv_send_message(client
, s
);
4072 /* re-add remote rmac if needed */
4073 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t
*zl3vni
,
4074 struct ethaddr
*rmac
)
4076 char buf
[ETHER_ADDR_STRLEN
];
4077 zebra_mac_t
*zrmac
= NULL
;
4079 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4083 if (IS_ZEBRA_DEBUG_VXLAN
)
4084 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
4085 prefix_mac2str(rmac
, buf
, sizeof(buf
)), zl3vni
->vni
);
4087 zl3vni_rmac_install(zl3vni
, zrmac
);
4091 /* Process a remote MACIP add from BGP. */
4092 static void process_remote_macip_add(vni_t vni
,
4093 struct ethaddr
*macaddr
,
4095 struct ipaddr
*ipaddr
,
4098 struct in_addr vtep_ip
)
4101 zebra_vtep_t
*zvtep
;
4102 zebra_mac_t
*mac
, *old_mac
;
4103 zebra_neigh_t
*n
= NULL
;
4104 int update_mac
= 0, update_neigh
= 0;
4105 char buf
[ETHER_ADDR_STRLEN
];
4106 char buf1
[INET6_ADDRSTRLEN
];
4107 struct interface
*ifp
= NULL
;
4108 struct zebra_if
*zif
= NULL
;
4114 /* Locate VNI hash entry - expected to exist. */
4115 zvni
= zvni_lookup(vni
);
4117 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni
);
4121 ifp
= zvni
->vxlan_if
;
4125 !if_is_operative(ifp
) ||
4127 !zif
->brslave_info
.br_if
) {
4128 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
4133 /* The remote VTEP specified should normally exist, but it is
4134 * possible that when peering comes up, peer may advertise MACIP
4135 * routes before advertising type-3 routes.
4137 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
4139 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
4141 EC_ZEBRA_VTEP_ADD_FAILED
,
4142 "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
4147 zvni_vtep_install(zvni
, &vtep_ip
);
4150 sticky
= !!CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
4151 remote_gw
= !!CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
4152 is_router
= !!CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
4154 mac
= zvni_mac_lookup(zvni
, macaddr
);
4156 /* Ignore if the mac is already present as a gateway mac */
4158 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
) &&
4159 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
4160 if (IS_ZEBRA_DEBUG_VXLAN
)
4161 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4163 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4164 ipa_len
? " IP " : "",
4166 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4170 /* check if the remote MAC is unknown or has a change.
4171 * If so, that needs to be updated first. Note that client could
4172 * install MAC and MACIP separately or just install the latter.
4175 || !CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)
4176 || sticky
!= !!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)
4177 || remote_gw
!= !!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
)
4178 || !IPV4_ADDR_SAME(&mac
->fwd_info
.r_vtep_ip
, &vtep_ip
)
4179 || seq
!= mac
->rem_seq
)
4184 mac
= zvni_mac_add(zvni
, macaddr
);
4187 "Failed to add MAC %s VNI %u Remote VTEP %s",
4188 prefix_mac2str(macaddr
, buf
,
4190 vni
, inet_ntoa(vtep_ip
));
4194 /* Is this MAC created for a MACIP? */
4196 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4198 const char *mac_type
;
4200 /* When host moves but changes its (MAC,IP)
4201 * binding, BGP may install a MACIP entry that
4202 * corresponds to "older" location of the host
4203 * in transient situations (because {IP1,M1}
4204 * is a different route from {IP1,M2}). Check
4205 * the sequence number and ignore this update
4208 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
4209 tmp_seq
= mac
->loc_seq
;
4212 tmp_seq
= mac
->rem_seq
;
4213 mac_type
= "remote";
4215 if (seq
< tmp_seq
) {
4216 if (IS_ZEBRA_DEBUG_VXLAN
)
4217 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
4219 prefix_mac2str(macaddr
,
4221 ipa_len
? " IP " : "",
4224 buf1
, sizeof(buf1
)) : "",
4231 /* Set "auto" and "remote" forwarding info. */
4232 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
4233 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
4234 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4235 mac
->fwd_info
.r_vtep_ip
= vtep_ip
;
4238 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4240 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
4243 SET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4245 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE_DEF_GW
);
4247 zvni_process_neigh_on_remote_mac_add(zvni
, mac
);
4249 /* Install the entry. */
4250 zvni_mac_install(zvni
, mac
);
4253 /* Update seq number. */
4256 /* If there is no IP, return after clearing AUTO flag of MAC. */
4258 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4262 /* Check if the remote neighbor itself is unknown or has a
4263 * change. If so, create or update and then install the entry.
4265 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4267 || !CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4268 || is_router
!= !!CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
)
4269 || (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0)
4270 || !IPV4_ADDR_SAME(&n
->r_vtep_ip
, &vtep_ip
)
4271 || seq
!= n
->rem_seq
)
4276 n
= zvni_neigh_add(zvni
, ipaddr
, macaddr
);
4279 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
4280 ipaddr2str(ipaddr
, buf1
,
4282 prefix_mac2str(macaddr
, buf
,
4284 vni
, inet_ntoa(vtep_ip
));
4291 /* When host moves but changes its (MAC,IP)
4292 * binding, BGP may install a MACIP entry that
4293 * corresponds to "older" location of the host
4294 * in transient situations (because {IP1,M1}
4295 * is a different route from {IP1,M2}). Check
4296 * the sequence number and ignore this update
4299 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
)) {
4300 tmp_seq
= n
->loc_seq
;
4303 tmp_seq
= n
->rem_seq
;
4306 if (seq
< tmp_seq
) {
4307 if (IS_ZEBRA_DEBUG_VXLAN
)
4308 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
4310 prefix_mac2str(macaddr
,
4313 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)),
4318 if (memcmp(&n
->emac
, macaddr
, sizeof(*macaddr
)) != 0) {
4319 /* MAC change, send a delete for old
4320 * neigh if learnt locally.
4322 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
) &&
4323 IS_ZEBRA_NEIGH_ACTIVE(n
))
4324 zvni_neigh_send_del_to_client(
4328 /* update neigh list for macs */
4329 old_mac
= zvni_mac_lookup(zvni
, &n
->emac
);
4331 listnode_delete(old_mac
->neigh_list
, n
);
4332 zvni_deref_ip2mac(zvni
, old_mac
);
4334 listnode_add_sort(mac
->neigh_list
, n
);
4335 memcpy(&n
->emac
, macaddr
, ETH_ALEN
);
4339 /* Set "remote" forwarding info. */
4340 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_LOCAL
);
4341 n
->r_vtep_ip
= vtep_ip
;
4342 SET_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
);
4344 /* Set router flag (R-bit) to this Neighbor entry */
4345 if (CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
))
4346 SET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4348 UNSET_FLAG(n
->flags
, ZEBRA_NEIGH_ROUTER_FLAG
);
4350 /* Install the entry. */
4351 zvni_neigh_install(zvni
, n
);
4354 /* Update seq number. */
4358 /* Process a remote MACIP delete from BGP. */
4359 static void process_remote_macip_del(vni_t vni
,
4360 struct ethaddr
*macaddr
,
4362 struct ipaddr
*ipaddr
,
4363 struct in_addr vtep_ip
)
4366 zebra_mac_t
*mac
= NULL
;
4367 zebra_neigh_t
*n
= NULL
;
4368 struct interface
*ifp
= NULL
;
4369 struct zebra_if
*zif
= NULL
;
4370 char buf
[ETHER_ADDR_STRLEN
];
4371 char buf1
[INET6_ADDRSTRLEN
];
4373 /* Locate VNI hash entry - expected to exist. */
4374 zvni
= zvni_lookup(vni
);
4376 if (IS_ZEBRA_DEBUG_VXLAN
)
4377 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni
);
4381 ifp
= zvni
->vxlan_if
;
4385 !if_is_operative(ifp
) ||
4387 !zif
->brslave_info
.br_if
) {
4388 if (IS_ZEBRA_DEBUG_VXLAN
)
4389 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
4394 /* The remote VTEP specified is normally expected to exist, but
4395 * it is possible that the peer may delete the VTEP before deleting
4396 * any MACs referring to the VTEP, in which case the handler (see
4397 * remote_vtep_del) would have already deleted the MACs.
4399 if (!zvni_vtep_find(zvni
, &vtep_ip
))
4402 mac
= zvni_mac_lookup(zvni
, macaddr
);
4404 n
= zvni_neigh_lookup(zvni
, ipaddr
);
4407 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
4408 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4409 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)), vni
);
4413 /* If the remote mac or neighbor doesn't exist there is nothing
4414 * more to do. Otherwise, uninstall the entry and then remove it.
4419 /* Ignore the delete if this mac is a gateway mac-ip */
4421 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)
4422 && CHECK_FLAG(mac
->flags
, ZEBRA_MAC_DEF_GW
)) {
4424 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4426 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
4427 ipa_len
? " IP " : "",
4429 ipaddr2str(ipaddr
, buf1
, sizeof(buf1
)) : "");
4433 /* Uninstall remote neighbor or MAC. */
4435 /* When the MAC changes for an IP, it is possible the
4436 * client may update the new MAC before trying to delete the
4437 * "old" neighbor (as these are two different MACIP routes).
4438 * Do the delete only if the MAC matches.
4440 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)
4441 && (memcmp(n
->emac
.octet
, macaddr
->octet
, ETH_ALEN
) == 0)) {
4442 zvni_neigh_uninstall(zvni
, n
);
4443 zvni_neigh_del(zvni
, n
);
4444 zvni_deref_ip2mac(zvni
, mac
);
4447 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
)) {
4448 zvni_process_neigh_on_remote_mac_del(zvni
, mac
);
4450 /* If all remote neighbors referencing a remote MAC
4451 * go away, we need to uninstall the MAC.
4453 if (remote_neigh_count(mac
) == 0) {
4454 zvni_mac_uninstall(zvni
, mac
);
4455 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
4457 if (list_isempty(mac
->neigh_list
))
4458 zvni_mac_del(zvni
, mac
);
4460 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
4466 /* Public functions */
4468 int is_l3vni_for_prefix_routes_only(vni_t vni
)
4470 zebra_l3vni_t
*zl3vni
= NULL
;
4472 zl3vni
= zl3vni_lookup(vni
);
4476 return CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
) ? 1 : 0;
4479 /* handle evpn route in vrf table */
4480 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id
, struct ethaddr
*rmac
,
4481 struct ipaddr
*vtep_ip
,
4482 struct prefix
*host_prefix
)
4484 zebra_l3vni_t
*zl3vni
= NULL
;
4485 struct ipaddr ipv4_vtep
;
4487 zl3vni
= zl3vni_from_vrf(vrf_id
);
4488 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
4492 * add the next hop neighbor -
4493 * neigh to be installed is the ipv6 nexthop neigh
4495 zl3vni_remote_nh_add(zl3vni
, vtep_ip
, rmac
, host_prefix
);
4498 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
4499 * address. Rmac is programmed against the ipv4 vtep because we only
4500 * support ipv4 tunnels in the h/w right now
4502 memset(&ipv4_vtep
, 0, sizeof(struct ipaddr
));
4503 ipv4_vtep
.ipa_type
= IPADDR_V4
;
4504 if (vtep_ip
->ipa_type
== IPADDR_V6
)
4505 ipv4_mapped_ipv6_to_ipv4(&vtep_ip
->ipaddr_v6
,
4506 &(ipv4_vtep
.ipaddr_v4
));
4508 memcpy(&(ipv4_vtep
.ipaddr_v4
), &vtep_ip
->ipaddr_v4
,
4509 sizeof(struct in_addr
));
4512 * add the rmac - remote rmac to be installed is against the ipv4
4515 zl3vni_remote_rmac_add(zl3vni
, rmac
, &ipv4_vtep
, host_prefix
);
4518 /* handle evpn vrf route delete */
4519 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id
,
4520 struct ipaddr
*vtep_ip
,
4521 struct prefix
*host_prefix
)
4523 zebra_l3vni_t
*zl3vni
= NULL
;
4524 zebra_neigh_t
*nh
= NULL
;
4525 zebra_mac_t
*zrmac
= NULL
;
4527 zl3vni
= zl3vni_from_vrf(vrf_id
);
4531 /* find the next hop entry and rmac entry */
4532 nh
= zl3vni_nh_lookup(zl3vni
, vtep_ip
);
4535 zrmac
= zl3vni_rmac_lookup(zl3vni
, &nh
->emac
);
4537 /* delete the next hop entry */
4538 zl3vni_remote_nh_del(zl3vni
, nh
, host_prefix
);
4540 /* delete the rmac entry */
4542 zl3vni_remote_rmac_del(zl3vni
, zrmac
, host_prefix
);
4546 void zebra_vxlan_print_specific_rmac_l3vni(struct vty
*vty
, vni_t l3vni
,
4547 struct ethaddr
*rmac
, bool use_json
)
4549 zebra_l3vni_t
*zl3vni
= NULL
;
4550 zebra_mac_t
*zrmac
= NULL
;
4551 json_object
*json
= NULL
;
4553 if (!is_evpn_enabled()) {
4555 vty_out(vty
, "{}\n");
4560 json
= json_object_new_object();
4562 zl3vni
= zl3vni_lookup(l3vni
);
4565 vty_out(vty
, "{}\n");
4567 vty_out(vty
, "%% L3-VNI %u doesnt exist\n", l3vni
);
4571 zrmac
= zl3vni_rmac_lookup(zl3vni
, rmac
);
4574 vty_out(vty
, "{}\n");
4577 "%% Requested RMAC doesnt exist in L3-VNI %u",
4582 zl3vni_print_rmac(zrmac
, vty
, json
);
4585 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4586 json
, JSON_C_TO_STRING_PRETTY
));
4587 json_object_free(json
);
4591 void zebra_vxlan_print_rmacs_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4593 zebra_l3vni_t
*zl3vni
;
4595 struct rmac_walk_ctx wctx
;
4596 json_object
*json
= NULL
;
4598 if (!is_evpn_enabled())
4601 zl3vni
= zl3vni_lookup(l3vni
);
4604 vty_out(vty
, "{}\n");
4606 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4609 num_rmacs
= hashcount(zl3vni
->rmac_table
);
4614 json
= json_object_new_object();
4616 memset(&wctx
, 0, sizeof(struct rmac_walk_ctx
));
4620 vty_out(vty
, "Number of Remote RMACs known for this VNI: %u\n",
4622 vty_out(vty
, "%-17s %-21s\n", "MAC", "Remote VTEP");
4624 json_object_int_add(json
, "numRmacs", num_rmacs
);
4626 hash_iterate(zl3vni
->rmac_table
, zl3vni_print_rmac_hash
, &wctx
);
4629 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4630 json
, JSON_C_TO_STRING_PRETTY
));
4631 json_object_free(json
);
4635 void zebra_vxlan_print_rmacs_all_l3vni(struct vty
*vty
, bool use_json
)
4637 struct zebra_ns
*zns
= NULL
;
4638 json_object
*json
= NULL
;
4641 if (!is_evpn_enabled()) {
4643 vty_out(vty
, "{}\n");
4647 zns
= zebra_ns_lookup(NS_DEFAULT
);
4650 vty_out(vty
, "{}\n");
4655 json
= json_object_new_object();
4659 hash_iterate(zns
->l3vni_table
,
4660 (void (*)(struct hash_backet
*,
4661 void *))zl3vni_print_rmac_hash_all_vni
,
4665 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4666 json
, JSON_C_TO_STRING_PRETTY
));
4667 json_object_free(json
);
4671 void zebra_vxlan_print_specific_nh_l3vni(struct vty
*vty
, vni_t l3vni
,
4672 struct ipaddr
*ip
, bool use_json
)
4674 zebra_l3vni_t
*zl3vni
= NULL
;
4675 zebra_neigh_t
*n
= NULL
;
4676 json_object
*json
= NULL
;
4678 if (!is_evpn_enabled()) {
4680 vty_out(vty
, "{}\n");
4685 json
= json_object_new_object();
4687 zl3vni
= zl3vni_lookup(l3vni
);
4690 vty_out(vty
, "{}\n");
4692 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4696 n
= zl3vni_nh_lookup(zl3vni
, ip
);
4699 vty_out(vty
, "{}\n");
4702 "%% Requested next-hop not present for L3-VNI %u",
4707 zl3vni_print_nh(n
, vty
, json
);
4710 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4711 json
, JSON_C_TO_STRING_PRETTY
));
4712 json_object_free(json
);
4716 void zebra_vxlan_print_nh_l3vni(struct vty
*vty
, vni_t l3vni
, bool use_json
)
4719 struct nh_walk_ctx wctx
;
4720 json_object
*json
= NULL
;
4721 zebra_l3vni_t
*zl3vni
= NULL
;
4723 if (!is_evpn_enabled())
4726 zl3vni
= zl3vni_lookup(l3vni
);
4729 vty_out(vty
, "{}\n");
4731 vty_out(vty
, "%% L3-VNI %u does not exist\n", l3vni
);
4735 num_nh
= hashcount(zl3vni
->nh_table
);
4740 json
= json_object_new_object();
4745 vty_out(vty
, "Number of NH Neighbors known for this VNI: %u\n",
4747 vty_out(vty
, "%-15s %-17s\n", "IP", "RMAC");
4749 json_object_int_add(json
, "numNextHops", num_nh
);
4751 hash_iterate(zl3vni
->nh_table
, zl3vni_print_nh_hash
, &wctx
);
4754 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4755 json
, JSON_C_TO_STRING_PRETTY
));
4756 json_object_free(json
);
4760 void zebra_vxlan_print_nh_all_l3vni(struct vty
*vty
, bool use_json
)
4762 struct zebra_ns
*zns
= NULL
;
4763 json_object
*json
= NULL
;
4766 if (!is_evpn_enabled()) {
4768 vty_out(vty
, "{}\n");
4772 zns
= zebra_ns_lookup(NS_DEFAULT
);
4777 json
= json_object_new_object();
4781 hash_iterate(zns
->l3vni_table
,
4782 (void (*)(struct hash_backet
*,
4783 void *))zl3vni_print_nh_hash_all_vni
,
4787 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4788 json
, JSON_C_TO_STRING_PRETTY
));
4789 json_object_free(json
);
4794 * Display L3 VNI information (VTY command handler).
4796 void zebra_vxlan_print_l3vni(struct vty
*vty
, vni_t vni
, bool use_json
)
4799 json_object
*json
= NULL
;
4800 zebra_l3vni_t
*zl3vni
= NULL
;
4802 if (!is_evpn_enabled()) {
4804 vty_out(vty
, "{}\n");
4808 zl3vni
= zl3vni_lookup(vni
);
4811 vty_out(vty
, "{}\n");
4813 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4818 json
= json_object_new_object();
4822 zl3vni_print(zl3vni
, (void *)args
);
4825 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4826 json
, JSON_C_TO_STRING_PRETTY
));
4827 json_object_free(json
);
4831 void zebra_vxlan_print_vrf_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4832 json_object
*json_vrfs
)
4834 char buf
[ETHER_ADDR_STRLEN
];
4835 zebra_l3vni_t
*zl3vni
= NULL
;
4837 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
4842 vty_out(vty
, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
4843 zvrf_name(zvrf
), zl3vni
->vni
,
4844 zl3vni_vxlan_if_name(zl3vni
),
4845 zl3vni_svi_if_name(zl3vni
), zl3vni_state2str(zl3vni
),
4846 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4848 json_object
*json_vrf
= NULL
;
4850 json_vrf
= json_object_new_object();
4851 json_object_string_add(json_vrf
, "vrf", zvrf_name(zvrf
));
4852 json_object_int_add(json_vrf
, "vni", zl3vni
->vni
);
4853 json_object_string_add(json_vrf
, "vxlanIntf",
4854 zl3vni_vxlan_if_name(zl3vni
));
4855 json_object_string_add(json_vrf
, "sviIntf",
4856 zl3vni_svi_if_name(zl3vni
));
4857 json_object_string_add(json_vrf
, "state",
4858 zl3vni_state2str(zl3vni
));
4859 json_object_string_add(
4860 json_vrf
, "routerMac",
4861 zl3vni_rmac2str(zl3vni
, buf
, sizeof(buf
)));
4862 json_object_array_add(json_vrfs
, json_vrf
);
4867 * Display Neighbors for a VNI (VTY command handler).
4869 void zebra_vxlan_print_neigh_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4870 vni_t vni
, bool use_json
)
4874 struct neigh_walk_ctx wctx
;
4875 json_object
*json
= NULL
;
4877 if (!is_evpn_enabled())
4879 zvni
= zvni_lookup(vni
);
4882 vty_out(vty
, "{}\n");
4884 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4887 num_neigh
= hashcount(zvni
->neigh_table
);
4892 json
= json_object_new_object();
4894 /* Since we have IPv6 addresses to deal with which can vary widely in
4895 * size, we try to be a bit more elegant in display by first computing
4896 * the maximum width.
4898 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
4901 wctx
.addr_width
= 15;
4903 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
4907 "Number of ARPs (local and remote) known for this VNI: %u\n",
4909 vty_out(vty
, "%*s %-6s %-8s %-17s %-21s\n",
4910 -wctx
.addr_width
, "IP", "Type",
4911 "State", "MAC", "Remote VTEP");
4913 json_object_int_add(json
, "numArpNd", num_neigh
);
4915 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
4917 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4918 json
, JSON_C_TO_STRING_PRETTY
));
4919 json_object_free(json
);
4924 * Display neighbors across all VNIs (VTY command handler).
4926 void zebra_vxlan_print_neigh_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4929 json_object
*json
= NULL
;
4932 if (!is_evpn_enabled())
4936 json
= json_object_new_object();
4940 hash_iterate(zvrf
->vni_table
,
4941 (void (*)(struct hash_backet
*,
4942 void *))zvni_print_neigh_hash_all_vni
,
4945 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4946 json
, JSON_C_TO_STRING_PRETTY
));
4947 json_object_free(json
);
4952 * Display specific neighbor for a VNI, if present (VTY command handler).
4954 void zebra_vxlan_print_specific_neigh_vni(struct vty
*vty
,
4955 struct zebra_vrf
*zvrf
, vni_t vni
,
4956 struct ipaddr
*ip
, bool use_json
)
4960 json_object
*json
= NULL
;
4962 if (!is_evpn_enabled())
4964 zvni
= zvni_lookup(vni
);
4967 vty_out(vty
, "{}\n");
4969 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
4972 n
= zvni_neigh_lookup(zvni
, ip
);
4976 "%% Requested neighbor does not exist in VNI %u\n",
4981 json
= json_object_new_object();
4983 zvni_print_neigh(n
, vty
, json
);
4986 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4987 json
, JSON_C_TO_STRING_PRETTY
));
4988 json_object_free(json
);
4993 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4994 * By definition, these are remote neighbors.
4996 void zebra_vxlan_print_neigh_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
4997 vni_t vni
, struct in_addr vtep_ip
,
5002 struct neigh_walk_ctx wctx
;
5003 json_object
*json
= NULL
;
5005 if (!is_evpn_enabled())
5007 zvni
= zvni_lookup(vni
);
5010 vty_out(vty
, "{}\n");
5012 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5015 num_neigh
= hashcount(zvni
->neigh_table
);
5019 memset(&wctx
, 0, sizeof(struct neigh_walk_ctx
));
5022 wctx
.addr_width
= 15;
5023 wctx
.flags
= SHOW_REMOTE_NEIGH_FROM_VTEP
;
5024 wctx
.r_vtep_ip
= vtep_ip
;
5026 hash_iterate(zvni
->neigh_table
, zvni_find_neigh_addr_width
, &wctx
);
5027 hash_iterate(zvni
->neigh_table
, zvni_print_neigh_hash
, &wctx
);
5030 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5031 json
, JSON_C_TO_STRING_PRETTY
));
5032 json_object_free(json
);
5037 * Display MACs for a VNI (VTY command handler).
5039 void zebra_vxlan_print_macs_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5040 vni_t vni
, bool use_json
)
5044 struct mac_walk_ctx wctx
;
5045 json_object
*json
= NULL
;
5046 json_object
*json_mac
= NULL
;
5048 if (!is_evpn_enabled())
5050 zvni
= zvni_lookup(vni
);
5053 vty_out(vty
, "{}\n");
5055 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5058 num_macs
= num_valid_macs(zvni
);
5063 json
= json_object_new_object();
5064 json_mac
= json_object_new_object();
5067 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5070 wctx
.json
= json_mac
;
5074 "Number of MACs (local and remote) known for this VNI: %u\n",
5076 vty_out(vty
, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
5077 "Intf/Remote VTEP", "VLAN");
5079 json_object_int_add(json
, "numMacs", num_macs
);
5081 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5084 json_object_object_add(json
, "macs", json_mac
);
5085 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5086 json
, JSON_C_TO_STRING_PRETTY
));
5087 json_object_free(json
);
5092 * Display MACs for all VNIs (VTY command handler).
5094 void zebra_vxlan_print_macs_all_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5097 struct mac_walk_ctx wctx
;
5098 json_object
*json
= NULL
;
5100 if (!is_evpn_enabled()) {
5102 vty_out(vty
, "{}\n");
5106 json
= json_object_new_object();
5108 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5111 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5114 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5115 json
, JSON_C_TO_STRING_PRETTY
));
5116 json_object_free(json
);
5121 * Display MACs for all VNIs (VTY command handler).
5123 void zebra_vxlan_print_macs_all_vni_vtep(struct vty
*vty
,
5124 struct zebra_vrf
*zvrf
,
5125 struct in_addr vtep_ip
, bool use_json
)
5127 struct mac_walk_ctx wctx
;
5128 json_object
*json
= NULL
;
5130 if (!is_evpn_enabled())
5134 json
= json_object_new_object();
5136 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5138 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5139 wctx
.r_vtep_ip
= vtep_ip
;
5141 hash_iterate(zvrf
->vni_table
, zvni_print_mac_hash_all_vni
, &wctx
);
5144 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5145 json
, JSON_C_TO_STRING_PRETTY
));
5146 json_object_free(json
);
5151 * Display specific MAC for a VNI, if present (VTY command handler).
5153 void zebra_vxlan_print_specific_mac_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5154 vni_t vni
, struct ethaddr
*macaddr
)
5159 if (!is_evpn_enabled())
5161 zvni
= zvni_lookup(vni
);
5163 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5166 mac
= zvni_mac_lookup(zvni
, macaddr
);
5168 vty_out(vty
, "%% Requested MAC does not exist in VNI %u\n",
5173 zvni_print_mac(mac
, vty
);
5177 * Display MACs for a VNI from specific VTEP (VTY command handler).
5179 void zebra_vxlan_print_macs_vni_vtep(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5180 vni_t vni
, struct in_addr vtep_ip
,
5185 struct mac_walk_ctx wctx
;
5186 json_object
*json
= NULL
;
5187 json_object
*json_mac
= NULL
;
5189 if (!is_evpn_enabled())
5191 zvni
= zvni_lookup(vni
);
5194 vty_out(vty
, "{}\n");
5196 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5199 num_macs
= num_valid_macs(zvni
);
5204 json
= json_object_new_object();
5205 json_mac
= json_object_new_object();
5208 memset(&wctx
, 0, sizeof(struct mac_walk_ctx
));
5211 wctx
.flags
= SHOW_REMOTE_MAC_FROM_VTEP
;
5212 wctx
.r_vtep_ip
= vtep_ip
;
5213 wctx
.json
= json_mac
;
5214 hash_iterate(zvni
->mac_table
, zvni_print_mac_hash
, &wctx
);
5217 json_object_int_add(json
, "numMacs", wctx
.count
);
5219 json_object_object_add(json
, "macs", json_mac
);
5220 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5221 json
, JSON_C_TO_STRING_PRETTY
));
5222 json_object_free(json
);
5228 * Display VNI information (VTY command handler).
5230 void zebra_vxlan_print_vni(struct vty
*vty
, struct zebra_vrf
*zvrf
, vni_t vni
,
5233 json_object
*json
= NULL
;
5235 zebra_l3vni_t
*zl3vni
= NULL
;
5236 zebra_vni_t
*zvni
= NULL
;
5238 if (!is_evpn_enabled())
5242 json
= json_object_new_object();
5246 zl3vni
= zl3vni_lookup(vni
);
5248 zl3vni_print(zl3vni
, (void *)args
);
5250 zvni
= zvni_lookup(vni
);
5253 vty_out(vty
, "{}\n");
5255 vty_out(vty
, "%% VNI %u does not exist\n", vni
);
5259 zvni_print(zvni
, (void *)args
);
5263 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5264 json
, JSON_C_TO_STRING_PRETTY
));
5265 json_object_free(json
);
5269 /* Display all global details for EVPN */
5270 void zebra_vxlan_print_evpn(struct vty
*vty
, bool uj
)
5275 json_object
*json
= NULL
;
5276 struct zebra_ns
*zns
= NULL
;
5277 struct zebra_vrf
*zvrf
= NULL
;
5279 if (!is_evpn_enabled())
5282 zns
= zebra_ns_lookup(NS_DEFAULT
);
5286 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
5290 num_l3vnis
= hashcount(zns
->l3vni_table
);
5291 num_l2vnis
= hashcount(zvrf
->vni_table
);
5292 num_vnis
= num_l2vnis
+ num_l3vnis
;
5295 json
= json_object_new_object();
5296 json_object_string_add(json
, "advertiseGatewayMacip",
5297 zvrf
->advertise_gw_macip
? "Yes" : "No");
5298 json_object_int_add(json
, "numVnis", num_vnis
);
5299 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
5300 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
5302 vty_out(vty
, "L2 VNIs: %u\n", num_l2vnis
);
5303 vty_out(vty
, "L3 VNIs: %u\n", num_l3vnis
);
5304 vty_out(vty
, "Advertise gateway mac-ip: %s\n",
5305 zvrf
->advertise_gw_macip
? "Yes" : "No");
5309 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5310 json
, JSON_C_TO_STRING_PRETTY
));
5311 json_object_free(json
);
5316 * Display VNI hash table (VTY command handler).
5318 void zebra_vxlan_print_vnis(struct vty
*vty
, struct zebra_vrf
*zvrf
,
5321 json_object
*json
= NULL
;
5322 struct zebra_ns
*zns
= NULL
;
5325 if (!is_evpn_enabled())
5328 zns
= zebra_ns_lookup(NS_DEFAULT
);
5334 json
= json_object_new_object();
5336 vty_out(vty
, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
5337 "Type", "VxLAN IF", "# MACs", "# ARPs",
5338 "# Remote VTEPs", "Tenant VRF");
5343 /* Display all L2-VNIs */
5344 hash_iterate(zvrf
->vni_table
,
5345 (void (*)(struct hash_backet
*, void *))zvni_print_hash
,
5348 /* Display all L3-VNIs */
5349 hash_iterate(zns
->l3vni_table
,
5350 (void (*)(struct hash_backet
*, void *))zl3vni_print_hash
,
5354 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5355 json
, JSON_C_TO_STRING_PRETTY
));
5356 json_object_free(json
);
5361 * Handle neighbor delete notification from the kernel (on a VLAN device
5362 * / L3 interface). This may result in either the neighbor getting deleted
5363 * from our database or being re-added to the kernel (if it is a valid
5366 int zebra_vxlan_handle_kernel_neigh_del(struct interface
*ifp
,
5367 struct interface
*link_if
,
5370 char buf
[INET6_ADDRSTRLEN
];
5371 char buf2
[ETHER_ADDR_STRLEN
];
5372 zebra_neigh_t
*n
= NULL
;
5373 zebra_vni_t
*zvni
= NULL
;
5374 zebra_mac_t
*zmac
= NULL
;
5375 zebra_l3vni_t
*zl3vni
= NULL
;
5377 /* check if this is a remote neigh entry corresponding to remote
5380 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5382 return zl3vni_local_nh_del(zl3vni
, ip
);
5384 /* We are only interested in neighbors on an SVI that resides on top
5385 * of a VxLAN bridge.
5387 zvni
= zvni_from_svi(ifp
, link_if
);
5391 if (!zvni
->vxlan_if
) {
5393 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
5398 if (IS_ZEBRA_DEBUG_VXLAN
)
5399 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
5400 ipaddr2str(ip
, buf
, sizeof(buf
)), ifp
->name
,
5401 ifp
->ifindex
, zvni
->vni
);
5403 /* If entry doesn't exist, nothing to do. */
5404 n
= zvni_neigh_lookup(zvni
, ip
);
5408 zmac
= zvni_mac_lookup(zvni
, &n
->emac
);
5410 if (IS_ZEBRA_DEBUG_VXLAN
)
5412 "Trying to del a neigh %s without a mac %s on VNI %u",
5413 ipaddr2str(ip
, buf
, sizeof(buf
)),
5414 prefix_mac2str(&n
->emac
, buf2
, sizeof(buf2
)),
5420 /* If it is a remote entry, the kernel has aged this out or someone has
5421 * deleted it, it needs to be re-installed as Quagga is the owner.
5423 if (CHECK_FLAG(n
->flags
, ZEBRA_NEIGH_REMOTE
)) {
5424 zvni_neigh_install(zvni
, n
);
5428 /* Remove neighbor from BGP. */
5429 if (IS_ZEBRA_NEIGH_ACTIVE(n
))
5430 zvni_neigh_send_del_to_client(zvni
->vni
, &n
->ip
, &n
->emac
, 0);
5432 /* Delete this neighbor entry. */
5433 zvni_neigh_del(zvni
, n
);
5435 /* see if the AUTO mac needs to be deleted */
5436 if (CHECK_FLAG(zmac
->flags
, ZEBRA_MAC_AUTO
)
5437 && !listcount(zmac
->neigh_list
))
5438 zvni_mac_del(zvni
, zmac
);
5444 * Handle neighbor add or update notification from the kernel (on a VLAN
5445 * device / L3 interface). This is typically for a local neighbor but can
5446 * also be for a remote neighbor (e.g., ageout notification). It could
5447 * also be a "move" scenario.
5449 int zebra_vxlan_handle_kernel_neigh_update(struct interface
*ifp
,
5450 struct interface
*link_if
,
5452 struct ethaddr
*macaddr
,
5457 char buf
[ETHER_ADDR_STRLEN
];
5458 char buf2
[INET6_ADDRSTRLEN
];
5459 zebra_vni_t
*zvni
= NULL
;
5460 zebra_l3vni_t
*zl3vni
= NULL
;
5462 /* check if this is a remote neigh entry corresponding to remote
5465 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
5467 return zl3vni_local_nh_add_update(zl3vni
, ip
, state
);
5469 /* We are only interested in neighbors on an SVI that resides on top
5470 * of a VxLAN bridge.
5472 zvni
= zvni_from_svi(ifp
, link_if
);
5476 if (IS_ZEBRA_DEBUG_VXLAN
)
5478 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
5479 ipaddr2str(ip
, buf2
, sizeof(buf2
)),
5480 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5481 ifp
->ifindex
, state
, is_ext
? "ext-learned " : "",
5482 is_router
? "router " : "",
5485 /* Is this about a local neighbor or a remote one? */
5487 return zvni_local_neigh_update(zvni
, ifp
, ip
, macaddr
,
5490 return zvni_remote_neigh_update(zvni
, ifp
, ip
, macaddr
, state
);
5495 * Handle message from client to delete a remote MACIP for a VNI.
5497 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS
)
5501 struct ethaddr macaddr
;
5503 struct in_addr vtep_ip
;
5504 uint16_t l
= 0, ipa_len
;
5505 char buf
[ETHER_ADDR_STRLEN
];
5506 char buf1
[INET6_ADDRSTRLEN
];
5508 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5509 memset(&ip
, 0, sizeof(struct ipaddr
));
5510 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5514 while (l
< hdr
->length
) {
5515 /* Obtain each remote MACIP and process. */
5516 /* Message contains VNI, followed by MAC followed by IP (if any)
5517 * followed by remote VTEP IP.
5519 memset(&ip
, 0, sizeof(ip
));
5520 STREAM_GETL(s
, vni
);
5521 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5522 STREAM_GETL(s
, ipa_len
);
5524 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5526 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5528 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5529 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5530 l
+= IPV4_MAX_BYTELEN
;
5532 if (IS_ZEBRA_DEBUG_VXLAN
)
5534 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
5536 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5537 ipa_len
? " IP " : "",
5539 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5541 zebra_route_string(client
->proto
));
5543 process_remote_macip_del(vni
, &macaddr
, ipa_len
, &ip
, vtep_ip
);
5551 * Handle message from client to add a remote MACIP for a VNI. This
5552 * could be just the add of a MAC address or the add of a neighbor
5555 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS
)
5559 struct ethaddr macaddr
;
5561 struct in_addr vtep_ip
;
5562 uint16_t l
= 0, ipa_len
;
5565 char buf
[ETHER_ADDR_STRLEN
];
5566 char buf1
[INET6_ADDRSTRLEN
];
5568 memset(&macaddr
, 0, sizeof(struct ethaddr
));
5569 memset(&ip
, 0, sizeof(struct ipaddr
));
5570 memset(&vtep_ip
, 0, sizeof(struct in_addr
));
5572 if (!EVPN_ENABLED(zvrf
)) {
5573 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
5579 while (l
< hdr
->length
) {
5580 /* Obtain each remote MACIP and process. */
5581 /* Message contains VNI, followed by MAC followed by IP (if any)
5582 * followed by remote VTEP IP.
5584 memset(&ip
, 0, sizeof(ip
));
5585 STREAM_GETL(s
, vni
);
5586 STREAM_GET(&macaddr
.octet
, s
, ETH_ALEN
);
5587 STREAM_GETL(s
, ipa_len
);
5589 ip
.ipa_type
= (ipa_len
== IPV4_MAX_BYTELEN
) ? IPADDR_V4
5591 STREAM_GET(&ip
.ip
.addr
, s
, ipa_len
);
5593 l
+= 4 + ETH_ALEN
+ 4 + ipa_len
;
5594 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5595 l
+= IPV4_MAX_BYTELEN
;
5597 /* Get flags - sticky mac and/or gateway mac */
5598 STREAM_GETC(s
, flags
);
5600 STREAM_GETL(s
, seq
);
5603 if (IS_ZEBRA_DEBUG_VXLAN
)
5605 "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
5607 prefix_mac2str(&macaddr
, buf
, sizeof(buf
)),
5608 ipa_len
? " IP " : "",
5610 ipaddr2str(&ip
, buf1
, sizeof(buf1
)) : "",
5611 flags
, seq
, inet_ntoa(vtep_ip
),
5612 zebra_route_string(client
->proto
));
5614 process_remote_macip_add(vni
, &macaddr
, ipa_len
, &ip
,
5615 flags
, seq
, vtep_ip
);
5623 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5624 * us, this must involve a multihoming scenario. Treat this as implicit delete
5625 * of any prior local MAC.
5627 int zebra_vxlan_check_del_local_mac(struct interface
*ifp
,
5628 struct interface
*br_if
,
5629 struct ethaddr
*macaddr
, vlanid_t vid
)
5631 struct zebra_if
*zif
;
5632 struct zebra_l2info_vxlan
*vxl
;
5636 char buf
[ETHER_ADDR_STRLEN
];
5640 vxl
= &zif
->l2info
.vxl
;
5643 /* Check if EVPN is enabled. */
5644 if (!is_evpn_enabled())
5647 /* Locate hash entry; it is expected to exist. */
5648 zvni
= zvni_lookup(vni
);
5652 /* If entry doesn't exist, nothing to do. */
5653 mac
= zvni_mac_lookup(zvni
, macaddr
);
5657 /* Is it a local entry? */
5658 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5661 if (IS_ZEBRA_DEBUG_VXLAN
)
5663 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5664 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5667 /* Remove MAC from BGP. */
5668 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5671 * If there are no neigh associated with the mac delete the mac
5672 * else mark it as AUTO for forward reference
5674 if (!listcount(mac
->neigh_list
)) {
5675 zvni_mac_del(zvni
, mac
);
5677 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5678 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5685 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5686 * This can happen because the remote MAC entries are also added as "dynamic",
5687 * so the kernel can ageout the entry.
5689 int zebra_vxlan_check_readd_remote_mac(struct interface
*ifp
,
5690 struct interface
*br_if
,
5691 struct ethaddr
*macaddr
, vlanid_t vid
)
5693 struct zebra_if
*zif
= NULL
;
5694 struct zebra_l2info_vxlan
*vxl
= NULL
;
5696 zebra_vni_t
*zvni
= NULL
;
5697 zebra_l3vni_t
*zl3vni
= NULL
;
5698 zebra_mac_t
*mac
= NULL
;
5699 char buf
[ETHER_ADDR_STRLEN
];
5703 vxl
= &zif
->l2info
.vxl
;
5706 /* Check if EVPN is enabled. */
5707 if (!is_evpn_enabled())
5710 /* check if this is a remote RMAC and readd simillar to remote macs */
5711 zl3vni
= zl3vni_lookup(vni
);
5713 return zebra_vxlan_readd_remote_rmac(zl3vni
, macaddr
);
5715 /* Locate hash entry; it is expected to exist. */
5716 zvni
= zvni_lookup(vni
);
5720 /* If entry doesn't exist, nothing to do. */
5721 mac
= zvni_mac_lookup(zvni
, macaddr
);
5725 /* Is it a remote entry? */
5726 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5729 if (IS_ZEBRA_DEBUG_VXLAN
)
5730 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5731 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5734 zvni_mac_install(zvni
, mac
);
5739 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5741 int zebra_vxlan_local_mac_del(struct interface
*ifp
, struct interface
*br_if
,
5742 struct ethaddr
*macaddr
, vlanid_t vid
)
5746 char buf
[ETHER_ADDR_STRLEN
];
5748 /* We are interested in MACs only on ports or (port, VLAN) that
5751 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5754 if (!zvni
->vxlan_if
) {
5756 "VNI %u hash %p doesn't have intf upon local MAC DEL",
5761 if (IS_ZEBRA_DEBUG_VXLAN
)
5762 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u",
5763 prefix_mac2str(macaddr
, buf
, sizeof(buf
)), ifp
->name
,
5764 ifp
->ifindex
, vid
, zvni
->vni
);
5766 /* If entry doesn't exist, nothing to do. */
5767 mac
= zvni_mac_lookup(zvni
, macaddr
);
5771 /* Is it a local entry? */
5772 if (!CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
))
5775 /* Update all the neigh entries associated with this mac */
5776 zvni_process_neigh_on_local_mac_del(zvni
, mac
);
5778 /* Remove MAC from BGP. */
5779 zvni_mac_send_del_to_client(zvni
->vni
, macaddr
, mac
->flags
);
5782 * If there are no neigh associated with the mac delete the mac
5783 * else mark it as AUTO for forward reference
5785 if (!listcount(mac
->neigh_list
)) {
5786 zvni_mac_del(zvni
, mac
);
5788 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5789 SET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5796 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5798 int zebra_vxlan_local_mac_add_update(struct interface
*ifp
,
5799 struct interface
*br_if
,
5800 struct ethaddr
*macaddr
, vlanid_t vid
,
5805 char buf
[ETHER_ADDR_STRLEN
];
5806 bool mac_sticky
= false;
5807 bool inform_client
= false;
5808 bool upd_neigh
= false;
5810 /* We are interested in MACs only on ports or (port, VLAN) that
5813 zvni
= zvni_map_vlan(ifp
, br_if
, vid
);
5815 if (IS_ZEBRA_DEBUG_VXLAN
)
5817 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5818 sticky
? "sticky " : "",
5819 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5820 ifp
->name
, ifp
->ifindex
, vid
);
5824 if (!zvni
->vxlan_if
) {
5826 "VNI %u hash %p doesn't have intf upon local MAC ADD",
5831 /* Check if we need to create or update or it is a NO-OP. */
5832 mac
= zvni_mac_lookup(zvni
, macaddr
);
5834 if (IS_ZEBRA_DEBUG_VXLAN
)
5836 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
5837 sticky
? "sticky " : "",
5838 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5839 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5841 mac
= zvni_mac_add(zvni
, macaddr
);
5844 EC_ZEBRA_MAC_ADD_FAILED
,
5845 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
5846 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5847 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
);
5850 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5851 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5852 mac
->fwd_info
.local
.vid
= vid
;
5854 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5855 inform_client
= true;
5858 if (IS_ZEBRA_DEBUG_VXLAN
)
5860 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
5861 sticky
? "sticky " : "",
5862 prefix_mac2str(macaddr
, buf
, sizeof(buf
)),
5863 ifp
->name
, ifp
->ifindex
, vid
, zvni
->vni
,
5866 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
)) {
5867 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
))
5871 * Update any changes and if changes are relevant to
5874 if (mac_sticky
== sticky
5875 && mac
->fwd_info
.local
.ifindex
== ifp
->ifindex
5876 && mac
->fwd_info
.local
.vid
== vid
) {
5877 if (IS_ZEBRA_DEBUG_VXLAN
)
5879 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5880 "entry exists and has not changed ",
5881 sticky
? "sticky " : "",
5882 prefix_mac2str(macaddr
, buf
,
5884 ifp
->name
, ifp
->ifindex
, vid
,
5888 if (mac_sticky
!= sticky
) {
5890 SET_FLAG(mac
->flags
,
5893 UNSET_FLAG(mac
->flags
,
5895 inform_client
= true;
5898 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5899 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5900 mac
->fwd_info
.local
.vid
= vid
;
5902 } else if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
) ||
5903 CHECK_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
)) {
5906 * MAC has either moved or was "internally" created due
5907 * to a neighbor learn and is now actually learnt. If
5908 * it was learnt as a remote sticky MAC, this is an
5911 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
)) {
5913 EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT
,
5914 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
5915 prefix_mac2str(macaddr
, buf
,
5917 inet_ntoa(mac
->fwd_info
.r_vtep_ip
),
5922 /* If an actual move, compute MAC's seq number */
5923 if (CHECK_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
))
5924 mac
->loc_seq
= MAX(mac
->rem_seq
+ 1,
5926 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_REMOTE
);
5927 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_AUTO
);
5928 SET_FLAG(mac
->flags
, ZEBRA_MAC_LOCAL
);
5929 memset(&mac
->fwd_info
, 0, sizeof(mac
->fwd_info
));
5930 mac
->fwd_info
.local
.ifindex
= ifp
->ifindex
;
5931 mac
->fwd_info
.local
.vid
= vid
;
5933 SET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5935 UNSET_FLAG(mac
->flags
, ZEBRA_MAC_STICKY
);
5937 * We have to inform BGP of this MAC as well as process
5940 inform_client
= true;
5945 /* Inform BGP if required. */
5946 if (inform_client
) {
5947 if (zvni_mac_send_add_to_client(zvni
->vni
, macaddr
,
5948 mac
->flags
, mac
->loc_seq
))
5952 /* Process all neighbors associated with this MAC, if required. */
5954 zvni_process_neigh_on_local_mac_change(zvni
, mac
, 0);
5960 * Handle message from client to delete a remote VTEP for a VNI.
5962 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS
)
5965 unsigned short l
= 0;
5967 struct in_addr vtep_ip
;
5969 zebra_vtep_t
*zvtep
;
5970 struct interface
*ifp
;
5971 struct zebra_if
*zif
;
5973 if (!is_evpn_enabled()) {
5975 "%s: EVPN is not enabled yet we have received a vtep del command",
5976 __PRETTY_FUNCTION__
);
5980 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
5981 zlog_debug("Recv MACIP DEL for non-default VRF %u",
5988 while (l
< hdr
->length
) {
5989 /* Obtain each remote VTEP and process. */
5990 STREAM_GETL(s
, vni
);
5992 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
5993 l
+= IPV4_MAX_BYTELEN
;
5995 if (IS_ZEBRA_DEBUG_VXLAN
)
5996 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5997 inet_ntoa(vtep_ip
), vni
,
5998 zebra_route_string(client
->proto
));
6000 /* Locate VNI hash entry - expected to exist. */
6001 zvni
= zvni_lookup(vni
);
6003 if (IS_ZEBRA_DEBUG_VXLAN
)
6005 "Failed to locate VNI hash upon remote VTEP DEL, "
6011 ifp
= zvni
->vxlan_if
;
6014 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
6020 /* If down or not mapped to a bridge, we're done. */
6021 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6024 /* If the remote VTEP does not exist, there's nothing more to
6026 * Otherwise, uninstall any remote MACs pointing to this VTEP
6028 * then, the VTEP entry itself and remove it.
6030 zvtep
= zvni_vtep_find(zvni
, &vtep_ip
);
6034 zvni_neigh_del_from_vtep(zvni
, 1, &vtep_ip
);
6035 zvni_mac_del_from_vtep(zvni
, 1, &vtep_ip
);
6036 zvni_vtep_uninstall(zvni
, &vtep_ip
);
6037 zvni_vtep_del(zvni
, zvtep
);
6045 * Handle message from client to add a remote VTEP for a VNI.
6047 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS
)
6050 unsigned short l
= 0;
6052 struct in_addr vtep_ip
;
6054 struct interface
*ifp
;
6055 struct zebra_if
*zif
;
6057 if (!is_evpn_enabled()) {
6059 "%s: EVPN not enabled yet we received a vtep_add zapi call",
6060 __PRETTY_FUNCTION__
);
6064 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6065 zlog_debug("Recv MACIP ADD for non-default VRF %u",
6072 while (l
< hdr
->length
) {
6073 /* Obtain each remote VTEP and process. */
6074 STREAM_GETL(s
, vni
);
6076 STREAM_GET(&vtep_ip
.s_addr
, s
, IPV4_MAX_BYTELEN
);
6077 l
+= IPV4_MAX_BYTELEN
;
6079 if (IS_ZEBRA_DEBUG_VXLAN
)
6080 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
6081 inet_ntoa(vtep_ip
), vni
,
6082 zebra_route_string(client
->proto
));
6084 /* Locate VNI hash entry - expected to exist. */
6085 zvni
= zvni_lookup(vni
);
6088 EC_ZEBRA_VTEP_ADD_FAILED
,
6089 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
6094 ifp
= zvni
->vxlan_if
;
6097 EC_ZEBRA_VTEP_ADD_FAILED
,
6098 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
6105 /* If down or not mapped to a bridge, we're done. */
6106 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6109 /* If the remote VTEP already exists,
6110 there's nothing more to do. */
6111 if (zvni_vtep_find(zvni
, &vtep_ip
))
6114 if (zvni_vtep_add(zvni
, &vtep_ip
) == NULL
) {
6115 flog_err(EC_ZEBRA_VTEP_ADD_FAILED
,
6116 "Failed to add remote VTEP, VNI %u zvni %p",
6121 zvni_vtep_install(zvni
, &vtep_ip
);
6129 * Add/Del gateway macip to evpn
6131 * 1. SVI interface on a vlan aware bridge
6132 * 2. SVI interface on a vlan unaware bridge
6133 * 3. vrr interface (MACVLAN) associated to a SVI
6134 * We advertise macip routes for an interface if it is associated to VxLan vlan
6136 int zebra_vxlan_add_del_gw_macip(struct interface
*ifp
, struct prefix
*p
,
6140 struct ethaddr macaddr
;
6141 zebra_vni_t
*zvni
= NULL
;
6143 memset(&ip
, 0, sizeof(struct ipaddr
));
6144 memset(&macaddr
, 0, sizeof(struct ethaddr
));
6146 /* Check if EVPN is enabled. */
6147 if (!is_evpn_enabled())
6150 if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
6151 struct interface
*svi_if
=
6152 NULL
; /* SVI corresponding to the MACVLAN */
6153 struct zebra_if
*ifp_zif
=
6154 NULL
; /* Zebra daemon specific info for MACVLAN */
6155 struct zebra_if
*svi_if_zif
=
6156 NULL
; /* Zebra daemon specific info for SVI*/
6158 ifp_zif
= ifp
->info
;
6163 * for a MACVLAN interface the link represents the svi_if
6165 svi_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
6166 ifp_zif
->link_ifindex
);
6168 zlog_debug("MACVLAN %s(%u) without link information",
6169 ifp
->name
, ifp
->ifindex
);
6173 if (IS_ZEBRA_IF_VLAN(svi_if
)) {
6175 * If it is a vlan aware bridge then the link gives the
6176 * bridge information
6178 struct interface
*svi_if_link
= NULL
;
6180 svi_if_zif
= svi_if
->info
;
6182 svi_if_link
= if_lookup_by_index_per_ns(
6183 zebra_ns_lookup(NS_DEFAULT
),
6184 svi_if_zif
->link_ifindex
);
6185 zvni
= zvni_from_svi(svi_if
, svi_if_link
);
6187 } else if (IS_ZEBRA_IF_BRIDGE(svi_if
)) {
6189 * If it is a vlan unaware bridge then svi is the bridge
6192 zvni
= zvni_from_svi(svi_if
, svi_if
);
6194 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
6195 struct zebra_if
*svi_if_zif
=
6196 NULL
; /* Zebra daemon specific info for SVI */
6197 struct interface
*svi_if_link
=
6198 NULL
; /* link info for the SVI = bridge info */
6200 svi_if_zif
= ifp
->info
;
6202 svi_if_link
= if_lookup_by_index_per_ns(
6203 zebra_ns_lookup(NS_DEFAULT
),
6204 svi_if_zif
->link_ifindex
);
6206 zvni
= zvni_from_svi(ifp
, svi_if_link
);
6208 } else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
6209 zvni
= zvni_from_svi(ifp
, ifp
);
6215 if (!zvni
->vxlan_if
) {
6216 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
6222 memcpy(&macaddr
.octet
, ifp
->hw_addr
, ETH_ALEN
);
6224 if (p
->family
== AF_INET
) {
6225 ip
.ipa_type
= IPADDR_V4
;
6226 memcpy(&(ip
.ipaddr_v4
), &(p
->u
.prefix4
),
6227 sizeof(struct in_addr
));
6228 } else if (p
->family
== AF_INET6
) {
6229 ip
.ipa_type
= IPADDR_V6
;
6230 memcpy(&(ip
.ipaddr_v6
), &(p
->u
.prefix6
),
6231 sizeof(struct in6_addr
));
6236 zvni_gw_macip_add(ifp
, zvni
, &macaddr
, &ip
);
6238 zvni_gw_macip_del(ifp
, zvni
, &ip
);
6244 * Handle SVI interface going down.
6245 * SVI can be associated to either L3-VNI or L2-VNI.
6246 * For L2-VNI: At this point, this is a NOP since
6247 * the kernel deletes the neighbor entries on this SVI (if any).
6248 * We only need to update the vrf corresponding to zvni.
6249 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
6252 int zebra_vxlan_svi_down(struct interface
*ifp
, struct interface
*link_if
)
6254 zebra_l3vni_t
*zl3vni
= NULL
;
6256 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6259 /* process l3-vni down */
6260 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6262 /* remove association with svi-if */
6263 zl3vni
->svi_if
= NULL
;
6265 zebra_vni_t
*zvni
= NULL
;
6267 /* since we dont have svi corresponding to zvni, we associate it
6268 * to default vrf. Note: the corresponding neigh entries on the
6269 * SVI would have already been deleted */
6270 zvni
= zvni_from_svi(ifp
, link_if
);
6272 zvni
->vrf_id
= VRF_DEFAULT
;
6274 /* update the tenant vrf in BGP */
6275 zvni_send_add_to_client(zvni
);
6282 * Handle SVI interface coming up.
6283 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
6285 * For L2-VNI: we need to install any remote neighbors entried (used for
6287 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
6289 int zebra_vxlan_svi_up(struct interface
*ifp
, struct interface
*link_if
)
6291 zebra_vni_t
*zvni
= NULL
;
6292 zebra_l3vni_t
*zl3vni
= NULL
;
6294 zl3vni
= zl3vni_from_svi(ifp
, link_if
);
6297 /* associate with svi */
6298 zl3vni
->svi_if
= ifp
;
6300 /* process oper-up */
6301 if (is_l3vni_oper_up(zl3vni
))
6302 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6305 /* process SVI up for l2-vni */
6306 struct neigh_walk_ctx n_wctx
;
6308 zvni
= zvni_from_svi(ifp
, link_if
);
6312 if (!zvni
->vxlan_if
) {
6314 "VNI %u hash %p doesn't have intf upon SVI up",
6319 if (IS_ZEBRA_DEBUG_VXLAN
)
6321 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
6322 ifp
->name
, ifp
->ifindex
, zvni
->vni
,
6323 vrf_id_to_name(ifp
->vrf_id
));
6325 /* update the vrf information for l2-vni and inform bgp */
6326 zvni
->vrf_id
= ifp
->vrf_id
;
6327 zvni_send_add_to_client(zvni
);
6329 /* Install any remote neighbors for this VNI. */
6330 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6332 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6340 * Handle VxLAN interface down
6342 int zebra_vxlan_if_down(struct interface
*ifp
)
6345 struct zebra_if
*zif
= NULL
;
6346 struct zebra_l2info_vxlan
*vxl
= NULL
;
6347 zebra_l3vni_t
*zl3vni
= NULL
;
6350 /* Check if EVPN is enabled. */
6351 if (!is_evpn_enabled())
6356 vxl
= &zif
->l2info
.vxl
;
6359 zl3vni
= zl3vni_lookup(vni
);
6361 /* process-if-down for l3-vni */
6362 if (IS_ZEBRA_DEBUG_VXLAN
)
6363 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
6366 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6368 /* process if-down for l2-vni */
6369 if (IS_ZEBRA_DEBUG_VXLAN
)
6370 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
6373 /* Locate hash entry; it is expected to exist. */
6374 zvni
= zvni_lookup(vni
);
6377 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
6378 ifp
->name
, ifp
->ifindex
, vni
);
6382 assert(zvni
->vxlan_if
== ifp
);
6384 /* Delete this VNI from BGP. */
6385 zvni_send_del_to_client(zvni
->vni
);
6387 /* Free up all neighbors and MACs, if any. */
6388 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6389 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6391 /* Free up all remote VTEPs, if any. */
6392 zvni_vtep_del_all(zvni
, 1);
6398 * Handle VxLAN interface up - update BGP if required.
6400 int zebra_vxlan_if_up(struct interface
*ifp
)
6403 struct zebra_if
*zif
= NULL
;
6404 struct zebra_l2info_vxlan
*vxl
= NULL
;
6405 zebra_vni_t
*zvni
= NULL
;
6406 zebra_l3vni_t
*zl3vni
= NULL
;
6408 /* Check if EVPN is enabled. */
6409 if (!is_evpn_enabled())
6414 vxl
= &zif
->l2info
.vxl
;
6417 zl3vni
= zl3vni_lookup(vni
);
6420 if (IS_ZEBRA_DEBUG_VXLAN
)
6421 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp
->name
,
6424 /* we need to associate with SVI, if any, we can associate with
6425 * svi-if only after association with vxlan-intf is complete
6427 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6429 if (is_l3vni_oper_up(zl3vni
))
6430 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6432 /* Handle L2-VNI add */
6433 struct interface
*vlan_if
= NULL
;
6435 if (IS_ZEBRA_DEBUG_VXLAN
)
6436 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
6439 /* Locate hash entry; it is expected to exist. */
6440 zvni
= zvni_lookup(vni
);
6443 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
6444 ifp
->name
, ifp
->ifindex
, vni
);
6448 assert(zvni
->vxlan_if
== ifp
);
6449 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6450 zif
->brslave_info
.br_if
);
6452 zvni
->vrf_id
= vlan_if
->vrf_id
;
6453 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6455 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6458 /* If part of a bridge, inform BGP about this VNI. */
6459 /* Also, read and populate local MACs and neighbors. */
6460 if (zif
->brslave_info
.br_if
) {
6461 zvni_send_add_to_client(zvni
);
6462 zvni_read_mac_neigh(zvni
, ifp
);
6470 * Handle VxLAN interface delete. Locate and remove entry in hash table
6471 * and update BGP, if required.
6473 int zebra_vxlan_if_del(struct interface
*ifp
)
6476 struct zebra_if
*zif
= NULL
;
6477 struct zebra_l2info_vxlan
*vxl
= NULL
;
6478 zebra_vni_t
*zvni
= NULL
;
6479 zebra_l3vni_t
*zl3vni
= NULL
;
6481 /* Check if EVPN is enabled. */
6482 if (!is_evpn_enabled())
6487 vxl
= &zif
->l2info
.vxl
;
6490 zl3vni
= zl3vni_lookup(vni
);
6493 if (IS_ZEBRA_DEBUG_VXLAN
)
6494 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
6497 /* process oper-down for l3-vni */
6498 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6500 /* remove the association with vxlan_if */
6501 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
6502 zl3vni
->vxlan_if
= NULL
;
6505 /* process if-del for l2-vni*/
6506 if (IS_ZEBRA_DEBUG_VXLAN
)
6507 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
6510 /* Locate hash entry; it is expected to exist. */
6511 zvni
= zvni_lookup(vni
);
6514 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6515 ifp
->name
, ifp
->ifindex
, vni
);
6519 /* remove from l3-vni list */
6520 zl3vni
= zl3vni_from_vrf(zvni
->vrf_id
);
6522 listnode_delete(zl3vni
->l2vnis
, zvni
);
6524 /* Delete VNI from BGP. */
6525 zvni_send_del_to_client(zvni
->vni
);
6527 /* Free up all neighbors and MAC, if any. */
6528 zvni_neigh_del_all(zvni
, 0, 0, DEL_ALL_NEIGH
);
6529 zvni_mac_del_all(zvni
, 0, 0, DEL_ALL_MAC
);
6531 /* Free up all remote VTEPs, if any. */
6532 zvni_vtep_del_all(zvni
, 0);
6534 /* Delete the hash entry. */
6535 if (zvni_del(zvni
)) {
6536 flog_err(EC_ZEBRA_VNI_DEL_FAILED
,
6537 "Failed to del VNI hash %p, IF %s(%u) VNI %u",
6538 zvni
, ifp
->name
, ifp
->ifindex
, zvni
->vni
);
6546 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6548 int zebra_vxlan_if_update(struct interface
*ifp
, uint16_t chgflags
)
6551 struct zebra_if
*zif
= NULL
;
6552 struct zebra_l2info_vxlan
*vxl
= NULL
;
6553 zebra_vni_t
*zvni
= NULL
;
6554 zebra_l3vni_t
*zl3vni
= NULL
;
6556 /* Check if EVPN is enabled. */
6557 if (!is_evpn_enabled())
6562 vxl
= &zif
->l2info
.vxl
;
6565 zl3vni
= zl3vni_lookup(vni
);
6568 if (IS_ZEBRA_DEBUG_VXLAN
)
6570 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6571 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6572 inet_ntoa(vxl
->vtep_ip
),
6573 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6575 /* Removed from bridge? Cleanup and return */
6576 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6577 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6578 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6582 /* access-vlan change - process oper down, associate with new
6583 * svi_if and then process oper up again
6585 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6586 if (if_is_operative(ifp
)) {
6587 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6588 zl3vni
->svi_if
= NULL
;
6589 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6590 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6591 if (is_l3vni_oper_up(zl3vni
))
6592 zebra_vxlan_process_l3vni_oper_up(
6598 * local-ip change - process oper down, associate with new
6599 * local-ip and then process oper up again
6601 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
6602 if (if_is_operative(ifp
)) {
6603 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6604 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6605 if (is_l3vni_oper_up(zl3vni
))
6606 zebra_vxlan_process_l3vni_oper_up(
6611 /* Update local tunnel IP. */
6612 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6614 /* if we have a valid new master, process l3-vni oper up */
6615 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
6616 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
6617 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6621 /* Update VNI hash. */
6622 zvni
= zvni_lookup(vni
);
6625 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6626 ifp
->name
, ifp
->ifindex
, vni
);
6630 if (IS_ZEBRA_DEBUG_VXLAN
)
6632 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6633 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6634 inet_ntoa(vxl
->vtep_ip
),
6635 zif
->brslave_info
.bridge_ifindex
, chgflags
);
6637 /* Removed from bridge? Cleanup and return */
6638 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6639 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
6640 /* Delete from client, remove all remote VTEPs */
6641 /* Also, free up all MACs and neighbors. */
6642 zvni_send_del_to_client(zvni
->vni
);
6643 zvni_neigh_del_all(zvni
, 1, 0, DEL_ALL_NEIGH
);
6644 zvni_mac_del_all(zvni
, 1, 0, DEL_ALL_MAC
);
6645 zvni_vtep_del_all(zvni
, 1);
6649 /* Handle other changes. */
6650 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6651 /* Remove all existing local neigh and MACs for this VNI
6652 * (including from BGP)
6654 zvni_neigh_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6655 zvni_mac_del_all(zvni
, 0, 1, DEL_LOCAL_MAC
);
6658 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6659 zvni
->vxlan_if
= ifp
;
6661 /* Take further actions needed.
6662 * Note that if we are here, there is a change of interest.
6664 /* If down or not mapped to a bridge, we're done. */
6665 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6668 /* Inform BGP, if there is a change of interest. */
6670 & (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
))
6671 zvni_send_add_to_client(zvni
);
6673 /* If there is a valid new master or a VLAN mapping change,
6674 * read and populate local MACs and neighbors.
6675 * Also, reinstall any remote MACs and neighbors
6676 * for this VNI (based on new VLAN).
6678 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
6679 zvni_read_mac_neigh(zvni
, ifp
);
6680 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
6681 struct mac_walk_ctx m_wctx
;
6682 struct neigh_walk_ctx n_wctx
;
6684 zvni_read_mac_neigh(zvni
, ifp
);
6686 memset(&m_wctx
, 0, sizeof(struct mac_walk_ctx
));
6688 hash_iterate(zvni
->mac_table
, zvni_install_mac_hash
,
6691 memset(&n_wctx
, 0, sizeof(struct neigh_walk_ctx
));
6693 hash_iterate(zvni
->neigh_table
, zvni_install_neigh_hash
,
6702 * Handle VxLAN interface add.
6704 int zebra_vxlan_if_add(struct interface
*ifp
)
6707 struct zebra_if
*zif
= NULL
;
6708 struct zebra_l2info_vxlan
*vxl
= NULL
;
6709 zebra_vni_t
*zvni
= NULL
;
6710 zebra_l3vni_t
*zl3vni
= NULL
;
6712 /* Check if EVPN is enabled. */
6713 if (!is_evpn_enabled())
6718 vxl
= &zif
->l2info
.vxl
;
6721 zl3vni
= zl3vni_lookup(vni
);
6724 /* process if-add for l3-vni*/
6725 if (IS_ZEBRA_DEBUG_VXLAN
)
6727 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6728 vni
, ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6729 inet_ntoa(vxl
->vtep_ip
),
6730 zif
->brslave_info
.bridge_ifindex
);
6732 /* associate with vxlan_if */
6733 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
6734 zl3vni
->vxlan_if
= ifp
;
6736 /* Associate with SVI, if any. We can associate with svi-if only
6737 * after association with vxlan_if is complete */
6738 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6740 if (is_l3vni_oper_up(zl3vni
))
6741 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6744 /* process if-add for l2-vni */
6745 struct interface
*vlan_if
= NULL
;
6747 /* Create or update VNI hash. */
6748 zvni
= zvni_lookup(vni
);
6750 zvni
= zvni_add(vni
);
6753 EC_ZEBRA_VNI_ADD_FAILED
,
6754 "Failed to add VNI hash, IF %s(%u) VNI %u",
6755 ifp
->name
, ifp
->ifindex
, vni
);
6760 zvni
->local_vtep_ip
= vxl
->vtep_ip
;
6761 zvni
->vxlan_if
= ifp
;
6762 vlan_if
= zvni_map_to_svi(vxl
->access_vlan
,
6763 zif
->brslave_info
.br_if
);
6765 zvni
->vrf_id
= vlan_if
->vrf_id
;
6766 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf_id
);
6768 listnode_add_sort(zl3vni
->l2vnis
, zvni
);
6771 if (IS_ZEBRA_DEBUG_VXLAN
)
6773 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6775 vlan_if
? vrf_id_to_name(vlan_if
->vrf_id
)
6777 ifp
->name
, ifp
->ifindex
, vxl
->access_vlan
,
6778 inet_ntoa(vxl
->vtep_ip
),
6779 zif
->brslave_info
.bridge_ifindex
);
6781 /* If down or not mapped to a bridge, we're done. */
6782 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
6786 zvni_send_add_to_client(zvni
);
6788 /* Read and populate local MACs and neighbors */
6789 zvni_read_mac_neigh(zvni
, ifp
);
6795 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf
*zvrf
, vni_t vni
,
6796 char *err
, int err_str_sz
, int filter
,
6799 zebra_l3vni_t
*zl3vni
= NULL
;
6800 struct zebra_vrf
*zvrf_default
= NULL
;
6802 zvrf_default
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
6806 if (IS_ZEBRA_DEBUG_VXLAN
)
6807 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf
), vni
,
6808 add
? "ADD" : "DEL");
6812 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6814 /* check if the vni is already present under zvrf */
6816 snprintf(err
, err_str_sz
,
6817 "VNI is already configured under the vrf");
6821 /* check if this VNI is already present in the system */
6822 zl3vni
= zl3vni_lookup(vni
);
6824 snprintf(err
, err_str_sz
,
6825 "VNI is already configured as L3-VNI");
6829 /* add the L3-VNI to the global table */
6830 zl3vni
= zl3vni_add(vni
, zvrf_id(zvrf
));
6832 snprintf(err
, err_str_sz
, "Could not add L3-VNI");
6836 /* associate the vrf with vni */
6839 /* set the filter in l3vni to denote if we are using l3vni only
6843 SET_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
);
6845 /* associate with vxlan-intf;
6846 * we need to associate with the vxlan-intf first
6848 zl3vni
->vxlan_if
= zl3vni_map_to_vxlan_if(zl3vni
);
6850 /* associate with corresponding SVI interface, we can associate
6851 * with svi-if only after vxlan interface association is
6854 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
6856 /* formulate l2vni list */
6857 hash_iterate(zvrf_default
->vni_table
, zvni_add_to_l3vni_list
,
6860 if (is_l3vni_oper_up(zl3vni
))
6861 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6864 zl3vni
= zl3vni_lookup(vni
);
6866 snprintf(err
, err_str_sz
, "VNI doesn't exist");
6870 if (filter
&& !CHECK_FLAG(zl3vni
->filter
, PREFIX_ROUTES_ONLY
)) {
6871 snprintf(err
, ERR_STR_SZ
,
6872 "prefix-routes-only is not set for the vni");
6876 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6878 /* delete and uninstall all rmacs */
6879 hash_iterate(zl3vni
->rmac_table
, zl3vni_del_rmac_hash_entry
,
6882 /* delete and uninstall all next-hops */
6883 hash_iterate(zl3vni
->nh_table
, zl3vni_del_nh_hash_entry
,
6889 zebra_vxlan_handle_vni_transition(zvrf
, vni
, add
);
6894 int zebra_vxlan_vrf_enable(struct zebra_vrf
*zvrf
)
6896 zebra_l3vni_t
*zl3vni
= NULL
;
6899 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6903 zl3vni
->vrf_id
= zvrf_id(zvrf
);
6904 if (is_l3vni_oper_up(zl3vni
))
6905 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
6909 int zebra_vxlan_vrf_disable(struct zebra_vrf
*zvrf
)
6911 zebra_l3vni_t
*zl3vni
= NULL
;
6914 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6918 zl3vni
->vrf_id
= VRF_UNKNOWN
;
6919 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
6923 int zebra_vxlan_vrf_delete(struct zebra_vrf
*zvrf
)
6925 zebra_l3vni_t
*zl3vni
= NULL
;
6929 zl3vni
= zl3vni_lookup(zvrf
->l3vni
);
6935 zebra_vxlan_handle_vni_transition(zvrf
, vni
, 0);
6941 * Handle message from client to specify the flooding mechanism for
6942 * BUM packets. The default is to do head-end (ingress) replication
6943 * and the other supported option is to disable it. This applies to
6944 * all BUM traffic and disabling it applies to both the transmit and
6945 * receive direction.
6947 void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS
)
6950 enum vxlan_flood_control flood_ctrl
;
6952 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6953 zlog_err("EVPN flood control for non-default VRF %u",
6959 STREAM_GETC(s
, flood_ctrl
);
6961 if (IS_ZEBRA_DEBUG_VXLAN
)
6962 zlog_debug("EVPN flood control %u, currently %u",
6963 flood_ctrl
, zvrf
->vxlan_flood_ctrl
);
6965 if (zvrf
->vxlan_flood_ctrl
== flood_ctrl
)
6968 zvrf
->vxlan_flood_ctrl
= flood_ctrl
;
6970 /* Install or uninstall flood entries corresponding to
6973 hash_iterate(zvrf
->vni_table
, zvni_handle_flooding_remote_vteps
,
6981 * Handle message from client to enable/disable advertisement of g/w macip
6984 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS
)
6989 zebra_vni_t
*zvni
= NULL
;
6990 struct interface
*ifp
= NULL
;
6991 struct zebra_if
*zif
= NULL
;
6992 struct zebra_l2info_vxlan zl2_info
;
6993 struct interface
*vlan_if
= NULL
;
6995 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
6996 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
7002 STREAM_GETC(s
, advertise
);
7003 vni
= stream_get3(s
);
7005 zvni
= zvni_lookup(vni
);
7009 if (zvni
->advertise_subnet
== advertise
)
7012 if (IS_ZEBRA_DEBUG_VXLAN
)
7013 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
7014 advertise
? "enabled" : "disabled", vni
,
7015 zvni
->advertise_subnet
? "enabled" : "disabled");
7018 zvni
->advertise_subnet
= advertise
;
7020 ifp
= zvni
->vxlan_if
;
7026 /* If down or not mapped to a bridge, we're done. */
7027 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
7030 zl2_info
= zif
->l2info
.vxl
;
7033 zvni_map_to_svi(zl2_info
.access_vlan
, zif
->brslave_info
.br_if
);
7037 if (zvni
->advertise_subnet
)
7038 zvni_advertise_subnet(zvni
, vlan_if
, 1);
7040 zvni_advertise_subnet(zvni
, vlan_if
, 0);
7047 * Handle message from client to enable/disable advertisement of g/w macip
7050 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS
)
7055 zebra_vni_t
*zvni
= NULL
;
7056 struct interface
*ifp
= NULL
;
7058 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
7059 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
7065 STREAM_GETC(s
, advertise
);
7066 STREAM_GETL(s
, vni
);
7069 if (IS_ZEBRA_DEBUG_VXLAN
)
7070 zlog_debug("EVPN gateway macip Adv %s, currently %s",
7071 advertise
? "enabled" : "disabled",
7072 advertise_gw_macip_enabled(NULL
)
7076 if (zvrf
->advertise_gw_macip
== advertise
)
7079 zvrf
->advertise_gw_macip
= advertise
;
7081 if (advertise_gw_macip_enabled(zvni
))
7082 hash_iterate(zvrf
->vni_table
,
7083 zvni_gw_macip_add_for_vni_hash
, NULL
);
7085 hash_iterate(zvrf
->vni_table
,
7086 zvni_gw_macip_del_for_vni_hash
, NULL
);
7089 struct zebra_if
*zif
= NULL
;
7090 struct zebra_l2info_vxlan zl2_info
;
7091 struct interface
*vlan_if
= NULL
;
7092 struct interface
*vrr_if
= NULL
;
7094 zvni
= zvni_lookup(vni
);
7098 if (IS_ZEBRA_DEBUG_VXLAN
)
7100 "EVPN gateway macip Adv %s on VNI %d , currently %s",
7101 advertise
? "enabled" : "disabled", vni
,
7102 advertise_gw_macip_enabled(zvni
) ? "enabled"
7105 if (zvni
->advertise_gw_macip
== advertise
)
7108 zvni
->advertise_gw_macip
= advertise
;
7110 ifp
= zvni
->vxlan_if
;
7116 /* If down or not mapped to a bridge, we're done. */
7117 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
7120 zl2_info
= zif
->l2info
.vxl
;
7122 vlan_if
= zvni_map_to_svi(zl2_info
.access_vlan
,
7123 zif
->brslave_info
.br_if
);
7127 if (advertise_gw_macip_enabled(zvni
)) {
7128 /* Add primary SVI MAC-IP */
7129 zvni_add_macip_for_intf(vlan_if
, zvni
);
7131 /* Add VRR MAC-IP - if any*/
7132 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7134 zvni_add_macip_for_intf(vrr_if
, zvni
);
7136 /* Del primary MAC-IP */
7137 zvni_del_macip_for_intf(vlan_if
, zvni
);
7139 /* Del VRR MAC-IP - if any*/
7140 vrr_if
= zebra_get_vrr_intf_for_svi(vlan_if
);
7142 zvni_del_macip_for_intf(vrr_if
, zvni
);
7152 * Handle message from client to learn (or stop learning) about VNIs and MACs.
7153 * When enabled, the VNI hash table will be built and MAC FDB table read;
7154 * when disabled, the entries should be deleted and remote VTEPs and MACs
7155 * uninstalled from the kernel.
7156 * This also informs the setting for BUM handling at the time this change
7157 * occurs; it is relevant only when specifying "learn".
7159 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS
)
7161 struct stream
*s
= NULL
;
7163 struct zebra_ns
*zns
= NULL
;
7164 enum vxlan_flood_control flood_ctrl
;
7166 if (zvrf_id(zvrf
) != VRF_DEFAULT
) {
7167 zlog_debug("EVPN VNI Adv for non-default VRF %u",
7173 STREAM_GETC(s
, advertise
);
7174 STREAM_GETC(s
, flood_ctrl
);
7176 if (IS_ZEBRA_DEBUG_VXLAN
)
7177 zlog_debug("EVPN VNI Adv %s, currently %s, flood control %u",
7178 advertise
? "enabled" : "disabled",
7179 is_evpn_enabled() ? "enabled" : "disabled",
7182 if (zvrf
->advertise_all_vni
== advertise
)
7185 zvrf
->advertise_all_vni
= advertise
;
7186 if (is_evpn_enabled()) {
7187 /* Note BUM handling */
7188 zvrf
->vxlan_flood_ctrl
= flood_ctrl
;
7190 /* Build VNI hash table and inform BGP. */
7191 zvni_build_hash_table();
7193 /* Add all SVI (L3 GW) MACs to BGP*/
7194 hash_iterate(zvrf
->vni_table
, zvni_gw_macip_add_for_vni_hash
,
7197 /* Read the MAC FDB */
7198 macfdb_read(zvrf
->zns
);
7200 /* Read neighbors */
7201 neigh_read(zvrf
->zns
);
7203 /* Cleanup VTEPs for all VNIs - uninstall from
7204 * kernel and free entries.
7206 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7208 /* cleanup all l3vnis */
7209 zns
= zebra_ns_lookup(NS_DEFAULT
);
7213 hash_iterate(zns
->l3vni_table
, zl3vni_cleanup_all
, NULL
);
7221 * Allocate VNI hash table for this VRF and do other initialization.
7222 * NOTE: Currently supported only for default VRF.
7224 void zebra_vxlan_init_tables(struct zebra_vrf
*zvrf
)
7228 zvrf
->vni_table
= hash_create(vni_hash_keymake
, vni_hash_cmp
,
7229 "Zebra VRF VNI Table");
7232 /* Cleanup VNI info, but don't free the table. */
7233 void zebra_vxlan_cleanup_tables(struct zebra_vrf
*zvrf
)
7237 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7240 /* Close all VNI handling */
7241 void zebra_vxlan_close_tables(struct zebra_vrf
*zvrf
)
7245 hash_iterate(zvrf
->vni_table
, zvni_cleanup_all
, zvrf
);
7246 hash_free(zvrf
->vni_table
);
7249 /* init the l3vni table */
7250 void zebra_vxlan_ns_init(struct zebra_ns
*zns
)
7252 zns
->l3vni_table
= hash_create(l3vni_hash_keymake
, l3vni_hash_cmp
,
7253 "Zebra VRF L3 VNI table");
7256 /* free l3vni table */
7257 void zebra_vxlan_ns_disable(struct zebra_ns
*zns
)
7259 hash_free(zns
->l3vni_table
);
7262 /* get the l3vni svi ifindex */
7263 ifindex_t
get_l3vni_svi_ifindex(vrf_id_t vrf_id
)
7265 zebra_l3vni_t
*zl3vni
= NULL
;
7267 zl3vni
= zl3vni_from_vrf(vrf_id
);
7268 if (!zl3vni
|| !is_l3vni_oper_up(zl3vni
))
7271 return zl3vni
->svi_if
->ifindex
;