Coverage Report

Created: 2026-01-21 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/zebra/zebra_evpn_neigh.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Zebra EVPN Neighbor code
4
 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5
 */
6
7
#include <zebra.h>
8
9
#include "hash.h"
10
#include "interface.h"
11
#include "jhash.h"
12
#include "memory.h"
13
#include "prefix.h"
14
#include "vlan.h"
15
#include "json.h"
16
17
#include "zebra/zserv.h"
18
#include "zebra/debug.h"
19
#include "zebra/zebra_router.h"
20
#include "zebra/rt.h"
21
#include "zebra/zebra_errors.h"
22
#include "zebra/zebra_vrf.h"
23
#include "zebra/zebra_vxlan.h"
24
#include "zebra/zebra_vxlan_if.h"
25
#include "zebra/zebra_evpn.h"
26
#include "zebra/zebra_evpn_mh.h"
27
#include "zebra/zebra_evpn_neigh.h"
28
#include "zebra/zebra_evpn_mac.h"
29
30
2
DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "EVI Neighbor");
31
2
32
2
/*
33
2
 * Make hash key for neighbors.
34
2
 */
35
2
static unsigned int neigh_hash_keymake(const void *p)
36
2
{
37
0
  const struct zebra_neigh *n = p;
38
0
  const struct ipaddr *ip = &n->ip;
39
40
0
  if (IS_IPADDR_V4(ip))
41
0
    return jhash_1word(ip->ipaddr_v4.s_addr, 0);
42
43
0
  return jhash2(ip->ipaddr_v6.s6_addr32,
44
0
          array_size(ip->ipaddr_v6.s6_addr32), 0);
45
0
}
46
47
/*
48
 * Compare two neighbor hash structures.
49
 */
50
static bool neigh_cmp(const void *p1, const void *p2)
51
0
{
52
0
  const struct zebra_neigh *n1 = p1;
53
0
  const struct zebra_neigh *n2 = p2;
54
55
0
  if (n1 == NULL && n2 == NULL)
56
0
    return true;
57
58
0
  if (n1 == NULL || n2 == NULL)
59
0
    return false;
60
61
0
  return ipaddr_cmp(&n1->ip, &n2->ip) == 0;
62
0
}
63
64
int neigh_list_cmp(void *p1, void *p2)
65
0
{
66
0
  const struct zebra_neigh *n1 = p1;
67
0
  const struct zebra_neigh *n2 = p2;
68
69
0
  return ipaddr_cmp(&n1->ip, &n2->ip);
70
0
}
71
72
struct hash *zebra_neigh_db_create(const char *desc)
73
1
{
74
1
  return hash_create_size(8, neigh_hash_keymake, neigh_cmp, desc);
75
1
}
76
77
uint32_t num_dup_detected_neighs(struct zebra_evpn *zevpn)
78
0
{
79
0
  unsigned int i;
80
0
  uint32_t num_neighs = 0;
81
0
  struct hash *hash;
82
0
  struct hash_bucket *hb;
83
0
  struct zebra_neigh *nbr;
84
85
0
  hash = zevpn->neigh_table;
86
0
  if (!hash)
87
0
    return num_neighs;
88
0
  for (i = 0; i < hash->size; i++) {
89
0
    for (hb = hash->index[i]; hb; hb = hb->next) {
90
0
      nbr = (struct zebra_neigh *)hb->data;
91
0
      if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
92
0
        num_neighs++;
93
0
    }
94
0
  }
95
96
0
  return num_neighs;
97
0
}
98
99
/*
100
 * Helper function to determine maximum width of neighbor IP address for
101
 * display - just because we're dealing with IPv6 addresses that can
102
 * widely vary.
103
 */
104
void zebra_evpn_find_neigh_addr_width(struct hash_bucket *bucket, void *ctxt)
105
0
{
106
0
  struct zebra_neigh *n;
107
0
  char buf[INET6_ADDRSTRLEN];
108
0
  struct neigh_walk_ctx *wctx = ctxt;
109
0
  int width;
110
111
0
  n = (struct zebra_neigh *)bucket->data;
112
113
0
  ipaddr2str(&n->ip, buf, sizeof(buf));
114
0
  width = strlen(buf);
115
0
  if (width > wctx->addr_width)
116
0
    wctx->addr_width = width;
117
0
}
118
119
/*
120
 * Count of remote neighbors referencing this MAC.
121
 */
122
int remote_neigh_count(struct zebra_mac *zmac)
123
0
{
124
0
  struct zebra_neigh *n = NULL;
125
0
  struct listnode *node = NULL;
126
0
  int count = 0;
127
128
0
  for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
129
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
130
0
      count++;
131
0
  }
132
133
0
  return count;
134
0
}
135
136
/*
137
 * Install remote neighbor into the kernel.
138
 */
139
int zebra_evpn_rem_neigh_install(struct zebra_evpn *zevpn,
140
         struct zebra_neigh *n, bool was_static)
141
0
{
142
0
  struct interface *vlan_if;
143
0
  int flags;
144
0
  int ret = 0;
145
146
0
  if (!(n->flags & ZEBRA_NEIGH_REMOTE))
147
0
    return 0;
148
149
0
  vlan_if = zevpn_map_to_svi(zevpn);
150
0
  if (!vlan_if)
151
0
    return -1;
152
153
0
  flags = DPLANE_NTF_EXT_LEARNED;
154
0
  if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
155
0
    flags |= DPLANE_NTF_ROUTER;
156
0
  ZEBRA_NEIGH_SET_ACTIVE(n);
157
158
0
  dplane_rem_neigh_add(vlan_if, &n->ip, &n->emac, flags, was_static);
159
160
0
  return ret;
161
0
}
162
163
/*
164
 * Install neighbor hash entry - called upon access VLAN change.
165
 */
166
void zebra_evpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt)
167
0
{
168
0
  struct zebra_neigh *n;
169
0
  struct neigh_walk_ctx *wctx = ctxt;
170
171
0
  n = (struct zebra_neigh *)bucket->data;
172
173
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
174
0
    zebra_evpn_rem_neigh_install(wctx->zevpn, n,
175
0
               false /*was_static*/);
176
0
}
177
178
/*
179
 * Callback to allocate neighbor hash entry.
180
 */
181
static void *zebra_evpn_neigh_alloc(void *p)
182
0
{
183
0
  const struct zebra_neigh *tmp_n = p;
184
0
  struct zebra_neigh *n;
185
186
0
  n = XCALLOC(MTYPE_NEIGH, sizeof(struct zebra_neigh));
187
0
  *n = *tmp_n;
188
189
0
  return ((void *)n);
190
0
}
191
192
static void zebra_evpn_local_neigh_ref_mac(struct zebra_neigh *n,
193
             const struct ethaddr *macaddr,
194
             struct zebra_mac *mac,
195
             bool send_mac_update)
196
0
{
197
0
  bool old_static;
198
0
  bool new_static;
199
200
0
  memcpy(&n->emac, macaddr, ETH_ALEN);
201
0
  n->mac = mac;
202
203
  /* Link to new MAC */
204
0
  if (!mac)
205
0
    return;
206
207
0
  listnode_add_sort(mac->neigh_list, n);
208
0
  if (n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) {
209
0
    old_static = zebra_evpn_mac_is_static(mac);
210
0
    ++mac->sync_neigh_cnt;
211
0
    new_static = zebra_evpn_mac_is_static(mac);
212
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
213
0
      zlog_debug(
214
0
        "sync-neigh ref mac vni %u ip %pIA mac %pEA ref %d",
215
0
        n->zevpn->vni, &n->ip, &n->emac,
216
0
        mac->sync_neigh_cnt);
217
0
    if ((old_static != new_static) && send_mac_update)
218
      /* program the local mac in the kernel */
219
0
      zebra_evpn_sync_mac_dp_install(
220
0
        mac, false /*set_inactive*/,
221
0
        false /*force_clear_static*/, __func__);
222
0
  }
223
0
}
224
225
/* sync-path that is active on an ES peer */
226
static void zebra_evpn_sync_neigh_dp_install(struct zebra_neigh *n,
227
               bool set_inactive,
228
               bool force_clear_static,
229
               const char *caller)
230
0
{
231
0
  struct zebra_ns *zns;
232
0
  struct interface *ifp;
233
0
  bool set_static;
234
0
  bool set_router;
235
236
0
  zns = zebra_ns_lookup(NS_DEFAULT);
237
0
  ifp = if_lookup_by_index_per_ns(zns, n->ifindex);
238
0
  if (!ifp) {
239
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
240
0
      zlog_debug(
241
0
        "%s: dp-install sync-neigh vni %u ip %pIA mac %pEA if %d f 0x%x skipped",
242
0
        caller, n->zevpn->vni, &n->ip, &n->emac,
243
0
        n->ifindex, n->flags);
244
0
    return;
245
0
  }
246
247
0
  if (force_clear_static)
248
0
    set_static = false;
249
0
  else
250
0
    set_static = zebra_evpn_neigh_is_static(n);
251
252
0
  set_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
253
254
  /* XXX - this will change post integration with the new kernel */
255
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
256
0
    set_inactive = true;
257
258
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
259
0
    zlog_debug(
260
0
      "%s: dp-install sync-neigh vni %u ip %pIA mac %pEA if %s(%d) f 0x%x%s%s%s",
261
0
      caller, n->zevpn->vni, &n->ip, &n->emac,
262
0
      ifp->name, n->ifindex, n->flags,
263
0
      set_router ? " router" : "",
264
0
      set_static ? " static" : "",
265
0
      set_inactive ? " inactive" : "");
266
0
  dplane_local_neigh_add(ifp, &n->ip, &n->emac, set_router, set_static,
267
0
             set_inactive);
268
0
}
269
270
/*
271
 * Inform BGP about local neighbor addition.
272
 */
273
int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip,
274
          const struct ethaddr *macaddr,
275
          struct zebra_mac *zmac,
276
          uint32_t neigh_flags, uint32_t seq)
277
0
{
278
0
  uint8_t flags = 0;
279
280
0
  if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
281
    /* host reachability has not been verified locally */
282
283
    /* if no ES peer is claiming reachability we can't advertise
284
     * the entry
285
     */
286
0
    if (!CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
287
0
      return 0;
288
289
    /* ES peers are claiming reachability; we will
290
     * advertise the entry but with a proxy flag
291
     */
292
0
    SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT);
293
0
  }
294
295
0
  if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
296
0
    SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
297
  /* Set router flag (R-bit) based on local neigh entry add */
298
0
  if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
299
0
    SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
300
0
  if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_SVI_IP))
301
0
    SET_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP);
302
303
0
  return zebra_evpn_macip_send_msg_to_client(vni, macaddr, ip, flags, seq,
304
0
               ZEBRA_NEIGH_ACTIVE, zmac->es,
305
0
               ZEBRA_MACIP_ADD);
306
0
}
307
308
/*
309
 * Inform BGP about local neighbor deletion.
310
 */
311
int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
312
          struct ethaddr *macaddr, uint32_t flags,
313
          int state, bool force)
