Coverage Report

Created: 2026-05-11 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/zebra/zebra_vxlan.c
Line
Count
Source
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
7
#include <zebra.h>
8
9
#include "hash.h"
10
#include "if.h"
11
#include "jhash.h"
12
#include "linklist.h"
13
#include "log.h"
14
#include "memory.h"
15
#include "prefix.h"
16
#include "stream.h"
17
#include "table.h"
18
#include "vlan.h"
19
#include "vxlan.h"
20
#ifdef GNU_LINUX
21
#include <linux/neighbour.h>
22
#endif
23
#include "lib/printfrr.h"
24
25
#include "zebra/zebra_router.h"
26
#include "zebra/debug.h"
27
#include "zebra/interface.h"
28
#include "zebra/rib.h"
29
#include "zebra/rt.h"
30
#include "zebra/rt_netlink.h"
31
#include "zebra/zebra_errors.h"
32
#include "zebra/zebra_l2.h"
33
#include "zebra/zebra_l2_bridge_if.h"
34
#include "zebra/zebra_ns.h"
35
#include "zebra/zebra_vrf.h"
36
#include "zebra/zebra_vxlan.h"
37
#include "zebra/zebra_vxlan_private.h"
38
#include "zebra/zebra_evpn.h"
39
#include "zebra/zebra_evpn_mac.h"
40
#include "zebra/zebra_evpn_neigh.h"
41
#include "zebra/zebra_evpn_mh.h"
42
#include "zebra/zebra_evpn_vxlan.h"
43
#include "zebra/zebra_router.h"
44
45
2
DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
46
2
DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
47
2
DEFINE_MTYPE_STATIC(ZEBRA, L3VNI_MAC, "EVPN L3VNI MAC");
48
2
DEFINE_MTYPE_STATIC(ZEBRA, L3NEIGH, "EVPN Neighbor");
49
2
DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group");
50
2
DEFINE_MTYPE_STATIC(ZEBRA, EVPN_VTEP, "zebra VxLAN VTEP IP");
51
2
52
2
DEFINE_HOOK(zebra_rmac_update,
53
2
      (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete,
54
2
       const char *reason),
55
2
      (rmac, zl3vni, delete, reason));
56
2
57
2
/* config knobs */
58
2
static bool accept_bgp_seq = true;
59
2
60
2
/* Single VXlan Device Global Neigh Table */
61
2
struct hash *svd_nh_table;
62
2
63
2
/* static function declarations */
64
2
static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
65
2
              void **args);
66
2
static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
67
2
          json_object *json);
68
2
static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
69
2
            json_object *json);
70
2
static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt);
71
2
72
2
/* l3-vni next-hop neigh related APIs */
73
2
static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
74
2
              const struct ipaddr *ip);
75
2
static void *zl3vni_nh_alloc(void *p);
76
2
static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
77
2
           const struct ipaddr *vtep_ip,
78
2
           const struct ethaddr *rmac);
79
2
static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
80
2
static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
81
2
static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
82
2
             struct zebra_neigh *n);
83
2
static struct zebra_neigh *svd_nh_add(const struct ipaddr *vtep_ip,
84
2
              const struct ethaddr *rmac);
85
2
static int svd_nh_del(struct zebra_neigh *n);
86
2
static int svd_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
87
2
static int svd_nh_uninstall(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
88
2
89
2
/* l3-vni rmac related APIs */
90
2
static void zl3vni_print_rmac_hash(struct hash_bucket *, void *);
91
2
static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
92
2
              const struct ethaddr *rmac);
93
2
static void *zl3vni_rmac_alloc(void *p);
94
2
static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
95
2
           const struct ethaddr *rmac);
96
2
static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac);
97
2
static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
98
2
             struct zebra_mac *zrmac);
99
2
static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
100
2
         struct zebra_mac *zrmac);
101
2
102
2
/* l3-vni related APIs*/
103
2
static void *zl3vni_alloc(void *p);
104
2
static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
105
2
static int zl3vni_del(struct zebra_l3vni *zl3vni);
106
2
107
2
static void zevpn_build_hash_table(void);
108
2
static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
109
2
static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
110
2
static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
111
2
    struct in_addr sip, struct in_addr mcast_grp);
112
2
static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf,
113
2
                struct in_addr sip,
114
2
                struct in_addr mcast_grp);
115
2
static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf);
116
2
117
2
bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf)
118
2
{
119
0
  return zvrf->dup_addr_detect && zebra_evpn_mh_do_dup_addr_detect();
120
0
}
121
122
/* Private functions */
123
static int host_rb_entry_compare(const struct host_rb_entry *hle1,
124
         const struct host_rb_entry *hle2)
125
0
{
126
0
  if (hle1->p.family < hle2->p.family)
127
0
    return -1;
128
129
0
  if (hle1->p.family > hle2->p.family)
130
0
    return 1;
131
132
0
  if (hle1->p.prefixlen < hle2->p.prefixlen)
133
0
    return -1;
134
135
0
  if (hle1->p.prefixlen > hle2->p.prefixlen)
136
0
    return 1;
137
138
0
  if (hle1->p.family == AF_INET) {
139
0
    if (hle1->p.u.prefix4.s_addr < hle2->p.u.prefix4.s_addr)
140
0
      return -1;
141
142
0
    if (hle1->p.u.prefix4.s_addr > hle2->p.u.prefix4.s_addr)
143
0
      return 1;
144
145
0
    return 0;
146
0
  } else if (hle1->p.family == AF_INET6) {
147
0
    return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
148
0
            IPV6_MAX_BYTELEN);
149
0
  } else if (hle1->p.family == AF_EVPN) {
150
0
    uint8_t family1;
151
0
    uint8_t family2;
152
153
    /* two (v4/v6) dummy prefixes of route_type BGP_EVPN_AD_ROUTE
154
     * are used for all nexthops associated with a non-zero ESI
155
     */
156
0
    family1 = is_evpn_prefix_ipaddr_v4(
157
0
          (const struct prefix_evpn *)&hle1->p)
158
0
          ? AF_INET
159
0
          : AF_INET6;
160
0
    family2 = is_evpn_prefix_ipaddr_v4(
161
0
          (const struct prefix_evpn *)&hle2->p)
162
0
          ? AF_INET
163
0
          : AF_INET6;
164
165
166
0
    if (family1 < family2)
167
0
      return -1;
168
169
0
    if (family1 > family2)
170
0
      return 1;
171
172
0
    return 0;
173
0
  } else {
174
0
    zlog_debug("%s: Unexpected family type: %d", __func__,
175
0
         hle1->p.family);
176
0
    return 0;
177
0
  }
178
0
}
179
RB_GENERATE(host_rb_tree_entry, host_rb_entry, hl_entry, host_rb_entry_compare);
180
181
static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe)
182
0
{
183
0
  struct host_rb_entry *hle;
184
0
  uint32_t count = 0;
185
186
0
  RB_FOREACH (hle, host_rb_tree_entry, hrbe)
187
0
    count++;
188
189
0
  return count;
190
0
}
191
192
static int l3vni_rmac_nh_list_cmp(void *p1, void *p2)
193
0
{
194
0
  const struct ipaddr *vtep_ip1 = p1;
195
0
  const struct ipaddr *vtep_ip2 = p2;
196
197
0
  return ipaddr_cmp(vtep_ip1, vtep_ip2);
198
0
}
199
200
static void l3vni_rmac_nh_free(struct ipaddr *vtep_ip)
201
0
{
202
0
  XFREE(MTYPE_EVPN_VTEP, vtep_ip);
203
0
}
204
205
static void l3vni_rmac_nh_list_nh_delete(struct zebra_l3vni *zl3vni,
206
           struct zebra_mac *zrmac,
207
           struct ipaddr *vtep_ip)
208
0
{
209
0
  struct listnode *node = NULL, *nnode = NULL;
210
0
  struct ipaddr *vtep = NULL;
211
212
0
  for (ALL_LIST_ELEMENTS(zrmac->nh_list, node, nnode, vtep)) {
213
0
    if (ipaddr_cmp(vtep, vtep_ip) == 0)
214
0
      break;
215
0
  }
216
217
0
  if (node) {
218
0
    l3vni_rmac_nh_free(vtep);
219
0
    list_delete_node(zrmac->nh_list, node);
220
0
  }
221
0
}
222
223
/*
224
 * Print neighbors for all EVPN.
225
 */
226
static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
227
            void **args)
228
0
{
229
0
  struct vty *vty;
230
0
  json_object *json = NULL, *json_evpn = NULL;
231
0
  struct zebra_evpn *zevpn;
232
0
  uint32_t num_neigh;
233
0
  struct neigh_walk_ctx wctx;
234
0
  char vni_str[VNI_STR_LEN];
235
0
  uint32_t print_dup;
236
237
0
  vty = (struct vty *)args[0];
238
0
  json = (json_object *)args[1];
239
0
  print_dup = (uint32_t)(uintptr_t)args[2];
240
241
0
  zevpn = (struct zebra_evpn *)bucket->data;
242
243
0
  num_neigh = hashcount(zevpn->neigh_table);
244
245
0
  if (print_dup)
246
0
    num_neigh = num_dup_detected_neighs(zevpn);
247
248
0
  if (json == NULL) {
249
0
    vty_out(vty,
250
0
      "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
251
0
      zevpn->vni, num_neigh);
252
0
  } else {
253
0
    json_evpn = json_object_new_object();
254
0
    json_object_int_add(json_evpn, "numArpNd", num_neigh);
255
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
256
0
  }
257
258
0
  if (!num_neigh) {
259
0
    if (json)
260
0
      json_object_object_add(json, vni_str, json_evpn);
261
0
    return;
262
0
  }
263
264
  /* Since we have IPv6 addresses to deal with which can vary widely in
265
   * size, we try to be a bit more elegant in display by first computing
266
   * the maximum width.
267
   */
268
0
  memset(&wctx, 0, sizeof(wctx));
269
0
  wctx.zevpn = zevpn;
270
0
  wctx.vty = vty;
271
0
  wctx.addr_width = 15;
272
0
  wctx.json = json_evpn;
273
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
274
0
         &wctx);
275
276
0
  if (json == NULL)
277
0
    zebra_evpn_print_neigh_hdr(vty, &wctx);
278
279
0
  if (print_dup)
280
0
    hash_iterate(zevpn->neigh_table,
281
0
           zebra_evpn_print_dad_neigh_hash, &wctx);
282
0
  else
283
0
    hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash,
284
0
           &wctx);
285
286
0
  if (json)
287
0
    json_object_object_add(json, vni_str, json_evpn);
288
0
}
289
290
/*
291
 * Print neighbors for all EVPNs in detail.
292
 */
293
static void zevpn_print_neigh_hash_all_evpn_detail(struct hash_bucket *bucket,
294
             void **args)
295
0
{
296
0
  struct vty *vty;
297
0
  json_object *json = NULL, *json_evpn = NULL;
298
0
  struct zebra_evpn *zevpn;
299
0
  uint32_t num_neigh;
300
0
  struct neigh_walk_ctx wctx;
301
0
  char vni_str[VNI_STR_LEN];
302
0
  uint32_t print_dup;
303
304
0
  vty = (struct vty *)args[0];
305
0
  json = (json_object *)args[1];
306
0
  print_dup = (uint32_t)(uintptr_t)args[2];
307
308
0
  zevpn = (struct zebra_evpn *)bucket->data;
309
0
  if (!zevpn) {
310
0
    if (json)
311
0
      vty_out(vty, "{}\n");
312
0
    return;
313
0
  }
314
0
  num_neigh = hashcount(zevpn->neigh_table);
315
316
0
  if (print_dup && num_dup_detected_neighs(zevpn) == 0)
317
0
    return;
318
319
0
  if (json == NULL) {
320
0
    vty_out(vty,
321
0
      "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
322
0
      zevpn->vni, num_neigh);
323
0
  } else {
324
0
    json_evpn = json_object_new_object();
325
0
    json_object_int_add(json_evpn, "numArpNd", num_neigh);
326
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
327
0
  }
328
0
  if (!num_neigh) {
329
0
    if (json)
330
0
      json_object_object_add(json, vni_str, json_evpn);
331
0
    return;
332
0
  }
333
334
0
  memset(&wctx, 0, sizeof(wctx));
335
0
  wctx.zevpn = zevpn;
336
0
  wctx.vty = vty;
337
0
  wctx.addr_width = 15;
338
0
  wctx.json = json_evpn;
339
340
0
  if (print_dup)
341
0
    hash_iterate(zevpn->neigh_table,
342
0
           zebra_evpn_print_dad_neigh_hash_detail, &wctx);
343
0
  else
344
0
    hash_iterate(zevpn->neigh_table,
345
0
           zebra_evpn_print_neigh_hash_detail, &wctx);
346
347
0
  if (json)
348
0
    json_object_object_add(json, vni_str, json_evpn);
349
0
}
350
351
/* print a specific next hop for an l3vni */
352
static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
353
          json_object *json)
354
0
{
355
0
  char buf1[ETHER_ADDR_STRLEN];
356
0
  char buf2[INET6_ADDRSTRLEN];
357
0
  json_object *json_hosts = NULL;
358
0
  struct host_rb_entry *hle;
359
360
0
  if (!json) {
361
0
    vty_out(vty, "Ip: %s\n",
362
0
      ipaddr2str(&n->ip, buf2, sizeof(buf2)));
363
0
    vty_out(vty, "  RMAC: %s\n",
364
0
      prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
365
0
    if (n->refcnt)
366
      /* SVD neigh */
367
0
      vty_out(vty, "  Refcount: %u\n", n->refcnt);
368
0
    else {
369
0
      vty_out(vty, "  Refcount: %d\n",
370
0
        rb_host_count(&n->host_rb));
371
0
      vty_out(vty, "  Prefixes:\n");
372
0
      RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
373
0
        vty_out(vty, "    %pFX\n", &hle->p);
374
0
    }
375
0
  } else {
376
0
    json_hosts = json_object_new_array();
377
0
    json_object_string_add(
378
0
      json, "ip", ipaddr2str(&(n->ip), buf2, sizeof(buf2)));
379
0
    json_object_string_add(
380
0
      json, "routerMac",
381
0
      prefix_mac2str(&n->emac, buf2, sizeof(buf2)));
382
0
    if (n->refcnt)
383
      /* SVD neigh */
384
0
      json_object_int_add(json, "refCount", n->refcnt);
385
0
    else {
386
0
      json_object_int_add(json, "refCount",
387
0
              rb_host_count(&n->host_rb));
388
0
      RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
389
0
        json_object_array_add(
390
0
          json_hosts,
391
0
          json_object_new_string(prefix2str(
392
0
            &hle->p, buf2, sizeof(buf2))));
393
0
      json_object_object_add(json, "prefixList", json_hosts);
394
0
    }
395
0
  }
396
0
}
397
398
/* Print a specific RMAC entry */
399
static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
400
            json_object *json)
401
0
{
402
0
  struct listnode *node = NULL;
403
0
  struct ipaddr *vtep = NULL;
404
0
  json_object *json_nhs = NULL;
405
406
0
  if (!json) {
407
0
    vty_out(vty, "MAC: %pEA\n", &zrmac->macaddr);
408
0
    vty_out(vty, " Remote VTEP: %pI4\n",
409
0
      &zrmac->fwd_info.r_vtep_ip);
410
0
  } else {
411
0
    json_nhs = json_object_new_array();
412
0
    json_object_string_addf(json, "routerMac", "%pEA",
413
0
          &zrmac->macaddr);
414
0
    json_object_string_addf(json, "vtepIp", "%pI4",
415
0
          &zrmac->fwd_info.r_vtep_ip);
416
0
    for (ALL_LIST_ELEMENTS_RO(zrmac->nh_list, node, vtep)) {
417
0
      json_object_array_add(json_nhs, json_object_new_stringf(
418
0
                "%pIA", vtep));
419
0
    }
420
0
    json_object_object_add(json, "nexthops", json_nhs);
421
0
  }
422
0
}
423
424
/*
425
 * Print MACs for all EVPNs.
426
 */
427
static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt)
428
0
{
429
0
  struct vty *vty;
430
0
  json_object *json = NULL, *json_evpn = NULL;
431
0
  json_object *json_mac = NULL;
432
0
  struct zebra_evpn *zevpn;
433
0
  uint32_t num_macs;
434
0
  struct mac_walk_ctx *wctx = ctxt;
435
0
  char vni_str[VNI_STR_LEN];
436
437
0
  vty = wctx->vty;
438
0
  json = wctx->json;
439
440
0
  zevpn = (struct zebra_evpn *)bucket->data;
441
0
  wctx->zevpn = zevpn;
442
443
  /*We are iterating over a new VNI, set the count to 0*/
444
0
  wctx->count = 0;
445
446
0
  num_macs = num_valid_macs(zevpn);
447
0
  if (!num_macs)
448
0
    return;
449
450
0
  if (wctx->print_dup)
451
0
    num_macs = num_dup_detected_macs(zevpn);
452
453
0
  if (json) {
454
0
    json_evpn = json_object_new_object();
455
0
    json_mac = json_object_new_object();
456
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
457
0
  }
458
459
0
  if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
460
0
    if (json == NULL) {
461
0
      vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
462
0
        zevpn->vni, num_macs);
463
0
      vty_out(vty,
464
0
        "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
465
0
      vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
466
0
        "Type", "Flags", "Intf/Remote ES/VTEP",
467
0
        "VLAN", "Seq #'s");
468
0
    } else
469
0
      json_object_int_add(json_evpn, "numMacs", num_macs);
470
0
  }
471
472
0
  if (!num_macs) {
473
0
    if (json) {
474
0
      json_object_int_add(json_evpn, "numMacs", num_macs);
475
0
      json_object_object_add(json, vni_str, json_evpn);
476
0
    }
477
0
    return;
478
0
  }
479
480
  /* assign per-evpn to wctx->json object to fill macs
481
   * under the evpn. Re-assign primary json object to fill
482
   * next evpn information.
483
   */
484
0
  wctx->json = json_mac;
485
0
  if (wctx->print_dup)
486
0
    hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash,
487
0
           wctx);
488
0
  else
489
0
    hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, wctx);
490
0
  wctx->json = json;
491
0
  if (json) {
492
0
    if (wctx->count)
493
0
      json_object_object_add(json_evpn, "macs", json_mac);
494
0
    json_object_object_add(json, vni_str, json_evpn);
495
0
  }
496
0
}
497
498
/*
499
 * Print MACs in detail for all EVPNs.
500
 */
501
static void zevpn_print_mac_hash_all_evpn_detail(struct hash_bucket *bucket,
502
                 void *ctxt)
503
0
{
504
0
  struct vty *vty;
505
0
  json_object *json = NULL, *json_evpn = NULL;
506
0
  json_object *json_mac = NULL;
507
0
  struct zebra_evpn *zevpn;
508
0
  uint32_t num_macs;
509
0
  struct mac_walk_ctx *wctx = ctxt;
510
0
  char vni_str[VNI_STR_LEN];
511
512
0
  vty = wctx->vty;
513
0
  json = wctx->json;
514
515
0
  zevpn = (struct zebra_evpn *)bucket->data;
516
0
  if (!zevpn) {
517
0
    if (json)
518
0
      vty_out(vty, "{}\n");
519
0
    return;
520
0
  }
521
0
  wctx->zevpn = zevpn;
522
523
  /*We are iterating over a new EVPN, set the count to 0*/
524
0
  wctx->count = 0;
525
526
0
  num_macs = num_valid_macs(zevpn);
527
0
  if (!num_macs)
528
0
    return;
529
530
0
  if (wctx->print_dup && (num_dup_detected_macs(zevpn) == 0))
531
0
    return;
532
533
0
  if (json) {
534
0
    json_evpn = json_object_new_object();
535
0
    json_mac = json_object_new_object();
536
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
537
0
  }
538
539
0
  if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
540
0
    if (json == NULL) {
541
0
      vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
542
0
        zevpn->vni, num_macs);
543
0
    } else
544
0
      json_object_int_add(json_evpn, "numMacs", num_macs);
545
0
  }
546
  /* assign per-evpn to wctx->json object to fill macs
547
   * under the evpn. Re-assign primary json object to fill
548
   * next evpn information.
549
   */
550
0
  wctx->json = json_mac;
551
0
  if (wctx->print_dup)
552
0
    hash_iterate(zevpn->mac_table,
553
0
           zebra_evpn_print_dad_mac_hash_detail, wctx);
554
0
  else
555
0
    hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
556
0
           wctx);
557
0
  wctx->json = json;
558
0
  if (json) {
559
0
    if (wctx->count)
560
0
      json_object_object_add(json_evpn, "macs", json_mac);
561
0
    json_object_object_add(json, vni_str, json_evpn);
562
0
  }
563
0
}
564
565
static void zl3vni_print_nh_hash(struct hash_bucket *bucket, void *ctx)
566
0
{
567
0
  struct nh_walk_ctx *wctx = NULL;
568
0
  struct vty *vty = NULL;
569
0
  struct json_object *json_evpn = NULL;
570
0
  struct json_object *json_nh = NULL;
571
0
  struct zebra_neigh *n = NULL;
572
0
  char buf1[ETHER_ADDR_STRLEN];
573
0
  char buf2[INET6_ADDRSTRLEN];
574
575
0
  wctx = (struct nh_walk_ctx *)ctx;
576
0
  vty = wctx->vty;
577
0
  json_evpn = wctx->json;
578
0
  if (json_evpn)
579
0
    json_nh = json_object_new_object();
580
0
  n = (struct zebra_neigh *)bucket->data;
581
582
0
  if (!json_evpn) {
583
0
    vty_out(vty, "%-15s %-17s\n",
584
0
      ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
585
0
      prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
586
0
  } else {
587
0
    json_object_string_add(json_nh, "nexthopIp",
588
0
               ipaddr2str(&n->ip, buf2, sizeof(buf2)));
589
0
    json_object_string_add(
590
0
      json_nh, "routerMac",
591
0
      prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
592
0
    json_object_object_add(json_evpn,
593
0
               ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
594
0
               json_nh);
595
0
  }
596
0
}
597
598
static void zl3vni_print_nh_all_table(struct hash *nh_table, vni_t vni,
599
              struct vty *vty, json_object *json)
600
0
{
601
0
  uint32_t num_nh = 0;
602
0
  struct nh_walk_ctx wctx;
603
0
  char vni_str[VNI_STR_LEN];
604
0
  json_object *json_evpn = NULL;
605
0
  bool is_svd = false;
606
0
  const char *svd_str = "Global SVD Table";
607
608
0
  if (vni == 0)
609
0
    is_svd = true;
610
611
0
  num_nh = hashcount(nh_table);
612
613
0
  if (!num_nh)
614
0
    return;
615
616
0
  if (json) {
617
0
    json_evpn = json_object_new_object();
618
619
0
    snprintf(vni_str, VNI_STR_LEN, "%u", vni);
620
0
  }
621
622
0
  if (json == NULL) {
623
0
    if (is_svd)
624
0
      vty_out(vty, "\n%s #Next-Hops %u\n\n", svd_str, num_nh);
625
0
    else
626
0
      vty_out(vty, "\nVNI %u #Next-Hops %u\n\n", vni, num_nh);
627
628
0
    vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
629
0
  } else
630
0
    json_object_int_add(json_evpn, "numNextHops", num_nh);
631
632
0
  memset(&wctx, 0, sizeof(wctx));
633
0
  wctx.vty = vty;
634
0
  wctx.json = json_evpn;
635
0
  hash_iterate(nh_table, zl3vni_print_nh_hash, &wctx);
636
0
  if (json)
637
0
    json_object_object_add(json, vni_str, json_evpn);
638
0
}
639
640
static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket,
641
           void **args)
642
0
{
643
0
  struct vty *vty = NULL;
644
0
  json_object *json = NULL;
645
0
  struct zebra_l3vni *zl3vni = NULL;
646
647
0
  vty = (struct vty *)args[0];
648
0
  json = (struct json_object *)args[1];
649
650
0
  zl3vni = (struct zebra_l3vni *)bucket->data;
651
652
0
  zl3vni_print_nh_all_table(zl3vni->nh_table, zl3vni->vni, vty, json);
653
0
}
654
655
static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket,
656
             void **args)
