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