314
0
{
315
0
  if (!force) {
316
0
    if (CHECK_FLAG(flags, ZEBRA_NEIGH_LOCAL_INACTIVE)
317
0
        && !CHECK_FLAG(flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
318
      /* the neigh was not advertised - nothing  to delete */
319
0
      return 0;
320
0
  }
321
322
0
  return zebra_evpn_macip_send_msg_to_client(
323
0
    vni, macaddr, ip, flags, 0, state, NULL, ZEBRA_MACIP_DEL);
324
0
}
325
326
static void zebra_evpn_neigh_send_add_del_to_client(struct zebra_neigh *n,
327
                bool old_bgp_ready,
328
                bool new_bgp_ready)
329
0
{
330
0
  if (new_bgp_ready)
331
0
    zebra_evpn_neigh_send_add_to_client(n->zevpn->vni, &n->ip,
332
0
                &n->emac, n->mac, n->flags,
333
0
                n->loc_seq);
334
0
  else if (old_bgp_ready)
335
0
    zebra_evpn_neigh_send_del_to_client(n->zevpn->vni, &n->ip,
336
0
                &n->emac, n->flags,
337
0
                n->state, true /*force*/);
338
0
}
339
340
/* if the static flag associated with the neigh changes we need
341
 * to update the sync-neigh references against the MAC
342
 * and inform the dataplane about the static flag changes.
343
 */
344
void zebra_evpn_sync_neigh_static_chg(struct zebra_neigh *n, bool old_n_static,
345
              bool new_n_static, bool defer_n_dp,
346
              bool defer_mac_dp, const char *caller)
347
0
{
348
0
  struct zebra_mac *mac = n->mac;
349
0
  bool old_mac_static;
350
0
  bool new_mac_static;
351
352
0
  if (old_n_static == new_n_static)
353
0
    return;
354
355
  /* update the neigh sync references in the dataplane. if
356
   * the neigh is in the middle of updates the caller can
357
   * request for a defer
358
   */
359
0
  if (!defer_n_dp)
360
0
    zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
361
0
             false /* force_clear_static */,
362
0
             __func__);
363
364
0
  if (!mac)
365
0
    return;
366
367
  /* update the mac sync ref cnt */
368
0
  old_mac_static = zebra_evpn_mac_is_static(mac);
369
0
  if (new_n_static) {
370
0
    ++mac->sync_neigh_cnt;
371
0
  } else if (old_n_static) {
372
0
    if (mac->sync_neigh_cnt)
373
0
      --mac->sync_neigh_cnt;
374
0
  }
375
0
  new_mac_static = zebra_evpn_mac_is_static(mac);
376
377
  /* update the mac sync references in the dataplane */
378
0
  if ((old_mac_static != new_mac_static) && !defer_mac_dp)
379
0
    zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
380
0
                 false /* force_clear_static */,
381
0
                 __func__);
382
383
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
384
0
    zlog_debug(
385
0
      "sync-neigh ref-chg vni %u ip %pIA mac %pEA f 0x%x %d%s%s%s%s by %s",
386
0
      n->zevpn->vni, &n->ip, &n->emac, n->flags,
387
0
      mac->sync_neigh_cnt,
388
0
      old_n_static ? " old_n_static" : "",
389
0
      new_n_static ? " new_n_static" : "",
390
0
      old_mac_static ? " old_mac_static" : "",
391
0
      new_mac_static ? " new_mac_static" : "", caller);
392
0
}
393
394
/* Neigh hold timer is used to age out peer-active flag.
395
 *
396
 * During this wait time we expect the dataplane component or an
397
 * external neighmgr daemon to probe existing hosts to independently
398
 * establish their presence on the ES.
399
 */
400
static void zebra_evpn_neigh_hold_exp_cb(struct event *t)
401
0
{
402
0
  struct zebra_neigh *n;
403
0
  bool old_bgp_ready;
404
0
  bool new_bgp_ready;
405
0
  bool old_n_static;
406
0
  bool new_n_static;
407
0
408
0
  n = EVENT_ARG(t);
409
0
  /* the purpose of the hold timer is to age out the peer-active
410
0
   * flag
411
0
   */
412
0
  if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
413
0
    return;
414
0
415
0
  old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
416
0
  old_n_static = zebra_evpn_neigh_is_static(n);
417
0
  UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
418
0
  new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
419
0
  new_n_static = zebra_evpn_neigh_is_static(n);
420
0
421
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
422
0
    zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x hold expired",
423
0
         n->zevpn->vni, &n->ip, &n->emac, n->flags);
424
0
425
0
  /* re-program the local neigh in the dataplane if the neigh is no
426
0
   * longer static
427
0
   */
428
0
  if (old_n_static != new_n_static)
429
0
    zebra_evpn_sync_neigh_static_chg(
430
0
      n, old_n_static, new_n_static, false /*defer_n_dp*/,
431
0
      false /*defer_mac_dp*/, __func__);
432
0
433
0
  /* inform bgp if needed */
434
0
  if (old_bgp_ready != new_bgp_ready)
435
0
    zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
436
0
              new_bgp_ready);
437
0
}
438
439
static inline void zebra_evpn_neigh_start_hold_timer(struct zebra_neigh *n)
440
0
{
441
0
  if (n->hold_timer)
442
0
    return;
443
444
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
445
0
    zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x hold start",
446
0
         n->zevpn->vni, &n->ip, &n->emac, n->flags);
447
0
  event_add_timer(zrouter.master, zebra_evpn_neigh_hold_exp_cb, n,
448
0
      zmh_info->neigh_hold_time, &n->hold_timer);
449
0
}
450
451
static void zebra_evpn_local_neigh_deref_mac(struct zebra_neigh *n,
452
               bool send_mac_update)
453
0
{
454
0
  struct zebra_mac *mac = n->mac;
455
0
  struct zebra_evpn *zevpn = n->zevpn;
456
0
  bool old_static;
457
0
  bool new_static;
458
459
0
  n->mac = NULL;
460
0
  if (!mac)
461
0
    return;
462
463
0
  if ((n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) && mac->sync_neigh_cnt) {
464
0
    old_static = zebra_evpn_mac_is_static(mac);
465
0
    --mac->sync_neigh_cnt;
466
0
    new_static = zebra_evpn_mac_is_static(mac);
467
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
468
0
      zlog_debug(
469
0
        "sync-neigh deref mac vni %u ip %pIA mac %pEA ref %d",
470
0
        n->zevpn->vni, &n->ip, &n->emac,
471
0
        mac->sync_neigh_cnt);
472
0
    if ((old_static != new_static) && send_mac_update)
473
      /* program the local mac in the kernel */
474
0
      zebra_evpn_sync_mac_dp_install(
475
0
        mac, false /* set_inactive */,
476
0
        false /* force_clear_static */, __func__);
477
0
  }
478
479
0
  listnode_delete(mac->neigh_list, n);
480
0
  zebra_evpn_deref_ip2mac(zevpn, mac);
481
0
}
482
483
bool zebra_evpn_neigh_is_bgp_seq_ok(struct zebra_evpn *zevpn,
484
            struct zebra_neigh *n,
485
            const struct ethaddr *macaddr, uint32_t seq,
486
            bool sync)
487
0
{
488
0
  uint32_t tmp_seq;
489
0
  const char *n_type;
490
0
  bool is_local = false;
491
492
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
493
0
    tmp_seq = n->loc_seq;
494
0
    n_type = "local";
495
0
    is_local = true;
496
0
  } else {
497
0
    tmp_seq = n->rem_seq;
498
0
    n_type = "remote";
499
0
  }
500
501
0
  if (seq < tmp_seq) {
502
0
    if (is_local && !zebra_evpn_neigh_is_ready_for_bgp(n)) {
503
0
      if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH ||
504
0
          IS_ZEBRA_DEBUG_VXLAN)
505
0
        zlog_debug(
506
0
          "%s-macip not ready vni %u %s mac %pEA IP %pIA lower seq %u f 0x%x",
507
0
          sync ? "sync" : "remote", zevpn->vni,
508
0
          n_type, macaddr, &n->ip, tmp_seq,
509
0
          n->flags);
510
0
      return true;
511
0
    }
512
513
    /* if the neigh was never advertised to bgp we must accept
514
     * whatever sequence number bgp sends
515
     */
516
0
    if (!is_local && zebra_vxlan_get_accept_bgp_seq()) {
517
0
      if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH
518
0
          || IS_ZEBRA_DEBUG_VXLAN)
519
0
        zlog_debug(
520
0
          "%s-macip accept vni %u %s mac %pEA IP %pIA lower seq %u f 0x%x",
521
0
          sync ? "sync" : "remote", zevpn->vni,
522
0
          n_type, macaddr, &n->ip,
523
0
          tmp_seq, n->flags);
524
0
      return true;
525
0
    }
526
527
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH || IS_ZEBRA_DEBUG_VXLAN)
528
0
      zlog_debug(
529
0
        "%s-macip ignore vni %u %s mac %pEA IP %pIA as existing has higher seq %u f 0x%x",
530
0
        sync ? "sync" : "remote", zevpn->vni, n_type,
531
0
        macaddr, &n->ip, tmp_seq, n->flags);
532
0
    return false;
533
0
  }
534
535
0
  return true;
536
0
}
537
538
/*
539
 * Add neighbor entry.
540
 */
541
static struct zebra_neigh *zebra_evpn_neigh_add(struct zebra_evpn *zevpn,
542
            const struct ipaddr *ip,
543
            const struct ethaddr *mac,
544
            struct zebra_mac *zmac,
545
            uint32_t n_flags)
546
0
{
547
0
  struct zebra_neigh tmp_n;
548
0
  struct zebra_neigh *n = NULL;
549
550
0
  memset(&tmp_n, 0, sizeof(tmp_n));
551
0
  memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
552
0
  n = hash_get(zevpn->neigh_table, &tmp_n, zebra_evpn_neigh_alloc);
553
554
0
  n->state = ZEBRA_NEIGH_INACTIVE;
555
0
  n->zevpn = zevpn;
556
0
  n->dad_ip_auto_recovery_timer = NULL;
557
0
  n->flags = n_flags;
558
0
  n->uptime = monotime(NULL);
559
560
0
  if (!zmac)
561
0
    zmac = zebra_evpn_mac_lookup(zevpn, mac);
562
0
  zebra_evpn_local_neigh_ref_mac(n, mac, zmac,
563
0
               false /* send_mac_update */);
564
565
0
  return n;
566
0
}
567
568
/*
569
 * Delete neighbor entry.
570
 */
571
int zebra_evpn_neigh_del(struct zebra_evpn *zevpn, struct zebra_neigh *n)
572
0
{
573
0
  struct zebra_neigh *tmp_n;
574
575
0
  if (n->mac)
576
0
    listnode_delete(n->mac->neigh_list, n);
577
578
  /* Cancel auto recovery */
579
0
  EVENT_OFF(n->dad_ip_auto_recovery_timer);
580
581
  /* Cancel proxy hold timer */
582
0
  zebra_evpn_neigh_stop_hold_timer(n);
583
584
  /* Free the VNI hash entry and allocated memory. */
585
0
  tmp_n = hash_release(zevpn->neigh_table, n);
586
0
  XFREE(MTYPE_NEIGH, tmp_n);
587
588
0
  return 0;
589
0
}
590
591
void zebra_evpn_sync_neigh_del(struct zebra_neigh *n)
592
0
{
593
0
  bool old_n_static;
594
0
  bool new_n_static;
595
596
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
597
0
    zlog_debug("sync-neigh del vni %u ip %pIA mac %pEA f 0x%x",
598
0
         n->zevpn->vni, &n->ip, &n->emac, n->flags);
599
600
0
  old_n_static = zebra_evpn_neigh_is_static(n);
601
0
  UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
602
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
603
0
    zebra_evpn_neigh_start_hold_timer(n);
604
0
  new_n_static = zebra_evpn_neigh_is_static(n);
605
606
0
  if (old_n_static != new_n_static)
607
0
    zebra_evpn_sync_neigh_static_chg(
608
0
      n, old_n_static, new_n_static, false /*defer-dp*/,
609
0
      false /*defer_mac_dp*/, __func__);
610
0
}
611
612
struct zebra_neigh *zebra_evpn_proc_sync_neigh_update(
613
  struct zebra_evpn *zevpn, struct zebra_neigh *n, uint16_t ipa_len,
614
  const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq,
615
  const esi_t *esi, struct zebra_mac *mac)