657
0
{
658
0
  struct vty *vty = NULL;
659
0
  json_object *json = NULL;
660
0
  json_object *json_evpn = NULL;
661
0
  struct zebra_l3vni *zl3vni = NULL;
662
0
  uint32_t num_rmacs;
663
0
  struct rmac_walk_ctx wctx;
664
0
  char vni_str[VNI_STR_LEN];
665
666
0
  vty = (struct vty *)args[0];
667
0
  json = (struct json_object *)args[1];
668
669
0
  zl3vni = (struct zebra_l3vni *)bucket->data;
670
671
0
  num_rmacs = hashcount(zl3vni->rmac_table);
672
0
  if (!num_rmacs)
673
0
    return;
674
675
0
  if (json) {
676
0
    json_evpn = json_object_new_object();
677
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
678
0
  }
679
680
0
  if (json == NULL) {
681
0
    vty_out(vty, "\nVNI %u #RMACs %u\n\n", zl3vni->vni, num_rmacs);
682
0
    vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
683
0
  } else
684
0
    json_object_int_add(json_evpn, "numRmacs", num_rmacs);
685
686
  /* assign per-vni to wctx->json object to fill macs
687
   * under the vni. Re-assign primary json object to fill
688
   * next vni information.
689
   */
690
0
  memset(&wctx, 0, sizeof(wctx));
691
0
  wctx.vty = vty;
692
0
  wctx.json = json_evpn;
693
0
  hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
694
0
  if (json)
695
0
    json_object_object_add(json, vni_str, json_evpn);
696
0
}
697
698
static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
699
0
{
700
0
  struct zebra_mac *zrmac = NULL;
701
0
  struct rmac_walk_ctx *wctx = NULL;
702
0
  struct vty *vty = NULL;
703
0
  struct json_object *json = NULL;
704
0
  struct json_object *json_rmac = NULL;
705
0
  char buf[PREFIX_STRLEN];
706
707
0
  wctx = (struct rmac_walk_ctx *)ctx;
708
0
  vty = wctx->vty;
709
0
  json = wctx->json;
710
0
  if (json)
711
0
    json_rmac = json_object_new_object();
712
0
  zrmac = (struct zebra_mac *)bucket->data;
713
714
0
  if (!json) {
715
0
    vty_out(vty, "%-17s %-21pI4\n",
716
0
      prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
717
0
      &zrmac->fwd_info.r_vtep_ip);
718
0
  } else {
719
0
    json_object_string_add(
720
0
      json_rmac, "routerMac",
721
0
      prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
722
0
    json_object_string_addf(json_rmac, "vtepIp", "%pI4",
723
0
          &zrmac->fwd_info.r_vtep_ip);
724
0
    json_object_object_add(
725
0
      json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
726
0
      json_rmac);
727
0
  }
728
0
}
729
730
/* print a specific L3 VNI entry */
731
static void zl3vni_print(struct zebra_l3vni *zl3vni, void **ctx)
732
0
{
733
0
  char buf[PREFIX_STRLEN];
734
0
  struct vty *vty = NULL;
735
0
  json_object *json = NULL;
736
0
  struct zebra_evpn *zevpn = NULL;
737
0
  json_object *json_evpn_list = NULL;
738
0
  struct listnode *node = NULL, *nnode = NULL;
739
740
0
  vty = ctx[0];
741
0
  json = ctx[1];
742
743
0
  if (!json) {
744
0
    vty_out(vty, "VNI: %u\n", zl3vni->vni);
745
0
    vty_out(vty, "  Type: %s\n", "L3");
746
0
    vty_out(vty, "  Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
747
0
    vty_out(vty, "  Vlan: %u\n", zl3vni->vid);
748
0
    vty_out(vty, "  Bridge: %s\n",
749
0
      zl3vni->bridge_if ? zl3vni->bridge_if->name : "-");
750
0
    vty_out(vty, "  Local Vtep Ip: %pI4\n",
751
0
      &zl3vni->local_vtep_ip);
752
0
    vty_out(vty, "  Vxlan-Intf: %s\n",
753
0
      zl3vni_vxlan_if_name(zl3vni));
754
0
    vty_out(vty, "  SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
755
0
    vty_out(vty, "  State: %s\n", zl3vni_state2str(zl3vni));
756
0
    vty_out(vty, "  VNI Filter: %s\n",
757
0
      CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
758
0
        ? "prefix-routes-only"
759
0
        : "none");
760
0
    vty_out(vty, "  System MAC: %s\n",
761
0
      zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
762
0
    vty_out(vty, "  Router MAC: %s\n",
763
0
      zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
764
0
    vty_out(vty, "  L2 VNIs: ");
765
0
    for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn))
766
0
      vty_out(vty, "%u ", zevpn->vni);
767
0
    vty_out(vty, "\n");
768
0
  } else {
769
0
    json_evpn_list = json_object_new_array();
770
0
    json_object_int_add(json, "vni", zl3vni->vni);
771
0
    json_object_string_add(json, "type", "L3");
772
#if CONFDATE > 20240210
773
CPP_NOTICE("Drop `vrf` from JSON outputs")
774
#endif
775
0
    json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
776
0
    json_object_string_add(json, "tenantVrf",
777
0
               zl3vni_vrf_name(zl3vni));
778
0
    json_object_string_addf(json, "localVtepIp", "%pI4",
779
0
          &zl3vni->local_vtep_ip);
780
0
    json_object_string_add(json, "vxlanIntf",
781
0
               zl3vni_vxlan_if_name(zl3vni));
782
0
    json_object_string_add(json, "sviIntf",
783
0
               zl3vni_svi_if_name(zl3vni));
784
0
    json_object_string_add(json, "state", zl3vni_state2str(zl3vni));
785
0
    json_object_string_add(
786
0
      json, "sysMac",
787
0
      zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
788
0
    json_object_string_add(
789
0
      json, "routerMac",
790
0
      zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
791
0
    json_object_string_add(
792
0
      json, "vniFilter",
793
0
      CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
794
0
        ? "prefix-routes-only"
795
0
        : "none");
796
0
    for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn)) {
797
0
      json_object_array_add(json_evpn_list,
798
0
                json_object_new_int(zevpn->vni));
799
0
    }
800
0
    json_object_object_add(json, "l2Vnis", json_evpn_list);
801
0
  }
802
0
}
803
804
/* print a L3 VNI hash entry */
805
static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[])
806
0
{
807
0
  struct vty *vty = NULL;
808
0
  json_object *json = NULL;
809
0
  json_object *json_evpn = NULL;
810
0
  struct zebra_l3vni *zl3vni = NULL;
811
812
0
  vty = (struct vty *)ctx[0];
813
0
  json = (json_object *)ctx[1];
814
815
0
  zl3vni = (struct zebra_l3vni *)bucket->data;
816
817
0
  if (!json) {
818
0
    vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
819
0
      zl3vni->vni, "L3", zl3vni_vxlan_if_name(zl3vni),
820
0
      hashcount(zl3vni->rmac_table),
821
0
      hashcount(zl3vni->nh_table), "n/a",
822
0
      zl3vni_vrf_name(zl3vni));
823
0
  } else {
824
0
    char vni_str[VNI_STR_LEN];
825
826
0
    snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
827
0
    json_evpn = json_object_new_object();
828
0
    json_object_int_add(json_evpn, "vni", zl3vni->vni);
829
0
    json_object_string_add(json_evpn, "vxlanIf",
830
0
               zl3vni_vxlan_if_name(zl3vni));
831
0
    json_object_int_add(json_evpn, "numMacs",
832
0
            hashcount(zl3vni->rmac_table));
833
0
    json_object_int_add(json_evpn, "numArpNd",
834
0
            hashcount(zl3vni->nh_table));
835
0
    json_object_string_add(json_evpn, "numRemoteVteps", "n/a");
836
0
    json_object_string_add(json_evpn, "type", "L3");
837
0
    json_object_string_add(json_evpn, "tenantVrf",
838
0
               zl3vni_vrf_name(zl3vni));
839
0
    json_object_object_add(json, vni_str, json_evpn);
840
0
  }
841
0
}
842
843
/* print a L3 VNI hash entry in detail*/
844
static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
845
0
{
846
0
  struct vty *vty = NULL;
847
0
  struct zebra_l3vni *zl3vni = NULL;
848
0
  json_object *json_array = NULL;
849
0
  bool use_json = false;
850
0
  struct zebra_evpn_show *zes = data;
851
852
0
  vty = zes->vty;
853
0
  json_array = zes->json;
854
0
  use_json = zes->use_json;
855
856
0
  zl3vni = (struct zebra_l3vni *)bucket->data;
857
858
0
  zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni,
859
0
    use_json, json_array);
860
861
0
  if (!use_json)
862
0
    vty_out(vty, "\n");
863
0
}
864
865
static int zvni_map_to_svi_ns(struct ns *ns,
866
            void *_in_param,
867
            void **_p_ifp)
868
0
{
869
0
  struct zebra_ns *zns = ns->info;
870
0
  struct route_node *rn;
871
0
  struct zebra_from_svi_param *in_param =
872
0
    (struct zebra_from_svi_param *)_in_param;
873
0
  struct zebra_l2info_vlan *vl;
874
0
  struct interface *tmp_if = NULL;
875
0
  struct interface **p_ifp = (struct interface **)_p_ifp;
876
0
  struct zebra_if *zif;
877
878
0
  assert(in_param && p_ifp);
879
880
  /* TODO: Optimize with a hash. */
881
0
  for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
882
0
    tmp_if = (struct interface *)rn->info;
883
    /* Check oper status of the SVI. */
884
0
    if (!tmp_if || !if_is_operative(tmp_if))
885
0
      continue;
886
0
    zif = tmp_if->info;
887
0
    if (!zif || zif->zif_type != ZEBRA_IF_VLAN
888
0
        || zif->link != in_param->br_if)
889
0
      continue;
890
0
    vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
891
892
0
    if (vl->vid == in_param->vid) {
893
0
      *p_ifp = tmp_if;
894
0
      return NS_WALK_STOP;
895
0
    }
896
0
  }
897
0
  return NS_WALK_CONTINUE;
898
0
}
899
900
/* Map to SVI on bridge corresponding to specified VLAN. This can be one
901
 * of two cases:
902
 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
903
 * linked to the bridge
904
 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge interface
905
 * itself
906
 */
907
struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
908
0
{
909
0
  struct interface *tmp_if = NULL;
910
0
  struct zebra_if *zif;
911
0
  struct zebra_from_svi_param in_param;
912
0
  struct interface **p_ifp;
913
  /* Defensive check, caller expected to invoke only with valid bridge. */
914
0
  if (!br_if)
915
0
    return NULL;
916
917
  /* Determine if bridge is VLAN-aware or not */
918
0
  zif = br_if->info;
919
0
  assert(zif);
920
0
  in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
921
  /* Check oper status of the SVI. */
922
0
  if (!in_param.bridge_vlan_aware)
923
0
    return if_is_operative(br_if) ? br_if : NULL;
924
925
0
  in_param.vid = vid;
926
0
  in_param.br_if = br_if;
927
0
  in_param.zif = NULL;
928
0
  p_ifp = &tmp_if;
929
  /* Identify corresponding VLAN interface. */
930
0
  ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param,
931
0
         (void **)p_ifp);
932
0
  return tmp_if;
933
0
}
934
935
int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)
936
0
{
937
0
  zevpn->vid = 0;
938
0
  zevpn_vxlan_if_set(zevpn, zevpn->vxlan_if, false /* set */);
939
0
  zevpn_bridge_if_set(zevpn, zevpn->bridge_if, false /* set */);
940
941
  /* Remove references to the BUM mcast grp */
942
0
  zebra_vxlan_sg_deref(zevpn->local_vtep_ip, zevpn->mcast_grp);
943
944
0
  return zebra_evpn_del(zevpn);
945
0
}
946
947
static int zevpn_build_vni_hash_table(struct zebra_if *zif,
948
              struct zebra_vxlan_vni *vnip, void *arg)
949
0
{
950
0
  vni_t vni;
951
0
  struct zebra_evpn *zevpn;
952
0
  struct zebra_l3vni *zl3vni;
953
0
  struct interface *ifp;
954
0
  struct zebra_l2info_vxlan *vxl;
955
0
  struct interface *br_if;
956
957
0
  ifp = zif->ifp;
958
0
  vxl = &zif->l2info.vxl;
959
0
  vni = vnip->vni;
960
961
0
  if (IS_ZEBRA_DEBUG_VXLAN)
962
0
    zlog_debug("Build vni table for vni %u for Intf %s", vni,
963
0
         ifp->name);
964
965
  /* L3-VNI and L2-VNI are handled seperately */
966
0
  zl3vni = zl3vni_lookup(vni);
967
0
  if (zl3vni) {
968
969
0
    if (IS_ZEBRA_DEBUG_VXLAN)
970
0
      zlog_debug(
971
0
        "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
972
0
        ifp->name, ifp->ifindex, vni);
973
974
    /* associate with vxlan_if */
975
0
    zl3vni->local_vtep_ip = vxl->vtep_ip;
976
0
    zl3vni->vxlan_if = ifp;
977
978
    /*
979
     * we need to associate with SVI.
980
     * we can associate with svi-if only after association
981
     * with vxlan-intf is complete
982
     */
983
0
    zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
984
985
    /* Associate l3vni to mac-vlan and extract VRR MAC */
986
0
    zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
987
988
0
    if (IS_ZEBRA_DEBUG_VXLAN)
989
0
      zlog_debug(
990
0
        "create l3vni %u svi_if %s mac_vlan_if %s", vni,
991
0
        zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
992
0
        zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
993
0
                : "NIL");
994
995
0
    if (is_l3vni_oper_up(zl3vni))
996
0
      zebra_vxlan_process_l3vni_oper_up(zl3vni);
997
998
0
  } else {
999
0
    struct interface *vlan_if = NULL;
1000
1001
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1002
0
      zlog_debug(
1003
0
        "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %pI4",
1004
0
        ifp->name, ifp->ifindex, vni, &vxl->vtep_ip);
1005
1006
    /*
1007
     * EVPN hash entry is expected to exist, if the BGP process is
1008
     * killed
1009
     */
1010
0
    zevpn = zebra_evpn_lookup(vni);
1011
0
    if (zevpn) {
1012
0
      zlog_debug(
1013
0
        "EVPN hash already present for IF %s(%u) L2-VNI %u",
1014
0
        ifp->name, ifp->ifindex, vni);
1015
1016
      /*
1017
       * Inform BGP if intf is up and mapped to
1018
       * bridge.
1019
       */
1020
0
      if (if_is_operative(ifp) && zif->brslave_info.br_if)
1021
0
        zebra_evpn_send_add_to_client(zevpn);
1022
1023
      /* Send Local MAC-entries to client */
1024
0
      zebra_evpn_send_mac_list_to_client(zevpn);
1025
1026
      /* Send Loval Neighbor entries to client */
1027
0
      zebra_evpn_send_neigh_to_client(zevpn);
1028
0
    } else {
1029
0
      zevpn = zebra_evpn_add(vni);
1030
0
      if (!zevpn) {
1031
0
        zlog_debug(
1032
0
          "Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
1033
0
          ifp->name, ifp->ifindex, vni);
1034
0
        return 0;
1035
0
      }
1036
1037
0
      if (zevpn->local_vtep_ip.s_addr !=
1038
0
            vxl->vtep_ip.s_addr ||
1039
0
          zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
1040
0
        zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
1041
0
                 zevpn->mcast_grp);
1042
0
        zebra_vxlan_sg_ref(vxl->vtep_ip,
1043
0
               vnip->mcast_grp);
1044
0
        zevpn->local_vtep_ip = vxl->vtep_ip;
1045
0
        zevpn->mcast_grp = vnip->mcast_grp;
1046
        /* on local vtep-ip check if ES
1047
         * orig-ip needs to be updated
1048
         */
1049
0
        zebra_evpn_es_set_base_evpn(zevpn);
1050
0
      }
1051
0
      zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
1052
0
      br_if = zif->brslave_info.br_if;
1053
0
      zevpn_bridge_if_set(zevpn, br_if, true /* set */);
1054
0
      vlan_if = zvni_map_to_svi(vnip->access_vlan, br_if);
1055
0
      if (vlan_if) {
1056
0
        zevpn->vid = vnip->access_vlan;
1057
0
        zevpn->svi_if = vlan_if;
1058
0
        zevpn->vrf_id = vlan_if->vrf->vrf_id;
1059
0
        zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
1060
0
        if (zl3vni)
1061
0
          listnode_add_sort(zl3vni->l2vnis,
1062
0
                zevpn);
1063
0
      }
1064
1065
      /*
1066
       * Inform BGP if intf is up and mapped to
1067
       * bridge.
1068
       */
1069
0
      if (if_is_operative(ifp) && zif->brslave_info.br_if)
1070
0
        zebra_evpn_send_add_to_client(zevpn);
1071
0
    }
1072
0
  }
1073
1074
0
  return 0;
1075
0
}
1076
1077
static int zevpn_build_hash_table_zns(struct ns *ns,
1078
             void *param_in __attribute__((unused)),
1079
             void **param_out __attribute__((unused)))
1080
1
{
1081
1
  struct zebra_ns *zns = ns->info;
1082
1
  struct route_node *rn;
1083
1
  struct interface *ifp;
1084
1
  struct zebra_vrf *zvrf;
1085
1086
1
  zvrf = zebra_vrf_get_evpn();
1087
1088
  /* Walk VxLAN interfaces and create EVPN hash. */
1089
1
  for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1090
0
    struct zebra_if *zif;
1091
0
    struct zebra_l2info_vxlan *vxl;
1092
1093
0
    ifp = (struct interface *)rn->info;
1094
0
    if (!ifp)
1095
0
      continue;
1096
0
    zif = ifp->info;
1097
0
    if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1098
0
      continue;
1099
1100
0
    vxl = &zif->l2info.vxl;
1101
    /* link of VXLAN interface should be in zebra_evpn_vrf */
1102
0
    if (zvrf->zns->ns_id != vxl->link_nsid) {
1103
0
      if (IS_ZEBRA_DEBUG_VXLAN)
1104
0
        zlog_debug(
1105
0
          "Intf %s(%u) link not in same "
1106
0
          "namespace than BGP EVPN core instance ",
1107
0
          ifp->name, ifp->ifindex);
1108
0
      continue;
1109
0
    }
1110
1111
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1112
0
      zlog_debug("Building vni table for %s-if %s",
1113
0
           IS_ZEBRA_VXLAN_IF_VNI(zif) ? "vni" : "svd",
1114
0
           ifp->name);
1115
1116
0
    zebra_vxlan_if_vni_iterate(zif, zevpn_build_vni_hash_table,
1117
0
             NULL);
1118
0
  }
1119
1
  return NS_WALK_CONTINUE;
1120
1
}
1121
1122
/*
1123
 * Build the VNI hash table by going over the VxLAN interfaces. This
1124
 * is called when EVPN (advertise-all-vni) is enabled.
1125
 */
1126
1127
static void zevpn_build_hash_table(void)
1128
1
{
1129
1
  ns_walk_func(zevpn_build_hash_table_zns, NULL, NULL);
1130
1
}
1131
1132
/*
1133
 * Cleanup EVPN/VTEP and update kernel
1134
 */
1135
static void zebra_evpn_vxlan_cleanup_all(struct hash_bucket *bucket, void *arg)
1136
0
{
1137
0
  struct zebra_evpn *zevpn = NULL;
1138
0
  struct zebra_l3vni *zl3vni = NULL;
1139
1140
0
  zevpn = (struct zebra_evpn *)bucket->data;
1141
1142
  /* remove l2vni from l2vni's tenant-vrf l3-vni list */
1143
0
  zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
1144
0
  if (zl3vni)
1145
0
    listnode_delete(zl3vni->l2vnis, zevpn);
1146
1147
0
  zebra_evpn_cleanup_all(bucket, arg);
1148
0
}
1149
1150
/* cleanup L3VNI */
1151
static void zl3vni_cleanup_all(struct hash_bucket *bucket, void *args)
1152
0
{
1153
0
  struct zebra_l3vni *zl3vni = NULL;
1154
1155
0
  zl3vni = (struct zebra_l3vni *)bucket->data;
1156
1157
0
  zebra_vxlan_process_l3vni_oper_down(zl3vni);
1158
0
}
1159
1160
static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
1161
        const struct prefix *host)
1162
0
{
1163
0
  struct host_rb_entry lookup;
1164
0
  struct host_rb_entry *hle;
1165
1166
0
  memset(&lookup, 0, sizeof(lookup));
1167
0
  memcpy(&lookup.p, host, sizeof(*host));
1168
1169
0
  hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1170
0
  if (hle)
1171
0
    return;
1172
1173
0
  hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
1174
0
  memcpy(hle, &lookup, sizeof(lookup));
1175
1176
0
  RB_INSERT(host_rb_tree_entry, hrbe, hle);
1177
0
}
1178
1179
static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
1180
0
{
1181
0
  struct host_rb_entry lookup;
1182
0
  struct host_rb_entry *hle;
1183
1184
0
  memset(&lookup, 0, sizeof(lookup));
1185
0
  memcpy(&lookup.p, host, sizeof(*host));
1186
1187
0
  hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1188
0
  if (hle) {
1189
0
    RB_REMOVE(host_rb_tree_entry, hrbe, hle);
1190
0
    XFREE(MTYPE_HOST_PREFIX, hle);
1191
0
  }
1192
1193
0
  return;
1194
0
}
1195
1196
/*
1197
 * Look up MAC hash entry.
1198
 */
1199
static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
1200
              const struct ethaddr *rmac)
1201
0
{
1202
0
  struct zebra_mac tmp;
1203
0
  struct zebra_mac *pmac;
1204
1205
0
  memset(&tmp, 0, sizeof(tmp));
1206
0
  memcpy(&tmp.macaddr, rmac, ETH_ALEN);
1207
0
  pmac = hash_lookup(zl3vni->rmac_table, &tmp);
1208
1209
0
  return pmac;
1210
0
}
1211
1212
/*
1213
 * Callback to allocate RMAC hash entry.
1214
 */
1215
static void *zl3vni_rmac_alloc(void *p)
1216
0
{
1217
0
  const struct zebra_mac *tmp_rmac = p;
1218
0
  struct zebra_mac *zrmac;
1219
1220
0
  zrmac = XCALLOC(MTYPE_L3VNI_MAC, sizeof(struct zebra_mac));
1221
0
  *zrmac = *tmp_rmac;
1222
1223
0
  return ((void *)zrmac);
1224
0
}
1225
1226
/*
1227
 * Add RMAC entry to l3-vni
1228
 */
1229
static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
1230
           const struct ethaddr *rmac)
1231
0
{
1232
0
  struct zebra_mac tmp_rmac;
1233
0
  struct zebra_mac *zrmac = NULL;
1234
1235
0
  memset(&tmp_rmac, 0, sizeof(tmp_rmac));
1236
0
  memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
1237
0
  zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
1238
0
  zrmac->nh_list = list_new();
1239
0
  zrmac->nh_list->cmp = (int (*)(void *, void *))l3vni_rmac_nh_list_cmp;
1240
0
  zrmac->nh_list->del = (void (*)(void *))l3vni_rmac_nh_free;
1241
1242
0
  SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
1243
0
  SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
1244
1245
0
  return zrmac;
1246
0
}
1247
1248
/*
1249
 * Delete MAC entry.
1250
 */
1251
static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac)
1252
0
{
1253
0
  struct zebra_mac *tmp_rmac;
1254
1255
  /* free the list of nh list*/
1256
0
  list_delete(&zrmac->nh_list);
1257
1258
0
  tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
1259
0
  XFREE(MTYPE_L3VNI_MAC, tmp_rmac);
1260
1261
0
  return 0;
1262
0
}
1263
1264
/*
1265
 * Install remote RMAC into the forwarding plane.
1266
 */
1267
static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
1268
             struct zebra_mac *zrmac)
1269
0
{
1270
0
  const struct zebra_if *zif = NULL, *br_zif = NULL;
1271
0
  const struct zebra_vxlan_vni *vni;
1272
0
  const struct interface *br_ifp;
1273
0
  enum zebra_dplane_result res;
1274
0
  vlanid_t vid;
1275
1276
0
  if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1277
0
      || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1278
0
    return 0;
1279
1280
0
  zif = zl3vni->vxlan_if->info;
1281
0
  if (!zif)
1282
0
    return -1;
1283
1284
0
  br_ifp = zif->brslave_info.br_if;
1285
0
  if (br_ifp == NULL)
1286
0
    return -1;
1287
1288
0
  vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1289
1290
0
  br_zif = (const struct zebra_if *)br_ifp->info;
1291
1292
0
  if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1293
0
    vid = vni->access_vlan;
1294
0
  else
1295
0
    vid = 0;
1296
1297
0
  res = dplane_rem_mac_add(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr,
1298
0
         vni->vni, zrmac->fwd_info.r_vtep_ip, 0, 0,
1299
0
         false /*was_static*/);
1300
0
  if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1301
0
    return 0;
1302
0
  else
1303
0
    return -1;
1304
0
}
1305
1306
/*
1307
 * Uninstall remote RMAC from the forwarding plane.
1308
 */
1309
static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
1310
         struct zebra_mac *zrmac)
1311
0
{
1312
0
  const struct zebra_if *zif = NULL, *br_zif;
1313
0
  const struct zebra_vxlan_vni *vni;
1314
0
  const struct interface *br_ifp;
1315
0
  vlanid_t vid;
1316
0
  enum zebra_dplane_result res;
1317
1318
0
  if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1319
0
      || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1320
0
    return 0;
1321
1322
0
  if (!zl3vni->vxlan_if) {
1323
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1324
0
      zlog_debug(
1325
0
        "RMAC %pEA on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
1326
0
        &zrmac->macaddr, zl3vni->vni, zl3vni);
1327
0
    return -1;
1328
0
  }
1329
1330
0
  zif = zl3vni->vxlan_if->info;
1331
0
  if (!zif)
1332
0
    return -1;
1333
1334
0
  br_ifp = zif->brslave_info.br_if;
1335
0
  if (br_ifp == NULL)
1336
0
    return -1;
1337
1338
0
  vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1339
1340
0
  br_zif = (const struct zebra_if *)br_ifp->info;
1341
0
  if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1342
0
    vid = vni->access_vlan;
1343
0
  else
1344
0
    vid = 0;
1345
1346
0
  res = dplane_rem_mac_del(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr,
1347
0
         vni->vni, zrmac->fwd_info.r_vtep_ip);
1348
0
  if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1349
0
    return 0;
1350
0
  else
1351
0
    return -1;
1352
0
}
1353
1354
/* handle rmac add */
1355
static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
1356
          const struct ethaddr *rmac,
1357
          const struct ipaddr *vtep_ip)
1358
0
{
1359
0
  struct zebra_mac *zrmac = NULL;
1360
0
  struct ipaddr *vtep = NULL;
1361
1362
0
  zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
1363
0
  if (!zrmac) {
1364
1365
     /* Create the RMAC entry, or update its vtep, if necessary. */
1366
0
    zrmac = zl3vni_rmac_add(zl3vni, rmac);
1367
0
    if (!zrmac) {
1368
0
      zlog_debug(
1369
0
        "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA",
1370
0
        rmac, zl3vni->vni, vtep_ip);
1371
0
      return -1;
1372
0
    }
1373
0
    memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
1374
0
    zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1375
1376
0
    vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1377
0
    memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1378
0
    if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1379
0
      XFREE(MTYPE_EVPN_VTEP, vtep);
1380
1381
    /* Send RMAC for FPM processing */
1382
0
    hook_call(zebra_rmac_update, zrmac, zl3vni, false,
1383
0
        "new RMAC added");
1384
1385
    /* install rmac in kernel */
1386
0
    zl3vni_rmac_install(zl3vni, zrmac);
1387
0
  } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1388
0
           &vtep_ip->ipaddr_v4)) {
1389
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1390
0
      zlog_debug(
1391
0
        "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA",
1392
0
        zl3vni->vni, &zrmac->fwd_info.r_vtep_ip,
1393
0
        vtep_ip, rmac);
1394
1395
0
    zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1396
1397
0
    vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1398
0
    memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1399
0
    if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1400
0
      XFREE(MTYPE_EVPN_VTEP, vtep);
1401
1402
    /* install rmac in kernel */
1403
0
    zl3vni_rmac_install(zl3vni, zrmac);
1404
0
  }
1405
1406
0
  return 0;
1407
0
}
1408
1409
1410
/* handle rmac delete */
1411
static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
1412
           struct zebra_mac *zrmac,
1413
           struct ipaddr *vtep_ip)
1414
0
{
1415
0
  struct ipaddr ipv4_vtep;
1416
1417
0
  if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) {
1418
0
    memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
1419
0
    ipv4_vtep.ipa_type = IPADDR_V4;
1420
0
    if (vtep_ip->ipa_type == IPADDR_V6)
1421
0
      ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
1422
0
             &ipv4_vtep.ipaddr_v4);
1423
0
    else
1424
0
      memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
1425
0
             sizeof(struct in_addr));
1426
1427
    /* remove nh from rmac's list */
1428
0
    l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep);
1429
    /* delete nh is same as current selected, fall back to
1430
     * one present in the list
1431
     */
1432
0
    if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1433
0
           &ipv4_vtep.ipaddr_v4) &&
1434
0
        listcount(zrmac->nh_list)) {
1435
0
      struct ipaddr *vtep;
1436
1437
0
      vtep = listgetdata(listhead(zrmac->nh_list));
1438
0
      zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4;
1439
0
      if (IS_ZEBRA_DEBUG_VXLAN)
1440
0
        zlog_debug(
1441
0
          "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
1442
0
          zl3vni->vni, &ipv4_vtep,
1443
0
          &zrmac->fwd_info.r_vtep_ip,
1444
0
          &zrmac->macaddr);
1445
1446
      /* install rmac in kernel */
1447
0
      zl3vni_rmac_install(zl3vni, zrmac);
1448
0
    }
1449
1450
0
    if (!listcount(zrmac->nh_list)) {
1451
      /* uninstall from kernel */
1452
0
      zl3vni_rmac_uninstall(zl3vni, zrmac);
1453
1454
      /* Send RMAC for FPM processing */
1455
0
      hook_call(zebra_rmac_update, zrmac, zl3vni, true,
1456
0
          "RMAC deleted");
1457
1458
0
      if (IS_ZEBRA_DEBUG_VXLAN)
1459
0
        zlog_debug(
1460
0
          "L3VNI %u RMAC %pEA vtep_ip %pIA delete",
1461
0
          zl3vni->vni, &zrmac->macaddr, vtep_ip);
1462
1463
      /* del the rmac entry */
1464
0
      zl3vni_rmac_del(zl3vni, zrmac);
1465
0
    }
1466
0
  }
1467
0
}
1468
1469
/*
1470
 * Common code for look up of nh hash entry.
1471
 */
1472
static struct zebra_neigh *_nh_lookup(struct zebra_l3vni *zl3vni,
1473
              const struct ipaddr *ip)
1474
0
{
1475
0
  struct zebra_neigh tmp;
1476
0
  struct zebra_neigh *n;
1477
1478
0
  memset(&tmp, 0, sizeof(tmp));
1479
0
  memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
1480
1481
0
  if (zl3vni)
1482
0
    n = hash_lookup(zl3vni->nh_table, &tmp);
1483
0
  else
1484
0
    n = hash_lookup(svd_nh_table, &tmp);
1485
1486
0
  return n;
1487
0
}
1488
1489
/*
1490
 * Look up nh hash entry on a l3-vni.
1491
 */
1492
static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
1493
              const struct ipaddr *ip)
1494
0
{
1495
0
  return _nh_lookup(zl3vni, ip);
1496
0
}
1497
1498
/*
1499
 * Look up nh hash entry on a SVD.
1500
 */
