]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_evpn.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / zebra / zebra_evpn.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
6006414d
PR
2/*
3 * Zebra EVPN for VxLAN code
4 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
6006414d 5 */
6006414d
PR
6#include <zebra.h>
7
8#include "hash.h"
9#include "if.h"
10#include "jhash.h"
11#include "linklist.h"
12#include "log.h"
13#include "memory.h"
14#include "prefix.h"
15#include "stream.h"
16#include "table.h"
17#include "vlan.h"
18#include "vxlan.h"
19#ifdef GNU_LINUX
20#include <linux/neighbour.h>
21#endif
22
23#include "zebra/zebra_router.h"
24#include "zebra/debug.h"
25#include "zebra/interface.h"
26#include "zebra/rib.h"
27#include "zebra/rt.h"
28#include "zebra/rt_netlink.h"
29#include "zebra/zebra_errors.h"
30#include "zebra/zebra_l2.h"
efde4f25 31#include "zebra/zebra_l2_bridge_if.h"
6006414d
PR
32#include "zebra/zebra_ns.h"
33#include "zebra/zebra_vrf.h"
34#include "zebra/zebra_vxlan.h"
0adeb5fd 35#include "zebra/zebra_vxlan_private.h"
6006414d
PR
36#include "zebra/zebra_evpn.h"
37#include "zebra/zebra_evpn_mac.h"
38#include "zebra/zebra_evpn_neigh.h"
6006414d 39#include "zebra/zebra_evpn_mh.h"
8b5fdf2e 40#include "zebra/zebra_evpn_vxlan.h"
6006414d
PR
41#include "zebra/zebra_router.h"
42
8b5fdf2e
PR
43DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN, "VNI hash");
44DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN_VTEP, "VNI remote VTEP");
6006414d 45
6006414d
PR
46/* PMSI strings. */
47#define VXLAN_FLOOD_STR_NO_INFO "-"
48#define VXLAN_FLOOD_STR_DEFAULT VXLAN_FLOOD_STR_NO_INFO
49static const struct message zvtep_flood_str[] = {
50 {VXLAN_FLOOD_DISABLED, VXLAN_FLOOD_STR_NO_INFO},
51 {VXLAN_FLOOD_PIM_SM, "PIM-SM"},
52 {VXLAN_FLOOD_HEAD_END_REPL, "HER"},
53 {0}
54};
55
f6371c34 56int advertise_gw_macip_enabled(struct zebra_evpn *zevpn)
6006414d
PR
57{
58 struct zebra_vrf *zvrf;
59
60 zvrf = zebra_vrf_get_evpn();
81157cbd 61 if (zvrf->advertise_gw_macip)
6006414d
PR
62 return 1;
63
64 if (zevpn && zevpn->advertise_gw_macip)
65 return 1;
66
67 return 0;
68}
69
f6371c34 70int advertise_svi_macip_enabled(struct zebra_evpn *zevpn)
6006414d
PR
71{
72 struct zebra_vrf *zvrf;
73
74 zvrf = zebra_vrf_get_evpn();
81157cbd 75 if (zvrf->advertise_svi_macip)
6006414d
PR
76 return 1;
77
78 if (zevpn && zevpn->advertise_svi_macip)
79 return 1;
80
81 return 0;
82}
83
6006414d
PR
84/*
85 * Print a specific EVPN entry.
86 */
f6371c34 87void zebra_evpn_print(struct zebra_evpn *zevpn, void **ctxt)
6006414d 88{
1a4a394d
PJD
89
90 struct vty *vty = NULL;
91 struct zebra_vtep *zvtep = NULL;
92 uint32_t num_macs = 0;
93 uint32_t num_neigh = 0;
94 uint32_t num_vteps = 0;
6006414d
PR
95 json_object *json = NULL;
96 json_object *json_vtep_list = NULL;
1a4a394d 97 json_object *json_vtep = NULL;
6006414d
PR
98
99 vty = ctxt[0];
100 json = ctxt[1];
101
102 if (json == NULL) {
103 vty_out(vty, "VNI: %u\n", zevpn->vni);
104 vty_out(vty, " Type: %s\n", "L2");
efde4f25
SR
105 vty_out(vty, " Vlan: %u\n", zevpn->vid);
106 vty_out(vty, " Bridge: %s\n",
107 zevpn->bridge_if ? zevpn->bridge_if->name : "-");
6006414d
PR
108 vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zevpn->vrf_id));
109 } else {
110 json_object_int_add(json, "vni", zevpn->vni);
111 json_object_string_add(json, "type", "L2");
1a4a394d
PJD
112#if CONFDATE > 20240210
113CPP_NOTICE("Drop `vrf` from JSON output")
114#endif
6006414d
PR
115 json_object_string_add(json, "vrf",
116 vrf_id_to_name(zevpn->vrf_id));
1a4a394d
PJD
117 json_object_string_add(json, "tenantVrf",
118 vrf_id_to_name(zevpn->vrf_id));
6006414d
PR
119 }
120
121 if (!zevpn->vxlan_if) { // unexpected
122 if (json == NULL)
123 vty_out(vty, " VxLAN interface: unknown\n");
1a4a394d
PJD
124 else
125 json_object_string_add(json, "vxlanInterface",
126 "unknown");
6006414d
PR
127 return;
128 }
129 num_macs = num_valid_macs(zevpn);
130 num_neigh = hashcount(zevpn->neigh_table);
131 if (json == NULL) {
132 vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name);
133 vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex);
9daa5d47
AD
134 vty_out(vty, " SVI interface: %s\n",
135 (zevpn->svi_if ? zevpn->svi_if->name : ""));
136 vty_out(vty, " SVI ifIndex: %u\n",
137 (zevpn->svi_if ? zevpn->svi_if->ifindex : 0));
9bcef951
MS
138 vty_out(vty, " Local VTEP IP: %pI4\n",
139 &zevpn->local_vtep_ip);
140 vty_out(vty, " Mcast group: %pI4\n",
141 &zevpn->mcast_grp);
6006414d
PR
142 } else {
143 json_object_string_add(json, "vxlanInterface",
144 zevpn->vxlan_if->name);
1a4a394d
PJD
145#if CONFDATE > 20240210
146CPP_NOTICE("Drop `ifindex` from JSON output")
147#endif
6006414d 148 json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex);
1a4a394d
PJD
149 json_object_int_add(json, "vxlanIfindex",
150 zevpn->vxlan_if->ifindex);
9daa5d47
AD
151 if (zevpn->svi_if) {
152 json_object_string_add(json, "sviInterface",
153 zevpn->svi_if->name);
154 json_object_int_add(json, "sviIfindex",
155 zevpn->svi_if->ifindex);
156 }
08edf9c6
DA
157 json_object_string_addf(json, "vtepIp", "%pI4",
158 &zevpn->local_vtep_ip);
159 json_object_string_addf(json, "mcastGroup", "%pI4",
160 &zevpn->mcast_grp);
6006414d 161 json_object_string_add(json, "advertiseGatewayMacip",
1a4a394d
PJD
162 zevpn->advertise_gw_macip ? "Yes"
163 : "No");
c0c7707d
AK
164 json_object_string_add(json, "advertiseSviMacip",
165 zevpn->advertise_svi_macip ? "Yes"
166 : "No");
6006414d
PR
167 json_object_int_add(json, "numMacs", num_macs);
168 json_object_int_add(json, "numArpNd", num_neigh);
169 }
170 if (!zevpn->vteps) {
171 if (json == NULL)
172 vty_out(vty, " No remote VTEPs known for this VNI\n");
1a4a394d
PJD
173 else
174 json_object_int_add(json, "numRemoteVteps", num_vteps);
6006414d
PR
175 } else {
176 if (json == NULL)
177 vty_out(vty, " Remote VTEPs for this VNI:\n");
178 else
179 json_vtep_list = json_object_new_array();
180 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
1a4a394d
PJD
181 const char *flood_str = lookup_msg(
182 zvtep_flood_str, zvtep->flood_control,
183 VXLAN_FLOOD_STR_DEFAULT);
6006414d
PR
184
185 if (json == NULL) {
9bcef951
MS
186 vty_out(vty, " %pI4 flood: %s\n",
187 &zvtep->vtep_ip,
6006414d
PR
188 flood_str);
189 } else {
1a4a394d
PJD
190 json_vtep = json_object_new_object();
191 json_object_string_addf(json_vtep, "ip", "%pI4",
192 &zvtep->vtep_ip);
193 json_object_string_add(json_vtep, "flood",
194 flood_str);
6006414d 195 json_object_array_add(json_vtep_list,
1a4a394d 196 json_vtep);
6006414d 197 }
1a4a394d 198 num_vteps++;
6006414d 199 }
1a4a394d
PJD
200 if (json) {
201 json_object_int_add(json, "numRemoteVteps", num_vteps);
202 json_object_object_add(json, "remoteVteps",
6006414d 203 json_vtep_list);
1a4a394d 204 }
6006414d
PR
205 }
206 if (json == NULL) {
207 vty_out(vty,
208 " Number of MACs (local and remote) known for this VNI: %u\n",
209 num_macs);
210 vty_out(vty,
211 " Number of ARPs (IPv4 and IPv6, local and remote) "
212 "known for this VNI: %u\n",
213 num_neigh);
214 vty_out(vty, " Advertise-gw-macip: %s\n",
215 zevpn->advertise_gw_macip ? "Yes" : "No");
c0c7707d
AK
216 vty_out(vty, " Advertise-svi-macip: %s\n",
217 zevpn->advertise_svi_macip ? "Yes" : "No");
6006414d
PR
218 }
219}
220
8b5fdf2e
PR
221/*
222 * Print an EVPN hash entry - called for display of all VNIs.
223 */
224void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
6006414d 225{
8b5fdf2e 226 struct vty *vty;
f6371c34 227 struct zebra_evpn *zevpn;
c172c032 228 struct zebra_vtep *zvtep;
8b5fdf2e
PR
229 uint32_t num_vteps = 0;
230 uint32_t num_macs = 0;
231 uint32_t num_neigh = 0;
6006414d
PR
232 json_object *json = NULL;
233 json_object *json_evpn = NULL;
8b5fdf2e
PR
234 json_object *json_ip_str = NULL;
235 json_object *json_vtep_list = NULL;
9bcef951 236 char buf[PREFIX_STRLEN];
6006414d 237
8b5fdf2e
PR
238 vty = ctxt[0];
239 json = ctxt[1];
6006414d 240
f6371c34 241 zevpn = (struct zebra_evpn *)bucket->data;
6006414d 242
8b5fdf2e
PR
243 zvtep = zevpn->vteps;
244 while (zvtep) {
245 num_vteps++;
246 zvtep = zvtep->next;
6006414d
PR
247 }
248
249 num_macs = num_valid_macs(zevpn);
250 num_neigh = hashcount(zevpn->neigh_table);
251 if (json == NULL)
252 vty_out(vty, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
253 zevpn->vni, "L2",
254 zevpn->vxlan_if ? zevpn->vxlan_if->name : "unknown",
255 num_macs, num_neigh, num_vteps,
256 vrf_id_to_name(zevpn->vrf_id));
257 else {
258 char vni_str[VNI_STR_LEN];
259 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
260 json_evpn = json_object_new_object();
261 json_object_int_add(json_evpn, "vni", zevpn->vni);
262 json_object_string_add(json_evpn, "type", "L2");
263 json_object_string_add(json_evpn, "vxlanIf",
264 zevpn->vxlan_if ? zevpn->vxlan_if->name
265 : "unknown");
266 json_object_int_add(json_evpn, "numMacs", num_macs);
267 json_object_int_add(json_evpn, "numArpNd", num_neigh);
268 json_object_int_add(json_evpn, "numRemoteVteps", num_vteps);
269 json_object_string_add(json_evpn, "tenantVrf",
270 vrf_id_to_name(zevpn->vrf_id));
271 if (num_vteps) {
272 json_vtep_list = json_object_new_array();
273 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
274 json_ip_str = json_object_new_string(
9bcef951
MS
275 inet_ntop(AF_INET, &zvtep->vtep_ip, buf,
276 sizeof(buf)));
6006414d
PR
277 json_object_array_add(json_vtep_list,
278 json_ip_str);
279 }
280 json_object_object_add(json_evpn, "remoteVteps",
281 json_vtep_list);
282 }
283 json_object_object_add(json, vni_str, json_evpn);
284 }
285}
286
287/*
288 * Print an EVPN hash entry in detail - called for display of all EVPNs.
289 */
8b5fdf2e 290void zebra_evpn_print_hash_detail(struct hash_bucket *bucket, void *data)
6006414d
PR
291{
292 struct vty *vty;
f6371c34 293 struct zebra_evpn *zevpn;
6006414d
PR
294 json_object *json_array = NULL;
295 bool use_json = false;
8b5fdf2e 296 struct zebra_evpn_show *zes = data;
6006414d
PR
297
298 vty = zes->vty;
299 json_array = zes->json;
300 use_json = zes->use_json;
301
f6371c34 302 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
303
304 zebra_vxlan_print_vni(vty, zes->zvrf, zevpn->vni, use_json, json_array);
305
306 if (!use_json)
307 vty_out(vty, "\n");
308}
309
f6371c34
DS
310int zebra_evpn_del_macip_for_intf(struct interface *ifp,
311 struct zebra_evpn *zevpn)
6006414d
PR
312{
313 struct listnode *cnode = NULL, *cnnode = NULL;
314 struct connected *c = NULL;
315 struct ethaddr macaddr;
316
317 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
318
319 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
320 struct ipaddr ip;
321
322 memset(&ip, 0, sizeof(struct ipaddr));
323 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
324 continue;
325
326 if (c->address->family == AF_INET) {
327 ip.ipa_type = IPADDR_V4;
328 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
329 sizeof(struct in_addr));
330 } else if (c->address->family == AF_INET6) {
331 ip.ipa_type = IPADDR_V6;
332 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
333 sizeof(struct in6_addr));
334 } else {
335 continue;
336 }
337
8b5fdf2e 338 zebra_evpn_gw_macip_del(ifp, zevpn, &ip);
6006414d
PR
339 }
340
341 return 0;
342}
343
f6371c34
DS
344int zebra_evpn_add_macip_for_intf(struct interface *ifp,
345 struct zebra_evpn *zevpn)
6006414d
PR
346{
347 struct listnode *cnode = NULL, *cnnode = NULL;
348 struct connected *c = NULL;
349 struct ethaddr macaddr;
350
351 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
352
353 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
354 struct ipaddr ip;
355
6006414d
PR
356 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
357 continue;
358
38eda16a 359 memset(&ip, 0, sizeof(struct ipaddr));
6006414d
PR
360 if (c->address->family == AF_INET) {
361 ip.ipa_type = IPADDR_V4;
362 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
363 sizeof(struct in_addr));
364 } else if (c->address->family == AF_INET6) {
365 ip.ipa_type = IPADDR_V6;
366 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
367 sizeof(struct in6_addr));
368 } else {
369 continue;
370 }
371
8b5fdf2e 372 zebra_evpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
6006414d
PR
373 }
374 return 0;
375}
376
8b5fdf2e
PR
377static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
378 uint16_t cmd)
379{
380 struct zserv *client = NULL;
381 struct stream *s = NULL;
8b5fdf2e
PR
382
383 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
384 /* BGP may not be running. */
385 if (!client)
386 return 0;
387
388 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
389
390 zclient_create_header(s, cmd, vrf_id);
391 stream_put(s, p, sizeof(struct prefix));
392
393 /* Write packet size. */
394 stream_putw_at(s, 0, stream_get_endp(s));
395
396 if (IS_ZEBRA_DEBUG_VXLAN)
2dbe669b 397 zlog_debug("Send ip prefix %pFX %s on vrf %s", p,
8b5fdf2e
PR
398 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
399 vrf_id_to_name(vrf_id));
400
401 if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
402 client->prefixadd_cnt++;
403 else
404 client->prefixdel_cnt++;
405
406 return zserv_send_message(client, s);
407}
6006414d 408
f6371c34 409int zebra_evpn_advertise_subnet(struct zebra_evpn *zevpn, struct interface *ifp,
8b5fdf2e 410 int advertise)
6006414d
PR
411{
412 struct listnode *cnode = NULL, *cnnode = NULL;
413 struct connected *c = NULL;
414 struct ethaddr macaddr;
415
416 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
417
418 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
419 struct prefix p;
420
421 memcpy(&p, c->address, sizeof(struct prefix));
422
423 /* skip link local address */
424 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
425 continue;
426
427 apply_mask(&p);
428 if (advertise)
096f7609 429 ip_prefix_send_to_client(ifp->vrf->vrf_id, &p,
6006414d
PR
430 ZEBRA_IP_PREFIX_ROUTE_ADD);
431 else
096f7609 432 ip_prefix_send_to_client(ifp->vrf->vrf_id, &p,
6006414d
PR
433 ZEBRA_IP_PREFIX_ROUTE_DEL);
434 }
435 return 0;
436}
437
438/*
8b5fdf2e 439 * zebra_evpn_gw_macip_add_to_client
6006414d 440 */
f6371c34 441int zebra_evpn_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn,
8b5fdf2e 442 struct ethaddr *macaddr, struct ipaddr *ip)
6006414d 443{
3198b2b3 444 struct zebra_mac *mac = NULL;
6006414d 445 struct zebra_if *zif = NULL;
8d30ff3b 446 struct zebra_vxlan_vni *vni;
6006414d
PR
447
448 zif = zevpn->vxlan_if->info;
449 if (!zif)
450 return -1;
451
8d30ff3b 452 vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
6006414d 453
5ff58d0a 454 zebra_evpn_mac_gw_macip_add(ifp, zevpn, ip, &mac, macaddr,
8d30ff3b 455 vni->access_vlan, true);
6006414d
PR
456
457 return zebra_evpn_neigh_gw_macip_add(ifp, zevpn, ip, mac);
458}
459
460/*
8b5fdf2e 461 * zebra_evpn_gw_macip_del_from_client
6006414d 462 */
f6371c34 463int zebra_evpn_gw_macip_del(struct interface *ifp, struct zebra_evpn *zevpn,
8b5fdf2e 464 struct ipaddr *ip)
6006414d 465{
72de4110 466 struct zebra_neigh *n = NULL;
3198b2b3 467 struct zebra_mac *mac = NULL;
6006414d
PR
468
469 /* If the neigh entry is not present nothing to do*/
470 n = zebra_evpn_neigh_lookup(zevpn, ip);
471 if (!n)
472 return 0;
473
474 /* mac entry should be present */
475 mac = zebra_evpn_mac_lookup(zevpn, &n->emac);
476 if (!mac) {
477 if (IS_ZEBRA_DEBUG_VXLAN)
ef7b8be4
DL
478 zlog_debug("MAC %pEA doesn't exist for neigh %pIA on VNI %u",
479 &n->emac, ip, zevpn->vni);
6006414d
PR
480 return -1;
481 }
482
483 /* If the entry is not local nothing to do*/
484 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
485 return -1;
486
487 /* only need to delete the entry from bgp if we sent it before */
488 if (IS_ZEBRA_DEBUG_VXLAN)
489 zlog_debug(
ef7b8be4 490 "%u:SVI %s(%u) VNI %u, sending GW MAC %pEA IP %pIA del to BGP",
096f7609 491 ifp->vrf->vrf_id, ifp->name, ifp->ifindex, zevpn->vni,
ef7b8be4 492 &n->emac, ip);
6006414d
PR
493
494 /* Remove neighbor from BGP. */
495 zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
496 n->flags, ZEBRA_NEIGH_ACTIVE,
497 false /*force*/);
498
499 /* Delete this neighbor entry. */
500 zebra_evpn_neigh_del(zevpn, n);
501
502 /* see if the mac needs to be deleted as well*/
503 if (mac)
504 zebra_evpn_deref_ip2mac(zevpn, mac);
505
506 return 0;
507}
508
8b5fdf2e 509void zebra_evpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
6006414d
PR
510 void *ctxt)
511{
f6371c34 512 struct zebra_evpn *zevpn = NULL;
6006414d 513 struct zebra_if *zif = NULL;
8d30ff3b 514 struct zebra_vxlan_vni *vni = NULL;
6006414d
PR
515 struct interface *vlan_if = NULL;
516 struct interface *vrr_if = NULL;
517 struct interface *ifp;
518
519 /* Add primary SVI MAC*/
f6371c34 520 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
521
522 /* Global (Zvrf) advertise-default-gw is disabled,
523 * but zevpn advertise-default-gw is enabled
524 */
525 if (zevpn->advertise_gw_macip) {
526 if (IS_ZEBRA_DEBUG_VXLAN)
527 zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
528 zevpn->vni);
529 return;
530 }
531
532 ifp = zevpn->vxlan_if;
533 if (!ifp)
534 return;
535 zif = ifp->info;
536
537 /* If down or not mapped to a bridge, we're done. */
538 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
539 return;
540
8d30ff3b
SR
541 vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
542 if (!vni)
543 return;
6006414d 544
8d30ff3b 545 vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
6006414d
PR
546 if (!vlan_if)
547 return;
548
549 /* Del primary MAC-IP */
8b5fdf2e 550 zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
6006414d
PR
551
552 /* Del VRR MAC-IP - if any*/
553 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
554 if (vrr_if)
8b5fdf2e 555 zebra_evpn_del_macip_for_intf(vrr_if, zevpn);
6006414d
PR
556
557 return;
558}
559
8b5fdf2e 560void zebra_evpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket,
6006414d
PR
561 void *ctxt)
562{
f6371c34 563 struct zebra_evpn *zevpn = NULL;
6006414d 564 struct zebra_if *zif = NULL;
6006414d
PR
565 struct interface *vlan_if = NULL;
566 struct interface *vrr_if = NULL;
567 struct interface *ifp = NULL;
8d30ff3b 568 struct zebra_vxlan_vni *vni = NULL;
6006414d 569
f6371c34 570 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
571
572 ifp = zevpn->vxlan_if;
573 if (!ifp)
574 return;
575 zif = ifp->info;
576
577 /* If down or not mapped to a bridge, we're done. */
578 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
579 return;
8d30ff3b
SR
580 vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
581 if (!vni)
582 return;
6006414d 583
8d30ff3b 584 vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
6006414d
PR
585 if (!vlan_if)
586 return;
587
588 /* Add primary SVI MAC-IP */
c0c7707d
AK
589 if (advertise_svi_macip_enabled(zevpn)
590 || advertise_gw_macip_enabled(zevpn))
591 zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
6006414d
PR
592
593 if (advertise_gw_macip_enabled(zevpn)) {
594 /* Add VRR MAC-IP - if any*/
595 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
596 if (vrr_if)
8b5fdf2e 597 zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
6006414d
PR
598 }
599
600 return;
601}
602
8b5fdf2e
PR
603void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
604 void *ctxt)
6006414d 605{
f6371c34 606 struct zebra_evpn *zevpn = NULL;
6006414d 607 struct zebra_if *zif = NULL;
6006414d 608 struct interface *vlan_if = NULL;
8d30ff3b 609 struct zebra_vxlan_vni *vni = NULL;
6006414d
PR
610 struct interface *ifp;
611
612 /* Add primary SVI MAC*/
f6371c34 613 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
614 if (!zevpn)
615 return;
616
617 /* Global(vrf) advertise-svi-ip disabled, but zevpn advertise-svi-ip
618 * enabled
619 */
620 if (zevpn->advertise_svi_macip) {
621 if (IS_ZEBRA_DEBUG_VXLAN)
622 zlog_debug("VNI: %u SVI-MACIP enabled, retain svi-macip",
623 zevpn->vni);
624 return;
625 }
626
627 ifp = zevpn->vxlan_if;
628 if (!ifp)
629 return;
630 zif = ifp->info;
631
632 /* If down or not mapped to a bridge, we're done. */
633 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
634 return;
635
8d30ff3b
SR
636 vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
637 if (!vni)
638 return;
6006414d 639
8d30ff3b 640 vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
6006414d
PR
641 if (!vlan_if)
642 return;
643
644 /* Del primary MAC-IP */
8b5fdf2e 645 zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
6006414d
PR
646
647 return;
648}
649
2961d060
PG
650static int zebra_evpn_map_vlan_ns(struct ns *ns,
651 void *_in_param,
652 void **_p_zevpn)
6006414d 653{
efde4f25 654 int found = 0;
2961d060 655 struct zebra_ns *zns = ns->info;
6006414d 656 struct route_node *rn;
9609fab7 657 struct interface *br_if;
f6371c34
DS
658 struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
659 struct zebra_evpn *zevpn;
6006414d
PR
660 struct interface *tmp_if = NULL;
661 struct zebra_if *zif;
9609fab7
PG
662 struct zebra_from_svi_param *in_param =
663 (struct zebra_from_svi_param *)_in_param;
efde4f25
SR
664 vlanid_t vid;
665 vni_t vni_id = 0;
666 uint8_t bridge_vlan_aware;
6006414d 667
44a84850 668 assert(p_zevpn && in_param);
669
9609fab7 670 br_if = in_param->br_if;
efde4f25 671 assert(br_if);
9609fab7 672 zif = in_param->zif;
6006414d 673 assert(zif);
efde4f25
SR
674 vid = in_param->vid;
675 bridge_vlan_aware = in_param->bridge_vlan_aware;
6006414d 676
efde4f25
SR
677 if (bridge_vlan_aware) {
678 vni_id = zebra_l2_bridge_if_vni_find(zif, vid);
679 if (vni_id)
680 found = 1;
681 } else {
9464e5b8
SR
682 /*
683 * See if this interface (or interface plus VLAN Id) maps to a
684 * VxLAN
685 */
efde4f25
SR
686 /* TODO: Optimize with a hash. */
687 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
688 tmp_if = (struct interface *)rn->info;
689 if (!tmp_if)
690 continue;
691 zif = tmp_if->info;
692 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
693 continue;
694 if (!if_is_operative(tmp_if))
695 continue;
696
697 if (zif->brslave_info.br_if != br_if)
698 continue;
699
feffe4ee
SR
700 vni_id =
701 zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
efde4f25
SR
702 if (vni_id) {
703 found = 1;
704 break;
705 }
6006414d
PR
706 }
707 }
6006414d 708
efde4f25
SR
709 if (!found)
710 return NS_WALK_CONTINUE;
711
712 zevpn = zebra_evpn_lookup(vni_id);
713 *p_zevpn = zevpn;
714 return NS_WALK_STOP;
9609fab7
PG
715}
716
6006414d
PR
717/*
718 * Map port or (port, VLAN) to an EVPN. This is invoked upon getting MAC
719 * notifications, to see if they are of interest.
720 */
f6371c34
DS
721struct zebra_evpn *zebra_evpn_map_vlan(struct interface *ifp,
722 struct interface *br_if, vlanid_t vid)
6006414d 723{
6006414d 724 struct zebra_if *zif;
f6371c34
DS
725 struct zebra_evpn **p_zevpn;
726 struct zebra_evpn *zevpn = NULL;
9609fab7 727 struct zebra_from_svi_param in_param;
6006414d
PR
728
729 /* Determine if bridge is VLAN-aware or not */
730 zif = br_if->info;
731 assert(zif);
784d88aa 732 in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
9609fab7
PG
733 in_param.vid = vid;
734 in_param.br_if = br_if;
735 in_param.zif = zif;
736 p_zevpn = &zevpn;
737
2961d060
PG
738 ns_walk_func(zebra_evpn_map_vlan_ns,
739 (void *)&in_param,
740 (void **)p_zevpn);
6006414d
PR
741 return zevpn;
742}
743
2961d060
PG
744static int zebra_evpn_from_svi_ns(struct ns *ns,
745 void *_in_param,
746 void **_p_zevpn)
6006414d 747{
2961d060 748 struct zebra_ns *zns = ns->info;
6006414d 749 struct route_node *rn;
9d277b8c 750 struct interface *br_if;
f6371c34
DS
751 struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
752 struct zebra_evpn *zevpn;
6006414d
PR
753 struct interface *tmp_if = NULL;
754 struct zebra_if *zif;
efde4f25
SR
755 struct zebra_if *br_zif;
756 struct zebra_l2_bridge_vlan *bvlan;
a237058f
PG
757 struct zebra_from_svi_param *in_param =
758 (struct zebra_from_svi_param *)_in_param;
6006414d 759 int found = 0;
efde4f25
SR
760 vni_t vni_id = 0;
761 vlanid_t vid = 0;
762 uint8_t bridge_vlan_aware;
6006414d 763
9d277b8c 764 if (!in_param)
2961d060 765 return NS_WALK_STOP;
efde4f25 766
9d277b8c
PG
767 br_if = in_param->br_if;
768 zif = in_param->zif;
6006414d 769 assert(zif);
efde4f25
SR
770 bridge_vlan_aware = in_param->bridge_vlan_aware;
771 vid = in_param->vid;
772 br_zif = br_if->info;
773 assert(br_zif);
774
775 if (bridge_vlan_aware) {
776 bvlan = zebra_l2_bridge_if_vlan_find(br_zif, vid);
777 if (bvlan && bvlan->access_bd && bvlan->access_bd->vni) {
6006414d 778 found = 1;
efde4f25
SR
779 vni_id = bvlan->access_bd->vni;
780 }
781 } else {
782 /* TODO: Optimize with a hash. */
783 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
784 tmp_if = (struct interface *)rn->info;
785 if (!tmp_if)
786 continue;
787 zif = tmp_if->info;
788 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
789 continue;
790 if (!if_is_operative(tmp_if))
791 continue;
792
793 if (zif->brslave_info.br_if != br_if)
794 continue;
795
feffe4ee
SR
796 vni_id =
797 zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
798 if (vni_id) {
efde4f25 799 found = 1;
feffe4ee
SR
800 break;
801 }
6006414d
PR
802 }
803 }
804
805 if (!found)
2961d060 806 return NS_WALK_CONTINUE;
6006414d 807
efde4f25 808 zevpn = zebra_evpn_lookup(vni_id);
9d277b8c
PG
809 if (p_zevpn)
810 *p_zevpn = zevpn;
2961d060 811 return NS_WALK_STOP;
6006414d
PR
812}
813
814/*
8b5fdf2e 815 * Map SVI and associated bridge to an EVPN. This is invoked upon getting
6006414d
PR
816 * neighbor notifications, to see if they are of interest.
817 */
f6371c34
DS
818struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp,
819 struct interface *br_if)
6006414d 820{
f6371c34
DS
821 struct zebra_evpn *zevpn = NULL;
822 struct zebra_evpn **p_zevpn;
9d277b8c 823 struct zebra_if *zif;
a237058f 824 struct zebra_from_svi_param in_param;
6006414d
PR
825
826 if (!br_if)
827 return NULL;
828
829 /* Make sure the linked interface is a bridge. */
830 if (!IS_ZEBRA_IF_BRIDGE(br_if))
831 return NULL;
832
833 /* Determine if bridge is VLAN-aware or not */
834 zif = br_if->info;
835 assert(zif);
784d88aa 836 in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
9d277b8c
PG
837 in_param.vid = 0;
838
839 if (in_param.bridge_vlan_aware) {
6006414d
PR
840 struct zebra_l2info_vlan *vl;
841
842 if (!IS_ZEBRA_IF_VLAN(ifp))
843 return NULL;
844
845 zif = ifp->info;
846 assert(zif);
847 vl = &zif->l2info.vl;
9d277b8c 848 in_param.vid = vl->vid;
6006414d
PR
849 }
850
9d277b8c
PG
851 in_param.br_if = br_if;
852 in_param.zif = zif;
853 p_zevpn = &zevpn;
6006414d 854 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2961d060
PG
855 ns_walk_func(zebra_evpn_from_svi_ns, (void *)&in_param,
856 (void **)p_zevpn);
6006414d
PR
857 return zevpn;
858}
859
a1ce03e1
PG
860static int zvni_map_to_macvlan_ns(struct ns *ns,
861 void *_in_param,
862 void **_p_ifp)
863{
864 struct zebra_ns *zns = ns->info;
865 struct zebra_from_svi_param *in_param =
866 (struct zebra_from_svi_param *)_in_param;
867 struct interface **p_ifp = (struct interface **)_p_ifp;
868 struct route_node *rn;
869 struct interface *tmp_if = NULL;
870 struct zebra_if *zif;
871
44a84850 872 assert(in_param && p_ifp);
a1ce03e1
PG
873
874 /* Identify corresponding VLAN interface. */
6006414d
PR
875 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
876 tmp_if = (struct interface *)rn->info;
a1ce03e1
PG
877 /* Check oper status of the SVI. */
878 if (!tmp_if || !if_is_operative(tmp_if))
6006414d
PR
879 continue;
880 zif = tmp_if->info;
6006414d 881
a1ce03e1 882 if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN)
6006414d
PR
883 continue;
884
a1ce03e1 885 if (zif->link == in_param->svi_if) {
44a84850 886 *p_ifp = tmp_if;
a1ce03e1 887 return NS_WALK_STOP;
6006414d
PR
888 }
889 }
890
a1ce03e1 891 return NS_WALK_CONTINUE;
6006414d
PR
892}
893
6006414d
PR
894/* Map to MAC-VLAN interface corresponding to specified SVI interface.
895 */
8b5fdf2e
PR
896struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if,
897 struct interface *svi_if)
6006414d 898{
6006414d
PR
899 struct interface *tmp_if = NULL;
900 struct zebra_if *zif;
a1ce03e1
PG
901 struct interface **p_ifp;
902 struct zebra_from_svi_param in_param;
6006414d
PR
903
904 /* Defensive check, caller expected to invoke only with valid bridge. */
905 if (!br_if)
906 return NULL;
907
908 if (!svi_if) {
909 zlog_debug("svi_if is not passed.");
910 return NULL;
911 }
912
913 /* Determine if bridge is VLAN-aware or not */
914 zif = br_if->info;
915 assert(zif);
916
a1ce03e1
PG
917 in_param.vid = 0;
918 in_param.br_if = br_if;
919 in_param.zif = NULL;
920 in_param.svi_if = svi_if;
921 p_ifp = &tmp_if;
6006414d 922
a1ce03e1
PG
923 /* Identify corresponding VLAN interface. */
924 ns_walk_func(zvni_map_to_macvlan_ns,
925 (void *)&in_param,
926 (void **)p_ifp);
927 return tmp_if;
6006414d
PR
928}
929
00d30205 930/*
931 * Uninstall MAC hash entry - called upon access VLAN change.
932 */
933static void zebra_evpn_uninstall_mac_hash(struct hash_bucket *bucket,
934 void *ctxt)
935{
936 struct zebra_mac *mac;
937 struct mac_walk_ctx *wctx = ctxt;
938
939 mac = (struct zebra_mac *)bucket->data;
940
941 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
942 zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac, false);
943}
944
6006414d
PR
945/*
946 * Install MAC hash entry - called upon access VLAN change.
947 */
00d30205 948static void zebra_evpn_install_mac_hash(struct hash_bucket *bucket, void *ctxt)
6006414d 949{
3198b2b3 950 struct zebra_mac *mac;
6006414d
PR
951 struct mac_walk_ctx *wctx = ctxt;
952
3198b2b3 953 mac = (struct zebra_mac *)bucket->data;
6006414d
PR
954
955 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
956 zebra_evpn_rem_mac_install(wctx->zevpn, mac, false);
957}
958
00d30205 959/*
960 * Uninstall remote MAC entries for this EVPN.
961 */
962void zebra_evpn_rem_mac_uninstall_all(struct zebra_evpn *zevpn)
963{
964 struct mac_walk_ctx wctx;
965
966 if (!zevpn->mac_table)
967 return;
968
969 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
970 wctx.zevpn = zevpn;
971 wctx.uninstall = 1;
972 wctx.upd_client = 0;
973 wctx.flags = ZEBRA_MAC_REMOTE;
974
975 hash_iterate(zevpn->mac_table, zebra_evpn_uninstall_mac_hash, &wctx);
976}
977
978/*
979 * Install remote MAC entries for this EVPN.
980 */
981void zebra_evpn_rem_mac_install_all(struct zebra_evpn *zevpn)
982{
983 struct mac_walk_ctx wctx;
984
985 if (!zevpn->mac_table)
986 return;
987
988 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
989 wctx.zevpn = zevpn;
990 wctx.uninstall = 0;
991 wctx.upd_client = 0;
992 wctx.flags = ZEBRA_MAC_REMOTE;
993
994 hash_iterate(zevpn->mac_table, zebra_evpn_install_mac_hash, &wctx);
995}
996
6006414d
PR
997/*
998 * Read and populate local MACs and neighbors corresponding to this EVPN.
999 */
f6371c34 1000void zebra_evpn_read_mac_neigh(struct zebra_evpn *zevpn, struct interface *ifp)
6006414d
PR
1001{
1002 struct zebra_ns *zns;
b5fde6fd 1003 struct zebra_vrf *zvrf;
6006414d
PR
1004 struct zebra_if *zif;
1005 struct interface *vlan_if;
8d30ff3b 1006 struct zebra_vxlan_vni *vni;
6006414d
PR
1007 struct interface *vrr_if;
1008
1009 zif = ifp->info;
8d30ff3b 1010 vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
b5fde6fd
PG
1011 zvrf = zebra_vrf_lookup_by_id(zevpn->vrf_id);
1012 if (!zvrf || !zvrf->zns)
1013 return;
1014 zns = zvrf->zns;
6006414d
PR
1015
1016 if (IS_ZEBRA_DEBUG_VXLAN)
1017 zlog_debug(
1018 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1019 ifp->name, ifp->ifindex, zevpn->vni,
1020 zif->brslave_info.bridge_ifindex);
1021
784d88aa
SR
1022 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if,
1023 vni->access_vlan);
9464e5b8
SR
1024 /* We need to specifically read and retrieve the entry for BUM handling
1025 * via multicast, if any.
1026 */
1027 macfdb_read_mcast_entry_for_vni(zns, ifp, zevpn->vni);
8d30ff3b 1028 vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
6006414d 1029 if (vlan_if) {
243b74ed
AK
1030 /* Add SVI MAC */
1031 zebra_evpn_acc_bd_svi_mac_add(vlan_if);
6006414d
PR
1032
1033 /* Add SVI MAC-IP */
c0c7707d
AK
1034 if (advertise_svi_macip_enabled(zevpn)
1035 || advertise_gw_macip_enabled(zevpn))
1036 zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
6006414d
PR
1037
1038 /* Add VRR MAC-IP - if any*/
c0c7707d
AK
1039 if (advertise_gw_macip_enabled(zevpn)) {
1040 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1041 if (vrr_if)
1042 zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
1043 }
6006414d
PR
1044
1045 neigh_read_for_vlan(zns, vlan_if);
1046 }
1047}
1048
1049/*
8b5fdf2e 1050 * Hash function for EVPN.
6006414d 1051 */
8b5fdf2e 1052unsigned int zebra_evpn_hash_keymake(const void *p)
6006414d 1053{
f6371c34 1054 const struct zebra_evpn *zevpn = p;
6006414d
PR
1055
1056 return (jhash_1word(zevpn->vni, 0));
1057}
1058
1059/*
8b5fdf2e 1060 * Compare 2 evpn hash entries.
6006414d 1061 */
8b5fdf2e 1062bool zebra_evpn_hash_cmp(const void *p1, const void *p2)
6006414d 1063{
f6371c34
DS
1064 const struct zebra_evpn *zevpn1 = p1;
1065 const struct zebra_evpn *zevpn2 = p2;
6006414d
PR
1066
1067 return (zevpn1->vni == zevpn2->vni);
1068}
1069
8b5fdf2e 1070int zebra_evpn_list_cmp(void *p1, void *p2)
6006414d 1071{
f6371c34
DS
1072 const struct zebra_evpn *zevpn1 = p1;
1073 const struct zebra_evpn *zevpn2 = p2;
6006414d
PR
1074
1075 if (zevpn1->vni == zevpn2->vni)
1076 return 0;
1077 return (zevpn1->vni < zevpn2->vni) ? -1 : 1;
1078}
1079
1080/*
1081 * Callback to allocate VNI hash entry.
1082 */
8b5fdf2e 1083void *zebra_evpn_alloc(void *p)
6006414d 1084{
f6371c34
DS
1085 const struct zebra_evpn *tmp_vni = p;
1086 struct zebra_evpn *zevpn;
6006414d 1087
f6371c34 1088 zevpn = XCALLOC(MTYPE_ZEVPN, sizeof(struct zebra_evpn));
6006414d
PR
1089 zevpn->vni = tmp_vni->vni;
1090 return ((void *)zevpn);
1091}
1092
1093/*
1094 * Look up EVPN hash entry.
1095 */
f6371c34 1096struct zebra_evpn *zebra_evpn_lookup(vni_t vni)
6006414d
PR
1097{
1098 struct zebra_vrf *zvrf;
f6371c34
DS
1099 struct zebra_evpn tmp_vni;
1100 struct zebra_evpn *zevpn = NULL;
6006414d
PR
1101
1102 zvrf = zebra_vrf_get_evpn();
6006b807 1103 memset(&tmp_vni, 0, sizeof(tmp_vni));
6006414d
PR
1104 tmp_vni.vni = vni;
1105 zevpn = hash_lookup(zvrf->evpn_table, &tmp_vni);
1106
1107 return zevpn;
1108}
1109
1110/*
1111 * Add EVPN hash entry.
1112 */
f6371c34 1113struct zebra_evpn *zebra_evpn_add(vni_t vni)
6006414d 1114{
38078b1d 1115 char buffer[80];
6006414d 1116 struct zebra_vrf *zvrf;
f6371c34
DS
1117 struct zebra_evpn tmp_zevpn;
1118 struct zebra_evpn *zevpn = NULL;
6006414d
PR
1119
1120 zvrf = zebra_vrf_get_evpn();
6006b807 1121 memset(&tmp_zevpn, 0, sizeof(tmp_zevpn));
6006414d 1122 tmp_zevpn.vni = vni;
8b5fdf2e 1123 zevpn = hash_get(zvrf->evpn_table, &tmp_zevpn, zebra_evpn_alloc);
6006414d 1124
945ee7b2 1125 zebra_evpn_es_evi_init(zevpn);
6006414d 1126
38078b1d 1127 snprintf(buffer, sizeof(buffer), "Zebra EVPN MAC Table vni: %u", vni);
6006414d 1128 /* Create hash table for MAC */
38078b1d 1129 zevpn->mac_table = zebra_mac_db_create(buffer);
6006414d 1130
e2071325
DL
1131 snprintf(buffer, sizeof(buffer), "Zebra EVPN Neighbor Table vni: %u",
1132 vni);
6006414d 1133 /* Create hash table for neighbors */
38078b1d 1134 zevpn->neigh_table = zebra_neigh_db_create(buffer);
6006414d
PR
1135
1136 return zevpn;
1137}
1138
6006414d
PR
1139/*
1140 * Delete EVPN hash entry.
1141 */
f6371c34 1142int zebra_evpn_del(struct zebra_evpn *zevpn)
6006414d
PR
1143{
1144 struct zebra_vrf *zvrf;
f6371c34 1145 struct zebra_evpn *tmp_zevpn;
6006414d
PR
1146
1147 zvrf = zebra_vrf_get_evpn();
6006414d 1148
9daa5d47
AD
1149 zevpn->svi_if = NULL;
1150
6006414d
PR
1151 /* Free the neighbor hash table. */
1152 hash_free(zevpn->neigh_table);
1153 zevpn->neigh_table = NULL;
1154
1155 /* Free the MAC hash table. */
1156 hash_free(zevpn->mac_table);
1157 zevpn->mac_table = NULL;
1158
963b0c55
AK
1159 /* Remove references to the zevpn in the MH databases */
1160 if (zevpn->vxlan_if)
1161 zebra_evpn_vxl_evpn_set(zevpn->vxlan_if->info, zevpn, false);
945ee7b2 1162 zebra_evpn_es_evi_cleanup(zevpn);
6006414d
PR
1163
1164 /* Free the EVPN hash entry and allocated memory. */
1165 tmp_zevpn = hash_release(zvrf->evpn_table, zevpn);
1166 XFREE(MTYPE_ZEVPN, tmp_zevpn);
1167
1168 return 0;
1169}
1170
1171/*
1172 * Inform BGP about local EVPN addition.
1173 */
f6371c34 1174int zebra_evpn_send_add_to_client(struct zebra_evpn *zevpn)
6006414d
PR
1175{
1176 struct zserv *client;
1177 struct stream *s;
9daa5d47 1178 ifindex_t svi_index;
6006414d
PR
1179 int rc;
1180
1181 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
1182 /* BGP may not be running. */
1183 if (!client)
1184 return 0;
1185
9daa5d47
AD
1186 svi_index = zevpn->svi_if ? zevpn->svi_if->ifindex : 0;
1187
6006414d
PR
1188 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1189
1190 zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
1191 stream_putl(s, zevpn->vni);
1192 stream_put_in_addr(s, &zevpn->local_vtep_ip);
1193 stream_put(s, &zevpn->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
1194 stream_put_in_addr(s, &zevpn->mcast_grp);
9daa5d47 1195 stream_put(s, &svi_index, sizeof(ifindex_t));
6006414d
PR
1196
1197 /* Write packet size. */
1198 stream_putw_at(s, 0, stream_get_endp(s));
1199
1200 if (IS_ZEBRA_DEBUG_VXLAN)
9daa5d47
AD
1201 zlog_debug(
1202 "Send EVPN_ADD %u %pI4 tenant vrf %s(%u) SVI index %u to %s",
1203 zevpn->vni, &zevpn->local_vtep_ip,
1204 vrf_id_to_name(zevpn->vrf_id), zevpn->vrf_id,
1205 (zevpn->svi_if ? zevpn->svi_if->ifindex : 0),
1206 zebra_route_string(client->proto));
6006414d
PR
1207
1208 client->vniadd_cnt++;
1209 rc = zserv_send_message(client, s);
1210
1211 if (!(zevpn->flags & ZEVPN_READY_FOR_BGP)) {
1212 zevpn->flags |= ZEVPN_READY_FOR_BGP;
1213 /* once the EVPN is sent the ES-EVIs can also be replayed
1214 * to BGP
1215 */
1216 zebra_evpn_update_all_es(zevpn);
1217 }
1218 return rc;
1219}
1220
1221/*
1222 * Inform BGP about local EVPN deletion.
1223 */
f6371c34 1224int zebra_evpn_send_del_to_client(struct zebra_evpn *zevpn)
6006414d
PR
1225{
1226 struct zserv *client;
1227 struct stream *s;
1228
1229 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
1230 /* BGP may not be running. */
1231 if (!client)
1232 return 0;
1233
1234 if (zevpn->flags & ZEVPN_READY_FOR_BGP) {
1235 zevpn->flags &= ~ZEVPN_READY_FOR_BGP;
1236 /* the ES-EVIs must be removed from BGP before the EVPN is */
1237 zebra_evpn_update_all_es(zevpn);
1238 }
1239
1240 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1241 stream_reset(s);
1242
1243 zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
1244 stream_putl(s, zevpn->vni);
1245
1246 /* Write packet size. */
1247 stream_putw_at(s, 0, stream_get_endp(s));
1248
1249 if (IS_ZEBRA_DEBUG_VXLAN)
1250 zlog_debug("Send EVPN_DEL %u to %s", zevpn->vni,
1251 zebra_route_string(client->proto));
1252
1253 client->vnidel_cnt++;
1254 return zserv_send_message(client, s);
1255}
1256
6006414d
PR
1257/*
1258 * See if remote VTEP matches with prefix.
1259 */
c172c032
DS
1260static int zebra_evpn_vtep_match(struct in_addr *vtep_ip,
1261 struct zebra_vtep *zvtep)
6006414d
PR
1262{
1263 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
1264}
1265
1266/*
1267 * Locate remote VTEP in EVPN hash table.
1268 */
c172c032
DS
1269struct zebra_vtep *zebra_evpn_vtep_find(struct zebra_evpn *zevpn,
1270 struct in_addr *vtep_ip)
6006414d 1271{
c172c032 1272 struct zebra_vtep *zvtep;
6006414d
PR
1273
1274 if (!zevpn)
1275 return NULL;
1276
1277 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
8b5fdf2e 1278 if (zebra_evpn_vtep_match(vtep_ip, zvtep))
6006414d
PR
1279 break;
1280 }
1281
1282 return zvtep;
1283}
1284
1285/*
1286 * Add remote VTEP to EVPN hash table.
1287 */
c172c032
DS
1288struct zebra_vtep *zebra_evpn_vtep_add(struct zebra_evpn *zevpn,
1289 struct in_addr *vtep_ip,
1290 int flood_control)
6006414d
PR
1291
1292{
c172c032 1293 struct zebra_vtep *zvtep;
6006414d 1294
c172c032 1295 zvtep = XCALLOC(MTYPE_ZEVPN_VTEP, sizeof(struct zebra_vtep));
6006414d
PR
1296
1297 zvtep->vtep_ip = *vtep_ip;
1298 zvtep->flood_control = flood_control;
1299
1300 if (zevpn->vteps)
1301 zevpn->vteps->prev = zvtep;
1302 zvtep->next = zevpn->vteps;
1303 zevpn->vteps = zvtep;
1304
1305 return zvtep;
1306}
1307
1308/*
1309 * Remove remote VTEP from EVPN hash table.
1310 */
c172c032 1311int zebra_evpn_vtep_del(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep)
6006414d
PR
1312{
1313 if (zvtep->next)
1314 zvtep->next->prev = zvtep->prev;
1315 if (zvtep->prev)
1316 zvtep->prev->next = zvtep->next;
1317 else
1318 zevpn->vteps = zvtep->next;
1319
1320 zvtep->prev = zvtep->next = NULL;
1321 XFREE(MTYPE_ZEVPN_VTEP, zvtep);
1322
1323 return 0;
1324}
1325
1326/*
1327 * Delete all remote VTEPs for this EVPN (upon VNI delete). Also
1328 * uninstall from kernel if asked to.
1329 */
f6371c34 1330int zebra_evpn_vtep_del_all(struct zebra_evpn *zevpn, int uninstall)
6006414d 1331{
c172c032 1332 struct zebra_vtep *zvtep, *zvtep_next;
6006414d
PR
1333
1334 if (!zevpn)
1335 return -1;
1336
1337 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep_next) {
1338 zvtep_next = zvtep->next;
1339 if (uninstall)
8b5fdf2e
PR
1340 zebra_evpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
1341 zebra_evpn_vtep_del(zevpn, zvtep);
6006414d
PR
1342 }
1343
1344 return 0;
1345}
1346
1347/*
1348 * Install remote VTEP into the kernel if the remote VTEP has asked
1349 * for head-end-replication.
1350 */
c172c032 1351int zebra_evpn_vtep_install(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep)
6006414d
PR
1352{
1353 if (is_vxlan_flooding_head_end() &&
1354 (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL)) {
1355 if (ZEBRA_DPLANE_REQUEST_FAILURE ==
1356 dplane_vtep_add(zevpn->vxlan_if,
1357 &zvtep->vtep_ip, zevpn->vni))
1358 return -1;
1359 }
1360
1361 return 0;
1362}
1363
1364/*
1365 * Uninstall remote VTEP from the kernel.
1366 */
f6371c34 1367int zebra_evpn_vtep_uninstall(struct zebra_evpn *zevpn, struct in_addr *vtep_ip)
6006414d
PR
1368{
1369 if (!zevpn->vxlan_if) {
1370 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
1371 zevpn->vni, zevpn);
1372 return -1;
1373 }
1374
1375 if (ZEBRA_DPLANE_REQUEST_FAILURE ==
1376 dplane_vtep_delete(zevpn->vxlan_if, vtep_ip, zevpn->vni))
1377 return -1;
1378
1379 return 0;
1380}
1381
1382/*
1383 * Install or uninstall flood entries in the kernel corresponding to
1384 * remote VTEPs. This is invoked upon change to BUM handling.
1385 */
8b5fdf2e
PR
1386void zebra_evpn_handle_flooding_remote_vteps(struct hash_bucket *bucket,
1387 void *zvrf)
6006414d 1388{
f6371c34 1389 struct zebra_evpn *zevpn;
c172c032 1390 struct zebra_vtep *zvtep;
6006414d 1391
f6371c34 1392 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
1393 if (!zevpn)
1394 return;
1395
1396 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
1397 if (is_vxlan_flooding_head_end())
8b5fdf2e 1398 zebra_evpn_vtep_install(zevpn, zvtep);
6006414d 1399 else
8b5fdf2e 1400 zebra_evpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
6006414d
PR
1401 }
1402}
1403
1404/*
1405 * Cleanup EVPN/VTEP and update kernel
1406 */
8b5fdf2e 1407void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg)
6006414d 1408{
f6371c34 1409 struct zebra_evpn *zevpn = NULL;
6006414d 1410
f6371c34 1411 zevpn = (struct zebra_evpn *)bucket->data;
6006414d 1412
6006414d
PR
1413 /* Free up all neighbors and MACs, if any. */
1414 zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
1415 zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
1416
1417 /* Free up all remote VTEPs, if any. */
8b5fdf2e 1418 zebra_evpn_vtep_del_all(zevpn, 1);
6006414d
PR
1419
1420 /* Delete the hash entry. */
8b5fdf2e 1421 zebra_evpn_del(zevpn);
6006414d
PR
1422}
1423
f6371c34 1424static void zebra_evpn_process_sync_macip_add(struct zebra_evpn *zevpn,
1a3bd37f
MS
1425 const struct ethaddr *macaddr,
1426 uint16_t ipa_len,
1427 const struct ipaddr *ipaddr,
1428 uint8_t flags, uint32_t seq,
1429 const esi_t *esi)
6006414d 1430{
8b5fdf2e
PR
1431 char ipbuf[INET6_ADDRSTRLEN];
1432 bool sticky;
1433 bool remote_gw;
72de4110 1434 struct zebra_neigh *n = NULL;
852d9f97 1435 struct zebra_mac *mac = NULL;
6006414d 1436
8b5fdf2e
PR
1437 sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
1438 remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
1439 /* if sticky or remote-gw ignore updates from the peer */
1440 if (sticky || remote_gw) {
1441 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH
1442 || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
1443 zlog_debug(
ef7b8be4 1444 "Ignore sync-macip vni %u mac %pEA%s%s%s%s",
8b5fdf2e 1445 zevpn->vni,
ef7b8be4 1446 macaddr,
8b5fdf2e
PR
1447 ipa_len ? " IP " : "",
1448 ipa_len ? ipaddr2str(ipaddr, ipbuf,
1449 sizeof(ipbuf))
1450 : "",
1451 sticky ? " sticky" : "",
1452 remote_gw ? " remote_gw" : "");
1453 return;
1454 }
6006414d 1455
852d9f97
SW
1456 if (!ipa_len) {
1457 /* MAC update */
1458 (void)zebra_evpn_proc_sync_mac_update(zevpn, macaddr, ipa_len,
1459 ipaddr, flags, seq, esi);
1460 } else {
1461 /* MAC-IP update */
1462 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
1463 if (!mac) {
1464 mac = zebra_evpn_proc_sync_mac_update(zevpn, macaddr,
1465 ipa_len, ipaddr,
1466 flags, seq, esi);
1467 }
1468 if (!mac)
1469 return;
1470
8b5fdf2e
PR
1471 n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
1472 if (n
16de1338
AK
1473 && !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq,
1474 true))
8b5fdf2e 1475 return;
6006414d 1476
852d9f97
SW
1477 zebra_evpn_proc_sync_neigh_update(zevpn, n, ipa_len, ipaddr,
1478 flags, seq, esi, mac);
1479 }
6006414d
PR
1480}
1481
8b5fdf2e
PR
1482/************************** remote mac-ip handling **************************/
1483/* Process a remote MACIP add from BGP. */
1a3bd37f
MS
1484void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
1485 uint16_t ipa_len, const struct ipaddr *ipaddr,
8b5fdf2e 1486 uint8_t flags, uint32_t seq,
1a3bd37f 1487 struct in_addr vtep_ip, const esi_t *esi)
6006414d 1488{
f6371c34 1489 struct zebra_evpn *zevpn;
c172c032 1490 struct zebra_vtep *zvtep;
3198b2b3 1491 struct zebra_mac *mac = NULL;
8b5fdf2e
PR
1492 struct interface *ifp = NULL;
1493 struct zebra_if *zif = NULL;
1494 struct zebra_vrf *zvrf;
6006414d 1495
8b5fdf2e
PR
1496 /* Locate EVPN hash entry - expected to exist. */
1497 zevpn = zebra_evpn_lookup(vni);
1498 if (!zevpn) {
34c9b28b
DS
1499 if (IS_ZEBRA_DEBUG_VXLAN)
1500 zlog_debug("Unknown VNI %u upon remote MACIP ADD", vni);
8b5fdf2e 1501 return;
6006414d
PR
1502 }
1503
8b5fdf2e
PR
1504 ifp = zevpn->vxlan_if;
1505 if (ifp)
1506 zif = ifp->info;
1507 if (!ifp || !if_is_operative(ifp) || !zif || !zif->brslave_info.br_if) {
4bf66f43 1508 if (IS_ZEBRA_DEBUG_VXLAN)
1509 zlog_debug(
1510 "Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
1511 vni);
8b5fdf2e
PR
1512 return;
1513 }
6006414d 1514
8b5fdf2e
PR
1515 /* Type-2 routes from another PE can be interpreted as remote or
1516 * SYNC based on the destination ES -
1517 * SYNC - if ES is local
1518 * REMOTE - if ES is not local
1519 */
1520 if (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) {
38f681e1
AK
1521 struct zebra_evpn_es *es;
1522
1523 es = zebra_evpn_es_find(esi);
1524 if (es && (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)) {
1525 zebra_evpn_process_sync_macip_add(zevpn, macaddr,
1526 ipa_len, ipaddr,
1527 flags, seq, esi);
1528 } else {
1529 if (IS_ZEBRA_DEBUG_EVPN_MH_ES) {
1530 char esi_str[ESI_STR_LEN];
1531
1532 esi_to_str(esi, esi_str, sizeof(esi_str));
1533 zlog_debug(
1534 "Ignore sync-macip add; ES %s is not ready",
1535 esi_str);
1536 }
1537 }
1538
8b5fdf2e
PR
1539 return;
1540 }
6006414d 1541
8b5fdf2e
PR
1542 /* The remote VTEP specified should normally exist, but it is
1543 * possible that when peering comes up, peer may advertise MACIP
1544 * routes before advertising type-3 routes.
1545 */
1546 if (vtep_ip.s_addr) {
1547 zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
1548 if (!zvtep) {
1549 zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip,
1550 VXLAN_FLOOD_DISABLED);
1551 if (!zvtep) {
1552 flog_err(
1553 EC_ZEBRA_VTEP_ADD_FAILED,
1554 "Failed to add remote VTEP, VNI %u zevpn %p upon remote MACIP ADD",
1555 vni, zevpn);
1556 return;
1557 }
6006414d 1558
8b5fdf2e
PR
1559 zebra_evpn_vtep_install(zevpn, zvtep);
1560 }
6006414d
PR
1561 }
1562
d6bf8f13 1563 zvrf = zebra_vrf_get_evpn();
852d9f97 1564 if (!zvrf)
6006414d 1565 return;
6006414d 1566
852d9f97
SW
1567 if (!ipa_len) {
1568 /* MAC update */
1569 zebra_evpn_mac_remote_macip_add(zevpn, zvrf, macaddr, vtep_ip,
1570 flags, seq, esi);
1571 } else {
1572 /* MAC-IP update
1573 * Add auto MAC if it doesn't exist.
1574 */
1575 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
1576 if (!mac) {
1577 mac = zebra_evpn_mac_add_auto(zevpn, macaddr);
1578
1579 if (IS_ZEBRA_DEBUG_VXLAN)
1580 zlog_debug(
1581 "Neigh %pIA: MAC %pEA not found, Auto MAC created",
1582 ipaddr, macaddr);
1583 }
1584
1585 zebra_evpn_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac,
1586 vtep_ip, flags, seq);
1587 }
6006414d
PR
1588}
1589
8b5fdf2e 1590/* Process a remote MACIP delete from BGP. */
1a3bd37f
MS
1591void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
1592 uint16_t ipa_len, const struct ipaddr *ipaddr,
8b5fdf2e 1593 struct in_addr vtep_ip)
6006414d 1594{
f6371c34 1595 struct zebra_evpn *zevpn;
3198b2b3 1596 struct zebra_mac *mac = NULL;
72de4110 1597 struct zebra_neigh *n = NULL;
8b5fdf2e
PR
1598 struct interface *ifp = NULL;
1599 struct zebra_if *zif = NULL;
1600 struct zebra_ns *zns;
8d30ff3b 1601 struct zebra_vxlan_vni *vnip;
6006414d 1602 struct zebra_vrf *zvrf;
8b5fdf2e 1603 char buf1[INET6_ADDRSTRLEN];
6006414d 1604
8b5fdf2e
PR
1605 /* Locate EVPN hash entry - expected to exist. */
1606 zevpn = zebra_evpn_lookup(vni);
1607 if (!zevpn) {
1608 if (IS_ZEBRA_DEBUG_VXLAN)
1609 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
6006414d 1610 return;
6006414d
PR
1611 }
1612
8b5fdf2e
PR
1613 ifp = zevpn->vxlan_if;
1614 if (ifp)
1615 zif = ifp->info;
1616 if (!ifp || !if_is_operative(ifp) || !zif || !zif->brslave_info.br_if) {
1617 if (IS_ZEBRA_DEBUG_VXLAN)
1618 zlog_debug(
1619 "Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
1620 vni);
6006414d 1621 return;
8b5fdf2e
PR
1622 }
1623 zns = zebra_ns_lookup(NS_DEFAULT);
8d30ff3b
SR
1624 vnip = zebra_vxlan_if_vni_find(zif, vni);
1625 if (!vnip) {
1626 if (IS_ZEBRA_DEBUG_VXLAN)
1627 zlog_debug(
1628 "VNI %u not in interface upon remote MACIP DEL",
1629 vni);
1630 return;
1631 }
6006414d 1632
8b5fdf2e
PR
1633 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
1634 if (ipa_len)
1635 n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
6006414d 1636
8b5fdf2e
PR
1637 if (n && !mac) {
1638 zlog_warn(
0653625d 1639 "Failed to locate MAC %pEA for Neigh %pIA VNI %u upon remote MACIP DEL",
ef7b8be4 1640 macaddr, ipaddr, vni);
6006414d 1641 return;
8b5fdf2e 1642 }
6006414d 1643
8b5fdf2e
PR
1644 /* If the remote mac or neighbor doesn't exist there is nothing
1645 * more to do. Otherwise, uninstall the entry and then remove it.
1646 */
0653625d
SW
1647 if (!mac && !n) {
1648 if (IS_ZEBRA_DEBUG_VXLAN)
1649 zlog_debug(
1650 "Failed to locate MAC %pEA & Neigh %pIA VNI %u upon remote MACIP DEL",
1651 macaddr, ipaddr, vni);
6006414d 1652 return;
0653625d 1653 }
6006414d 1654
096f7609 1655 zvrf = zevpn->vxlan_if->vrf->info;
6006414d 1656
8b5fdf2e
PR
1657 /* Ignore the delete if this mac is a gateway mac-ip */
1658 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
1659 && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
1660 zlog_warn(
ef7b8be4
DL
1661 "Ignore remote MACIP DEL VNI %u MAC %pEA%s%s as MAC is already configured as gateway MAC",
1662 vni, macaddr,
8b5fdf2e
PR
1663 ipa_len ? " IP " : "",
1664 ipa_len ? ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
6006414d 1665 return;
8b5fdf2e 1666 }
6006414d 1667
8b5fdf2e
PR
1668 /* Uninstall remote neighbor or MAC. */
1669 if (n)
1670 zebra_evpn_neigh_remote_uninstall(zevpn, zvrf, n, mac, ipaddr);
1671 else {
1672 /* DAD: when MAC is freeze state as remote learn event,
1673 * remote mac-ip delete event is received will result in freeze
1674 * entry removal, first fetch kernel for the same entry present
1675 * as LOCAL and reachable, avoid deleting this entry instead
1676 * use kerenel local entry to update during unfreeze time.
1677 */
1678 if (zvrf->dad_freeze
1679 && CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)
1680 && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1681 if (IS_ZEBRA_DEBUG_VXLAN)
1682 zlog_debug(
ef7b8be4
DL
1683 "%s: MAC %pEA (flags 0x%x) is remote and duplicate, read kernel for local entry",
1684 __func__, macaddr, mac->flags);
8b5fdf2e 1685 macfdb_read_specific_mac(zns, zif->brslave_info.br_if,
8d30ff3b 1686 macaddr, vnip->access_vlan);
8b5fdf2e 1687 }
6006414d 1688
8b5fdf2e
PR
1689 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1690 if (!ipa_len)
1691 zebra_evpn_sync_mac_del(mac);
1692 } else if (CHECK_FLAG(mac->flags, ZEBRA_NEIGH_REMOTE)) {
1693 zebra_evpn_rem_mac_del(zevpn, mac);
1694 }
6006414d 1695 }
6006414d
PR
1696}
1697
1698/************************** EVPN BGP config management ************************/
8b5fdf2e 1699void zebra_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt)
6006414d 1700{
f6371c34 1701 struct zebra_evpn *zevpn = NULL;
6006414d 1702
f6371c34 1703 zevpn = (struct zebra_evpn *)bucket->data;
6006414d
PR
1704 zevpn->advertise_gw_macip = 0;
1705 zevpn->advertise_svi_macip = 0;
1706 zevpn->advertise_subnet = 0;
1707
1708 zebra_evpn_neigh_del_all(zevpn, 1, 0,
1709 DEL_REMOTE_NEIGH | DEL_REMOTE_NEIGH_FROM_VTEP);
1710 zebra_evpn_mac_del_all(zevpn, 1, 0,
1711 DEL_REMOTE_MAC | DEL_REMOTE_MAC_FROM_VTEP);
8b5fdf2e 1712 zebra_evpn_vtep_del_all(zevpn, 1);
6006414d 1713}