616
0
{
617
0
  struct interface *ifp = NULL;
618
0
  bool is_router;
619
0
  uint32_t tmp_seq;
620
0
  bool old_router = false;
621
0
  bool old_bgp_ready = false;
622
0
  bool new_bgp_ready;
623
0
  bool inform_dataplane = false;
624
0
  bool inform_bgp = false;
625
0
  bool old_mac_static;
626
0
  bool new_mac_static;
627
0
  bool set_dp_inactive = false;
628
0
  bool created;
629
0
  ifindex_t ifindex = 0;
630
631
  /* locate l3-svi */
632
0
  ifp = zevpn_map_to_svi(zevpn);
633
0
  if (ifp)
634
0
    ifindex = ifp->ifindex;
635
636
0
  is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
637
0
  old_mac_static = zebra_evpn_mac_is_static(mac);
638
639
0
  if (!n) {
640
0
    uint32_t n_flags = 0;
641
642
    /* New neighbor - create */
643
0
    SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL);
644
0
    if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
645
0
      SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_PROXY);
646
0
    else
647
0
      SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
648
0
    SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
649
650
0
    n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr, mac,
651
0
           n_flags);
652
0
    n->ifindex = ifindex;
653
0
    ZEBRA_NEIGH_SET_ACTIVE(n);
654
655
0
    created = true;
656
0
    inform_dataplane = true;
657
0
    inform_bgp = true;
658
0
    set_dp_inactive = true;
659
0
  } else {
660
0
    bool mac_change;
661
0
    uint32_t old_flags = n->flags;
662
0
    bool old_n_static;
663
0
    bool new_n_static;
664
665
0
    created = false;
666
0
    old_n_static = zebra_evpn_neigh_is_static(n);
667
0
    old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
668
0
    old_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
669
670
0
    mac_change = !!memcmp(&n->emac, &mac->macaddr, ETH_ALEN);
671
672
    /* deref and clear old info */
673
0
    if (mac_change) {
674
0
      if (old_bgp_ready) {
675
0
        zebra_evpn_neigh_send_del_to_client(
676
0
          zevpn->vni, &n->ip, &n->emac, n->flags,
677
0
          n->state, false /*force*/);
678
0
        old_bgp_ready = false;
679
0
      }
680
0
      zebra_evpn_local_neigh_deref_mac(n,
681
0
               false /*send_mac_update*/);
682
0
    }
683
    /* clear old fwd info */
684
0
    n->rem_seq = 0;
685
0
    n->r_vtep_ip.s_addr = 0;
686
687
    /* setup new flags */
688
0
    n->flags = 0;
689
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
690
    /* retain activity flag if the neigh was
691
     * previously local
692
     */
693
0
    if (old_flags & ZEBRA_NEIGH_LOCAL) {
694
0
      n->flags |= (old_flags & ZEBRA_NEIGH_LOCAL_INACTIVE);
695
0
    } else {
696
0
      inform_dataplane = true;
697
0
      set_dp_inactive = true;
698
0
      n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
699
0
    }
700
701
0
    if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
702
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
703
      /* if the neigh was peer-active previously we
704
       * need to keep the flag and start the
705
       * holdtimer on it. the peer-active flag is
706
       * cleared on holdtimer expiry.
707
       */
708
0
      if (CHECK_FLAG(old_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
709
0
        SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
710
0
        zebra_evpn_neigh_start_hold_timer(n);
711
0
      }
712
0
    } else {
713
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
714
      /* stop hold timer if a peer has verified
715
       * reachability
716
       */
717
0
      zebra_evpn_neigh_stop_hold_timer(n);
718
0
    }
719
0
    ZEBRA_NEIGH_SET_ACTIVE(n);
720
721
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH && (old_flags != n->flags))
722
0
      zlog_debug(
723
0
        "sync-neigh vni %u ip %pIA mac %pEA old_f 0x%x new_f 0x%x",
724
0
        n->zevpn->vni, &n->ip, &n->emac,
725
0
        old_flags, n->flags);
726
727
0
    new_n_static = zebra_evpn_neigh_is_static(n);
728
0
    if (mac_change) {
729
0
      set_dp_inactive = true;
730
0
      n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
731
0
      inform_dataplane = true;
732
0
      zebra_evpn_local_neigh_ref_mac(
733
0
        n, &mac->macaddr, mac,
734
0
        false /*send_mac_update*/);
735
0
    } else if (old_n_static != new_n_static) {
736
0
      inform_dataplane = true;
737
      /* if static flags have changed without a mac change
738
       * we need to create the correct sync-refs against
739
       * the existing mac
740
       */
741
0
      zebra_evpn_sync_neigh_static_chg(
742
0
        n, old_n_static, new_n_static,
743
0
        true /*defer_dp*/, true /*defer_mac_dp*/,
744
0
        __func__);
745
0
    }
746
747
    /* Update the forwarding info. */
748
0
    if (n->ifindex != ifindex) {
749
0
      n->ifindex = ifindex;
750
0
      inform_dataplane = true;
751
0
    }
752
753
0
    n->uptime = monotime(NULL);
754
0
  }
755
756
  /* update the neigh seq. we don't bother with the mac seq as
757
   * sync_mac_update already took care of that
758
   */
759
0
  tmp_seq = MAX(n->loc_seq, seq);
760
0
  if (tmp_seq != n->loc_seq) {
761
0
    n->loc_seq = tmp_seq;
762
0
    inform_bgp = true;
763
0
  }
764
765
  /* Mark Router flag (R-bit) */
766
0
  if (is_router)
767
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
768
0
  else
769
0
    UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
770
771
0
  if (old_router != is_router)
772
0
    inform_dataplane = true;
773
774
0
  new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
775
0
  if (old_bgp_ready != new_bgp_ready)
776
0
    inform_bgp = true;
777
778
0
  new_mac_static = zebra_evpn_mac_is_static(mac);
779
0
  if (old_mac_static != new_mac_static)
780
0
    zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
781
0
                 false /* force_clear_static */,
782
0
                 __func__);
783
784
0
  if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
785
0
    zlog_debug(
786
0
      "sync-neigh %s vni %u ip %pIA mac %pEA if %s(%d) seq %d f 0x%x%s%s",
787
0
      created ? "created" : "updated", n->zevpn->vni,
788
0
      &n->ip, &n->emac,
789
0
      ifp ? ifp->name : "", ifindex, n->loc_seq, n->flags,
790
0
      inform_bgp ? " inform_bgp" : "",
791
0
      inform_dataplane ? " inform_dp" : "");
792
793
0
  if (inform_dataplane)
794
0
    zebra_evpn_sync_neigh_dp_install(n, set_dp_inactive,
795
0
             false /* force_clear_static */,
796
0
             __func__);
797
798
0
  if (inform_bgp)
799
0
    zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
800
0
              new_bgp_ready);
801
802
0
  return n;
803
0
}
804
805
/*
806
 * Uninstall remote neighbor from the kernel.
807
 */
808
static int zebra_evpn_neigh_uninstall(struct zebra_evpn *zevpn,
809
              struct zebra_neigh *n)
810
0
{
811
0
  struct interface *vlan_if;
812
813
0
  if (!(n->flags & ZEBRA_NEIGH_REMOTE))
814
0
    return 0;
815
816
0
  vlan_if = zevpn_map_to_svi(zevpn);
817
0
  if (!vlan_if)
818
0
    return -1;
819
820
0
  ZEBRA_NEIGH_SET_INACTIVE(n);
821
0
  n->loc_seq = 0;
822
823
0
  dplane_rem_neigh_delete(vlan_if, &n->ip);
824
825
0
  return 0;
826
0
}
827
828
/*
829
 * Free neighbor hash entry (callback)
830
 */
831
static void zebra_evpn_neigh_del_hash_entry(struct hash_bucket *bucket,
832
              void *arg)
833
0
{
834
0
  struct neigh_walk_ctx *wctx = arg;
835
0
  struct zebra_neigh *n = bucket->data;
836
837
0
  if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
838
0
      || ((wctx->flags & DEL_REMOTE_NEIGH)
839
0
    && (n->flags & ZEBRA_NEIGH_REMOTE))
840
0
      || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
841
0
    && (n->flags & ZEBRA_NEIGH_REMOTE)
842
0
    && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
843
0
    if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
844
0
      zebra_evpn_neigh_send_del_to_client(
845
0
        wctx->zevpn->vni, &n->ip, &n->emac, n->flags,
846
0
        n->state, false /*force*/);
847
848
0
    if (wctx->uninstall) {
849
0
      if (zebra_evpn_neigh_is_static(n))
850
0
        zebra_evpn_sync_neigh_dp_install(
851
0
          n, false /* set_inactive */,
852
0
          true /* force_clear_static */,
853
0
          __func__);
854
0
      if ((n->flags & ZEBRA_NEIGH_REMOTE))
855
0
        zebra_evpn_neigh_uninstall(wctx->zevpn, n);
856
0
    }
857
858
0
    zebra_evpn_neigh_del(wctx->zevpn, n);
859
0
  }
860
861
0
  return;
862
0
}
863
864
/*
865
 * Delete all neighbor entries for this EVPN.
866
 */
867
void zebra_evpn_neigh_del_all(struct zebra_evpn *zevpn, int uninstall,
868
            int upd_client, uint32_t flags)
869
0
{
870
0
  struct neigh_walk_ctx wctx;
871
872
0
  if (!zevpn->neigh_table)
873
0
    return;
874
875
0
  memset(&wctx, 0, sizeof(wctx));
876
0
  wctx.zevpn = zevpn;
877
0
  wctx.uninstall = uninstall;
878
0
  wctx.upd_client = upd_client;
879
0
  wctx.flags = flags;
880
881
0
  hash_iterate(zevpn->neigh_table, zebra_evpn_neigh_del_hash_entry,
882
0
         &wctx);
883
0
}
884
885
/*
886
 * Look up neighbor hash entry.
887
 */
888
struct zebra_neigh *zebra_evpn_neigh_lookup(struct zebra_evpn *zevpn,
889
              const struct ipaddr *ip)
890
0
{
891
0
  struct zebra_neigh tmp;
892
0
  struct zebra_neigh *n;
893
894
0
  memset(&tmp, 0, sizeof(tmp));
895
0
  memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
896
0
  n = hash_lookup(zevpn->neigh_table, &tmp);
897
898
0
  return n;
899
0
}
900
901
/*
902
 * Process all neighbors associated with a MAC upon the MAC being learnt
903
 * locally or undergoing any other change (such as sequence number).
904
 */
905
void zebra_evpn_process_neigh_on_local_mac_change(struct zebra_evpn *zevpn,
906
              struct zebra_mac *zmac,
907
              bool seq_change,
908
              bool es_change)
909
0
{
910
0
  struct zebra_neigh *n = NULL;
911
0
  struct listnode *node = NULL;
912
0
  struct zebra_vrf *zvrf = NULL;
913
914
0
  zvrf = zevpn->vxlan_if->vrf->info;
915
916
0
  if (IS_ZEBRA_DEBUG_VXLAN)
917
0
    zlog_debug("Processing neighbors on local MAC %pEA %s, VNI %u",
918
0
         &zmac->macaddr, seq_change ? "CHANGE" : "ADD",
919
0
         zevpn->vni);
920
921
  /* Walk all neighbors and mark any inactive local neighbors as
922
   * active and/or update sequence number upon a move, and inform BGP.
923
   * The action for remote neighbors is TBD.
924
   * NOTE: We can't simply uninstall remote neighbors as the kernel may
925
   * accidentally end up deleting a just-learnt local neighbor.
926
   */
927
0
  for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
928
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
929
0
      if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change
930
0
          || es_change) {
931
0
        ZEBRA_NEIGH_SET_ACTIVE(n);
932
0
        n->loc_seq = zmac->loc_seq;
933
0
        if (!(zebra_evpn_do_dup_addr_detect(zvrf)
934
0
              && zvrf->dad_freeze
935
0
              && !!CHECK_FLAG(n->flags,
936
0
                  ZEBRA_NEIGH_DUPLICATE)))
937
0
          zebra_evpn_neigh_send_add_to_client(
938
0
            zevpn->vni, &n->ip, &n->emac,
939
0
            n->mac, n->flags, n->loc_seq);
940
0
      }