1501
static struct zebra_neigh *svd_nh_lookup(const struct ipaddr *ip)
1502
0
{
1503
0
  return _nh_lookup(NULL, ip);
1504
0
}
1505
1506
/*
1507
 * Callback to allocate NH hash entry on L3-VNI.
1508
 */
1509
static void *zl3vni_nh_alloc(void *p)
1510
0
{
1511
0
  const struct zebra_neigh *tmp_n = p;
1512
0
  struct zebra_neigh *n;
1513
1514
0
  n = XCALLOC(MTYPE_L3NEIGH, sizeof(struct zebra_neigh));
1515
0
  *n = *tmp_n;
1516
1517
0
  return ((void *)n);
1518
0
}
1519
1520
/*
1521
 * Common code for neigh add.
1522
 */
1523
static struct zebra_neigh *_nh_add(struct zebra_l3vni *zl3vni,
1524
           const struct ipaddr *ip,
1525
           const struct ethaddr *mac)
1526
0
{
1527
0
  struct zebra_neigh tmp_n;
1528
0
  struct zebra_neigh *n = NULL;
1529
1530
0
  memset(&tmp_n, 0, sizeof(tmp_n));
1531
0
  memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
1532
1533
0
  if (zl3vni)
1534
0
    n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
1535
0
  else
1536
0
    n = hash_get(svd_nh_table, &tmp_n, zl3vni_nh_alloc);
1537
1538
0
  assert(n);
1539
1540
0
  RB_INIT(host_rb_tree_entry, &n->host_rb);
1541
1542
0
  memcpy(&n->emac, mac, ETH_ALEN);
1543
0
  SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1544
0
  SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
1545
1546
0
  return n;
1547
0
}
1548
1549
/*
1550
 * Add neighbor entry.
1551
 */
1552
static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
1553
           const struct ipaddr *ip,
1554
           const struct ethaddr *mac)
1555
0
{
1556
0
  return _nh_add(zl3vni, ip, mac);
1557
0
}
1558
1559
/*
1560
 * Delete neighbor entry.
1561
 */
1562
static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1563
0
{
1564
0
  struct zebra_neigh *tmp_n;
1565
0
  struct host_rb_entry *hle;
1566
1567
0
  while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
1568
0
    hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
1569
1570
0
    RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
1571
0
    XFREE(MTYPE_HOST_PREFIX, hle);
1572
0
  }
1573
1574
0
  tmp_n = hash_release(zl3vni->nh_table, n);
1575
0
  XFREE(MTYPE_L3NEIGH, tmp_n);
1576
1577
0
  return 0;
1578
0
}
1579
1580
/*
1581
 * Add Single VXlan Device neighbor entry.
1582
 */
1583
static struct zebra_neigh *svd_nh_add(const struct ipaddr *ip,
1584
              const struct ethaddr *mac)
1585
0
{
1586
0
  return _nh_add(NULL, ip, mac);
1587
0
}
1588
1589
/*
1590
 * Del Single VXlan Device neighbor entry.
1591
 */
1592
static int svd_nh_del(struct zebra_neigh *n)
1593
0
{
1594
0
  if (n->refcnt > 0)
1595
0
    return -1;
1596
1597
0
  hash_release(svd_nh_table, n);
1598
0
  XFREE(MTYPE_L3NEIGH, n);
1599
1600
0
  return 0;
1601
0
}
1602
1603
/*
1604
 * Common code to install remote nh as neigh into the kernel.
1605
 */
1606
static int _nh_install(struct zebra_l3vni *zl3vni, struct interface *ifp,
1607
           struct zebra_neigh *n)
1608
0
{
1609
0
  uint8_t flags;
1610
0
  int ret = 0;
1611
1612
0
  if (zl3vni && !is_l3vni_oper_up(zl3vni))
1613
0
    return -1;
1614
1615
0
  if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1616
0
      || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1617
0
    return 0;
1618
1619
0
  flags = DPLANE_NTF_EXT_LEARNED;
1620
0
  if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
1621
0
    flags |= DPLANE_NTF_ROUTER;
1622
1623
0
  dplane_rem_neigh_add(ifp, &n->ip, &n->emac, flags,
1624
0
           false /*was_static*/);
1625
1626
0
  return ret;
1627
0
}
1628
1629
/*
1630
 * Common code to uninstall remote nh from the kernel.
1631
 */
1632
static int _nh_uninstall(struct interface *ifp, struct zebra_neigh *n)
1633
0
{
1634
0
  if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1635
0
      || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1636
0
    return 0;
1637
1638
0
  if (!ifp || !if_is_operative(ifp))
1639
0
    return 0;
1640
1641
0
  dplane_rem_neigh_delete(ifp, &n->ip);
1642
1643
0
  return 0;
1644
0
}
1645
1646
/*
1647
 * Install remote nh as neigh into the kernel.
1648
 */
1649
static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1650
0
{
1651
0
  return _nh_install(zl3vni, zl3vni->svi_if, n);
1652
0
}
1653
1654
/*
1655
 * Uninstall remote nh from the kernel.
1656
 */
1657
static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
1658
             struct zebra_neigh *n)
1659
0
{
1660
0
  return _nh_uninstall(zl3vni->svi_if, n);
1661
0
}
1662
1663
/*
1664
 * Install SVD remote nh as neigh into the kernel.
1665
 */
1666
static int svd_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1667
0
{
1668
0
  return _nh_install(zl3vni, zl3vni->vxlan_if, n);
1669
0
}
1670
1671
/*
1672
 * Uninstall SVD remote nh from the kernel.
1673
 */
1674
static int svd_nh_uninstall(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1675
0
{
1676
0
  return _nh_uninstall(zl3vni->vxlan_if, n);
1677
0
}
1678
1679
/* Add remote vtep as a neigh entry */
1680
static int zl3vni_remote_nh_add(struct zebra_l3vni *zl3vni,
1681
        const struct ipaddr *vtep_ip,
1682
        const struct ethaddr *rmac,
1683
        const struct prefix *host_prefix)
1684
0
{
1685
0
  struct zebra_neigh *nh = NULL;
1686
1687
  /* Create the next hop entry, or update its mac, if necessary. */
1688
0
  nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
1689
0
  if (!nh) {
1690
0
    nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
1691
0
    if (!nh) {
1692
0
      zlog_debug(
1693
0
        "Failed to add NH %pIA as Neigh (RMAC %pEA L3-VNI %u prefix %pFX)",
1694
0
        vtep_ip, rmac, zl3vni->vni, host_prefix);
1695
0
      return -1;
1696
0
    }
1697
1698
    /* install the nh neigh in kernel */
1699
0
    zl3vni_nh_install(zl3vni, nh);
1700
0
  } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
1701
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1702
0
      zlog_debug(
1703
0
        "L3VNI %u RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX",
1704
0
        zl3vni->vni, &nh->emac, rmac, vtep_ip,
1705
0
        host_prefix);
1706
1707
0
    memcpy(&nh->emac, rmac, ETH_ALEN);
1708
    /* install (update) the nh neigh in kernel */
1709
0
    zl3vni_nh_install(zl3vni, nh);
1710
0
  }
1711
1712
0
  rb_find_or_add_host(&nh->host_rb, host_prefix);
1713
1714
0
  return 0;
1715
0
}
1716
1717
/* Del remote vtep as a neigh entry */
1718
static void zl3vni_remote_nh_del(struct zebra_l3vni *zl3vni,
1719
         struct zebra_neigh *nh,
1720
         struct prefix *host_prefix)
1721
0
{
1722
0
  rb_delete_host(&nh->host_rb, host_prefix);
1723
1724
0
  if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
1725
    /* uninstall from kernel */
1726
0
    zl3vni_nh_uninstall(zl3vni, nh);
1727
1728
    /* delete the nh entry */
1729
0
    zl3vni_nh_del(zl3vni, nh);
1730
0
  }
1731
0
}
1732
1733
/* Add remote vtep as a SVD neigh entry */
1734
static int svd_remote_nh_add(struct zebra_l3vni *zl3vni,
1735
           const struct ipaddr *vtep_ip,
1736
           const struct ethaddr *rmac,
1737
           const struct prefix *host_prefix)
1738
0
{
1739
0
  struct zebra_neigh *nh = NULL;
1740
1741
  /* SVD backed VNI check */
1742
0
  if (!IS_ZL3VNI_SVD_BACKED(zl3vni))
1743
0
    return 0;
1744
1745
  /* Create the SVD next hop entry, or update its mac, if necessary. */
1746
0
  nh = svd_nh_lookup(vtep_ip);
1747
0
  if (!nh) {
1748
0
    nh = svd_nh_add(vtep_ip, rmac);
1749
0
    if (!nh) {
1750
0
      zlog_debug(
1751
0
        "Failed to add NH %pIA as SVD Neigh (RMAC %pEA prefix %pFX)",
1752
0
        vtep_ip, rmac, host_prefix);
1753
0
      return -1;
1754
0
    }
1755
1756
0
  } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
1757
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1758
0
      zlog_debug(
1759
0
        "SVD RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX",
1760
0
        &nh->emac, rmac, vtep_ip, host_prefix);
1761
1762
0
    memcpy(&nh->emac, rmac, ETH_ALEN);
1763
    /* install (update) the nh neigh in kernel */
1764
0
    svd_nh_install(zl3vni, nh);
1765
1766
    /* Don't increment refcnt change */
1767
0
    return 0;
1768
0
  }
1769
1770
0
  nh->refcnt++;
1771
1772
0
  if (IS_ZEBRA_DEBUG_VXLAN)
1773
0
    zlog_debug("SVD NH ADD refcnt (%u) for nexthop %pIA",
1774
0
         nh->refcnt, vtep_ip);
1775
1776
  /*
1777
   * Install the nh neigh in kernel if this is the first time we
1778
   * have seen it.
1779
   */
1780
0
  if (nh->refcnt == 1)
1781
0
    svd_nh_install(zl3vni, nh);
1782
1783
0
  return 0;
1784
0
}
1785
1786
/* Del remote vtep as a SVD neigh entry */
1787
static int svd_remote_nh_del(struct zebra_l3vni *zl3vni,
1788
           const struct ipaddr *vtep_ip)
1789
0
{
1790
0
  struct zebra_neigh *nh;
1791
1792
  /* SVD backed VNI check */
1793
0
  if (!IS_ZL3VNI_SVD_BACKED(zl3vni))
1794
0
    return 0;
1795
1796
0
  nh = svd_nh_lookup(vtep_ip);
1797
0
  if (!nh) {
1798
0
    zlog_debug("Failed to del NH %pIA as SVD Neigh", vtep_ip);
1799
1800
0
    return -1;
1801
0
  }
1802
1803
0
  nh->refcnt--;
1804
1805
0
  if (IS_ZEBRA_DEBUG_VXLAN)
1806
0
    zlog_debug("SVD NH Del refcnt (%u) for nexthop %pIA",
1807
0
         nh->refcnt, vtep_ip);
1808
1809
  /* Last refcnt on NH, remove it completely. */
1810
0
  if (nh->refcnt == 0) {
1811
0
    svd_nh_uninstall(zl3vni, nh);
1812
0
    svd_nh_del(nh);
1813
0
  }
1814
1815
0
  return 0;
1816
0
}
1817
1818
/* handle neigh update from kernel - the only thing of interest is to
1819
 * readd stale entries.
1820
 */
1821
static int zl3vni_local_nh_add_update(struct zebra_l3vni *zl3vni,
1822
              struct ipaddr *ip, uint16_t state)
1823
0
{
1824
0
#ifdef GNU_LINUX
1825
0
  struct zebra_neigh *n = NULL;
1826
1827
0
  n = zl3vni_nh_lookup(zl3vni, ip);
1828
0
  if (!n)
1829
0
    return 0;
1830
1831
  /* all next hop neigh are remote and installed by frr.
1832
   * If the kernel has aged this entry, re-install.
1833
   */
1834
0
  if (state & NUD_STALE)
1835
0
    zl3vni_nh_install(zl3vni, n);
1836
0
#endif
1837
0
  return 0;
1838
0
}
1839
1840
/* handle neigh delete from kernel */
1841
static int zl3vni_local_nh_del(struct zebra_l3vni *zl3vni, struct ipaddr *ip)
1842
0
{
1843
0
  struct zebra_neigh *n = NULL;
1844
1845
0
  n = zl3vni_nh_lookup(zl3vni, ip);
1846
0
  if (!n)
1847
0
    return 0;
1848
1849
  /* all next hop neigh are remote and installed by frr.
1850
   * If we get an age out notification for these neigh entries, we have to
1851
   * install it back
1852
   */
1853
0
  zl3vni_nh_install(zl3vni, n);
1854
1855
0
  return 0;
1856
0
}
1857
1858
/*
1859
 * Hash function for L3 VNI.
1860
 */
1861
static unsigned int l3vni_hash_keymake(const void *p)
1862
0
{
1863
0
  const struct zebra_l3vni *zl3vni = p;
1864
1865
0
  return jhash_1word(zl3vni->vni, 0);
1866
0
}
1867
1868
/*
1869
 * Compare 2 L3 VNI hash entries.
1870
 */
1871
static bool l3vni_hash_cmp(const void *p1, const void *p2)
1872
0
{
1873
0
  const struct zebra_l3vni *zl3vni1 = p1;
1874
0
  const struct zebra_l3vni *zl3vni2 = p2;
1875
1876
0
  return (zl3vni1->vni == zl3vni2->vni);
1877
0
}
1878
1879
/*
1880
 * Callback to allocate L3 VNI hash entry.
1881
 */
1882
static void *zl3vni_alloc(void *p)
1883
0
{
1884
0
  struct zebra_l3vni *zl3vni = NULL;
1885
0
  const struct zebra_l3vni *tmp_l3vni = p;
1886
1887
0
  zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(struct zebra_l3vni));
1888
0
  zl3vni->vni = tmp_l3vni->vni;
1889
0
  return ((void *)zl3vni);
1890
0
}
1891
1892
/*
1893
 * Look up L3 VNI hash entry.
1894
 */
1895
struct zebra_l3vni *zl3vni_lookup(vni_t vni)
1896
0
{
1897
0
  struct zebra_l3vni tmp_l3vni;
1898
0
  struct zebra_l3vni *zl3vni = NULL;
1899
1900
0
  memset(&tmp_l3vni, 0, sizeof(tmp_l3vni));
1901
0
  tmp_l3vni.vni = vni;
1902
0
  zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
1903
1904
0
  return zl3vni;
1905
0
}
1906
1907
/*
1908
 * Add L3 VNI hash entry.
1909
 */
1910
static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
1911
0
{
1912
0
  struct zebra_l3vni tmp_zl3vni;
1913
0
  struct zebra_l3vni *zl3vni = NULL;
1914
1915
0
  memset(&tmp_zl3vni, 0, sizeof(tmp_zl3vni));
1916
0
  tmp_zl3vni.vni = vni;
1917
1918
0
  zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
1919
1920
0
  zl3vni->vrf_id = vrf_id;
1921
0
  zl3vni->svi_if = NULL;
1922
0
  zl3vni->vxlan_if = NULL;
1923
0
  zl3vni->l2vnis = list_new();
1924
0
  zl3vni->l2vnis->cmp = zebra_evpn_list_cmp;
1925
1926
  /* Create hash table for remote RMAC */
1927
0
  zl3vni->rmac_table = zebra_mac_db_create("Zebra L3-VNI RMAC-Table");
1928
1929
  /* Create hash table for neighbors */
1930
0
  zl3vni->nh_table = zebra_neigh_db_create("Zebra L3-VNI next-hop table");
1931
1932
0
  return zl3vni;
1933
0
}
1934
1935
/*
1936
 * Delete L3 VNI hash entry.
1937
 */
1938
static int zl3vni_del(struct zebra_l3vni *zl3vni)
1939
0
{
1940
0
  struct zebra_l3vni *tmp_zl3vni;
1941
1942
  /* free the list of l2vnis */
1943
0
  list_delete(&zl3vni->l2vnis);
1944
0
  zl3vni->l2vnis = NULL;
1945
1946
  /* Free the rmac table */
1947
0
  hash_free(zl3vni->rmac_table);
1948
0
  zl3vni->rmac_table = NULL;
1949
1950
  /* Free the nh table */
1951
0
  hash_free(zl3vni->nh_table);
1952
0
  zl3vni->nh_table = NULL;
1953
1954
  /* Free the VNI hash entry and allocated memory. */
1955
0
  tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
1956
0
  XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
1957
1958
0
  return 0;
1959
0
}
1960
1961
static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
1962
             void *_zl3vni,
1963
             void **_pifp)
1964
0
{
1965
0
  struct zebra_ns *zns = ns->info;
1966
0
  struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)_zl3vni;
1967
0
  struct route_node *rn = NULL;
1968
0
  struct interface *ifp = NULL;
1969
0
  struct zebra_vrf *zvrf;
1970
1971
0
  zvrf = zebra_vrf_get_evpn();
1972
1973
0
  assert(_pifp);
1974
1975
  /* loop through all vxlan-interface */
1976
0
  for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1977
1978
0
    struct zebra_if *zif = NULL;
1979
0
    struct zebra_l2info_vxlan *vxl;
1980
0
    struct zebra_vxlan_vni *vni = NULL;
1981
1982
0
    ifp = (struct interface *)rn->info;
1983
0
    if (!ifp)
1984
0
      continue;
1985
1986
0
    zif = ifp->info;
1987
0
    if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1988
0
      continue;
1989
1990
0
    vxl = &zif->l2info.vxl;
1991
0
    vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1992
0
    if (!vni || vni->vni != zl3vni->vni)
1993
0
      continue;
1994
1995
    /* link of VXLAN interface should be in zebra_evpn_vrf */
1996
0
    if (zvrf->zns->ns_id != vxl->link_nsid) {
1997
0
      if (IS_ZEBRA_DEBUG_VXLAN)
1998
0
        zlog_debug(
1999
0
          "Intf %s(%u) VNI %u, link not in same "
2000
0
          "namespace than BGP EVPN core instance ",
2001
0
          ifp->name, ifp->ifindex, vni->vni);
2002
0
      continue;
2003
0
    }
2004
2005
2006
0
    zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip;
2007
0
    *_pifp = (void *)ifp;
2008
0
    return NS_WALK_STOP;
2009
0
  }
2010
2011
0
  return NS_WALK_CONTINUE;
2012
0
}
2013
2014
struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
2015
0
{
2016
0
  struct interface **p_ifp;
2017
0
  struct interface *ifp = NULL;
2018
2019
0
  p_ifp = &ifp;
2020
2021
0
  ns_walk_func(zl3vni_map_to_vxlan_if_ns,
2022
0
         (void *)zl3vni, (void **)p_ifp);
2023
0
  return ifp;
2024
0
}
2025
2026
struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
2027
0
{
2028
0
  struct zebra_if *zif = NULL;    /* zebra_if for vxlan_if */
2029
0
  struct zebra_vxlan_vni *vni = NULL; /* vni info in vxlan_if */
2030
2031
0
  if (!zl3vni)
2032
0
    return NULL;
2033
2034
0
  if (!zl3vni->vxlan_if)
2035
0
    return NULL;
2036
2037
0
  zif = zl3vni->vxlan_if->info;
2038
0
  if (!zif)
2039
0
    return NULL;
2040
2041
0
  vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
2042
0
  if (!vni)
2043
0
    return NULL;
2044
2045
0
  return zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
2046
0
}
2047
2048
struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni)
2049
0
{
2050
0
  struct zebra_if *zif = NULL;    /* zebra_if for vxlan_if */
2051
2052
0
  if (!zl3vni)
2053
0
    return NULL;
2054
2055
0
  if (!zl3vni->vxlan_if)
2056
0
    return NULL;
2057
2058
0
  zif = zl3vni->vxlan_if->info;
2059
0
  if (!zif)
2060
0
    return NULL;
2061
2062
0
  return zebra_evpn_map_to_macvlan(zif->brslave_info.br_if,
2063
0
           zl3vni->svi_if);
2064
0
}
2065
2066
2067
struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id)
2068
0
{
2069
0
  struct zebra_vrf *zvrf = NULL;
2070
2071
0
  zvrf = zebra_vrf_lookup_by_id(vrf_id);
2072
0
  if (!zvrf)
2073
0
    return NULL;
2074
2075
0
  return zl3vni_lookup(zvrf->l3vni);
2076
0
}
2077
2078
static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
2079
0
{
2080
0
  int found = 0;
2081
0
  vni_t vni_id = 0;
2082
0
  struct zebra_ns *zns = ns->info;
2083
0
  struct zebra_l3vni **p_zl3vni = (struct zebra_l3vni **)_p_zl3vni;
2084
0
  struct zebra_from_svi_param *in_param =
2085
0
    (struct zebra_from_svi_param *)_in_param;
2086
0
  struct route_node *rn = NULL;
2087
0
  struct interface *tmp_if = NULL;
2088
0
  struct zebra_if *zif = NULL;
2089
0
  struct zebra_if *br_zif = NULL;
2090
2091
0
  assert(in_param && p_zl3vni);
2092
2093
0
  br_zif = in_param->br_if->info;
2094
0
  assert(br_zif);
2095
2096
0
  if (in_param->bridge_vlan_aware) {
2097
0
    vni_id = zebra_l2_bridge_if_vni_find(br_zif, in_param->vid);
2098
0
    if (vni_id)
2099
0
      found = 1;
2100
0
  } else {
2101
    /* loop through all vxlan-interface */
2102
0
    for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2103
0
      tmp_if = (struct interface *)rn->info;
2104
0
      if (!tmp_if)
2105
0
        continue;
2106
0
      zif = tmp_if->info;
2107
0
      if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2108
0
        continue;
2109
0
      if (!if_is_operative(tmp_if))
2110
0
        continue;
2111
2112
0
      if (zif->brslave_info.br_if != in_param->br_if)
2113
0
        continue;
2114
2115
0
      vni_id = zebra_vxlan_if_access_vlan_vni_find(
2116
0
        zif, in_param->br_if);
2117
0
      if (vni_id) {
2118
0
        found = 1;
2119
0
        break;
2120
0
      }
2121
0
    }
2122
0
  }
2123
2124
0
  if (!found)
2125
0
    return NS_WALK_CONTINUE;
2126
2127
0
  *p_zl3vni = zl3vni_lookup(vni_id);
2128
0
  return NS_WALK_STOP;
2129
0
}
2130
2131
/*
2132
 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2133
 * neighbor notifications, to see if they are of interest.
2134
 */
2135
static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
2136
             struct interface *br_if)
2137
0
{
2138
0
  struct zebra_l3vni *zl3vni = NULL;
2139
0
  struct zebra_if *zif = NULL;
2140
0
  struct zebra_from_svi_param in_param = {};
2141
0
  struct zebra_l3vni **p_zl3vni;
2142
2143
0
  if (!br_if)
2144
0
    return NULL;
2145
2146
  /* Make sure the linked interface is a bridge. */
2147
0
  if (!IS_ZEBRA_IF_BRIDGE(br_if))
2148
0
    return NULL;
2149
0
  in_param.br_if = br_if;
2150
2151
  /* Determine if bridge is VLAN-aware or not */
2152
0
  zif = br_if->info;
2153
0
  assert(zif);
2154
0
  in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
2155
0
  if (in_param.bridge_vlan_aware) {
2156
0
    struct zebra_l2info_vlan *vl;
2157
2158
0
    if (!IS_ZEBRA_IF_VLAN(ifp))
2159
0
      return NULL;
2160
2161
0
    zif = ifp->info;
2162
0
    assert(zif);
2163
0
    vl = &zif->l2info.vl;
2164
0
    in_param.vid = vl->vid;
2165
0
  }
2166
2167
  /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2168
  /* TODO: Optimize with a hash. */
2169
2170
0
  p_zl3vni = &zl3vni;
2171
2172
0
  ns_walk_func(zl3vni_from_svi_ns, (void *)&in_param, (void **)p_zl3vni);
2173
0
  return zl3vni;
2174
0
}
2175
2176
vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if)
2177
0
{
2178
0
  vni_t vni = 0;
2179
0
  struct zebra_evpn *zevpn = NULL;
2180
0
  struct zebra_l3vni *zl3vni = NULL;
2181
2182
  /* Check if an L3VNI belongs to this SVI interface.
2183
   * If not, check if an L2VNI belongs to this SVI interface.
2184
   */
2185
0
  zl3vni = zl3vni_from_svi(ifp, br_if);
2186
0
  if (zl3vni)
2187
0
    vni = zl3vni->vni;
2188
0
  else {
2189
0
    zevpn = zebra_evpn_from_svi(ifp, br_if);
2190
0
    if (zevpn)
2191
0
      vni = zevpn->vni;
2192
0
  }
2193
2194
0
  return vni;
2195
0
}
2196
2197
static inline void zl3vni_get_vrr_rmac(struct zebra_l3vni *zl3vni,
2198
               struct ethaddr *rmac)
2199
0
{
2200
0
  if (!zl3vni)
2201
0
    return;
2202
2203
0
  if (!is_l3vni_oper_up(zl3vni))
2204
0
    return;
2205
2206
0
  if (zl3vni->mac_vlan_if && if_is_operative(zl3vni->mac_vlan_if))
2207
0
    memcpy(rmac->octet, zl3vni->mac_vlan_if->hw_addr, ETH_ALEN);
2208
0
}
2209
2210
/*
2211
 * Inform BGP about l3-vni.
2212
 */
2213
static int zl3vni_send_add_to_client(struct zebra_l3vni *zl3vni)
2214
0
{
2215
0
  struct stream *s = NULL;
2216
0
  struct zserv *client = NULL;
2217
0
  struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
2218
0
  struct zebra_vrf *zvrf;
2219
0
  bool is_anycast_mac = true;
2220
2221
0
  client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
2222
  /* BGP may not be running. */
2223
0
  if (!client)
2224
0
    return 0;
2225
2226
0
  zvrf = zebra_vrf_lookup_by_id(zl3vni->vrf_id);
2227
0
  assert(zvrf);
2228
2229
  /* get the svi and vrr rmac values */
2230
0
  memset(&svi_rmac, 0, sizeof(svi_rmac));
2231
0
  zl3vni_get_svi_rmac(zl3vni, &svi_rmac);
2232
0
  zl3vni_get_vrr_rmac(zl3vni, &vrr_rmac);
2233
2234
  /* In absence of vrr mac use svi mac as anycast MAC value */
2235
0
  if (is_zero_mac(&vrr_rmac)) {
2236
0
    memcpy(&vrr_rmac, &svi_rmac, ETH_ALEN);
2237
0
    is_anycast_mac = false;
2238
0
  }
2239
2240
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2241
2242
  /* The message is used for both vni add and/or update like
2243
   * vrr mac is added for l3vni SVI.
2244
   */
2245
0
  zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
2246
0
  stream_putl(s, zl3vni->vni);
2247
0
  stream_put(s, &svi_rmac, sizeof(struct ethaddr));
2248
0
  stream_put_in_addr(s, &zl3vni->local_vtep_ip);
2249
0
  stream_put(s, &zl3vni->filter, sizeof(int));
2250
0
  stream_putl(s, zl3vni->svi_if->ifindex);
2251
0
  stream_put(s, &vrr_rmac, sizeof(struct ethaddr));
2252
0
  stream_putl(s, is_anycast_mac);
2253
2254
  /* Write packet size. */
2255
0
  stream_putw_at(s, 0, stream_get_endp(s));
2256
2257
0
  if (IS_ZEBRA_DEBUG_VXLAN)
2258
0
    zlog_debug(
2259
0
      "Send L3_VNI_ADD %u VRF %s RMAC %pEA VRR %pEA local-ip %pI4 filter %s to %s",
2260
0
      zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2261
0
      &svi_rmac, &vrr_rmac, &zl3vni->local_vtep_ip,
2262
0
      CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
2263
0
        ? "prefix-routes-only"
2264
0
        : "none",
2265
0
      zebra_route_string(client->proto));
2266
2267
0
  client->l3vniadd_cnt++;
2268
0
  return zserv_send_message(client, s);
2269
0
}
2270
2271
/*
2272
 * Inform BGP about local l3-VNI deletion.
2273
 */
