Coverage Report

Created: 2025-07-14 06:48

/src/frr/zebra/redistribute.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* Redistribution Handler
3
 * Copyright (C) 1998 Kunihiro Ishiguro
4
 */
5
6
#include <zebra.h>
7
8
#include "vector.h"
9
#include "vty.h"
10
#include "command.h"
11
#include "prefix.h"
12
#include "table.h"
13
#include "stream.h"
14
#include "zclient.h"
15
#include "linklist.h"
16
#include "log.h"
17
#include "vrf.h"
18
#include "srcdest_table.h"
19
20
#include "zebra/rib.h"
21
#include "zebra/zebra_router.h"
22
#include "zebra/zebra_ns.h"
23
#include "zebra/zebra_vrf.h"
24
#include "zebra/zebra_routemap.h"
25
#include "zebra/redistribute.h"
26
#include "zebra/debug.h"
27
#include "zebra/router-id.h"
28
#include "zebra/zapi_msg.h"
29
#include "zebra/zebra_vxlan.h"
30
#include "zebra/zebra_errors.h"
31
32
#define ZEBRA_PTM_SUPPORT
33
34
/* array holding redistribute info about table redistribution */
35
/* bit AFI is set if that AFI is redistributing routes from this table */
36
static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
37
static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
38
39
int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id)
40
0
{
41
  /*
42
   * Make sure that what we are called with actualy makes sense
43
   */
44
0
  if (afi == AFI_MAX)
45
0
    return 0;
46
47
0
  if (is_zebra_valid_kernel_table(table_id) &&
48
0
      table_id < ZEBRA_KERNEL_TABLE_MAX)
49
0
    return zebra_import_table_used[afi][table_id];
50
0
  return 0;
51
0
}
52
53
static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
54
0
{
55
0
  int afi;
56
0
  struct prefix p;
57
0
  struct route_table *table;
58
0
  struct route_node *rn;
59
0
  struct route_entry *newre;
60
61
0
  for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
62
63
0
    if (!vrf_bitmap_check(client->redist_default[afi], vrf_id))
64
0
      continue;
65
66
    /* Lookup table.  */
67
0
    table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
68
0
    if (!table)
69
0
      continue;
70
71
    /* Lookup default route. */
72
0
    memset(&p, 0, sizeof(p));
73
0
    p.family = afi2family(afi);
74
0
    rn = route_node_lookup(table, &p);
75
0
    if (!rn)
76
0
      continue;
77
78
0
    RNODE_FOREACH_RE (rn, newre) {
79
0
      if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
80
0
        zsend_redistribute_route(
81
0
          ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
82
0
          rn, newre);
83
0
    }
84
85
0
    route_unlock_node(rn);
86
0
  }
87
0
}
88
89
/* Redistribute routes. */
90
static void zebra_redistribute(struct zserv *client, int type,
91
             unsigned short instance, vrf_id_t vrf_id,
92
             int afi)
93
0
{
94
0
  struct route_entry *newre;
95
0
  struct route_table *table;
96
0
  struct route_node *rn;
97
98
0
  table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
99
0
  if (!table)
100
0
    return;
101
102
0
  for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
103
0
    RNODE_FOREACH_RE (rn, newre) {
104
0
      if (IS_ZEBRA_DEBUG_RIB)
105
0
        zlog_debug(
106
0
          "%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d",
107
0
          __func__,
108
0
          zebra_route_string(client->proto), rn,
109
0
          vrf_id, newre->instance,
110
0
          !!CHECK_FLAG(newre->flags,
111
0
                 ZEBRA_FLAG_SELECTED),
112
0
          zebra_route_string(newre->type),
113
0
          newre->instance,
114
0
          newre->distance,
115
0
          newre->metric,
116
0
          zebra_check_addr(&rn->p));
117
118
0
      if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
119
0
        continue;
120
0
      if ((type != ZEBRA_ROUTE_ALL
121
0
           && (newre->type != type
122
0
         || newre->instance != instance)))
123
0
        continue;
124
0
      if (!zebra_check_addr(&rn->p))
125
0
        continue;
126
127
0
      zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
128
0
             client, rn, newre);
129
0
    }
130
0
}
131
132
/*
133
 * Function to check if prefix is candidate for
134
 * redistribute.
135
 */
