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