2274
static int zl3vni_send_del_to_client(struct zebra_l3vni *zl3vni)
2275
0
{
2276
0
  struct stream *s = NULL;
2277
0
  struct zserv *client = NULL;
2278
2279
0
  client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
2280
  /* BGP may not be running. */
2281
0
  if (!client)
2282
0
    return 0;
2283
2284
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2285
2286
0
  zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
2287
0
  stream_putl(s, zl3vni->vni);
2288
2289
  /* Write packet size. */
2290
0
  stream_putw_at(s, 0, stream_get_endp(s));
2291
2292
0
  if (IS_ZEBRA_DEBUG_VXLAN)
2293
0
    zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
2294
0
         vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2295
0
         zebra_route_string(client->proto));
2296
2297
0
  client->l3vnidel_cnt++;
2298
0
  return zserv_send_message(client, s);
2299
0
}
2300
2301
void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni)
2302
0
{
2303
0
  if (!zl3vni)
2304
0
    return;
2305
2306
  /* send l3vni add to BGP */
2307
0
  zl3vni_send_add_to_client(zl3vni);
2308
0
}
2309
2310
void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni)
2311
0
{
2312
0
  if (!zl3vni)
2313
0
    return;
2314
2315
  /* send l3-vni del to BGP*/
2316
0
  zl3vni_send_del_to_client(zl3vni);
2317
0
}
2318
2319
static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
2320
0
{
2321
0
  struct zebra_evpn *zevpn = (struct zebra_evpn *)bucket->data;
2322
0
  struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)ctxt;
2323
2324
0
  if (zevpn->vrf_id == zl3vni_vrf_id(zl3vni))
2325
0
    listnode_add_sort(zl3vni->l2vnis, zevpn);
2326
0
}
2327
2328
/*
2329
 * Handle transition of vni from l2 to l3 and vice versa.
2330
 * This function handles only the L2VNI add/delete part of
2331
 * the above transition.
2332
 * L3VNI add/delete is handled by the calling functions.
2333
 */
2334
static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
2335
               int add)
2336
0
{
2337
0
  struct zebra_evpn *zevpn = NULL;
2338
0
  struct zebra_l3vni *zl3vni = NULL;
2339
2340
  /* There is a possibility that VNI notification was already received
2341
   * from kernel and we programmed it as L2-VNI
2342
   * In such a case we need to delete this L2-VNI first, so
2343
   * that it can be reprogrammed as L3-VNI in the system. It is also
2344
   * possible that the vrf-vni mapping is removed from FRR while the vxlan
2345
   * interface is still present in kernel. In this case to keep it
2346
   * symmetric, we will delete the l3-vni and reprogram it as l2-vni
2347
   */
2348
0
  if (add) {
2349
    /* Locate hash entry */
2350
0
    zevpn = zebra_evpn_lookup(vni);
2351
0
    if (!zevpn)
2352
0
      return 0;
2353
2354
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2355
0
      zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
2356
2357
    /* Delete EVPN from BGP. */
2358
0
    zebra_evpn_send_del_to_client(zevpn);
2359
2360
0
    zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
2361
0
    zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
2362
2363
    /* Free up all remote VTEPs, if any. */
2364
0
    zebra_evpn_vtep_del_all(zevpn, 1);
2365
2366
0
    zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
2367
0
    if (zl3vni)
2368
0
      listnode_delete(zl3vni->l2vnis, zevpn);
2369
2370
    /* Delete the hash entry. */
2371
0
    if (zebra_evpn_vxlan_del(zevpn)) {
2372
0
      flog_err(EC_ZEBRA_VNI_DEL_FAILED,
2373
0
         "Failed to del EVPN hash %p, VNI %u", zevpn,
2374
0
         zevpn->vni);
2375
0
      return -1;
2376
0
    }
2377
0
  } else {
2378
0
    struct zebra_ns *zns;
2379
0
    struct route_node *rn;
2380
0
    struct interface *ifp;
2381
0
    struct zebra_if *zif;
2382
0
    struct zebra_vxlan_vni *vnip;
2383
0
    struct zebra_l2info_vxlan *vxl;
2384
0
    struct interface *vlan_if;
2385
0
    bool found = false;
2386
2387
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2388
0
      zlog_debug("Adding L2-VNI %u - transition from L3-VNI",
2389
0
           vni);
2390
2391
    /* Find VxLAN interface for this VNI. */
2392
0
    zns = zebra_ns_lookup(NS_DEFAULT);
2393
0
    for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2394
0
      ifp = (struct interface *)rn->info;
2395
0
      if (!ifp)
2396
0
        continue;
2397
0
      zif = ifp->info;
2398
0
      if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2399
0
        continue;
2400
2401
0
      vxl = &zif->l2info.vxl;
2402
0
      vnip = zebra_vxlan_if_vni_find(zif, vni);
2403
0
      if (vnip) {
2404
0
        found = true;
2405
0
        break;
2406
0
      }
2407
0
    }
2408
2409
0
    if (!found) {
2410
0
      if (IS_ZEBRA_DEBUG_VXLAN)
2411
0
        zlog_err(
2412
0
          "Adding L2-VNI - Failed to find VxLAN interface for VNI %u",
2413
0
          vni);
2414
0
      return -1;
2415
0
    }
2416
2417
    /* Create VNI hash entry for L2VNI */
2418
0
    zevpn = zebra_evpn_lookup(vni);
2419
0
    if (zevpn)
2420
0
      return 0;
2421
2422
0
    zevpn = zebra_evpn_add(vni);
2423
2424
    /* Find bridge interface for the VNI */
2425
0
    vlan_if = zvni_map_to_svi(vnip->access_vlan,
2426
0
            zif->brslave_info.br_if);
2427
0
    if (vlan_if) {
2428
0
      zevpn->vrf_id = vlan_if->vrf->vrf_id;
2429
0
      zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
2430
0
      if (zl3vni)
2431
0
        listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
2432
0
    }
2433
2434
0
    zevpn->vxlan_if = ifp;
2435
0
    zevpn->local_vtep_ip = vxl->vtep_ip;
2436
2437
    /* Inform BGP if the VNI is up and mapped to a bridge. */
2438
0
    if (if_is_operative(ifp) && zif->brslave_info.br_if) {
2439
0
      zebra_evpn_send_add_to_client(zevpn);
2440
0
      zebra_evpn_read_mac_neigh(zevpn, ifp);
2441
0
    }
2442
0
  }
2443
2444
0
  return 0;
2445
0
}
2446
2447
/* delete and uninstall rmac hash entry */
2448
static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx)
2449
0
{
2450
0
  struct zebra_mac *zrmac = NULL;
2451
0
  struct zebra_l3vni *zl3vni = NULL;
2452
2453
0
  zrmac = (struct zebra_mac *)bucket->data;
2454
0
  zl3vni = (struct zebra_l3vni *)ctx;
2455
0
  zl3vni_rmac_uninstall(zl3vni, zrmac);
2456
2457
  /* Send RMAC for FPM processing */
2458
0
  hook_call(zebra_rmac_update, zrmac, zl3vni, true, "RMAC deleted");
2459
2460
0
  zl3vni_rmac_del(zl3vni, zrmac);
2461
0
}
2462
2463
/* delete and uninstall nh hash entry */
2464
static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx)
2465
0
{
2466
0
  struct zebra_neigh *n = NULL;
2467
0
  struct zebra_l3vni *zl3vni = NULL;
2468
2469
0
  n = (struct zebra_neigh *)bucket->data;
2470
0
  zl3vni = (struct zebra_l3vni *)ctx;
2471
0
  zl3vni_nh_uninstall(zl3vni, n);
2472
0
  zl3vni_nh_del(zl3vni, n);
2473
0
}
2474
2475
/* re-add remote rmac if needed */
2476
static int zebra_vxlan_readd_remote_rmac(struct zebra_l3vni *zl3vni,
2477
           struct ethaddr *rmac)
2478
0
{
2479
0
  struct zebra_mac *zrmac = NULL;
2480
2481
0
  zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2482
0
  if (!zrmac)
2483
0
    return 0;
2484
2485
0
  if (IS_ZEBRA_DEBUG_VXLAN)
2486
0
    zlog_debug("Del remote RMAC %pEA L3VNI %u - readd",
2487
0
         rmac, zl3vni->vni);
2488
2489
0
  zl3vni_rmac_install(zl3vni, zrmac);
2490
0
  return 0;
2491
0
}
2492
2493
/* Public functions */
2494
2495
int is_l3vni_for_prefix_routes_only(vni_t vni)
2496
0
{
2497
0
  struct zebra_l3vni *zl3vni = NULL;
2498
2499
0
  zl3vni = zl3vni_lookup(vni);
2500
0
  if (!zl3vni)
2501
0
    return 0;
2502
2503
0
  return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
2504
0
}
2505
2506
/* handle evpn route in vrf table */
2507
void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
2508
            const struct ipaddr *vtep_ip,
2509
            const struct prefix *host_prefix)
2510
0
{
2511
0
  struct zebra_l3vni *zl3vni = NULL;
2512
0
  struct ipaddr ipv4_vtep;
2513
2514
0
  zl3vni = zl3vni_from_vrf(vrf_id);
2515
0
  if (!zl3vni || !is_l3vni_oper_up(zl3vni))
2516
0
    return;
2517
2518
  /*
2519
   * add the next hop neighbor -
2520
   * neigh to be installed is the ipv6 nexthop neigh
2521
   */
2522
0
  zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
2523
2524
  /* Add SVD next hop neighbor */
2525
0
  svd_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
2526
2527
  /*
2528
   * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
2529
   * address. Rmac is programmed against the ipv4 vtep because we only
2530
   * support ipv4 tunnels in the h/w right now
2531
   */
2532
0
  memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
2533
0
  ipv4_vtep.ipa_type = IPADDR_V4;
2534
0
  if (vtep_ip->ipa_type == IPADDR_V6)
2535
0
    ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
2536
0
           &(ipv4_vtep.ipaddr_v4));
2537
0
  else
2538
0
    memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
2539
0
           sizeof(struct in_addr));
2540
2541
  /*
2542
   * add the rmac - remote rmac to be installed is against the ipv4
2543
   * nexthop address
2544
   */
2545
0
  zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep);
2546
0
}
2547
2548
/* handle evpn vrf route delete */
2549
void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
2550
            struct ipaddr *vtep_ip,
2551
            struct prefix *host_prefix)
2552
0
{
2553
0
  struct zebra_l3vni *zl3vni = NULL;
2554
0
  struct zebra_neigh *nh = NULL;
2555
0
  struct zebra_mac *zrmac = NULL;
2556
2557
0
  zl3vni = zl3vni_from_vrf(vrf_id);
2558
0
  if (!zl3vni)
2559
0
    return;
2560
2561
  /* find the next hop entry and rmac entry */
2562
0
  nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
2563
0
  if (!nh)
2564
0
    return;
2565
0
  zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
2566
2567
  /* delete the next hop entry */
2568
0
  zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
2569
2570
  /* Delete SVD next hop entry */
2571
0
  svd_remote_nh_del(zl3vni, vtep_ip);
2572
2573
  /* delete the rmac entry */
2574
0
  if (zrmac)
2575
0
    zl3vni_remote_rmac_del(zl3vni, zrmac, vtep_ip);
2576
0
}
2577
2578
void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
2579
             struct ethaddr *rmac, bool use_json)
2580
0
{
2581
0
  struct zebra_l3vni *zl3vni = NULL;
2582
0
  struct zebra_mac *zrmac = NULL;
2583
0
  json_object *json = NULL;
2584
2585
0
  if (use_json)
2586
0
    json = json_object_new_object();
2587
2588
0
  if (!is_evpn_enabled()) {
2589
0
    vty_json(vty, json);
2590
0
    return;
2591
0
  }
2592
2593
0
  zl3vni = zl3vni_lookup(l3vni);
2594
0
  if (!zl3vni) {
2595
0
    if (use_json)
2596
0
      vty_json(vty, json);
2597
0
    else
2598
0
      vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
2599
0
    return;
2600
0
  }
2601
2602
0
  zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2603
0
  if (!zrmac) {
2604
0
    if (use_json)
2605
0
      vty_json(vty, json);
2606
0
    else
2607
0
      vty_out(vty,
2608
0
        "%% Requested RMAC doesn't exist in L3-VNI %u\n",
2609
0
        l3vni);
2610
0
    return;
2611
0
  }
2612
2613
0
  zl3vni_print_rmac(zrmac, vty, json);
2614
2615
0
  if (use_json)
2616
0
    vty_json(vty, json);
2617
0
}
2618
2619
void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2620
0
{
2621
0
  struct zebra_l3vni *zl3vni;
2622
0
  uint32_t num_rmacs;
2623
0
  struct rmac_walk_ctx wctx;
2624
0
  json_object *json = NULL;
2625
2626
0
  if (use_json)
2627
0
    json = json_object_new_object();
2628
2629
0
  if (!is_evpn_enabled()) {
2630
0
    vty_json(vty, json);
2631
0
    return;
2632
0
  }
2633
2634
0
  zl3vni = zl3vni_lookup(l3vni);
2635
0
  if (!zl3vni) {
2636
0
    if (use_json)
2637
0
      vty_json(vty, json);
2638
0
    else
2639
0
      vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2640
0
    return;
2641
0
  }
2642
0
  num_rmacs = hashcount(zl3vni->rmac_table);
2643
0
  if (!num_rmacs)
2644
0
    return;
2645
2646
0
  memset(&wctx, 0, sizeof(wctx));
2647
0
  wctx.vty = vty;
2648
0
  wctx.json = json;
2649
0
  if (!use_json) {
2650
0
    vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
2651
0
      num_rmacs);
2652
0
    vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
2653
0
  } else
2654
0
    json_object_int_add(json, "numRmacs", num_rmacs);
2655
2656
0
  hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
2657
2658
0
  if (use_json)
2659
0
    vty_json(vty, json);
2660
0
}
2661
2662
void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
2663
0
{
2664
0
  json_object *json = NULL;
2665
0
  void *args[2];
2666
2667
0
  if (use_json)
2668
0
    json = json_object_new_object();
2669
2670
0
  if (!is_evpn_enabled()) {
2671
0
    vty_json(vty, json);
2672
0
    return;
2673
0
  }
2674
2675
0
  args[0] = vty;
2676
0
  args[1] = json;
2677
0
  hash_iterate(zrouter.l3vni_table,
2678
0
         (void (*)(struct hash_bucket *,
2679
0
             void *))zl3vni_print_rmac_hash_all_vni,
2680
0
         args);
2681
2682
0
  if (use_json)
2683
0
    vty_json(vty, json);
2684
0
}
2685
2686
void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
2687
           struct ipaddr *ip, bool use_json)
2688
0
{
2689
0
  struct zebra_l3vni *zl3vni = NULL;
2690
0
  struct zebra_neigh *n = NULL;
2691
0
  json_object *json = NULL;
2692
2693
0
  if (use_json)
2694
0
    json = json_object_new_object();
2695
2696
0
  if (!is_evpn_enabled()) {
2697
0
    vty_json(vty, json);
2698
0
    return;
2699
0
  }
2700
2701
  /* If vni=0 passed, assume svd lookup */
2702
0
  if (!l3vni)
2703
0
    n = svd_nh_lookup(ip);
2704
0
  else {
2705
0
    zl3vni = zl3vni_lookup(l3vni);
2706
0
    if (!zl3vni) {
2707
0
      if (use_json)
2708
0
        vty_out(vty, "{}\n");
2709
0
      else
2710
0
        vty_out(vty, "%% L3-VNI %u does not exist\n",
2711
0
          l3vni);
2712
0
      return;
2713
0
    }
2714
2715
0
    n = zl3vni_nh_lookup(zl3vni, ip);
2716
0
  }
2717
2718
0
  if (!n) {
2719
0
    if (use_json)
2720
0
      vty_out(vty, "{}\n");
2721
0
    else
2722
0
      vty_out(vty,
2723
0
        "%% Requested next-hop not present for L3-VNI %u\n",
2724
0
        l3vni);
2725
0
    return;
2726
0
  }
2727
2728
0
  zl3vni_print_nh(n, vty, json);
2729
2730
0
  if (use_json)
2731
0
    vty_json(vty, json);
2732
0
}
2733
2734
static void l3vni_print_nh_table(struct hash *nh_table, struct vty *vty,
2735
         bool use_json)
2736
0
{
2737
0
  uint32_t num_nh;
2738
0
  struct nh_walk_ctx wctx;
2739
0
  json_object *json = NULL;
2740
2741
0
  num_nh = hashcount(nh_table);
2742
0
  if (!num_nh)
2743
0
    return;
2744
2745
0
  if (use_json)
2746
0
    json = json_object_new_object();
2747
2748
0
  wctx.vty = vty;
2749
0
  wctx.json = json;
2750
0
  if (!use_json) {
2751
0
    vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
2752
0
      num_nh);
2753
0
    vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
2754
0
  } else
2755
0
    json_object_int_add(json, "numNextHops", num_nh);
2756
2757
0
  hash_iterate(nh_table, zl3vni_print_nh_hash, &wctx);
2758
2759
0
  if (use_json)
2760
0
    vty_json(vty, json);
2761
0
}
2762
2763
void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2764
0
{
2765
0
  struct zebra_l3vni *zl3vni = NULL;
2766
2767
0
  if (!is_evpn_enabled()) {
2768
0
    if (use_json)
2769
0
      vty_out(vty, "{}\n");
2770
0
    return;
2771
0
  }
2772
2773
0
  zl3vni = zl3vni_lookup(l3vni);
2774
0
  if (!zl3vni) {
2775
0
    if (use_json)
2776
0
      vty_out(vty, "{}\n");
2777
0
    else
2778
0
      vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2779
0
    return;
2780
0
  }
2781
2782
0
  l3vni_print_nh_table(zl3vni->nh_table, vty, use_json);
2783
0
}
2784
2785
void zebra_vxlan_print_nh_svd(struct vty *vty, bool use_json)
2786
0
{
2787
0
  if (!is_evpn_enabled()) {
2788
0
    if (use_json)
2789
0
      vty_out(vty, "{}\n");
2790
0
    return;
2791
0
  }
2792
2793
0
  l3vni_print_nh_table(svd_nh_table, vty, use_json);
2794
0
}
2795
2796
void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
2797
0
{
2798
0
  json_object *json = NULL;
2799
0
  void *args[2];
2800
2801
0
  if (use_json)
2802
0
    json = json_object_new_object();
2803
2804
0
  if (!is_evpn_enabled()) {
2805
0
    vty_json(vty, json);
2806
0
    return;
2807
0
  }
2808
2809
0
  args[0] = vty;
2810
0
  args[1] = json;
2811
0
  hash_iterate(zrouter.l3vni_table,
2812
0
         (void (*)(struct hash_bucket *,
2813
0
             void *))zl3vni_print_nh_hash_all_vni,
2814
0
         args);
2815
2816
0
  if (use_json)
2817
0
    vty_json(vty, json);
2818
0
}
2819
2820
/*
2821
 * Display L3 VNI information (VTY command handler).
2822
 */
2823
void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
2824
0
{
2825
0
  void *args[2];
2826
0
  json_object *json = NULL;
2827
0
  struct zebra_l3vni *zl3vni = NULL;
2828
2829
0
  if (use_json)
2830
0
    json = json_object_new_object();
2831
2832
0
  if (!is_evpn_enabled()) {
2833
0
    vty_json(vty, json);
2834
0
    return;
2835
0
  }
2836
2837
0
  zl3vni = zl3vni_lookup(vni);
2838
0
  if (!zl3vni) {
2839
0
    if (use_json)
2840
0
      vty_json(vty, json);
2841
0
    else
2842
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
2843
0
    return;
2844
0
  }
2845
2846
0
  args[0] = vty;
2847
0
  args[1] = json;
2848
0
  zl3vni_print(zl3vni, (void *)args);
2849
2850
0
  if (use_json)
2851
0
    vty_json(vty, json);
2852
0
}
2853
2854
void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
2855
             json_object *json_vrfs)
2856
0
{
2857
0
  char buf[ETHER_ADDR_STRLEN];
2858
0
  struct zebra_l3vni *zl3vni = NULL;
2859
2860
0
  zl3vni = zl3vni_lookup(zvrf->l3vni);
2861
0
  if (!zl3vni)
2862
0
    return;
2863
2864
0
  if (!json_vrfs) {
2865
0
    vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
2866
0
      zvrf_name(zvrf), zl3vni->vni,
2867
0
      zl3vni_vxlan_if_name(zl3vni),
2868
0
      zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
2869
0
      zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2870
0
  } else {
2871
0
    json_object *json_vrf = NULL;
2872
2873
0
    json_vrf = json_object_new_object();
2874
0
    json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
2875
0
    json_object_int_add(json_vrf, "vni", zl3vni->vni);
2876
0
    json_object_string_add(json_vrf, "vxlanIntf",
2877
0
               zl3vni_vxlan_if_name(zl3vni));
2878
0
    json_object_string_add(json_vrf, "sviIntf",
2879
0
               zl3vni_svi_if_name(zl3vni));
2880
0
    json_object_string_add(json_vrf, "state",
2881
0
               zl3vni_state2str(zl3vni));
2882
0
    json_object_string_add(
2883
0
      json_vrf, "routerMac",
2884
0
      zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2885
0
    json_object_array_add(json_vrfs, json_vrf);
2886
0
  }
2887
0
}
2888
2889
/*
2890
 * Display Neighbors for a VNI (VTY command handler).
2891
 */
2892
void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
2893
         vni_t vni, bool use_json)
2894
0
{
2895
0
  struct zebra_evpn *zevpn;
2896
0
  uint32_t num_neigh;
2897
0
  struct neigh_walk_ctx wctx;
2898
0
  json_object *json = NULL;
2899
2900
0
  if (use_json)
2901
0
    json = json_object_new_object();
2902
2903
0
  if (!is_evpn_enabled()) {
2904
0
    vty_json(vty, json);
2905
0
    return;
2906
0
  }
2907
2908
0
  zevpn = zebra_evpn_lookup(vni);
2909
0
  if (!zevpn) {
2910
0
    if (use_json)
2911
0
      vty_json(vty, json);
2912
0
    else
2913
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
2914
0
    return;
2915
0
  }
2916
0
  num_neigh = hashcount(zevpn->neigh_table);
2917
0
  if (!num_neigh)
2918
0
    return;
2919
2920
  /* Since we have IPv6 addresses to deal with which can vary widely in
2921
   * size, we try to be a bit more elegant in display by first computing
2922
   * the maximum width.
2923
   */
2924
0
  memset(&wctx, 0, sizeof(wctx));
2925
0
  wctx.zevpn = zevpn;
2926
0
  wctx.vty = vty;
2927
0
  wctx.addr_width = 15;
2928
0
  wctx.json = json;
2929
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2930
0
         &wctx);
2931
2932
0
  if (!use_json) {
2933
0
    vty_out(vty,
2934
0
      "Number of ARPs (local and remote) known for this VNI: %u\n",
2935
0
      num_neigh);
2936
0
    zebra_evpn_print_neigh_hdr(vty, &wctx);
2937
0
  } else
2938
0
    json_object_int_add(json, "numArpNd", num_neigh);
2939
2940
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
2941
0
  if (use_json)
2942
0
    vty_json(vty, json);
2943
0
}
2944
2945
/*
2946
 * Display neighbors across all VNIs (VTY command handler).
2947
 */
2948
void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2949
             bool print_dup, bool use_json)
2950
0
{
2951
0
  json_object *json = NULL;
2952
0
  void *args[3];
2953
2954
0
  if (use_json)
2955
0
    json = json_object_new_object();
2956
2957
0
  if (!is_evpn_enabled()) {
2958
0
    vty_json(vty, json);
2959
0
    return;
2960
0
  }
2961
2962
0
  args[0] = vty;
2963
0
  args[1] = json;
2964
0
  args[2] = (void *)(ptrdiff_t)print_dup;
2965
2966
0
  hash_iterate(zvrf->evpn_table,
2967
0
         (void (*)(struct hash_bucket *,
2968
0
             void *))zevpn_print_neigh_hash_all_evpn,
2969
0
         args);
2970
0
  if (use_json)
2971
0
    vty_json(vty, json);
2972
0
}
2973
2974
/*
2975
 * Display neighbors across all VNIs in detail(VTY command handler).
2976
 */
2977
void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
2978
              struct zebra_vrf *zvrf,
2979
              bool print_dup, bool use_json)
2980
0
{
2981
0
  json_object *json = NULL;
2982
0
  void *args[3];
2983
2984
0
  if (use_json)
2985
0
    json = json_object_new_object();
2986
2987
0
  if (!is_evpn_enabled()) {
2988
0
    vty_json(vty, json);
2989
0
    return;
2990
0
  }
2991
2992
0
  args[0] = vty;
2993
0
  args[1] = json;
2994
0
  args[2] = (void *)(ptrdiff_t)print_dup;
2995
2996
0
  hash_iterate(zvrf->evpn_table,
2997
0
         (void (*)(struct hash_bucket *,
2998
0
             void *))zevpn_print_neigh_hash_all_evpn_detail,
2999
0
         args);
3000
0
  if (use_json)
3001
0
    vty_json(vty, json);
3002
0
}
3003
3004
/*
3005
 * Display specific neighbor for a VNI, if present (VTY command handler).
3006
 */
3007
void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
3008
            struct zebra_vrf *zvrf, vni_t vni,
3009
            struct ipaddr *ip, bool use_json)
3010
0
{
3011
0
  struct zebra_evpn *zevpn;
3012
0
  struct zebra_neigh *n;
3013
0
  json_object *json = NULL;
3014
3015
0
  if (use_json)
3016
0
    json = json_object_new_object();
3017
3018
0
  if (!is_evpn_enabled()) {
3019
0
    vty_json(vty, json);
3020
0
    return;
3021
0
  }
3022
3023
0
  zevpn = zebra_evpn_lookup(vni);
3024
0
  if (!zevpn) {
3025
0
    if (use_json)
3026
0
      vty_json(vty, json);
3027
0
    else
3028
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3029
0
    return;
3030
0
  }
3031
0
  n = zebra_evpn_neigh_lookup(zevpn, ip);
3032
0
  if (!n) {
3033
0
    if (!use_json)
3034
0
      vty_out(vty,
3035
0
        "%% Requested neighbor does not exist in VNI %u\n",
3036
0
        vni);
3037
0
    return;
3038
0
  }
3039
3040
0
  zebra_evpn_print_neigh(n, vty, json);
3041
3042
0
  if (use_json)
3043
0
    vty_json(vty, json);
3044
0
}
3045
3046
/*
3047
 * Display neighbors for a VNI from specific VTEP (VTY command handler).
3048
 * By definition, these are remote neighbors.
3049
 */
3050
void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
3051
              vni_t vni, struct in_addr vtep_ip,
3052
              bool use_json)
3053
0
{
3054
0
  struct zebra_evpn *zevpn;
3055
0
  uint32_t num_neigh;
3056
0
  struct neigh_walk_ctx wctx;
3057
0
  json_object *json = NULL;
3058
3059
0
  if (use_json)
3060
0
    json = json_object_new_object();
3061
3062
0
  if (!is_evpn_enabled()) {
3063
0
    vty_json(vty, json);
3064
0
    return;
3065
0
  }
3066
3067
0
  zevpn = zebra_evpn_lookup(vni);
3068
0
  if (!zevpn) {
3069
0
    if (use_json)
3070
0
      vty_json(vty, json);
3071
0
    else
3072
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3073
0
    return;
3074
0
  }
3075
0
  num_neigh = hashcount(zevpn->neigh_table);
3076
0
  if (!num_neigh)
3077
0
    return;
3078
3079
0
  memset(&wctx, 0, sizeof(wctx));
3080
0
  wctx.zevpn = zevpn;
3081
0
  wctx.vty = vty;
3082
0
  wctx.addr_width = 15;
3083
0
  wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
3084
0
  wctx.r_vtep_ip = vtep_ip;
3085
0
  wctx.json = json;
3086
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
3087
0
         &wctx);
3088
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
3089
3090
0
  if (use_json)