136
static bool zebra_redistribute_check(const struct route_node *rn,
137
             const struct route_entry *re,
138
             struct zserv *client)
139
0
{
140
0
  struct zebra_vrf *zvrf;
141
0
  afi_t afi;
142
143
  /* Process only if there is valid re */
144
0
  if (!re)
145
0
    return false;
146
147
0
  afi = family2afi(rn->p.family);
148
0
  zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
149
0
  if (re->vrf_id == VRF_DEFAULT && zvrf->table_id != re->table)
150
0
    return false;
151
152
  /* If default route and redistributed */
153
0
  if (is_default_prefix(&rn->p) &&
154
0
      vrf_bitmap_check(client->redist_default[afi], re->vrf_id))
155
0
    return true;
156
157
  /* If redistribute in enabled for zebra route all */
158
0
  if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id))
159
0
    return true;
160
161
  /*
162
   * If multi-instance then check for route
163
   * redistribution for given instance.
164
   */
165
0
  if (re->instance) {
166
0
    if (redist_check_instance(&client->mi_redist[afi][re->type],
167
0
            re->instance))
168
0
      return true;
169
0
    else
170
0
      return false;
171
0
  }
172
173
  /* If redistribution is enabled for give route type. */
174
0
  if (vrf_bitmap_check(client->redist[afi][re->type], re->vrf_id))
175
0
    return true;
176
177
0
  return false;
178
0
}
179
180
/* Either advertise a route for redistribution to registered clients or */
181
/* withdraw redistribution if add cannot be done for client */
182
void redistribute_update(const struct route_node *rn,
183
       const struct route_entry *re,
184
       const struct route_entry *prev_re)
185
0
{
186
0
  struct listnode *node, *nnode;
187
0
  struct zserv *client;
188
189
0
  if (IS_ZEBRA_DEBUG_RIB)
190
0
    zlog_debug(
191
0
      "(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)",
192
0
      re->vrf_id, re->table, rn, re->instance, re,
193
0
      zebra_route_string(re->type), prev_re,
194
0
      prev_re ? zebra_route_string(prev_re->type) : "None");
195
196
0
  if (!zebra_check_addr(&rn->p)) {
197
0
    if (IS_ZEBRA_DEBUG_RIB)
198
0
      zlog_debug("Redist update filter prefix %pRN", rn);
199
0
    return;
200
0
  }
201
202
203
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
204
0
    if (zebra_redistribute_check(rn, re, client)) {
205
0
      if (IS_ZEBRA_DEBUG_RIB) {
206
0
        zlog_debug(
207
0
          "%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d",
208
0
          __func__,
209
0
          zebra_route_string(client->proto), rn,
210
0
          re->vrf_id, re->table, re->type,
211
0
          re->distance, re->metric);
212
0
      }
213
0
      zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
214
0
             client, rn, re);
215
0
    } else if (zebra_redistribute_check(rn, prev_re, client))
216
0
      zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
217
0
             client, rn, prev_re);
218
0
  }
219
0
}
220
221
/*
222
 * During a route delete, where 'new_re' is NULL, redist a delete to all
223
 * clients registered for the type of 'old_re'.
224
 * During a route update, redist a delete to any clients who will not see
225
 * an update when the new route is installed. There are cases when a client
226
 * may have seen a redist for 'old_re', but will not see
227
 * the redist for 'new_re'.
228
 */
229
void redistribute_delete(const struct route_node *rn,
230
       const struct route_entry *old_re,
231
       const struct route_entry *new_re)
