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