Line data Source code
1 : /*
2 : * Zebra EVPN for VxLAN code
3 : * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
4 : *
5 : * This file is part of FRR.
6 : *
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
10 : * later version.
11 : *
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.
16 : *
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
20 : * 02111-1307, USA.
21 : */
22 :
23 : #include <zebra.h>
24 :
25 : #include "hash.h"
26 : #include "if.h"
27 : #include "jhash.h"
28 : #include "linklist.h"
29 : #include "log.h"
30 : #include "memory.h"
31 : #include "prefix.h"
32 : #include "stream.h"
33 : #include "table.h"
34 : #include "vlan.h"
35 : #include "vxlan.h"
36 : #ifdef GNU_LINUX
37 : #include <linux/neighbour.h>
38 : #endif
39 : #include "lib/printfrr.h"
40 :
41 : #include "zebra/zebra_router.h"
42 : #include "zebra/debug.h"
43 : #include "zebra/interface.h"
44 : #include "zebra/rib.h"
45 : #include "zebra/rt.h"
46 : #include "zebra/rt_netlink.h"
47 : #include "zebra/zebra_errors.h"
48 : #include "zebra/zebra_l2.h"
49 : #include "zebra/zebra_ns.h"
50 : #include "zebra/zebra_vrf.h"
51 : #include "zebra/zebra_vxlan.h"
52 : #include "zebra/zebra_evpn.h"
53 : #include "zebra/zebra_evpn_mac.h"
54 : #include "zebra/zebra_evpn_neigh.h"
55 : #include "zebra/zebra_vxlan_private.h"
56 : #include "zebra/zebra_evpn_mh.h"
57 : #include "zebra/zebra_evpn_vxlan.h"
58 : #include "zebra/zebra_router.h"
59 :
60 6 : DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
61 6 : DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
62 6 : DEFINE_MTYPE_STATIC(ZEBRA, L3VNI_MAC, "EVPN L3VNI MAC");
63 6 : DEFINE_MTYPE_STATIC(ZEBRA, L3NEIGH, "EVPN Neighbor");
64 6 : DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group");
65 6 : DEFINE_MTYPE_STATIC(ZEBRA, EVPN_VTEP, "zebra VxLAN VTEP IP");
66 :
67 0 : DEFINE_HOOK(zebra_rmac_update,
68 : (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete,
69 : const char *reason),
70 : (rmac, zl3vni, delete, reason));
71 :
72 : /* config knobs */
73 : static bool accept_bgp_seq = true;
74 :
75 : /* static function declarations */
76 : static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
77 : void **args);
78 : static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
79 : json_object *json);
80 : static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
81 : json_object *json);
82 : static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt);
83 :
84 : /* l3-vni next-hop neigh related APIs */
85 : static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
86 : const struct ipaddr *ip);
87 : static void *zl3vni_nh_alloc(void *p);
88 : static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
89 : const struct ipaddr *vtep_ip,
90 : const struct ethaddr *rmac);
91 : static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
92 : static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
93 : static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
94 : struct zebra_neigh *n);
95 :
96 : /* l3-vni rmac related APIs */
97 : static void zl3vni_print_rmac_hash(struct hash_bucket *, void *);
98 : static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
99 : const struct ethaddr *rmac);
100 : static void *zl3vni_rmac_alloc(void *p);
101 : static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
102 : const struct ethaddr *rmac);
103 : static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac);
104 : static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
105 : struct zebra_mac *zrmac);
106 : static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
107 : struct zebra_mac *zrmac);
108 :
109 : /* l3-vni related APIs*/
110 : static void *zl3vni_alloc(void *p);
111 : static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
112 : static int zl3vni_del(struct zebra_l3vni *zl3vni);
113 : static void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni);
114 : static void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni);
115 :
116 : static void zevpn_build_hash_table(void);
117 : static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
118 : static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
119 : static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
120 : struct in_addr sip, struct in_addr mcast_grp);
121 : static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf,
122 : struct in_addr sip,
123 : struct in_addr mcast_grp);
124 : static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
125 : struct in_addr mcast_grp);
126 : static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
127 : struct in_addr mcast_grp);
128 : static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf);
129 :
130 0 : bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf)
131 : {
132 0 : return zvrf->dup_addr_detect && zebra_evpn_mh_do_dup_addr_detect();
133 : }
134 :
135 : /* Private functions */
136 0 : static int host_rb_entry_compare(const struct host_rb_entry *hle1,
137 : const struct host_rb_entry *hle2)
138 : {
139 0 : if (hle1->p.family < hle2->p.family)
140 : return -1;
141 :
142 0 : if (hle1->p.family > hle2->p.family)
143 : return 1;
144 :
145 0 : if (hle1->p.prefixlen < hle2->p.prefixlen)
146 : return -1;
147 :
148 0 : if (hle1->p.prefixlen > hle2->p.prefixlen)
149 : return 1;
150 :
151 0 : if (hle1->p.family == AF_INET) {
152 0 : if (hle1->p.u.prefix4.s_addr < hle2->p.u.prefix4.s_addr)
153 : return -1;
154 :
155 0 : if (hle1->p.u.prefix4.s_addr > hle2->p.u.prefix4.s_addr)
156 : return 1;
157 :
158 : return 0;
159 0 : } else if (hle1->p.family == AF_INET6) {
160 0 : return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
161 : IPV6_MAX_BYTELEN);
162 0 : } else if (hle1->p.family == AF_EVPN) {
163 0 : uint8_t family1;
164 0 : uint8_t family2;
165 :
166 : /* two (v4/v6) dummy prefixes of route_type BGP_EVPN_AD_ROUTE
167 : * are used for all nexthops associated with a non-zero ESI
168 : */
169 0 : family1 = is_evpn_prefix_ipaddr_v4(
170 0 : (const struct prefix_evpn *)&hle1->p)
171 : ? AF_INET
172 : : AF_INET6;
173 0 : family2 = is_evpn_prefix_ipaddr_v4(
174 0 : (const struct prefix_evpn *)&hle2->p)
175 : ? AF_INET
176 : : AF_INET6;
177 :
178 :
179 0 : if (family1 < family2)
180 : return -1;
181 :
182 0 : if (family1 > family2)
183 : return 1;
184 :
185 : return 0;
186 : } else {
187 0 : zlog_debug("%s: Unexpected family type: %d", __func__,
188 : hle1->p.family);
189 0 : return 0;
190 : }
191 : }
192 0 : RB_GENERATE(host_rb_tree_entry, host_rb_entry, hl_entry, host_rb_entry_compare);
193 :
194 0 : static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe)
195 : {
196 0 : struct host_rb_entry *hle;
197 0 : uint32_t count = 0;
198 :
199 0 : RB_FOREACH (hle, host_rb_tree_entry, hrbe)
200 0 : count++;
201 :
202 0 : return count;
203 : }
204 :
205 0 : static int l3vni_rmac_nh_list_cmp(void *p1, void *p2)
206 : {
207 0 : const struct ipaddr *vtep_ip1 = p1;
208 0 : const struct ipaddr *vtep_ip2 = p2;
209 :
210 0 : return !ipaddr_cmp(vtep_ip1, vtep_ip2);
211 : }
212 :
213 0 : static void l3vni_rmac_nh_free(struct ipaddr *vtep_ip)
214 : {
215 0 : XFREE(MTYPE_EVPN_VTEP, vtep_ip);
216 0 : }
217 :
218 0 : static void l3vni_rmac_nh_list_nh_delete(struct zebra_l3vni *zl3vni,
219 : struct zebra_mac *zrmac,
220 : struct ipaddr *vtep_ip)
221 : {
222 0 : struct listnode *node = NULL, *nnode = NULL;
223 0 : struct ipaddr *vtep = NULL;
224 :
225 0 : for (ALL_LIST_ELEMENTS(zrmac->nh_list, node, nnode, vtep)) {
226 0 : if (ipaddr_cmp(vtep, vtep_ip) == 0)
227 : break;
228 : }
229 :
230 0 : if (node) {
231 0 : l3vni_rmac_nh_free(vtep);
232 0 : list_delete_node(zrmac->nh_list, node);
233 : }
234 0 : }
235 :
236 : /*
237 : * Print neighbors for all EVPN.
238 : */
239 0 : static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
240 : void **args)
241 : {
242 0 : struct vty *vty;
243 0 : json_object *json = NULL, *json_evpn = NULL;
244 0 : struct zebra_evpn *zevpn;
245 0 : uint32_t num_neigh;
246 0 : struct neigh_walk_ctx wctx;
247 0 : char vni_str[VNI_STR_LEN];
248 0 : uint32_t print_dup;
249 :
250 0 : vty = (struct vty *)args[0];
251 0 : json = (json_object *)args[1];
252 0 : print_dup = (uint32_t)(uintptr_t)args[2];
253 :
254 0 : zevpn = (struct zebra_evpn *)bucket->data;
255 :
256 0 : num_neigh = hashcount(zevpn->neigh_table);
257 :
258 0 : if (print_dup)
259 0 : num_neigh = num_dup_detected_neighs(zevpn);
260 :
261 0 : if (json == NULL) {
262 0 : vty_out(vty,
263 : "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
264 : zevpn->vni, num_neigh);
265 : } else {
266 0 : json_evpn = json_object_new_object();
267 0 : json_object_int_add(json_evpn, "numArpNd", num_neigh);
268 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
269 : }
270 :
271 0 : if (!num_neigh) {
272 0 : if (json)
273 0 : json_object_object_add(json, vni_str, json_evpn);
274 0 : return;
275 : }
276 :
277 : /* Since we have IPv6 addresses to deal with which can vary widely in
278 : * size, we try to be a bit more elegant in display by first computing
279 : * the maximum width.
280 : */
281 0 : memset(&wctx, 0, sizeof(wctx));
282 0 : wctx.zevpn = zevpn;
283 0 : wctx.vty = vty;
284 0 : wctx.addr_width = 15;
285 0 : wctx.json = json_evpn;
286 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
287 : &wctx);
288 :
289 0 : if (json == NULL)
290 0 : zebra_evpn_print_neigh_hdr(vty, &wctx);
291 :
292 0 : if (print_dup)
293 0 : hash_iterate(zevpn->neigh_table,
294 : zebra_evpn_print_dad_neigh_hash, &wctx);
295 : else
296 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash,
297 : &wctx);
298 :
299 0 : if (json)
300 0 : json_object_object_add(json, vni_str, json_evpn);
301 : }
302 :
303 : /*
304 : * Print neighbors for all EVPNs in detail.
305 : */
306 0 : static void zevpn_print_neigh_hash_all_evpn_detail(struct hash_bucket *bucket,
307 : void **args)
308 : {
309 0 : struct vty *vty;
310 0 : json_object *json = NULL, *json_evpn = NULL;
311 0 : struct zebra_evpn *zevpn;
312 0 : uint32_t num_neigh;
313 0 : struct neigh_walk_ctx wctx;
314 0 : char vni_str[VNI_STR_LEN];
315 0 : uint32_t print_dup;
316 :
317 0 : vty = (struct vty *)args[0];
318 0 : json = (json_object *)args[1];
319 0 : print_dup = (uint32_t)(uintptr_t)args[2];
320 :
321 0 : zevpn = (struct zebra_evpn *)bucket->data;
322 0 : if (!zevpn) {
323 0 : if (json)
324 0 : vty_out(vty, "{}\n");
325 0 : return;
326 : }
327 0 : num_neigh = hashcount(zevpn->neigh_table);
328 :
329 0 : if (print_dup && num_dup_detected_neighs(zevpn) == 0)
330 : return;
331 :
332 0 : if (json == NULL) {
333 0 : vty_out(vty,
334 : "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
335 : zevpn->vni, num_neigh);
336 : } else {
337 0 : json_evpn = json_object_new_object();
338 0 : json_object_int_add(json_evpn, "numArpNd", num_neigh);
339 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
340 : }
341 0 : if (!num_neigh) {
342 0 : if (json)
343 0 : json_object_object_add(json, vni_str, json_evpn);
344 0 : return;
345 : }
346 :
347 0 : memset(&wctx, 0, sizeof(wctx));
348 0 : wctx.zevpn = zevpn;
349 0 : wctx.vty = vty;
350 0 : wctx.addr_width = 15;
351 0 : wctx.json = json_evpn;
352 :
353 0 : if (print_dup)
354 0 : hash_iterate(zevpn->neigh_table,
355 : zebra_evpn_print_dad_neigh_hash_detail, &wctx);
356 : else
357 0 : hash_iterate(zevpn->neigh_table,
358 : zebra_evpn_print_neigh_hash_detail, &wctx);
359 :
360 0 : if (json)
361 0 : json_object_object_add(json, vni_str, json_evpn);
362 : }
363 :
364 : /* print a specific next hop for an l3vni */
365 0 : static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
366 : json_object *json)
367 : {
368 0 : char buf1[ETHER_ADDR_STRLEN];
369 0 : char buf2[INET6_ADDRSTRLEN];
370 0 : json_object *json_hosts = NULL;
371 0 : struct host_rb_entry *hle;
372 :
373 0 : if (!json) {
374 0 : vty_out(vty, "Ip: %s\n",
375 0 : ipaddr2str(&n->ip, buf2, sizeof(buf2)));
376 0 : vty_out(vty, " RMAC: %s\n",
377 0 : prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
378 0 : vty_out(vty, " Refcount: %d\n",
379 : rb_host_count(&n->host_rb));
380 0 : vty_out(vty, " Prefixes:\n");
381 0 : RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
382 0 : vty_out(vty, " %pFX\n", &hle->p);
383 : } else {
384 0 : json_hosts = json_object_new_array();
385 0 : json_object_string_add(
386 0 : json, "ip", ipaddr2str(&(n->ip), buf2, sizeof(buf2)));
387 0 : json_object_string_add(
388 : json, "routerMac",
389 0 : prefix_mac2str(&n->emac, buf2, sizeof(buf2)));
390 0 : json_object_int_add(json, "refCount",
391 0 : rb_host_count(&n->host_rb));
392 0 : RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
393 0 : json_object_array_add(json_hosts,
394 : json_object_new_string(prefix2str(
395 0 : &hle->p, buf2, sizeof(buf2))));
396 0 : json_object_object_add(json, "prefixList", json_hosts);
397 : }
398 0 : }
399 :
400 : /* Print a specific RMAC entry */
401 0 : static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
402 : json_object *json)
403 : {
404 0 : struct listnode *node = NULL;
405 0 : struct ipaddr *vtep = NULL;
406 0 : json_object *json_nhs = NULL;
407 :
408 0 : if (!json) {
409 0 : vty_out(vty, "MAC: %pEA\n", &zrmac->macaddr);
410 0 : vty_out(vty, " Remote VTEP: %pI4\n",
411 : &zrmac->fwd_info.r_vtep_ip);
412 : } else {
413 0 : json_nhs = json_object_new_array();
414 0 : json_object_string_addf(json, "routerMac", "%pEA",
415 : &zrmac->macaddr);
416 0 : json_object_string_addf(json, "vtepIp", "%pI4",
417 : &zrmac->fwd_info.r_vtep_ip);
418 0 : for (ALL_LIST_ELEMENTS_RO(zrmac->nh_list, node, vtep)) {
419 0 : json_object_array_add(json_nhs, json_object_new_stringf(
420 : "%pIA", vtep));
421 : }
422 0 : json_object_object_add(json, "nexthops", json_nhs);
423 : }
424 0 : }
425 :
426 : /*
427 : * Print MACs for all EVPNs.
428 : */
429 0 : static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt)
430 : {
431 0 : struct vty *vty;
432 0 : json_object *json = NULL, *json_evpn = NULL;
433 0 : json_object *json_mac = NULL;
434 0 : struct zebra_evpn *zevpn;
435 0 : uint32_t num_macs;
436 0 : struct mac_walk_ctx *wctx = ctxt;
437 0 : char vni_str[VNI_STR_LEN];
438 :
439 0 : vty = wctx->vty;
440 0 : json = wctx->json;
441 :
442 0 : zevpn = (struct zebra_evpn *)bucket->data;
443 0 : wctx->zevpn = zevpn;
444 :
445 : /*We are iterating over a new VNI, set the count to 0*/
446 0 : wctx->count = 0;
447 :
448 0 : num_macs = num_valid_macs(zevpn);
449 0 : if (!num_macs)
450 0 : return;
451 :
452 0 : if (wctx->print_dup)
453 0 : num_macs = num_dup_detected_macs(zevpn);
454 :
455 0 : if (json) {
456 0 : json_evpn = json_object_new_object();
457 0 : json_mac = json_object_new_object();
458 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
459 : }
460 :
461 0 : if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
462 0 : if (json == NULL) {
463 0 : vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
464 : zevpn->vni, num_macs);
465 0 : vty_out(vty,
466 : "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
467 0 : vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
468 : "Type", "Flags", "Intf/Remote ES/VTEP",
469 : "VLAN", "Seq #'s");
470 : } else
471 0 : json_object_int_add(json_evpn, "numMacs", num_macs);
472 : }
473 :
474 0 : if (!num_macs) {
475 0 : if (json) {
476 0 : json_object_int_add(json_evpn, "numMacs", num_macs);
477 0 : json_object_object_add(json, vni_str, json_evpn);
478 : }
479 0 : return;
480 : }
481 :
482 : /* assign per-evpn to wctx->json object to fill macs
483 : * under the evpn. Re-assign primary json object to fill
484 : * next evpn information.
485 : */
486 0 : wctx->json = json_mac;
487 0 : if (wctx->print_dup)
488 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash,
489 : wctx);
490 : else
491 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, wctx);
492 0 : wctx->json = json;
493 0 : if (json) {
494 0 : if (wctx->count)
495 0 : json_object_object_add(json_evpn, "macs", json_mac);
496 0 : json_object_object_add(json, vni_str, json_evpn);
497 : }
498 : }
499 :
500 : /*
501 : * Print MACs in detail for all EVPNs.
502 : */
503 0 : static void zevpn_print_mac_hash_all_evpn_detail(struct hash_bucket *bucket,
504 : void *ctxt)
505 : {
506 0 : struct vty *vty;
507 0 : json_object *json = NULL, *json_evpn = NULL;
508 0 : json_object *json_mac = NULL;
509 0 : struct zebra_evpn *zevpn;
510 0 : uint32_t num_macs;
511 0 : struct mac_walk_ctx *wctx = ctxt;
512 0 : char vni_str[VNI_STR_LEN];
513 :
514 0 : vty = wctx->vty;
515 0 : json = wctx->json;
516 :
517 0 : zevpn = (struct zebra_evpn *)bucket->data;
518 0 : if (!zevpn) {
519 0 : if (json)
520 0 : vty_out(vty, "{}\n");
521 0 : return;
522 : }
523 0 : wctx->zevpn = zevpn;
524 :
525 : /*We are iterating over a new EVPN, set the count to 0*/
526 0 : wctx->count = 0;
527 :
528 0 : num_macs = num_valid_macs(zevpn);
529 0 : if (!num_macs)
530 : return;
531 :
532 0 : if (wctx->print_dup && (num_dup_detected_macs(zevpn) == 0))
533 : return;
534 :
535 0 : if (json) {
536 0 : json_evpn = json_object_new_object();
537 0 : json_mac = json_object_new_object();
538 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
539 : }
540 :
541 0 : if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
542 0 : if (json == NULL) {
543 0 : vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
544 : zevpn->vni, num_macs);
545 : } else
546 0 : json_object_int_add(json_evpn, "numMacs", num_macs);
547 : }
548 : /* assign per-evpn to wctx->json object to fill macs
549 : * under the evpn. Re-assign primary json object to fill
550 : * next evpn information.
551 : */
552 0 : wctx->json = json_mac;
553 0 : if (wctx->print_dup)
554 0 : hash_iterate(zevpn->mac_table,
555 : zebra_evpn_print_dad_mac_hash_detail, wctx);
556 : else
557 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
558 : wctx);
559 0 : wctx->json = json;
560 0 : if (json) {
561 0 : if (wctx->count)
562 0 : json_object_object_add(json_evpn, "macs", json_mac);
563 0 : json_object_object_add(json, vni_str, json_evpn);
564 : }
565 : }
566 :
567 0 : static void zl3vni_print_nh_hash(struct hash_bucket *bucket, void *ctx)
568 : {
569 0 : struct nh_walk_ctx *wctx = NULL;
570 0 : struct vty *vty = NULL;
571 0 : struct json_object *json_evpn = NULL;
572 0 : struct json_object *json_nh = NULL;
573 0 : struct zebra_neigh *n = NULL;
574 0 : char buf1[ETHER_ADDR_STRLEN];
575 0 : char buf2[INET6_ADDRSTRLEN];
576 :
577 0 : wctx = (struct nh_walk_ctx *)ctx;
578 0 : vty = wctx->vty;
579 0 : json_evpn = wctx->json;
580 0 : if (json_evpn)
581 0 : json_nh = json_object_new_object();
582 0 : n = (struct zebra_neigh *)bucket->data;
583 :
584 0 : if (!json_evpn) {
585 0 : vty_out(vty, "%-15s %-17s\n",
586 0 : ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
587 0 : prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
588 : } else {
589 0 : json_object_string_add(json_nh, "nexthopIp",
590 0 : ipaddr2str(&n->ip, buf2, sizeof(buf2)));
591 0 : json_object_string_add(
592 : json_nh, "routerMac",
593 0 : prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
594 0 : json_object_object_add(json_evpn,
595 0 : ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
596 : json_nh);
597 : }
598 0 : }
599 :
600 0 : static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket,
601 : void **args)
602 : {
603 0 : struct vty *vty = NULL;
604 0 : json_object *json = NULL;
605 0 : json_object *json_evpn = NULL;
606 0 : struct zebra_l3vni *zl3vni = NULL;
607 0 : uint32_t num_nh = 0;
608 0 : struct nh_walk_ctx wctx;
609 0 : char vni_str[VNI_STR_LEN];
610 :
611 0 : vty = (struct vty *)args[0];
612 0 : json = (struct json_object *)args[1];
613 :
614 0 : zl3vni = (struct zebra_l3vni *)bucket->data;
615 :
616 0 : num_nh = hashcount(zl3vni->nh_table);
617 0 : if (!num_nh)
618 0 : return;
619 :
620 0 : if (json) {
621 0 : json_evpn = json_object_new_object();
622 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
623 : }
624 :
625 0 : if (json == NULL) {
626 0 : vty_out(vty, "\nVNI %u #Next-Hops %u\n\n", zl3vni->vni, num_nh);
627 0 : vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
628 : } else
629 0 : json_object_int_add(json_evpn, "numNextHops", num_nh);
630 :
631 0 : memset(&wctx, 0, sizeof(wctx));
632 0 : wctx.vty = vty;
633 0 : wctx.json = json_evpn;
634 0 : hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
635 0 : if (json)
636 0 : json_object_object_add(json, vni_str, json_evpn);
637 : }
638 :
639 0 : static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket,
640 : void **args)
641 : {
642 0 : struct vty *vty = NULL;
643 0 : json_object *json = NULL;
644 0 : json_object *json_evpn = NULL;
645 0 : struct zebra_l3vni *zl3vni = NULL;
646 0 : uint32_t num_rmacs;
647 0 : struct rmac_walk_ctx wctx;
648 0 : char vni_str[VNI_STR_LEN];
649 :
650 0 : vty = (struct vty *)args[0];
651 0 : json = (struct json_object *)args[1];
652 :
653 0 : zl3vni = (struct zebra_l3vni *)bucket->data;
654 :
655 0 : num_rmacs = hashcount(zl3vni->rmac_table);
656 0 : if (!num_rmacs)
657 0 : return;
658 :
659 0 : if (json) {
660 0 : json_evpn = json_object_new_object();
661 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
662 : }
663 :
664 0 : if (json == NULL) {
665 0 : vty_out(vty, "\nVNI %u #RMACs %u\n\n", zl3vni->vni, num_rmacs);
666 0 : vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
667 : } else
668 0 : json_object_int_add(json_evpn, "numRmacs", num_rmacs);
669 :
670 : /* assign per-vni to wctx->json object to fill macs
671 : * under the vni. Re-assign primary json object to fill
672 : * next vni information.
673 : */
674 0 : memset(&wctx, 0, sizeof(wctx));
675 0 : wctx.vty = vty;
676 0 : wctx.json = json_evpn;
677 0 : hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
678 0 : if (json)
679 0 : json_object_object_add(json, vni_str, json_evpn);
680 : }
681 :
682 0 : static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
683 : {
684 0 : struct zebra_mac *zrmac = NULL;
685 0 : struct rmac_walk_ctx *wctx = NULL;
686 0 : struct vty *vty = NULL;
687 0 : struct json_object *json = NULL;
688 0 : struct json_object *json_rmac = NULL;
689 0 : char buf[PREFIX_STRLEN];
690 :
691 0 : wctx = (struct rmac_walk_ctx *)ctx;
692 0 : vty = wctx->vty;
693 0 : json = wctx->json;
694 0 : if (json)
695 0 : json_rmac = json_object_new_object();
696 0 : zrmac = (struct zebra_mac *)bucket->data;
697 :
698 0 : if (!json) {
699 0 : vty_out(vty, "%-17s %-21pI4\n",
700 0 : prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
701 : &zrmac->fwd_info.r_vtep_ip);
702 : } else {
703 0 : json_object_string_add(
704 : json_rmac, "routerMac",
705 0 : prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
706 0 : json_object_string_addf(json_rmac, "vtepIp", "%pI4",
707 : &zrmac->fwd_info.r_vtep_ip);
708 0 : json_object_object_add(
709 0 : json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
710 : json_rmac);
711 : }
712 0 : }
713 :
714 : /* print a specific L3 VNI entry */
715 0 : static void zl3vni_print(struct zebra_l3vni *zl3vni, void **ctx)
716 : {
717 0 : char buf[PREFIX_STRLEN];
718 0 : struct vty *vty = NULL;
719 0 : json_object *json = NULL;
720 0 : struct zebra_evpn *zevpn = NULL;
721 0 : json_object *json_evpn_list = NULL;
722 0 : struct listnode *node = NULL, *nnode = NULL;
723 :
724 0 : vty = ctx[0];
725 0 : json = ctx[1];
726 :
727 0 : if (!json) {
728 0 : vty_out(vty, "VNI: %u\n", zl3vni->vni);
729 0 : vty_out(vty, " Type: %s\n", "L3");
730 0 : vty_out(vty, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
731 0 : vty_out(vty, " Local Vtep Ip: %pI4\n",
732 : &zl3vni->local_vtep_ip);
733 0 : vty_out(vty, " Vxlan-Intf: %s\n",
734 : zl3vni_vxlan_if_name(zl3vni));
735 0 : vty_out(vty, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
736 0 : vty_out(vty, " State: %s\n", zl3vni_state2str(zl3vni));
737 0 : vty_out(vty, " VNI Filter: %s\n",
738 0 : CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
739 : ? "prefix-routes-only"
740 : : "none");
741 0 : vty_out(vty, " System MAC: %s\n",
742 : zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
743 0 : vty_out(vty, " Router MAC: %s\n",
744 : zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
745 0 : vty_out(vty, " L2 VNIs: ");
746 0 : for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn))
747 0 : vty_out(vty, "%u ", zevpn->vni);
748 0 : vty_out(vty, "\n");
749 : } else {
750 0 : json_evpn_list = json_object_new_array();
751 0 : json_object_int_add(json, "vni", zl3vni->vni);
752 0 : json_object_string_add(json, "type", "L3");
753 : #if CONFDATE > 20240210
754 : CPP_NOTICE("Drop `vrf` from JSON outputs")
755 : #endif
756 0 : json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
757 0 : json_object_string_add(json, "tenantVrf",
758 : zl3vni_vrf_name(zl3vni));
759 0 : json_object_string_addf(json, "localVtepIp", "%pI4",
760 : &zl3vni->local_vtep_ip);
761 0 : json_object_string_add(json, "vxlanIntf",
762 : zl3vni_vxlan_if_name(zl3vni));
763 0 : json_object_string_add(json, "sviIntf",
764 : zl3vni_svi_if_name(zl3vni));
765 0 : json_object_string_add(json, "state", zl3vni_state2str(zl3vni));
766 0 : json_object_string_add(
767 : json, "sysMac",
768 : zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
769 0 : json_object_string_add(
770 : json, "routerMac",
771 : zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
772 0 : json_object_string_add(
773 : json, "vniFilter",
774 0 : CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
775 : ? "prefix-routes-only"
776 : : "none");
777 0 : for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn)) {
778 0 : json_object_array_add(json_evpn_list,
779 0 : json_object_new_int(zevpn->vni));
780 : }
781 0 : json_object_object_add(json, "l2Vnis", json_evpn_list);
782 : }
783 0 : }
784 :
785 : /* print a L3 VNI hash entry */
786 0 : static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[])
787 : {
788 0 : struct vty *vty = NULL;
789 0 : json_object *json = NULL;
790 0 : json_object *json_evpn = NULL;
791 0 : struct zebra_l3vni *zl3vni = NULL;
792 :
793 0 : vty = (struct vty *)ctx[0];
794 0 : json = (json_object *)ctx[1];
795 :
796 0 : zl3vni = (struct zebra_l3vni *)bucket->data;
797 :
798 0 : if (!json) {
799 0 : vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
800 : zl3vni->vni, "L3", zl3vni_vxlan_if_name(zl3vni),
801 0 : hashcount(zl3vni->rmac_table),
802 0 : hashcount(zl3vni->nh_table), "n/a",
803 : zl3vni_vrf_name(zl3vni));
804 : } else {
805 0 : char vni_str[VNI_STR_LEN];
806 :
807 0 : snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
808 0 : json_evpn = json_object_new_object();
809 0 : json_object_int_add(json_evpn, "vni", zl3vni->vni);
810 0 : json_object_string_add(json_evpn, "vxlanIf",
811 : zl3vni_vxlan_if_name(zl3vni));
812 0 : json_object_int_add(json_evpn, "numMacs",
813 0 : hashcount(zl3vni->rmac_table));
814 0 : json_object_int_add(json_evpn, "numArpNd",
815 0 : hashcount(zl3vni->nh_table));
816 0 : json_object_string_add(json_evpn, "numRemoteVteps", "n/a");
817 0 : json_object_string_add(json_evpn, "type", "L3");
818 0 : json_object_string_add(json_evpn, "tenantVrf",
819 : zl3vni_vrf_name(zl3vni));
820 0 : json_object_object_add(json, vni_str, json_evpn);
821 : }
822 0 : }
823 :
824 : /* print a L3 VNI hash entry in detail*/
825 0 : static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
826 : {
827 0 : struct vty *vty = NULL;
828 0 : struct zebra_l3vni *zl3vni = NULL;
829 0 : json_object *json_array = NULL;
830 0 : bool use_json = false;
831 0 : struct zebra_evpn_show *zes = data;
832 :
833 0 : vty = zes->vty;
834 0 : json_array = zes->json;
835 0 : use_json = zes->use_json;
836 :
837 0 : zl3vni = (struct zebra_l3vni *)bucket->data;
838 :
839 0 : zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni,
840 : use_json, json_array);
841 :
842 0 : if (!use_json)
843 0 : vty_out(vty, "\n");
844 0 : }
845 :
846 0 : static int zvni_map_to_svi_ns(struct ns *ns,
847 : void *_in_param,
848 : void **_p_ifp)
849 : {
850 0 : struct zebra_ns *zns = ns->info;
851 0 : struct route_node *rn;
852 0 : struct zebra_from_svi_param *in_param =
853 : (struct zebra_from_svi_param *)_in_param;
854 0 : struct zebra_l2info_vlan *vl;
855 0 : struct interface *tmp_if = NULL;
856 0 : struct interface **p_ifp = (struct interface **)_p_ifp;
857 0 : struct zebra_if *zif;
858 :
859 0 : assert(in_param && p_ifp);
860 :
861 : /* TODO: Optimize with a hash. */
862 0 : for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
863 0 : tmp_if = (struct interface *)rn->info;
864 : /* Check oper status of the SVI. */
865 0 : if (!tmp_if || !if_is_operative(tmp_if))
866 0 : continue;
867 0 : zif = tmp_if->info;
868 0 : if (!zif || zif->zif_type != ZEBRA_IF_VLAN
869 0 : || zif->link != in_param->br_if)
870 0 : continue;
871 0 : vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
872 :
873 0 : if (vl->vid == in_param->vid) {
874 0 : *p_ifp = tmp_if;
875 0 : return NS_WALK_STOP;
876 : }
877 : }
878 : return NS_WALK_CONTINUE;
879 : }
880 :
881 : /* Map to SVI on bridge corresponding to specified VLAN. This can be one
882 : * of two cases:
883 : * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
884 : * linked to the bridge
885 : * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge interface
886 : * itself
887 : */
888 0 : struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
889 : {
890 0 : struct interface *tmp_if = NULL;
891 0 : struct zebra_if *zif;
892 0 : struct zebra_l2info_bridge *br;
893 0 : struct zebra_from_svi_param in_param;
894 0 : struct interface **p_ifp;
895 : /* Defensive check, caller expected to invoke only with valid bridge. */
896 0 : if (!br_if)
897 : return NULL;
898 :
899 : /* Determine if bridge is VLAN-aware or not */
900 0 : zif = br_if->info;
901 0 : assert(zif);
902 0 : br = &zif->l2info.br;
903 0 : in_param.bridge_vlan_aware = br->vlan_aware;
904 : /* Check oper status of the SVI. */
905 0 : if (!in_param.bridge_vlan_aware)
906 0 : return if_is_operative(br_if) ? br_if : NULL;
907 :
908 0 : in_param.vid = vid;
909 0 : in_param.br_if = br_if;
910 0 : in_param.zif = NULL;
911 0 : p_ifp = &tmp_if;
912 : /* Identify corresponding VLAN interface. */
913 0 : ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param,
914 : (void **)p_ifp);
915 0 : return tmp_if;
916 : }
917 :
918 0 : static int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)
919 : {
920 0 : zevpn_vxlan_if_set(zevpn, zevpn->vxlan_if, false /* set */);
921 :
922 : /* Remove references to the BUM mcast grp */
923 0 : zebra_vxlan_sg_deref(zevpn->local_vtep_ip, zevpn->mcast_grp);
924 :
925 0 : return zebra_evpn_del(zevpn);
926 : }
927 :
928 0 : static int zevpn_build_hash_table_zns(struct ns *ns,
929 : void *param_in __attribute__((unused)),
930 : void **param_out __attribute__((unused)))
931 : {
932 0 : struct zebra_ns *zns = ns->info;
933 0 : struct route_node *rn;
934 0 : struct interface *ifp;
935 0 : struct zebra_vrf *zvrf;
936 :
937 0 : zvrf = zebra_vrf_get_evpn();
938 :
939 : /* Walk VxLAN interfaces and create EVPN hash. */
940 0 : for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
941 0 : vni_t vni;
942 0 : struct zebra_evpn *zevpn = NULL;
943 0 : struct zebra_l3vni *zl3vni = NULL;
944 0 : struct zebra_if *zif;
945 0 : struct zebra_l2info_vxlan *vxl;
946 :
947 0 : ifp = (struct interface *)rn->info;
948 0 : if (!ifp)
949 0 : continue;
950 0 : zif = ifp->info;
951 0 : if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
952 0 : continue;
953 :
954 0 : vxl = &zif->l2info.vxl;
955 0 : vni = vxl->vni;
956 : /* link of VXLAN interface should be in zebra_evpn_vrf */
957 0 : if (zvrf->zns->ns_id != vxl->link_nsid) {
958 0 : if (IS_ZEBRA_DEBUG_VXLAN)
959 0 : zlog_debug(
960 : "Intf %s(%u) VNI %u, link not in same "
961 : "namespace than BGP EVPN core instance ",
962 : ifp->name, ifp->ifindex, vni);
963 0 : continue;
964 : }
965 : /* L3-VNI and L2-VNI are handled seperately */
966 0 : zl3vni = zl3vni_lookup(vni);
967 0 : if (zl3vni) {
968 :
969 0 : if (IS_ZEBRA_DEBUG_VXLAN)
970 0 : zlog_debug(
971 : "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
972 : ifp->name, ifp->ifindex, vni);
973 :
974 : /* associate with vxlan_if */
975 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
976 0 : zl3vni->vxlan_if = ifp;
977 :
978 : /*
979 : * we need to associate with SVI.
980 : * we can associate with svi-if only after association
981 : * with vxlan-intf is complete
982 : */
983 0 : zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
984 :
985 : /* Associate l3vni to mac-vlan and extract VRR MAC */
986 0 : zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
987 :
988 0 : if (IS_ZEBRA_DEBUG_VXLAN)
989 0 : zlog_debug("create l3vni %u svi_if %s mac_vlan_if %s",
990 : vni, zl3vni->svi_if ? zl3vni->svi_if->name
991 : : "NIL",
992 : zl3vni->mac_vlan_if ?
993 : zl3vni->mac_vlan_if->name : "NIL");
994 :
995 0 : if (is_l3vni_oper_up(zl3vni))
996 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
997 :
998 : } else {
999 0 : struct interface *vlan_if = NULL;
1000 :
1001 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1002 0 : zlog_debug(
1003 : "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %pI4",
1004 : ifp->name, ifp->ifindex, vni,
1005 : &vxl->vtep_ip);
1006 :
1007 : /* EVPN hash entry is expected to exist, if the BGP process is killed */
1008 0 : zevpn = zebra_evpn_lookup(vni);
1009 0 : if (zevpn) {
1010 0 : zlog_debug(
1011 : "EVPN hash already present for IF %s(%u) L2-VNI %u",
1012 : ifp->name, ifp->ifindex, vni);
1013 :
1014 : /*
1015 : * Inform BGP if intf is up and mapped to
1016 : * bridge.
1017 : */
1018 0 : if (if_is_operative(ifp) &&
1019 0 : zif->brslave_info.br_if)
1020 0 : zebra_evpn_send_add_to_client(zevpn);
1021 :
1022 : /* Send Local MAC-entries to client */
1023 0 : zebra_evpn_send_mac_list_to_client(zevpn);
1024 :
1025 : /* Send Loval Neighbor entries to client */
1026 0 : zebra_evpn_send_neigh_to_client(zevpn);
1027 : } else {
1028 0 : zevpn = zebra_evpn_add(vni);
1029 0 : if (!zevpn) {
1030 0 : zlog_debug(
1031 : "Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
1032 : ifp->name, ifp->ifindex, vni);
1033 0 : return NS_WALK_CONTINUE;
1034 : }
1035 :
1036 0 : if (zevpn->local_vtep_ip.s_addr !=
1037 0 : vxl->vtep_ip.s_addr ||
1038 0 : zevpn->mcast_grp.s_addr !=
1039 0 : vxl->mcast_grp.s_addr) {
1040 0 : zebra_vxlan_sg_deref(
1041 : zevpn->local_vtep_ip,
1042 : zevpn->mcast_grp);
1043 0 : zebra_vxlan_sg_ref(vxl->vtep_ip,
1044 : vxl->mcast_grp);
1045 0 : zevpn->local_vtep_ip = vxl->vtep_ip;
1046 0 : zevpn->mcast_grp = vxl->mcast_grp;
1047 : /* on local vtep-ip check if ES
1048 : * orig-ip needs to be updated
1049 : */
1050 0 : zebra_evpn_es_set_base_evpn(zevpn);
1051 : }
1052 0 : zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
1053 0 : vlan_if = zvni_map_to_svi(
1054 0 : vxl->access_vlan,
1055 : zif->brslave_info.br_if);
1056 0 : if (vlan_if) {
1057 0 : zevpn->svi_if = vlan_if;
1058 0 : zevpn->vrf_id = vlan_if->vrf->vrf_id;
1059 0 : zl3vni = zl3vni_from_vrf(
1060 : vlan_if->vrf->vrf_id);
1061 0 : if (zl3vni)
1062 0 : listnode_add_sort(
1063 : zl3vni->l2vnis, zevpn);
1064 : }
1065 :
1066 : /*
1067 : * Inform BGP if intf is up and mapped to
1068 : * bridge.
1069 : */
1070 0 : if (if_is_operative(ifp) &&
1071 0 : zif->brslave_info.br_if)
1072 0 : zebra_evpn_send_add_to_client(zevpn);
1073 : }
1074 : }
1075 : }
1076 : return NS_WALK_CONTINUE;
1077 : }
1078 :
1079 : /*
1080 : * Build the VNI hash table by going over the VxLAN interfaces. This
1081 : * is called when EVPN (advertise-all-vni) is enabled.
1082 : */
1083 :
1084 0 : static void zevpn_build_hash_table(void)
1085 : {
1086 0 : ns_walk_func(zevpn_build_hash_table_zns, NULL, NULL);
1087 : }
1088 :
1089 : /*
1090 : * Cleanup EVPN/VTEP and update kernel
1091 : */
1092 0 : static void zebra_evpn_vxlan_cleanup_all(struct hash_bucket *bucket, void *arg)
1093 : {
1094 0 : struct zebra_evpn *zevpn = NULL;
1095 0 : struct zebra_l3vni *zl3vni = NULL;
1096 :
1097 0 : zevpn = (struct zebra_evpn *)bucket->data;
1098 :
1099 : /* remove l2vni from l2vni's tenant-vrf l3-vni list */
1100 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
1101 0 : if (zl3vni)
1102 0 : listnode_delete(zl3vni->l2vnis, zevpn);
1103 :
1104 0 : zebra_evpn_cleanup_all(bucket, arg);
1105 0 : }
1106 :
1107 : /* cleanup L3VNI */
1108 0 : static void zl3vni_cleanup_all(struct hash_bucket *bucket, void *args)
1109 : {
1110 0 : struct zebra_l3vni *zl3vni = NULL;
1111 :
1112 0 : zl3vni = (struct zebra_l3vni *)bucket->data;
1113 :
1114 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
1115 0 : }
1116 :
1117 0 : static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
1118 : const struct prefix *host)
1119 : {
1120 0 : struct host_rb_entry lookup;
1121 0 : struct host_rb_entry *hle;
1122 :
1123 0 : memset(&lookup, 0, sizeof(lookup));
1124 0 : memcpy(&lookup.p, host, sizeof(*host));
1125 :
1126 0 : hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1127 0 : if (hle)
1128 0 : return;
1129 :
1130 0 : hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
1131 0 : memcpy(hle, &lookup, sizeof(lookup));
1132 :
1133 0 : RB_INSERT(host_rb_tree_entry, hrbe, hle);
1134 : }
1135 :
1136 0 : static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
1137 : {
1138 0 : struct host_rb_entry lookup;
1139 0 : struct host_rb_entry *hle;
1140 :
1141 0 : memset(&lookup, 0, sizeof(lookup));
1142 0 : memcpy(&lookup.p, host, sizeof(*host));
1143 :
1144 0 : hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1145 0 : if (hle) {
1146 0 : RB_REMOVE(host_rb_tree_entry, hrbe, hle);
1147 0 : XFREE(MTYPE_HOST_PREFIX, hle);
1148 : }
1149 :
1150 0 : return;
1151 : }
1152 :
1153 : /*
1154 : * Look up MAC hash entry.
1155 : */
1156 0 : static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
1157 : const struct ethaddr *rmac)
1158 : {
1159 0 : struct zebra_mac tmp;
1160 0 : struct zebra_mac *pmac;
1161 :
1162 0 : memset(&tmp, 0, sizeof(tmp));
1163 0 : memcpy(&tmp.macaddr, rmac, ETH_ALEN);
1164 0 : pmac = hash_lookup(zl3vni->rmac_table, &tmp);
1165 :
1166 0 : return pmac;
1167 : }
1168 :
1169 : /*
1170 : * Callback to allocate RMAC hash entry.
1171 : */
1172 0 : static void *zl3vni_rmac_alloc(void *p)
1173 : {
1174 0 : const struct zebra_mac *tmp_rmac = p;
1175 0 : struct zebra_mac *zrmac;
1176 :
1177 0 : zrmac = XCALLOC(MTYPE_L3VNI_MAC, sizeof(struct zebra_mac));
1178 0 : *zrmac = *tmp_rmac;
1179 :
1180 0 : return ((void *)zrmac);
1181 : }
1182 :
1183 : /*
1184 : * Add RMAC entry to l3-vni
1185 : */
1186 0 : static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
1187 : const struct ethaddr *rmac)
1188 : {
1189 0 : struct zebra_mac tmp_rmac;
1190 0 : struct zebra_mac *zrmac = NULL;
1191 :
1192 0 : memset(&tmp_rmac, 0, sizeof(tmp_rmac));
1193 0 : memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
1194 0 : zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
1195 0 : zrmac->nh_list = list_new();
1196 0 : zrmac->nh_list->cmp = (int (*)(void *, void *))l3vni_rmac_nh_list_cmp;
1197 0 : zrmac->nh_list->del = (void (*)(void *))l3vni_rmac_nh_free;
1198 :
1199 0 : SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
1200 0 : SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
1201 :
1202 0 : return zrmac;
1203 : }
1204 :
1205 : /*
1206 : * Delete MAC entry.
1207 : */
1208 0 : static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac)
1209 : {
1210 0 : struct zebra_mac *tmp_rmac;
1211 :
1212 : /* free the list of nh list*/
1213 0 : list_delete(&zrmac->nh_list);
1214 :
1215 0 : tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
1216 0 : XFREE(MTYPE_L3VNI_MAC, tmp_rmac);
1217 :
1218 0 : return 0;
1219 : }
1220 :
1221 : /*
1222 : * Install remote RMAC into the forwarding plane.
1223 : */
1224 0 : static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
1225 : struct zebra_mac *zrmac)
1226 : {
1227 0 : const struct zebra_if *zif = NULL, *br_zif = NULL;
1228 0 : const struct zebra_l2info_vxlan *vxl = NULL;
1229 0 : const struct interface *br_ifp;
1230 0 : enum zebra_dplane_result res;
1231 0 : vlanid_t vid;
1232 :
1233 0 : if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1234 0 : || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1235 : return 0;
1236 :
1237 0 : zif = zl3vni->vxlan_if->info;
1238 0 : if (!zif)
1239 : return -1;
1240 :
1241 0 : br_ifp = zif->brslave_info.br_if;
1242 0 : if (br_ifp == NULL)
1243 : return -1;
1244 :
1245 0 : vxl = &zif->l2info.vxl;
1246 :
1247 0 : br_zif = (const struct zebra_if *)br_ifp->info;
1248 :
1249 0 : if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1250 0 : vid = vxl->access_vlan;
1251 : else
1252 : vid = 0;
1253 :
1254 0 : res = dplane_rem_mac_add(zl3vni->vxlan_if, br_ifp, vid,
1255 0 : &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0, 0,
1256 : false /*was_static*/);
1257 0 : if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1258 : return 0;
1259 : else
1260 : return -1;
1261 : }
1262 :
1263 : /*
1264 : * Uninstall remote RMAC from the forwarding plane.
1265 : */
1266 0 : static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
1267 : struct zebra_mac *zrmac)
1268 : {
1269 0 : const struct zebra_if *zif = NULL, *br_zif;
1270 0 : const struct zebra_l2info_vxlan *vxl = NULL;
1271 0 : const struct interface *br_ifp;
1272 0 : vlanid_t vid;
1273 0 : enum zebra_dplane_result res;
1274 :
1275 0 : if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1276 0 : || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1277 : return 0;
1278 :
1279 0 : if (!zl3vni->vxlan_if) {
1280 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1281 0 : zlog_debug(
1282 : "RMAC %pEA on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
1283 : &zrmac->macaddr, zl3vni->vni, zl3vni);
1284 0 : return -1;
1285 : }
1286 :
1287 0 : zif = zl3vni->vxlan_if->info;
1288 0 : if (!zif)
1289 : return -1;
1290 :
1291 0 : br_ifp = zif->brslave_info.br_if;
1292 0 : if (br_ifp == NULL)
1293 : return -1;
1294 :
1295 0 : vxl = &zif->l2info.vxl;
1296 :
1297 0 : br_zif = (const struct zebra_if *)br_ifp->info;
1298 0 : if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1299 0 : vid = vxl->access_vlan;
1300 : else
1301 : vid = 0;
1302 :
1303 0 : res = dplane_rem_mac_del(zl3vni->vxlan_if, br_ifp, vid,
1304 0 : &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
1305 0 : if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1306 : return 0;
1307 : else
1308 : return -1;
1309 : }
1310 :
1311 : /* handle rmac add */
1312 0 : static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
1313 : const struct ethaddr *rmac,
1314 : const struct ipaddr *vtep_ip)
1315 : {
1316 0 : struct zebra_mac *zrmac = NULL;
1317 0 : struct ipaddr *vtep = NULL;
1318 :
1319 0 : zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
1320 0 : if (!zrmac) {
1321 :
1322 : /* Create the RMAC entry, or update its vtep, if necessary. */
1323 0 : zrmac = zl3vni_rmac_add(zl3vni, rmac);
1324 0 : if (!zrmac) {
1325 0 : zlog_debug(
1326 : "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA",
1327 : rmac, zl3vni->vni, vtep_ip);
1328 0 : return -1;
1329 : }
1330 0 : memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
1331 0 : zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1332 :
1333 0 : vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1334 0 : memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1335 0 : if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1336 0 : XFREE(MTYPE_EVPN_VTEP, vtep);
1337 :
1338 : /* Send RMAC for FPM processing */
1339 0 : hook_call(zebra_rmac_update, zrmac, zl3vni, false,
1340 : "new RMAC added");
1341 :
1342 : /* install rmac in kernel */
1343 0 : zl3vni_rmac_install(zl3vni, zrmac);
1344 0 : } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1345 : &vtep_ip->ipaddr_v4)) {
1346 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1347 0 : zlog_debug(
1348 : "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA",
1349 : zl3vni->vni, &zrmac->fwd_info.r_vtep_ip,
1350 : vtep_ip, rmac);
1351 :
1352 0 : zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1353 :
1354 0 : vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1355 0 : memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1356 0 : if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1357 0 : XFREE(MTYPE_EVPN_VTEP, vtep);
1358 :
1359 : /* install rmac in kernel */
1360 0 : zl3vni_rmac_install(zl3vni, zrmac);
1361 : }
1362 :
1363 : return 0;
1364 : }
1365 :
1366 :
1367 : /* handle rmac delete */
1368 0 : static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
1369 : struct zebra_mac *zrmac,
1370 : struct ipaddr *vtep_ip)
1371 : {
1372 0 : struct ipaddr ipv4_vtep;
1373 :
1374 0 : if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) {
1375 0 : memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
1376 0 : ipv4_vtep.ipa_type = IPADDR_V4;
1377 0 : if (vtep_ip->ipa_type == IPADDR_V6)
1378 0 : ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
1379 : &ipv4_vtep.ipaddr_v4);
1380 : else
1381 0 : memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
1382 : sizeof(struct in_addr));
1383 :
1384 : /* remove nh from rmac's list */
1385 0 : l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep);
1386 : /* delete nh is same as current selected, fall back to
1387 : * one present in the list
1388 : */
1389 0 : if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1390 0 : &ipv4_vtep.ipaddr_v4) &&
1391 0 : listcount(zrmac->nh_list)) {
1392 0 : struct ipaddr *vtep;
1393 :
1394 0 : vtep = listgetdata(listhead(zrmac->nh_list));
1395 0 : zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4;
1396 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1397 0 : zlog_debug(
1398 : "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
1399 : zl3vni->vni, &ipv4_vtep,
1400 : &zrmac->fwd_info.r_vtep_ip,
1401 : &zrmac->macaddr);
1402 :
1403 : /* install rmac in kernel */
1404 0 : zl3vni_rmac_install(zl3vni, zrmac);
1405 : }
1406 :
1407 0 : if (!listcount(zrmac->nh_list)) {
1408 : /* uninstall from kernel */
1409 0 : zl3vni_rmac_uninstall(zl3vni, zrmac);
1410 :
1411 : /* Send RMAC for FPM processing */
1412 0 : hook_call(zebra_rmac_update, zrmac, zl3vni, true,
1413 : "RMAC deleted");
1414 :
1415 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1416 0 : zlog_debug(
1417 : "L3VNI %u RMAC %pEA vtep_ip %pIA delete",
1418 : zl3vni->vni, &zrmac->macaddr, vtep_ip);
1419 :
1420 : /* del the rmac entry */
1421 0 : zl3vni_rmac_del(zl3vni, zrmac);
1422 : }
1423 : }
1424 0 : }
1425 :
1426 : /*
1427 : * Look up nh hash entry on a l3-vni.
1428 : */
1429 0 : static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
1430 : const struct ipaddr *ip)
1431 : {
1432 0 : struct zebra_neigh tmp;
1433 0 : struct zebra_neigh *n;
1434 :
1435 0 : memset(&tmp, 0, sizeof(tmp));
1436 0 : memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
1437 0 : n = hash_lookup(zl3vni->nh_table, &tmp);
1438 :
1439 0 : return n;
1440 : }
1441 :
1442 :
1443 : /*
1444 : * Callback to allocate NH hash entry on L3-VNI.
1445 : */
1446 0 : static void *zl3vni_nh_alloc(void *p)
1447 : {
1448 0 : const struct zebra_neigh *tmp_n = p;
1449 0 : struct zebra_neigh *n;
1450 :
1451 0 : n = XCALLOC(MTYPE_L3NEIGH, sizeof(struct zebra_neigh));
1452 0 : *n = *tmp_n;
1453 :
1454 0 : return ((void *)n);
1455 : }
1456 :
1457 : /*
1458 : * Add neighbor entry.
1459 : */
1460 0 : static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
1461 : const struct ipaddr *ip,
1462 : const struct ethaddr *mac)
1463 : {
1464 0 : struct zebra_neigh tmp_n;
1465 0 : struct zebra_neigh *n = NULL;
1466 :
1467 0 : memset(&tmp_n, 0, sizeof(tmp_n));
1468 0 : memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
1469 0 : n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
1470 :
1471 0 : RB_INIT(host_rb_tree_entry, &n->host_rb);
1472 :
1473 0 : memcpy(&n->emac, mac, ETH_ALEN);
1474 0 : SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1475 0 : SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
1476 :
1477 0 : return n;
1478 : }
1479 :
1480 : /*
1481 : * Delete neighbor entry.
1482 : */
1483 0 : static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1484 : {
1485 0 : struct zebra_neigh *tmp_n;
1486 0 : struct host_rb_entry *hle;
1487 :
1488 0 : while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
1489 0 : hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
1490 :
1491 0 : RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
1492 0 : XFREE(MTYPE_HOST_PREFIX, hle);
1493 : }
1494 :
1495 0 : tmp_n = hash_release(zl3vni->nh_table, n);
1496 0 : XFREE(MTYPE_L3NEIGH, tmp_n);
1497 :
1498 0 : return 0;
1499 : }
1500 :
1501 : /*
1502 : * Install remote nh as neigh into the kernel.
1503 : */
1504 0 : static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1505 : {
1506 0 : uint8_t flags;
1507 0 : int ret = 0;
1508 :
1509 0 : if (!is_l3vni_oper_up(zl3vni))
1510 : return -1;
1511 :
1512 0 : if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1513 0 : || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1514 : return 0;
1515 :
1516 0 : flags = DPLANE_NTF_EXT_LEARNED;
1517 0 : if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
1518 0 : flags |= DPLANE_NTF_ROUTER;
1519 :
1520 0 : dplane_rem_neigh_add(zl3vni->svi_if, &n->ip, &n->emac, flags,
1521 : false /*was_static*/);
1522 :
1523 0 : return ret;
1524 : }
1525 :
1526 : /*
1527 : * Uninstall remote nh from the kernel.
1528 : */
1529 0 : static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
1530 : struct zebra_neigh *n)
1531 : {
1532 0 : if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1533 0 : || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1534 : return 0;
1535 :
1536 0 : if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
1537 0 : return 0;
1538 :
1539 0 : dplane_rem_neigh_delete(zl3vni->svi_if, &n->ip);
1540 :
1541 0 : return 0;
1542 : }
1543 :
1544 : /* add remote vtep as a neigh entry */
1545 0 : static int zl3vni_remote_nh_add(struct zebra_l3vni *zl3vni,
1546 : const struct ipaddr *vtep_ip,
1547 : const struct ethaddr *rmac,
1548 : const struct prefix *host_prefix)
1549 : {
1550 0 : struct zebra_neigh *nh = NULL;
1551 :
1552 : /* Create the next hop entry, or update its mac, if necessary. */
1553 0 : nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
1554 0 : if (!nh) {
1555 0 : nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
1556 0 : if (!nh) {
1557 0 : zlog_debug(
1558 : "Failed to add NH %pIA as Neigh (RMAC %pEA L3-VNI %u prefix %pFX)",
1559 : vtep_ip, rmac, zl3vni->vni, host_prefix);
1560 0 : return -1;
1561 : }
1562 :
1563 : /* install the nh neigh in kernel */
1564 0 : zl3vni_nh_install(zl3vni, nh);
1565 0 : } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
1566 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1567 0 : zlog_debug(
1568 : "L3VNI %u RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX",
1569 : zl3vni->vni, &nh->emac, rmac, vtep_ip,
1570 : host_prefix);
1571 :
1572 0 : memcpy(&nh->emac, rmac, ETH_ALEN);
1573 : /* install (update) the nh neigh in kernel */
1574 0 : zl3vni_nh_install(zl3vni, nh);
1575 : }
1576 :
1577 0 : rb_find_or_add_host(&nh->host_rb, host_prefix);
1578 :
1579 0 : return 0;
1580 : }
1581 :
1582 : /* handle nh neigh delete */
1583 0 : static void zl3vni_remote_nh_del(struct zebra_l3vni *zl3vni,
1584 : struct zebra_neigh *nh,
1585 : struct prefix *host_prefix)
1586 : {
1587 0 : rb_delete_host(&nh->host_rb, host_prefix);
1588 :
1589 0 : if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
1590 : /* uninstall from kernel */
1591 0 : zl3vni_nh_uninstall(zl3vni, nh);
1592 :
1593 : /* delete the nh entry */
1594 0 : zl3vni_nh_del(zl3vni, nh);
1595 : }
1596 0 : }
1597 :
1598 : /* handle neigh update from kernel - the only thing of interest is to
1599 : * readd stale entries.
1600 : */
1601 0 : static int zl3vni_local_nh_add_update(struct zebra_l3vni *zl3vni,
1602 : struct ipaddr *ip, uint16_t state)
1603 : {
1604 : #ifdef GNU_LINUX
1605 0 : struct zebra_neigh *n = NULL;
1606 :
1607 0 : n = zl3vni_nh_lookup(zl3vni, ip);
1608 0 : if (!n)
1609 : return 0;
1610 :
1611 : /* all next hop neigh are remote and installed by frr.
1612 : * If the kernel has aged this entry, re-install.
1613 : */
1614 0 : if (state & NUD_STALE)
1615 0 : zl3vni_nh_install(zl3vni, n);
1616 : #endif
1617 : return 0;
1618 : }
1619 :
1620 : /* handle neigh delete from kernel */
1621 0 : static int zl3vni_local_nh_del(struct zebra_l3vni *zl3vni, struct ipaddr *ip)
1622 : {
1623 0 : struct zebra_neigh *n = NULL;
1624 :
1625 0 : n = zl3vni_nh_lookup(zl3vni, ip);
1626 0 : if (!n)
1627 : return 0;
1628 :
1629 : /* all next hop neigh are remote and installed by frr.
1630 : * If we get an age out notification for these neigh entries, we have to
1631 : * install it back
1632 : */
1633 0 : zl3vni_nh_install(zl3vni, n);
1634 :
1635 0 : return 0;
1636 : }
1637 :
1638 : /*
1639 : * Hash function for L3 VNI.
1640 : */
1641 0 : static unsigned int l3vni_hash_keymake(const void *p)
1642 : {
1643 0 : const struct zebra_l3vni *zl3vni = p;
1644 :
1645 0 : return jhash_1word(zl3vni->vni, 0);
1646 : }
1647 :
1648 : /*
1649 : * Compare 2 L3 VNI hash entries.
1650 : */
1651 0 : static bool l3vni_hash_cmp(const void *p1, const void *p2)
1652 : {
1653 0 : const struct zebra_l3vni *zl3vni1 = p1;
1654 0 : const struct zebra_l3vni *zl3vni2 = p2;
1655 :
1656 0 : return (zl3vni1->vni == zl3vni2->vni);
1657 : }
1658 :
1659 : /*
1660 : * Callback to allocate L3 VNI hash entry.
1661 : */
1662 0 : static void *zl3vni_alloc(void *p)
1663 : {
1664 0 : struct zebra_l3vni *zl3vni = NULL;
1665 0 : const struct zebra_l3vni *tmp_l3vni = p;
1666 :
1667 0 : zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(struct zebra_l3vni));
1668 0 : zl3vni->vni = tmp_l3vni->vni;
1669 0 : return ((void *)zl3vni);
1670 : }
1671 :
1672 : /*
1673 : * Look up L3 VNI hash entry.
1674 : */
1675 0 : struct zebra_l3vni *zl3vni_lookup(vni_t vni)
1676 : {
1677 0 : struct zebra_l3vni tmp_l3vni;
1678 0 : struct zebra_l3vni *zl3vni = NULL;
1679 :
1680 0 : memset(&tmp_l3vni, 0, sizeof(tmp_l3vni));
1681 0 : tmp_l3vni.vni = vni;
1682 0 : zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
1683 :
1684 0 : return zl3vni;
1685 : }
1686 :
1687 : /*
1688 : * Add L3 VNI hash entry.
1689 : */
1690 0 : static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
1691 : {
1692 0 : struct zebra_l3vni tmp_zl3vni;
1693 0 : struct zebra_l3vni *zl3vni = NULL;
1694 :
1695 0 : memset(&tmp_zl3vni, 0, sizeof(tmp_zl3vni));
1696 0 : tmp_zl3vni.vni = vni;
1697 :
1698 0 : zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
1699 :
1700 0 : zl3vni->vrf_id = vrf_id;
1701 0 : zl3vni->svi_if = NULL;
1702 0 : zl3vni->vxlan_if = NULL;
1703 0 : zl3vni->l2vnis = list_new();
1704 0 : zl3vni->l2vnis->cmp = zebra_evpn_list_cmp;
1705 :
1706 : /* Create hash table for remote RMAC */
1707 0 : zl3vni->rmac_table = zebra_mac_db_create("Zebra L3-VNI RMAC-Table");
1708 :
1709 : /* Create hash table for neighbors */
1710 0 : zl3vni->nh_table = zebra_neigh_db_create("Zebra L3-VNI next-hop table");
1711 :
1712 0 : return zl3vni;
1713 : }
1714 :
1715 : /*
1716 : * Delete L3 VNI hash entry.
1717 : */
1718 0 : static int zl3vni_del(struct zebra_l3vni *zl3vni)
1719 : {
1720 0 : struct zebra_l3vni *tmp_zl3vni;
1721 :
1722 : /* free the list of l2vnis */
1723 0 : list_delete(&zl3vni->l2vnis);
1724 0 : zl3vni->l2vnis = NULL;
1725 :
1726 : /* Free the rmac table */
1727 0 : hash_free(zl3vni->rmac_table);
1728 0 : zl3vni->rmac_table = NULL;
1729 :
1730 : /* Free the nh table */
1731 0 : hash_free(zl3vni->nh_table);
1732 0 : zl3vni->nh_table = NULL;
1733 :
1734 : /* Free the VNI hash entry and allocated memory. */
1735 0 : tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
1736 0 : XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
1737 :
1738 0 : return 0;
1739 : }
1740 :
1741 0 : static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
1742 : void *_zl3vni,
1743 : void **_pifp)
1744 : {
1745 0 : struct zebra_ns *zns = ns->info;
1746 0 : struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)_zl3vni;
1747 0 : struct route_node *rn = NULL;
1748 0 : struct interface *ifp = NULL;
1749 0 : struct zebra_vrf *zvrf;
1750 :
1751 0 : zvrf = zebra_vrf_get_evpn();
1752 :
1753 0 : assert(_pifp);
1754 :
1755 : /* loop through all vxlan-interface */
1756 0 : for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1757 :
1758 0 : struct zebra_if *zif = NULL;
1759 0 : struct zebra_l2info_vxlan *vxl = NULL;
1760 :
1761 0 : ifp = (struct interface *)rn->info;
1762 0 : if (!ifp)
1763 0 : continue;
1764 :
1765 0 : zif = ifp->info;
1766 0 : if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1767 0 : continue;
1768 :
1769 0 : vxl = &zif->l2info.vxl;
1770 0 : if (vxl->vni != zl3vni->vni)
1771 0 : continue;
1772 :
1773 : /* link of VXLAN interface should be in zebra_evpn_vrf */
1774 0 : if (zvrf->zns->ns_id != vxl->link_nsid) {
1775 0 : if (IS_ZEBRA_DEBUG_VXLAN)
1776 0 : zlog_debug(
1777 : "Intf %s(%u) VNI %u, link not in same "
1778 : "namespace than BGP EVPN core instance ",
1779 : ifp->name, ifp->ifindex, vxl->vni);
1780 0 : continue;
1781 : }
1782 :
1783 :
1784 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
1785 0 : *_pifp = (void *)ifp;
1786 0 : return NS_WALK_STOP;
1787 : }
1788 :
1789 : return NS_WALK_CONTINUE;
1790 : }
1791 :
1792 0 : struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
1793 : {
1794 0 : struct interface **p_ifp;
1795 0 : struct interface *ifp = NULL;
1796 :
1797 0 : p_ifp = &ifp;
1798 :
1799 0 : ns_walk_func(zl3vni_map_to_vxlan_if_ns,
1800 : (void *)zl3vni, (void **)p_ifp);
1801 0 : return ifp;
1802 : }
1803 :
1804 0 : struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
1805 : {
1806 0 : struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
1807 0 : struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
1808 :
1809 0 : if (!zl3vni)
1810 : return NULL;
1811 :
1812 0 : if (!zl3vni->vxlan_if)
1813 : return NULL;
1814 :
1815 0 : zif = zl3vni->vxlan_if->info;
1816 0 : if (!zif)
1817 : return NULL;
1818 :
1819 0 : vxl = &zif->l2info.vxl;
1820 :
1821 0 : return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1822 : }
1823 :
1824 0 : struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni)
1825 : {
1826 0 : struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
1827 :
1828 0 : if (!zl3vni)
1829 : return NULL;
1830 :
1831 0 : if (!zl3vni->vxlan_if)
1832 : return NULL;
1833 :
1834 0 : zif = zl3vni->vxlan_if->info;
1835 0 : if (!zif)
1836 : return NULL;
1837 :
1838 0 : return zebra_evpn_map_to_macvlan(zif->brslave_info.br_if,
1839 : zl3vni->svi_if);
1840 : }
1841 :
1842 :
1843 0 : struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id)
1844 : {
1845 0 : struct zebra_vrf *zvrf = NULL;
1846 :
1847 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
1848 0 : if (!zvrf)
1849 : return NULL;
1850 :
1851 0 : return zl3vni_lookup(zvrf->l3vni);
1852 : }
1853 :
1854 0 : static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
1855 : {
1856 0 : struct zebra_ns *zns = ns->info;
1857 0 : struct zebra_l3vni **p_zl3vni = (struct zebra_l3vni **)_p_zl3vni;
1858 0 : struct zebra_from_svi_param *in_param =
1859 : (struct zebra_from_svi_param *)_in_param;
1860 0 : struct route_node *rn = NULL;
1861 0 : struct interface *tmp_if = NULL;
1862 0 : struct zebra_if *zif = NULL;
1863 0 : struct zebra_l2info_vxlan *vxl = NULL;
1864 :
1865 0 : assert(in_param && p_zl3vni);
1866 :
1867 : /* loop through all vxlan-interface */
1868 0 : for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1869 0 : tmp_if = (struct interface *)rn->info;
1870 0 : if (!tmp_if)
1871 0 : continue;
1872 0 : zif = tmp_if->info;
1873 0 : if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1874 0 : continue;
1875 0 : if (!if_is_operative(tmp_if))
1876 0 : continue;
1877 0 : vxl = &zif->l2info.vxl;
1878 :
1879 0 : if (zif->brslave_info.br_if != in_param->br_if)
1880 0 : continue;
1881 :
1882 0 : if (!in_param->bridge_vlan_aware
1883 0 : || vxl->access_vlan == in_param->vid) {
1884 0 : *p_zl3vni = zl3vni_lookup(vxl->vni);
1885 0 : return NS_WALK_STOP;
1886 : }
1887 : }
1888 :
1889 : return NS_WALK_CONTINUE;
1890 : }
1891 :
1892 : /*
1893 : * Map SVI and associated bridge to a VNI. This is invoked upon getting
1894 : * neighbor notifications, to see if they are of interest.
1895 : */
1896 0 : static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
1897 : struct interface *br_if)
1898 : {
1899 0 : struct zebra_l3vni *zl3vni = NULL;
1900 0 : struct zebra_if *zif = NULL;
1901 0 : struct zebra_l2info_bridge *br = NULL;
1902 0 : struct zebra_from_svi_param in_param = {};
1903 0 : struct zebra_l3vni **p_zl3vni;
1904 :
1905 0 : if (!br_if)
1906 : return NULL;
1907 :
1908 : /* Make sure the linked interface is a bridge. */
1909 0 : if (!IS_ZEBRA_IF_BRIDGE(br_if))
1910 : return NULL;
1911 0 : in_param.br_if = br_if;
1912 :
1913 : /* Determine if bridge is VLAN-aware or not */
1914 0 : zif = br_if->info;
1915 0 : assert(zif);
1916 0 : br = &zif->l2info.br;
1917 0 : in_param.bridge_vlan_aware = br->vlan_aware;
1918 0 : if (in_param.bridge_vlan_aware) {
1919 0 : struct zebra_l2info_vlan *vl;
1920 :
1921 0 : if (!IS_ZEBRA_IF_VLAN(ifp))
1922 : return NULL;
1923 :
1924 0 : zif = ifp->info;
1925 0 : assert(zif);
1926 0 : vl = &zif->l2info.vl;
1927 0 : in_param.vid = vl->vid;
1928 : }
1929 :
1930 : /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1931 : /* TODO: Optimize with a hash. */
1932 :
1933 0 : p_zl3vni = &zl3vni;
1934 :
1935 0 : ns_walk_func(zl3vni_from_svi_ns, (void *)&in_param, (void **)p_zl3vni);
1936 0 : return zl3vni;
1937 : }
1938 :
1939 0 : vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if)
1940 : {
1941 0 : vni_t vni = 0;
1942 0 : struct zebra_evpn *zevpn = NULL;
1943 0 : struct zebra_l3vni *zl3vni = NULL;
1944 :
1945 : /* Check if an L3VNI belongs to this SVI interface.
1946 : * If not, check if an L2VNI belongs to this SVI interface.
1947 : */
1948 0 : zl3vni = zl3vni_from_svi(ifp, br_if);
1949 0 : if (zl3vni)
1950 0 : vni = zl3vni->vni;
1951 : else {
1952 0 : zevpn = zebra_evpn_from_svi(ifp, br_if);
1953 0 : if (zevpn)
1954 0 : vni = zevpn->vni;
1955 : }
1956 :
1957 0 : return vni;
1958 : }
1959 :
1960 0 : static inline void zl3vni_get_vrr_rmac(struct zebra_l3vni *zl3vni,
1961 : struct ethaddr *rmac)
1962 : {
1963 0 : if (!zl3vni)
1964 : return;
1965 :
1966 0 : if (!is_l3vni_oper_up(zl3vni))
1967 : return;
1968 :
1969 0 : if (zl3vni->mac_vlan_if && if_is_operative(zl3vni->mac_vlan_if))
1970 0 : memcpy(rmac->octet, zl3vni->mac_vlan_if->hw_addr, ETH_ALEN);
1971 : }
1972 :
1973 : /*
1974 : * Inform BGP about l3-vni.
1975 : */
1976 0 : static int zl3vni_send_add_to_client(struct zebra_l3vni *zl3vni)
1977 : {
1978 0 : struct stream *s = NULL;
1979 0 : struct zserv *client = NULL;
1980 0 : struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
1981 0 : struct zebra_vrf *zvrf;
1982 0 : bool is_anycast_mac = true;
1983 :
1984 0 : client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
1985 : /* BGP may not be running. */
1986 0 : if (!client)
1987 : return 0;
1988 :
1989 0 : zvrf = zebra_vrf_lookup_by_id(zl3vni->vrf_id);
1990 0 : assert(zvrf);
1991 :
1992 : /* get the svi and vrr rmac values */
1993 0 : memset(&svi_rmac, 0, sizeof(svi_rmac));
1994 0 : zl3vni_get_svi_rmac(zl3vni, &svi_rmac);
1995 0 : zl3vni_get_vrr_rmac(zl3vni, &vrr_rmac);
1996 :
1997 : /* In absence of vrr mac use svi mac as anycast MAC value */
1998 0 : if (is_zero_mac(&vrr_rmac)) {
1999 0 : memcpy(&vrr_rmac, &svi_rmac, ETH_ALEN);
2000 0 : is_anycast_mac = false;
2001 : }
2002 :
2003 0 : s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2004 :
2005 : /* The message is used for both vni add and/or update like
2006 : * vrr mac is added for l3vni SVI.
2007 : */
2008 0 : zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
2009 0 : stream_putl(s, zl3vni->vni);
2010 0 : stream_put(s, &svi_rmac, sizeof(struct ethaddr));
2011 0 : stream_put_in_addr(s, &zl3vni->local_vtep_ip);
2012 0 : stream_put(s, &zl3vni->filter, sizeof(int));
2013 0 : stream_putl(s, zl3vni->svi_if->ifindex);
2014 0 : stream_put(s, &vrr_rmac, sizeof(struct ethaddr));
2015 0 : stream_putl(s, is_anycast_mac);
2016 :
2017 : /* Write packet size. */
2018 0 : stream_putw_at(s, 0, stream_get_endp(s));
2019 :
2020 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2021 0 : zlog_debug(
2022 : "Send L3_VNI_ADD %u VRF %s RMAC %pEA VRR %pEA local-ip %pI4 filter %s to %s",
2023 : zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2024 : &svi_rmac, &vrr_rmac, &zl3vni->local_vtep_ip,
2025 : CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
2026 : ? "prefix-routes-only"
2027 : : "none",
2028 : zebra_route_string(client->proto));
2029 :
2030 0 : client->l3vniadd_cnt++;
2031 0 : return zserv_send_message(client, s);
2032 : }
2033 :
2034 : /*
2035 : * Inform BGP about local l3-VNI deletion.
2036 : */
2037 0 : static int zl3vni_send_del_to_client(struct zebra_l3vni *zl3vni)
2038 : {
2039 0 : struct stream *s = NULL;
2040 0 : struct zserv *client = NULL;
2041 :
2042 0 : client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
2043 : /* BGP may not be running. */
2044 0 : if (!client)
2045 : return 0;
2046 :
2047 0 : s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2048 :
2049 0 : zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
2050 0 : stream_putl(s, zl3vni->vni);
2051 :
2052 : /* Write packet size. */
2053 0 : stream_putw_at(s, 0, stream_get_endp(s));
2054 :
2055 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2056 0 : zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
2057 : vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2058 : zebra_route_string(client->proto));
2059 :
2060 0 : client->l3vnidel_cnt++;
2061 0 : return zserv_send_message(client, s);
2062 : }
2063 :
2064 0 : static void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni)
2065 : {
2066 0 : if (!zl3vni)
2067 : return;
2068 :
2069 : /* send l3vni add to BGP */
2070 0 : zl3vni_send_add_to_client(zl3vni);
2071 : }
2072 :
2073 0 : static void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni)
2074 : {
2075 0 : if (!zl3vni)
2076 : return;
2077 :
2078 : /* send l3-vni del to BGP*/
2079 0 : zl3vni_send_del_to_client(zl3vni);
2080 : }
2081 :
2082 0 : static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
2083 : {
2084 0 : struct zebra_evpn *zevpn = (struct zebra_evpn *)bucket->data;
2085 0 : struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)ctxt;
2086 :
2087 0 : if (zevpn->vrf_id == zl3vni_vrf_id(zl3vni))
2088 0 : listnode_add_sort(zl3vni->l2vnis, zevpn);
2089 0 : }
2090 :
2091 : /*
2092 : * Handle transition of vni from l2 to l3 and vice versa.
2093 : * This function handles only the L2VNI add/delete part of
2094 : * the above transition.
2095 : * L3VNI add/delete is handled by the calling functions.
2096 : */
2097 0 : static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
2098 : int add)
2099 : {
2100 0 : struct zebra_evpn *zevpn = NULL;
2101 0 : struct zebra_l3vni *zl3vni = NULL;
2102 :
2103 : /* There is a possibility that VNI notification was already received
2104 : * from kernel and we programmed it as L2-VNI
2105 : * In such a case we need to delete this L2-VNI first, so
2106 : * that it can be reprogrammed as L3-VNI in the system. It is also
2107 : * possible that the vrf-vni mapping is removed from FRR while the vxlan
2108 : * interface is still present in kernel. In this case to keep it
2109 : * symmetric, we will delete the l3-vni and reprogram it as l2-vni
2110 : */
2111 0 : if (add) {
2112 : /* Locate hash entry */
2113 0 : zevpn = zebra_evpn_lookup(vni);
2114 0 : if (!zevpn)
2115 : return 0;
2116 :
2117 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2118 0 : zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
2119 :
2120 : /* Delete EVPN from BGP. */
2121 0 : zebra_evpn_send_del_to_client(zevpn);
2122 :
2123 0 : zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
2124 0 : zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
2125 :
2126 : /* Free up all remote VTEPs, if any. */
2127 0 : zebra_evpn_vtep_del_all(zevpn, 1);
2128 :
2129 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
2130 0 : if (zl3vni)
2131 0 : listnode_delete(zl3vni->l2vnis, zevpn);
2132 :
2133 : /* Delete the hash entry. */
2134 0 : if (zebra_evpn_vxlan_del(zevpn)) {
2135 0 : flog_err(EC_ZEBRA_VNI_DEL_FAILED,
2136 : "Failed to del EVPN hash %p, VNI %u", zevpn,
2137 : zevpn->vni);
2138 0 : return -1;
2139 : }
2140 : } else {
2141 0 : struct zebra_ns *zns;
2142 0 : struct route_node *rn;
2143 0 : struct interface *ifp;
2144 0 : struct zebra_if *zif;
2145 0 : struct zebra_l2info_vxlan *vxl;
2146 0 : struct interface *vlan_if;
2147 0 : bool found = false;
2148 :
2149 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2150 0 : zlog_debug("Adding L2-VNI %u - transition from L3-VNI",
2151 : vni);
2152 :
2153 : /* Find VxLAN interface for this VNI. */
2154 0 : zns = zebra_ns_lookup(NS_DEFAULT);
2155 0 : for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2156 0 : ifp = (struct interface *)rn->info;
2157 0 : if (!ifp)
2158 0 : continue;
2159 0 : zif = ifp->info;
2160 0 : if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2161 0 : continue;
2162 :
2163 0 : vxl = &zif->l2info.vxl;
2164 0 : if (vxl->vni == vni) {
2165 : found = true;
2166 : break;
2167 : }
2168 : }
2169 :
2170 0 : if (!found) {
2171 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2172 0 : zlog_err(
2173 : "Adding L2-VNI - Failed to find VxLAN interface for VNI %u",
2174 : vni);
2175 0 : return -1;
2176 : }
2177 :
2178 : /* Create VNI hash entry for L2VNI */
2179 0 : zevpn = zebra_evpn_lookup(vni);
2180 0 : if (zevpn)
2181 : return 0;
2182 :
2183 0 : zevpn = zebra_evpn_add(vni);
2184 :
2185 : /* Find bridge interface for the VNI */
2186 0 : vlan_if = zvni_map_to_svi(vxl->access_vlan,
2187 : zif->brslave_info.br_if);
2188 0 : if (vlan_if) {
2189 0 : zevpn->vrf_id = vlan_if->vrf->vrf_id;
2190 0 : zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
2191 0 : if (zl3vni)
2192 0 : listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
2193 : }
2194 :
2195 0 : zevpn->vxlan_if = ifp;
2196 0 : zevpn->local_vtep_ip = vxl->vtep_ip;
2197 :
2198 : /* Inform BGP if the VNI is up and mapped to a bridge. */
2199 0 : if (if_is_operative(ifp) && zif->brslave_info.br_if) {
2200 0 : zebra_evpn_send_add_to_client(zevpn);
2201 0 : zebra_evpn_read_mac_neigh(zevpn, ifp);
2202 : }
2203 : }
2204 :
2205 : return 0;
2206 : }
2207 :
2208 : /* delete and uninstall rmac hash entry */
2209 0 : static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx)
2210 : {
2211 0 : struct zebra_mac *zrmac = NULL;
2212 0 : struct zebra_l3vni *zl3vni = NULL;
2213 :
2214 0 : zrmac = (struct zebra_mac *)bucket->data;
2215 0 : zl3vni = (struct zebra_l3vni *)ctx;
2216 0 : zl3vni_rmac_uninstall(zl3vni, zrmac);
2217 :
2218 : /* Send RMAC for FPM processing */
2219 0 : hook_call(zebra_rmac_update, zrmac, zl3vni, true, "RMAC deleted");
2220 :
2221 0 : zl3vni_rmac_del(zl3vni, zrmac);
2222 0 : }
2223 :
2224 : /* delete and uninstall nh hash entry */
2225 0 : static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx)
2226 : {
2227 0 : struct zebra_neigh *n = NULL;
2228 0 : struct zebra_l3vni *zl3vni = NULL;
2229 :
2230 0 : n = (struct zebra_neigh *)bucket->data;
2231 0 : zl3vni = (struct zebra_l3vni *)ctx;
2232 0 : zl3vni_nh_uninstall(zl3vni, n);
2233 0 : zl3vni_nh_del(zl3vni, n);
2234 0 : }
2235 :
2236 : /* re-add remote rmac if needed */
2237 0 : static int zebra_vxlan_readd_remote_rmac(struct zebra_l3vni *zl3vni,
2238 : struct ethaddr *rmac)
2239 : {
2240 0 : struct zebra_mac *zrmac = NULL;
2241 :
2242 0 : zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2243 0 : if (!zrmac)
2244 : return 0;
2245 :
2246 0 : if (IS_ZEBRA_DEBUG_VXLAN)
2247 0 : zlog_debug("Del remote RMAC %pEA L3VNI %u - readd",
2248 : rmac, zl3vni->vni);
2249 :
2250 0 : zl3vni_rmac_install(zl3vni, zrmac);
2251 0 : return 0;
2252 : }
2253 :
2254 : /* Public functions */
2255 :
2256 0 : int is_l3vni_for_prefix_routes_only(vni_t vni)
2257 : {
2258 0 : struct zebra_l3vni *zl3vni = NULL;
2259 :
2260 0 : zl3vni = zl3vni_lookup(vni);
2261 0 : if (!zl3vni)
2262 : return 0;
2263 :
2264 0 : return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
2265 : }
2266 :
2267 : /* handle evpn route in vrf table */
2268 0 : void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
2269 : const struct ipaddr *vtep_ip,
2270 : const struct prefix *host_prefix)
2271 : {
2272 0 : struct zebra_l3vni *zl3vni = NULL;
2273 0 : struct ipaddr ipv4_vtep;
2274 :
2275 0 : zl3vni = zl3vni_from_vrf(vrf_id);
2276 0 : if (!zl3vni || !is_l3vni_oper_up(zl3vni))
2277 0 : return;
2278 :
2279 : /*
2280 : * add the next hop neighbor -
2281 : * neigh to be installed is the ipv6 nexthop neigh
2282 : */
2283 0 : zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
2284 :
2285 : /*
2286 : * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
2287 : * address. Rmac is programmed against the ipv4 vtep because we only
2288 : * support ipv4 tunnels in the h/w right now
2289 : */
2290 0 : memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
2291 0 : ipv4_vtep.ipa_type = IPADDR_V4;
2292 0 : if (vtep_ip->ipa_type == IPADDR_V6)
2293 0 : ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
2294 : &(ipv4_vtep.ipaddr_v4));
2295 : else
2296 0 : memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
2297 : sizeof(struct in_addr));
2298 :
2299 : /*
2300 : * add the rmac - remote rmac to be installed is against the ipv4
2301 : * nexthop address
2302 : */
2303 0 : zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep);
2304 : }
2305 :
2306 : /* handle evpn vrf route delete */
2307 0 : void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
2308 : struct ipaddr *vtep_ip,
2309 : struct prefix *host_prefix)
2310 : {
2311 0 : struct zebra_l3vni *zl3vni = NULL;
2312 0 : struct zebra_neigh *nh = NULL;
2313 0 : struct zebra_mac *zrmac = NULL;
2314 :
2315 0 : zl3vni = zl3vni_from_vrf(vrf_id);
2316 0 : if (!zl3vni)
2317 : return;
2318 :
2319 : /* find the next hop entry and rmac entry */
2320 0 : nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
2321 0 : if (!nh)
2322 : return;
2323 0 : zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
2324 :
2325 : /* delete the next hop entry */
2326 0 : zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
2327 :
2328 : /* delete the rmac entry */
2329 0 : if (zrmac)
2330 0 : zl3vni_remote_rmac_del(zl3vni, zrmac, vtep_ip);
2331 : }
2332 :
2333 0 : void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
2334 : struct ethaddr *rmac, bool use_json)
2335 : {
2336 0 : struct zebra_l3vni *zl3vni = NULL;
2337 0 : struct zebra_mac *zrmac = NULL;
2338 0 : json_object *json = NULL;
2339 :
2340 0 : if (!is_evpn_enabled()) {
2341 0 : if (use_json)
2342 0 : vty_out(vty, "{}\n");
2343 0 : return;
2344 : }
2345 :
2346 0 : if (use_json)
2347 0 : json = json_object_new_object();
2348 :
2349 0 : zl3vni = zl3vni_lookup(l3vni);
2350 0 : if (!zl3vni) {
2351 0 : if (use_json)
2352 0 : vty_out(vty, "{}\n");
2353 : else
2354 0 : vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
2355 0 : return;
2356 : }
2357 :
2358 0 : zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2359 0 : if (!zrmac) {
2360 0 : if (use_json)
2361 0 : vty_out(vty, "{}\n");
2362 : else
2363 0 : vty_out(vty,
2364 : "%% Requested RMAC doesn't exist in L3-VNI %u\n",
2365 : l3vni);
2366 0 : return;
2367 : }
2368 :
2369 0 : zl3vni_print_rmac(zrmac, vty, json);
2370 :
2371 0 : if (use_json)
2372 0 : vty_json(vty, json);
2373 : }
2374 :
2375 0 : void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2376 : {
2377 0 : struct zebra_l3vni *zl3vni;
2378 0 : uint32_t num_rmacs;
2379 0 : struct rmac_walk_ctx wctx;
2380 0 : json_object *json = NULL;
2381 :
2382 0 : if (!is_evpn_enabled())
2383 0 : return;
2384 :
2385 0 : zl3vni = zl3vni_lookup(l3vni);
2386 0 : if (!zl3vni) {
2387 0 : if (use_json)
2388 0 : vty_out(vty, "{}\n");
2389 : else
2390 0 : vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2391 0 : return;
2392 : }
2393 0 : num_rmacs = hashcount(zl3vni->rmac_table);
2394 0 : if (!num_rmacs)
2395 : return;
2396 :
2397 0 : if (use_json)
2398 0 : json = json_object_new_object();
2399 :
2400 0 : memset(&wctx, 0, sizeof(wctx));
2401 0 : wctx.vty = vty;
2402 0 : wctx.json = json;
2403 0 : if (!use_json) {
2404 0 : vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
2405 : num_rmacs);
2406 0 : vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
2407 : } else
2408 0 : json_object_int_add(json, "numRmacs", num_rmacs);
2409 :
2410 0 : hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
2411 :
2412 0 : if (use_json)
2413 0 : vty_json(vty, json);
2414 : }
2415 :
2416 0 : void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
2417 : {
2418 0 : json_object *json = NULL;
2419 0 : void *args[2];
2420 :
2421 0 : if (!is_evpn_enabled()) {
2422 0 : if (use_json)
2423 0 : vty_out(vty, "{}\n");
2424 0 : return;
2425 : }
2426 :
2427 0 : if (use_json)
2428 0 : json = json_object_new_object();
2429 :
2430 0 : args[0] = vty;
2431 0 : args[1] = json;
2432 0 : hash_iterate(zrouter.l3vni_table,
2433 : (void (*)(struct hash_bucket *,
2434 : void *))zl3vni_print_rmac_hash_all_vni,
2435 : args);
2436 :
2437 0 : if (use_json)
2438 0 : vty_json(vty, json);
2439 : }
2440 :
2441 0 : void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
2442 : struct ipaddr *ip, bool use_json)
2443 : {
2444 0 : struct zebra_l3vni *zl3vni = NULL;
2445 0 : struct zebra_neigh *n = NULL;
2446 0 : json_object *json = NULL;
2447 :
2448 0 : if (!is_evpn_enabled()) {
2449 0 : if (use_json)
2450 0 : vty_out(vty, "{}\n");
2451 0 : return;
2452 : }
2453 :
2454 0 : if (use_json)
2455 0 : json = json_object_new_object();
2456 :
2457 0 : zl3vni = zl3vni_lookup(l3vni);
2458 0 : if (!zl3vni) {
2459 0 : if (use_json)
2460 0 : vty_out(vty, "{}\n");
2461 : else
2462 0 : vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2463 0 : return;
2464 : }
2465 :
2466 0 : n = zl3vni_nh_lookup(zl3vni, ip);
2467 0 : if (!n) {
2468 0 : if (use_json)
2469 0 : vty_out(vty, "{}\n");
2470 : else
2471 0 : vty_out(vty,
2472 : "%% Requested next-hop not present for L3-VNI %u",
2473 : l3vni);
2474 0 : return;
2475 : }
2476 :
2477 0 : zl3vni_print_nh(n, vty, json);
2478 :
2479 0 : if (use_json)
2480 0 : vty_json(vty, json);
2481 : }
2482 :
2483 0 : void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2484 : {
2485 0 : uint32_t num_nh;
2486 0 : struct nh_walk_ctx wctx;
2487 0 : json_object *json = NULL;
2488 0 : struct zebra_l3vni *zl3vni = NULL;
2489 :
2490 0 : if (!is_evpn_enabled())
2491 0 : return;
2492 :
2493 0 : zl3vni = zl3vni_lookup(l3vni);
2494 0 : if (!zl3vni) {
2495 0 : if (use_json)
2496 0 : vty_out(vty, "{}\n");
2497 : else
2498 0 : vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2499 0 : return;
2500 : }
2501 :
2502 0 : num_nh = hashcount(zl3vni->nh_table);
2503 0 : if (!num_nh)
2504 : return;
2505 :
2506 0 : if (use_json)
2507 0 : json = json_object_new_object();
2508 :
2509 0 : wctx.vty = vty;
2510 0 : wctx.json = json;
2511 0 : if (!use_json) {
2512 0 : vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
2513 : num_nh);
2514 0 : vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
2515 : } else
2516 0 : json_object_int_add(json, "numNextHops", num_nh);
2517 :
2518 0 : hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
2519 :
2520 0 : if (use_json)
2521 0 : vty_json(vty, json);
2522 : }
2523 :
2524 0 : void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
2525 : {
2526 0 : json_object *json = NULL;
2527 0 : void *args[2];
2528 :
2529 0 : if (!is_evpn_enabled()) {
2530 0 : if (use_json)
2531 0 : vty_out(vty, "{}\n");
2532 0 : return;
2533 : }
2534 :
2535 0 : if (use_json)
2536 0 : json = json_object_new_object();
2537 :
2538 0 : args[0] = vty;
2539 0 : args[1] = json;
2540 0 : hash_iterate(zrouter.l3vni_table,
2541 : (void (*)(struct hash_bucket *,
2542 : void *))zl3vni_print_nh_hash_all_vni,
2543 : args);
2544 :
2545 0 : if (use_json)
2546 0 : vty_json(vty, json);
2547 : }
2548 :
2549 : /*
2550 : * Display L3 VNI information (VTY command handler).
2551 : */
2552 0 : void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
2553 : {
2554 0 : void *args[2];
2555 0 : json_object *json = NULL;
2556 0 : struct zebra_l3vni *zl3vni = NULL;
2557 :
2558 0 : if (!is_evpn_enabled()) {
2559 0 : if (use_json)
2560 0 : vty_out(vty, "{}\n");
2561 0 : return;
2562 : }
2563 :
2564 0 : zl3vni = zl3vni_lookup(vni);
2565 0 : if (!zl3vni) {
2566 0 : if (use_json)
2567 0 : vty_out(vty, "{}\n");
2568 : else
2569 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2570 0 : return;
2571 : }
2572 :
2573 0 : if (use_json)
2574 0 : json = json_object_new_object();
2575 :
2576 0 : args[0] = vty;
2577 0 : args[1] = json;
2578 0 : zl3vni_print(zl3vni, (void *)args);
2579 :
2580 0 : if (use_json)
2581 0 : vty_json(vty, json);
2582 : }
2583 :
2584 0 : void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
2585 : json_object *json_vrfs)
2586 : {
2587 0 : char buf[ETHER_ADDR_STRLEN];
2588 0 : struct zebra_l3vni *zl3vni = NULL;
2589 :
2590 0 : zl3vni = zl3vni_lookup(zvrf->l3vni);
2591 0 : if (!zl3vni)
2592 0 : return;
2593 :
2594 0 : if (!json_vrfs) {
2595 0 : vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
2596 : zvrf_name(zvrf), zl3vni->vni,
2597 : zl3vni_vxlan_if_name(zl3vni),
2598 : zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
2599 : zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2600 : } else {
2601 0 : json_object *json_vrf = NULL;
2602 :
2603 0 : json_vrf = json_object_new_object();
2604 0 : json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
2605 0 : json_object_int_add(json_vrf, "vni", zl3vni->vni);
2606 0 : json_object_string_add(json_vrf, "vxlanIntf",
2607 : zl3vni_vxlan_if_name(zl3vni));
2608 0 : json_object_string_add(json_vrf, "sviIntf",
2609 : zl3vni_svi_if_name(zl3vni));
2610 0 : json_object_string_add(json_vrf, "state",
2611 : zl3vni_state2str(zl3vni));
2612 0 : json_object_string_add(
2613 : json_vrf, "routerMac",
2614 : zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2615 0 : json_object_array_add(json_vrfs, json_vrf);
2616 : }
2617 : }
2618 :
2619 : /*
2620 : * Display Neighbors for a VNI (VTY command handler).
2621 : */
2622 0 : void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
2623 : vni_t vni, bool use_json)
2624 : {
2625 0 : struct zebra_evpn *zevpn;
2626 0 : uint32_t num_neigh;
2627 0 : struct neigh_walk_ctx wctx;
2628 0 : json_object *json = NULL;
2629 :
2630 0 : if (!is_evpn_enabled())
2631 0 : return;
2632 0 : zevpn = zebra_evpn_lookup(vni);
2633 0 : if (!zevpn) {
2634 0 : if (use_json)
2635 0 : vty_out(vty, "{}\n");
2636 : else
2637 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2638 0 : return;
2639 : }
2640 0 : num_neigh = hashcount(zevpn->neigh_table);
2641 0 : if (!num_neigh)
2642 : return;
2643 :
2644 0 : if (use_json)
2645 0 : json = json_object_new_object();
2646 :
2647 : /* Since we have IPv6 addresses to deal with which can vary widely in
2648 : * size, we try to be a bit more elegant in display by first computing
2649 : * the maximum width.
2650 : */
2651 0 : memset(&wctx, 0, sizeof(wctx));
2652 0 : wctx.zevpn = zevpn;
2653 0 : wctx.vty = vty;
2654 0 : wctx.addr_width = 15;
2655 0 : wctx.json = json;
2656 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2657 : &wctx);
2658 :
2659 0 : if (!use_json) {
2660 0 : vty_out(vty,
2661 : "Number of ARPs (local and remote) known for this VNI: %u\n",
2662 : num_neigh);
2663 0 : zebra_evpn_print_neigh_hdr(vty, &wctx);
2664 : } else
2665 0 : json_object_int_add(json, "numArpNd", num_neigh);
2666 :
2667 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
2668 0 : if (use_json)
2669 0 : vty_json(vty, json);
2670 : }
2671 :
2672 : /*
2673 : * Display neighbors across all VNIs (VTY command handler).
2674 : */
2675 0 : void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2676 : bool print_dup, bool use_json)
2677 : {
2678 0 : json_object *json = NULL;
2679 0 : void *args[3];
2680 :
2681 0 : if (!is_evpn_enabled())
2682 0 : return;
2683 :
2684 0 : if (use_json)
2685 0 : json = json_object_new_object();
2686 :
2687 0 : args[0] = vty;
2688 0 : args[1] = json;
2689 0 : args[2] = (void *)(ptrdiff_t)print_dup;
2690 :
2691 0 : hash_iterate(zvrf->evpn_table,
2692 : (void (*)(struct hash_bucket *,
2693 : void *))zevpn_print_neigh_hash_all_evpn,
2694 : args);
2695 0 : if (use_json)
2696 0 : vty_json(vty, json);
2697 : }
2698 :
2699 : /*
2700 : * Display neighbors across all VNIs in detail(VTY command handler).
2701 : */
2702 0 : void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
2703 : struct zebra_vrf *zvrf,
2704 : bool print_dup, bool use_json)
2705 : {
2706 0 : json_object *json = NULL;
2707 0 : void *args[3];
2708 :
2709 0 : if (!is_evpn_enabled())
2710 0 : return;
2711 :
2712 0 : if (use_json)
2713 0 : json = json_object_new_object();
2714 :
2715 0 : args[0] = vty;
2716 0 : args[1] = json;
2717 0 : args[2] = (void *)(ptrdiff_t)print_dup;
2718 :
2719 0 : hash_iterate(zvrf->evpn_table,
2720 : (void (*)(struct hash_bucket *,
2721 : void *))zevpn_print_neigh_hash_all_evpn_detail,
2722 : args);
2723 0 : if (use_json)
2724 0 : vty_json(vty, json);
2725 : }
2726 :
2727 : /*
2728 : * Display specific neighbor for a VNI, if present (VTY command handler).
2729 : */
2730 0 : void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
2731 : struct zebra_vrf *zvrf, vni_t vni,
2732 : struct ipaddr *ip, bool use_json)
2733 : {
2734 0 : struct zebra_evpn *zevpn;
2735 0 : struct zebra_neigh *n;
2736 0 : json_object *json = NULL;
2737 :
2738 0 : if (!is_evpn_enabled())
2739 : return;
2740 0 : zevpn = zebra_evpn_lookup(vni);
2741 0 : if (!zevpn) {
2742 0 : if (use_json)
2743 0 : vty_out(vty, "{}\n");
2744 : else
2745 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2746 0 : return;
2747 : }
2748 0 : n = zebra_evpn_neigh_lookup(zevpn, ip);
2749 0 : if (!n) {
2750 0 : if (!use_json)
2751 0 : vty_out(vty,
2752 : "%% Requested neighbor does not exist in VNI %u\n",
2753 : vni);
2754 0 : return;
2755 : }
2756 0 : if (use_json)
2757 0 : json = json_object_new_object();
2758 :
2759 0 : zebra_evpn_print_neigh(n, vty, json);
2760 :
2761 0 : if (use_json)
2762 0 : vty_json(vty, json);
2763 : }
2764 :
2765 : /*
2766 : * Display neighbors for a VNI from specific VTEP (VTY command handler).
2767 : * By definition, these are remote neighbors.
2768 : */
2769 0 : void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2770 : vni_t vni, struct in_addr vtep_ip,
2771 : bool use_json)
2772 : {
2773 0 : struct zebra_evpn *zevpn;
2774 0 : uint32_t num_neigh;
2775 0 : struct neigh_walk_ctx wctx;
2776 0 : json_object *json = NULL;
2777 :
2778 0 : if (!is_evpn_enabled())
2779 0 : return;
2780 0 : zevpn = zebra_evpn_lookup(vni);
2781 0 : if (!zevpn) {
2782 0 : if (use_json)
2783 0 : vty_out(vty, "{}\n");
2784 : else
2785 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2786 0 : return;
2787 : }
2788 0 : num_neigh = hashcount(zevpn->neigh_table);
2789 0 : if (!num_neigh)
2790 : return;
2791 :
2792 0 : if (use_json)
2793 0 : json = json_object_new_object();
2794 :
2795 0 : memset(&wctx, 0, sizeof(wctx));
2796 0 : wctx.zevpn = zevpn;
2797 0 : wctx.vty = vty;
2798 0 : wctx.addr_width = 15;
2799 0 : wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
2800 0 : wctx.r_vtep_ip = vtep_ip;
2801 0 : wctx.json = json;
2802 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2803 : &wctx);
2804 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
2805 :
2806 0 : if (use_json)
2807 0 : vty_json(vty, json);
2808 : }
2809 :
2810 : /*
2811 : * Display Duplicate detected Neighbors for a VNI
2812 : * (VTY command handler).
2813 : */
2814 0 : void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
2815 : struct zebra_vrf *zvrf,
2816 : vni_t vni,
2817 : bool use_json)
2818 : {
2819 0 : struct zebra_evpn *zevpn;
2820 0 : uint32_t num_neigh;
2821 0 : struct neigh_walk_ctx wctx;
2822 0 : json_object *json = NULL;
2823 :
2824 0 : if (!is_evpn_enabled())
2825 0 : return;
2826 :
2827 0 : zevpn = zebra_evpn_lookup(vni);
2828 0 : if (!zevpn) {
2829 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2830 0 : return;
2831 : }
2832 :
2833 0 : num_neigh = hashcount(zevpn->neigh_table);
2834 0 : if (!num_neigh)
2835 : return;
2836 :
2837 0 : num_neigh = num_dup_detected_neighs(zevpn);
2838 0 : if (!num_neigh)
2839 : return;
2840 :
2841 0 : if (use_json)
2842 0 : json = json_object_new_object();
2843 :
2844 : /* Since we have IPv6 addresses to deal with which can vary widely in
2845 : * size, we try to be a bit more elegant in display by first computing
2846 : * the maximum width.
2847 : */
2848 0 : memset(&wctx, 0, sizeof(wctx));
2849 0 : wctx.zevpn = zevpn;
2850 0 : wctx.vty = vty;
2851 0 : wctx.addr_width = 15;
2852 0 : wctx.json = json;
2853 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2854 : &wctx);
2855 :
2856 0 : if (!use_json) {
2857 0 : vty_out(vty,
2858 : "Number of ARPs (local and remote) known for this VNI: %u\n",
2859 : num_neigh);
2860 0 : vty_out(vty, "%*s %-6s %-8s %-17s %-30s\n",
2861 0 : -wctx.addr_width, "IP", "Type",
2862 : "State", "MAC", "Remote ES/VTEP");
2863 : } else
2864 0 : json_object_int_add(json, "numArpNd", num_neigh);
2865 :
2866 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_print_dad_neigh_hash,
2867 : &wctx);
2868 :
2869 0 : if (use_json)
2870 0 : vty_json(vty, json);
2871 : }
2872 :
2873 : /*
2874 : * Display MACs for a VNI (VTY command handler).
2875 : */
2876 0 : void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
2877 : vni_t vni, bool use_json, bool detail)
2878 : {
2879 0 : struct zebra_evpn *zevpn;
2880 0 : uint32_t num_macs;
2881 0 : struct mac_walk_ctx wctx;
2882 0 : json_object *json = NULL;
2883 0 : json_object *json_mac = NULL;
2884 :
2885 0 : if (!is_evpn_enabled())
2886 0 : return;
2887 0 : zevpn = zebra_evpn_lookup(vni);
2888 0 : if (!zevpn) {
2889 0 : if (use_json)
2890 0 : vty_out(vty, "{}\n");
2891 : else
2892 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
2893 0 : return;
2894 : }
2895 0 : num_macs = num_valid_macs(zevpn);
2896 0 : if (!num_macs)
2897 : return;
2898 :
2899 0 : if (use_json) {
2900 0 : json = json_object_new_object();
2901 0 : json_mac = json_object_new_object();
2902 : }
2903 :
2904 0 : memset(&wctx, 0, sizeof(wctx));
2905 0 : wctx.zevpn = zevpn;
2906 0 : wctx.vty = vty;
2907 0 : wctx.json = json_mac;
2908 :
2909 0 : if (!use_json) {
2910 0 : if (detail) {
2911 0 : vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
2912 : zevpn->vni, num_macs);
2913 : } else {
2914 0 : vty_out(vty,
2915 : "Number of MACs (local and remote) known for this VNI: %u\n",
2916 : num_macs);
2917 0 : vty_out(vty,
2918 : "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
2919 0 : vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
2920 : "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN",
2921 : "Seq #'s");
2922 : }
2923 : } else
2924 0 : json_object_int_add(json, "numMacs", num_macs);
2925 :
2926 0 : if (detail)
2927 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
2928 : &wctx);
2929 : else
2930 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash,
2931 : &wctx);
2932 :
2933 0 : if (use_json) {
2934 0 : json_object_object_add(json, "macs", json_mac);
2935 0 : vty_json(vty, json);
2936 : }
2937 : }
2938 :
2939 : /*
2940 : * Display MACs for all VNIs (VTY command handler).
2941 : */
2942 0 : void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2943 : bool print_dup, bool use_json)
2944 : {
2945 0 : struct mac_walk_ctx wctx;
2946 0 : json_object *json = NULL;
2947 :
2948 0 : if (!is_evpn_enabled()) {
2949 0 : if (use_json)
2950 0 : vty_out(vty, "{}\n");
2951 0 : return;
2952 : }
2953 0 : if (use_json)
2954 0 : json = json_object_new_object();
2955 :
2956 0 : memset(&wctx, 0, sizeof(wctx));
2957 0 : wctx.vty = vty;
2958 0 : wctx.json = json;
2959 0 : wctx.print_dup = print_dup;
2960 0 : hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
2961 :
2962 0 : if (use_json)
2963 0 : vty_json(vty, json);
2964 : }
2965 :
2966 : /*
2967 : * Display MACs in detail for all VNIs (VTY command handler).
2968 : */
2969 0 : void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
2970 : struct zebra_vrf *zvrf,
2971 : bool print_dup, bool use_json)
2972 : {
2973 0 : struct mac_walk_ctx wctx;
2974 0 : json_object *json = NULL;
2975 :
2976 0 : if (!is_evpn_enabled()) {
2977 0 : if (use_json)
2978 0 : vty_out(vty, "{}\n");
2979 0 : return;
2980 : }
2981 0 : if (use_json)
2982 0 : json = json_object_new_object();
2983 :
2984 0 : memset(&wctx, 0, sizeof(wctx));
2985 0 : wctx.vty = vty;
2986 0 : wctx.json = json;
2987 0 : wctx.print_dup = print_dup;
2988 0 : hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn_detail,
2989 : &wctx);
2990 :
2991 0 : if (use_json)
2992 0 : vty_json(vty, json);
2993 : }
2994 :
2995 : /*
2996 : * Display MACs for all VNIs (VTY command handler).
2997 : */
2998 0 : void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
2999 : struct zebra_vrf *zvrf,
3000 : struct in_addr vtep_ip, bool use_json)
3001 : {
3002 0 : struct mac_walk_ctx wctx;
3003 0 : json_object *json = NULL;
3004 :
3005 0 : if (!is_evpn_enabled())
3006 0 : return;
3007 :
3008 0 : if (use_json)
3009 0 : json = json_object_new_object();
3010 :
3011 0 : memset(&wctx, 0, sizeof(wctx));
3012 0 : wctx.vty = vty;
3013 0 : wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3014 0 : wctx.r_vtep_ip = vtep_ip;
3015 0 : wctx.json = json;
3016 0 : hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
3017 :
3018 0 : if (use_json)
3019 0 : vty_json(vty, json);
3020 : }
3021 :
3022 : /*
3023 : * Display specific MAC for a VNI, if present (VTY command handler).
3024 : */
3025 0 : void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
3026 : vni_t vni, struct ethaddr *macaddr,
3027 : bool use_json)
3028 : {
3029 0 : struct zebra_evpn *zevpn;
3030 0 : struct zebra_mac *mac;
3031 0 : json_object *json = NULL;
3032 :
3033 0 : if (!is_evpn_enabled())
3034 : return;
3035 :
3036 0 : zevpn = zebra_evpn_lookup(vni);
3037 0 : if (!zevpn) {
3038 0 : if (use_json)
3039 0 : vty_out(vty, "{}\n");
3040 : else
3041 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
3042 0 : return;
3043 : }
3044 0 : mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3045 0 : if (!mac) {
3046 0 : if (use_json)
3047 0 : vty_out(vty, "{}\n");
3048 : else
3049 0 : vty_out(vty,
3050 : "%% Requested MAC does not exist in VNI %u\n",
3051 : vni);
3052 0 : return;
3053 : }
3054 :
3055 0 : if (use_json)
3056 0 : json = json_object_new_object();
3057 :
3058 0 : zebra_evpn_print_mac(mac, vty, json);
3059 0 : if (use_json)
3060 0 : vty_json(vty, json);
3061 : }
3062 :
3063 : /* Print Duplicate MACs per VNI */
3064 0 : void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
3065 : struct zebra_vrf *zvrf,
3066 : vni_t vni, bool use_json)
3067 : {
3068 0 : struct zebra_evpn *zevpn;
3069 0 : struct mac_walk_ctx wctx;
3070 0 : uint32_t num_macs;
3071 0 : json_object *json = NULL;
3072 0 : json_object *json_mac = NULL;
3073 :
3074 0 : if (!is_evpn_enabled())
3075 0 : return;
3076 :
3077 0 : zevpn = zebra_evpn_lookup(vni);
3078 0 : if (!zevpn) {
3079 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
3080 0 : return;
3081 : }
3082 :
3083 0 : num_macs = num_valid_macs(zevpn);
3084 0 : if (!num_macs)
3085 : return;
3086 :
3087 0 : num_macs = num_dup_detected_macs(zevpn);
3088 0 : if (!num_macs)
3089 : return;
3090 :
3091 0 : if (use_json) {
3092 0 : json = json_object_new_object();
3093 0 : json_mac = json_object_new_object();
3094 : }
3095 :
3096 0 : memset(&wctx, 0, sizeof(wctx));
3097 0 : wctx.zevpn = zevpn;
3098 0 : wctx.vty = vty;
3099 0 : wctx.json = json_mac;
3100 :
3101 0 : if (!use_json) {
3102 0 : vty_out(vty,
3103 : "Number of MACs (local and remote) known for this VNI: %u\n",
3104 : num_macs);
3105 0 : vty_out(vty, "%-17s %-6s %-5s %-30s %-5s\n", "MAC", "Type",
3106 : "Flags", "Intf/Remote ES/VTEP", "VLAN");
3107 : } else
3108 0 : json_object_int_add(json, "numMacs", num_macs);
3109 :
3110 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash, &wctx);
3111 :
3112 0 : if (use_json) {
3113 0 : json_object_object_add(json, "macs", json_mac);
3114 0 : vty_json(vty, json);
3115 : }
3116 :
3117 : }
3118 :
3119 0 : int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
3120 : struct ethaddr *macaddr, char *errmsg,
3121 : size_t errmsg_len)
3122 : {
3123 0 : struct zebra_evpn *zevpn;
3124 0 : struct zebra_mac *mac;
3125 0 : struct listnode *node = NULL;
3126 0 : struct zebra_neigh *nbr = NULL;
3127 :
3128 0 : if (!is_evpn_enabled())
3129 : return 0;
3130 :
3131 0 : zevpn = zebra_evpn_lookup(vni);
3132 0 : if (!zevpn) {
3133 0 : snprintfrr(errmsg, errmsg_len, "VNI %u does not exist", vni);
3134 0 : return -1;
3135 : }
3136 :
3137 0 : mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3138 0 : if (!mac) {
3139 0 : snprintf(errmsg, errmsg_len,
3140 : "Requested MAC does not exist in VNI %u\n", vni);
3141 0 : return -1;
3142 : }
3143 :
3144 0 : if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3145 0 : snprintfrr(errmsg, errmsg_len,
3146 : "Requested MAC is not duplicate detected\n");
3147 0 : return -1;
3148 : }
3149 :
3150 : /* Remove all IPs as duplicate associcated with this MAC */
3151 0 : for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3152 : /* For local neigh mark inactive so MACIP update is generated
3153 : * to BGP. This is a scenario where MAC update received
3154 : * and detected as duplicate which marked neigh as duplicate.
3155 : * Later local neigh update did not get a chance to relay
3156 : * to BGP. Similarly remote macip update, neigh needs to be
3157 : * installed locally.
3158 : */
3159 0 : if (zvrf->dad_freeze &&
3160 0 : CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3161 0 : if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
3162 0 : ZEBRA_NEIGH_SET_INACTIVE(nbr);
3163 0 : else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
3164 0 : zebra_evpn_rem_neigh_install(
3165 : zevpn, nbr, false /*was_static*/);
3166 : }
3167 :
3168 0 : UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3169 0 : nbr->dad_count = 0;
3170 0 : nbr->detect_start_time.tv_sec = 0;
3171 0 : nbr->dad_dup_detect_time = 0;
3172 : }
3173 :
3174 0 : UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3175 0 : mac->dad_count = 0;
3176 0 : mac->detect_start_time.tv_sec = 0;
3177 0 : mac->detect_start_time.tv_usec = 0;
3178 0 : mac->dad_dup_detect_time = 0;
3179 0 : THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3180 :
3181 : /* warn-only action return */
3182 0 : if (!zvrf->dad_freeze)
3183 : return 0;
3184 :
3185 : /* Local: Notify Peer VTEPs, Remote: Install the entry */
3186 0 : if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3187 : /* Inform to BGP */
3188 0 : if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3189 : mac->flags, mac->loc_seq,
3190 : mac->es))
3191 : return 0;
3192 :
3193 : /* Process all neighbors associated with this MAC. */
3194 0 : zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3195 : 0 /*es_change*/);
3196 :
3197 0 : } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3198 0 : zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3199 :
3200 : /* Install the entry. */
3201 0 : zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3202 : }
3203 :
3204 : return 0;
3205 : }
3206 :
3207 0 : int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
3208 : struct ipaddr *ip, char *errmsg,
3209 : size_t errmsg_len)
3210 : {
3211 0 : struct zebra_evpn *zevpn;
3212 0 : struct zebra_neigh *nbr;
3213 0 : struct zebra_mac *mac;
3214 0 : char buf[INET6_ADDRSTRLEN];
3215 0 : char buf2[ETHER_ADDR_STRLEN];
3216 :
3217 0 : if (!is_evpn_enabled())
3218 : return 0;
3219 :
3220 0 : zevpn = zebra_evpn_lookup(vni);
3221 0 : if (!zevpn) {
3222 0 : snprintfrr(errmsg, errmsg_len, "VNI %u does not exist\n", vni);
3223 0 : return -1;
3224 : }
3225 :
3226 0 : nbr = zebra_evpn_neigh_lookup(zevpn, ip);
3227 0 : if (!nbr) {
3228 0 : snprintfrr(errmsg, errmsg_len,
3229 : "Requested host IP does not exist in VNI %u\n", vni);
3230 0 : return -1;
3231 : }
3232 :
3233 0 : ipaddr2str(&nbr->ip, buf, sizeof(buf));
3234 :
3235 0 : if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3236 0 : snprintfrr(errmsg, errmsg_len,
3237 : "Requested host IP %s is not duplicate detected\n",
3238 : buf);
3239 0 : return -1;
3240 : }
3241 :
3242 0 : mac = zebra_evpn_mac_lookup(zevpn, &nbr->emac);
3243 :
3244 0 : if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3245 0 : snprintfrr(
3246 : errmsg, errmsg_len,
3247 : "Requested IP's associated MAC %s is still in duplicate state\n",
3248 : prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
3249 0 : return -1;
3250 : }
3251 :
3252 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3253 0 : zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
3254 : __func__, buf, nbr->flags, nbr->loc_seq);
3255 :
3256 0 : UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3257 0 : nbr->dad_count = 0;
3258 0 : nbr->detect_start_time.tv_sec = 0;
3259 0 : nbr->detect_start_time.tv_usec = 0;
3260 0 : nbr->dad_dup_detect_time = 0;
3261 0 : THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
3262 :
3263 0 : if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
3264 0 : zebra_evpn_neigh_send_add_to_client(zevpn->vni, ip, &nbr->emac,
3265 : nbr->mac, nbr->flags,
3266 : nbr->loc_seq);
3267 0 : } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
3268 0 : zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
3269 : }
3270 :
3271 : return 0;
3272 : }
3273 :
3274 0 : static void zevpn_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt)
3275 : {
3276 0 : struct mac_walk_ctx *wctx = ctxt;
3277 0 : struct zebra_mac *mac;
3278 0 : struct zebra_evpn *zevpn;
3279 0 : struct listnode *node = NULL;
3280 0 : struct zebra_neigh *nbr = NULL;
3281 :
3282 0 : mac = (struct zebra_mac *)bucket->data;
3283 0 : if (!mac)
3284 : return;
3285 :
3286 0 : zevpn = wctx->zevpn;
3287 :
3288 0 : if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
3289 : return;
3290 :
3291 0 : UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3292 0 : mac->dad_count = 0;
3293 0 : mac->detect_start_time.tv_sec = 0;
3294 0 : mac->detect_start_time.tv_usec = 0;
3295 0 : mac->dad_dup_detect_time = 0;
3296 0 : THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3297 :
3298 : /* Remove all IPs as duplicate associcated with this MAC */
3299 0 : for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3300 0 : if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
3301 0 : && nbr->dad_count)
3302 0 : ZEBRA_NEIGH_SET_INACTIVE(nbr);
3303 :
3304 0 : UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3305 0 : nbr->dad_count = 0;
3306 0 : nbr->detect_start_time.tv_sec = 0;
3307 0 : nbr->dad_dup_detect_time = 0;
3308 : }
3309 :
3310 : /* Local: Notify Peer VTEPs, Remote: Install the entry */
3311 0 : if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3312 : /* Inform to BGP */
3313 0 : if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3314 : mac->flags, mac->loc_seq,
3315 : mac->es))
3316 : return;
3317 :
3318 : /* Process all neighbors associated with this MAC. */
3319 0 : zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3320 : 0 /*es_change*/);
3321 :
3322 0 : } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3323 0 : zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3324 :
3325 : /* Install the entry. */
3326 0 : zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3327 : }
3328 : }
3329 :
3330 0 : static void zevpn_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket,
3331 : void **args)
3332 : {
3333 0 : struct zebra_evpn *zevpn;
3334 0 : struct zebra_vrf *zvrf;
3335 0 : struct mac_walk_ctx m_wctx;
3336 0 : struct neigh_walk_ctx n_wctx;
3337 :
3338 0 : zevpn = (struct zebra_evpn *)bucket->data;
3339 0 : if (!zevpn)
3340 0 : return;
3341 :
3342 0 : zvrf = (struct zebra_vrf *)args[0];
3343 :
3344 0 : if (hashcount(zevpn->neigh_table)) {
3345 0 : memset(&n_wctx, 0, sizeof(n_wctx));
3346 0 : n_wctx.zevpn = zevpn;
3347 0 : n_wctx.zvrf = zvrf;
3348 0 : hash_iterate(zevpn->neigh_table,
3349 : zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3350 : }
3351 :
3352 0 : if (num_valid_macs(zevpn)) {
3353 0 : memset(&m_wctx, 0, sizeof(m_wctx));
3354 0 : m_wctx.zevpn = zevpn;
3355 0 : m_wctx.zvrf = zvrf;
3356 0 : hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3357 : }
3358 :
3359 : }
3360 :
3361 0 : int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf)
3362 : {
3363 0 : void *args[1];
3364 :
3365 0 : if (!is_evpn_enabled())
3366 : return 0;
3367 :
3368 0 : args[0] = zvrf;
3369 :
3370 0 : hash_iterate(zvrf->evpn_table,
3371 : (void (*)(struct hash_bucket *, void *))
3372 : zevpn_clear_dup_detect_hash_vni_all, args);
3373 :
3374 0 : return 0;
3375 : }
3376 :
3377 0 : int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni)
3378 : {
3379 0 : struct zebra_evpn *zevpn;
3380 0 : struct mac_walk_ctx m_wctx;
3381 0 : struct neigh_walk_ctx n_wctx;
3382 :
3383 0 : if (!is_evpn_enabled())
3384 : return 0;
3385 :
3386 0 : zevpn = zebra_evpn_lookup(vni);
3387 0 : if (!zevpn) {
3388 0 : zlog_warn("VNI %u does not exist", vni);
3389 0 : return CMD_WARNING;
3390 : }
3391 :
3392 0 : if (hashcount(zevpn->neigh_table)) {
3393 0 : memset(&n_wctx, 0, sizeof(n_wctx));
3394 0 : n_wctx.zevpn = zevpn;
3395 0 : n_wctx.zvrf = zvrf;
3396 0 : hash_iterate(zevpn->neigh_table,
3397 : zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3398 : }
3399 :
3400 0 : if (num_valid_macs(zevpn)) {
3401 0 : memset(&m_wctx, 0, sizeof(m_wctx));
3402 0 : m_wctx.zevpn = zevpn;
3403 0 : m_wctx.zvrf = zvrf;
3404 0 : hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3405 : }
3406 :
3407 : return 0;
3408 : }
3409 :
3410 : /*
3411 : * Display MACs for a VNI from specific VTEP (VTY command handler).
3412 : */
3413 0 : void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
3414 : vni_t vni, struct in_addr vtep_ip,
3415 : bool use_json)
3416 : {
3417 0 : struct zebra_evpn *zevpn;
3418 0 : uint32_t num_macs;
3419 0 : struct mac_walk_ctx wctx;
3420 0 : json_object *json = NULL;
3421 0 : json_object *json_mac = NULL;
3422 :
3423 0 : if (!is_evpn_enabled())
3424 0 : return;
3425 0 : zevpn = zebra_evpn_lookup(vni);
3426 0 : if (!zevpn) {
3427 0 : if (use_json)
3428 0 : vty_out(vty, "{}\n");
3429 : else
3430 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
3431 0 : return;
3432 : }
3433 0 : num_macs = num_valid_macs(zevpn);
3434 0 : if (!num_macs)
3435 : return;
3436 :
3437 0 : if (use_json) {
3438 0 : json = json_object_new_object();
3439 0 : json_mac = json_object_new_object();
3440 : }
3441 :
3442 0 : memset(&wctx, 0, sizeof(wctx));
3443 0 : wctx.zevpn = zevpn;
3444 0 : wctx.vty = vty;
3445 0 : wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3446 0 : wctx.r_vtep_ip = vtep_ip;
3447 0 : wctx.json = json_mac;
3448 0 : hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, &wctx);
3449 :
3450 0 : if (use_json) {
3451 0 : json_object_int_add(json, "numMacs", wctx.count);
3452 0 : if (wctx.count)
3453 0 : json_object_object_add(json, "macs", json_mac);
3454 0 : vty_json(vty, json);
3455 : }
3456 : }
3457 :
3458 :
3459 : /*
3460 : * Display VNI information (VTY command handler).
3461 : *
3462 : * use_json flag indicates that output should be in JSON format.
3463 : * json_array is non NULL when JSON output needs to be aggregated (by the
3464 : * caller) and then printed, otherwise, JSON evpn vni info is printed
3465 : * right away.
3466 : */
3467 0 : void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
3468 : bool use_json, json_object *json_array)
3469 : {
3470 0 : json_object *json = NULL;
3471 0 : void *args[2];
3472 0 : struct zebra_l3vni *zl3vni = NULL;
3473 0 : struct zebra_evpn *zevpn = NULL;
3474 :
3475 0 : if (!is_evpn_enabled())
3476 0 : return;
3477 :
3478 0 : if (use_json)
3479 0 : json = json_object_new_object();
3480 :
3481 0 : args[0] = vty;
3482 0 : args[1] = json;
3483 :
3484 0 : zl3vni = zl3vni_lookup(vni);
3485 0 : if (zl3vni) {
3486 0 : zl3vni_print(zl3vni, (void *)args);
3487 : } else {
3488 0 : zevpn = zebra_evpn_lookup(vni);
3489 0 : if (zevpn)
3490 0 : zebra_evpn_print(zevpn, (void *)args);
3491 0 : else if (!json)
3492 0 : vty_out(vty, "%% VNI %u does not exist\n", vni);
3493 : }
3494 :
3495 0 : if (use_json) {
3496 : /*
3497 : * Each "json" object contains info about 1 VNI.
3498 : * When "json_array" is non-null, we aggreggate the json output
3499 : * into json_array and print it as a JSON array.
3500 : */
3501 0 : if (json_array)
3502 0 : json_object_array_add(json_array, json);
3503 : else
3504 0 : vty_json(vty, json);
3505 : }
3506 : }
3507 :
3508 : /* Display all global details for EVPN */
3509 0 : void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
3510 : {
3511 0 : int num_l2vnis = 0;
3512 0 : int num_l3vnis = 0;
3513 0 : int num_vnis = 0;
3514 0 : json_object *json = NULL;
3515 0 : struct zebra_vrf *zvrf = NULL;
3516 :
3517 0 : if (!is_evpn_enabled())
3518 : return;
3519 :
3520 0 : zvrf = zebra_vrf_get_evpn();
3521 :
3522 0 : num_l3vnis = hashcount(zrouter.l3vni_table);
3523 0 : num_l2vnis = hashcount(zvrf->evpn_table);
3524 0 : num_vnis = num_l2vnis + num_l3vnis;
3525 :
3526 0 : if (uj) {
3527 0 : json = json_object_new_object();
3528 0 : json_object_string_add(json, "advertiseGatewayMacip",
3529 0 : zvrf->advertise_gw_macip ? "Yes" : "No");
3530 0 : json_object_string_add(json, "advertiseSviMacip",
3531 0 : zvrf->advertise_svi_macip ? "Yes"
3532 : : "No");
3533 0 : json_object_string_add(json, "advertiseSviMac",
3534 : zebra_evpn_mh_do_adv_svi_mac() ? "Yes"
3535 : : "No");
3536 0 : json_object_int_add(json, "numVnis", num_vnis);
3537 0 : json_object_int_add(json, "numL2Vnis", num_l2vnis);
3538 0 : json_object_int_add(json, "numL3Vnis", num_l3vnis);
3539 0 : if (zebra_evpn_do_dup_addr_detect(zvrf))
3540 0 : json_object_boolean_true_add(json,
3541 : "isDuplicateAddrDetection");
3542 : else
3543 0 : json_object_boolean_false_add(json,
3544 : "isDuplicateAddrDetection");
3545 0 : json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
3546 0 : json_object_int_add(json, "detectionTime", zvrf->dad_time);
3547 0 : json_object_int_add(json, "detectionFreezeTime",
3548 0 : zvrf->dad_freeze_time);
3549 0 : zebra_evpn_mh_json(json);
3550 : } else {
3551 0 : vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
3552 0 : vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
3553 0 : vty_out(vty, "Advertise gateway mac-ip: %s\n",
3554 0 : zvrf->advertise_gw_macip ? "Yes" : "No");
3555 0 : vty_out(vty, "Advertise svi mac-ip: %s\n",
3556 0 : zvrf->advertise_svi_macip ? "Yes" : "No");
3557 0 : vty_out(vty, "Advertise svi mac: %s\n",
3558 : zebra_evpn_mh_do_adv_svi_mac() ? "Yes" : "No");
3559 0 : vty_out(vty, "Duplicate address detection: %s\n",
3560 0 : zebra_evpn_do_dup_addr_detect(zvrf) ? "Enable"
3561 : : "Disable");
3562 0 : vty_out(vty, " Detection max-moves %u, time %d\n",
3563 : zvrf->dad_max_moves, zvrf->dad_time);
3564 0 : if (zvrf->dad_freeze) {
3565 0 : if (zvrf->dad_freeze_time)
3566 0 : vty_out(vty, " Detection freeze %u\n",
3567 : zvrf->dad_freeze_time);
3568 : else
3569 0 : vty_out(vty, " Detection freeze %s\n",
3570 : "permanent");
3571 : }
3572 0 : zebra_evpn_mh_print(vty);
3573 : }
3574 :
3575 0 : if (uj)
3576 0 : vty_json(vty, json);
3577 : }
3578 :
3579 : /*
3580 : * Display VNI hash table (VTY command handler).
3581 : */
3582 0 : void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
3583 : bool use_json)
3584 : {
3585 0 : json_object *json = NULL;
3586 0 : void *args[2];
3587 :
3588 0 : if (!is_evpn_enabled())
3589 0 : return;
3590 :
3591 0 : if (use_json)
3592 0 : json = json_object_new_object();
3593 : else
3594 0 : vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
3595 : "Type", "VxLAN IF", "# MACs", "# ARPs",
3596 : "# Remote VTEPs", "Tenant VRF");
3597 :
3598 0 : args[0] = vty;
3599 0 : args[1] = json;
3600 :
3601 : /* Display all L2-VNIs */
3602 0 : hash_iterate(
3603 : zvrf->evpn_table,
3604 : (void (*)(struct hash_bucket *, void *))zebra_evpn_print_hash,
3605 : args);
3606 :
3607 : /* Display all L3-VNIs */
3608 0 : hash_iterate(zrouter.l3vni_table,
3609 : (void (*)(struct hash_bucket *, void *))zl3vni_print_hash,
3610 : args);
3611 :
3612 0 : if (use_json)
3613 0 : vty_json(vty, json);
3614 : }
3615 :
3616 0 : void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
3617 : {
3618 0 : struct stream *s;
3619 0 : int time = 0;
3620 0 : uint32_t max_moves = 0;
3621 0 : uint32_t freeze_time = 0;
3622 0 : bool dup_addr_detect = false;
3623 0 : bool freeze = false;
3624 0 : bool old_addr_detect;
3625 :
3626 0 : s = msg;
3627 0 : STREAM_GETL(s, dup_addr_detect);
3628 0 : STREAM_GETL(s, time);
3629 0 : STREAM_GETL(s, max_moves);
3630 0 : STREAM_GETL(s, freeze);
3631 0 : STREAM_GETL(s, freeze_time);
3632 :
3633 0 : old_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3634 0 : zvrf->dup_addr_detect = dup_addr_detect;
3635 0 : dup_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3636 :
3637 : /* DAD previous state was enabled, and new state is disable,
3638 : * clear all duplicate detected addresses.
3639 : */
3640 0 : if (old_addr_detect && !dup_addr_detect)
3641 0 : zebra_vxlan_clear_dup_detect_vni_all(zvrf);
3642 :
3643 0 : zvrf->dad_time = time;
3644 0 : zvrf->dad_max_moves = max_moves;
3645 0 : zvrf->dad_freeze = freeze;
3646 0 : zvrf->dad_freeze_time = freeze_time;
3647 :
3648 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3649 0 : zlog_debug(
3650 : "VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
3651 : vrf_id_to_name(zvrf->vrf->vrf_id),
3652 : dup_addr_detect ? "enable" : "disable",
3653 : zvrf->dad_max_moves, zvrf->dad_time,
3654 : zvrf->dad_freeze ? "enable" : "disable",
3655 : zvrf->dad_freeze_time);
3656 :
3657 0 : stream_failure:
3658 0 : return;
3659 : }
3660 :
3661 : /*
3662 : * Display VNI hash table in detail(VTY command handler).
3663 : */
3664 0 : void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
3665 : bool use_json)
3666 : {
3667 0 : json_object *json_array = NULL;
3668 0 : struct zebra_ns *zns = NULL;
3669 0 : struct zebra_evpn_show zes;
3670 :
3671 0 : if (!is_evpn_enabled())
3672 0 : return;
3673 :
3674 0 : zns = zebra_ns_lookup(NS_DEFAULT);
3675 0 : if (!zns)
3676 : return;
3677 :
3678 0 : if (use_json)
3679 0 : json_array = json_object_new_array();
3680 :
3681 0 : zes.vty = vty;
3682 0 : zes.json = json_array;
3683 0 : zes.zvrf = zvrf;
3684 0 : zes.use_json = use_json;
3685 :
3686 : /* Display all L2-VNIs */
3687 0 : hash_iterate(zvrf->evpn_table,
3688 : (void (*)(struct hash_bucket *,
3689 : void *))zebra_evpn_print_hash_detail,
3690 : &zes);
3691 :
3692 : /* Display all L3-VNIs */
3693 0 : hash_iterate(zrouter.l3vni_table,
3694 : (void (*)(struct hash_bucket *,
3695 : void *))zl3vni_print_hash_detail,
3696 : &zes);
3697 :
3698 0 : if (use_json)
3699 0 : vty_json(vty, json_array);
3700 : }
3701 :
3702 : /*
3703 : * Handle neighbor delete notification from the kernel (on a VLAN device
3704 : * / L3 interface). This may result in either the neighbor getting deleted
3705 : * from our database or being re-added to the kernel (if it is a valid
3706 : * remote neighbor).
3707 : */
3708 0 : int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
3709 : struct interface *link_if,
3710 : struct ipaddr *ip)
3711 : {
3712 0 : struct zebra_evpn *zevpn = NULL;
3713 0 : struct zebra_l3vni *zl3vni = NULL;
3714 :
3715 : /* check if this is a remote neigh entry corresponding to remote
3716 : * next-hop
3717 : */
3718 0 : zl3vni = zl3vni_from_svi(ifp, link_if);
3719 0 : if (zl3vni)
3720 0 : return zl3vni_local_nh_del(zl3vni, ip);
3721 :
3722 : /* We are only interested in neighbors on an SVI that resides on top
3723 : * of a VxLAN bridge.
3724 : */
3725 0 : zevpn = zebra_evpn_from_svi(ifp, link_if);
3726 0 : if (!zevpn) {
3727 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3728 0 : zlog_debug(
3729 : "%s: Del neighbor %pIA EVPN is not present for interface %s",
3730 : __func__, ip, ifp->name);
3731 0 : return 0;
3732 : }
3733 :
3734 0 : if (!zevpn->vxlan_if) {
3735 0 : zlog_debug(
3736 : "VNI %u hash %p doesn't have intf upon local neighbor DEL",
3737 : zevpn->vni, zevpn);
3738 0 : return -1;
3739 : }
3740 :
3741 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3742 0 : zlog_debug("Del neighbor %pIA intf %s(%u) -> L2-VNI %u",
3743 : ip, ifp->name, ifp->ifindex, zevpn->vni);
3744 :
3745 0 : return zebra_evpn_neigh_del_ip(zevpn, ip);
3746 : }
3747 :
3748 : /*
3749 : * Handle neighbor add or update notification from the kernel (on a VLAN
3750 : * device / L3 interface). This is typically for a local neighbor but can
3751 : * also be for a remote neighbor (e.g., ageout notification). It could
3752 : * also be a "move" scenario.
3753 : */
3754 0 : int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
3755 : struct interface *link_if,
3756 : struct ipaddr *ip,
3757 : struct ethaddr *macaddr,
3758 : uint16_t state,
3759 : bool is_ext,
3760 : bool is_router,
3761 : bool local_inactive, bool dp_static)
3762 : {
3763 0 : struct zebra_evpn *zevpn = NULL;
3764 0 : struct zebra_l3vni *zl3vni = NULL;
3765 :
3766 : /* check if this is a remote neigh entry corresponding to remote
3767 : * next-hop
3768 : */
3769 0 : zl3vni = zl3vni_from_svi(ifp, link_if);
3770 0 : if (zl3vni)
3771 0 : return zl3vni_local_nh_add_update(zl3vni, ip, state);
3772 :
3773 : /* We are only interested in neighbors on an SVI that resides on top
3774 : * of a VxLAN bridge.
3775 : */
3776 0 : zevpn = zebra_evpn_from_svi(ifp, link_if);
3777 0 : if (!zevpn)
3778 : return 0;
3779 :
3780 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
3781 0 : zlog_debug(
3782 : "Add/Update neighbor %pIA MAC %pEA intf %s(%u) state 0x%x %s%s%s%s-> L2-VNI %u",
3783 : ip, macaddr, ifp->name,
3784 : ifp->ifindex, state, is_ext ? "ext-learned " : "",
3785 : is_router ? "router " : "",
3786 : local_inactive ? "local_inactive " : "",
3787 : dp_static ? "peer_sync " : "", zevpn->vni);
3788 :
3789 : /* Is this about a local neighbor or a remote one? */
3790 0 : if (!is_ext)
3791 0 : return zebra_evpn_local_neigh_update(zevpn, ifp, ip, macaddr,
3792 : is_router, local_inactive,
3793 : dp_static);
3794 :
3795 0 : return zebra_evpn_remote_neigh_update(zevpn, ifp, ip, macaddr, state);
3796 : }
3797 :
3798 : static int32_t
3799 0 : zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
3800 : struct ethaddr *macaddr, uint16_t *ipa_len,
3801 : struct ipaddr *ip, struct in_addr *vtep_ip,
3802 : uint8_t *flags, uint32_t *seq, esi_t *esi)
3803 : {
3804 0 : uint16_t l = 0;
3805 :
3806 : /*
3807 : * Obtain each remote MACIP and process.
3808 : * Message contains VNI, followed by MAC followed by IP (if any)
3809 : * followed by remote VTEP IP.
3810 : */
3811 0 : memset(ip, 0, sizeof(*ip));
3812 0 : STREAM_GETL(s, *vni);
3813 0 : STREAM_GET(macaddr->octet, s, ETH_ALEN);
3814 0 : STREAM_GETW(s, *ipa_len);
3815 :
3816 0 : if (*ipa_len) {
3817 0 : if (*ipa_len == IPV4_MAX_BYTELEN)
3818 0 : ip->ipa_type = IPADDR_V4;
3819 0 : else if (*ipa_len == IPV6_MAX_BYTELEN)
3820 0 : ip->ipa_type = IPADDR_V6;
3821 : else {
3822 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3823 0 : zlog_debug(
3824 : "ipa_len *must* be %d or %d bytes in length not %d",
3825 : IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
3826 : *ipa_len);
3827 0 : goto stream_failure;
3828 : }
3829 :
3830 0 : STREAM_GET(&ip->ip.addr, s, *ipa_len);
3831 : }
3832 0 : l += 4 + ETH_ALEN + 4 + *ipa_len;
3833 0 : STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
3834 0 : l += IPV4_MAX_BYTELEN;
3835 :
3836 0 : if (add) {
3837 0 : STREAM_GETC(s, *flags);
3838 0 : STREAM_GETL(s, *seq);
3839 0 : l += 5;
3840 0 : STREAM_GET(esi, s, sizeof(esi_t));
3841 0 : l += sizeof(esi_t);
3842 : }
3843 :
3844 0 : return l;
3845 :
3846 : stream_failure:
3847 : return -1;
3848 : }
3849 :
3850 : /*
3851 : * Handle message from client to delete a remote MACIP for a VNI.
3852 : */
3853 0 : void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
3854 : {
3855 0 : struct stream *s;
3856 0 : vni_t vni;
3857 0 : struct ethaddr macaddr;
3858 0 : struct ipaddr ip;
3859 0 : struct in_addr vtep_ip;
3860 0 : uint16_t l = 0, ipa_len;
3861 0 : char buf1[INET6_ADDRSTRLEN];
3862 :
3863 0 : s = msg;
3864 :
3865 0 : while (l < hdr->length) {
3866 0 : int res_length = zebra_vxlan_remote_macip_helper(
3867 : false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
3868 : NULL, NULL);
3869 :
3870 0 : if (res_length == -1)
3871 0 : goto stream_failure;
3872 :
3873 0 : l += res_length;
3874 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3875 0 : zlog_debug(
3876 : "Recv MACIP DEL VNI %u MAC %pEA%s%s Remote VTEP %pI4 from %s",
3877 : vni, &macaddr,
3878 : ipa_len ? " IP " : "",
3879 : ipa_len ?
3880 : ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
3881 : &vtep_ip, zebra_route_string(client->proto));
3882 :
3883 : /* Enqueue to workqueue for processing */
3884 0 : zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
3885 : }
3886 :
3887 0 : stream_failure:
3888 0 : return;
3889 : }
3890 :
3891 : /*
3892 : * Handle message from client to add a remote MACIP for a VNI. This
3893 : * could be just the add of a MAC address or the add of a neighbor
3894 : * (IP+MAC).
3895 : */
3896 0 : void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
3897 : {
3898 0 : struct stream *s;
3899 0 : vni_t vni;
3900 0 : struct ethaddr macaddr;
3901 0 : struct ipaddr ip;
3902 0 : struct in_addr vtep_ip;
3903 0 : uint16_t l = 0, ipa_len;
3904 0 : uint8_t flags = 0;
3905 0 : uint32_t seq;
3906 0 : char buf1[INET6_ADDRSTRLEN];
3907 0 : esi_t esi;
3908 0 : char esi_buf[ESI_STR_LEN];
3909 :
3910 0 : if (!EVPN_ENABLED(zvrf)) {
3911 0 : zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
3912 0 : return;
3913 : }
3914 :
3915 : s = msg;
3916 :
3917 0 : while (l < hdr->length) {
3918 :
3919 0 : int res_length = zebra_vxlan_remote_macip_helper(
3920 : true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
3921 : &flags, &seq, &esi);
3922 :
3923 0 : if (res_length == -1)
3924 0 : goto stream_failure;
3925 :
3926 0 : l += res_length;
3927 0 : if (IS_ZEBRA_DEBUG_VXLAN) {
3928 0 : if (memcmp(&esi, zero_esi, sizeof(esi_t)))
3929 0 : esi_to_str(&esi, esi_buf, sizeof(esi_buf));
3930 : else
3931 0 : strlcpy(esi_buf, "-", ESI_STR_LEN);
3932 0 : zlog_debug(
3933 : "Recv %sMACIP ADD VNI %u MAC %pEA%s%s flags 0x%x seq %u VTEP %pI4 ESI %s from %s",
3934 : (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ?
3935 : "sync-" : "",
3936 : vni, &macaddr,
3937 : ipa_len ? " IP " : "",
3938 : ipa_len ?
3939 : ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
3940 : flags, seq, &vtep_ip, esi_buf,
3941 : zebra_route_string(client->proto));
3942 : }
3943 :
3944 : /* Enqueue to workqueue for processing */
3945 0 : zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags,
3946 : seq, vtep_ip, &esi);
3947 : }
3948 :
3949 0 : stream_failure:
3950 : return;
3951 : }
3952 :
3953 : /*
3954 : * Handle remote vtep delete by kernel; re-add the vtep if we have it
3955 : */
3956 0 : int zebra_vxlan_check_readd_vtep(struct interface *ifp,
3957 : struct in_addr vtep_ip)
3958 : {
3959 0 : struct zebra_if *zif;
3960 0 : struct zebra_vrf *zvrf = NULL;
3961 0 : struct zebra_l2info_vxlan *vxl;
3962 0 : vni_t vni;
3963 0 : struct zebra_evpn *zevpn = NULL;
3964 0 : struct zebra_vtep *zvtep = NULL;
3965 :
3966 0 : zif = ifp->info;
3967 0 : assert(zif);
3968 0 : vxl = &zif->l2info.vxl;
3969 0 : vni = vxl->vni;
3970 :
3971 : /* If EVPN is not enabled, nothing to do. */
3972 0 : if (!is_evpn_enabled())
3973 : return 0;
3974 :
3975 : /* Locate VRF corresponding to interface. */
3976 0 : zvrf = ifp->vrf->info;
3977 0 : if (!zvrf)
3978 : return -1;
3979 :
3980 : /* Locate hash entry; it is expected to exist. */
3981 0 : zevpn = zebra_evpn_lookup(vni);
3982 0 : if (!zevpn)
3983 : return 0;
3984 :
3985 : /* If the remote vtep entry doesn't exists nothing to do */
3986 0 : zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
3987 0 : if (!zvtep)
3988 : return 0;
3989 :
3990 0 : if (IS_ZEBRA_DEBUG_VXLAN)
3991 0 : zlog_debug(
3992 : "Del MAC for remote VTEP %pI4 intf %s(%u) VNI %u - readd",
3993 : &vtep_ip, ifp->name, ifp->ifindex, vni);
3994 :
3995 0 : zebra_evpn_vtep_install(zevpn, zvtep);
3996 0 : return 0;
3997 : }
3998 :
3999 : /*
4000 : * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
4001 : * us, this must involve a multihoming scenario. Treat this as implicit delete
4002 : * of any prior local MAC.
4003 : */
4004 0 : static int zebra_vxlan_check_del_local_mac(struct interface *ifp,
4005 : struct interface *br_if,
4006 : struct ethaddr *macaddr,
4007 : vlanid_t vid)
4008 : {
4009 0 : struct zebra_if *zif;
4010 0 : struct zebra_l2info_vxlan *vxl;
4011 0 : vni_t vni;
4012 0 : struct zebra_evpn *zevpn;
4013 0 : struct zebra_mac *mac;
4014 :
4015 0 : zif = ifp->info;
4016 0 : assert(zif);
4017 0 : vxl = &zif->l2info.vxl;
4018 0 : vni = vxl->vni;
4019 :
4020 : /* Check if EVPN is enabled. */
4021 0 : if (!is_evpn_enabled())
4022 : return 0;
4023 :
4024 : /* Locate hash entry; it is expected to exist. */
4025 0 : zevpn = zebra_evpn_lookup(vni);
4026 0 : if (!zevpn)
4027 : return 0;
4028 :
4029 : /* If entry doesn't exist, nothing to do. */
4030 0 : mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4031 0 : if (!mac)
4032 : return 0;
4033 :
4034 : /* Is it a local entry? */
4035 0 : if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4036 : return 0;
4037 :
4038 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4039 0 : zlog_debug(
4040 : "Add/update remote MAC %pEA intf %s(%u) VNI %u flags 0x%x - del local",
4041 : macaddr, ifp->name, ifp->ifindex, vni, mac->flags);
4042 :
4043 : /* Remove MAC from BGP. */
4044 0 : zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, mac->flags,
4045 : false /* force */);
4046 :
4047 : /*
4048 : * If there are no neigh associated with the mac delete the mac
4049 : * else mark it as AUTO for forward reference
4050 : */
4051 0 : if (!listcount(mac->neigh_list)) {
4052 0 : zebra_evpn_mac_del(zevpn, mac);
4053 : } else {
4054 0 : zebra_evpn_mac_clear_fwd_info(mac);
4055 0 : UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
4056 0 : UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
4057 0 : SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
4058 : }
4059 :
4060 : return 0;
4061 : }
4062 :
4063 : /* MAC notification from the dataplane with a network dest port -
4064 : * 1. This can be a local MAC on a down ES (if fast-failover is not possible
4065 : * 2. Or it can be a remote MAC
4066 : */
4067 0 : int zebra_vxlan_dp_network_mac_add(struct interface *ifp,
4068 : struct interface *br_if,
4069 : struct ethaddr *macaddr, vlanid_t vid,
4070 : uint32_t nhg_id, bool sticky, bool dp_static)
4071 : {
4072 0 : struct zebra_evpn_es *es;
4073 0 : struct interface *acc_ifp;
4074 :
4075 : /* If netlink message is with vid, it will have no nexthop.
4076 : * So skip it.
4077 : */
4078 0 : if (vid) {
4079 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4080 0 : zlog_debug("dpAdd MAC %pEA VID %u - ignore as no nhid",
4081 : macaddr, vid);
4082 0 : return 0;
4083 : }
4084 :
4085 : /* Get vxlan's vid for netlink message has no it. */
4086 0 : vid = ((struct zebra_if *)ifp->info)->l2info.vxl.access_vlan;
4087 :
4088 : /* if remote mac delete the local entry */
4089 0 : if (!nhg_id || !zebra_evpn_nhg_is_local_es(nhg_id, &es)
4090 0 : || !zebra_evpn_es_local_mac_via_network_port(es)) {
4091 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4092 0 : zlog_debug("dpAdd remote MAC %pEA VID %u", macaddr,
4093 : vid);
4094 0 : return zebra_vxlan_check_del_local_mac(ifp, br_if, macaddr,
4095 : vid);
4096 : }
4097 :
4098 : /* If local MAC on a down local ES translate the network-mac-add
4099 : * to a local-active-mac-add
4100 : */
4101 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4102 0 : zlog_debug("dpAdd local-nw-MAC %pEA VID %u", macaddr, vid);
4103 0 : acc_ifp = es->zif->ifp;
4104 0 : return zebra_vxlan_local_mac_add_update(
4105 : acc_ifp, br_if, macaddr, vid, sticky,
4106 : false /* local_inactive */, dp_static);
4107 : }
4108 :
4109 : /*
4110 : * Handle network MAC delete by kernel -
4111 : * 1. readd the remote MAC if we have it
4112 : * 2. local MAC with does ES may also need to be re-installed
4113 : */
4114 0 : int zebra_vxlan_dp_network_mac_del(struct interface *ifp,
4115 : struct interface *br_if,
4116 : struct ethaddr *macaddr, vlanid_t vid)
4117 : {
4118 0 : struct zebra_if *zif = NULL;
4119 0 : struct zebra_l2info_vxlan *vxl = NULL;
4120 0 : vni_t vni;
4121 0 : struct zebra_evpn *zevpn = NULL;
4122 0 : struct zebra_l3vni *zl3vni = NULL;
4123 0 : struct zebra_mac *mac = NULL;
4124 :
4125 0 : zif = ifp->info;
4126 0 : assert(zif);
4127 0 : vxl = &zif->l2info.vxl;
4128 0 : vni = vxl->vni;
4129 :
4130 : /* Check if EVPN is enabled. */
4131 0 : if (!is_evpn_enabled())
4132 : return 0;
4133 :
4134 : /* check if this is a remote RMAC and readd simillar to remote macs */
4135 0 : zl3vni = zl3vni_lookup(vni);
4136 0 : if (zl3vni)
4137 0 : return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
4138 :
4139 : /* Locate hash entry; it is expected to exist. */
4140 0 : zevpn = zebra_evpn_lookup(vni);
4141 0 : if (!zevpn)
4142 : return 0;
4143 :
4144 : /* If entry doesn't exist, nothing to do. */
4145 0 : mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4146 0 : if (!mac)
4147 : return 0;
4148 :
4149 0 : if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
4150 : /* If remote entry simply re-install */
4151 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4152 0 : zlog_debug(
4153 : "dpDel remote MAC %pEA intf %s(%u) VNI %u - readd",
4154 : macaddr, ifp->name, ifp->ifindex, vni);
4155 0 : zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
4156 0 : } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) && mac->es
4157 0 : && zebra_evpn_es_local_mac_via_network_port(mac->es)) {
4158 : /* If local entry via nw-port call local-del which will
4159 : * re-install entry in the dataplane is needed
4160 : */
4161 0 : if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4162 0 : zlog_debug("dpDel local-nw-MAC %pEA VNI %u", macaddr,
4163 : vni);
4164 :
4165 0 : zebra_evpn_del_local_mac(zevpn, mac, false);
4166 : }
4167 :
4168 : return 0;
4169 : }
4170 :
4171 : /*
4172 : * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
4173 : */
4174 0 : int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
4175 : struct ethaddr *macaddr, vlanid_t vid)
4176 : {
4177 0 : struct zebra_evpn *zevpn;
4178 0 : struct zebra_mac *mac;
4179 :
4180 : /* We are interested in MACs only on ports or (port, VLAN) that
4181 : * map to a VNI.
4182 : */
4183 0 : zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4184 0 : if (!zevpn)
4185 : return 0;
4186 0 : if (!zevpn->vxlan_if) {
4187 0 : zlog_debug(
4188 : "VNI %u hash %p doesn't have intf upon local MAC DEL",
4189 : zevpn->vni, zevpn);
4190 0 : return -1;
4191 : }
4192 :
4193 : /* If entry doesn't exist, nothing to do. */
4194 0 : mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4195 0 : if (!mac)
4196 : return 0;
4197 :
4198 : /* Is it a local entry? */
4199 0 : if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4200 : return 0;
4201 :
4202 0 : return zebra_evpn_del_local_mac(zevpn, mac, false);
4203 : }
4204 :
4205 : /*
4206 : * Handle local MAC add (on a port or VLAN corresponding to this VNI).
4207 : */
4208 0 : int zebra_vxlan_local_mac_add_update(struct interface *ifp,
4209 : struct interface *br_if,
4210 : struct ethaddr *macaddr, vlanid_t vid,
4211 : bool sticky, bool local_inactive,
4212 : bool dp_static)
4213 : {
4214 0 : struct zebra_evpn *zevpn;
4215 0 : struct zebra_vrf *zvrf;
4216 :
4217 0 : assert(ifp);
4218 :
4219 : /* We are interested in MACs only on ports or (port, VLAN) that
4220 : * map to an EVPN.
4221 : */
4222 0 : zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4223 0 : if (!zevpn) {
4224 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4225 0 : zlog_debug(
4226 : " Add/Update %sMAC %pEA intf %s(%u) VID %u, could not find EVPN",
4227 : sticky ? "sticky " : "", macaddr,
4228 : ifp->name, ifp->ifindex, vid);
4229 0 : return 0;
4230 : }
4231 :
4232 0 : if (!zevpn->vxlan_if) {
4233 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4234 0 : zlog_debug(
4235 : " VNI %u hash %p doesn't have intf upon local MAC ADD",
4236 : zevpn->vni, zevpn);
4237 0 : return -1;
4238 : }
4239 :
4240 0 : zvrf = zebra_vrf_get_evpn();
4241 0 : return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid,
4242 : sticky, local_inactive,
4243 : dp_static, NULL);
4244 : }
4245 :
4246 : /*
4247 : * Handle message from client to delete a remote VTEP for an EVPN.
4248 : */
4249 0 : void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS)
4250 : {
4251 0 : struct stream *s;
4252 0 : unsigned short l = 0;
4253 0 : vni_t vni;
4254 0 : struct in_addr vtep_ip;
4255 :
4256 0 : if (!is_evpn_enabled()) {
4257 0 : zlog_debug(
4258 : "%s: EVPN is not enabled yet we have received a VTEP DEL msg",
4259 : __func__);
4260 0 : return;
4261 : }
4262 :
4263 0 : if (!EVPN_ENABLED(zvrf)) {
4264 0 : zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u",
4265 : zvrf_id(zvrf));
4266 0 : return;
4267 : }
4268 :
4269 : s = msg;
4270 :
4271 0 : while (l < hdr->length) {
4272 0 : int flood_control __attribute__((unused));
4273 :
4274 : /* Obtain each remote VTEP and process. */
4275 0 : STREAM_GETL(s, vni);
4276 0 : l += 4;
4277 0 : STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4278 0 : l += IPV4_MAX_BYTELEN;
4279 :
4280 : /* Flood control is intentionally ignored right now */
4281 0 : STREAM_GETL(s, flood_control);
4282 0 : l += 4;
4283 :
4284 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4285 0 : zlog_debug("Recv VTEP DEL %pI4 VNI %u from %s",
4286 : &vtep_ip, vni,
4287 : zebra_route_string(client->proto));
4288 :
4289 : /* Enqueue for processing */
4290 0 : zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip);
4291 : }
4292 :
4293 0 : stream_failure:
4294 : return;
4295 : }
4296 :
4297 : /*
4298 : * Handle message from client to delete a remote VTEP for an EVPN.
4299 : */
4300 0 : void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni,
4301 : struct in_addr vtep_ip)
4302 : {
4303 0 : struct zebra_evpn *zevpn;
4304 0 : struct zebra_vtep *zvtep;
4305 0 : struct interface *ifp;
4306 0 : struct zebra_if *zif;
4307 0 : struct zebra_vrf *zvrf;
4308 :
4309 0 : if (!is_evpn_enabled()) {
4310 0 : zlog_debug("%s: Can't process vtep del: EVPN is not enabled",
4311 : __func__);
4312 0 : return;
4313 : }
4314 :
4315 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
4316 0 : if (!zvrf)
4317 : return;
4318 :
4319 0 : if (!EVPN_ENABLED(zvrf)) {
4320 0 : zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u",
4321 : zvrf_id(zvrf));
4322 0 : return;
4323 : }
4324 :
4325 : /* Locate VNI hash entry - expected to exist. */
4326 0 : zevpn = zebra_evpn_lookup(vni);
4327 0 : if (!zevpn) {
4328 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4329 0 : zlog_debug(
4330 : "Failed to locate VNI hash for remote VTEP DEL, VNI %u",
4331 : vni);
4332 0 : return;
4333 : }
4334 :
4335 0 : ifp = zevpn->vxlan_if;
4336 0 : if (!ifp) {
4337 0 : zlog_debug(
4338 : "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
4339 : zevpn->vni, zevpn);
4340 0 : return;
4341 : }
4342 0 : zif = ifp->info;
4343 :
4344 : /* If down or not mapped to a bridge, we're done. */
4345 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4346 : return;
4347 :
4348 : /* If the remote VTEP does not exist, there's nothing more to
4349 : * do.
4350 : * Otherwise, uninstall any remote MACs pointing to this VTEP
4351 : * and then, the VTEP entry itself and remove it.
4352 : */
4353 0 : zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4354 0 : if (!zvtep)
4355 : return;
4356 :
4357 0 : zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4358 0 : zebra_evpn_vtep_del(zevpn, zvtep);
4359 : }
4360 :
4361 : /*
4362 : * Handle message from client to add a remote VTEP for an EVPN.
4363 : */
4364 0 : void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
4365 : struct in_addr vtep_ip, int flood_control)
4366 : {
4367 0 : struct zebra_evpn *zevpn;
4368 0 : struct interface *ifp;
4369 0 : struct zebra_if *zif;
4370 0 : struct zebra_vtep *zvtep;
4371 0 : struct zebra_vrf *zvrf;
4372 :
4373 0 : if (!is_evpn_enabled()) {
4374 0 : zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD",
4375 : __func__);
4376 0 : return;
4377 : }
4378 :
4379 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
4380 0 : if (!zvrf)
4381 : return;
4382 :
4383 0 : if (!EVPN_ENABLED(zvrf)) {
4384 0 : zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u",
4385 : zvrf_id(zvrf));
4386 0 : return;
4387 : }
4388 :
4389 : /* Locate VNI hash entry - expected to exist. */
4390 0 : zevpn = zebra_evpn_lookup(vni);
4391 0 : if (!zevpn) {
4392 0 : flog_err(
4393 : EC_ZEBRA_VTEP_ADD_FAILED,
4394 : "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
4395 : vni);
4396 0 : return;
4397 : }
4398 :
4399 0 : ifp = zevpn->vxlan_if;
4400 0 : if (!ifp) {
4401 0 : flog_err(
4402 : EC_ZEBRA_VTEP_ADD_FAILED,
4403 : "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
4404 : zevpn->vni, zevpn);
4405 0 : return;
4406 : }
4407 :
4408 0 : zif = ifp->info;
4409 :
4410 : /* If down or not mapped to a bridge, we're done. */
4411 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4412 : return;
4413 :
4414 0 : zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4415 0 : if (zvtep) {
4416 : /* If the remote VTEP already exists check if
4417 : * the flood mode has changed
4418 : */
4419 0 : if (zvtep->flood_control != flood_control) {
4420 0 : if (zvtep->flood_control == VXLAN_FLOOD_DISABLED)
4421 : /* old mode was head-end-replication but
4422 : * is no longer; get rid of the HER fdb
4423 : * entry installed before
4424 : */
4425 0 : zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4426 0 : zvtep->flood_control = flood_control;
4427 0 : zebra_evpn_vtep_install(zevpn, zvtep);
4428 : }
4429 : } else {
4430 0 : zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, flood_control);
4431 0 : if (zvtep)
4432 0 : zebra_evpn_vtep_install(zevpn, zvtep);
4433 : else
4434 0 : flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
4435 : "Failed to add remote VTEP, VNI %u zevpn %p",
4436 : vni, zevpn);
4437 : }
4438 : }
4439 :
4440 : /*
4441 : * Handle message from client to add a remote VTEP for an EVPN.
4442 : */
4443 0 : void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS)
4444 : {
4445 0 : struct stream *s;
4446 0 : unsigned short l = 0;
4447 0 : vni_t vni;
4448 0 : struct in_addr vtep_ip;
4449 0 : int flood_control;
4450 :
4451 0 : if (!is_evpn_enabled()) {
4452 0 : zlog_debug(
4453 : "%s: EVPN not enabled yet we received a VTEP ADD zapi msg",
4454 : __func__);
4455 0 : return;
4456 : }
4457 :
4458 0 : if (!EVPN_ENABLED(zvrf)) {
4459 0 : zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u",
4460 : zvrf_id(zvrf));
4461 0 : return;
4462 : }
4463 :
4464 : s = msg;
4465 :
4466 0 : while (l < hdr->length) {
4467 : /* Obtain each remote VTEP and process. */
4468 0 : STREAM_GETL(s, vni);
4469 0 : l += 4;
4470 0 : STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4471 0 : STREAM_GETL(s, flood_control);
4472 0 : l += IPV4_MAX_BYTELEN + 4;
4473 :
4474 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4475 0 : zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s",
4476 : &vtep_ip, vni, flood_control,
4477 : zebra_route_string(client->proto));
4478 :
4479 : /* Enqueue for processing */
4480 0 : zebra_rib_queue_evpn_rem_vtep_add(zvrf_id(zvrf), vni, vtep_ip,
4481 : flood_control);
4482 : }
4483 :
4484 0 : stream_failure:
4485 : return;
4486 : }
4487 :
4488 : /*
4489 : * Add/Del gateway macip to evpn
4490 : * g/w can be:
4491 : * 1. SVI interface on a vlan aware bridge
4492 : * 2. SVI interface on a vlan unaware bridge
4493 : * 3. vrr interface (MACVLAN) associated to a SVI
4494 : * We advertise macip routes for an interface if it is associated to VxLan vlan
4495 : */
4496 22 : int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p,
4497 : int add)
4498 : {
4499 22 : struct ipaddr ip;
4500 22 : struct ethaddr macaddr;
4501 22 : struct zebra_evpn *zevpn = NULL;
4502 :
4503 22 : memset(&ip, 0, sizeof(ip));
4504 22 : memset(&macaddr, 0, sizeof(macaddr));
4505 :
4506 : /* Check if EVPN is enabled. */
4507 22 : if (!is_evpn_enabled())
4508 : return 0;
4509 :
4510 0 : if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4511 0 : struct interface *svi_if =
4512 : NULL; /* SVI corresponding to the MACVLAN */
4513 0 : struct zebra_if *ifp_zif =
4514 : NULL; /* Zebra daemon specific info for MACVLAN */
4515 0 : struct zebra_if *svi_if_zif =
4516 : NULL; /* Zebra daemon specific info for SVI*/
4517 :
4518 0 : ifp_zif = ifp->info;
4519 0 : if (!ifp_zif)
4520 : return -1;
4521 :
4522 : /*
4523 : * for a MACVLAN interface the link represents the svi_if
4524 : */
4525 0 : svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4526 0 : ifp_zif->link_ifindex);
4527 0 : if (!svi_if) {
4528 0 : zlog_debug("MACVLAN %s(%u) without link information",
4529 : ifp->name, ifp->ifindex);
4530 0 : return -1;
4531 : }
4532 :
4533 0 : if (IS_ZEBRA_IF_VLAN(svi_if)) {
4534 : /*
4535 : * If it is a vlan aware bridge then the link gives the
4536 : * bridge information
4537 : */
4538 0 : struct interface *svi_if_link = NULL;
4539 :
4540 0 : svi_if_zif = svi_if->info;
4541 0 : if (svi_if_zif) {
4542 0 : svi_if_link = if_lookup_by_index_per_ns(
4543 : zebra_ns_lookup(NS_DEFAULT),
4544 0 : svi_if_zif->link_ifindex);
4545 0 : zevpn = zebra_evpn_from_svi(svi_if,
4546 : svi_if_link);
4547 : }
4548 0 : } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
4549 : /*
4550 : * If it is a vlan unaware bridge then svi is the bridge
4551 : * itself
4552 : */
4553 0 : zevpn = zebra_evpn_from_svi(svi_if, svi_if);
4554 : }
4555 0 : } else if (IS_ZEBRA_IF_VLAN(ifp)) {
4556 0 : struct zebra_if *svi_if_zif =
4557 : NULL; /* Zebra daemon specific info for SVI */
4558 0 : struct interface *svi_if_link =
4559 : NULL; /* link info for the SVI = bridge info */
4560 :
4561 0 : svi_if_zif = ifp->info;
4562 0 : if (svi_if_zif) {
4563 0 : svi_if_link = if_lookup_by_index_per_ns(
4564 : zebra_ns_lookup(NS_DEFAULT),
4565 0 : svi_if_zif->link_ifindex);
4566 0 : if (svi_if_link)
4567 0 : zevpn = zebra_evpn_from_svi(ifp, svi_if_link);
4568 : }
4569 0 : } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
4570 0 : zevpn = zebra_evpn_from_svi(ifp, ifp);
4571 : }
4572 :
4573 0 : if (!zevpn)
4574 0 : return 0;
4575 :
4576 0 : if (!zevpn->vxlan_if) {
4577 0 : zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
4578 : zevpn->vni, zevpn);
4579 0 : return -1;
4580 : }
4581 :
4582 : /* VRR IP is advertised only if gw-macip-adv-enabled */
4583 0 : if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4584 0 : if (!advertise_gw_macip_enabled(zevpn))
4585 : return 0;
4586 : } else {
4587 : /* SVI IP is advertised if gw or svi macip-adv-enabled */
4588 0 : if (!advertise_svi_macip_enabled(zevpn)
4589 0 : && !advertise_gw_macip_enabled(zevpn))
4590 : return 0;
4591 : }
4592 :
4593 0 : memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
4594 :
4595 0 : if (p->family == AF_INET) {
4596 0 : ip.ipa_type = IPADDR_V4;
4597 0 : memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
4598 : sizeof(struct in_addr));
4599 0 : } else if (p->family == AF_INET6) {
4600 0 : ip.ipa_type = IPADDR_V6;
4601 0 : memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
4602 : sizeof(struct in6_addr));
4603 : }
4604 :
4605 :
4606 0 : if (add)
4607 0 : zebra_evpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
4608 : else
4609 0 : zebra_evpn_gw_macip_del(ifp, zevpn, &ip);
4610 :
4611 : return 0;
4612 : }
4613 :
4614 : /*
4615 : * Handle SVI interface going down.
4616 : * SVI can be associated to either L3-VNI or L2-VNI.
4617 : * For L2-VNI: At this point, this is a NOP since
4618 : * the kernel deletes the neighbor entries on this SVI (if any).
4619 : * We only need to update the vrf corresponding to zevpn.
4620 : * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
4621 : * from bgp
4622 : */
4623 0 : int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
4624 : {
4625 0 : struct zebra_l3vni *zl3vni = NULL;
4626 :
4627 0 : zl3vni = zl3vni_from_svi(ifp, link_if);
4628 0 : if (zl3vni) {
4629 :
4630 : /* process l3-vni down */
4631 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
4632 :
4633 : /* remove association with svi-if */
4634 0 : zl3vni->svi_if = NULL;
4635 : } else {
4636 0 : struct zebra_evpn *zevpn = NULL;
4637 :
4638 : /* Unlink the SVI from the access VLAN */
4639 0 : zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, false);
4640 :
4641 : /* since we dont have svi corresponding to zevpn, we associate it
4642 : * to default vrf. Note: the corresponding neigh entries on the
4643 : * SVI would have already been deleted */
4644 0 : zevpn = zebra_evpn_from_svi(ifp, link_if);
4645 :
4646 0 : if (zevpn) {
4647 : /* remove from l3-vni list */
4648 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4649 0 : if (zl3vni)
4650 0 : listnode_delete(zl3vni->l2vnis, zevpn);
4651 :
4652 0 : zevpn->svi_if = NULL;
4653 0 : zevpn->vrf_id = VRF_DEFAULT;
4654 :
4655 : /* update the tenant vrf in BGP */
4656 0 : if (if_is_operative(zevpn->vxlan_if))
4657 0 : zebra_evpn_send_add_to_client(zevpn);
4658 : }
4659 : }
4660 0 : return 0;
4661 : }
4662 :
4663 : /*
4664 : * Handle SVI interface coming up.
4665 : * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
4666 : * vxlan intf).
4667 : * For L2-VNI: we need to install any remote neighbors entried (used for
4668 : * arp-suppression)
4669 : * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
4670 : */
4671 0 : int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
4672 : {
4673 0 : struct zebra_evpn *zevpn = NULL;
4674 0 : struct zebra_l3vni *zl3vni = NULL;
4675 :
4676 0 : zl3vni = zl3vni_from_svi(ifp, link_if);
4677 0 : if (zl3vni) {
4678 :
4679 : /* associate with svi */
4680 0 : zl3vni->svi_if = ifp;
4681 :
4682 : /* process oper-up */
4683 0 : if (is_l3vni_oper_up(zl3vni))
4684 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
4685 : } else {
4686 :
4687 : /* process SVI up for l2-vni */
4688 0 : struct neigh_walk_ctx n_wctx;
4689 :
4690 0 : zevpn = zebra_evpn_from_svi(ifp, link_if);
4691 0 : if (!zevpn)
4692 0 : return 0;
4693 :
4694 0 : if (!zevpn->vxlan_if) {
4695 0 : zlog_debug(
4696 : "VNI %u hash %p doesn't have intf upon SVI up",
4697 : zevpn->vni, zevpn);
4698 0 : return -1;
4699 : }
4700 :
4701 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4702 0 : zlog_debug(
4703 : "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
4704 : ifp->name, ifp->ifindex, zevpn->vni,
4705 : ifp->vrf->name);
4706 :
4707 : /* update the vrf information for l2-vni and inform bgp */
4708 0 : zevpn->svi_if = ifp;
4709 0 : zevpn->vrf_id = ifp->vrf->vrf_id;
4710 :
4711 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4712 0 : if (zl3vni)
4713 0 : listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
4714 :
4715 0 : if (if_is_operative(zevpn->vxlan_if))
4716 0 : zebra_evpn_send_add_to_client(zevpn);
4717 :
4718 : /* Install any remote neighbors for this VNI. */
4719 0 : memset(&n_wctx, 0, sizeof(n_wctx));
4720 0 : n_wctx.zevpn = zevpn;
4721 0 : hash_iterate(zevpn->neigh_table, zebra_evpn_install_neigh_hash,
4722 : &n_wctx);
4723 :
4724 : /* Link the SVI from the access VLAN */
4725 0 : zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, true);
4726 :
4727 : /* Update MACIP routes created by advertise-svi-ip */
4728 0 : if (advertise_svi_macip_enabled(zevpn)) {
4729 0 : zebra_evpn_del_macip_for_intf(ifp, zevpn);
4730 0 : zebra_evpn_add_macip_for_intf(ifp, zevpn);
4731 : }
4732 : }
4733 :
4734 : return 0;
4735 : }
4736 :
4737 : /*
4738 : * Handle MAC-VLAN interface going down.
4739 : * L3VNI: When MAC-VLAN interface goes down,
4740 : * find its associated SVI and update type2/type-5 routes
4741 : * with SVI as RMAC
4742 : */
4743 0 : void zebra_vxlan_macvlan_down(struct interface *ifp)
4744 : {
4745 0 : struct zebra_l3vni *zl3vni = NULL;
4746 0 : struct zebra_if *zif, *link_zif;
4747 0 : struct interface *link_ifp, *link_if;
4748 :
4749 0 : zif = ifp->info;
4750 0 : assert(zif);
4751 0 : link_ifp = zif->link;
4752 0 : if (!link_ifp) {
4753 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4754 0 : zlog_debug(
4755 : "macvlan parent link is not found. Parent index %d ifp %s",
4756 : zif->link_ifindex,
4757 : ifindex2ifname(zif->link_ifindex,
4758 : ifp->vrf->vrf_id));
4759 0 : return;
4760 : }
4761 0 : link_zif = link_ifp->info;
4762 0 : assert(link_zif);
4763 :
4764 0 : link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4765 0 : link_zif->link_ifindex);
4766 :
4767 0 : zl3vni = zl3vni_from_svi(link_ifp, link_if);
4768 0 : if (zl3vni) {
4769 0 : zl3vni->mac_vlan_if = NULL;
4770 0 : if (is_l3vni_oper_up(zl3vni))
4771 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
4772 : }
4773 : }
4774 :
4775 : /*
4776 : * Handle MAC-VLAN interface going up.
4777 : * L3VNI: When MAC-VLAN interface comes up,
4778 : * find its associated SVI and update type-2 routes
4779 : * with MAC-VLAN's MAC as RMAC and for type-5 routes
4780 : * use SVI's MAC as RMAC.
4781 : */
4782 0 : void zebra_vxlan_macvlan_up(struct interface *ifp)
4783 : {
4784 0 : struct zebra_l3vni *zl3vni = NULL;
4785 0 : struct zebra_if *zif, *link_zif;
4786 0 : struct interface *link_ifp, *link_if;
4787 :
4788 0 : zif = ifp->info;
4789 0 : assert(zif);
4790 0 : link_ifp = zif->link;
4791 0 : link_zif = link_ifp->info;
4792 0 : assert(link_zif);
4793 :
4794 0 : link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4795 0 : link_zif->link_ifindex);
4796 0 : zl3vni = zl3vni_from_svi(link_ifp, link_if);
4797 0 : if (zl3vni) {
4798 : /* associate with macvlan (VRR) interface */
4799 0 : zl3vni->mac_vlan_if = ifp;
4800 :
4801 : /* process oper-up */
4802 0 : if (is_l3vni_oper_up(zl3vni))
4803 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
4804 : }
4805 0 : }
4806 :
4807 : /*
4808 : * Handle VxLAN interface down
4809 : */
4810 0 : int zebra_vxlan_if_down(struct interface *ifp)
4811 : {
4812 0 : vni_t vni;
4813 0 : struct zebra_if *zif = NULL;
4814 0 : struct zebra_l2info_vxlan *vxl = NULL;
4815 0 : struct zebra_l3vni *zl3vni = NULL;
4816 0 : struct zebra_evpn *zevpn;
4817 :
4818 : /* Check if EVPN is enabled. */
4819 0 : if (!is_evpn_enabled())
4820 : return 0;
4821 :
4822 0 : zif = ifp->info;
4823 0 : assert(zif);
4824 0 : vxl = &zif->l2info.vxl;
4825 0 : vni = vxl->vni;
4826 :
4827 0 : zl3vni = zl3vni_lookup(vni);
4828 0 : if (zl3vni) {
4829 : /* process-if-down for l3-vni */
4830 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4831 0 : zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
4832 : ifp->ifindex, vni);
4833 :
4834 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
4835 : } else {
4836 : /* process if-down for l2-vni */
4837 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4838 0 : zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
4839 : ifp->ifindex, vni);
4840 :
4841 : /* Locate hash entry; it is expected to exist. */
4842 0 : zevpn = zebra_evpn_lookup(vni);
4843 0 : if (!zevpn) {
4844 0 : zlog_debug(
4845 : "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
4846 : ifp->name, ifp->ifindex, vni);
4847 0 : return -1;
4848 : }
4849 :
4850 0 : assert(zevpn->vxlan_if == ifp);
4851 :
4852 : /* remove from l3-vni list */
4853 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4854 0 : if (zl3vni)
4855 0 : listnode_delete(zl3vni->l2vnis, zevpn);
4856 :
4857 : /* Delete this VNI from BGP. */
4858 0 : zebra_evpn_send_del_to_client(zevpn);
4859 :
4860 : /* Free up all neighbors and MACs, if any. */
4861 0 : zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
4862 0 : zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
4863 :
4864 : /* Free up all remote VTEPs, if any. */
4865 0 : zebra_evpn_vtep_del_all(zevpn, 1);
4866 : }
4867 : return 0;
4868 : }
4869 :
4870 : /*
4871 : * Handle VxLAN interface up - update BGP if required.
4872 : */
4873 0 : int zebra_vxlan_if_up(struct interface *ifp)
4874 : {
4875 0 : vni_t vni;
4876 0 : struct zebra_if *zif = NULL;
4877 0 : struct zebra_l2info_vxlan *vxl = NULL;
4878 0 : struct zebra_evpn *zevpn = NULL;
4879 0 : struct zebra_l3vni *zl3vni = NULL;
4880 :
4881 : /* Check if EVPN is enabled. */
4882 0 : if (!is_evpn_enabled())
4883 : return 0;
4884 :
4885 0 : zif = ifp->info;
4886 0 : assert(zif);
4887 0 : vxl = &zif->l2info.vxl;
4888 0 : vni = vxl->vni;
4889 :
4890 0 : zl3vni = zl3vni_lookup(vni);
4891 0 : if (zl3vni) {
4892 : /* we need to associate with SVI, if any, we can associate with
4893 : * svi-if only after association with vxlan-intf is complete
4894 : */
4895 0 : zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
4896 0 : zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
4897 :
4898 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4899 0 : zlog_debug("Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s"
4900 : , ifp->name, ifp->ifindex, vni,
4901 : zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
4902 : zl3vni->mac_vlan_if ?
4903 : zl3vni->mac_vlan_if->name : "NIL");
4904 :
4905 0 : if (is_l3vni_oper_up(zl3vni))
4906 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
4907 : } else {
4908 : /* Handle L2-VNI add */
4909 0 : struct interface *vlan_if = NULL;
4910 :
4911 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4912 0 : zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
4913 : ifp->ifindex, vni);
4914 :
4915 : /* Locate hash entry; it is expected to exist. */
4916 0 : zevpn = zebra_evpn_lookup(vni);
4917 0 : if (!zevpn) {
4918 0 : zlog_debug(
4919 : "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
4920 : ifp->name, ifp->ifindex, vni);
4921 0 : return -1;
4922 : }
4923 :
4924 0 : assert(zevpn->vxlan_if == ifp);
4925 0 : vlan_if = zvni_map_to_svi(vxl->access_vlan,
4926 : zif->brslave_info.br_if);
4927 0 : if (vlan_if) {
4928 0 : zevpn->svi_if = vlan_if;
4929 0 : zevpn->vrf_id = vlan_if->vrf->vrf_id;
4930 0 : zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
4931 0 : if (zl3vni)
4932 0 : listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
4933 : }
4934 :
4935 : /* If part of a bridge, inform BGP about this VNI. */
4936 : /* Also, read and populate local MACs and neighbors. */
4937 0 : if (zif->brslave_info.br_if) {
4938 0 : zebra_evpn_send_add_to_client(zevpn);
4939 0 : zebra_evpn_read_mac_neigh(zevpn, ifp);
4940 : }
4941 : }
4942 :
4943 : return 0;
4944 : }
4945 :
4946 : /*
4947 : * Handle VxLAN interface delete. Locate and remove entry in hash table
4948 : * and update BGP, if required.
4949 : */
4950 0 : int zebra_vxlan_if_del(struct interface *ifp)
4951 : {
4952 0 : vni_t vni;
4953 0 : struct zebra_if *zif = NULL;
4954 0 : struct zebra_l2info_vxlan *vxl = NULL;
4955 0 : struct zebra_evpn *zevpn = NULL;
4956 0 : struct zebra_l3vni *zl3vni = NULL;
4957 :
4958 : /* Check if EVPN is enabled. */
4959 0 : if (!is_evpn_enabled())
4960 : return 0;
4961 :
4962 0 : zif = ifp->info;
4963 0 : assert(zif);
4964 0 : vxl = &zif->l2info.vxl;
4965 0 : vni = vxl->vni;
4966 :
4967 0 : zl3vni = zl3vni_lookup(vni);
4968 0 : if (zl3vni) {
4969 :
4970 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4971 0 : zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
4972 : ifp->ifindex);
4973 :
4974 : /* process oper-down for l3-vni */
4975 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
4976 :
4977 : /* remove the association with vxlan_if */
4978 0 : memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
4979 0 : zl3vni->vxlan_if = NULL;
4980 : } else {
4981 :
4982 : /* process if-del for l2-vni*/
4983 0 : if (IS_ZEBRA_DEBUG_VXLAN)
4984 0 : zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name,
4985 : ifp->ifindex);
4986 :
4987 : /* Locate hash entry; it is expected to exist. */
4988 0 : zevpn = zebra_evpn_lookup(vni);
4989 0 : if (!zevpn) {
4990 0 : zlog_debug(
4991 : "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
4992 : ifp->name, ifp->ifindex, vni);
4993 0 : return 0;
4994 : }
4995 :
4996 : /* remove from l3-vni list */
4997 0 : zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4998 0 : if (zl3vni)
4999 0 : listnode_delete(zl3vni->l2vnis, zevpn);
5000 : /* Delete VNI from BGP. */
5001 0 : zebra_evpn_send_del_to_client(zevpn);
5002 :
5003 : /* Free up all neighbors and MAC, if any. */
5004 0 : zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
5005 0 : zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
5006 :
5007 : /* Free up all remote VTEPs, if any. */
5008 0 : zebra_evpn_vtep_del_all(zevpn, 0);
5009 :
5010 : /* Delete the hash entry. */
5011 0 : if (zebra_evpn_vxlan_del(zevpn)) {
5012 0 : flog_err(EC_ZEBRA_VNI_DEL_FAILED,
5013 : "Failed to del EVPN hash %p, IF %s(%u) VNI %u",
5014 : zevpn, ifp->name, ifp->ifindex, zevpn->vni);
5015 0 : return -1;
5016 : }
5017 : }
5018 : return 0;
5019 : }
5020 :
5021 : /*
5022 : * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
5023 : */
5024 0 : int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
5025 : {
5026 0 : vni_t vni;
5027 0 : struct zebra_if *zif = NULL;
5028 0 : struct zebra_l2info_vxlan *vxl = NULL;
5029 0 : struct zebra_evpn *zevpn = NULL;
5030 0 : struct zebra_l3vni *zl3vni = NULL;
5031 0 : struct interface *vlan_if = NULL;
5032 :
5033 : /* Check if EVPN is enabled. */
5034 0 : if (!is_evpn_enabled())
5035 : return 0;
5036 :
5037 0 : zif = ifp->info;
5038 0 : assert(zif);
5039 0 : vxl = &zif->l2info.vxl;
5040 0 : vni = vxl->vni;
5041 :
5042 0 : zl3vni = zl3vni_lookup(vni);
5043 0 : if (zl3vni) {
5044 :
5045 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5046 0 : zlog_debug(
5047 : "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
5048 : vni, ifp->name, ifp->ifindex, vxl->access_vlan,
5049 : &vxl->vtep_ip,
5050 : zif->brslave_info.bridge_ifindex, chgflags);
5051 :
5052 : /* Removed from bridge? Cleanup and return */
5053 0 : if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5054 0 : && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
5055 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5056 0 : return 0;
5057 : }
5058 :
5059 0 : if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE)
5060 0 : && if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) {
5061 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5062 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
5063 0 : return 0;
5064 : }
5065 :
5066 : /* access-vlan change - process oper down, associate with new
5067 : * svi_if and then process oper up again
5068 : */
5069 0 : if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5070 0 : if (if_is_operative(ifp)) {
5071 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5072 0 : zl3vni->svi_if = NULL;
5073 0 : zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5074 0 : zl3vni->mac_vlan_if =
5075 0 : zl3vni_map_to_mac_vlan_if(zl3vni);
5076 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
5077 0 : if (is_l3vni_oper_up(zl3vni))
5078 0 : zebra_vxlan_process_l3vni_oper_up(
5079 : zl3vni);
5080 : }
5081 : }
5082 :
5083 : /*
5084 : * local-ip change - process oper down, associate with new
5085 : * local-ip and then process oper up again
5086 : */
5087 0 : if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) {
5088 0 : if (if_is_operative(ifp)) {
5089 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5090 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
5091 0 : if (is_l3vni_oper_up(zl3vni))
5092 0 : zebra_vxlan_process_l3vni_oper_up(
5093 : zl3vni);
5094 : }
5095 : }
5096 :
5097 : /* Update local tunnel IP. */
5098 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
5099 :
5100 : /* if we have a valid new master, process l3-vni oper up */
5101 0 : if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
5102 0 : if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni))
5103 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
5104 : }
5105 : } else {
5106 :
5107 : /* Update VNI hash. */
5108 0 : zevpn = zebra_evpn_lookup(vni);
5109 0 : if (!zevpn) {
5110 0 : zlog_debug(
5111 : "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
5112 : ifp->name, ifp->ifindex, vni);
5113 0 : return -1;
5114 : }
5115 :
5116 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5117 0 : zlog_debug(
5118 : "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
5119 : vni, ifp->name, ifp->ifindex, vxl->access_vlan,
5120 : &vxl->vtep_ip,
5121 : zif->brslave_info.bridge_ifindex, chgflags);
5122 :
5123 : /* Removed from bridge? Cleanup and return */
5124 0 : if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5125 0 : && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
5126 : /* Delete from client, remove all remote VTEPs */
5127 : /* Also, free up all MACs and neighbors. */
5128 0 : zevpn->svi_if = NULL;
5129 0 : zebra_evpn_send_del_to_client(zevpn);
5130 0 : zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
5131 0 : zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
5132 0 : zebra_evpn_vtep_del_all(zevpn, 1);
5133 0 : return 0;
5134 : }
5135 :
5136 : /* Handle other changes. */
5137 0 : if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5138 : /* Remove all existing local neigh and MACs for this VNI
5139 : * (including from BGP)
5140 : */
5141 0 : zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
5142 0 : zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
5143 : }
5144 :
5145 0 : if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
5146 0 : zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
5147 0 : zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
5148 : zevpn->mcast_grp);
5149 0 : zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
5150 0 : zevpn->local_vtep_ip = vxl->vtep_ip;
5151 0 : zevpn->mcast_grp = vxl->mcast_grp;
5152 : /* on local vtep-ip check if ES orig-ip
5153 : * needs to be updated
5154 : */
5155 0 : zebra_evpn_es_set_base_evpn(zevpn);
5156 : }
5157 0 : zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
5158 0 : vlan_if = zvni_map_to_svi(vxl->access_vlan,
5159 : zif->brslave_info.br_if);
5160 0 : if (vlan_if) {
5161 0 : zevpn->svi_if = vlan_if;
5162 0 : zevpn->vrf_id = vlan_if->vrf->vrf_id;
5163 0 : zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
5164 0 : if (zl3vni)
5165 0 : listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
5166 : }
5167 :
5168 : /* Take further actions needed.
5169 : * Note that if we are here, there is a change of interest.
5170 : */
5171 : /* If down or not mapped to a bridge, we're done. */
5172 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5173 : return 0;
5174 :
5175 : /* Inform BGP, if there is a change of interest. */
5176 0 : if (chgflags &
5177 : (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE |
5178 : ZEBRA_VXLIF_MCAST_GRP_CHANGE | ZEBRA_VXLIF_VLAN_CHANGE))
5179 0 : zebra_evpn_send_add_to_client(zevpn);
5180 :
5181 : /* If there is a valid new master or a VLAN mapping change,
5182 : * read and populate local MACs and neighbors.
5183 : * Also, reinstall any remote MACs and neighbors
5184 : * for this VNI (based on new VLAN).
5185 : */
5186 0 : if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5187 0 : zebra_evpn_read_mac_neigh(zevpn, ifp);
5188 0 : else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5189 0 : struct mac_walk_ctx m_wctx;
5190 0 : struct neigh_walk_ctx n_wctx;
5191 :
5192 0 : zebra_evpn_read_mac_neigh(zevpn, ifp);
5193 :
5194 0 : memset(&m_wctx, 0, sizeof(m_wctx));
5195 0 : m_wctx.zevpn = zevpn;
5196 0 : hash_iterate(zevpn->mac_table,
5197 : zebra_evpn_install_mac_hash, &m_wctx);
5198 :
5199 0 : memset(&n_wctx, 0, sizeof(n_wctx));
5200 0 : n_wctx.zevpn = zevpn;
5201 0 : hash_iterate(zevpn->neigh_table,
5202 : zebra_evpn_install_neigh_hash, &n_wctx);
5203 : }
5204 : }
5205 :
5206 : return 0;
5207 : }
5208 :
5209 : /*
5210 : * Handle VxLAN interface add.
5211 : */
5212 0 : int zebra_vxlan_if_add(struct interface *ifp)
5213 : {
5214 0 : vni_t vni;
5215 0 : struct zebra_if *zif = NULL;
5216 0 : struct zebra_l2info_vxlan *vxl = NULL;
5217 0 : struct zebra_evpn *zevpn = NULL;
5218 0 : struct zebra_l3vni *zl3vni = NULL;
5219 :
5220 : /* Check if EVPN is enabled. */
5221 0 : if (!is_evpn_enabled())
5222 : return 0;
5223 :
5224 0 : zif = ifp->info;
5225 0 : assert(zif);
5226 0 : vxl = &zif->l2info.vxl;
5227 0 : vni = vxl->vni;
5228 :
5229 0 : zl3vni = zl3vni_lookup(vni);
5230 0 : if (zl3vni) {
5231 :
5232 : /* process if-add for l3-vni*/
5233 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5234 0 : zlog_debug(
5235 : "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
5236 : vni, ifp->name, ifp->ifindex, vxl->access_vlan,
5237 : &vxl->vtep_ip,
5238 : zif->brslave_info.bridge_ifindex);
5239 :
5240 : /* associate with vxlan_if */
5241 0 : zl3vni->local_vtep_ip = vxl->vtep_ip;
5242 0 : zl3vni->vxlan_if = ifp;
5243 :
5244 : /* Associate with SVI, if any. We can associate with svi-if only
5245 : * after association with vxlan_if is complete */
5246 0 : zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5247 :
5248 0 : zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
5249 :
5250 0 : if (is_l3vni_oper_up(zl3vni))
5251 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
5252 : } else {
5253 :
5254 : /* process if-add for l2-vni */
5255 0 : struct interface *vlan_if = NULL;
5256 :
5257 : /* Create or update EVPN hash. */
5258 0 : zevpn = zebra_evpn_lookup(vni);
5259 0 : if (!zevpn)
5260 0 : zevpn = zebra_evpn_add(vni);
5261 :
5262 0 : if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
5263 0 : zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
5264 0 : zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
5265 : zevpn->mcast_grp);
5266 0 : zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
5267 0 : zevpn->local_vtep_ip = vxl->vtep_ip;
5268 0 : zevpn->mcast_grp = vxl->mcast_grp;
5269 : /* on local vtep-ip check if ES orig-ip
5270 : * needs to be updated
5271 : */
5272 0 : zebra_evpn_es_set_base_evpn(zevpn);
5273 : }
5274 0 : zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
5275 0 : vlan_if = zvni_map_to_svi(vxl->access_vlan,
5276 : zif->brslave_info.br_if);
5277 0 : if (vlan_if) {
5278 0 : zevpn->svi_if = vlan_if;
5279 0 : zevpn->vrf_id = vlan_if->vrf->vrf_id;
5280 0 : zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
5281 0 : if (zl3vni)
5282 0 : listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
5283 : }
5284 :
5285 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5286 0 : zlog_debug(
5287 : "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
5288 : vni,
5289 : vlan_if ? vlan_if->vrf->name : VRF_DEFAULT_NAME,
5290 : ifp->name, ifp->ifindex, vxl->access_vlan,
5291 : &vxl->vtep_ip, &vxl->mcast_grp,
5292 : zif->brslave_info.bridge_ifindex);
5293 :
5294 : /* If down or not mapped to a bridge, we're done. */
5295 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5296 : return 0;
5297 :
5298 : /* Inform BGP */
5299 0 : zebra_evpn_send_add_to_client(zevpn);
5300 :
5301 : /* Read and populate local MACs and neighbors */
5302 0 : zebra_evpn_read_mac_neigh(zevpn, ifp);
5303 : }
5304 :
5305 : return 0;
5306 : }
5307 :
5308 0 : int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
5309 : char *err, int err_str_sz, int filter,
5310 : int add)
5311 : {
5312 0 : struct zebra_l3vni *zl3vni = NULL;
5313 0 : struct zebra_vrf *zvrf_evpn = NULL;
5314 :
5315 0 : zvrf_evpn = zebra_vrf_get_evpn();
5316 :
5317 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5318 0 : zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
5319 : add ? "ADD" : "DEL");
5320 :
5321 0 : if (add) {
5322 : /* check if the vni is already present under zvrf */
5323 0 : if (zvrf->l3vni) {
5324 0 : snprintf(err, err_str_sz,
5325 : "VNI is already configured under the vrf");
5326 0 : return -1;
5327 : }
5328 :
5329 : /* check if this VNI is already present in the system */
5330 0 : zl3vni = zl3vni_lookup(vni);
5331 0 : if (zl3vni) {
5332 0 : snprintf(err, err_str_sz,
5333 : "VNI is already configured as L3-VNI");
5334 0 : return -1;
5335 : }
5336 :
5337 : /* Remove L2VNI if present */
5338 0 : zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5339 :
5340 : /* add the L3-VNI to the global table */
5341 0 : zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
5342 :
5343 : /* associate the vrf with vni */
5344 0 : zvrf->l3vni = vni;
5345 :
5346 : /* set the filter in l3vni to denote if we are using l3vni only
5347 : * for prefix routes
5348 : */
5349 0 : if (filter)
5350 0 : SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
5351 :
5352 : /* associate with vxlan-intf;
5353 : * we need to associate with the vxlan-intf first
5354 : */
5355 0 : zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
5356 :
5357 : /* associate with corresponding SVI interface, we can associate
5358 : * with svi-if only after vxlan interface association is
5359 : * complete
5360 : */
5361 0 : zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5362 :
5363 0 : zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
5364 :
5365 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5366 0 : zlog_debug(
5367 : "%s: l3vni %u svi_if %s mac_vlan_if %s",
5368 : __func__, vni,
5369 : zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
5370 : zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
5371 : : "NIL");
5372 :
5373 : /* formulate l2vni list */
5374 0 : hash_iterate(zvrf_evpn->evpn_table, zevpn_add_to_l3vni_list,
5375 : zl3vni);
5376 :
5377 0 : if (is_l3vni_oper_up(zl3vni))
5378 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
5379 :
5380 : } else {
5381 0 : zl3vni = zl3vni_lookup(vni);
5382 0 : if (!zl3vni) {
5383 0 : snprintf(err, err_str_sz, "VNI doesn't exist");
5384 0 : return -1;
5385 : }
5386 :
5387 0 : if (zvrf->l3vni != vni) {
5388 0 : snprintf(err, err_str_sz,
5389 : "VNI %d doesn't exist in VRF: %s",
5390 0 : vni, zvrf->vrf->name);
5391 0 : return -1;
5392 : }
5393 :
5394 0 : if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
5395 0 : snprintf(err, ERR_STR_SZ,
5396 : "prefix-routes-only is not set for the vni");
5397 0 : return -1;
5398 : }
5399 :
5400 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5401 :
5402 : /* delete and uninstall all rmacs */
5403 0 : hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
5404 : zl3vni);
5405 :
5406 : /* delete and uninstall all next-hops */
5407 0 : hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
5408 : zl3vni);
5409 :
5410 0 : zvrf->l3vni = 0;
5411 0 : zl3vni_del(zl3vni);
5412 :
5413 : /* Add L2VNI for this VNI */
5414 0 : zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5415 : }
5416 : return 0;
5417 : }
5418 :
5419 2 : int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
5420 : {
5421 2 : struct zebra_l3vni *zl3vni = NULL;
5422 :
5423 2 : if (zvrf->l3vni)
5424 0 : zl3vni = zl3vni_lookup(zvrf->l3vni);
5425 0 : if (!zl3vni)
5426 2 : return 0;
5427 :
5428 0 : zl3vni->vrf_id = zvrf_id(zvrf);
5429 0 : if (is_l3vni_oper_up(zl3vni))
5430 0 : zebra_vxlan_process_l3vni_oper_up(zl3vni);
5431 : return 0;
5432 : }
5433 :
5434 2 : int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
5435 : {
5436 2 : struct zebra_l3vni *zl3vni = NULL;
5437 :
5438 2 : if (zvrf->l3vni)
5439 0 : zl3vni = zl3vni_lookup(zvrf->l3vni);
5440 0 : if (!zl3vni)
5441 2 : return 0;
5442 :
5443 0 : zebra_vxlan_process_l3vni_oper_down(zl3vni);
5444 :
5445 : /* delete and uninstall all rmacs */
5446 0 : hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry, zl3vni);
5447 : /* delete and uninstall all next-hops */
5448 0 : hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry, zl3vni);
5449 :
5450 0 : zl3vni->vrf_id = VRF_UNKNOWN;
5451 :
5452 0 : return 0;
5453 : }
5454 :
5455 2 : int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
5456 : {
5457 2 : struct zebra_l3vni *zl3vni = NULL;
5458 2 : vni_t vni;
5459 :
5460 2 : if (zvrf->l3vni)
5461 0 : zl3vni = zl3vni_lookup(zvrf->l3vni);
5462 0 : if (!zl3vni)
5463 2 : return 0;
5464 :
5465 0 : vni = zl3vni->vni;
5466 0 : zl3vni_del(zl3vni);
5467 0 : zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
5468 :
5469 0 : return 0;
5470 : }
5471 :
5472 : /*
5473 : * Handle message from client to specify the flooding mechanism for
5474 : * BUM packets. The default is to do head-end (ingress) replication
5475 : * and the other supported option is to disable it. This applies to
5476 : * all BUM traffic and disabling it applies to both the transmit and
5477 : * receive direction.
5478 : */
5479 0 : void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
5480 : {
5481 0 : struct stream *s;
5482 0 : enum vxlan_flood_control flood_ctrl;
5483 :
5484 0 : if (!EVPN_ENABLED(zvrf)) {
5485 0 : zlog_err("EVPN flood control for non-EVPN VRF %u",
5486 : zvrf_id(zvrf));
5487 0 : return;
5488 : }
5489 :
5490 0 : s = msg;
5491 0 : STREAM_GETC(s, flood_ctrl);
5492 :
5493 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5494 0 : zlog_debug("EVPN flood control %u, currently %u",
5495 : flood_ctrl, zvrf->vxlan_flood_ctrl);
5496 :
5497 0 : if (zvrf->vxlan_flood_ctrl == flood_ctrl)
5498 : return;
5499 :
5500 0 : zvrf->vxlan_flood_ctrl = flood_ctrl;
5501 :
5502 : /* Install or uninstall flood entries corresponding to
5503 : * remote VTEPs.
5504 : */
5505 0 : hash_iterate(zvrf->evpn_table, zebra_evpn_handle_flooding_remote_vteps,
5506 : zvrf);
5507 :
5508 0 : stream_failure:
5509 : return;
5510 : }
5511 :
5512 : /*
5513 : * Handle message from client to enable/disable advertisement of svi macip
5514 : * routes
5515 : */
5516 0 : void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
5517 : {
5518 0 : struct stream *s;
5519 0 : int advertise;
5520 0 : vni_t vni = 0;
5521 0 : struct zebra_evpn *zevpn = NULL;
5522 0 : struct interface *ifp = NULL;
5523 :
5524 0 : if (!EVPN_ENABLED(zvrf)) {
5525 0 : zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
5526 : zvrf_id(zvrf));
5527 0 : return;
5528 : }
5529 :
5530 0 : s = msg;
5531 0 : STREAM_GETC(s, advertise);
5532 0 : STREAM_GETL(s, vni);
5533 :
5534 0 : if (!vni) {
5535 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5536 0 : zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
5537 : advertise ? "enabled" : "disabled",
5538 : advertise_svi_macip_enabled(NULL)
5539 : ? "enabled"
5540 : : "disabled");
5541 :
5542 0 : if (zvrf->advertise_svi_macip == advertise)
5543 : return;
5544 :
5545 :
5546 0 : if (advertise) {
5547 0 : zvrf->advertise_svi_macip = advertise;
5548 0 : hash_iterate(zvrf->evpn_table,
5549 : zebra_evpn_gw_macip_add_for_evpn_hash,
5550 : NULL);
5551 : } else {
5552 0 : hash_iterate(zvrf->evpn_table,
5553 : zebra_evpn_svi_macip_del_for_evpn_hash,
5554 : NULL);
5555 0 : zvrf->advertise_svi_macip = advertise;
5556 : }
5557 :
5558 : } else {
5559 0 : struct zebra_if *zif = NULL;
5560 0 : struct zebra_l2info_vxlan zl2_info;
5561 0 : struct interface *vlan_if = NULL;
5562 0 : int old_advertise;
5563 :
5564 0 : zevpn = zebra_evpn_lookup(vni);
5565 0 : if (!zevpn)
5566 0 : return;
5567 :
5568 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5569 0 : zlog_debug(
5570 : "EVPN SVI macip Adv %s on VNI %d, currently %s",
5571 : advertise ? "enabled" : "disabled", vni,
5572 : advertise_svi_macip_enabled(zevpn)
5573 : ? "enabled"
5574 : : "disabled");
5575 :
5576 0 : old_advertise = advertise_svi_macip_enabled(zevpn);
5577 :
5578 : /* Store flag even though SVI is not present.
5579 : * Once SVI comes up triggers self MAC-IP route add.
5580 : */
5581 0 : zevpn->advertise_svi_macip = advertise;
5582 0 : if (advertise_svi_macip_enabled(zevpn) == old_advertise)
5583 : return;
5584 :
5585 0 : ifp = zevpn->vxlan_if;
5586 0 : if (!ifp)
5587 : return;
5588 :
5589 0 : zif = ifp->info;
5590 :
5591 : /* If down or not mapped to a bridge, we're done. */
5592 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5593 : return;
5594 :
5595 0 : zl2_info = zif->l2info.vxl;
5596 0 : vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
5597 : zif->brslave_info.br_if);
5598 0 : if (!vlan_if)
5599 : return;
5600 :
5601 0 : if (advertise) {
5602 : /* Add primary SVI MAC-IP */
5603 0 : zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5604 : } else {
5605 : /* Del primary SVI MAC-IP */
5606 0 : zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5607 : }
5608 : }
5609 :
5610 0 : stream_failure:
5611 : return;
5612 : }
5613 :
5614 : /*
5615 : * Handle message from client to enable/disable advertisement of g/w macip
5616 : * routes
5617 : */
5618 0 : void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
5619 : {
5620 0 : struct stream *s;
5621 0 : int advertise;
5622 0 : vni_t vni = 0;
5623 0 : struct zebra_evpn *zevpn = NULL;
5624 0 : struct interface *ifp = NULL;
5625 0 : struct zebra_if *zif = NULL;
5626 0 : struct zebra_l2info_vxlan zl2_info;
5627 0 : struct interface *vlan_if = NULL;
5628 :
5629 0 : if (!EVPN_ENABLED(zvrf)) {
5630 0 : zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5631 : zvrf_id(zvrf));
5632 0 : return;
5633 : }
5634 :
5635 0 : s = msg;
5636 0 : STREAM_GETC(s, advertise);
5637 0 : STREAM_GET(&vni, s, 3);
5638 :
5639 0 : zevpn = zebra_evpn_lookup(vni);
5640 0 : if (!zevpn)
5641 : return;
5642 :
5643 0 : if (zevpn->advertise_subnet == advertise)
5644 : return;
5645 :
5646 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5647 0 : zlog_debug("EVPN subnet Adv %s on VNI %d, currently %s",
5648 : advertise ? "enabled" : "disabled", vni,
5649 : zevpn->advertise_subnet ? "enabled" : "disabled");
5650 :
5651 :
5652 0 : zevpn->advertise_subnet = advertise;
5653 :
5654 0 : ifp = zevpn->vxlan_if;
5655 0 : if (!ifp)
5656 : return;
5657 :
5658 0 : zif = ifp->info;
5659 :
5660 : /* If down or not mapped to a bridge, we're done. */
5661 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5662 : return;
5663 :
5664 0 : zl2_info = zif->l2info.vxl;
5665 :
5666 0 : vlan_if =
5667 0 : zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
5668 0 : if (!vlan_if)
5669 : return;
5670 :
5671 0 : if (zevpn->advertise_subnet)
5672 0 : zebra_evpn_advertise_subnet(zevpn, vlan_if, 1);
5673 : else
5674 0 : zebra_evpn_advertise_subnet(zevpn, vlan_if, 0);
5675 :
5676 0 : stream_failure:
5677 : return;
5678 : }
5679 :
5680 : /*
5681 : * Handle message from client to enable/disable advertisement of g/w macip
5682 : * routes
5683 : */
5684 0 : void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
5685 : {
5686 0 : struct stream *s;
5687 0 : int advertise;
5688 0 : vni_t vni = 0;
5689 0 : struct zebra_evpn *zevpn = NULL;
5690 0 : struct interface *ifp = NULL;
5691 :
5692 0 : if (!EVPN_ENABLED(zvrf)) {
5693 0 : zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5694 : zvrf_id(zvrf));
5695 0 : return;
5696 : }
5697 :
5698 0 : s = msg;
5699 0 : STREAM_GETC(s, advertise);
5700 0 : STREAM_GETL(s, vni);
5701 :
5702 0 : if (!vni) {
5703 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5704 0 : zlog_debug("EVPN gateway macip Adv %s, currently %s",
5705 : advertise ? "enabled" : "disabled",
5706 : advertise_gw_macip_enabled(NULL)
5707 : ? "enabled"
5708 : : "disabled");
5709 :
5710 0 : if (zvrf->advertise_gw_macip == advertise)
5711 : return;
5712 :
5713 0 : zvrf->advertise_gw_macip = advertise;
5714 :
5715 0 : if (advertise_gw_macip_enabled(zevpn))
5716 0 : hash_iterate(zvrf->evpn_table,
5717 : zebra_evpn_gw_macip_add_for_evpn_hash,
5718 : NULL);
5719 : else
5720 0 : hash_iterate(zvrf->evpn_table,
5721 : zebra_evpn_gw_macip_del_for_evpn_hash,
5722 : NULL);
5723 :
5724 : } else {
5725 0 : struct zebra_if *zif = NULL;
5726 0 : struct zebra_l2info_vxlan zl2_info;
5727 0 : struct interface *vlan_if = NULL;
5728 0 : struct interface *vrr_if = NULL;
5729 0 : int old_advertise;
5730 :
5731 0 : zevpn = zebra_evpn_lookup(vni);
5732 0 : if (!zevpn)
5733 0 : return;
5734 :
5735 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5736 0 : zlog_debug(
5737 : "EVPN gateway macip Adv %s on VNI %d, currently %s",
5738 : advertise ? "enabled" : "disabled", vni,
5739 : advertise_gw_macip_enabled(zevpn) ? "enabled"
5740 : : "disabled");
5741 :
5742 0 : old_advertise = advertise_gw_macip_enabled(zevpn);
5743 :
5744 0 : zevpn->advertise_gw_macip = advertise;
5745 0 : if (advertise_gw_macip_enabled(zevpn) == old_advertise)
5746 : return;
5747 :
5748 0 : ifp = zevpn->vxlan_if;
5749 0 : if (!ifp)
5750 : return;
5751 :
5752 0 : zif = ifp->info;
5753 :
5754 : /* If down or not mapped to a bridge, we're done. */
5755 0 : if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5756 : return;
5757 :
5758 0 : zl2_info = zif->l2info.vxl;
5759 :
5760 0 : vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
5761 : zif->brslave_info.br_if);
5762 0 : if (!vlan_if)
5763 : return;
5764 :
5765 0 : if (advertise_gw_macip_enabled(zevpn)) {
5766 : /* Add primary SVI MAC-IP */
5767 0 : zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5768 :
5769 : /* Add VRR MAC-IP - if any*/
5770 0 : vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5771 0 : if (vrr_if)
5772 0 : zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
5773 : } else {
5774 : /* Del primary MAC-IP */
5775 0 : zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5776 :
5777 : /* Del VRR MAC-IP - if any*/
5778 0 : vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5779 0 : if (vrr_if)
5780 0 : zebra_evpn_del_macip_for_intf(vrr_if, zevpn);
5781 : }
5782 : }
5783 :
5784 0 : stream_failure:
5785 : return;
5786 : }
5787 :
5788 0 : static int macfdb_read_ns(struct ns *ns,
5789 : void *_in_param __attribute__((unused)),
5790 : void **out_param __attribute__((unused)))
5791 : {
5792 0 : struct zebra_ns *zns = ns->info;
5793 :
5794 0 : macfdb_read(zns);
5795 0 : return NS_WALK_CONTINUE;
5796 : }
5797 :
5798 0 : static int neigh_read_ns(struct ns *ns,
5799 : void *_in_param __attribute__((unused)),
5800 : void **out_param __attribute__((unused)))
5801 : {
5802 0 : struct zebra_ns *zns = ns->info;
5803 :
5804 0 : neigh_read(zns);
5805 0 : return NS_WALK_CONTINUE;
5806 : }
5807 :
5808 : /*
5809 : * Handle message from client to learn (or stop learning) about VNIs and MACs.
5810 : * When enabled, the VNI hash table will be built and MAC FDB table read;
5811 : * when disabled, the entries should be deleted and remote VTEPs and MACs
5812 : * uninstalled from the kernel.
5813 : * This also informs the setting for BUM handling at the time this change
5814 : * occurs; it is relevant only when specifying "learn".
5815 : */
5816 0 : void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
5817 : {
5818 0 : struct stream *s = NULL;
5819 0 : int advertise = 0;
5820 0 : enum vxlan_flood_control flood_ctrl;
5821 :
5822 : /* Mismatch between EVPN VRF and current VRF (should be prevented by
5823 : * bgpd's cli) */
5824 0 : if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
5825 : return;
5826 :
5827 0 : s = msg;
5828 0 : STREAM_GETC(s, advertise);
5829 0 : STREAM_GETC(s, flood_ctrl);
5830 :
5831 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5832 0 : zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
5833 : zvrf_name(zvrf), zvrf_id(zvrf),
5834 : advertise ? "enabled" : "disabled",
5835 : is_evpn_enabled() ? "enabled" : "disabled",
5836 : flood_ctrl);
5837 :
5838 0 : if (zvrf->advertise_all_vni == advertise)
5839 : return;
5840 :
5841 0 : zvrf->advertise_all_vni = advertise;
5842 0 : if (EVPN_ENABLED(zvrf)) {
5843 0 : zrouter.evpn_vrf = zvrf;
5844 :
5845 : /* Note BUM handling */
5846 0 : zvrf->vxlan_flood_ctrl = flood_ctrl;
5847 :
5848 : /* Replay all ESs */
5849 0 : zebra_evpn_es_send_all_to_client(true /* add */);
5850 :
5851 : /* Build EVPN hash table and inform BGP. */
5852 0 : zevpn_build_hash_table();
5853 :
5854 : /* Add all SVI (L3 GW) MACs to BGP*/
5855 0 : hash_iterate(zvrf->evpn_table,
5856 : zebra_evpn_gw_macip_add_for_evpn_hash, NULL);
5857 :
5858 : /* Read the MAC FDB */
5859 0 : ns_walk_func(macfdb_read_ns, NULL, NULL);
5860 :
5861 : /* Read neighbors */
5862 0 : ns_walk_func(neigh_read_ns, NULL, NULL);
5863 : } else {
5864 : /* Cleanup VTEPs for all EVPNs - uninstall from
5865 : * kernel and free entries.
5866 : */
5867 0 : hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all,
5868 : zvrf);
5869 :
5870 : /* Delete all ESs in BGP */
5871 0 : zebra_evpn_es_send_all_to_client(false /* add */);
5872 :
5873 : /* cleanup all l3vnis */
5874 0 : hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
5875 :
5876 : /* Mark as "no EVPN VRF" */
5877 0 : zrouter.evpn_vrf = NULL;
5878 : }
5879 :
5880 0 : stream_failure:
5881 : return;
5882 : }
5883 :
5884 : /*
5885 : * Allocate EVPN hash table for this VRF and do other initialization.
5886 : * NOTE: Currently supported only for default VRF.
5887 : */
5888 2 : void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
5889 : {
5890 2 : char buffer[80];
5891 :
5892 2 : if (!zvrf)
5893 0 : return;
5894 :
5895 2 : snprintf(buffer, sizeof(buffer), "Zebra VRF EVPN Table: %s",
5896 2 : zvrf->vrf->name);
5897 2 : zvrf->evpn_table = hash_create_size(8, zebra_evpn_hash_keymake,
5898 : zebra_evpn_hash_cmp, buffer);
5899 :
5900 2 : snprintf(buffer, sizeof(buffer), "Zebra VxLAN SG Table: %s",
5901 2 : zvrf->vrf->name);
5902 2 : zvrf->vxlan_sg_table = hash_create_size(8, zebra_vxlan_sg_hash_key_make,
5903 : zebra_vxlan_sg_hash_eq, buffer);
5904 : }
5905 :
5906 : /* Cleanup EVPN info, but don't free the table. */
5907 2 : void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
5908 : {
5909 2 : struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn();
5910 :
5911 2 : hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5912 2 : zebra_vxlan_cleanup_sg_table(zvrf);
5913 :
5914 2 : if (zvrf == evpn_zvrf)
5915 2 : zebra_evpn_es_cleanup();
5916 2 : }
5917 :
5918 : /* Close all EVPN handling */
5919 2 : void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
5920 : {
5921 2 : if (!zvrf)
5922 : return;
5923 2 : hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5924 2 : hash_free(zvrf->evpn_table);
5925 2 : if (zvrf->vxlan_sg_table) {
5926 2 : zebra_vxlan_cleanup_sg_table(zvrf);
5927 2 : hash_free(zvrf->vxlan_sg_table);
5928 2 : zvrf->vxlan_sg_table = NULL;
5929 : }
5930 : }
5931 :
5932 : /* init the l3vni table */
5933 2 : void zebra_vxlan_init(void)
5934 : {
5935 2 : zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
5936 : "Zebra VRF L3 VNI table");
5937 2 : zrouter.evpn_vrf = NULL;
5938 2 : zebra_evpn_mh_init();
5939 2 : }
5940 :
5941 : /* free l3vni table */
5942 2 : void zebra_vxlan_disable(void)
5943 : {
5944 2 : hash_free(zrouter.l3vni_table);
5945 2 : zebra_evpn_mh_terminate();
5946 2 : }
5947 :
5948 : /* get the l3vni svi ifindex */
5949 0 : ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
5950 : {
5951 0 : struct zebra_l3vni *zl3vni = NULL;
5952 :
5953 0 : zl3vni = zl3vni_from_vrf(vrf_id);
5954 0 : if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5955 0 : return 0;
5956 :
5957 0 : return zl3vni->svi_if->ifindex;
5958 : }
5959 :
5960 : /************************** vxlan SG cache management ************************/
5961 : /* Inform PIM about the mcast group */
5962 0 : static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
5963 : struct prefix_sg *sg,
5964 : char *sg_str, uint16_t cmd)
5965 : {
5966 0 : struct zserv *client = NULL;
5967 0 : struct stream *s = NULL;
5968 :
5969 0 : client = zserv_find_client(ZEBRA_ROUTE_PIM, 0);
5970 0 : if (!client)
5971 : return 0;
5972 :
5973 0 : if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
5974 : return 0;
5975 :
5976 0 : s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5977 :
5978 0 : zclient_create_header(s, cmd, VRF_DEFAULT);
5979 0 : stream_putl(s, IPV4_MAX_BYTELEN);
5980 0 : stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
5981 0 : stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
5982 :
5983 : /* Write packet size. */
5984 0 : stream_putw_at(s, 0, stream_get_endp(s));
5985 :
5986 0 : if (IS_ZEBRA_DEBUG_VXLAN)
5987 0 : zlog_debug(
5988 : "Send %s %s to %s",
5989 : (cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", sg_str,
5990 : zebra_route_string(client->proto));
5991 :
5992 0 : if (cmd == ZEBRA_VXLAN_SG_ADD)
5993 0 : client->vxlan_sg_add_cnt++;
5994 : else
5995 0 : client->vxlan_sg_del_cnt++;
5996 :
5997 0 : return zserv_send_message(client, s);
5998 : }
5999 :
6000 0 : static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
6001 : {
6002 0 : const struct zebra_vxlan_sg *vxlan_sg = p;
6003 :
6004 0 : return (jhash_2words(vxlan_sg->sg.src.s_addr,
6005 0 : vxlan_sg->sg.grp.s_addr, 0));
6006 : }
6007 :
6008 0 : static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
6009 : {
6010 0 : const struct zebra_vxlan_sg *sg1 = p1;
6011 0 : const struct zebra_vxlan_sg *sg2 = p2;
6012 :
6013 0 : return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
6014 0 : && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
6015 : }
6016 :
6017 0 : static struct zebra_vxlan_sg *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
6018 : struct prefix_sg *sg)
6019 : {
6020 0 : struct zebra_vxlan_sg *vxlan_sg;
6021 :
6022 0 : vxlan_sg = XCALLOC(MTYPE_ZVXLAN_SG, sizeof(*vxlan_sg));
6023 :
6024 0 : vxlan_sg->zvrf = zvrf;
6025 0 : vxlan_sg->sg = *sg;
6026 0 : prefix_sg2str(sg, vxlan_sg->sg_str);
6027 :
6028 0 : vxlan_sg = hash_get(zvrf->vxlan_sg_table, vxlan_sg, hash_alloc_intern);
6029 :
6030 0 : if (IS_ZEBRA_DEBUG_VXLAN)
6031 0 : zlog_debug("vxlan SG %s created", vxlan_sg->sg_str);
6032 :
6033 0 : return vxlan_sg;
6034 : }
6035 :
6036 0 : static struct zebra_vxlan_sg *zebra_vxlan_sg_find(struct zebra_vrf *zvrf,
6037 : struct prefix_sg *sg)
6038 : {
6039 0 : struct zebra_vxlan_sg lookup;
6040 :
6041 0 : lookup.sg = *sg;
6042 0 : return hash_lookup(zvrf->vxlan_sg_table, &lookup);
6043 : }
6044 :
6045 0 : static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
6046 : struct prefix_sg *sg)
6047 : {
6048 0 : struct zebra_vxlan_sg *vxlan_sg;
6049 0 : struct zebra_vxlan_sg *parent = NULL;
6050 0 : struct in_addr sip;
6051 :
6052 0 : vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
6053 0 : if (vxlan_sg)
6054 : return vxlan_sg;
6055 :
6056 : /* create a *G entry for every BUM group implicitly -
6057 : * 1. The SG entry is used by pimd to setup the vxlan-origination-mroute
6058 : * 2. the XG entry is used by pimd to setup the
6059 : * vxlan-termination-mroute
6060 : */
6061 0 : if (sg->src.s_addr != INADDR_ANY) {
6062 0 : memset(&sip, 0, sizeof(sip));
6063 0 : parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
6064 0 : if (!parent)
6065 : return NULL;
6066 : }
6067 :
6068 0 : vxlan_sg = zebra_vxlan_sg_new(zvrf, sg);
6069 :
6070 0 : zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
6071 : ZEBRA_VXLAN_SG_ADD);
6072 :
6073 0 : return vxlan_sg;
6074 : }
6075 :
6076 0 : static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
6077 : {
6078 0 : struct in_addr sip;
6079 0 : struct zebra_vrf *zvrf;
6080 :
6081 0 : zvrf = vrf_info_lookup(VRF_DEFAULT);
6082 0 : if (!zvrf)
6083 0 : return;
6084 :
6085 : /* On SG entry deletion remove the reference to its parent XG
6086 : * entry
6087 : */
6088 0 : if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
6089 0 : memset(&sip, 0, sizeof(sip));
6090 0 : zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
6091 : }
6092 :
6093 0 : zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
6094 0 : vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
6095 :
6096 0 : hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
6097 :
6098 0 : if (IS_ZEBRA_DEBUG_VXLAN)
6099 0 : zlog_debug("VXLAN SG %s deleted", vxlan_sg->sg_str);
6100 :
6101 0 : XFREE(MTYPE_ZVXLAN_SG, vxlan_sg);
6102 : }
6103 :
6104 0 : static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
6105 : struct in_addr sip, struct in_addr mcast_grp)
6106 : {
6107 0 : struct zebra_vxlan_sg *vxlan_sg;
6108 0 : struct prefix_sg sg;
6109 :
6110 0 : sg.family = AF_INET;
6111 0 : sg.prefixlen = IPV4_MAX_BYTELEN;
6112 0 : sg.src = sip;
6113 0 : sg.grp = mcast_grp;
6114 0 : vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
6115 0 : if (!vxlan_sg)
6116 0 : return;
6117 :
6118 0 : if (vxlan_sg->ref_cnt)
6119 0 : --vxlan_sg->ref_cnt;
6120 :
6121 0 : if (!vxlan_sg->ref_cnt)
6122 0 : zebra_vxlan_sg_del(vxlan_sg);
6123 : }
6124 :
6125 0 : static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
6126 : struct in_addr sip,
6127 : struct in_addr mcast_grp)
6128 : {
6129 0 : struct zebra_vxlan_sg *vxlan_sg;
6130 0 : struct prefix_sg sg;
6131 :
6132 0 : sg.family = AF_INET;
6133 0 : sg.prefixlen = IPV4_MAX_BYTELEN;
6134 0 : sg.src = sip;
6135 0 : sg.grp = mcast_grp;
6136 0 : vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
6137 0 : if (vxlan_sg)
6138 0 : ++vxlan_sg->ref_cnt;
6139 :
6140 0 : return vxlan_sg;
6141 : }
6142 :
6143 0 : static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
6144 : struct in_addr mcast_grp)
6145 : {
6146 0 : struct zebra_vrf *zvrf;
6147 :
6148 0 : if (local_vtep_ip.s_addr == INADDR_ANY
6149 0 : || mcast_grp.s_addr == INADDR_ANY)
6150 : return;
6151 :
6152 0 : zvrf = vrf_info_lookup(VRF_DEFAULT);
6153 0 : if (!zvrf)
6154 : return;
6155 :
6156 0 : zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
6157 : }
6158 :
6159 0 : static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
6160 : struct in_addr mcast_grp)
6161 : {
6162 0 : struct zebra_vrf *zvrf;
6163 :
6164 0 : if (local_vtep_ip.s_addr == INADDR_ANY
6165 0 : || mcast_grp.s_addr == INADDR_ANY)
6166 : return;
6167 :
6168 0 : zvrf = vrf_info_lookup(VRF_DEFAULT);
6169 0 : if (!zvrf)
6170 : return;
6171 0 : zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
6172 : }
6173 :
6174 0 : static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg)
6175 : {
6176 0 : struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6177 :
6178 : /* increment the ref count against (*,G) to prevent them from being
6179 : * deleted
6180 : */
6181 0 : if (vxlan_sg->sg.src.s_addr == INADDR_ANY)
6182 0 : ++vxlan_sg->ref_cnt;
6183 0 : }
6184 :
6185 0 : static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg)
6186 : {
6187 0 : struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6188 :
6189 : /* decrement the dummy ref count against (*,G) to delete them */
6190 0 : if (vxlan_sg->sg.src.s_addr == INADDR_ANY) {
6191 0 : if (vxlan_sg->ref_cnt)
6192 0 : --vxlan_sg->ref_cnt;
6193 0 : if (!vxlan_sg->ref_cnt)
6194 0 : zebra_vxlan_sg_del(vxlan_sg);
6195 : }
6196 0 : }
6197 :
6198 0 : static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg)
6199 : {
6200 0 : struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6201 :
6202 0 : zebra_vxlan_sg_del(vxlan_sg);
6203 0 : }
6204 :
6205 4 : static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf)
6206 : {
6207 : /* increment the ref count against (*,G) to prevent them from being
6208 : * deleted
6209 : */
6210 4 : hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_pre_cleanup, NULL);
6211 :
6212 4 : hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_cleanup, NULL);
6213 :
6214 : /* decrement the dummy ref count against the XG entries */
6215 4 : hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_post_cleanup, NULL);
6216 4 : }
6217 :
6218 0 : static void zebra_vxlan_sg_replay_send(struct hash_bucket *bucket, void *arg)
6219 : {
6220 0 : struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6221 :
6222 0 : zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
6223 0 : vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
6224 0 : }
6225 :
6226 : /* Handle message from client to replay vxlan SG entries */
6227 0 : void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
6228 : {
6229 0 : if (IS_ZEBRA_DEBUG_VXLAN)
6230 0 : zlog_debug("VxLAN SG updates to PIM, start");
6231 :
6232 0 : SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6233 :
6234 0 : if (!EVPN_ENABLED(zvrf)) {
6235 0 : if (IS_ZEBRA_DEBUG_VXLAN)
6236 0 : zlog_debug("VxLAN SG replay request on unexpected vrf %d",
6237 : zvrf->vrf->vrf_id);
6238 0 : return;
6239 : }
6240 :
6241 0 : hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
6242 : }
6243 :
6244 :
6245 : /* Cleanup EVPN configuration of a specific VRF */
6246 0 : static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
6247 : {
6248 0 : struct zebra_l3vni *zl3vni = NULL;
6249 :
6250 0 : zvrf->advertise_all_vni = 0;
6251 0 : zvrf->advertise_gw_macip = 0;
6252 0 : zvrf->advertise_svi_macip = 0;
6253 0 : zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
6254 :
6255 0 : hash_iterate(zvrf->evpn_table, zebra_evpn_cfg_cleanup, NULL);
6256 :
6257 0 : if (zvrf->l3vni)
6258 0 : zl3vni = zl3vni_lookup(zvrf->l3vni);
6259 0 : if (zl3vni) {
6260 : /* delete and uninstall all rmacs */
6261 0 : hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
6262 : zl3vni);
6263 : /* delete and uninstall all next-hops */
6264 0 : hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
6265 : zl3vni);
6266 : }
6267 0 : }
6268 :
6269 : /* Cleanup BGP EVPN configuration upon client disconnect */
6270 0 : static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
6271 : {
6272 0 : struct vrf *vrf;
6273 0 : struct zebra_vrf *zvrf;
6274 :
6275 0 : RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
6276 0 : zvrf = vrf->info;
6277 0 : if (zvrf)
6278 0 : zebra_evpn_vrf_cfg_cleanup(zvrf);
6279 : }
6280 :
6281 0 : return 0;
6282 : }
6283 :
6284 2 : static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
6285 : {
6286 2 : struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
6287 :
6288 2 : if (CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
6289 0 : if (IS_ZEBRA_DEBUG_VXLAN)
6290 0 : zlog_debug("VxLAN SG updates to PIM, stop");
6291 0 : UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6292 : }
6293 :
6294 2 : return 0;
6295 : }
6296 :
6297 6 : static int zebra_evpn_cfg_clean_up(struct zserv *client)
6298 : {
6299 6 : if (client->proto == ZEBRA_ROUTE_BGP)
6300 0 : return zebra_evpn_bgp_cfg_clean_up(client);
6301 :
6302 6 : if (client->proto == ZEBRA_ROUTE_PIM)
6303 2 : return zebra_evpn_pim_cfg_clean_up(client);
6304 :
6305 : return 0;
6306 : }
6307 :
6308 : /*
6309 : * Handle results for vxlan dataplane operations.
6310 : */
6311 0 : extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx)
6312 : {
6313 0 : return;
6314 : }
6315 :
6316 : /* Config knob for accepting lower sequence numbers */
6317 0 : void zebra_vxlan_set_accept_bgp_seq(bool set)
6318 : {
6319 0 : accept_bgp_seq = set;
6320 0 : }
6321 :
6322 0 : bool zebra_vxlan_get_accept_bgp_seq(void)
6323 : {
6324 0 : return accept_bgp_seq;
6325 : }
6326 :
6327 : /* Cleanup BGP EVPN configuration upon client disconnect */
6328 2 : extern void zebra_evpn_init(void)
6329 : {
6330 2 : hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
6331 2 : }
|