232
0
{
233
0
  struct listnode *node, *nnode;
234
0
  struct zserv *client;
235
0
  vrf_id_t vrfid;
236
237
0
  if (old_re)
238
0
    vrfid = old_re->vrf_id;
239
0
  else if (new_re)
240
0
    vrfid = new_re->vrf_id;
241
0
  else
242
0
    return;
243
244
0
  if (IS_ZEBRA_DEBUG_RIB) {
245
0
    uint8_t old_inst, new_inst;
246
0
    uint32_t table = 0;
247
248
0
    old_inst = new_inst = 0;
249
250
0
    if (old_re) {
251
0
      old_inst = old_re->instance;
252
0
      table = old_re->table;
253
0
    }
254
0
    if (new_re) {
255
0
      new_inst = new_re->instance;
256
0
      table = new_re->table;
257
0
    }
258
259
0
    zlog_debug(
260
0
      "%u:%u%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)",
261
0
      vrfid, table, rn, old_re, old_inst,
262
0
      old_re ? zebra_route_string(old_re->type) : "None",
263
0
      new_re, new_inst,
264
0
      new_re ? zebra_route_string(new_re->type) : "None");
265
0
  }
266
267
  /* Skip invalid (e.g. linklocal) prefix */
268
0
  if (!zebra_check_addr(&rn->p)) {
269
0
    if (IS_ZEBRA_DEBUG_RIB) {
270
0
      zlog_debug(
271
0
        "%u:%pRN: Redist del old: skipping invalid prefix",
272
0
        vrfid, rn);
273
0
    }
274
0
    return;
275
0
  }
276
277
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
278
    /* Do not send unsolicited messages to synchronous clients. */
279
0
    if (client->synchronous)
280
0
      continue;
281
    /*
282
     * Skip this client if it will receive an update for the
283
     * 'new' re
284
     */
285
0
    if (zebra_redistribute_check(rn, new_re, client))
286
0
      continue;
287
288
    /* Send a delete for the 'old' re to any subscribed client. */
289
0
    if (zebra_redistribute_check(rn, old_re, client))
290
0
      zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
291
0
             client, rn, old_re);
292
0
  }
293
0
}
294
295
296
void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
297
0
{
298
0
  afi_t afi = 0;
299
0
  int type = 0;
300
0
  unsigned short instance;
301
302
0
  STREAM_GETC(msg, afi);
303
0
  STREAM_GETC(msg, type);
304
0
  STREAM_GETW(msg, instance);
305
306
0
  if (IS_ZEBRA_DEBUG_EVENT)
307
0
    zlog_debug(
308
0
      "%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d",
309
0
      __func__, zebra_route_string(client->proto), afi,
310
0
      zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
311
0
      zvrf_id(zvrf), instance);
312
313
0
  if (afi == 0 || afi >= AFI_MAX) {
314
0
    flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
315
0
        "%s: Specified afi %d does not exist", __func__, afi);
316
0
    return;
317
0
  }
318
319
0
  if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
320
0
    zlog_debug("%s: Specified Route Type %d does not exist",
321
0
         __func__, type);
322
0
    return;
323
0
  }
324
325
0
  if (instance) {
326
0
    if (!redist_check_instance(&client->mi_redist[afi][type],
327
0
             instance)) {
328
0
      redist_add_instance(&client->mi_redist[afi][type],
329
0
              instance);
330
0
      zebra_redistribute(client, type, instance,
331
0
             zvrf_id(zvrf), afi);
332
0
    }
333
0
  } else {
334
0
    if (!vrf_bitmap_check(client->redist[afi][type],
335
0
              zvrf_id(zvrf))) {
336
0
      if (IS_ZEBRA_DEBUG_EVENT)
337
0
        zlog_debug(
338
0
          "%s: setting vrf %s(%u) redist bitmap",
339
0
          __func__, VRF_LOGNAME(zvrf->vrf),
340
0
          zvrf_id(zvrf));
341
0
      vrf_bitmap_set(client->redist[afi][type],
342
0
               zvrf_id(zvrf));
343
0
      zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
344
0
    }
345
0
  }
346
347
0
stream_failure:
348
0
  return;
349
0
}
350
351
void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
352
0
{
353
0
  afi_t afi = 0;
354
0
  int type = 0;
355
0
  unsigned short instance;
356
357
0
  STREAM_GETC(msg, afi);
358
0
  STREAM_GETC(msg, type);
359
0
  STREAM_GETW(msg, instance);
360
361
0
  if (IS_ZEBRA_DEBUG_EVENT)
362
0
    zlog_debug(
363
0
      "%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d",
364
0
      __func__, zebra_route_string(client->proto), afi,
365
0
      zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
366
0
      zvrf_id(zvrf), instance);
367
368
369
0
  if (afi == 0 || afi >= AFI_MAX) {
370
0
    flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
371
0
        "%s: Specified afi %d does not exist", __func__, afi);
372
0
    return;
373
0
  }
374
375
0
  if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