3091
0
    vty_json(vty, json);
3092
0
}
3093
3094
/*
3095
 * Display Duplicate detected Neighbors for a VNI
3096
 * (VTY command handler).
3097
 */
3098
void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
3099
             struct zebra_vrf *zvrf,
3100
             vni_t vni,
3101
             bool use_json)
3102
0
{
3103
0
  struct zebra_evpn *zevpn;
3104
0
  uint32_t num_neigh;
3105
0
  struct neigh_walk_ctx wctx;
3106
0
  json_object *json = NULL;
3107
3108
0
  if (use_json)
3109
0
    json = json_object_new_object();
3110
3111
0
  if (!is_evpn_enabled()) {
3112
0
    vty_json(vty, json);
3113
0
    return;
3114
0
  }
3115
3116
0
  zevpn = zebra_evpn_lookup(vni);
3117
0
  if (!zevpn) {
3118
0
    if (use_json)
3119
0
      vty_json(vty, json);
3120
0
    else
3121
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3122
0
    return;
3123
0
  }
3124
3125
0
  num_neigh = hashcount(zevpn->neigh_table);
3126
0
  if (!num_neigh)
3127
0
    return;
3128
3129
0
  num_neigh = num_dup_detected_neighs(zevpn);
3130
0
  if (!num_neigh)
3131
0
    return;
3132
3133
  /* Since we have IPv6 addresses to deal with which can vary widely in
3134
   * size, we try to be a bit more elegant in display by first computing
3135
   * the maximum width.
3136
   */
3137
0
  memset(&wctx, 0, sizeof(wctx));
3138
0
  wctx.zevpn = zevpn;
3139
0
  wctx.vty = vty;
3140
0
  wctx.addr_width = 15;
3141
0
  wctx.json = json;
3142
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
3143
0
         &wctx);
3144
3145
0
  if (!use_json) {
3146
0
    vty_out(vty,
3147
0
      "Number of ARPs (local and remote) known for this VNI: %u\n",
3148
0
      num_neigh);
3149
0
    vty_out(vty, "%*s %-6s %-8s %-17s %-30s\n",
3150
0
      -wctx.addr_width, "IP", "Type",
3151
0
      "State", "MAC", "Remote ES/VTEP");
3152
0
  } else
3153
0
    json_object_int_add(json, "numArpNd", num_neigh);
3154
3155
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_print_dad_neigh_hash,
3156
0
         &wctx);
3157
3158
0
  if (use_json)
3159
0
    vty_json(vty, json);
3160
0
}
3161
3162
/*
3163
 * Display MACs for a VNI (VTY command handler).
3164
 */
3165
void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
3166
        vni_t vni, bool use_json, bool detail)
3167
0
{
3168
0
  struct zebra_evpn *zevpn;
3169
0
  uint32_t num_macs;
3170
0
  struct mac_walk_ctx wctx;
3171
0
  json_object *json = NULL;
3172
0
  json_object *json_mac = NULL;
3173
3174
0
  if (!is_evpn_enabled()) {
3175
0
    if (use_json)
3176
0
      vty_out(vty, "{}\n");
3177
0
    return;
3178
0
  }
3179
3180
0
  zevpn = zebra_evpn_lookup(vni);
3181
0
  if (!zevpn) {
3182
0
    if (use_json)
3183
0
      vty_out(vty, "{}\n");
3184
0
    else
3185
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3186
0
    return;
3187
0
  }
3188
0
  num_macs = num_valid_macs(zevpn);
3189
0
  if (!num_macs)
3190
0
    return;
3191
3192
0
  if (use_json) {
3193
0
    json = json_object_new_object();
3194
0
    json_mac = json_object_new_object();
3195
0
  }
3196
3197
0
  memset(&wctx, 0, sizeof(wctx));
3198
0
  wctx.zevpn = zevpn;
3199
0
  wctx.vty = vty;
3200
0
  wctx.json = json_mac;
3201
3202
0
  if (!use_json) {
3203
0
    if (detail) {
3204
0
      vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
3205
0
        zevpn->vni, num_macs);
3206
0
    } else {
3207
0
      vty_out(vty,
3208
0
        "Number of MACs (local and remote) known for this VNI: %u\n",
3209
0
        num_macs);
3210
0
      vty_out(vty,
3211
0
        "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
3212
0
      vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
3213
0
        "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN",
3214
0
        "Seq #'s");
3215
0
    }
3216
0
  } else
3217
0
    json_object_int_add(json, "numMacs", num_macs);
3218
3219
0
  if (detail)
3220
0
    hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
3221
0
           &wctx);
3222
0
  else
3223
0
    hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash,
3224
0
           &wctx);
3225
3226
0
  if (use_json) {
3227
0
    json_object_object_add(json, "macs", json_mac);
3228
0
    vty_json(vty, json);
3229
0
  }
3230
0
}
3231
3232
/*
3233
 * Display MACs for all VNIs (VTY command handler).
3234
 */
3235
void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
3236
            bool print_dup, bool use_json)
3237
0
{
3238
0
  struct mac_walk_ctx wctx;
3239
0
  json_object *json = NULL;
3240
3241
0
  if (use_json)
3242
0
    json = json_object_new_object();
3243
3244
0
  if (!is_evpn_enabled()) {
3245
0
    vty_json(vty, json);
3246
0
    return;
3247
0
  }
3248
3249
0
  memset(&wctx, 0, sizeof(wctx));
3250
0
  wctx.vty = vty;
3251
0
  wctx.json = json;
3252
0
  wctx.print_dup = print_dup;
3253
0
  hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
3254
3255
0
  if (use_json)
3256
0
    vty_json(vty, json);
3257
0
}
3258
3259
/*
3260
 * Display MACs in detail for all VNIs (VTY command handler).
3261
 */
3262
void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
3263
             struct zebra_vrf *zvrf,
3264
             bool print_dup, bool use_json)
3265
0
{
3266
0
  struct mac_walk_ctx wctx;
3267
0
  json_object *json = NULL;
3268
3269
0
  if (use_json)
3270
0
    json = json_object_new_object();
3271
3272
0
  if (!is_evpn_enabled()) {
3273
0
    vty_json(vty, json);
3274
0
    return;
3275
0
  }
3276
3277
0
  memset(&wctx, 0, sizeof(wctx));
3278
0
  wctx.vty = vty;
3279
0
  wctx.json = json;
3280
0
  wctx.print_dup = print_dup;
3281
0
  hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn_detail,
3282
0
         &wctx);
3283
3284
0
  if (use_json)
3285
0
    vty_json(vty, json);
3286
0
}
3287
3288
/*
3289
 * Display MACs for all VNIs (VTY command handler).
3290
 */
3291
void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
3292
           struct zebra_vrf *zvrf,
3293
           struct in_addr vtep_ip, bool use_json)
3294
0
{
3295
0
  struct mac_walk_ctx wctx;
3296
0
  json_object *json = NULL;
3297
3298
0
  if (use_json)
3299
0
    json = json_object_new_object();
3300
3301
0
  if (!is_evpn_enabled()) {
3302
0
    vty_json(vty, json);
3303
0
    return;
3304
0
  }
3305
3306
0
  memset(&wctx, 0, sizeof(wctx));
3307
0
  wctx.vty = vty;
3308
0
  wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3309
0
  wctx.r_vtep_ip = vtep_ip;
3310
0
  wctx.json = json;
3311
0
  hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
3312
3313
0
  if (use_json)
3314
0
    vty_json(vty, json);
3315
0
}
3316
3317
/*
3318
 * Display specific MAC for a VNI, if present (VTY command handler).
3319
 */
3320
void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
3321
          vni_t vni, struct ethaddr *macaddr,
3322
          bool use_json)
3323
0
{
3324
0
  struct zebra_evpn *zevpn;
3325
0
  struct zebra_mac *mac;
3326
0
  json_object *json = NULL;
3327
3328
0
  if (use_json)
3329
0
    json = json_object_new_object();
3330
3331
0
  if (!is_evpn_enabled()) {
3332
0
    vty_json(vty, json);
3333
0
    return;
3334
0
  }
3335
3336
0
  zevpn = zebra_evpn_lookup(vni);
3337
0
  if (!zevpn) {
3338
0
    if (use_json)
3339
0
      vty_json(vty, json);
3340
0
    else
3341
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3342
0
    return;
3343
0
  }
3344
0
  mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3345
0
  if (!mac) {
3346
0
    if (use_json)
3347
0
      vty_json(vty, json);
3348
0
    else
3349
0
      vty_out(vty,
3350
0
        "%% Requested MAC does not exist in VNI %u\n",
3351
0
        vni);
3352
0
    return;
3353
0
  }
3354
3355
0
  zebra_evpn_print_mac(mac, vty, json);
3356
3357
0
  if (use_json)
3358
0
    vty_json(vty, json);
3359
0
}
3360
3361
/* Print Duplicate MACs per VNI */
3362
void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
3363
            struct zebra_vrf *zvrf,
3364
            vni_t vni, bool use_json)
3365
0
{
3366
0
  struct zebra_evpn *zevpn;
3367
0
  struct mac_walk_ctx wctx;
3368
0
  uint32_t num_macs;
3369
0
  json_object *json = NULL;
3370
0
  json_object *json_mac = NULL;
3371
3372
0
  if (!is_evpn_enabled())
3373
0
    return;
3374
3375
0
  zevpn = zebra_evpn_lookup(vni);
3376
0
  if (!zevpn) {
3377
0
    vty_out(vty, "%% VNI %u does not exist\n", vni);
3378
0
    return;
3379
0
  }
3380
3381
0
  num_macs = num_valid_macs(zevpn);
3382
0
  if (!num_macs)
3383
0
    return;
3384
3385
0
  num_macs = num_dup_detected_macs(zevpn);
3386
0
  if (!num_macs)
3387
0
    return;
3388
3389
0
  if (use_json) {
3390
0
    json = json_object_new_object();
3391
0
    json_mac = json_object_new_object();
3392
0
  }
3393
3394
0
  memset(&wctx, 0, sizeof(wctx));
3395
0
  wctx.zevpn = zevpn;
3396
0
  wctx.vty = vty;
3397
0
  wctx.json = json_mac;
3398
3399
0
  if (!use_json) {
3400
0
    vty_out(vty,
3401
0
    "Number of MACs (local and remote) known for this VNI: %u\n",
3402
0
      num_macs);
3403
0
    vty_out(vty, "%-17s %-6s %-5s %-30s %-5s\n", "MAC", "Type",
3404
0
      "Flags", "Intf/Remote ES/VTEP", "VLAN");
3405
0
  } else
3406
0
    json_object_int_add(json, "numMacs", num_macs);
3407
3408
0
  hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash, &wctx);
3409
3410
0
  if (use_json) {
3411
0
    json_object_object_add(json, "macs", json_mac);
3412
0
    vty_json(vty, json);
3413
0
  }
3414
3415
0
}
3416
3417
int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
3418
           struct ethaddr *macaddr, char *errmsg,
3419
           size_t errmsg_len)
3420
0
{
3421
0
  struct zebra_evpn *zevpn;
3422
0
  struct zebra_mac *mac;
3423
0
  struct listnode *node = NULL;
3424
0
  struct zebra_neigh *nbr = NULL;
3425
3426
0
  if (!is_evpn_enabled())
3427
0
    return 0;
3428
3429
0
  zevpn = zebra_evpn_lookup(vni);
3430
0
  if (!zevpn) {
3431
0
    snprintfrr(errmsg, errmsg_len, "VNI %u does not exist", vni);
3432
0
    return -1;
3433
0
  }
3434
3435
0
  mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3436
0
  if (!mac) {
3437
0
    snprintf(errmsg, errmsg_len,
3438
0
       "Requested MAC does not exist in VNI %u\n", vni);
3439
0
    return -1;
3440
0
  }
3441
3442
0
  if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3443
0
    snprintfrr(errmsg, errmsg_len,
3444
0
         "Requested MAC is not duplicate detected\n");
3445
0
    return -1;
3446
0
  }
3447
3448
  /* Remove all IPs as duplicate associcated with this MAC */
3449
0
  for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3450
    /* For local neigh mark inactive so MACIP update is generated
3451
     * to BGP. This is a scenario where MAC update received
3452
     * and detected as duplicate which marked neigh as duplicate.
3453
     * Later local neigh update did not get a chance to relay
3454
     * to BGP. Similarly remote macip update, neigh needs to be
3455
     * installed locally.
3456
     */
3457
0
    if (zvrf->dad_freeze &&
3458
0
        CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3459
0
      if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
3460
0
        ZEBRA_NEIGH_SET_INACTIVE(nbr);
3461
0
      else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
3462
0
        zebra_evpn_rem_neigh_install(
3463
0
          zevpn, nbr, false /*was_static*/);
3464
0
    }
3465
3466
0
    UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3467
0
    nbr->dad_count = 0;
3468
0
    nbr->detect_start_time.tv_sec = 0;
3469
0
    nbr->dad_dup_detect_time = 0;
3470
0
  }
3471
3472
0
  UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3473
0
  mac->dad_count = 0;
3474
0
  mac->detect_start_time.tv_sec = 0;
3475
0
  mac->detect_start_time.tv_usec = 0;
3476
0
  mac->dad_dup_detect_time = 0;
3477
0
  EVENT_OFF(mac->dad_mac_auto_recovery_timer);
3478
3479
  /* warn-only action return */
3480
0
  if (!zvrf->dad_freeze)
3481
0
    return 0;
3482
3483
  /* Local: Notify Peer VTEPs, Remote: Install the entry */
3484
0
  if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3485
    /* Inform to BGP */
3486
0
    if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3487
0
                  mac->flags, mac->loc_seq,
3488
0
                  mac->es))
3489
0
      return 0;
3490
3491
    /* Process all neighbors associated with this MAC. */
3492
0
    zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3493
0
                   0 /*es_change*/);
3494
3495
0
  } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3496
0
    zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3497
3498
    /* Install the entry. */
3499
0
    zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3500
0
  }
3501
3502
0
  return 0;
3503
0
}
3504
3505
int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
3506
          struct ipaddr *ip, char *errmsg,
3507
          size_t errmsg_len)
3508
0
{
3509
0
  struct zebra_evpn *zevpn;
3510
0
  struct zebra_neigh *nbr;
3511
0
  struct zebra_mac *mac;
3512
0
  char buf[INET6_ADDRSTRLEN];
3513
0
  char buf2[ETHER_ADDR_STRLEN];
3514
3515
0
  if (!is_evpn_enabled())
3516
0
    return 0;
3517
3518
0
  zevpn = zebra_evpn_lookup(vni);
3519
0
  if (!zevpn) {
3520
0
    snprintfrr(errmsg, errmsg_len, "VNI %u does not exist\n", vni);
3521
0
    return -1;
3522
0
  }
3523
3524
0
  nbr = zebra_evpn_neigh_lookup(zevpn, ip);
3525
0
  if (!nbr) {
3526
0
    snprintfrr(errmsg, errmsg_len,
3527
0
         "Requested host IP does not exist in VNI %u\n", vni);
3528
0
    return -1;
3529
0
  }
3530
3531
0
  ipaddr2str(&nbr->ip, buf, sizeof(buf));
3532
3533
0
  if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3534
0
    snprintfrr(errmsg, errmsg_len,
3535
0
         "Requested host IP %s is not duplicate detected\n",
3536
0
         buf);
3537
0
    return -1;
3538
0
  }
3539
3540
0
  mac = zebra_evpn_mac_lookup(zevpn, &nbr->emac);
3541
3542
0
  if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3543
0
    snprintfrr(
3544
0
      errmsg, errmsg_len,
3545
0
      "Requested IP's associated MAC %s is still in duplicate state\n",
3546
0
      prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
3547
0
    return -1;
3548
0
  }
3549
3550
0
  if (IS_ZEBRA_DEBUG_VXLAN)
3551
0
    zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
3552
0
         __func__, buf, nbr->flags, nbr->loc_seq);
3553
3554
0
  UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3555
0
  nbr->dad_count = 0;
3556
0
  nbr->detect_start_time.tv_sec = 0;
3557
0
  nbr->detect_start_time.tv_usec = 0;
3558
0
  nbr->dad_dup_detect_time = 0;
3559
0
  EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
3560
3561
0
  if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
3562
0
    zebra_evpn_neigh_send_add_to_client(zevpn->vni, ip, &nbr->emac,
3563
0
                nbr->mac, nbr->flags,
3564
0
                nbr->loc_seq);
3565
0
  } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
3566
0
    zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
3567
0
  }
3568
3569
0
  return 0;
3570
0
}
3571
3572
static void zevpn_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt)
3573
0
{
3574
0
  struct mac_walk_ctx *wctx = ctxt;
3575
0
  struct zebra_mac *mac;
3576
0
  struct zebra_evpn *zevpn;
3577
0
  struct listnode *node = NULL;
3578
0
  struct zebra_neigh *nbr = NULL;
3579
3580
0
  mac = (struct zebra_mac *)bucket->data;
3581
0
  if (!mac)
3582
0
    return;
3583
3584
0
  zevpn = wctx->zevpn;
3585
3586
0
  if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
3587
0
    return;
3588
3589
0
  UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3590
0
  mac->dad_count = 0;
3591
0
  mac->detect_start_time.tv_sec = 0;
3592
0
  mac->detect_start_time.tv_usec = 0;
3593
0
  mac->dad_dup_detect_time = 0;
3594
0
  EVENT_OFF(mac->dad_mac_auto_recovery_timer);
3595
3596
  /* Remove all IPs as duplicate associcated with this MAC */
3597
0
  for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3598
0
    if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
3599
0
        && nbr->dad_count)
3600
0
      ZEBRA_NEIGH_SET_INACTIVE(nbr);
3601
3602
0
    UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3603
0
    nbr->dad_count = 0;
3604
0
    nbr->detect_start_time.tv_sec = 0;
3605
0
    nbr->dad_dup_detect_time = 0;
3606
0
  }
3607
3608
  /* Local: Notify Peer VTEPs, Remote: Install the entry */
3609
0
  if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3610
    /* Inform to BGP */
3611
0
    if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3612
0
                  mac->flags, mac->loc_seq,
3613
0
                  mac->es))
3614
0
      return;
3615
3616
    /* Process all neighbors associated with this MAC. */
3617
0
    zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3618
0
                   0 /*es_change*/);
3619
3620
0
  } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3621
0
    zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3622
3623
    /* Install the entry. */
3624
0
    zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3625
0
  }
3626
0
}
3627
3628
static void zevpn_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket,
3629
              void **args)
3630
0
{
3631
0
  struct zebra_evpn *zevpn;
3632
0
  struct zebra_vrf *zvrf;
3633
0
  struct mac_walk_ctx m_wctx;
3634
0
  struct neigh_walk_ctx n_wctx;
3635
3636
0
  zevpn = (struct zebra_evpn *)bucket->data;
3637
0
  if (!zevpn)
3638
0
    return;
3639
3640
0
  zvrf = (struct zebra_vrf *)args[0];
3641
3642
0
  if (hashcount(zevpn->neigh_table)) {
3643
0
    memset(&n_wctx, 0, sizeof(n_wctx));
3644
0
    n_wctx.zevpn = zevpn;
3645
0
    n_wctx.zvrf = zvrf;
3646
0
    hash_iterate(zevpn->neigh_table,
3647
0
           zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3648
0
  }
3649
3650
0
  if (num_valid_macs(zevpn)) {
3651
0
    memset(&m_wctx, 0, sizeof(m_wctx));
3652
0
    m_wctx.zevpn = zevpn;
3653
0
    m_wctx.zvrf = zvrf;
3654
0
    hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3655
0
  }
3656
3657
0
}
3658
3659
int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf)
3660
0
{
3661
0
  void *args[1];
3662
3663
0
  if (!is_evpn_enabled())
3664
0
    return 0;
3665
3666
0
  args[0] = zvrf;
3667
3668
0
  hash_iterate(zvrf->evpn_table,
3669
0
         (void (*)(struct hash_bucket *, void *))
3670
0
         zevpn_clear_dup_detect_hash_vni_all, args);
3671
3672
0
  return 0;
3673
0
}
3674
3675
int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni)
3676
0
{
3677
0
  struct zebra_evpn *zevpn;
3678
0
  struct mac_walk_ctx m_wctx;
3679
0
  struct neigh_walk_ctx n_wctx;
3680
3681
0
  if (!is_evpn_enabled())
3682
0
    return 0;
3683
3684
0
  zevpn = zebra_evpn_lookup(vni);
3685
0
  if (!zevpn) {
3686
0
    zlog_warn("VNI %u does not exist", vni);
3687
0
    return CMD_WARNING;
3688
0
  }
3689
3690
0
  if (hashcount(zevpn->neigh_table)) {
3691
0
    memset(&n_wctx, 0, sizeof(n_wctx));
3692
0
    n_wctx.zevpn = zevpn;
3693
0
    n_wctx.zvrf = zvrf;
3694
0
    hash_iterate(zevpn->neigh_table,
3695
0
           zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3696
0
  }
3697
3698
0
  if (num_valid_macs(zevpn)) {
3699
0
    memset(&m_wctx, 0, sizeof(m_wctx));
3700
0
    m_wctx.zevpn = zevpn;
3701
0
    m_wctx.zvrf = zvrf;
3702
0
    hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3703
0
  }
3704
3705
0
  return 0;
3706
0
}
3707
3708
/*
3709
 * Display MACs for a VNI from specific VTEP (VTY command handler).
3710
 */
3711
void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
3712
             vni_t vni, struct in_addr vtep_ip,
3713
             bool use_json)
3714
0
{
3715
0
  struct zebra_evpn *zevpn;
3716
0
  uint32_t num_macs;
3717
0
  struct mac_walk_ctx wctx;
3718
0
  json_object *json = NULL;
3719
0
  json_object *json_mac = NULL;
3720
3721
0
  if (!is_evpn_enabled()) {
3722
0
    vty_json(vty, json);
3723
0
    return;
3724
0
  }
3725
3726
0
  zevpn = zebra_evpn_lookup(vni);
3727
0
  if (!zevpn) {
3728
0
    if (use_json)
3729
0
      vty_out(vty, "{}\n");
3730
0
    else
3731
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3732
0
    return;
3733
0
  }
3734
0
  num_macs = num_valid_macs(zevpn);
3735
0
  if (!num_macs)
3736
0
    return;
3737
3738
0
  if (use_json) {
3739
0
    json = json_object_new_object();
3740
0
    json_mac = json_object_new_object();
3741
0
  }
3742
3743
0
  memset(&wctx, 0, sizeof(wctx));
3744
0
  wctx.zevpn = zevpn;
3745
0
  wctx.vty = vty;
3746
0
  wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3747
0
  wctx.r_vtep_ip = vtep_ip;
3748
0
  wctx.json = json_mac;
3749
0
  hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, &wctx);
3750
3751
0
  if (use_json) {
3752
0
    json_object_int_add(json, "numMacs", wctx.count);
3753
0
    if (wctx.count)
3754
0
      json_object_object_add(json, "macs", json_mac);
3755
0
    vty_json(vty, json);
3756
0
  }
3757
0
}
3758
3759
3760
/*
3761
 * Display VNI information (VTY command handler).
3762
 *
3763
 * use_json flag indicates that output should be in JSON format.
3764
 * json_array is non NULL when JSON output needs to be aggregated (by the
3765
 * caller) and then printed, otherwise, JSON evpn vni info is printed
3766
 * right away.
3767
 */
3768
void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
3769
         bool use_json, json_object *json_array)
3770
0
{
3771
0
  json_object *json = NULL;
3772
0
  void *args[2];
3773
0
  struct zebra_l3vni *zl3vni = NULL;
3774
0
  struct zebra_evpn *zevpn = NULL;
3775
3776
0
  if (use_json)
3777
0
    json = json_object_new_object();
3778
3779
0
  if (!is_evpn_enabled()) {
3780
0
    vty_json(vty, json);
3781
0
    return;
3782
0
  }
3783
3784
0
  args[0] = vty;
3785
0
  args[1] = json;
3786
3787
0
  zl3vni = zl3vni_lookup(vni);
3788
0
  if (zl3vni) {
3789
0
    zl3vni_print(zl3vni, (void *)args);
3790
0
  } else {
3791
0
    zevpn = zebra_evpn_lookup(vni);
3792
0
    if (zevpn)
3793
0
      zebra_evpn_print(zevpn, (void *)args);
3794
0
    else if (!json)
3795
0
      vty_out(vty, "%% VNI %u does not exist\n", vni);
3796
0
  }
3797
3798
0
  if (use_json) {
3799
    /*
3800
     * Each "json" object contains info about 1 VNI.
3801
     * When "json_array" is non-null, we aggreggate the json output
3802
     * into json_array and print it as a JSON array.
3803
     */
3804
0
    if (json_array)
3805
0
      json_object_array_add(json_array, json);
3806
0
    else
3807
0
      vty_json(vty, json);
3808
0
  }
3809
0
}
3810
3811
/* Display all global details for EVPN */
3812
void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
3813
0
{
3814
0
  int num_l2vnis = 0;
3815
0
  int num_l3vnis = 0;
3816
0
  int num_vnis = 0;
3817
0
  json_object *json = NULL;
3818
0
  struct zebra_vrf *zvrf = NULL;
3819
3820
0
  if (uj)
3821
0
    json = json_object_new_object();
3822
3823
0
  if (!is_evpn_enabled()) {
3824
0
    vty_json(vty, json);
3825
0
    return;
3826
0
  }
3827
3828
0
  zvrf = zebra_vrf_get_evpn();
3829
3830
0
  num_l3vnis = hashcount(zrouter.l3vni_table);
3831
0
  num_l2vnis = hashcount(zvrf->evpn_table);
3832
0
  num_vnis = num_l2vnis + num_l3vnis;
3833
3834
0
  if (uj) {
3835
0
    json_object_string_add(json, "advertiseGatewayMacip",
3836
0
               zvrf->advertise_gw_macip ? "Yes" : "No");
3837
0
    json_object_string_add(json, "advertiseSviMacip",
3838
0
               zvrf->advertise_svi_macip ? "Yes"
3839
0
                 : "No");
3840
0
    json_object_string_add(json, "advertiseSviMac",
3841
0
               zebra_evpn_mh_do_adv_svi_mac() ? "Yes"
3842
0
                      : "No");
3843
0
    json_object_int_add(json, "numVnis", num_vnis);
3844
0
    json_object_int_add(json, "numL2Vnis", num_l2vnis);
3845
0
    json_object_int_add(json, "numL3Vnis", num_l3vnis);
3846
0
    if (zebra_evpn_do_dup_addr_detect(zvrf))
3847
0
      json_object_boolean_true_add(json,
3848
0
            "isDuplicateAddrDetection");
3849
0
    else
3850
0
      json_object_boolean_false_add(json,
3851
0
            "isDuplicateAddrDetection");
3852
0
    json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
3853
0
    json_object_int_add(json, "detectionTime", zvrf->dad_time);
3854
0
    json_object_int_add(json, "detectionFreezeTime",
3855
0
            zvrf->dad_freeze_time);
3856
0
    json_object_boolean_add(json, "isDetectionFreeze",
3857
0
          zvrf->dad_freeze);
3858
0
    zebra_evpn_mh_json(json);
3859
0
  } else {
3860
0
    vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
3861
0
    vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
3862
0
    vty_out(vty, "Advertise gateway mac-ip: %s\n",
3863
0
      zvrf->advertise_gw_macip ? "Yes" : "No");
3864
0
    vty_out(vty, "Advertise svi mac-ip: %s\n",
3865
0
      zvrf->advertise_svi_macip ? "Yes" : "No");
3866
0
    vty_out(vty, "Advertise svi mac: %s\n",
3867
0
      zebra_evpn_mh_do_adv_svi_mac() ? "Yes" : "No");
3868
0
    vty_out(vty, "Duplicate address detection: %s\n",
3869
0
      zebra_evpn_do_dup_addr_detect(zvrf) ? "Enable"
3870
0
                  : "Disable");
3871
0
    vty_out(vty, "  Detection max-moves %u, time %d\n",
3872
0
      zvrf->dad_max_moves, zvrf->dad_time);
3873
0
    if (zvrf->dad_freeze) {
3874
0
      if (zvrf->dad_freeze_time)
3875
0
        vty_out(vty, "  Detection freeze %u\n",
3876
0
          zvrf->dad_freeze_time);
3877
0
      else
3878
0
        vty_out(vty, "  Detection freeze %s\n",
3879
0
          "permanent");
3880
0
    }
3881
0
    zebra_evpn_mh_print(vty);
3882
0
  }
3883
3884
0
  if (uj)
3885
0
    vty_json(vty, json);
3886
0
}
3887
3888
/*
3889
 * Display VNI hash table (VTY command handler).
3890
 */