941
0
    }
942
0
  }
943
0
}
944
945
/*
946
 * Process all neighbors associated with a local MAC upon the MAC being
947
 * deleted.
948
 */
949
void zebra_evpn_process_neigh_on_local_mac_del(struct zebra_evpn *zevpn,
950
                 struct zebra_mac *zmac)
951
0
{
952
0
  struct zebra_neigh *n = NULL;
953
0
  struct listnode *node = NULL;
954
955
0
  if (IS_ZEBRA_DEBUG_VXLAN)
956
0
    zlog_debug("Processing neighbors on local MAC %pEA DEL, VNI %u",
957
0
         &zmac->macaddr, zevpn->vni);
958
959
  /* Walk all local neighbors and mark as inactive and inform
960
   * BGP, if needed.
961
   * TBD: There is currently no handling for remote neighbors. We
962
   * don't expect them to exist, if they do, do we install the MAC
963
   * as a remote MAC and the neighbor as remote?
964
   */
965
0
  for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
966
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
967
0
      if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
968
0
        ZEBRA_NEIGH_SET_INACTIVE(n);
969
0
        n->loc_seq = 0;
970
0
        zebra_evpn_neigh_send_del_to_client(
971
0
          zevpn->vni, &n->ip, &n->emac, n->flags,
972
0
          ZEBRA_NEIGH_ACTIVE, false /*force*/);
973
0
      }
974
0
    }
975
0
  }
976
0
}
977
978
/*
979
 * Process all neighbors associated with a MAC upon the MAC being remotely
980
 * learnt.
981
 */
982
void zebra_evpn_process_neigh_on_remote_mac_add(struct zebra_evpn *zevpn,
983
            struct zebra_mac *zmac)
984
0
{
985
0
  struct zebra_neigh *n = NULL;
986
0
  struct listnode *node = NULL;
987
988
0
  if (IS_ZEBRA_DEBUG_VXLAN)
989
0
    zlog_debug("Processing neighbors on remote MAC %pEA ADD, VNI %u",
990
0
         &zmac->macaddr, zevpn->vni);
991
992
  /* Walk all local neighbors and mark as inactive and inform
993
   * BGP, if needed.
994
   */
995
0
  for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
996
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
997
0
      if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
998
0
        ZEBRA_NEIGH_SET_INACTIVE(n);
999
0
        n->loc_seq = 0;
1000
0
        zebra_evpn_neigh_send_del_to_client(
1001
0
          zevpn->vni, &n->ip, &n->emac, n->flags,
1002
0
          ZEBRA_NEIGH_ACTIVE, false /* force */);
1003
0
      }
1004
0
    }
1005
0
  }
1006
0
}
1007
1008
/*
1009
 * Process all neighbors associated with a remote MAC upon the MAC being
1010
 * deleted.
1011
 */
1012
void zebra_evpn_process_neigh_on_remote_mac_del(struct zebra_evpn *zevpn,
1013
            struct zebra_mac *zmac)
1014
0
{
1015
  /* NOTE: Currently a NO-OP. */
1016
0
}
1017
1018
static inline void zebra_evpn_local_neigh_update_log(
1019
  const char *pfx, struct zebra_neigh *n, bool is_router,
1020
  bool local_inactive, bool old_bgp_ready, bool new_bgp_ready,
1021
  bool inform_dataplane, bool inform_bgp, const char *sfx)
1022
0
{
1023
0
  if (!IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
1024
0
    return;
1025
1026
0
  zlog_debug("%s neigh vni %u ip %pIA mac %pEA f 0x%x%s%s%s%s%s%s %s", pfx,
1027
0
       n->zevpn->vni, &n->ip, &n->emac, n->flags,
1028
0
       is_router ? " router" : "",
1029
0
       local_inactive ? " local-inactive" : "",
1030
0
       old_bgp_ready ? " old_bgp_ready" : "",
1031
0
       new_bgp_ready ? " new_bgp_ready" : "",
1032
0
       inform_dataplane ? " inform_dp" : "",
1033
0
       inform_bgp ? " inform_bgp" : "", sfx);
1034
0
}
1035
1036
/* As part Duplicate Address Detection (DAD) for IP mobility
1037
 * MAC binding changes, ensure to inherit duplicate flag
1038
 * from MAC.
1039
 */
1040
static int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
1041
                struct zebra_mac *old_zmac,
1042
                struct zebra_mac *new_zmac,
1043
                struct zebra_neigh *nbr)
1044
0
{
1045
0
  bool is_old_mac_dup = false;
1046
0
  bool is_new_mac_dup = false;
1047
1048
0
  if (!zebra_evpn_do_dup_addr_detect(zvrf))
1049
0
    return 0;
1050
  /* Check old or new MAC is detected as duplicate
1051
   * mark this neigh as duplicate
1052
   */
1053
0
  if (old_zmac)
1054
0
    is_old_mac_dup =
1055
0
      CHECK_FLAG(old_zmac->flags, ZEBRA_MAC_DUPLICATE);
1056
0
  if (new_zmac)
1057
0
    is_new_mac_dup =
1058
0
      CHECK_FLAG(new_zmac->flags, ZEBRA_MAC_DUPLICATE);
1059
  /* Old and/or new MAC can be in duplicate state,
1060
   * based on that IP/Neigh Inherits the flag.
1061
   * If New MAC is marked duplicate, inherit to the IP.
1062
   * If old MAC is duplicate but new MAC is not, clear
1063
   * duplicate flag for IP and reset detection params
1064
   * and let IP DAD retrigger.
1065
   */
1066
0
  if (is_new_mac_dup && !CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1067
0
    SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1068
    /* Capture Duplicate detection time */
1069
0
    nbr->dad_dup_detect_time = monotime(NULL);
1070
    /* Mark neigh inactive */
1071
0
    ZEBRA_NEIGH_SET_INACTIVE(nbr);
1072
1073
0
    return 1;
1074
0
  } else if (is_old_mac_dup && !is_new_mac_dup) {
1075
0
    UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1076
0
    nbr->dad_count = 0;
1077
0
    nbr->detect_start_time.tv_sec = 0;
1078
0
    nbr->detect_start_time.tv_usec = 0;
1079
0
  }
1080
0
  return 0;
1081
0
}
1082
1083
static void zebra_evpn_dad_ip_auto_recovery_exp(struct event *t)
1084
0
{
1085
0
  struct zebra_vrf *zvrf = NULL;
1086
0
  struct zebra_neigh *nbr = NULL;
1087
0
  struct zebra_evpn *zevpn = NULL;
1088
0
1089
0
  nbr = EVENT_ARG(t);
1090
0
1091
0
  /* since this is asynchronous we need sanity checks*/
1092
0
  zvrf = vrf_info_lookup(nbr->zevpn->vrf_id);
1093
0
  if (!zvrf)
1094
0
    return;
1095
0
1096
0
  zevpn = zebra_evpn_lookup(nbr->zevpn->vni);
1097
0
  if (!zevpn)
1098
0
    return;
1099
0
1100
0
  nbr = zebra_evpn_neigh_lookup(zevpn, &nbr->ip);
1101
0
  if (!nbr)
1102
0
    return;
1103
0
1104
0
  if (IS_ZEBRA_DEBUG_VXLAN)
1105
0
    zlog_debug(
1106
0
      "%s: duplicate addr MAC %pEA IP %pIA flags 0x%x learn count %u vni %u auto recovery expired",
1107
0
      __func__, &nbr->emac, &nbr->ip, nbr->flags,
1108
0
      nbr->dad_count, zevpn->vni);
1109
0
1110
0
  UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1111
0
  nbr->dad_count = 0;
1112
0
  nbr->detect_start_time.tv_sec = 0;
1113
0
  nbr->detect_start_time.tv_usec = 0;
1114
0
  nbr->dad_dup_detect_time = 0;
1115
0
  nbr->dad_ip_auto_recovery_timer = NULL;
1116
0
  ZEBRA_NEIGH_SET_ACTIVE(nbr);
1117
0
1118
0
  /* Send to BGP */
1119
0
  if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1120
0
    zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1121
0
                &nbr->emac, nbr->mac,
1122
0
                nbr->flags, nbr->loc_seq);
1123
0
  } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1124
0
    zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1125
0
  }
1126
0
}
1127
1128
static void zebra_evpn_dup_addr_detect_for_neigh(
1129
  struct zebra_vrf *zvrf, struct zebra_neigh *nbr, struct in_addr vtep_ip,
1130
  bool do_dad, bool *is_dup_detect, bool is_local)
1131
0
{
1132
1133
0
  struct timeval elapsed = {0, 0};
1134
0
  bool reset_params = false;
1135
1136
0
  if (!zebra_evpn_do_dup_addr_detect(zvrf))
1137
0
    return;
1138
1139
  /* IP is detected as duplicate or inherit dup
1140
   * state, hold on to install as remote entry
1141
   * only if freeze is enabled.
1142
   */
1143
0
  if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1144
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1145
0
      zlog_debug(
1146
0
        "%s: duplicate addr MAC %pEA IP %pIA flags 0x%x skip installing, learn count %u recover time %u",
1147
0
        __func__, &nbr->emac, &nbr->ip,
1148
0
        nbr->flags, nbr->dad_count,
1149
0
        zvrf->dad_freeze_time);
1150
1151
0
    if (zvrf->dad_freeze)
1152
0
      *is_dup_detect = true;
1153
1154
    /* warn-only action, neigh will be installed.
1155
     * freeze action, it wil not be installed.
1156
     */
1157
0
    return;
1158
0
  }
1159
1160
0
  if (!do_dad)
1161
0
    return;
1162
1163
  /* Check if detection time (M-secs) expired.
1164
   * Reset learn count and detection start time.
1165
   * During remote mac add, count should already be 1
1166
   * via local learning.
1167
   */
1168
0
  monotime_since(&nbr->detect_start_time, &elapsed);
1169
0
  reset_params = (elapsed.tv_sec > zvrf->dad_time);
1170
1171
0
  if (is_local && !reset_params) {
1172
    /* RFC-7432: A PE/VTEP that detects a MAC mobility
1173
     * event via LOCAL learning starts an M-second timer.
1174
     *
1175
     * NOTE: This is the START of the probe with count is
1176
     * 0 during LOCAL learn event.
1177
     */
1178
0
    reset_params = !nbr->dad_count;
1179
0
  }
1180
1181
0
  if (reset_params) {
1182
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1183
0
      zlog_debug(
1184
0
        "%s: duplicate addr MAC %pEA IP %pIA flags 0x%x detection time passed, reset learn count %u",
1185
0
        __func__, &nbr->emac, &nbr->ip,
1186
0
        nbr->flags, nbr->dad_count);
1187
    /* Reset learn count but do not start detection
1188
     * during REMOTE learn event.
1189
     */
1190
0
    nbr->dad_count = 0;
1191
    /* Start dup. addr detection (DAD) start time,
1192
     * ONLY during LOCAL learn.
1193
     */
1194
0
    if (is_local)
1195
0
      monotime(&nbr->detect_start_time);
1196
1197
0
  } else if (!is_local) {
1198
    /* For REMOTE IP/Neigh, increment detection count
1199
     * ONLY while in probe window, once window passed,
1200
     * next local learn event should trigger DAD.
1201
     */
1202
0
    nbr->dad_count++;
1203
0
  }