376
0
    zlog_debug("%s: Specified Route Type %d does not exist",
377
0
         __func__, type);
378
0
    return;
379
0
  }
380
381
  /*
382
   * NOTE: no need to withdraw the previously advertised routes. The
383
   * clients
384
   * themselves should keep track of the received routes from zebra and
385
   * withdraw them when necessary.
386
   */
387
0
  if (instance)
388
0
    redist_del_instance(&client->mi_redist[afi][type], instance);
389
0
  else
390
0
    vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
391
392
0
stream_failure:
393
0
  return;
394
0
}
395
396
void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
397
0
{
398
0
  afi_t afi = 0;
399
400
0
  STREAM_GETC(msg, afi);
401
402
0
  if (afi == 0 || afi >= AFI_MAX) {
403
0
    flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
404
0
        "%s: Specified afi %u does not exist", __func__, afi);
405
0
    return;
406
0
  }
407
408
0
  vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
409
0
  zebra_redistribute_default(client, zvrf_id(zvrf));
410
411
0
stream_failure:
412
0
  return;
413
0
}
414
415
void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
416
0
{
417
0
  afi_t afi = 0;
418
419
0
  STREAM_GETC(msg, afi);
420
421
0
  if (afi == 0 || afi >= AFI_MAX) {
422
0
    flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
423
0
        "%s: Specified afi %u does not exist", __func__, afi);
424
0
    return;
425
0
  }
426
427
0
  vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
428
429
0
stream_failure:
430
0
  return;
431
0
}
432
433
/* Interface up information. */
434
void zebra_interface_up_update(struct interface *ifp)
435
0
{
436
0
  struct listnode *node, *nnode;
437
0
  struct zserv *client;
438
439
0
  if (IS_ZEBRA_DEBUG_EVENT)
440
0
    zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)",
441
0
         ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
442
443
0
  if (ifp->ptm_status || !ifp->ptm_enable) {
444
0
    for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
445
0
               client)) {
446
      /* Do not send unsolicited messages to synchronous
447
       * clients.
448
       */
449
0
      if (client->synchronous)
450
0
        continue;
451
452
0
      zsend_interface_update(ZEBRA_INTERFACE_UP,
453
0
                 client, ifp);
454
0
      zsend_interface_link_params(client, ifp);
455
0
    }
456
0
  }
457
0
}
458
459
/* Interface down information. */
460
void zebra_interface_down_update(struct interface *ifp)
461
0
{
462
0
  struct listnode *node, *nnode;
463
0
  struct zserv *client;
464
465
0
  if (IS_ZEBRA_DEBUG_EVENT)
466
0
    zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)",
467
0
         ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
468
469
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
470
    /* Do not send unsolicited messages to synchronous clients. */
471
0
    if (client->synchronous)
472
0
      continue;
473
474
0
    zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
475
0
  }
476
0
}
477
478
/* Interface information update. */
479
void zebra_interface_add_update(struct interface *ifp)
480
0
{
481
0
  struct listnode *node, *nnode;
482
0
  struct zserv *client;
483
484
0
  if (IS_ZEBRA_DEBUG_EVENT)
485
0
    zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)",
486
0
         ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
487
488
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
489
    /* Do not send unsolicited messages to synchronous clients. */
490
0
    if (client->synchronous)
491
0
      continue;
492
493
0
    client->ifadd_cnt++;
494
0
    zsend_interface_add(client, ifp);
495
0
    zsend_interface_link_params(client, ifp);
496
0
  }
497
0
}
498
499
void zebra_interface_delete_update(struct interface *ifp)
500
0
{
501
0
  struct listnode *node, *nnode;
502
0
  struct zserv *client;
503
504
0
  if (IS_ZEBRA_DEBUG_EVENT)
505
0
    zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)",
506
0
         ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
507
508
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
509
    /* Do not send unsolicited messages to synchronous clients. */
510
0
    if (client->synchronous)
511
0
      continue;
512
513
0
    client->ifdel_cnt++;
514
0
    zsend_interface_delete(client, ifp);
515
0
  }
516
0
}
517
518
/* Interface address addition. */
519
void zebra_interface_address_add_update(struct interface *ifp,
520
          struct connected *ifc)