3891
void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
3892
          bool use_json)
3893
0
{
3894
0
  json_object *json = NULL;
3895
0
  void *args[2];
3896
3897
0
  if (use_json)
3898
0
    json = json_object_new_object();
3899
3900
0
  if (!is_evpn_enabled()) {
3901
0
    vty_json(vty, json);
3902
0
    return;
3903
0
  }
3904
3905
0
  if (!use_json)
3906
0
    vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
3907
0
      "Type", "VxLAN IF", "# MACs", "# ARPs",
3908
0
      "# Remote VTEPs", "Tenant VRF");
3909
3910
0
  args[0] = vty;
3911
0
  args[1] = json;
3912
3913
  /* Display all L2-VNIs */
3914
0
  hash_iterate(
3915
0
    zvrf->evpn_table,
3916
0
    (void (*)(struct hash_bucket *, void *))zebra_evpn_print_hash,
3917
0
    args);
3918
3919
  /* Display all L3-VNIs */
3920
0
  hash_iterate(zrouter.l3vni_table,
3921
0
         (void (*)(struct hash_bucket *, void *))zl3vni_print_hash,
3922
0
         args);
3923
3924
0
  if (use_json)
3925
0
    vty_json(vty, json);
3926
0
}
3927
3928
void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
3929
0
{
3930
0
  struct stream *s;
3931
0
  int time = 0;
3932
0
  uint32_t max_moves = 0;
3933
0
  uint32_t freeze_time = 0;
3934
0
  bool dup_addr_detect = false;
3935
0
  bool freeze = false;
3936
0
  bool old_addr_detect;
3937
3938
0
  s = msg;
3939
0
  STREAM_GETL(s, dup_addr_detect);
3940
0
  STREAM_GETL(s, time);
3941
0
  STREAM_GETL(s, max_moves);
3942
0
  STREAM_GETL(s, freeze);
3943
0
  STREAM_GETL(s, freeze_time);
3944
3945
0
  old_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3946
0
  zvrf->dup_addr_detect = dup_addr_detect;
3947
0
  dup_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3948
3949
  /* DAD previous state was enabled, and new state is disable,
3950
   * clear all duplicate detected addresses.
3951
   */
3952
0
  if (old_addr_detect && !dup_addr_detect)
3953
0
    zebra_vxlan_clear_dup_detect_vni_all(zvrf);
3954
3955
0
  zvrf->dad_time = time;
3956
0
  zvrf->dad_max_moves = max_moves;
3957
0
  zvrf->dad_freeze = freeze;
3958
0
  zvrf->dad_freeze_time = freeze_time;
3959
3960
0
  if (IS_ZEBRA_DEBUG_VXLAN)
3961
0
    zlog_debug(
3962
0
      "VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
3963
0
      vrf_id_to_name(zvrf->vrf->vrf_id),
3964
0
      dup_addr_detect ? "enable" : "disable",
3965
0
      zvrf->dad_max_moves, zvrf->dad_time,
3966
0
      zvrf->dad_freeze ? "enable" : "disable",
3967
0
      zvrf->dad_freeze_time);
3968
3969
0
stream_failure:
3970
0
  return;
3971
0
}
3972
3973
/*
3974
 * Display VNI hash table in detail(VTY command handler).
3975
 */
3976
void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
3977
           bool use_json)
3978
0
{
3979
0
  json_object *json_array = NULL;
3980
0
  struct zebra_ns *zns = NULL;
3981
0
  struct zebra_evpn_show zes;
3982
3983
0
  if (!is_evpn_enabled()) {
3984
0
    if (use_json)
3985
0
      vty_out(vty, "{}\n");
3986
0
    return;
3987
0
  }
3988
3989
0
  zns = zebra_ns_lookup(NS_DEFAULT);
3990
0
  if (!zns)
3991
0
    return;
3992
3993
0
  if (use_json)
3994
0
    json_array = json_object_new_array();
3995
3996
0
  zes.vty = vty;
3997
0
  zes.json = json_array;
3998
0
  zes.zvrf = zvrf;
3999
0
  zes.use_json = use_json;
4000
4001
  /* Display all L2-VNIs */
4002
0
  hash_iterate(zvrf->evpn_table,
4003
0
         (void (*)(struct hash_bucket *,
4004
0
             void *))zebra_evpn_print_hash_detail,
4005
0
         &zes);
4006
4007
  /* Display all L3-VNIs */
4008
0
  hash_iterate(zrouter.l3vni_table,
4009
0
         (void (*)(struct hash_bucket *,
4010
0
             void *))zl3vni_print_hash_detail,
4011
0
         &zes);
4012
4013
0
  if (use_json)
4014
0
    vty_json(vty, json_array);
4015
0
}
4016
4017
/*
4018
 * Handle neighbor delete notification from the kernel (on a VLAN device
4019
 * / L3 interface). This may result in either the neighbor getting deleted
4020
 * from our database or being re-added to the kernel (if it is a valid
4021
 * remote neighbor).
4022
 */
4023
int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
4024
          struct interface *link_if,
4025
          struct ipaddr *ip)
4026
0
{
4027
0
  struct zebra_evpn *zevpn = NULL;
4028
0
  struct zebra_l3vni *zl3vni = NULL;
4029
4030
  /* check if this is a remote neigh entry corresponding to remote
4031
   * next-hop
4032
   */
4033
0
  zl3vni = zl3vni_from_svi(ifp, link_if);
4034
0
  if (zl3vni)
4035
0
    return zl3vni_local_nh_del(zl3vni, ip);
4036
4037
  /* We are only interested in neighbors on an SVI that resides on top
4038
   * of a VxLAN bridge.
4039
   */
4040
0
  zevpn = zebra_evpn_from_svi(ifp, link_if);
4041
0
  if (!zevpn) {
4042
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4043
0
      zlog_debug(
4044
0
        "%s: Del neighbor %pIA EVPN is not present for interface %s",
4045
0
        __func__, ip, ifp->name);
4046
0
    return 0;
4047
0
  }
4048
4049
0
  if (!zevpn->vxlan_if) {
4050
0
    zlog_debug(
4051
0
      "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4052
0
      zevpn->vni, zevpn);
4053
0
    return -1;
4054
0
  }
4055
4056
0
  if (IS_ZEBRA_DEBUG_VXLAN)
4057
0
    zlog_debug("Del neighbor %pIA intf %s(%u) -> L2-VNI %u",
4058
0
         ip, ifp->name, ifp->ifindex, zevpn->vni);
4059
4060
0
  return zebra_evpn_neigh_del_ip(zevpn, ip);
4061
0
}
4062
4063
/*
4064
 * Handle neighbor add or update notification from the kernel (on a VLAN
4065
 * device / L3 interface). This is typically for a local neighbor but can
4066
 * also be for a remote neighbor (e.g., ageout notification). It could
4067
 * also be a "move" scenario.
4068
 */
4069
int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
4070
             struct interface *link_if,
4071
             struct ipaddr *ip,
4072
             struct ethaddr *macaddr,
4073
             uint16_t state,
4074
             bool is_ext,
4075
             bool is_router,
4076
             bool local_inactive, bool dp_static)
4077
0
{
4078
0
  struct zebra_evpn *zevpn = NULL;
4079
0
  struct zebra_l3vni *zl3vni = NULL;
4080
4081
  /* check if this is a remote neigh entry corresponding to remote
4082
   * next-hop
4083
   */
4084
0
  zl3vni = zl3vni_from_svi(ifp, link_if);
4085
0
  if (zl3vni)
4086
0
    return zl3vni_local_nh_add_update(zl3vni, ip, state);
4087
4088
  /* We are only interested in neighbors on an SVI that resides on top
4089
   * of a VxLAN bridge.
4090
   */
4091
0
  zevpn = zebra_evpn_from_svi(ifp, link_if);
4092
0
  if (!zevpn)
4093
0
    return 0;
4094
4095
0
  if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
4096
0
    zlog_debug(
4097
0
      "Add/Update neighbor %pIA MAC %pEA intf %s(%u) state 0x%x %s%s%s%s-> L2-VNI %u",
4098
0
      ip, macaddr, ifp->name,
4099
0
      ifp->ifindex, state, is_ext ? "ext-learned " : "",
4100
0
      is_router ? "router " : "",
4101
0
      local_inactive ? "local_inactive " : "",
4102
0
      dp_static ? "peer_sync " : "", zevpn->vni);
4103
4104
  /* Is this about a local neighbor or a remote one? */
4105
0
  if (!is_ext)
4106
0
    return zebra_evpn_local_neigh_update(zevpn, ifp, ip, macaddr,
4107
0
                 is_router, local_inactive,
4108
0
                 dp_static);
4109
4110
0
  return zebra_evpn_remote_neigh_update(zevpn, ifp, ip, macaddr, state);
4111
0
}
4112
4113
static int32_t
4114
zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
4115
        struct ethaddr *macaddr, uint16_t *ipa_len,
4116
        struct ipaddr *ip, struct in_addr *vtep_ip,
4117
        uint8_t *flags, uint32_t *seq, esi_t *esi)
4118
2
{
4119
2
  uint16_t l = 0;
4120
4121
  /*
4122
   * Obtain each remote MACIP and process.
4123
   * Message contains VNI, followed by MAC followed by IP (if any)
4124
   * followed by remote VTEP IP.
4125
   */
4126
2
  memset(ip, 0, sizeof(*ip));
4127
2
  STREAM_GETL(s, *vni);
4128
2
  STREAM_GET(macaddr->octet, s, ETH_ALEN);
4129
2
  STREAM_GETW(s, *ipa_len);
4130
4131
2
  if (*ipa_len) {
4132
2
    if (*ipa_len == IPV4_MAX_BYTELEN)
4133
0
      ip->ipa_type = IPADDR_V4;
4134
2
    else if (*ipa_len == IPV6_MAX_BYTELEN)
4135
0
      ip->ipa_type = IPADDR_V6;
4136
2
    else {
4137
2
      if (IS_ZEBRA_DEBUG_VXLAN)
4138
0
        zlog_debug(
4139
2
          "ipa_len *must* be %d or %d bytes in length not %d",
4140
2
          IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
4141
2
          *ipa_len);
4142
2
      goto stream_failure;
4143
2
    }
4144
4145
0
    STREAM_GET(&ip->ip.addr, s, *ipa_len);
4146
0
  }
4147
0
  l += 4 + ETH_ALEN + 4 + *ipa_len;
4148
0
  STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
4149
0
  l += IPV4_MAX_BYTELEN;
4150
4151
0
  if (add) {
4152
0
    STREAM_GETC(s, *flags);
4153
0
    STREAM_GETL(s, *seq);
4154
0
    l += 5;
4155
0
    STREAM_GET(esi, s, sizeof(esi_t));
4156
0
    l += sizeof(esi_t);
4157
0
  }
4158
4159
0
  return l;
4160
4161
2
stream_failure:
4162
2
  return -1;
4163
0
}
4164
4165
/*
4166
 * Handle message from client to delete a remote MACIP for a VNI.
4167
 */
4168
void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
4169
2
{
4170
2
  struct stream *s;
4171
2
  vni_t vni;
4172
2
  struct ethaddr macaddr;
4173
2
  struct ipaddr ip;
4174
2
  struct in_addr vtep_ip;
4175
2
  uint16_t l = 0, ipa_len;
4176
2
  char buf1[INET6_ADDRSTRLEN];
4177
4178
2
  s = msg;
4179
4180
2
  while (l < hdr->length) {
4181
2
    int res_length = zebra_vxlan_remote_macip_helper(
4182
2
      false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
4183
2
      NULL, NULL);
4184
4185
2
    if (res_length == -1)
4186
2
      goto stream_failure;
4187
4188
0
    l += res_length;
4189
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4190
0
      zlog_debug(
4191
0
        "Recv MACIP DEL VNI %u MAC %pEA%s%s Remote VTEP %pI4 from %s",
4192
0
        vni, &macaddr,
4193
0
        ipa_len ? " IP " : "",
4194
0
        ipa_len ?
4195
0
        ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
4196
0
        &vtep_ip, zebra_route_string(client->proto));
4197
4198
    /* Enqueue to workqueue for processing */
4199
0
    zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
4200
0
  }
4201
4202
2
stream_failure:
4203
2
  return;
4204
2
}
4205
4206
/*
4207
 * Handle message from client to add a remote MACIP for a VNI. This
4208
 * could be just the add of a MAC address or the add of a neighbor
4209
 * (IP+MAC).
4210
 */
4211
void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
4212
0
{
4213
0
  struct stream *s;
4214
0
  vni_t vni;
4215
0
  struct ethaddr macaddr;
4216
0
  struct ipaddr ip;
4217
0
  struct in_addr vtep_ip;
4218
0
  uint16_t l = 0, ipa_len;
4219
0
  uint8_t flags = 0;
4220
0
  uint32_t seq;
4221
0
  char buf1[INET6_ADDRSTRLEN];
4222
0
  esi_t esi;
4223
0
  char esi_buf[ESI_STR_LEN];
4224
4225
0
  if (!EVPN_ENABLED(zvrf)) {
4226
0
    zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
4227
0
    return;
4228
0
  }
4229
4230
0
  s = msg;
4231
4232
0
  while (l < hdr->length) {
4233
4234
0
    int res_length = zebra_vxlan_remote_macip_helper(
4235
0
      true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
4236
0
      &flags, &seq, &esi);
4237
4238
0
    if (res_length == -1)
4239
0
      goto stream_failure;
4240
4241
0
    l += res_length;
4242
0
    if (IS_ZEBRA_DEBUG_VXLAN) {
4243
0
      if (memcmp(&esi, zero_esi, sizeof(esi_t)))
4244
0
        esi_to_str(&esi, esi_buf, sizeof(esi_buf));
4245
0
      else
4246
0
        strlcpy(esi_buf, "-", ESI_STR_LEN);
4247
0
      zlog_debug(
4248
0
        "Recv %sMACIP ADD VNI %u MAC %pEA%s%s flags 0x%x seq %u VTEP %pI4 ESI %s from %s",
4249
0
        (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ?
4250
0
        "sync-" : "",
4251
0
        vni, &macaddr,
4252
0
        ipa_len ? " IP " : "",
4253
0
        ipa_len ?
4254
0
        ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
4255
0
        flags, seq, &vtep_ip, esi_buf,
4256
0
        zebra_route_string(client->proto));
4257
0
    }
4258
4259
    /* Enqueue to workqueue for processing */
4260
0
    zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags,
4261
0
               seq, vtep_ip, &esi);
4262
0
  }
4263
4264
0
stream_failure:
4265
0
  return;
4266
0
}
4267
4268
/*
4269
 * Handle remote vtep delete by kernel; re-add the vtep if we have it
4270
 */
4271
int zebra_vxlan_check_readd_vtep(struct interface *ifp, vni_t vni,
4272
         struct in_addr vtep_ip)
4273
0
{
4274
0
  struct zebra_if *zif;
4275
0
  struct zebra_vrf *zvrf = NULL;
4276
0
  struct zebra_evpn *zevpn = NULL;
4277
0
  struct zebra_vtep *zvtep = NULL;
4278
0
  struct zebra_vxlan_vni *vnip;
4279
4280
0
  zif = ifp->info;
4281
0
  assert(zif);
4282
4283
  /* If EVPN is not enabled, nothing to do. */
4284
0
  if (!is_evpn_enabled())
4285
0
    return 0;
4286
4287
  /* Locate VRF corresponding to interface. */
4288
0
  zvrf = ifp->vrf->info;
4289
0
  if (!zvrf)
4290
0
    return -1;
4291
4292
0
  vnip = zebra_vxlan_if_vni_find(zif, vni);
4293
0
  if (!vnip)
4294
0
    return 0;
4295
4296
  /* Locate hash entry; it is expected to exist. */
4297
0
  zevpn = zebra_evpn_lookup(vni);
4298
0
  if (!zevpn)
4299
0
    return 0;
4300
4301
  /* If the remote vtep entry doesn't exists nothing to do */
4302
0
  zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4303
0
  if (!zvtep)
4304
0
    return 0;
4305
4306
0
  if (IS_ZEBRA_DEBUG_VXLAN)
4307
0
    zlog_debug(
4308
0
      "Del MAC for remote VTEP %pI4 intf %s(%u) VNI %u - readd",
4309
0
      &vtep_ip, ifp->name, ifp->ifindex, vni);
4310
4311
0
  zebra_evpn_vtep_install(zevpn, zvtep);
4312
0
  return 0;
4313
0
}
4314
4315
/*
4316
 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
4317
 * us, this must involve a multihoming scenario. Treat this as implicit delete
4318
 * of any prior local MAC.
4319
 */
4320
static int zebra_vxlan_check_del_local_mac(struct interface *ifp,
4321
             struct interface *br_if,
4322
             struct ethaddr *macaddr,
4323
             vlanid_t vid, vni_t vni)
4324
0
{
4325
0
  struct zebra_if *zif;
4326
0
  struct zebra_evpn *zevpn;
4327
0
  struct zebra_mac *mac;
4328
4329
0
  zif = ifp->info;
4330
0
  assert(zif);
4331
4332
  /* Check if EVPN is enabled. */
4333
0
  if (!is_evpn_enabled())
4334
0
    return 0;
4335
4336
  /* Locate hash entry; it is expected to exist. */
4337
0
  zevpn = zebra_evpn_lookup(vni);
4338
0
  if (!zevpn)
4339
0
    return 0;
4340
4341
  /* If entry doesn't exist, nothing to do. */
4342
0
  mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4343
0
  if (!mac)
4344
0
    return 0;
4345
4346
  /* Is it a local entry? */
4347
0
  if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4348
0
    return 0;
4349
4350
0
  if (IS_ZEBRA_DEBUG_VXLAN)
4351
0
    zlog_debug(
4352
0
      "Add/update remote MAC %pEA intf %s(%u) VNI %u flags 0x%x - del local",
4353
0
      macaddr, ifp->name, ifp->ifindex, vni, mac->flags);
4354
4355
  /* Remove MAC from BGP. */
4356
0
  zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, mac->flags,
4357
0
            false /* force */);
4358
4359
  /*
4360
   * If there are no neigh associated with the mac delete the mac
4361
   * else mark it as AUTO for forward reference
4362
   */
4363
0
  if (!listcount(mac->neigh_list)) {
4364
0
    zebra_evpn_mac_del(zevpn, mac);
4365
0
  } else {
4366
0
    zebra_evpn_mac_clear_fwd_info(mac);
4367
0
    UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
4368
0
    UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
4369
0
    SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
4370
0
  }
4371
4372
0
  return 0;
4373
0
}
4374
4375
/* MAC notification from the dataplane with a network dest port -
4376
 * 1. This can be a local MAC on a down ES (if fast-failover is not possible
4377
 * 2. Or it can be a remote MAC
4378
 */
4379
int zebra_vxlan_dp_network_mac_add(struct interface *ifp,
4380
           struct interface *br_if,
4381
           struct ethaddr *macaddr, vlanid_t vid,
4382
           vni_t vni, uint32_t nhg_id, bool sticky,
4383
           bool dp_static)
4384
0
{
4385
0
  struct zebra_evpn_es *es;
4386
0
  struct interface *acc_ifp;
4387
4388
  /* If netlink message is with vid, it will have no nexthop.
4389
   * So skip it.
4390
   */
4391
0
  if (vid) {
4392
0
    if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4393
0
      zlog_debug("dpAdd MAC %pEA VID %u - ignore as no nhid",
4394
0
           macaddr, vid);
4395
0
    return 0;
4396
0
  }
4397
4398
  /* Get vxlan's vid for netlink message has no it. */
4399
0
  vid = ((struct zebra_if *)ifp->info)
4400
0
          ->l2info.vxl.vni_info.vni.access_vlan;
4401
4402
  /* if remote mac delete the local entry */
4403
0
  if (!nhg_id || !zebra_evpn_nhg_is_local_es(nhg_id, &es)
4404
0
      || !zebra_evpn_es_local_mac_via_network_port(es)) {
4405
0
    if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4406
0
      zlog_debug("dpAdd remote MAC %pEA VID %u", macaddr,
4407
0
           vid);
4408
0
    return zebra_vxlan_check_del_local_mac(ifp, br_if, macaddr, vid,
4409
0
                   vni);
4410
0
  }
4411
4412
  /* If local MAC on a down local ES translate the network-mac-add
4413
   * to a local-active-mac-add
4414
   */
4415
0
  if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4416
0
    zlog_debug("dpAdd local-nw-MAC %pEA VID %u", macaddr, vid);
4417
0
  acc_ifp = es->zif->ifp;
4418
0
  return zebra_vxlan_local_mac_add_update(
4419
0
    acc_ifp, br_if, macaddr, vid, sticky,
4420
0
    false /* local_inactive */, dp_static);
4421
0
}
4422
4423
/*
4424
 * Handle network MAC delete by kernel -
4425
 * 1. readd the remote MAC if we have it
4426
 * 2. local MAC with does ES may also need to be re-installed
4427
 */
4428
int zebra_vxlan_dp_network_mac_del(struct interface *ifp,
4429
           struct interface *br_if,
4430
           struct ethaddr *macaddr, vlanid_t vid,
4431
           vni_t vni)
4432
0
{
4433
0
  struct zebra_if *zif = NULL;
4434
0
  struct zebra_evpn *zevpn = NULL;
4435
0
  struct zebra_l3vni *zl3vni = NULL;
4436
0
  struct zebra_mac *mac = NULL;
4437
4438
0
  zif = ifp->info;
4439
0
  assert(zif);
4440
4441
  /* Check if EVPN is enabled. */
4442
0
  if (!is_evpn_enabled())
4443
0
    return 0;
4444
4445
  /* check if this is a remote RMAC and readd simillar to remote macs */
4446
0
  zl3vni = zl3vni_lookup(vni);
4447
0
  if (zl3vni)
4448
0
    return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
4449
4450
  /* Locate hash entry; it is expected to exist. */
4451
0
  zevpn = zebra_evpn_lookup(vni);
4452
0
  if (!zevpn)
4453
0
    return 0;
4454
4455
  /* If entry doesn't exist, nothing to do. */
4456
0
  mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4457
0
  if (!mac)
4458
0
    return 0;
4459
4460
0
  if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
4461
    /* If remote entry simply re-install */
4462
0
    if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4463
0
      zlog_debug(
4464
0
        "dpDel remote MAC %pEA intf %s(%u) VNI %u - readd",
4465
0
        macaddr, ifp->name, ifp->ifindex, vni);
4466
0
    zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
4467
0
  } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) && mac->es
4468
0
       && zebra_evpn_es_local_mac_via_network_port(mac->es)) {
4469
    /* If local entry via nw-port call local-del which will
4470
     * re-install entry in the dataplane is needed
4471
     */
4472
0
    if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4473
0
      zlog_debug("dpDel local-nw-MAC %pEA VNI %u", macaddr,
4474
0
           vni);
4475
4476
0
    zebra_evpn_del_local_mac(zevpn, mac, false);
4477
0
  }
4478
4479
0
  return 0;
4480
0
}
4481
4482
/*
4483
 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
4484
 */
4485
int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
4486
            struct ethaddr *macaddr, vlanid_t vid)
4487
0
{
4488
0
  struct zebra_evpn *zevpn;
4489
0
  struct zebra_mac *mac;
4490
4491
  /* We are interested in MACs only on ports or (port, VLAN) that
4492
   * map to a VNI.
4493
   */
4494
0
  zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4495
0
  if (!zevpn)
4496
0
    return 0;
4497
0
  if (!zevpn->vxlan_if) {
4498
0
    zlog_debug(
4499
0
      "VNI %u hash %p doesn't have intf upon local MAC DEL",
4500
0
      zevpn->vni, zevpn);
4501
0
    return -1;
4502
0
  }
4503
4504
  /* If entry doesn't exist, nothing to do. */
4505
0
  mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4506
0
  if (!mac)
4507
0
    return 0;
4508
4509
  /* Is it a local entry? */
4510
0
  if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4511
0
    return 0;
4512
4513
0
  return zebra_evpn_del_local_mac(zevpn, mac, false);
4514
0
}
4515
4516
/*
4517
 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
4518
 */
4519
int zebra_vxlan_local_mac_add_update(struct interface *ifp,
4520
             struct interface *br_if,
4521
             struct ethaddr *macaddr, vlanid_t vid,
4522
           bool sticky, bool local_inactive,
4523
           bool dp_static)
4524
0
{
4525
0
  struct zebra_evpn *zevpn;
4526
0
  struct zebra_vrf *zvrf;
4527
4528
0
  assert(ifp);
4529
4530
  /* We are interested in MACs only on ports or (port, VLAN) that
4531
   * map to an EVPN.
4532
   */
4533
0
  zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4534
0
  if (!zevpn) {
4535
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4536
0
      zlog_debug(
4537
0
        "        Add/Update %sMAC %pEA intf %s(%u) VID %u, could not find EVPN",
4538
0
        sticky ? "sticky " : "", macaddr,
4539
0
        ifp->name, ifp->ifindex, vid);
4540
0
    return 0;
4541
0
  }
4542
4543
0
  if (!zevpn->vxlan_if) {
4544
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4545
0
      zlog_debug(
4546
0
        "        VNI %u hash %p doesn't have intf upon local MAC ADD",
4547
0
        zevpn->vni, zevpn);
4548
0
    return -1;
4549
0
  }
4550
4551
0
  zvrf = zebra_vrf_get_evpn();
4552
0
  return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid,
4553
0
                 sticky, local_inactive,
4554
0
                 dp_static, NULL);
4555
0
}
4556
4557
/*
4558
 * Handle message from client to delete a remote VTEP for an EVPN.
4559
 */
4560
void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS)
4561
0
{
4562
0
  struct stream *s;
4563
0
  unsigned short l = 0;
4564
0
  vni_t vni;
4565
0
  struct in_addr vtep_ip;
4566
4567
0
  if (!is_evpn_enabled()) {
4568
0
    zlog_debug(
4569
0
      "%s: EVPN is not enabled yet we have received a VTEP DEL msg",
4570
0
      __func__);
4571
0
    return;
4572
0
  }
4573
4574
0
  if (!EVPN_ENABLED(zvrf)) {
4575
0
    zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u",
4576
0
         zvrf_id(zvrf));
4577
0
    return;
4578
0
  }
4579
4580
0
  s = msg;
4581
4582
0
  while (l < hdr->length) {
4583
0
    int flood_control __attribute__((unused));
4584
4585
    /* Obtain each remote VTEP and process. */
4586
0
    STREAM_GETL(s, vni);
4587
0
    l += 4;
4588
0
    STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4589
0
    l += IPV4_MAX_BYTELEN;
4590
4591
    /* Flood control is intentionally ignored right now */
4592
0
    STREAM_GETL(s, flood_control);
4593
0
    l += 4;
4594
4595
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4596
0
      zlog_debug("Recv VTEP DEL %pI4 VNI %u from %s",
4597
0
           &vtep_ip, vni,
4598
0
           zebra_route_string(client->proto));
4599
4600
    /* Enqueue for processing */
4601
0
    zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip);
4602
0
  }
4603
4604
0
stream_failure:
4605
0
  return;
4606
0
}
4607
4608
/*
4609
 * Handle message from client to delete a remote VTEP for an EVPN.
4610
 */
4611
void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni,
4612
         struct in_addr vtep_ip)