1204
1205
  /* For LOCAL IP/Neigh learn event, once count is reset above via either
1206
   * initial/start detection time or passed the probe time, the count
1207
   * needs to be incremented.
1208
   */
1209
0
  if (is_local)
1210
0
    nbr->dad_count++;
1211
1212
0
  if (nbr->dad_count >= zvrf->dad_max_moves) {
1213
0
    flog_warn(
1214
0
      EC_ZEBRA_DUP_IP_DETECTED,
1215
0
      "VNI %u: MAC %pEA IP %pIA detected as duplicate during %s VTEP %pI4",
1216
0
      nbr->zevpn->vni, &nbr->emac, &nbr->ip,
1217
0
      is_local ? "local update, last" : "remote update, from",
1218
0
      &vtep_ip);
1219
1220
0
    SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1221
1222
    /* Capture Duplicate detection time */
1223
0
    nbr->dad_dup_detect_time = monotime(NULL);
1224
1225
    /* Start auto recovery timer for this IP */
1226
0
    EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
1227
0
    if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
1228
0
      if (IS_ZEBRA_DEBUG_VXLAN)
1229
0
        zlog_debug(
1230
0
          "%s: duplicate addr MAC %pEA IP %pIA flags 0x%x auto recovery time %u start",
1231
0
          __func__, &nbr->emac, &nbr->ip,
1232
0
          nbr->flags, zvrf->dad_freeze_time);
1233
1234
0
      event_add_timer(zrouter.master,
1235
0
          zebra_evpn_dad_ip_auto_recovery_exp,
1236
0
          nbr, zvrf->dad_freeze_time,
1237
0
          &nbr->dad_ip_auto_recovery_timer);
1238
0
    }
1239
0
    if (zvrf->dad_freeze)
1240
0
      *is_dup_detect = true;
1241
0
  }
1242
0
}
1243
1244
int zebra_evpn_local_neigh_update(struct zebra_evpn *zevpn,
1245
          struct interface *ifp,
1246
          const struct ipaddr *ip,
1247
          const struct ethaddr *macaddr, bool is_router,
1248
          bool local_inactive, bool dp_static)
1249
0
{
1250
0
  struct zebra_vrf *zvrf;
1251
0
  struct zebra_neigh *n = NULL;
1252
0
  struct zebra_mac *zmac = NULL, *old_zmac = NULL;
1253
0
  uint32_t old_mac_seq = 0, mac_new_seq = 0;
1254
0
  bool upd_mac_seq = false;
1255
0
  bool neigh_mac_change = false;
1256
0
  bool neigh_on_hold = false;
1257
0
  bool neigh_was_remote = false;
1258
0
  bool do_dad = false;
1259
0
  struct in_addr vtep_ip = {.s_addr = 0};
1260
0
  bool inform_dataplane = false;
1261
0
  bool created = false;
1262
0
  bool new_static = false;
1263
0
  bool old_bgp_ready = false;
1264
0
  bool new_bgp_ready;
1265
1266
  /* Check if the MAC exists. */
1267
0
  zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1268
0
  if (!zmac) {
1269
    /* create a dummy MAC if the MAC is not already present */
1270
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1271
0
      zlog_debug("AUTO MAC %pEA created for neigh %pIA on VNI %u",
1272
0
           macaddr, ip, zevpn->vni);
1273
1274
0
    zmac = zebra_evpn_mac_add_auto(zevpn, macaddr);
1275
0
    if (!zmac) {
1276
0
      zlog_debug("Failed to add MAC %pEA VNI %u", macaddr,
1277
0
           zevpn->vni);
1278
0
      return -1;
1279
0
    }
1280
0
  } else {
1281
0
    if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1282
      /*
1283
       * We don't change the MAC to local upon a neighbor
1284
       * learn event, we wait for the explicit local MAC
1285
       * learn. However, we have to compute its sequence
1286
       * number in preparation for when it actually turns
1287
       * local.
1288
       */
1289
0
      upd_mac_seq = true;
1290
0
    }
1291
0
  }
1292
1293
0
  zvrf = zevpn->vxlan_if->vrf->info;
1294
0
  if (!zvrf) {
1295
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1296
0
      zlog_debug("        Unable to find vrf for: %d",
1297
0
           zevpn->vxlan_if->vrf->vrf_id);
1298
0
    return -1;
1299
0
  }
1300
1301
  /* Check if the neighbor exists. */
1302
0
  n = zebra_evpn_neigh_lookup(zevpn, ip);
1303
0
  if (!n) {
1304
    /* New neighbor - create */
1305
0
    n = zebra_evpn_neigh_add(zevpn, ip, macaddr, zmac, 0);
1306
1307
    /* Set "local" forwarding info. */
1308
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1309
0
    n->ifindex = ifp->ifindex;
1310
0
    created = true;
1311
0
  } else {
1312
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1313
0
      bool mac_different;
1314
0
      bool cur_is_router;
1315
0
      bool old_local_inactive;
1316
1317
0
      old_local_inactive = !!CHECK_FLAG(
1318
0
        n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1319
1320
0
      old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1321
1322
      /* Note any changes and see if of interest to BGP. */
1323
0
      mac_different = !!memcmp(&n->emac, macaddr, ETH_ALEN);
1324
0
      cur_is_router =
1325
0
        !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1326
0
      new_static = zebra_evpn_neigh_is_static(n);
1327
0
      if (!mac_different && is_router == cur_is_router
1328
0
          && old_local_inactive == local_inactive
1329
0
          && dp_static != new_static) {
1330
0
        if (IS_ZEBRA_DEBUG_VXLAN)
1331
0
          zlog_debug(
1332
0
            "        Ignoring entry mac is the same and is_router == cur_is_router");
1333
0
        n->ifindex = ifp->ifindex;
1334
0
        return 0;
1335
0
      }
1336
1337
0
      old_zmac = n->mac;
1338
0
      if (!mac_different) {
1339
        /* XXX - cleanup this code duplication */
1340
0
        bool is_neigh_freezed = false;
1341
1342
        /* Only the router flag has changed. */
1343
0
        if (is_router)
1344
0
          SET_FLAG(n->flags,
1345
0
             ZEBRA_NEIGH_ROUTER_FLAG);
1346
0
        else
1347
0
          UNSET_FLAG(n->flags,
1348
0
               ZEBRA_NEIGH_ROUTER_FLAG);
1349
1350
0
        if (local_inactive)
1351
0
          SET_FLAG(n->flags,
1352
0
             ZEBRA_NEIGH_LOCAL_INACTIVE);
1353
0
        else
1354
0
          UNSET_FLAG(n->flags,
1355
0
               ZEBRA_NEIGH_LOCAL_INACTIVE);
1356
0
        new_bgp_ready =
1357
0
          zebra_evpn_neigh_is_ready_for_bgp(n);
1358
1359
0
        if (dp_static != new_static)
1360
0
          inform_dataplane = true;
1361
1362
        /* Neigh is in freeze state and freeze action
1363
         * is enabled, do not send update to client.
1364
         */
1365
0
        is_neigh_freezed =
1366
0
          (zebra_evpn_do_dup_addr_detect(zvrf)
1367
0
           && zvrf->dad_freeze
1368
0
           && CHECK_FLAG(n->flags,
1369
0
                   ZEBRA_NEIGH_DUPLICATE));
1370
1371
0
        zebra_evpn_local_neigh_update_log(
1372
0
          "local", n, is_router, local_inactive,
1373
0
          old_bgp_ready, new_bgp_ready, false,
1374
0
          false, "flag-update");
1375
1376
0
        if (inform_dataplane)
1377
0
          zebra_evpn_sync_neigh_dp_install(
1378
0
            n, false /* set_inactive */,
1379
0
            false /* force_clear_static */,
1380
0
            __func__);
1381
1382
        /* if the neigh can no longer be advertised
1383
         * remove it from bgp
1384
         */
1385
0
        if (!is_neigh_freezed) {
1386
0
          zebra_evpn_neigh_send_add_del_to_client(
1387
0
            n, old_bgp_ready,
1388
0
            new_bgp_ready);
1389
0
        } else {
1390
0
          if (IS_ZEBRA_DEBUG_VXLAN
1391
0
              && IS_ZEBRA_NEIGH_ACTIVE(n))
1392
0
            zlog_debug(
1393
0
              "        Neighbor active and frozen");
1394
0
        }
1395
0
        return 0;
1396
0
      }
1397
1398
      /* The MAC has changed, need to issue a delete
1399
       * first as this means a different MACIP route.
1400
       * Also, need to do some unlinking/relinking.
1401
       * We also need to update the MAC's sequence number
1402
       * in different situations.
1403
       */
1404
0
      if (old_bgp_ready) {
1405
0
        zebra_evpn_neigh_send_del_to_client(
1406
0
          zevpn->vni, &n->ip, &n->emac, n->flags,
1407
0
          n->state, false /*force*/);
1408
0
        old_bgp_ready = false;
1409
0
      }
1410
0
      if (old_zmac) {
1411
0
        old_mac_seq = CHECK_FLAG(old_zmac->flags,
1412
0
               ZEBRA_MAC_REMOTE)
1413
0
                  ? old_zmac->rem_seq
1414
0
                  : old_zmac->loc_seq;
1415
0
        neigh_mac_change = upd_mac_seq = true;
1416
0
        zebra_evpn_local_neigh_deref_mac(
1417
0
          n, true /* send_mac_update */);
1418
0
      }
1419
1420
      /* if mac changes abandon peer flags and tell
1421
       * dataplane to clear the static flag
1422
       */
1423
0
      if (zebra_evpn_neigh_clear_sync_info(n))
1424
0
        inform_dataplane = true;
1425
      /* Update the forwarding info. */
1426
0
      n->ifindex = ifp->ifindex;
1427
1428
      /* Link to new MAC */
1429
0
      zebra_evpn_local_neigh_ref_mac(
1430
0
        n, macaddr, zmac, true /* send_mac_update */);
1431
0
    } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1432
      /*
1433
       * Neighbor has moved from remote to local. Its
1434
       * MAC could have also changed as part of the move.
1435
       */
1436
0
      if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN)
1437
0
          != 0) {
1438
0
        old_zmac = n->mac;
1439
0
        if (old_zmac) {
1440
0
          old_mac_seq =
1441
0
            CHECK_FLAG(old_zmac->flags,
1442
0
                 ZEBRA_MAC_REMOTE)
1443
0
              ? old_zmac->rem_seq
1444
0
              : old_zmac->loc_seq;
1445
0
          neigh_mac_change = upd_mac_seq = true;
1446
0
          zebra_evpn_local_neigh_deref_mac(
1447
0
            n, true /* send_update */);
1448
0
        }
1449
1450
        /* Link to new MAC */
1451
0
        zebra_evpn_local_neigh_ref_mac(
1452
0
          n, macaddr, zmac, true /*send_update*/);
1453
0
      }
1454
      /* Based on Mobility event Scenario-B from the
1455
       * draft, neigh's previous state was remote treat this
1456
       * event for DAD.
1457
       */
1458
0
      neigh_was_remote = true;
1459
0
      vtep_ip = n->r_vtep_ip;
1460
      /* Mark appropriately */
1461
0
      UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1462
0
      n->r_vtep_ip.s_addr = INADDR_ANY;
1463
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1464
0
      n->ifindex = ifp->ifindex;
1465
0
    }
1466
0
  }