521
0
{
522
0
  struct listnode *node, *nnode;
523
0
  struct zserv *client;
524
525
0
  if (IS_ZEBRA_DEBUG_EVENT)
526
0
    zlog_debug(
527
0
      "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)",
528
0
      ifc->address, ifp->name, ifp->vrf->name,
529
0
      ifp->vrf->vrf_id);
530
531
0
  if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
532
0
    flog_warn(
533
0
      EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
534
0
      "advertising address to clients that is not yet usable.");
535
536
0
  zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
537
538
0
  router_id_add_address(ifc);
539
540
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
541
    /* Do not send unsolicited messages to synchronous clients. */
542
0
    if (client->synchronous)
543
0
      continue;
544
545
0
    if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
546
0
      client->connected_rt_add_cnt++;
547
0
      zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
548
0
            client, ifp, ifc);
549
0
    }
550
0
  }
551
  /* interface associated NHGs may have been deleted,
552
   * re-sync zebra -> dplane NHGs
553
   */
554
0
  zebra_interface_nhg_reinstall(ifp);
555
0
}
556
557
/* Interface address deletion. */
558
void zebra_interface_address_delete_update(struct interface *ifp,
559
             struct connected *ifc)
560
0
{
561
0
  struct listnode *node, *nnode;
562
0
  struct zserv *client;
563
564
0
  if (IS_ZEBRA_DEBUG_EVENT)
565
0
    zlog_debug(
566
0
      "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)",
567
0
      ifc->address, ifp->name, ifp->vrf->name,
568
0
      ifp->vrf->vrf_id);
569
570
0
  zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
571
572
0
  router_id_del_address(ifc);
573
574
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
575
    /* Do not send unsolicited messages to synchronous clients. */
576
0
    if (client->synchronous)
577
0
      continue;
578
579
0
    if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
580
0
      client->connected_rt_del_cnt++;
581
0
      zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
582
0
            client, ifp, ifc);
583
0
    }
584
0
  }
585
0
}
586
587
/* Interface VRF change. May need to delete from clients not interested in
588
 * the new VRF. Note that this function is invoked *prior* to the VRF change.
589
 */
590
void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
591
0
{
592
0
  struct listnode *node, *nnode;
593
0
  struct zserv *client;
594
595
0
  if (IS_ZEBRA_DEBUG_EVENT)
596
0
    zlog_debug(
597
0
      "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
598
0
      ifp->name, ifp->vrf->vrf_id, new_vrf_id);
599
600
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
601
    /* Do not send unsolicited messages to synchronous clients. */
602
0
    if (client->synchronous)
603
0
      continue;
604
605
    /* Need to delete if the client is not interested in the new
606
     * VRF. */
607
0
    zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
608
0
    client->ifdel_cnt++;
609
0
    zsend_interface_delete(client, ifp);
610
0
    zsend_interface_vrf_update(client, ifp, new_vrf_id);
611
0
  }
612
0
}
613
614
/* Interface VRF change. This function is invoked *post* VRF change and sends an
615
 * add to clients who are interested in the new VRF but not in the old VRF.
616
 */
617
void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
618
0
{
619
0
  struct listnode *node, *nnode;
620
0
  struct zserv *client;
621
622
0
  if (IS_ZEBRA_DEBUG_EVENT)
623
0
    zlog_debug(
624
0
      "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
625
0
      ifp->name, old_vrf_id, ifp->vrf->vrf_id);
626
627
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
628
    /* Do not send unsolicited messages to synchronous clients. */
629
0
    if (client->synchronous)
630
0
      continue;
631
632
    /* Need to add if the client is interested in the new VRF. */
633
0
    client->ifadd_cnt++;
634
0
    zsend_interface_add(client, ifp);
635
0
    zsend_interface_addresses(client, ifp);
636
0
  }
637
0
}
638
639
int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
640
         struct route_entry *re, const char *rmap_name)