4613
0
{
4614
0
  struct zebra_evpn *zevpn;
4615
0
  struct zebra_vtep *zvtep;
4616
0
  struct interface *ifp;
4617
0
  struct zebra_if *zif;
4618
0
  struct zebra_vrf *zvrf;
4619
4620
0
  if (!is_evpn_enabled()) {
4621
0
    zlog_debug("%s: Can't process vtep del: EVPN is not enabled",
4622
0
         __func__);
4623
0
    return;
4624
0
  }
4625
4626
0
  zvrf = zebra_vrf_lookup_by_id(vrf_id);
4627
0
  if (!zvrf)
4628
0
    return;
4629
4630
0
  if (!EVPN_ENABLED(zvrf)) {
4631
0
    zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u",
4632
0
         zvrf_id(zvrf));
4633
0
    return;
4634
0
  }
4635
4636
  /* Locate VNI hash entry - expected to exist. */
4637
0
  zevpn = zebra_evpn_lookup(vni);
4638
0
  if (!zevpn) {
4639
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4640
0
      zlog_debug(
4641
0
        "Failed to locate VNI hash for remote VTEP DEL, VNI %u",
4642
0
        vni);
4643
0
    return;
4644
0
  }
4645
4646
0
  ifp = zevpn->vxlan_if;
4647
0
  if (!ifp) {
4648
0
    zlog_debug(
4649
0
      "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
4650
0
      zevpn->vni, zevpn);
4651
0
    return;
4652
0
  }
4653
0
  zif = ifp->info;
4654
4655
  /* If down or not mapped to a bridge, we're done. */
4656
0
  if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4657
0
    return;
4658
4659
  /* If the remote VTEP does not exist, there's nothing more to
4660
   * do.
4661
   * Otherwise, uninstall any remote MACs pointing to this VTEP
4662
   * and then, the VTEP entry itself and remove it.
4663
   */
4664
0
  zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4665
0
  if (!zvtep)
4666
0
    return;
4667
4668
0
  zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4669
0
  zebra_evpn_vtep_del(zevpn, zvtep);
4670
0
}
4671
4672
/*
4673
 * Handle message from client to add a remote VTEP for an EVPN.
4674
 */
4675
void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
4676
         struct in_addr vtep_ip, int flood_control)
4677
0
{
4678
0
  struct zebra_evpn *zevpn;
4679
0
  struct interface *ifp;
4680
0
  struct zebra_if *zif;
4681
0
  struct zebra_vtep *zvtep;
4682
0
  struct zebra_vrf *zvrf;
4683
4684
0
  if (!is_evpn_enabled()) {
4685
0
    zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD",
4686
0
         __func__);
4687
0
    return;
4688
0
  }
4689
4690
0
  zvrf = zebra_vrf_lookup_by_id(vrf_id);
4691
0
  if (!zvrf)
4692
0
    return;
4693
4694
0
  if (!EVPN_ENABLED(zvrf)) {
4695
0
    zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u",
4696
0
         zvrf_id(zvrf));
4697
0
    return;
4698
0
  }
4699
4700
  /* Locate VNI hash entry - expected to exist. */
4701
0
  zevpn = zebra_evpn_lookup(vni);
4702
0
  if (!zevpn) {
4703
0
    flog_err(
4704
0
      EC_ZEBRA_VTEP_ADD_FAILED,
4705
0
      "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
4706
0
      vni);
4707
0
    return;
4708
0
  }
4709
4710
0
  ifp = zevpn->vxlan_if;
4711
0
  if (!ifp) {
4712
0
    flog_err(
4713
0
      EC_ZEBRA_VTEP_ADD_FAILED,
4714
0
      "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
4715
0
      zevpn->vni, zevpn);
4716
0
    return;
4717
0
  }
4718
4719
0
  zif = ifp->info;
4720
4721
  /* If down or not mapped to a bridge, we're done. */
4722
0
  if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4723
0
    return;
4724
4725
0
  zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4726
0
  if (zvtep) {
4727
    /* If the remote VTEP already exists check if
4728
     * the flood mode has changed
4729
     */
4730
0
    if (zvtep->flood_control != flood_control) {
4731
0
      if (zvtep->flood_control == VXLAN_FLOOD_DISABLED)
4732
        /* old mode was head-end-replication but
4733
         * is no longer; get rid of the HER fdb
4734
         * entry installed before
4735
         */
4736
0
        zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4737
0
      zvtep->flood_control = flood_control;
4738
0
      zebra_evpn_vtep_install(zevpn, zvtep);
4739
0
    }
4740
0
  } else {
4741
0
    zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, flood_control);
4742
0
    if (zvtep)
4743
0
      zebra_evpn_vtep_install(zevpn, zvtep);
4744
0
    else
4745
0
      flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
4746
0
         "Failed to add remote VTEP, VNI %u zevpn %p",
4747
0
         vni, zevpn);
4748
0
  }
4749
0
}
4750
4751
/*
4752
 * Handle message from client to add a remote VTEP for an EVPN.
4753
 */
4754
void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS)
4755
0
{
4756
0
  struct stream *s;
4757
0
  unsigned short l = 0;
4758
0
  vni_t vni;
4759
0
  struct in_addr vtep_ip;
4760
0
  int flood_control;
4761
4762
0
  if (!is_evpn_enabled()) {
4763
0
    zlog_debug(
4764
0
      "%s: EVPN not enabled yet we received a VTEP ADD zapi msg",
4765
0
      __func__);
4766
0
    return;
4767
0
  }
4768
4769
0
  if (!EVPN_ENABLED(zvrf)) {
4770
0
    zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u",
4771
0
         zvrf_id(zvrf));
4772
0
    return;
4773
0
  }
4774
4775
0
  s = msg;
4776
4777
0
  while (l < hdr->length) {
4778
    /* Obtain each remote VTEP and process. */
4779
0
    STREAM_GETL(s, vni);
4780
0
    l += 4;
4781
0
    STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4782
0
    STREAM_GETL(s, flood_control);
4783
0
    l += IPV4_MAX_BYTELEN + 4;
4784
4785
0
    if (IS_ZEBRA_DEBUG_VXLAN)
4786
0
      zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s",
4787
0
           &vtep_ip, vni, flood_control,
4788
0
           zebra_route_string(client->proto));
4789
4790
    /* Enqueue for processing */
4791
0
    zebra_rib_queue_evpn_rem_vtep_add(zvrf_id(zvrf), vni, vtep_ip,
4792
0
              flood_control);
4793
0
  }
4794
4795
0
stream_failure:
4796
0
  return;
4797
0
}
4798
4799
/*
4800
 * Add/Del gateway macip to evpn
4801
 * g/w can be:
4802
 *  1. SVI interface on a vlan aware bridge
4803
 *  2. SVI interface on a vlan unaware bridge
4804
 *  3. vrr interface (MACVLAN) associated to a SVI
4805
 * We advertise macip routes for an interface if it is associated to VxLan vlan
4806
 */
4807
int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p,
4808
         int add)
4809
0
{
4810
0
  struct ipaddr ip;
4811
0
  struct ethaddr macaddr;
4812
0
  struct zebra_evpn *zevpn = NULL;
4813
4814
0
  memset(&ip, 0, sizeof(ip));
4815
0
  memset(&macaddr, 0, sizeof(macaddr));
4816
4817
  /* Check if EVPN is enabled. */
4818
0
  if (!is_evpn_enabled())
4819
0
    return 0;
4820
4821
0
  if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4822
0
    struct interface *svi_if =
4823
0
      NULL; /* SVI corresponding to the MACVLAN */
4824
0
    struct zebra_if *ifp_zif =
4825
0
      NULL; /* Zebra daemon specific info for MACVLAN */
4826
0
    struct zebra_if *svi_if_zif =
4827
0
      NULL; /* Zebra daemon specific info for SVI*/
4828
4829
0
    ifp_zif = ifp->info;
4830
0
    if (!ifp_zif)
4831
0
      return -1;
4832
4833
    /*
4834
     * for a MACVLAN interface the link represents the svi_if
4835
     */
4836
0
    svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4837
0
               ifp_zif->link_ifindex);
4838
0
    if (!svi_if) {
4839
0
      zlog_debug("MACVLAN %s(%u) without link information",
4840
0
           ifp->name, ifp->ifindex);
4841
0
      return -1;
4842
0
    }
4843
4844
0
    if (IS_ZEBRA_IF_VLAN(svi_if)) {
4845
      /*
4846
       * If it is a vlan aware bridge then the link gives the
4847
       * bridge information
4848
       */
4849
0
      struct interface *svi_if_link = NULL;
4850
4851
0
      svi_if_zif = svi_if->info;
4852
0
      if (svi_if_zif) {
4853
0
        svi_if_link = if_lookup_by_index_per_ns(
4854
0
          zebra_ns_lookup(NS_DEFAULT),
4855
0
          svi_if_zif->link_ifindex);
4856
0
        zevpn = zebra_evpn_from_svi(svi_if,
4857
0
                  svi_if_link);
4858
0
      }
4859
0
    } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
4860
      /*
4861
       * If it is a vlan unaware bridge then svi is the bridge
4862
       * itself
4863
       */
4864
0
      zevpn = zebra_evpn_from_svi(svi_if, svi_if);
4865
0
    }
4866
0
  } else if (IS_ZEBRA_IF_VLAN(ifp)) {
4867
0
    struct zebra_if *svi_if_zif =
4868
0
      NULL; /* Zebra daemon specific info for SVI */
4869
0
    struct interface *svi_if_link =
4870
0
      NULL; /* link info for the SVI = bridge info */
4871
4872
0
    svi_if_zif = ifp->info;
4873
0
    if (svi_if_zif) {
4874
0
      svi_if_link = if_lookup_by_index_per_ns(
4875
0
        zebra_ns_lookup(NS_DEFAULT),
4876
0
        svi_if_zif->link_ifindex);
4877
0
      if (svi_if_link)
4878
0
        zevpn = zebra_evpn_from_svi(ifp, svi_if_link);
4879
0
    }
4880
0
  } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
4881
0
    zevpn = zebra_evpn_from_svi(ifp, ifp);
4882
0
  }
4883
4884
0
  if (!zevpn)
4885
0
    return 0;
4886
4887
0
  if (!zevpn->vxlan_if) {
4888
0
    zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
4889
0
         zevpn->vni, zevpn);
4890
0
    return -1;
4891
0
  }
4892
4893
  /* VRR IP is advertised only if gw-macip-adv-enabled */
4894
0
  if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4895
0
    if (!advertise_gw_macip_enabled(zevpn))
4896
0
      return 0;
4897
0
  } else {
4898
    /* SVI IP is advertised if gw or svi macip-adv-enabled */
4899
0
    if (!advertise_svi_macip_enabled(zevpn)
4900
0
        && !advertise_gw_macip_enabled(zevpn))
4901
0
      return 0;
4902
0
  }
4903
4904
0
  memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
4905
4906
0
  if (p->family == AF_INET) {
4907
0
    ip.ipa_type = IPADDR_V4;
4908
0
    memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
4909
0
           sizeof(struct in_addr));
4910
0
  } else if (p->family == AF_INET6) {
4911
0
    ip.ipa_type = IPADDR_V6;
4912
0
    memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
4913
0
           sizeof(struct in6_addr));
4914
0
  }
4915
4916
4917
0
  if (add)
4918
0
    zebra_evpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
4919
0
  else
4920
0
    zebra_evpn_gw_macip_del(ifp, zevpn, &ip);
4921
4922
0
  return 0;
4923
0
}
4924
4925
/*
4926
 * Handle SVI interface going down.
4927
 * SVI can be associated to either L3-VNI or L2-VNI.
4928
 * For L2-VNI: At this point, this is a NOP since
4929
 *  the kernel deletes the neighbor entries on this SVI (if any).
4930
 *      We only need to update the vrf corresponding to zevpn.
4931
 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
4932
 *  from bgp
4933
 */
4934
int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
4935
0
{
4936
0
  struct zebra_l3vni *zl3vni = NULL;
4937
4938
0
  zl3vni = zl3vni_from_svi(ifp, link_if);
4939
0
  if (zl3vni) {
4940
4941
    /* process l3-vni down */
4942
0
    zebra_vxlan_process_l3vni_oper_down(zl3vni);
4943
4944
    /* remove association with svi-if */
4945
0
    zl3vni->svi_if = NULL;
4946
0
  } else {
4947
0
    struct zebra_evpn *zevpn = NULL;
4948
4949
    /* Unlink the SVI from the access VLAN */
4950
0
    zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, false);
4951
4952
    /* since we dont have svi corresponding to zevpn, we associate it
4953
     * to default vrf. Note: the corresponding neigh entries on the
4954
     * SVI would have already been deleted */
4955
0
    zevpn = zebra_evpn_from_svi(ifp, link_if);
4956
4957
0
    if (zevpn) {
4958
      /* remove from l3-vni list */
4959
0
      zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4960
0
      if (zl3vni)
4961
0
        listnode_delete(zl3vni->l2vnis, zevpn);
4962
4963
0
      zevpn->svi_if = NULL;
4964
0
      zevpn->vrf_id = VRF_DEFAULT;
4965
4966
      /* update the tenant vrf in BGP */
4967
0
      if (if_is_operative(zevpn->vxlan_if))
4968
0
        zebra_evpn_send_add_to_client(zevpn);
4969
0
    }
4970
0
  }
4971
0
  return 0;
4972
0
}
4973
4974
/*
4975
 * Handle SVI interface coming up.
4976
 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
4977
 * vxlan intf).
4978
 * For L2-VNI: we need to install any remote neighbors entried (used for
4979
 * arp-suppression)
4980
 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
4981
 */
4982
int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
4983
0
{
4984
0
  struct zebra_evpn *zevpn = NULL;
4985
0
  struct zebra_l3vni *zl3vni = NULL;
4986
4987
0
  zl3vni = zl3vni_from_svi(ifp, link_if);
4988
0
  if (zl3vni) {
4989
4990
    /* associate with svi */
4991
0
    zl3vni->svi_if = ifp;
4992
4993
    /* process oper-up */
4994
0
    if (is_l3vni_oper_up(zl3vni))
4995
0
      zebra_vxlan_process_l3vni_oper_up(zl3vni);
4996
0
  } else {
4997
4998
    /* process SVI up for l2-vni */
4999
0
    struct neigh_walk_ctx n_wctx;
5000
5001
0
    zevpn = zebra_evpn_from_svi(ifp, link_if);
5002
0
    if (!zevpn)
5003
0
      return 0;
5004
5005
0
    if (!zevpn->vxlan_if) {
5006
0
      zlog_debug(
5007
0
        "VNI %u hash %p doesn't have intf upon SVI up",
5008
0
        zevpn->vni, zevpn);
5009
0
      return -1;
5010
0
    }
5011
5012
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5013
0
      zlog_debug(
5014
0
        "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5015
0
        ifp->name, ifp->ifindex, zevpn->vni,
5016
0
        ifp->vrf->name);
5017
5018
    /* update the vrf information for l2-vni and inform bgp */
5019
0
    zevpn->svi_if = ifp;
5020
0
    zevpn->vrf_id = ifp->vrf->vrf_id;
5021
5022
0
    zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
5023
0
    if (zl3vni)
5024
0
      listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
5025
5026
0
    if (if_is_operative(zevpn->vxlan_if))
5027
0
      zebra_evpn_send_add_to_client(zevpn);
5028
5029
    /* Install any remote neighbors for this VNI. */
5030
0
    memset(&n_wctx, 0, sizeof(n_wctx));
5031
0
    n_wctx.zevpn = zevpn;
5032
0
    hash_iterate(zevpn->neigh_table, zebra_evpn_install_neigh_hash,
5033
0
           &n_wctx);
5034
5035
    /* Link the SVI from the access VLAN */
5036
0
    zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, true);
5037
5038
    /* Update MACIP routes created by advertise-svi-ip */
5039
0
    if (advertise_svi_macip_enabled(zevpn)) {
5040
0
      zebra_evpn_del_macip_for_intf(ifp, zevpn);
5041
0
      zebra_evpn_add_macip_for_intf(ifp, zevpn);
5042
0
    }
5043
0
  }
5044
5045
0
  return 0;
5046
0
}
5047
5048
/*
5049
 * Handle MAC-VLAN interface going down.
5050
 * L3VNI: When MAC-VLAN interface goes down,
5051
 * find its associated SVI and update type2/type-5 routes
5052
 * with SVI as RMAC
5053
 */
5054
void zebra_vxlan_macvlan_down(struct interface *ifp)
5055
0
{
5056
0
  struct zebra_l3vni *zl3vni = NULL;
5057
0
  struct zebra_if *zif, *link_zif;
5058
0
  struct interface *link_ifp, *link_if;
5059
5060
0
  zif = ifp->info;
5061
0
  assert(zif);
5062
0
  link_ifp = zif->link;
5063
0
  if (!link_ifp) {
5064
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5065
0
      zlog_debug(
5066
0
        "macvlan parent link is not found. Parent index %d ifp %s",
5067
0
        zif->link_ifindex,
5068
0
        ifindex2ifname(zif->link_ifindex,
5069
0
                 ifp->vrf->vrf_id));
5070
0
    return;
5071
0
  }
5072
0
  link_zif = link_ifp->info;
5073
0
  assert(link_zif);
5074
5075
0
  link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
5076
0
              link_zif->link_ifindex);
5077
5078
0
  zl3vni = zl3vni_from_svi(link_ifp, link_if);
5079
0
  if (zl3vni) {
5080
0
    zl3vni->mac_vlan_if = NULL;
5081
0
    if (is_l3vni_oper_up(zl3vni))
5082
0
      zebra_vxlan_process_l3vni_oper_up(zl3vni);
5083
0
  }
5084
0
}
5085
5086
/*
5087
 * Handle MAC-VLAN interface going up.
5088
 * L3VNI: When MAC-VLAN interface comes up,
5089
 * find its associated SVI and update type-2 routes
5090
 * with MAC-VLAN's MAC as RMAC and for type-5 routes
5091
 * use SVI's MAC as RMAC.
5092
 */
5093
void zebra_vxlan_macvlan_up(struct interface *ifp)
5094
0
{
5095
0
  struct zebra_l3vni *zl3vni = NULL;
5096
0
  struct zebra_if *zif, *link_zif;
5097
0
  struct interface *link_ifp, *link_if;
5098
5099
0
  zif = ifp->info;
5100
0
  assert(zif);
5101
0
  link_ifp = zif->link;
5102
0
  link_zif = link_ifp->info;
5103
0
  assert(link_zif);
5104
5105
0
  link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
5106
0
              link_zif->link_ifindex);
5107
0
  zl3vni = zl3vni_from_svi(link_ifp, link_if);
5108
0
  if (zl3vni) {
5109
    /* associate with macvlan (VRR) interface */
5110
0
    zl3vni->mac_vlan_if = ifp;
5111
5112
    /* process oper-up */
5113
0
    if (is_l3vni_oper_up(zl3vni))
5114
0
      zebra_vxlan_process_l3vni_oper_up(zl3vni);
5115
0
  }
5116
0
}
5117
5118
int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
5119
            char *err, int err_str_sz, int filter,
5120
            int add)
5121
0
{
5122
0
  struct zebra_l3vni *zl3vni = NULL;
5123
0
  struct zebra_vrf *zvrf_evpn = NULL;
5124
5125
0
  zvrf_evpn = zebra_vrf_get_evpn();
5126
5127
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5128
0
    zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
5129
0
         add ? "ADD" : "DEL");
5130
5131
0
  if (add) {
5132
    /* check if the vni is already present under zvrf */
5133
0
    if (zvrf->l3vni) {
5134
0
      snprintf(err, err_str_sz,
5135
0
         "VNI is already configured under the vrf");
5136
0
      return -1;
5137
0
    }
5138
5139
    /* check if this VNI is already present in the system */
5140
0
    zl3vni = zl3vni_lookup(vni);
5141
0
    if (zl3vni) {
5142
0
      snprintf(err, err_str_sz,
5143
0
         "VNI is already configured as L3-VNI");
5144
0
      return -1;
5145
0
    }
5146
5147
    /* Remove L2VNI if present */
5148
0
    zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5149
5150
    /* add the L3-VNI to the global table */
5151
0
    zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
5152
5153
    /* associate the vrf with vni */
5154
0
    zvrf->l3vni = vni;
5155
5156
    /* set the filter in l3vni to denote if we are using l3vni only
5157
     * for prefix routes
5158
     */
5159
0
    if (filter)
5160
0
      SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
5161
5162
    /* associate with vxlan-intf;
5163
     * we need to associate with the vxlan-intf first
5164
     */
5165
0
    zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
5166
5167
    /* associate with corresponding SVI interface, we can associate
5168
     * with svi-if only after vxlan interface association is
5169
     * complete
5170
     */
5171
0
    zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5172
5173
0
    zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
5174
5175
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5176
0
      zlog_debug(
5177
0
        "%s: l3vni %u svi_if %s mac_vlan_if %s",
5178
0
        __func__, vni,
5179
0
        zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
5180
0
        zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
5181
0
                : "NIL");
5182
5183
    /* formulate l2vni list */
5184
0
    hash_iterate(zvrf_evpn->evpn_table, zevpn_add_to_l3vni_list,
5185
0
           zl3vni);
5186
5187
0
    if (is_l3vni_oper_up(zl3vni))
5188
0
      zebra_vxlan_process_l3vni_oper_up(zl3vni);
5189
5190
0
  } else {
5191
0
    zl3vni = zl3vni_lookup(vni);
5192
0
    if (!zl3vni) {
5193
0
      snprintf(err, err_str_sz, "VNI doesn't exist");
5194
0
      return -1;
5195
0
    }
5196
5197
0
    if (zvrf->l3vni != vni) {
5198
0
      snprintf(err, err_str_sz,
5199
0
          "VNI %d doesn't exist in VRF: %s",
5200
0
          vni, zvrf->vrf->name);
5201
0
      return -1;
5202
0
    }
5203
5204
0
    if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
5205
0
      snprintf(err, ERR_STR_SZ,
5206
0
         "prefix-routes-only is not set for the vni");
5207
0
      return -1;
5208
0
    }
5209
5210
0
    zebra_vxlan_process_l3vni_oper_down(zl3vni);
5211
5212
    /* delete and uninstall all rmacs */
5213
0
    hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
5214
0
           zl3vni);
5215
5216
    /* delete and uninstall all next-hops */
5217
0
    hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
5218
0
           zl3vni);
5219
5220
0
    zvrf->l3vni = 0;
5221
0
    zl3vni_del(zl3vni);
5222
5223
    /* Add L2VNI for this VNI */
5224
0
    zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5225
0
  }
5226
0
  return 0;
5227
0
}
5228
5229
int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
5230
1
{
5231
1
  struct zebra_l3vni *zl3vni = NULL;
5232
5233
1
  if (zvrf->l3vni)
5234
0
    zl3vni = zl3vni_lookup(zvrf->l3vni);
5235
1
  if (!zl3vni)
5236
1
    return 0;
5237
5238
0
  zl3vni->vrf_id = zvrf_id(zvrf);
5239
0
  if (is_l3vni_oper_up(zl3vni))
5240
0
    zebra_vxlan_process_l3vni_oper_up(zl3vni);
5241
0
  return 0;
5242
1
}
5243
5244
int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
5245
0
{
5246
0
  struct zebra_l3vni *zl3vni = NULL;
5247
5248
0
  if (zvrf->l3vni)
5249
0
    zl3vni = zl3vni_lookup(zvrf->l3vni);
5250
0
  if (!zl3vni)
5251
0
    return 0;
5252
5253
0
  zebra_vxlan_process_l3vni_oper_down(zl3vni);
5254
5255
  /* delete and uninstall all rmacs */
5256
0
  hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry, zl3vni);
5257
  /* delete and uninstall all next-hops */
5258
0
  hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry, zl3vni);
5259
5260
0
  zl3vni->vrf_id = VRF_UNKNOWN;
5261
5262
0
  return 0;
5263
0
}
5264
5265
int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
5266
0
{
5267
0
  struct zebra_l3vni *zl3vni = NULL;
5268
0
  vni_t vni;
5269
5270
0
  if (zvrf->l3vni)
5271
0
    zl3vni = zl3vni_lookup(zvrf->l3vni);
5272
0
  if (!zl3vni)
5273
0
    return 0;
5274
5275
0
  vni = zl3vni->vni;
5276
0
  zl3vni_del(zl3vni);
5277
5278
0
  if (!zrouter.in_shutdown)
5279
0
    zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
5280
5281
0
  return 0;
5282
0
}
5283
5284
/*
5285
 * Handle message from client to specify the flooding mechanism for
5286
 * BUM packets. The default is to do head-end (ingress) replication
5287
 * and the other supported option is to disable it. This applies to
5288
 * all BUM traffic and disabling it applies to both the transmit and
5289
 * receive direction.
5290
 */
5291
void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
5292
0
{
5293
0
  struct stream *s;
5294
0
  enum vxlan_flood_control flood_ctrl;
5295
5296
0
  if (!EVPN_ENABLED(zvrf)) {
5297
0
    zlog_err("EVPN flood control for non-EVPN VRF %u",
5298
0
       zvrf_id(zvrf));
5299
0
    return;
5300
0
  }
5301
5302
0
  s = msg;
5303
0
  STREAM_GETC(s, flood_ctrl);
5304
5305
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5306
0
    zlog_debug("EVPN flood control %u, currently %u",
5307
0
         flood_ctrl, zvrf->vxlan_flood_ctrl);
5308
5309
0
  if (zvrf->vxlan_flood_ctrl == flood_ctrl)
5310
0
    return;
5311
5312
0
  zvrf->vxlan_flood_ctrl = flood_ctrl;
5313
5314
  /* Install or uninstall flood entries corresponding to
5315
   * remote VTEPs.
5316
   */
5317
0
  hash_iterate(zvrf->evpn_table, zebra_evpn_handle_flooding_remote_vteps,
5318
0
         zvrf);
5319
5320
0
stream_failure:
5321
0
  return;
5322
0
}
5323
5324
/*
5325
 * Handle message from client to enable/disable advertisement of svi macip
5326
 * routes
5327
 */
5328
void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
5329
1
{
5330
1
  struct stream *s;
5331
1
  int advertise;
5332
1
  vni_t vni = 0;
5333
1
  struct zebra_evpn *zevpn = NULL;
5334
1
  struct interface *ifp = NULL;
5335
5336
1
  if (!EVPN_ENABLED(zvrf)) {
5337
0
    zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
5338
0
        zvrf_id(zvrf));
5339
0
    return;
5340
0
  }
5341
5342
1
  s = msg;
5343
1
  STREAM_GETC(s, advertise);
5344
1
  STREAM_GETL(s, vni);
5345
5346
1
  if (!vni) {
5347
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5348
0
      zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
5349
0
           advertise ? "enabled" : "disabled",
5350
0
           advertise_svi_macip_enabled(NULL)
5351
0
             ? "enabled"
5352
0
             : "disabled");
5353
5354
0
    if (zvrf->advertise_svi_macip == advertise)
5355
0
      return;
5356
5357
5358
0
    if (advertise) {
5359
0
      zvrf->advertise_svi_macip = advertise;
5360
0
      hash_iterate(zvrf->evpn_table,
5361
0
             zebra_evpn_gw_macip_add_for_evpn_hash,
5362
0
             NULL);
5363
0
    } else {
5364
0
      hash_iterate(zvrf->evpn_table,
5365
0
             zebra_evpn_svi_macip_del_for_evpn_hash,
5366
0
             NULL);
5367
0
      zvrf->advertise_svi_macip = advertise;
5368
0
    }