1467
1468
  /* If MAC was previously remote, or the neighbor had a different
1469
   * MAC earlier, recompute the sequence number.
1470
   */
1471
0
  if (upd_mac_seq) {
1472
0
    uint32_t seq1, seq2;
1473
1474
0
    seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)
1475
0
             ? zmac->rem_seq + 1
1476
0
             : zmac->loc_seq;
1477
0
    seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
1478
0
    mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ? MAX(seq1, seq2)
1479
0
                    : zmac->loc_seq;
1480
0
  }
1481
1482
0
  if (local_inactive)
1483
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1484
0
  else
1485
0
    UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1486
1487
  /* Mark Router flag (R-bit) */
1488
0
  if (is_router)
1489
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1490
0
  else
1491
0
    UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1492
1493
  /* if zebra and dataplane don't agree this is a sync entry
1494
   * re-install in the dataplane */
1495
0
  new_static = zebra_evpn_neigh_is_static(n);
1496
0
  if (dp_static != new_static)
1497
0
    inform_dataplane = true;
1498
1499
  /* Check old and/or new MAC detected as duplicate mark
1500
   * the neigh as duplicate
1501
   */
1502
0
  if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
1503
0
    flog_warn(
1504
0
      EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
1505
0
      "VNI %u: MAC %pEA IP %pIA detected as duplicate during local update, inherit duplicate from MAC",
1506
0
      zevpn->vni, macaddr, &n->ip);
1507
0
  }
1508
1509
  /* For IP Duplicate Address Detection (DAD) is trigger,
1510
   * when the event is extended mobility based on scenario-B
1511
   * from the draft, IP/Neigh's MAC binding changed and
1512
   * neigh's previous state was remote.
1513
   */
1514
0
  if (neigh_mac_change && neigh_was_remote)
1515
0
    do_dad = true;
1516
1517
0
  zebra_evpn_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
1518
0
               &neigh_on_hold, true);
1519
1520
0
  if (inform_dataplane)
1521
0
    zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
1522
0
             false /* force_clear_static */,
1523
0
             __func__);
1524
1525
  /* Before we program this in BGP, we need to check if MAC is locally
1526
   * learnt. If not, force neighbor to be inactive and reset its seq.
1527
   */
1528
0
  if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
1529
0
    zebra_evpn_local_neigh_update_log(
1530
0
      "local", n, is_router, local_inactive, false, false,
1531
0
      inform_dataplane, false, "auto-mac");
1532
0
    ZEBRA_NEIGH_SET_INACTIVE(n);
1533
0
    n->loc_seq = 0;
1534
0
    zmac->loc_seq = mac_new_seq;
1535
0
    return 0;
1536
0
  }
1537
1538
0
  zebra_evpn_local_neigh_update_log("local", n, is_router, local_inactive,
1539
0
            false, false, inform_dataplane, true,
1540
0
            created ? "created" : "updated");
1541
1542
  /* If the MAC's sequence number has changed, inform the MAC and all
1543
   * neighbors associated with the MAC to BGP, else just inform this
1544
   * neighbor.
1545
   */
1546
0
  if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
1547
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1548
0
      zlog_debug(
1549
0
        "Seq changed for MAC %pEA VNI %u - old %u new %u",
1550
0
        macaddr, zevpn->vni,
1551
0
        zmac->loc_seq, mac_new_seq);
1552
0
    zmac->loc_seq = mac_new_seq;
1553
0
    if (zebra_evpn_mac_send_add_to_client(zevpn->vni, macaddr,
1554
0
                  zmac->flags,
1555
0
                  zmac->loc_seq, zmac->es))
1556
0
      return -1;
1557
0
    zebra_evpn_process_neigh_on_local_mac_change(zevpn, zmac, 1,
1558
0
                   0 /*es_change*/);
1559
0
    return 0;
1560
0
  }
1561
1562
0
  n->loc_seq = zmac->loc_seq;
1563
1564
0
  if (!neigh_on_hold) {
1565
0
    ZEBRA_NEIGH_SET_ACTIVE(n);
1566
0
    new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1567
0
    zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
1568
0
              new_bgp_ready);
1569
0
  } else {
1570
0
    if (IS_ZEBRA_DEBUG_VXLAN)
1571
0
      zlog_debug("        Neighbor on hold not sending");
1572
0
  }
1573
0
  return 0;
1574
0
}
1575
1576
int zebra_evpn_remote_neigh_update(struct zebra_evpn *zevpn,
1577
           struct interface *ifp,
1578
           const struct ipaddr *ip,
1579
           const struct ethaddr *macaddr,
1580
           uint16_t state)
1581
0
{
1582
0
  struct zebra_neigh *n = NULL;
1583
0
  struct zebra_mac *zmac = NULL;
1584
1585
  /* If the neighbor is unknown, there is no further action. */
1586
0
  n = zebra_evpn_neigh_lookup(zevpn, ip);
1587
0
  if (!n)
1588
0
    return 0;
1589
1590
  /* If a remote entry, see if it needs to be refreshed */
1591
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1592
0
#ifdef GNU_LINUX
1593
0
    if (state & NUD_STALE)
1594
0
      zebra_evpn_rem_neigh_install(zevpn, n,
1595
0
                 false /*was_static*/);
1596
0
#endif
1597
0
  } else {
1598
    /* We got a "remote" neighbor notification for an entry
1599
     * we think is local. This can happen in a multihoming
1600
     * scenario - but only if the MAC is already "remote".
1601
     * Just mark our entry as "remote".
1602
     */
1603
0
    zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1604
0
    if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1605
0
      zlog_debug(
1606
0
        "Ignore remote neigh %pIA (MAC %pEA) on L2-VNI %u - MAC unknown or local",
1607
0
        &n->ip, macaddr, zevpn->vni);
1608
0
      return -1;
1609
0
    }
1610
1611
0
    UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
1612
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1613
0
    ZEBRA_NEIGH_SET_ACTIVE(n);
1614
0
    n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
1615
0
  }
1616
1617
0
  return 0;
1618
0
}
1619
1620
/* Notify Neighbor entries to the Client, skips the GW entry */
1621
static void
1622
zebra_evpn_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
1623
             void *arg)
1624
0
{
1625
0
  struct mac_walk_ctx *wctx = arg;
1626
0
  struct zebra_neigh *zn = bucket->data;
1627
0
  struct zebra_mac *zmac = NULL;
1628
1629
0
  if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
1630
0
    return;
1631
1632
0
  if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL)
1633
0
      && IS_ZEBRA_NEIGH_ACTIVE(zn)) {
1634
0
    zmac = zebra_evpn_mac_lookup(wctx->zevpn, &zn->emac);
1635
0
    if (!zmac)
1636
0
      return;
1637
1638
0
    zebra_evpn_neigh_send_add_to_client(wctx->zevpn->vni, &zn->ip,
1639
0
                &zn->emac, zn->mac,
1640
0
                zn->flags, zn->loc_seq);
1641
0
  }
1642
0
}
1643
1644
/* Iterator of a specific EVPN */
1645
void zebra_evpn_send_neigh_to_client(struct zebra_evpn *zevpn)
1646
0
{
1647
0
  struct neigh_walk_ctx wctx;
1648
1649
0
  memset(&wctx, 0, sizeof(wctx));
1650
0
  wctx.zevpn = zevpn;
1651
1652
0
  hash_iterate(zevpn->neigh_table,
1653
0
         zebra_evpn_send_neigh_hash_entry_to_client, &wctx);
1654
0
}
1655
1656
void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1657
0
{
1658
0
  struct neigh_walk_ctx *wctx = ctxt;
1659
0
  struct zebra_neigh *nbr;
1660
0
  struct zebra_evpn *zevpn;
1661
0
  char buf[INET6_ADDRSTRLEN];
1662
1663
0
  nbr = (struct zebra_neigh *)bucket->data;
1664
0
  if (!nbr)
1665
0
    return;
1666
1667
0
  zevpn = wctx->zevpn;
1668
1669
0
  if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
1670
0
    return;
1671
1672
0
  if (IS_ZEBRA_DEBUG_VXLAN) {
1673
0
    ipaddr2str(&nbr->ip, buf, sizeof(buf));
1674
0
    zlog_debug("%s: clear neigh %s dup state, flags 0x%x seq %u",
1675
0
         __func__, buf, nbr->flags, nbr->loc_seq);
1676
0
  }
1677
1678
0
  UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1679
0
  nbr->dad_count = 0;
1680
0
  nbr->detect_start_time.tv_sec = 0;
1681
0
  nbr->detect_start_time.tv_usec = 0;
1682
0
  nbr->dad_dup_detect_time = 0;
1683
0
  EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
1684
1685
0
  if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1686
0
    zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1687
0
                &nbr->emac, nbr->mac,
1688
0
                nbr->flags, nbr->loc_seq);
1689
0
  } else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1690
0
    zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1691
0
  }
1692
0
}
1693
1694
/*
1695
 * Print a specific neighbor entry.
1696
 */
1697
void zebra_evpn_print_neigh(struct zebra_neigh *n, void *ctxt,
1698
          json_object *json)
1699
0
{
1700
0
  struct vty *vty;
1701
0
  char buf1[ETHER_ADDR_STRLEN];
1702
0
  char buf2[INET6_ADDRSTRLEN];
1703
0
  const char *type_str;
1704
0
  const char *state_str;
1705
0
  bool flags_present = false;
1706
0
  struct zebra_vrf *zvrf = NULL;
1707
0
  struct timeval detect_start_time = {0, 0};
1708
0
  char timebuf[MONOTIME_STRLEN];
1709
0
  char thread_buf[EVENT_TIMER_STRLEN];
1710
0
  time_t uptime;
1711
0
  char up_str[MONOTIME_STRLEN];
1712
1713
0
  zvrf = zebra_vrf_get_evpn();
1714
0
  uptime = monotime(NULL);
1715
0
  uptime -= n->uptime;
1716
1717
0
  frrtime_to_interval(uptime, up_str, sizeof(up_str));
1718
1719
0
  ipaddr2str(&n->ip, buf2, sizeof(buf2));
1720
0
  prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1721
0
  type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote";
1722
0
  state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1723
0
  vty = (struct vty *)ctxt;
1724
0
  if (json == NULL) {
1725
0
    bool sync_info = false;
1726
1727
0
    vty_out(vty, "IP: %s\n",
1728
0
      ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1729
0
    vty_out(vty, " Type: %s\n", type_str);
1730
0
    vty_out(vty, " State: %s\n", state_str);
1731
0
    vty_out(vty, " Uptime: %s\n", up_str);
1732
0
    vty_out(vty, " MAC: %s\n",
1733
0
      prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1734
0
    vty_out(vty, " Sync-info:");
1735
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
1736
0
      vty_out(vty, " local-inactive");
1737
0
      sync_info = true;
1738
0
    }
1739
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY)) {
1740
0
      vty_out(vty, " peer-proxy");
1741
0
      sync_info = true;
1742
0
    }
1743
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
1744
0
      vty_out(vty, " peer-active");
1745
0
      sync_info = true;
1746
0
    }
1747
0
    if (n->hold_timer) {
1748
0
      vty_out(vty, " (ht: %s)",
1749
0
        event_timer_to_hhmmss(thread_buf,
1750
0
                  sizeof(thread_buf),
1751
0
                  n->hold_timer));
1752
0
      sync_info = true;
1753
0
    }
1754
0
    if (!sync_info)
1755
0
      vty_out(vty, " -");
1756
0
    vty_out(vty, "\n");