641
0
{
642
0
  struct route_entry *newre;
643
0
  struct route_entry *same;
644
0
  struct prefix p;
645
0
  struct nexthop_group *ng;
646
0
  route_map_result_t ret = RMAP_PERMITMATCH;
647
0
  afi_t afi;
648
649
0
  afi = family2afi(rn->p.family);
650
0
  if (rmap_name)
651
0
    ret = zebra_import_table_route_map_check(
652
0
      afi, re->type, re->instance, &rn->p,
653
0
      re->nhe->nhg.nexthop,
654
0
      zvrf->vrf->vrf_id, re->tag, rmap_name);
655
656
0
  if (ret != RMAP_PERMITMATCH) {
657
0
    UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
658
0
    zebra_del_import_table_entry(zvrf, rn, re);
659
0
    return 0;
660
0
  }
661
662
0
  prefix_copy(&p, &rn->p);
663
664
0
  RNODE_FOREACH_RE (rn, same) {
665
0
    if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
666
0
      continue;
667
668
0
    if (same->type == re->type && same->instance == re->instance
669
0
        && same->table == re->table
670
0
        && same->type != ZEBRA_ROUTE_CONNECT)
671
0
      break;
672
0
  }
673
674
0
  if (same) {
675
0
    UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
676
0
    zebra_del_import_table_entry(zvrf, rn, same);
677
0
  }
678
679
0
  newre = zebra_rib_route_entry_new(
680
0
    0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id,
681
0
    zvrf->table_id, re->metric, re->mtu,
682
0
    zebra_import_table_distance[afi][re->table], re->tag);
683
684
0
  ng = nexthop_group_new();
685
0
  copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL);
686
687
0
  rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng, false);
688
689
0
  return 0;
690
0
}
691
692
int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
693
         struct route_entry *re)
694
0
{
695
0
  struct prefix p;
696
0
  afi_t afi;
697
698
0
  afi = family2afi(rn->p.family);
699
0
  prefix_copy(&p, &rn->p);
700
701
0
  rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
702
0
       re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
703
0
       re->nhe_id, zvrf->table_id, re->metric, re->distance,
704
0
       false);
705
706
0
  return 0;
707
0
}
708
709
/* Assuming no one calls this with the main routing table */
710
int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
711
           uint32_t distance, const char *rmap_name, int add)
712
0
{
713
0
  struct route_table *table;
714
0
  struct route_entry *re;
715
0
  struct route_node *rn;
716
0
  struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
717
718
0
  if (!is_zebra_valid_kernel_table(table_id)
719
0
      || (table_id == RT_TABLE_MAIN))
720
0
    return -1;
721
722
0
  if (afi >= AFI_MAX)
723
0
    return -1;
724
725
0
  table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id,
726
0
              table_id);
727
0
  if (table == NULL) {
728
0
    return 0;
729
0
  } else if (IS_ZEBRA_DEBUG_RIB) {
730
0
    zlog_debug("%s routes from table %d",
731
0
         add ? "Importing" : "Unimporting", table_id);
732
0
  }
733
734
0
  if (add) {
735
0
    if (rmap_name)
736
0
      zebra_add_import_table_route_map(afi, rmap_name,
737
0
               table_id);
738
0
    else {
739
0
      rmap_name =
740
0
        zebra_get_import_table_route_map(afi, table_id);
741
0
      if (rmap_name) {
742
0
        zebra_del_import_table_route_map(afi, table_id);
743
0
        rmap_name = NULL;
744
0
      }
745
0
    }
746
747
0
    zebra_import_table_used[afi][table_id] = 1;
748
0
    zebra_import_table_distance[afi][table_id] = distance;
749
0
  } else {
750
0
    zebra_import_table_used[afi][table_id] = 0;
751
0
    zebra_import_table_distance[afi][table_id] =
752
0
      ZEBRA_TABLE_DISTANCE_DEFAULT;
753
754
0
    rmap_name = zebra_get_import_table_route_map(afi, table_id);
755
0
    if (rmap_name) {
756
0
      zebra_del_import_table_route_map(afi, table_id);
757
0
      rmap_name = NULL;
758
0
    }
759
0
  }
760
761
0
  for (rn = route_top(table); rn; rn = route_next(rn)) {
762
    /* For each entry in the non-default routing table,
763
     * add the entry in the main table
764
     */
765
0
    if (!rn->info)
766
0
      continue;
767
768
0
    RNODE_FOREACH_RE (rn, re) {
769
0
      if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
770
0
        continue;
771
0
      break;
772
0
    }
773
774
0
    if (!re)
775
0
      continue;
776
777
0
    if (((afi == AFI_IP) && (rn->p.family == AF_INET))
778
0
        || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
779
0
      if (add)
780
0
        zebra_add_import_table_entry(zvrf, rn, re,
781
0
                   rmap_name);
782
0
      else
783
0
        zebra_del_import_table_entry(zvrf, rn, re);
784
0
    }
785
0
  }