5369
5370
1
  } else {
5371
1
    struct zebra_if *zif = NULL;
5372
1
    struct interface *vlan_if = NULL;
5373
1
    struct zebra_vxlan_vni *zl2_info_vni;
5374
1
    int old_advertise;
5375
5376
1
    zevpn = zebra_evpn_lookup(vni);
5377
1
    if (!zevpn)
5378
1
      return;
5379
5380
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5381
0
      zlog_debug(
5382
0
        "EVPN SVI macip Adv %s on VNI %d, currently %s",
5383
0
        advertise ? "enabled" : "disabled", vni,
5384
0
        advertise_svi_macip_enabled(zevpn)
5385
0
          ? "enabled"
5386
0
          : "disabled");
5387
5388
0
    old_advertise = advertise_svi_macip_enabled(zevpn);
5389
5390
    /* Store flag even though SVI is not present.
5391
     * Once SVI comes up triggers self MAC-IP route add.
5392
     */
5393
0
    zevpn->advertise_svi_macip = advertise;
5394
0
    if (advertise_svi_macip_enabled(zevpn) == old_advertise)
5395
0
      return;
5396
5397
0
    ifp = zevpn->vxlan_if;
5398
0
    if (!ifp)
5399
0
      return;
5400
5401
0
    zif = ifp->info;
5402
5403
    /* If down or not mapped to a bridge, we're done. */
5404
0
    if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5405
0
      return;
5406
5407
0
    zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5408
0
    if (!zl2_info_vni)
5409
0
      return;
5410
5411
0
    vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5412
0
            zif->brslave_info.br_if);
5413
0
    if (!vlan_if)
5414
0
      return;
5415
5416
0
    if (advertise) {
5417
      /* Add primary SVI MAC-IP */
5418
0
      zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5419
0
    } else {
5420
      /* Del primary SVI MAC-IP */
5421
0
      zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5422
0
    }
5423
0
  }
5424
5425
0
stream_failure:
5426
0
  return;
5427
1
}
5428
5429
/*
5430
 * Handle message from client to enable/disable advertisement of g/w macip
5431
 * routes
5432
 */
5433
void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
5434
0
{
5435
0
  struct stream *s;
5436
0
  int advertise;
5437
0
  vni_t vni = 0;
5438
0
  struct zebra_evpn *zevpn = NULL;
5439
0
  struct interface *ifp = NULL;
5440
0
  struct zebra_if *zif = NULL;
5441
0
  struct interface *vlan_if = NULL;
5442
0
  struct zebra_vxlan_vni *zl2_info_vni = NULL;
5443
5444
0
  if (!EVPN_ENABLED(zvrf)) {
5445
0
    zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5446
0
        zvrf_id(zvrf));
5447
0
    return;
5448
0
  }
5449
5450
0
  s = msg;
5451
0
  STREAM_GETC(s, advertise);
5452
0
  STREAM_GET(&vni, s, 3);
5453
5454
0
  zevpn = zebra_evpn_lookup(vni);
5455
0
  if (!zevpn)
5456
0
    return;
5457
5458
0
  if (zevpn->advertise_subnet == advertise)
5459
0
    return;
5460
5461
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5462
0
    zlog_debug("EVPN subnet Adv %s on VNI %d, currently %s",
5463
0
         advertise ? "enabled" : "disabled", vni,
5464
0
         zevpn->advertise_subnet ? "enabled" : "disabled");
5465
5466
5467
0
  zevpn->advertise_subnet = advertise;
5468
5469
0
  ifp = zevpn->vxlan_if;
5470
0
  if (!ifp)
5471
0
    return;
5472
5473
0
  zif = ifp->info;
5474
5475
  /* If down or not mapped to a bridge, we're done. */
5476
0
  if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5477
0
    return;
5478
5479
0
  zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5480
0
  if (!zl2_info_vni)
5481
0
    return;
5482
5483
0
  vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5484
0
          zif->brslave_info.br_if);
5485
0
  if (!vlan_if)
5486
0
    return;
5487
5488
0
  if (zevpn->advertise_subnet)
5489
0
    zebra_evpn_advertise_subnet(zevpn, vlan_if, 1);
5490
0
  else
5491
0
    zebra_evpn_advertise_subnet(zevpn, vlan_if, 0);
5492
5493
0
stream_failure:
5494
0
  return;
5495
0
}
5496
5497
/*
5498
 * Handle message from client to enable/disable advertisement of g/w macip
5499
 * routes
5500
 */
5501
void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
5502
1
{
5503
1
  struct stream *s;
5504
1
  int advertise;
5505
1
  vni_t vni = 0;
5506
1
  struct zebra_evpn *zevpn = NULL;
5507
1
  struct interface *ifp = NULL;
5508
5509
1
  if (!EVPN_ENABLED(zvrf)) {
5510
1
    zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5511
1
         zvrf_id(zvrf));
5512
1
    return;
5513
1
  }
5514
5515
0
  s = msg;
5516
0
  STREAM_GETC(s, advertise);
5517
0
  STREAM_GETL(s, vni);
5518
5519
0
  if (!vni) {
5520
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5521
0
      zlog_debug("EVPN gateway macip Adv %s, currently %s",
5522
0
           advertise ? "enabled" : "disabled",
5523
0
           advertise_gw_macip_enabled(NULL)
5524
0
             ? "enabled"
5525
0
             : "disabled");
5526
5527
0
    if (zvrf->advertise_gw_macip == advertise)
5528
0
      return;
5529
5530
0
    zvrf->advertise_gw_macip = advertise;
5531
5532
0
    if (advertise_gw_macip_enabled(zevpn))
5533
0
      hash_iterate(zvrf->evpn_table,
5534
0
             zebra_evpn_gw_macip_add_for_evpn_hash,
5535
0
             NULL);
5536
0
    else
5537
0
      hash_iterate(zvrf->evpn_table,
5538
0
             zebra_evpn_gw_macip_del_for_evpn_hash,
5539
0
             NULL);
5540
5541
0
  } else {
5542
0
    struct zebra_if *zif = NULL;
5543
0
    struct interface *vlan_if = NULL;
5544
0
    struct interface *vrr_if = NULL;
5545
0
    struct zebra_vxlan_vni *zl2_info_vni = NULL;
5546
0
    int old_advertise;
5547
5548
0
    zevpn = zebra_evpn_lookup(vni);
5549
0
    if (!zevpn)
5550
0
      return;
5551
5552
0
    if (IS_ZEBRA_DEBUG_VXLAN)
5553
0
      zlog_debug(
5554
0
        "EVPN gateway macip Adv %s on VNI %d, currently %s",
5555
0
        advertise ? "enabled" : "disabled", vni,
5556
0
        advertise_gw_macip_enabled(zevpn) ? "enabled"
5557
0
                  : "disabled");
5558
5559
0
    old_advertise = advertise_gw_macip_enabled(zevpn);
5560
5561
0
    zevpn->advertise_gw_macip = advertise;
5562
0
    if (advertise_gw_macip_enabled(zevpn) == old_advertise)
5563
0
      return;
5564
5565
0
    ifp = zevpn->vxlan_if;
5566
0
    if (!ifp)
5567
0
      return;
5568
5569
0
    zif = ifp->info;
5570
5571
    /* If down or not mapped to a bridge, we're done. */
5572
0
    if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5573
0
      return;
5574
5575
0
    zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5576
0
    if (!zl2_info_vni)
5577
0
      return;
5578
5579
0
    vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5580
0
            zif->brslave_info.br_if);
5581
0
    if (!vlan_if)
5582
0
      return;
5583
5584
0
    if (advertise_gw_macip_enabled(zevpn)) {
5585
      /* Add primary SVI MAC-IP */
5586
0
      zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5587
5588
      /* Add VRR MAC-IP - if any*/
5589
0
      vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5590
0
      if (vrr_if)
5591
0
        zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
5592
0
    } else {
5593
      /* Del primary MAC-IP */
5594
0
      zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5595
5596
      /* Del VRR MAC-IP - if any*/
5597
0
      vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5598
0
      if (vrr_if)
5599
0
        zebra_evpn_del_macip_for_intf(vrr_if, zevpn);
5600
0
    }
5601
0
  }
5602
5603
0
stream_failure:
5604
0
  return;
5605
0
}
5606
5607
static int macfdb_read_ns(struct ns *ns,
5608
        void *_in_param __attribute__((unused)),
5609
        void **out_param __attribute__((unused)))
5610
1
{
5611
1
  struct zebra_ns *zns = ns->info;
5612
5613
1
  macfdb_read(zns);
5614
1
  return NS_WALK_CONTINUE;
5615
1
}
5616
5617
static int neigh_read_ns(struct ns *ns,
5618
       void *_in_param __attribute__((unused)),
5619
       void **out_param __attribute__((unused)))
5620
1
{
5621
1
  struct zebra_ns *zns = ns->info;
5622
5623
1
  neigh_read(zns);
5624
1
  return NS_WALK_CONTINUE;
5625
1
}
5626
5627
/*
5628
 * Handle message from client to learn (or stop learning) about VNIs and MACs.
5629
 * When enabled, the VNI hash table will be built and MAC FDB table read;
5630
 * when disabled, the entries should be deleted and remote VTEPs and MACs
5631
 * uninstalled from the kernel.
5632
 * This also informs the setting for BUM handling at the time this change
5633
 * occurs; it is relevant only when specifying "learn".
5634
 */
5635
void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
5636
1
{
5637
1
  struct stream *s = NULL;
5638
1
  int advertise = 0;
5639
1
  enum vxlan_flood_control flood_ctrl;
5640
5641
  /* Mismatch between EVPN VRF and current VRF (should be prevented by
5642
   * bgpd's cli) */
5643
1
  if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
5644
0
    return;
5645
5646
1
  s = msg;
5647
1
  STREAM_GETC(s, advertise);
5648
1
  STREAM_GETC(s, flood_ctrl);
5649
5650
1
  if (IS_ZEBRA_DEBUG_VXLAN)
5651
0
    zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
5652
1
         zvrf_name(zvrf), zvrf_id(zvrf),
5653
1
         advertise ? "enabled" : "disabled",
5654
1
         is_evpn_enabled() ? "enabled" : "disabled",
5655
1
         flood_ctrl);
5656
5657
1
  if (zvrf->advertise_all_vni == advertise)
5658
0
    return;
5659
5660
1
  zvrf->advertise_all_vni = advertise;
5661
1
  if (EVPN_ENABLED(zvrf)) {
5662
1
    zrouter.evpn_vrf = zvrf;
5663
5664
    /* Note BUM handling */
5665
1
    zvrf->vxlan_flood_ctrl = flood_ctrl;
5666
5667
    /* Replay all ESs */
5668
1
    zebra_evpn_es_send_all_to_client(true /* add */);
5669
5670
    /* Build EVPN hash table and inform BGP. */
5671
1
    zevpn_build_hash_table();
5672
5673
    /* Add all SVI (L3 GW) MACs to BGP*/
5674
1
    hash_iterate(zvrf->evpn_table,
5675
1
           zebra_evpn_gw_macip_add_for_evpn_hash, NULL);
5676
5677
    /* Read the MAC FDB */
5678
1
    ns_walk_func(macfdb_read_ns, NULL, NULL);
5679
5680
    /* Read neighbors */
5681
1
    ns_walk_func(neigh_read_ns, NULL, NULL);
5682
1
  } else {
5683
    /* Cleanup VTEPs for all EVPNs - uninstall from
5684
     * kernel and free entries.
5685
     */
5686
0
    hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all,
5687
0
           zvrf);
5688
5689
    /* Delete all ESs in BGP */
5690
0
    zebra_evpn_es_send_all_to_client(false /* add */);
5691
5692
    /* cleanup all l3vnis */
5693
0
    hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
5694
5695
    /* Mark as "no EVPN VRF" */
5696
0
    zrouter.evpn_vrf = NULL;
5697
0
  }
5698
5699
1
stream_failure:
5700
1
  return;
5701
1
}
5702
5703
/*
5704
 * Allocate EVPN hash table for this VRF and do other initialization.
5705
 * NOTE: Currently supported only for default VRF.
5706
 */
5707
void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
5708
1
{
5709
1
  char buffer[80];
5710
5711
1
  if (!zvrf)
5712
0
    return;
5713
5714
1
  snprintf(buffer, sizeof(buffer), "Zebra VRF EVPN Table: %s",
5715
1
     zvrf->vrf->name);
5716
1
  zvrf->evpn_table = hash_create_size(8, zebra_evpn_hash_keymake,
5717
1
              zebra_evpn_hash_cmp, buffer);
5718
5719
1
  snprintf(buffer, sizeof(buffer), "Zebra VxLAN SG Table: %s",
5720
1
     zvrf->vrf->name);
5721
1
  zvrf->vxlan_sg_table = hash_create_size(8, zebra_vxlan_sg_hash_key_make,
5722
1
            zebra_vxlan_sg_hash_eq, buffer);
5723
1
}
5724
5725
/* Cleanup EVPN info, but don't free the table. */
5726
void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
5727
0
{
5728
0
  struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn();
5729
5730
0
  hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5731
0
  zebra_vxlan_cleanup_sg_table(zvrf);
5732
5733
0
  if (zvrf == evpn_zvrf)
5734
0
    zebra_evpn_es_cleanup();
5735
0
}
5736
5737
/* Close all EVPN handling */
5738
void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
5739
0
{
5740
0
  if (!zvrf)
5741
0
    return;
5742
0
  hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5743
0
  hash_free(zvrf->evpn_table);
5744
0
  if (zvrf->vxlan_sg_table) {
5745
0
    zebra_vxlan_cleanup_sg_table(zvrf);
5746
0
    hash_free(zvrf->vxlan_sg_table);
5747
0
    zvrf->vxlan_sg_table = NULL;
5748
0
  }
5749
0
}
5750
5751
/* init the l3vni table */
5752
void zebra_vxlan_init(void)
5753
1
{
5754
1
  zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
5755
1
            "Zebra VRF L3 VNI table");
5756
5757
1
  svd_nh_table = zebra_neigh_db_create("Zebra SVD next-hop table");
5758
5759
1
  zrouter.evpn_vrf = NULL;
5760
1
  zebra_evpn_mh_init();
5761
1
}
5762
5763
/* free l3vni table */
5764
void zebra_vxlan_disable(void)
5765
0
{
5766
0
  hash_free(zrouter.l3vni_table);
5767
0
  zebra_evpn_mh_terminate();
5768
0
}
5769
5770
/* get the l3vni svi ifindex */
5771
ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
5772
0
{
5773
0
  struct zebra_l3vni *zl3vni = NULL;
5774
5775
0
  zl3vni = zl3vni_from_vrf(vrf_id);
5776
0
  if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5777
0
    return 0;
5778
5779
0
  return zl3vni->svi_if->ifindex;
5780
0
}
5781
5782
/* get the l3vni vxlan ifindex */
5783
ifindex_t get_l3vni_vxlan_ifindex(vrf_id_t vrf_id)
5784
0
{
5785
0
  struct zebra_l3vni *zl3vni = NULL;
5786
5787
0
  zl3vni = zl3vni_from_vrf(vrf_id);
5788
0
  if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5789
0
    return 0;
5790
5791
0
  return zl3vni->vxlan_if->ifindex;
5792
0
}
5793
5794
/* get the l3vni vni */
5795
vni_t get_l3vni_vni(vrf_id_t vrf_id)
5796
0
{
5797
0
  struct zebra_l3vni *zl3vni = NULL;
5798
5799
0
  zl3vni = zl3vni_from_vrf(vrf_id);
5800
0
  if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5801
0
    return 0;
5802
5803
0
  return zl3vni->vni;
5804
0
}
5805
5806
/* is the vrf l3vni SVD backed? */
5807
bool is_vrf_l3vni_svd_backed(vrf_id_t vrf_id)
5808
0
{
5809
0
  struct zebra_l3vni *zl3vni = NULL;
5810
5811
0
  zl3vni = zl3vni_from_vrf(vrf_id);
5812
0
  if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5813
0
    return false;
5814
5815
0
  return IS_ZL3VNI_SVD_BACKED(zl3vni);
5816
0
}
5817
5818
/************************** vxlan SG cache management ************************/
5819
/* Inform PIM about the mcast group */
5820
static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
5821
    struct prefix_sg *sg,
5822
    char *sg_str, uint16_t cmd)
5823
0
{
5824
0
  struct zserv *client = NULL;
5825
0
  struct stream *s = NULL;
5826
5827
0
  client = zserv_find_client(ZEBRA_ROUTE_PIM, 0);
5828
0
  if (!client)
5829
0
    return 0;
5830
5831
0
  if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
5832
0
    return 0;
5833
5834
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5835
5836
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
5837
0
  stream_putl(s, IPV4_MAX_BYTELEN);
5838
0
  stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
5839
0
  stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
5840
5841
  /* Write packet size. */
5842
0
  stream_putw_at(s, 0, stream_get_endp(s));
5843
5844
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5845
0
    zlog_debug(
5846
0
      "Send %s %s to %s",
5847
0
      (cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", sg_str,
5848
0
      zebra_route_string(client->proto));
5849
5850
0
  if (cmd == ZEBRA_VXLAN_SG_ADD)
5851
0
    client->vxlan_sg_add_cnt++;
5852
0
  else
5853
0
    client->vxlan_sg_del_cnt++;
5854
5855
0
  return zserv_send_message(client, s);
5856
0
}
5857
5858
static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
5859
0
{
5860
0
  const struct zebra_vxlan_sg *vxlan_sg = p;
5861
5862
0
  return (jhash_2words(vxlan_sg->sg.src.s_addr,
5863
0
        vxlan_sg->sg.grp.s_addr, 0));
5864
0
}
5865
5866
static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
5867
0
{
5868
0
  const struct zebra_vxlan_sg *sg1 = p1;
5869
0
  const struct zebra_vxlan_sg *sg2 = p2;
5870
5871
0
  return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
5872
0
    && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
5873
0
}
5874
5875
static struct zebra_vxlan_sg *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
5876
             struct prefix_sg *sg)
5877
0
{
5878
0
  struct zebra_vxlan_sg *vxlan_sg;
5879
5880
0
  vxlan_sg = XCALLOC(MTYPE_ZVXLAN_SG, sizeof(*vxlan_sg));
5881
5882
0
  vxlan_sg->zvrf = zvrf;
5883
0
  vxlan_sg->sg = *sg;
5884
0
  prefix_sg2str(sg, vxlan_sg->sg_str);
5885
5886
0
  vxlan_sg = hash_get(zvrf->vxlan_sg_table, vxlan_sg, hash_alloc_intern);
5887
5888
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5889
0
    zlog_debug("vxlan SG %s created", vxlan_sg->sg_str);
5890
5891
0
  return vxlan_sg;
5892
0
}
5893
5894
static struct zebra_vxlan_sg *zebra_vxlan_sg_find(struct zebra_vrf *zvrf,
5895
              struct prefix_sg *sg)
5896
0
{
5897
0
  struct zebra_vxlan_sg lookup;
5898
5899
0
  lookup.sg = *sg;
5900
0
  return hash_lookup(zvrf->vxlan_sg_table, &lookup);
5901
0
}
5902
5903
static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
5904
             struct prefix_sg *sg)
5905
0
{
5906
0
  struct zebra_vxlan_sg *vxlan_sg;
5907
0
  struct zebra_vxlan_sg *parent = NULL;
5908
0
  struct in_addr sip;
5909
5910
0
  vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
5911
0
  if (vxlan_sg)
5912
0
    return vxlan_sg;
5913
5914
  /* create a *G entry for every BUM group implicitly -
5915
   * 1. The SG entry is used by pimd to setup the vxlan-origination-mroute
5916
   * 2. the XG entry is used by pimd to setup the
5917
   * vxlan-termination-mroute
5918
   */
5919
0
  if (sg->src.s_addr != INADDR_ANY) {
5920
0
    memset(&sip, 0, sizeof(sip));
5921
0
    parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
5922
0
    if (!parent)
5923
0
      return NULL;
5924
0
  }
5925
5926
0
  vxlan_sg = zebra_vxlan_sg_new(zvrf, sg);
5927
5928
0
  zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
5929
0
      ZEBRA_VXLAN_SG_ADD);
5930
5931
0
  return vxlan_sg;
5932
0
}
5933
5934
static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
5935
0
{
5936
0
  struct in_addr sip;
5937
0
  struct zebra_vrf *zvrf;
5938
5939
0
  zvrf = vrf_info_lookup(VRF_DEFAULT);
5940
0
  if (!zvrf)
5941
0
    return;
5942
5943
  /* On SG entry deletion remove the reference to its parent XG
5944
   * entry
5945
   */
5946
0
  if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
5947
0
    memset(&sip, 0, sizeof(sip));
5948
0
    zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
5949
0
  }
5950
5951
0
  zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
5952
0
      vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
5953
5954
0
  hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
5955
5956
0
  if (IS_ZEBRA_DEBUG_VXLAN)
5957
0
    zlog_debug("VXLAN SG %s deleted", vxlan_sg->sg_str);
5958
5959
0
  XFREE(MTYPE_ZVXLAN_SG, vxlan_sg);
5960
0
}
5961
5962
static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
5963
    struct in_addr sip, struct in_addr mcast_grp)
5964
0
{
5965
0
  struct zebra_vxlan_sg *vxlan_sg;
5966
0
  struct prefix_sg sg;
5967
5968
0
  sg.family = AF_INET;
5969
0
  sg.prefixlen = IPV4_MAX_BYTELEN;
5970
0
  sg.src = sip;
5971
0
  sg.grp = mcast_grp;
5972
0
  vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
5973
0
  if (!vxlan_sg)
5974
0
    return;
5975
5976
0
  if (vxlan_sg->ref_cnt)
5977
0
    --vxlan_sg->ref_cnt;
5978
5979
0
  if (!vxlan_sg->ref_cnt)
5980
0
    zebra_vxlan_sg_del(vxlan_sg);
5981
0
}
5982
5983
static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
5984
                struct in_addr sip,
5985
                struct in_addr mcast_grp)
5986
0
{
5987
0
  struct zebra_vxlan_sg *vxlan_sg;
5988
0
  struct prefix_sg sg;
5989
5990
0
  sg.family = AF_INET;
5991
0
  sg.prefixlen = IPV4_MAX_BYTELEN;
5992
0
  sg.src = sip;
5993
0
  sg.grp = mcast_grp;
5994
0
  vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
5995
0
  if (vxlan_sg)
5996
0
    ++vxlan_sg->ref_cnt;
5997
5998
0
  return vxlan_sg;
5999
0
}
6000
6001
void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
6002
        struct in_addr mcast_grp)
6003
0
{
6004
0
  struct zebra_vrf *zvrf;
6005
6006
0
  if (local_vtep_ip.s_addr == INADDR_ANY
6007
0
      || mcast_grp.s_addr == INADDR_ANY)
6008
0
    return;
6009
6010
0
  zvrf = vrf_info_lookup(VRF_DEFAULT);
6011
0
  if (!zvrf)
6012
0
    return;
6013
6014
0
  zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
6015
0
}
6016
6017
void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, struct in_addr mcast_grp)
6018
0
{
6019
0
  struct zebra_vrf *zvrf;
6020
6021
0
  if (local_vtep_ip.s_addr == INADDR_ANY
6022
0
      || mcast_grp.s_addr == INADDR_ANY)
6023
0
    return;
6024
6025
0
  zvrf = vrf_info_lookup(VRF_DEFAULT);
6026
0
  if (!zvrf)
6027
0
    return;
6028
0
  zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
6029
0
}
6030
6031
static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg)
6032
0
{
6033
0
  struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6034
6035
  /* increment the ref count against (*,G) to prevent them from being
6036
   * deleted
6037
   */
6038
0
  if (vxlan_sg->sg.src.s_addr == INADDR_ANY)
6039
0
    ++vxlan_sg->ref_cnt;
6040
0
}
6041
6042
static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg)
6043
0
{
6044
0
  struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6045
6046
  /* decrement the dummy ref count against (*,G) to delete them */
6047
0
  if (vxlan_sg->sg.src.s_addr == INADDR_ANY) {
6048
0
    if (vxlan_sg->ref_cnt)
6049
0
      --vxlan_sg->ref_cnt;
6050
0
    if (!vxlan_sg->ref_cnt)
6051
0
      zebra_vxlan_sg_del(vxlan_sg);
6052
0
  }
6053
0
}
6054
6055
static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg)
6056
0
{
6057
0
  struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6058
6059
0
  zebra_vxlan_sg_del(vxlan_sg);
6060
0
}
6061
6062
static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf)
6063
0
{
6064
  /* increment the ref count against (*,G) to prevent them from being
6065
   * deleted
6066
   */
6067
0
  hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_pre_cleanup, NULL);
6068
6069
0
  hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_cleanup, NULL);
6070
6071
  /* decrement the dummy ref count against the XG entries */
6072
0
  hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_post_cleanup, NULL);
6073
0
}
6074
6075
static void zebra_vxlan_sg_replay_send(struct hash_bucket *bucket, void *arg)
6076
0
{
6077
0
  struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6078
6079
0
  zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
6080
0
      vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
6081
0
}
6082
6083
/* Handle message from client to replay vxlan SG entries */
6084
void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
6085
0
{
6086
0
  if (IS_ZEBRA_DEBUG_VXLAN)
6087
0
    zlog_debug("VxLAN SG updates to PIM, start");
6088
6089
0
  SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6090
6091
0
  if (!EVPN_ENABLED(zvrf)) {
6092
0
    if (IS_ZEBRA_DEBUG_VXLAN)
6093
0
      zlog_debug("VxLAN SG replay request on unexpected vrf %d",
6094
0
           zvrf->vrf->vrf_id);
6095
0
    return;
6096
0
  }
6097
6098
0
  hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
6099
0
}
6100
6101
6102
/* Cleanup EVPN configuration of a specific VRF */
6103
static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
6104
0
{
6105
0
  struct zebra_l3vni *zl3vni = NULL;
6106
6107
0
  zvrf->advertise_all_vni = 0;
6108
0
  zvrf->advertise_gw_macip = 0;
6109
0
  zvrf->advertise_svi_macip = 0;
6110
0
  zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
6111
6112
0
  hash_iterate(zvrf->evpn_table, zebra_evpn_cfg_cleanup, NULL);
6113
6114
0
  if (zvrf->l3vni)
6115
0
    zl3vni = zl3vni_lookup(zvrf->l3vni);
6116
0
  if (zl3vni) {
6117
    /* delete and uninstall all rmacs */
6118
0
    hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
6119
0
           zl3vni);
6120
    /* delete and uninstall all next-hops */
6121
0
    hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
6122
0
           zl3vni);
6123
0
  }
6124
0
}
6125
6126
/* Cleanup BGP EVPN configuration upon client disconnect */
6127
static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
6128
0
{
6129
0
  struct vrf *vrf;
6130
0
  struct zebra_vrf *zvrf;
6131
6132
0
  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
6133
0
    zvrf = vrf->info;
6134
0
    if (zvrf)
6135
0
      zebra_evpn_vrf_cfg_cleanup(zvrf);
6136
0
  }
6137
6138
0
  return 0;
6139
0
}
6140
6141
static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
6142
0
{
6143
0
  struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
6144
6145
0
  if (CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
6146
0
    if (IS_ZEBRA_DEBUG_VXLAN)
6147
0
      zlog_debug("VxLAN SG updates to PIM, stop");
6148
0
    UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6149
0
  }
6150
6151
0
  return 0;
6152
0
}
6153
6154
static int zebra_evpn_cfg_clean_up(struct zserv *client)
6155
319
{
6156
319
  if (client->proto == ZEBRA_ROUTE_BGP)
6157
0
    return zebra_evpn_bgp_cfg_clean_up(client);
6158
6159
319
  if (client->proto == ZEBRA_ROUTE_PIM)
6160
0
    return zebra_evpn_pim_cfg_clean_up(client);
6161
6162
319
  return 0;
6163
319
}
6164
6165
/*
6166
 * Handle results for vxlan dataplane operations.
6167
 */
6168
extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx)
6169
0
{
6170
0
  return;
6171
0
}
6172
6173
/* Config knob for accepting lower sequence numbers */
6174
void zebra_vxlan_set_accept_bgp_seq(bool set)
6175
0
{
6176
0
  accept_bgp_seq = set;
6177
0
}
6178
6179
bool zebra_vxlan_get_accept_bgp_seq(void)
6180
0
{
6181
0
  return accept_bgp_seq;
6182
0
}
6183
6184
/* Cleanup BGP EVPN configuration upon client disconnect */
6185
extern void zebra_evpn_init(void)
6186
1
{
6187
1
  hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
6188
1
}