1757
0
  } else {
1758
0
    json_object_string_add(json, "uptime", up_str);
1759
0
    json_object_string_add(json, "ip", buf2);
1760
0
    json_object_string_add(json, "type", type_str);
1761
0
    json_object_string_add(json, "state", state_str);
1762
0
    json_object_string_add(json, "mac", buf1);
1763
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
1764
0
      json_object_boolean_true_add(json, "localInactive");
1765
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY))
1766
0
      json_object_boolean_true_add(json, "peerProxy");
1767
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
1768
0
      json_object_boolean_true_add(json, "peerActive");
1769
0
    if (n->hold_timer)
1770
0
      json_object_string_add(
1771
0
        json, "peerActiveHold",
1772
0
        event_timer_to_hhmmss(thread_buf,
1773
0
                  sizeof(thread_buf),
1774
0
                  n->hold_timer));
1775
0
  }
1776
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1777
0
    if (n->mac->es) {
1778
0
      if (json)
1779
0
        json_object_string_add(json, "remoteEs",
1780
0
                   n->mac->es->esi_str);
1781
0
      else
1782
0
        vty_out(vty, " Remote ES: %s\n",
1783
0
          n->mac->es->esi_str);
1784
0
    } else {
1785
0
      if (json)
1786
0
        json_object_string_addf(json, "remoteVtep",
1787
0
              "%pI4", &n->r_vtep_ip);
1788
0
      else
1789
0
        vty_out(vty, " Remote VTEP: %pI4\n",
1790
0
          &n->r_vtep_ip);
1791
0
    }
1792
0
  }
1793
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
1794
0
    if (!json) {
1795
0
      vty_out(vty, " Flags: Default-gateway");
1796
0
      flags_present = true;
1797
0
    } else
1798
0
      json_object_boolean_true_add(json, "defaultGateway");
1799
0
  }
1800
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
1801
0
    if (!json) {
1802
0
      vty_out(vty,
1803
0
        flags_present ? " ,Router" : " Flags: Router");
1804
0
      flags_present = true;
1805
0
    }
1806
0
  }
1807
0
  if (json == NULL) {
1808
0
    if (flags_present)
1809
0
      vty_out(vty, "\n");
1810
0
    vty_out(vty, " Local Seq: %u Remote Seq: %u\n", n->loc_seq,
1811
0
      n->rem_seq);
1812
1813
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
1814
0
      vty_out(vty, " Duplicate, detected at %s",
1815
0
        time_to_string(n->dad_dup_detect_time,
1816
0
                 timebuf));
1817
0
    } else if (n->dad_count) {
1818
0
      monotime_since(&n->detect_start_time,
1819
0
               &detect_start_time);
1820
0
      if (detect_start_time.tv_sec <= zvrf->dad_time) {
1821
0
        time_to_string(n->detect_start_time.tv_sec,
1822
0
                 timebuf);
1823
0
        vty_out(vty,
1824
0
          " Duplicate detection started at %s, detection count %u\n",
1825
0
          timebuf, n->dad_count);
1826
0
      }
1827
0
    }
1828
0
  } else {
1829
0
    json_object_int_add(json, "localSequence", n->loc_seq);
1830
0
    json_object_int_add(json, "remoteSequence", n->rem_seq);
1831
0
    json_object_int_add(json, "detectionCount", n->dad_count);
1832
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1833
0
      json_object_boolean_true_add(json, "isDuplicate");
1834
0
    else
1835
0
      json_object_boolean_false_add(json, "isDuplicate");
1836
0
  }
1837
0
}
1838
1839
void zebra_evpn_print_neigh_hdr(struct vty *vty, struct neigh_walk_ctx *wctx)
1840
0
{
1841
0
  vty_out(vty, "Flags: I=local-inactive, P=peer-active, X=peer-proxy\n");
1842
0
  vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %s\n", -wctx->addr_width,
1843
0
    "Neighbor", "Type", "Flags", "State", "MAC", "Remote ES/VTEP",
1844
0
    "Seq #'s");
1845
0
}
1846
1847
static char *zebra_evpn_print_neigh_flags(struct zebra_neigh *n,
1848
            char *flags_buf,
1849
            uint32_t flags_buf_sz)
1850
0
{
1851
0
  snprintf(flags_buf, flags_buf_sz, "%s%s%s",
1852
0
      (n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE) ?
1853
0
      "P" : "",
1854
0
      (n->flags & ZEBRA_NEIGH_ES_PEER_PROXY) ?
1855
0
      "X" : "",
1856
0
      (n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) ?
1857
0
      "I" : "");
1858
1859
0
  return flags_buf;
1860
0
}
1861
1862
/*
1863
 * Print neighbor hash entry - called for display of all neighbors.
1864
 */
1865
void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1866
0
{
1867
0
  struct vty *vty;
1868
0
  json_object *json_evpn = NULL, *json_row = NULL;
1869
0
  struct zebra_neigh *n;
1870
0
  char buf1[ETHER_ADDR_STRLEN];
1871
0
  char buf2[INET6_ADDRSTRLEN];
1872
0
  char addr_buf[PREFIX_STRLEN];
1873
0
  struct neigh_walk_ctx *wctx = ctxt;
1874
0
  const char *state_str;
1875
0
  char flags_buf[6];
1876
1877
0
  vty = wctx->vty;
1878
0
  json_evpn = wctx->json;
1879
0
  n = (struct zebra_neigh *)bucket->data;
1880
1881
0
  if (json_evpn)
1882
0
    json_row = json_object_new_object();
1883
1884
0
  prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1885
0
  ipaddr2str(&n->ip, buf2, sizeof(buf2));
1886
0
  state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1887
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1888
0
    if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
1889
0
      return;
1890
1891
0
    if (json_evpn == NULL) {
1892
0
      vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
1893
0
        -wctx->addr_width, buf2, "local",
1894
0
        zebra_evpn_print_neigh_flags(n, flags_buf,
1895
0
                    sizeof(flags_buf)), state_str, buf1,
1896
0
                    "", n->loc_seq, n->rem_seq);
1897
0
    } else {
1898
0
      json_object_string_add(json_row, "type", "local");
1899
0
      json_object_string_add(json_row, "state", state_str);
1900
0
      json_object_string_add(json_row, "mac", buf1);
1901
0
      if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
1902
0
        json_object_boolean_true_add(json_row,
1903
0
                   "defaultGateway");
1904
0
      json_object_int_add(json_row, "localSequence",
1905
0
              n->loc_seq);
1906
0
      json_object_int_add(json_row, "remoteSequence",
1907
0
              n->rem_seq);
1908
0
      json_object_int_add(json_row, "detectionCount",
1909
0
              n->dad_count);
1910
0
      if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1911
0
        json_object_boolean_true_add(json_row,
1912
0
                   "isDuplicate");
1913
0
      else
1914
0
        json_object_boolean_false_add(json_row,
1915
0
                    "isDuplicate");
1916
0
    }
1917
0
    wctx->count++;
1918
0
  } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1919
0
    if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
1920
0
        && !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
1921
0
      return;
1922
1923
0
    if (json_evpn == NULL) {
1924
0
      if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
1925
0
          && (wctx->count == 0))
1926
0
        zebra_evpn_print_neigh_hdr(vty, wctx);
1927
1928
0
      if (n->mac->es == NULL)
1929
0
        inet_ntop(AF_INET, &n->r_vtep_ip,
1930
0
            addr_buf, sizeof(addr_buf));
1931
1932
0
      vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
1933
0
        -wctx->addr_width, buf2, "remote",
1934
0
        zebra_evpn_print_neigh_flags(n, flags_buf,
1935
0
        sizeof(flags_buf)), state_str, buf1,
1936
0
        n->mac->es ? n->mac->es->esi_str : addr_buf,
1937
0
        n->loc_seq, n->rem_seq);
1938
0
    } else {
1939
0
      json_object_string_add(json_row, "type", "remote");
1940
0
      json_object_string_add(json_row, "state", state_str);
1941
0
      json_object_string_add(json_row, "mac", buf1);
1942
0
      if (n->mac->es)
1943
0
        json_object_string_add(json_row, "remoteEs",
1944
0
                   n->mac->es->esi_str);
1945
0
      else
1946
0
        json_object_string_addf(json_row, "remoteVtep",
1947
0
              "%pI4", &n->r_vtep_ip);
1948
0
      if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
1949
0
        json_object_boolean_true_add(json_row,
1950
0
                   "defaultGateway");
1951
0
      json_object_int_add(json_row, "localSequence",
1952
0
              n->loc_seq);
1953
0
      json_object_int_add(json_row, "remoteSequence",
1954
0
              n->rem_seq);
1955
0
      json_object_int_add(json_row, "detectionCount",
1956
0
              n->dad_count);
1957
0
      if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1958
0
        json_object_boolean_true_add(json_row,
1959
0
                   "isDuplicate");
1960
0
      else
1961
0
        json_object_boolean_false_add(json_row,
1962
0
                    "isDuplicate");
1963
0
    }
1964
0
    wctx->count++;
1965
0
  }
1966
1967
0
  if (json_evpn)
1968
0
    json_object_object_add(json_evpn, buf2, json_row);
1969
0
}
1970
1971
/*
1972
 * Print neighbor hash entry in detail - called for display of all neighbors.
1973
 */
1974
void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt)
1975
0
{
1976
0
  struct vty *vty;
1977
0
  json_object *json_evpn = NULL, *json_row = NULL;
1978
0
  struct zebra_neigh *n;
1979
0
  char buf[INET6_ADDRSTRLEN];
1980
0
  struct neigh_walk_ctx *wctx = ctxt;
1981
1982
0
  vty = wctx->vty;
1983
0
  json_evpn = wctx->json;
1984
0
  n = (struct zebra_neigh *)bucket->data;
1985
0
  if (!n)
1986
0
    return;
1987
1988
0
  ipaddr2str(&n->ip, buf, sizeof(buf));
1989
0
  if (json_evpn)
1990
0
    json_row = json_object_new_object();
1991
1992
0
  zebra_evpn_print_neigh(n, vty, json_row);
1993
1994
0
  if (json_evpn)
1995
0
    json_object_object_add(json_evpn, buf, json_row);
1996
0
}
1997
1998
void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1999
0
{
2000
0
  struct zebra_neigh *nbr;
2001
2002
0
  nbr = (struct zebra_neigh *)bucket->data;
2003
0
  if (!nbr)
2004
0
    return;
2005
2006
0
  if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2007
0
    zebra_evpn_print_neigh_hash(bucket, ctxt);
2008
0
}
2009
2010
void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
2011
              void *ctxt)
2012
0
{
2013
0
  struct zebra_neigh *nbr;
2014
2015
0
  nbr = (struct zebra_neigh *)bucket->data;
2016
0
  if (!nbr)
2017
0
    return;
2018
2019
0
  if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2020
0
    zebra_evpn_print_neigh_hash_detail(bucket, ctxt);
2021
0
}
2022
2023
void zebra_evpn_neigh_remote_macip_add(struct zebra_evpn *zevpn,
2024
               struct zebra_vrf *zvrf,
2025
               const struct ipaddr *ipaddr,
2026
               struct zebra_mac *mac,
2027
               struct in_addr vtep_ip, uint8_t flags,
2028
               uint32_t seq)
2029
0
{
2030
0
  struct zebra_neigh *n;
2031
0
  int update_neigh = 0;
2032
0
  struct zebra_mac *old_mac = NULL;
2033
0
  bool old_static = false;
2034
0
  bool do_dad = false;
2035
0
  bool is_dup_detect = false;
2036
0
  bool is_router;
2037
2038
0
  assert(mac);
2039
0
  is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
2040
2041
  /* Check if the remote neighbor itself is unknown or has a
2042
   * change. If so, create or update and then install the entry.
2043
   */
2044
0
  n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
2045
0
  if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2046
0
      || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
2047
0
      || (memcmp(&n->emac, &mac->macaddr, sizeof(struct ethaddr)) != 0)
2048
0
      || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) || seq != n->rem_seq)
