Coverage Report

Created: 2025-08-26 06:20

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