786
0
  return 0;
787
0
}
788
789
int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id)
790
0
{
791
0
  int i;
792
0
  afi_t afi;
793
0
  int write = 0;
794
0
  char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
795
0
  const char *rmap_name;
796
797
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
798
0
    for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
799
0
      if (!is_zebra_import_table_enabled(afi, vrf_id, i))
800
0
        continue;
801
802
0
      if (zebra_import_table_distance[afi][i]
803
0
          != ZEBRA_TABLE_DISTANCE_DEFAULT) {
804
0
        vty_out(vty, "%s import-table %d distance %d",
805
0
          afi_str[afi], i,
806
0
          zebra_import_table_distance[afi][i]);
807
0
      } else {
808
0
        vty_out(vty, "%s import-table %d", afi_str[afi],
809
0
          i);
810
0
      }
811
812
0
      rmap_name = zebra_get_import_table_route_map(afi, i);
813
0
      if (rmap_name)
814
0
        vty_out(vty, " route-map %s", rmap_name);
815
816
0
      vty_out(vty, "\n");
817
0
      write = 1;
818
0
    }
819
0
  }
820
821
0
  return write;
822
0
}
823
824
static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf,
825
             afi_t afi, int table_id,
826
             const char *rmap)
827
0
{
828
0
  struct route_table *table;
829
0
  struct route_entry *re;
830
0
  struct route_node *rn;
831
0
  const char *rmap_name;
832
833
0
  rmap_name = zebra_get_import_table_route_map(afi, table_id);
834
0
  if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
835
0
    return;
836
837
0
  table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST,
838
0
              zvrf->vrf->vrf_id, table_id);
839
0
  if (!table) {
840
0
    if (IS_ZEBRA_DEBUG_RIB_DETAILED)
841
0
      zlog_debug("%s: Table id=%d not found", __func__,
842
0
           table_id);
843
0
    return;
844
0
  }
845
846
0
  for (rn = route_top(table); rn; rn = route_next(rn)) {
847
    /*
848
     * For each entry in the non-default routing table,
849
     * add the entry in the main table
850
     */
851
0
    if (!rn->info)
852
0
      continue;
853
854
0
    RNODE_FOREACH_RE (rn, re) {
855
0
      if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
856
0
        continue;
857
0
      break;
858
0
    }
859
860
0
    if (!re)
861
0
      continue;
862
863
0
    if (((afi == AFI_IP) && (rn->p.family == AF_INET))
864
0
        || ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
865
0
      zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
866
0
  }
867
868
0
  return;
869
0
}
870
871
static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf,
872
               const char *rmap)
873
0
{
874
0
  afi_t afi;
875
0
  int i;
876
877
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
878
0
    for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
879
0
      if (!is_zebra_import_table_enabled(
880
0
            afi, zvrf->vrf->vrf_id, i))
881
0
        continue;
882
883
0
      zebra_import_table_rm_update_vrf_afi(zvrf, afi, i,
884
0
                   rmap);
885
0
    }
886
0
  }
887
0
}
888
889
void zebra_import_table_rm_update(const char *rmap)
890
0
{
891
0
  struct vrf *vrf;
892
0
  struct zebra_vrf *zvrf;
893
894
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
895
0
    zvrf = vrf->info;
896
897
0
    if (!zvrf)
898
0
      continue;
899
900
0
    zebra_import_table_rm_update_vrf(zvrf, rmap);
901
0
  }
902
0
}
903
904
/* Interface parameters update */
905
void zebra_interface_parameters_update(struct interface *ifp)
906
0
{
907
0
  struct listnode *node, *nnode;
908
0
  struct zserv *client;
909
910
0
  if (IS_ZEBRA_DEBUG_EVENT)
911
0
    zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)",
912
0
         ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
913
914
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
915
    /* Do not send unsolicited messages to synchronous clients. */
916
0
    if (client->synchronous)
917
0
      continue;
918
919
0
    zsend_interface_link_params(client, ifp);
920
0
  }
921
0
}