2049
0
    update_neigh = 1;
2050
2051
0
  if (update_neigh) {
2052
0
    if (!n) {
2053
0
      n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr,
2054
0
             mac, 0);
2055
0
    } else {
2056
      /* When host moves but changes its (MAC,IP)
2057
       * binding, BGP may install a MACIP entry that
2058
       * corresponds to "older" location of the host
2059
       * in transient situations (because {IP1,M1}
2060
       * is a different route from {IP1,M2}). Check
2061
       * the sequence number and ignore this update
2062
       * if appropriate.
2063
       */
2064
2065
0
      if (!zebra_evpn_neigh_is_bgp_seq_ok(
2066
0
            zevpn, n, &mac->macaddr, seq, false))
2067
0
        return;
2068
0
      if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2069
0
        old_static = zebra_evpn_neigh_is_static(n);
2070
0
        if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2071
0
          zlog_debug(
2072
0
            "sync->remote neigh vni %u ip %pIA mac %pEA seq %d f0x%x",
2073
0
            n->zevpn->vni, &n->ip, &n->emac,
2074
0
            seq, n->flags);
2075
0
        if (IS_ZEBRA_NEIGH_ACTIVE(n))
2076
0
          zebra_evpn_neigh_send_del_to_client(
2077
0
            zevpn->vni, &n->ip, &n->emac,
2078
0
            n->flags, n->state,
2079
0
            false /*force*/);
2080
0
        zebra_evpn_neigh_clear_sync_info(n);
2081
0
      }
2082
0
      if (memcmp(&n->emac, &mac->macaddr,
2083
0
           sizeof(struct ethaddr))
2084
0
          != 0) {
2085
        /* update neigh list for macs */
2086
0
        old_mac =
2087
0
          zebra_evpn_mac_lookup(zevpn, &n->emac);
2088
0
        if (old_mac) {
2089
0
          listnode_delete(old_mac->neigh_list, n);
2090
0
          n->mac = NULL;
2091
0
          zebra_evpn_deref_ip2mac(zevpn, old_mac);
2092
0
        }
2093
0
        n->mac = mac;
2094
0
        listnode_add_sort(mac->neigh_list, n);
2095
0
        memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2096
2097
        /* Check Neigh's curent state is local
2098
         * (this is the case where neigh/host has  moved
2099
         * from L->R) and check previous detction
2100
         * started via local learning.
2101
         *
2102
         * RFC-7432: A PE/VTEP that detects a MAC
2103
         * mobilit event via local learning starts
2104
         * an M-second timer.
2105
         * VTEP-IP or seq. change along is not
2106
         * considered for dup. detection.
2107
         *
2108
         * Mobilty event scenario-B IP-MAC binding
2109
         * changed.
2110
         */
2111
0
        if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2112
0
            && n->dad_count)
2113
0
          do_dad = true;
2114
0
      }
2115
0
    }
2116
2117
    /* Set "remote" forwarding info. */
2118
0
    UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
2119
0
    n->r_vtep_ip = vtep_ip;
2120
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2121
2122
    /* Set router flag (R-bit) to this Neighbor entry */
2123
0
    if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
2124
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2125
0
    else
2126
0
      UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2127
2128
    /* Check old or new MAC detected as duplicate,
2129
     * inherit duplicate flag to this neigh.
2130
     */
2131
0
    if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_mac, mac, n)) {
2132
0
      flog_warn(
2133
0
        EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
2134
0
        "VNI %u: MAC %pEA IP %pIA detected as duplicate during remote update, inherit duplicate from MAC",
2135
0
        zevpn->vni, &mac->macaddr, &n->ip);
2136
0
    }
2137
2138
    /* Check duplicate address detection for IP */
2139
0
    zebra_evpn_dup_addr_detect_for_neigh(
2140
0
      zvrf, n, n->r_vtep_ip, do_dad, &is_dup_detect, false);
2141
    /* Install the entry. */
2142
0
    if (!is_dup_detect)
2143
0
      zebra_evpn_rem_neigh_install(zevpn, n, old_static);
2144
0
  }
2145
2146
  /* Update seq number. */
2147
0
  n->rem_seq = seq;
2148
0
}
2149
2150
int zebra_evpn_neigh_gw_macip_add(struct interface *ifp,
2151
          struct zebra_evpn *zevpn, struct ipaddr *ip,
2152
          struct zebra_mac *mac)
2153
0
{
2154
0
  struct zebra_neigh *n;
2155
2156
0
  assert(mac);
2157
2158
0
  n = zebra_evpn_neigh_lookup(zevpn, ip);
2159
0
  if (!n)
2160
0
    n = zebra_evpn_neigh_add(zevpn, ip, &mac->macaddr, mac, 0);
2161
2162
  /* Set "local" forwarding info. */
2163
0
  SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2164
0
  ZEBRA_NEIGH_SET_ACTIVE(n);
2165
0
  memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2166
0
  n->ifindex = ifp->ifindex;
2167
2168
  /* Only advertise in BGP if the knob is enabled */
2169
0
  if (advertise_gw_macip_enabled(zevpn)) {
2170
2171
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
2172
    /* Set Router flag (R-bit) */
2173
0
    if (ip->ipa_type == IPADDR_V6)
2174
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2175
2176
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2177
0
      zlog_debug(
2178
0
        "SVI %s(%u) L2-VNI %u, sending GW MAC %pEA IP %pIA add to BGP with flags 0x%x",
2179
0
        ifp->name, ifp->ifindex, zevpn->vni,
2180
0
        &mac->macaddr, ip, n->flags);
2181
2182
0
    zebra_evpn_neigh_send_add_to_client(
2183
0
      zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2184
0
  } else if (advertise_svi_macip_enabled(zevpn)) {
2185
2186
0
    SET_FLAG(n->flags, ZEBRA_NEIGH_SVI_IP);
2187
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2188
0
      zlog_debug(
2189
0
        "SVI %s(%u) L2-VNI %u, sending SVI MAC %pEA IP %pIA add to BGP with flags 0x%x",
2190
0
        ifp->name, ifp->ifindex, zevpn->vni,
2191
0
        &mac->macaddr, ip, n->flags);
2192
2193
0
    zebra_evpn_neigh_send_add_to_client(
2194
0
      zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2195
0
  }
2196
2197
0
  return 0;
2198
0
}
2199
2200
void zebra_evpn_neigh_remote_uninstall(struct zebra_evpn *zevpn,
2201
               struct zebra_vrf *zvrf,
2202
               struct zebra_neigh *n,
2203
               struct zebra_mac *mac,
2204
               const struct ipaddr *ipaddr)
2205
0
{
2206
0
  if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)
2207
0
      && CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2208
0
      && (memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN) == 0)) {
2209
0
    struct interface *vlan_if;
2210
2211
0
    vlan_if = zevpn_map_to_svi(zevpn);
2212
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2213
0
      zlog_debug(
2214
0
        "%s: IP %pIA (flags 0x%x intf %s) is remote and duplicate, read kernel for local entry",
2215
0
        __func__, ipaddr, n->flags,
2216
0
        vlan_if ? vlan_if->name : "Unknown");
2217
0
    if (vlan_if)
2218
0
      neigh_read_specific_ip(ipaddr, vlan_if);
2219
0
  }
2220
2221
  /* When the MAC changes for an IP, it is possible the
2222
   * client may update the new MAC before trying to delete the
2223
   * "old" neighbor (as these are two different MACIP routes).
2224
   * Do the delete only if the MAC matches.
2225
   */
2226
0
  if (!memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN)) {
2227
0
    if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2228
0
      zebra_evpn_sync_neigh_del(n);
2229
0
    } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2230
0
      zebra_evpn_neigh_uninstall(zevpn, n);
2231
0
      zebra_evpn_neigh_del(zevpn, n);
2232
0
      zebra_evpn_deref_ip2mac(zevpn, mac);
2233
0
    }
2234
0
  } else {
2235
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2236
0
      zlog_debug(
2237
0
        "%s: IP %pIA MAC %pEA (flags 0x%x) found doesn't match MAC %pEA, ignoring Neigh DEL",
2238
0
        __func__, ipaddr, &n->emac, n->flags,
2239
0
        &mac->macaddr);
2240
0
  }
2241
0
}
2242
2243
int zebra_evpn_neigh_del_ip(struct zebra_evpn *zevpn, const struct ipaddr *ip)
2244
0
{
2245
0
  struct zebra_neigh *n;
2246
0
  struct zebra_mac *zmac;
2247
0
  bool old_bgp_ready;
2248
0
  bool new_bgp_ready;
2249
0
  struct zebra_vrf *zvrf;
2250
2251
  /* If entry doesn't exist, nothing to do. */
2252
0
  n = zebra_evpn_neigh_lookup(zevpn, ip);
2253
0
  if (!n)
2254
0
    return 0;
2255
2256
0
  zmac = zebra_evpn_mac_lookup(zevpn, &n->emac);
2257
0
  if (!zmac) {
2258
0
    if (IS_ZEBRA_DEBUG_VXLAN)
2259
0
      zlog_debug(
2260
0
        "Trying to del a neigh %pIA without a mac %pEA on VNI %u",
2261
0
        ip, &n->emac,
2262
0
        zevpn->vni);
2263
2264
0
    return 0;
2265
0
  }
2266
2267
  /* If it is a remote entry, the kernel has aged this out or someone has
2268
   * deleted it, it needs to be re-installed as FRR is the owner.
2269
   */
2270
0
  if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2271
0
    zebra_evpn_rem_neigh_install(zevpn, n, false /*was_static*/);
2272
0
    return 0;
2273
0
  }
2274
2275
  /* if this is a sync entry it cannot be dropped re-install it in
2276
   * the dataplane
2277
   */
2278
0
  old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2279
0
  if (zebra_evpn_neigh_is_static(n)) {
2280
0
    if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2281
0
      zlog_debug("re-add sync neigh vni %u ip %pIA mac %pEA 0x%x",
2282
0
           n->zevpn->vni, &n->ip, &n->emac,
2283
0
           n->flags);
2284
2285
0
    if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
2286
0
      SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
2287
    /* inform-bgp about change in local-activity if any */
2288
0
    new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2289
0
    zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
2290
0
              new_bgp_ready);
2291
2292
    /* re-install the entry in the kernel */
2293
0
    zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
2294
0
             false /* force_clear_static */,
2295
0
             __func__);
2296
2297
0
    return 0;
2298
0
  }
2299
2300
0
  zvrf = zevpn->vxlan_if->vrf->info;
2301
0
  if (!zvrf) {
2302
0
    zlog_debug("%s: VNI %u vrf lookup failed.", __func__,
2303
0
         zevpn->vni);
2304
0
    return -1;
2305
0
  }
2306
2307
  /* In case of feeze action, if local neigh is in duplicate state,
2308
   * Mark the Neigh as inactive before sending delete request to BGPd,
2309
   * If BGPd has remote entry, it will re-install
2310
   */
2311
0
  if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
2312
0
    ZEBRA_NEIGH_SET_INACTIVE(n);
2313
2314
  /* Remove neighbor from BGP. */
2315
0
  zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
2316
0
              n->flags, n->state,
2317
0
              false /* force */);
2318
2319
  /* Delete this neighbor entry. */
2320
0
  zebra_evpn_neigh_del(zevpn, n);
2321
2322
  /* see if the AUTO mac needs to be deleted */
2323
0
  if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
2324
0
      && !zebra_evpn_mac_in_use(zmac))
2325
0
    zebra_evpn_mac_del(zevpn, zmac);
2326
2327
0
  return 0;
2328
0
}