Coverage Report

Created: 2026-02-21 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/bgpd/rfapi/bgp_rfapi_cfg.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 *
4
 * Copyright 2009-2016, LabN Consulting, L.L.C.
5
 *
6
 */
7
#include "lib/zebra.h"
8
9
#include "lib/command.h"
10
#include "lib/prefix.h"
11
#include "lib/memory.h"
12
#include "lib/linklist.h"
13
#include "lib/agg_table.h"
14
#include "lib/plist.h"
15
#include "lib/routemap.h"
16
17
#include "bgpd/bgpd.h"
18
#include "bgpd/bgp_attr.h"
19
#include "bgpd/bgp_route.h"
20
#include "bgpd/bgp_mplsvpn.h"
21
22
#include "bgpd/bgp_vty.h"
23
#include "bgpd/bgp_ecommunity.h"
24
#include "bgpd/rfapi/rfapi.h"
25
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
26
#include "bgpd/rfapi/rfapi_backend.h"
27
#include "bgpd/rfapi/rfapi_import.h"
28
#include "bgpd/rfapi/rfapi_private.h"
29
#include "bgpd/rfapi/rfapi_monitor.h"
30
#include "bgpd/rfapi/vnc_zebra.h"
31
#include "bgpd/rfapi/vnc_export_bgp.h"
32
#include "bgpd/rfapi/vnc_export_bgp_p.h"
33
#include "bgpd/rfapi/rfapi_vty.h"
34
#include "bgpd/rfapi/vnc_import_bgp.h"
35
#include "bgpd/rfapi/vnc_debug.h"
36
37
#ifdef ENABLE_BGP_VNC
38
39
#undef BGP_VNC_DEBUG_MATCH_GROUP
40
41
42
DEFINE_MGROUP(RFAPI, "rfapi");
43
2
DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration");
44
2
DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration");
45
2
DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration");
46
2
DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration");
47
2
DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic");
48
2
DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor");
49
2
DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table");
50
2
DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN");
51
2
DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap");
52
2
DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop");
53
2
DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option");
54
2
DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option");
55
2
DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw");
56
2
DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName");
57
2
DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data");
58
2
DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info");
59
2
DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address");
60
2
DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag");
61
2
DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra");
62
2
DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info");
63
2
DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr");
64
2
DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue");
65
2
DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route");
66
2
DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option");
67
2
DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix");
68
2
DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet");
69
2
70
2
DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg);
71
2
DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg);
72
2
/***********************************************************************
73
2
 *      RFAPI Support
74
2
 ***********************************************************************/
75
2
76
2
77
2
/*
78
2
 * compaitibility to old quagga_time call
79
2
 * time_t value in terms of stabilised absolute time.
80
2
 * replacement for POSIX time()
81
2
 */
82
2
time_t rfapi_time(time_t *t)
83
2
{
84
0
  time_t clock = monotime(NULL);
85
0
  if (t)
86
0
    *t = clock;
87
0
  return clock;
88
0
}
89
90
void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, struct list **nves,
91
         uint8_t family) /* AF_INET, AF_INET6 */
92
0
{
93
0
  struct listnode *hln;
94
0
  struct rfapi_descriptor *rfd;
95
96
  /*
97
   * loop over nves in this grp, add to list
98
   */
99
0
  for (ALL_LIST_ELEMENTS_RO(rfg->nves, hln, rfd)) {
100
0
    if (rfd->vn_addr.addr_family == family) {
101
0
      if (!*nves)
102
0
        *nves = list_new();
103
0
      listnode_add(*nves, rfd);
104
0
    }
105
0
  }
106
0
}
107
108
109
struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
110
                  struct prefix *vn,
111
                  struct prefix *un)
112
0
{
113
0
  struct rfapi_nve_group_cfg *rfg_vn = NULL;
114
0
  struct rfapi_nve_group_cfg *rfg_un = NULL;
115
116
0
  struct agg_table *rt_vn;
117
0
  struct agg_table *rt_un;
118
0
  struct agg_node *rn_vn;
119
0
  struct agg_node *rn_un;
120
121
0
  struct rfapi_nve_group_cfg *rfg;
122
0
  struct listnode *node, *nnode;
123
124
0
  switch (vn->family) {
125
0
  case AF_INET:
126
0
    rt_vn = hc->nve_groups_vn[AFI_IP];
127
0
    break;
128
0
  case AF_INET6:
129
0
    rt_vn = hc->nve_groups_vn[AFI_IP6];
130
0
    break;
131
0
  default:
132
0
    return NULL;
133
0
  }
134
135
0
  switch (un->family) {
136
0
  case AF_INET:
137
0
    rt_un = hc->nve_groups_un[AFI_IP];
138
0
    break;
139
0
  case AF_INET6:
140
0
    rt_un = hc->nve_groups_un[AFI_IP6];
141
0
    break;
142
0
  default:
143
0
    return NULL;
144
0
  }
145
146
0
  rn_vn = agg_node_match(rt_vn, vn); /* NB locks node */
147
0
  if (rn_vn) {
148
0
    rfg_vn = rn_vn->info;
149
0
    agg_unlock_node(rn_vn);
150
0
  }
151
152
0
  rn_un = agg_node_match(rt_un, un); /* NB locks node */
153
0
  if (rn_un) {
154
0
    rfg_un = rn_un->info;
155
0
    agg_unlock_node(rn_un);
156
0
  }
157
158
#ifdef BGP_VNC_DEBUG_MATCH_GROUP
159
  {
160
    vnc_zlog_debug_verbose("%s: vn prefix: %pFX", __func__, vn);
161
    vnc_zlog_debug_verbose("%s: un prefix: %pFX", __func__, un);
162
    vnc_zlog_debug_verbose(
163
      "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p",
164
      __func__, rn_vn, rn_un, rfg_vn, rfg_un);
165
  }
166
#endif
167
168
169
0
  if (rfg_un == rfg_vn) /* same group */
170
0
    return rfg_un;
171
0
  if (!rfg_un) /* un doesn't match, return vn-matched grp */
172
0
    return rfg_vn;
173
0
  if (!rfg_vn) /* vn doesn't match, return un-matched grp */
174
0
    return rfg_un;
175
176
  /*
177
   * Two different nve groups match: the group configured earlier wins.
178
   * For now, just walk the sequential list and pick the first one.
179
   * If this approach is too slow, then store serial numbers in the
180
   * nve group structures as they are defined and just compare
181
   * serial numbers.
182
   */
183
0
  for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) {
184
0
    if ((rfg == rfg_un) || (rfg == rfg_vn)) {
185
0
      return rfg;
186
0
    }
187
0
  }
188
0
  vnc_zlog_debug_verbose(
189
0
    "%s: shouldn't happen, returning NULL when un and vn match",
190
0
    __func__);
191
0
  return NULL; /* shouldn't happen */
192
0
}
193
194
/*------------------------------------------
195
 * rfapi_get_rfp_start_val
196
 *
197
 * Returns value passed to rfapi on rfp_start
198
 *
199
 * input:
200
 *  void *    bgp structure
201
 *
202
 * returns:
203
 *  void *
204
 *------------------------------------------*/
205
void *rfapi_get_rfp_start_val(void *bgpv)
206
0
{
207
0
  struct bgp *bgp = bgpv;
208
0
  if (bgp == NULL || bgp->rfapi == NULL)
209
0
    return NULL;
210
0
  return bgp->rfapi->rfp;
211
0
}
212
213
/*------------------------------------------
214
 * bgp_rfapi_is_vnc_configured
215
 *
216
 * Returns if VNC is configured
217
 *
218
 * input:
219
 *    bgp        NULL (=use default instance)
220
 *
221
 * output:
222
 *
223
 * return value: If VNC is configured for the bgpd instance
224
 *  0   Success
225
 *      EPERM   Not Default instance (VNC operations not allowed)
226
 *  ENXIO   VNC not configured
227
 --------------------------------------------*/
228
int bgp_rfapi_is_vnc_configured(struct bgp *bgp)
229
0
{
230
0
  if (bgp == NULL)
231
0
    bgp = bgp_get_default();
232
233
0
  if (bgp && bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
234
0
    return EPERM;
235
236
0
  if (bgp && bgp->rfapi_cfg)
237
0
    return 0;
238
0
  return ENXIO;
239
0
}
240
241
/***********************************************************************
242
 *      VNC Configuration/CLI
243
 ***********************************************************************/
244
#define VNC_VTY_CONFIG_CHECK(bgp)                                                            \
245
0
  {                                                                                    \
246
0
    switch (bgp_rfapi_is_vnc_configured(bgp)) {                                  \
247
0
    case EPERM:                                                                  \
248
0
      vty_out(vty,                                                         \
249
0
        "VNC operations only permitted on default BGP instance.\n"); \
250
0
      return CMD_WARNING_CONFIG_FAILED;                                    \
251
0
      break;                                                               \
252
0
    case ENXIO:                                                                  \
253
0
      vty_out(vty, "VNC not configured.\n");                               \
254
0
      return CMD_WARNING_CONFIG_FAILED;                                    \
255
0
      break;                                                               \
256
0
    default:                                                                     \
257
0
      break;                                                               \
258
0
    }                                                                            \
259
0
  }
260
261
DEFUN (vnc_advertise_un_method,
262
       vnc_advertise_un_method_cmd,
263
       "vnc advertise-un-method encap-attr",
264
       VNC_CONFIG_STR
265
       "Method of advertising UN addresses\n"
266
       "Via Tunnel Encap attribute (in VPN SAFI)\n")
267
0
{
268
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
269
0
  VNC_VTY_CONFIG_CHECK(bgp);
270
271
0
  if (!strncmp(argv[2]->arg, "encap-safi", 7)) {
272
0
    bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
273
0
  } else {
274
0
    bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
275
0
  }
276
277
0
  return CMD_SUCCESS;
278
0
}
279
280
/*-------------------------------------------------------------------------
281
 *      RFG defaults
282
 *-----------------------------------------------------------------------*/
283
284
285
DEFUN_NOSH (vnc_defaults,
286
      vnc_defaults_cmd,
287
      "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n")
288
0
{
289
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
290
0
  VNC_VTY_CONFIG_CHECK(bgp);
291
0
  if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
292
0
    vty_out(vty, "Malformed community-list value\n");
293
0
    return CMD_WARNING_CONFIG_FAILED;
294
0
  }
295
0
  vty->node = BGP_VNC_DEFAULTS_NODE;
296
0
  return CMD_SUCCESS;
297
0
}
298
299
static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
300
       struct ecommunity **list)
301
0
{
302
0
  struct ecommunity *ecom = NULL;
303
0
  struct ecommunity *ecomadd;
304
305
0
  for (; argc; --argc, ++argv) {
306
307
0
    ecomadd = ecommunity_str2com(argv[0]->arg,
308
0
               ECOMMUNITY_ROUTE_TARGET, 0);
309
0
    if (!ecomadd) {
310
0
      vty_out(vty, "Malformed community-list value\n");
311
0
      if (ecom)
312
0
        ecommunity_free(&ecom);
313
0
      return CMD_WARNING_CONFIG_FAILED;
314
0
    }
315
316
0
    if (ecom) {
317
0
      ecommunity_merge(ecom, ecomadd);
318
0
      ecommunity_free(&ecomadd);
319
0
    } else {
320
0
      ecom = ecomadd;
321
0
    }
322
0
  }
323
324
0
  if (*list) {
325
0
    ecommunity_free(&*list);
326
0
  }
327
0
  *list = ecom;
328
329
0
  return CMD_SUCCESS;
330
0
}
331
332
DEFUN (vnc_defaults_rt_import,
333
       vnc_defaults_rt_import_cmd,
334
       "rt import RTLIST...",
335
       "Specify default route targets\n"
336
       "Import filter\n"
337
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
338
0
{
339
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
340
0
  return set_ecom_list(vty, argc - 2, argv + 2,
341
0
           &bgp->rfapi_cfg->default_rt_import_list);
342
0
}
343
344
DEFUN (vnc_defaults_rt_export,
345
       vnc_defaults_rt_export_cmd,
346
       "rt export RTLIST...",
347
       "Configure default route targets\n"
348
       "Export filter\n"
349
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
350
0
{
351
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
352
0
  return set_ecom_list(vty, argc - 2, argv + 2,
353
0
           &bgp->rfapi_cfg->default_rt_export_list);
354
0
}
355
356
DEFUN (vnc_defaults_rt_both,
357
       vnc_defaults_rt_both_cmd,
358
       "rt both RTLIST...",
359
       "Configure default route targets\n"
360
       "Export+import filters\n"
361
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
362
0
{
363
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
364
0
  int rc;
365
366
0
  rc = set_ecom_list(vty, argc - 2, argv + 2,
367
0
         &bgp->rfapi_cfg->default_rt_import_list);
368
0
  if (rc != CMD_SUCCESS)
369
0
    return rc;
370
0
  return set_ecom_list(vty, argc - 2, argv + 2,
371
0
           &bgp->rfapi_cfg->default_rt_export_list);
372
0
}
373
374
DEFUN (vnc_defaults_rd,
375
       vnc_defaults_rd_cmd,
376
       "rd ASN:NN_OR_IP-ADDRESS:NN",
377
       "Specify default route distinguisher\n"
378
       "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
379
0
{
380
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
381
0
  int ret;
382
0
  struct prefix_rd prd;
383
384
0
  if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
385
    /*
386
     * use AF_UNIX to designate automatically-assigned RD
387
     * auto:vn:nn where nn is a 2-octet quantity
388
     */
389
0
    char *end = NULL;
390
0
    uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
391
0
    uint16_t value = value32 & 0xffff;
392
393
0
    if (!argv[1]->arg[8] || *end) {
394
0
      vty_out(vty, "%% Malformed rd\n");
395
0
      return CMD_WARNING_CONFIG_FAILED;
396
0
    }
397
0
    if (value32 > 0xffff) {
398
0
      vty_out(vty, "%% Malformed rd (must be less than %u\n",
399
0
        0x0ffff);
400
0
      return CMD_WARNING_CONFIG_FAILED;
401
0
    }
402
403
0
    memset(&prd, 0, sizeof(prd));
404
0
    prd.family = AF_UNIX;
405
0
    prd.prefixlen = 64;
406
0
    prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
407
0
    prd.val[1] = RD_TYPE_IP & 0x0ff;
408
0
    prd.val[6] = (value >> 8) & 0x0ff;
409
0
    prd.val[7] = value & 0x0ff;
410
411
0
  } else {
412
413
    /* TODO: save RD format */
414
0
    ret = str2prefix_rd(argv[1]->arg, &prd);
415
0
    if (!ret) {
416
0
      vty_out(vty, "%% Malformed rd\n");
417
0
      return CMD_WARNING_CONFIG_FAILED;
418
0
    }
419
0
  }
420
421
0
  bgp->rfapi_cfg->default_rd = prd;
422
0
  return CMD_SUCCESS;
423
0
}
424
425
DEFUN (vnc_defaults_l2rd,
426
       vnc_defaults_l2rd_cmd,
427
       "l2rd <(1-255)|auto-vn>",
428
       "Specify default Local Nve ID value to use in RD for L2 routes\n"
429
       "Fixed value 1-255\n"
430
       "use the low-order octet of the NVE's VN address\n")
431
0
{
432
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
433
0
  uint8_t value = 0;
434
435
0
  if (strmatch(argv[1]->text, "auto-vn")) {
436
0
    value = 0;
437
0
  } else {
438
0
    char *end = NULL;
439
0
    unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
440
441
0
    value = value_l & 0xff;
442
0
    if (!argv[1]->arg[0] || *end) {
443
0
      vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
444
0
        argv[1]->arg);
445
0
      return CMD_WARNING_CONFIG_FAILED;
446
0
    }
447
0
    if ((value_l < 1) || (value_l > 0xff)) {
448
0
      vty_out(vty,
449
0
        "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
450
0
        0x100);
451
0
      return CMD_WARNING_CONFIG_FAILED;
452
0
    }
453
0
  }
454
0
  bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD;
455
0
  bgp->rfapi_cfg->default_l2rd = value;
456
457
0
  return CMD_SUCCESS;
458
0
}
459
460
DEFUN (vnc_defaults_no_l2rd,
461
       vnc_defaults_no_l2rd_cmd,
462
       "no l2rd",
463
       NO_STR
464
       "Specify default Local Nve ID value to use in RD for L2 routes\n")
465
0
{
466
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
467
468
0
  bgp->rfapi_cfg->default_l2rd = 0;
469
0
  bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD;
470
471
0
  return CMD_SUCCESS;
472
0
}
473
474
DEFUN (vnc_defaults_responselifetime,
475
       vnc_defaults_responselifetime_cmd,
476
       "response-lifetime <LIFETIME|infinite>",
477
       "Specify default response lifetime\n"
478
       "Response lifetime in seconds\n" "Infinite response lifetime\n")
479
0
{
480
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
481
0
  uint32_t rspint;
482
0
  struct rfapi *h = NULL;
483
0
  struct listnode *hdnode;
484
0
  struct rfapi_descriptor *rfd;
485
486
0
  h = bgp->rfapi;
487
0
  if (!h)
488
0
    return CMD_WARNING_CONFIG_FAILED;
489
490
0
  if (strmatch(argv[1]->text, "infinite")) {
491
0
    rspint = RFAPI_INFINITE_LIFETIME;
492
0
  } else {
493
0
    rspint = strtoul(argv[1]->arg, NULL, 10);
494
0
    if (rspint > INT32_MAX)
495
0
      rspint = INT32_MAX; /* is really an int, not an unsigned
496
                 int */
497
0
  }
498
499
0
  bgp->rfapi_cfg->default_response_lifetime = rspint;
500
501
0
  for (ALL_LIST_ELEMENTS_RO(&h->descriptors, hdnode, rfd))
502
0
    if (rfd->rfg
503
0
        && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME))
504
0
      rfd->response_lifetime = rfd->rfg->response_lifetime =
505
0
        rspint;
506
507
0
  return CMD_SUCCESS;
508
0
}
509
510
struct rfapi_nve_group_cfg *
511
bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name,
512
         rfapi_group_cfg_type_t type) /* _MAX = any */
513
0
{
514
0
  struct rfapi_nve_group_cfg *rfg;
515
0
  struct listnode *node, *nnode;
516
517
0
  for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node,
518
0
             nnode, rfg)) {
519
0
    if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type)
520
0
        && !strcmp(rfg->name, name))
521
0
      return rfg;
522
0
  }
523
0
  return NULL;
524
0
}
525
526
static struct rfapi_nve_group_cfg *
527
rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name)
528
0
{
529
0
  struct rfapi_nve_group_cfg *rfg;
530
531
0
  rfg = XCALLOC(MTYPE_RFAPI_GROUP_CFG,
532
0
          sizeof(struct rfapi_nve_group_cfg));
533
0
  rfg->type = type;
534
0
  rfg->name = strdup(name);
535
  /* add to tail of list */
536
0
  listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg);
537
0
  rfg->label = MPLS_LABEL_NONE;
538
539
0
  QOBJ_REG(rfg, rfapi_nve_group_cfg);
540
541
0
  return rfg;
542
0
}
543
544
static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp,
545
                     const char *name)
546
0
{
547
0
  struct rfapi_l2_group_cfg *rfg;
548
0
  struct listnode *node, *nnode;
549
550
0
  if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
551
0
    bgp->rfapi_cfg->l2_groups = list_new();
552
553
0
  for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) {
554
0
    if (!strcmp(rfg->name, name))
555
0
      return rfg;
556
0
  }
557
0
  return NULL;
558
0
}
559
560
static struct rfapi_l2_group_cfg *rfapi_l2_group_new(void)
561
0
{
562
0
  struct rfapi_l2_group_cfg *rfg;
563
564
0
  rfg = XCALLOC(MTYPE_RFAPI_L2_CFG, sizeof(struct rfapi_l2_group_cfg));
565
0
  QOBJ_REG(rfg, rfapi_l2_group_cfg);
566
567
0
  return rfg;
568
0
}
569
570
static void rfapi_l2_group_del(struct rfapi_l2_group_cfg *rfg)
571
0
{
572
0
  QOBJ_UNREG(rfg);
573
0
  XFREE(MTYPE_RFAPI_L2_CFG, rfg);
574
0
}
575
576
static int rfapi_str2route_type(const char *l3str, const char *pstr, afi_t *afi,
577
        int *type)
578
0
{
579
0
  if (!l3str || !pstr)
580
0
    return EINVAL;
581
582
0
  if (!strcmp(l3str, "ipv4")) {
583
0
    *afi = AFI_IP;
584
0
  } else {
585
0
    if (!strcmp(l3str, "ipv6"))
586
0
      *afi = AFI_IP6;
587
0
    else
588
0
      return ENOENT;
589
0
  }
590
591
0
  if (!strcmp(pstr, "connected"))
592
0
    *type = ZEBRA_ROUTE_CONNECT;
593
0
  if (!strcmp(pstr, "kernel"))
594
0
    *type = ZEBRA_ROUTE_KERNEL;
595
0
  if (!strcmp(pstr, "static"))
596
0
    *type = ZEBRA_ROUTE_STATIC;
597
0
  if (!strcmp(pstr, "bgp"))
598
0
    *type = ZEBRA_ROUTE_BGP;
599
0
  if (!strcmp(pstr, "bgp-direct"))
600
0
    *type = ZEBRA_ROUTE_BGP_DIRECT;
601
0
  if (!strcmp(pstr, "bgp-direct-to-nve-groups"))
602
0
    *type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
603
604
0
  if (!strcmp(pstr, "rip")) {
605
0
    if (*afi == AFI_IP)
606
0
      *type = ZEBRA_ROUTE_RIP;
607
0
    else
608
0
      *type = ZEBRA_ROUTE_RIPNG;
609
0
  }
610
611
0
  if (!strcmp(pstr, "ripng")) {
612
0
    if (*afi == AFI_IP)
613
0
      return EAFNOSUPPORT;
614
0
    *type = ZEBRA_ROUTE_RIPNG;
615
0
  }
616
617
0
  if (!strcmp(pstr, "ospf")) {
618
0
    if (*afi == AFI_IP)
619
0
      *type = ZEBRA_ROUTE_OSPF;
620
0
    else
621
0
      *type = ZEBRA_ROUTE_OSPF6;
622
0
  }
623
624
0
  if (!strcmp(pstr, "ospf6")) {
625
0
    if (*afi == AFI_IP)
626
0
      return EAFNOSUPPORT;
627
0
    *type = ZEBRA_ROUTE_OSPF6;
628
0
  }
629
630
0
  return 0;
631
0
}
632
633
/*-------------------------------------------------------------------------
634
 *      redistribute
635
 *-----------------------------------------------------------------------*/
636
637
#define VNC_REDIST_ENABLE(bgp, afi, type)                                      \
638
0
  do {                                                                   \
639
0
    switch (type) {                                                \
640
0
    case ZEBRA_ROUTE_BGP_DIRECT:                                   \
641
0
      vnc_import_bgp_redist_enable((bgp), (afi));            \
642
0
      break;                                                 \
643
0
    case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \
644
0
      vnc_import_bgp_exterior_redist_enable((bgp), (afi));   \
645
0
      break;                                                 \
646
0
    default:                                                       \
647
0
      if ((type) < ZEBRA_ROUTE_MAX)            \
648
0
        vnc_redistribute_set((bgp), (afi), (type));    \
649
0
      break;                                                 \
650
0
    }                                                              \
651
0
  } while (0)
652
653
#define VNC_REDIST_DISABLE(bgp, afi, type)                                     \
654
0
  do {                                                                   \
655
0
    switch (type) {                                                \
656
0
    case ZEBRA_ROUTE_BGP_DIRECT:                                   \
657
0
      vnc_import_bgp_redist_disable((bgp), (afi));           \
658
0
      break;                                                 \
659
0
    case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \
660
0
      vnc_import_bgp_exterior_redist_disable((bgp), (afi));  \
661
0
      break;                                                 \
662
0
    default:                                                       \
663
0
      if ((type) < ZEBRA_ROUTE_MAX)            \
664
0
        vnc_redistribute_unset((bgp), (afi), (type));  \
665
0
      break;                                                 \
666
0
    }                                                              \
667
0
  } while (0)
668
669
static uint8_t redist_was_enabled[AFI_MAX][ZEBRA_ROUTE_MAX];
670
671
static void vnc_redistribute_prechange(struct bgp *bgp)
672
0
{
673
0
  afi_t afi;
674
0
  int type;
675
676
0
  vnc_zlog_debug_verbose("%s: entry", __func__);
677
0
  memset(redist_was_enabled, 0, sizeof(redist_was_enabled));
678
679
  /*
680
   * Look to see if we have any redistribution enabled. If so, flush
681
   * the corresponding routes and turn off redistribution temporarily.
682
   * We need to do it because the RD's used for the redistributed
683
   * routes depend on the nve group.
684
   */
685
0
  for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
686
0
    for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
687
0
      if (bgp->rfapi_cfg->redist[afi][type]) {
688
0
        redist_was_enabled[afi][type] = 1;
689
0
        VNC_REDIST_DISABLE(bgp, afi, type);
690
0
      }
691
0
    }
692
0
  }
693
0
  vnc_zlog_debug_verbose("%s: return", __func__);
694
0
}
695
696
static void vnc_redistribute_postchange(struct bgp *bgp)
697
0
{
698
0
  afi_t afi;
699
0
  int type;
700
701
0
  vnc_zlog_debug_verbose("%s: entry", __func__);
702
  /*
703
   * If we turned off redistribution above, turn it back on. Doing so
704
   * will tell zebra to resend the routes to us
705
   */
706
0
  for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
707
0
    for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
708
0
      if (redist_was_enabled[afi][type]) {
709
0
        VNC_REDIST_ENABLE(bgp, afi, type);
710
0
      }
711
0
    }
712
0
  }
713
0
  vnc_zlog_debug_verbose("%s: return", __func__);
714
0
}
715
716
DEFUN (vnc_redistribute_rh_roo_localadmin,
717
       vnc_redistribute_rh_roo_localadmin_cmd,
718
       "vnc redistribute resolve-nve roo-ec-local-admin (0-65535)",
719
       VNC_CONFIG_STR
720
       "Redistribute routes into VNC\n"
721
       "Resolve-NVE mode\n"
722
       "Route Origin Extended Community Local Admin Field\n" "Field value\n")
723
0
{
724
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
725
0
  uint32_t localadmin;
726
0
  char *endptr;
727
728
0
  VNC_VTY_CONFIG_CHECK(bgp);
729
730
0
  localadmin = strtoul(argv[4]->arg, &endptr, 0);
731
0
  if (!argv[4]->arg[0] || *endptr) {
732
0
    vty_out(vty, "%% Malformed value\n");
733
0
    return CMD_WARNING_CONFIG_FAILED;
734
0
  }
735
736
0
  if (localadmin > 0xffff) {
737
0
    vty_out(vty, "%% Value out of range (0-%d)\n", 0xffff);
738
0
    return CMD_WARNING_CONFIG_FAILED;
739
0
  }
740
741
0
  if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin)
742
0
    return CMD_SUCCESS;
743
744
0
  if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
745
0
      == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
746
747
0
    vnc_export_bgp_prechange(bgp);
748
0
  }
749
0
  vnc_redistribute_prechange(bgp);
750
751
0
  bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin;
752
753
0
  if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
754
0
      == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
755
756
0
    vnc_export_bgp_postchange(bgp);
757
0
  }
758
0
  vnc_redistribute_postchange(bgp);
759
760
0
  return CMD_SUCCESS;
761
0
}
762
763
764
DEFUN (vnc_redistribute_mode,
765
       vnc_redistribute_mode_cmd,
766
       "vnc redistribute mode <nve-group|plain|resolve-nve>",
767
       VNC_CONFIG_STR
768
       "Redistribute routes into VNC\n"
769
       "Redistribution mode\n"
770
       "Based on redistribute nve-group\n"
771
       "Unmodified\n" "Resolve each nexthop to connected NVEs\n")
772
0
{
773
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
774
0
  vnc_redist_mode_t newmode;
775
776
0
  VNC_VTY_CONFIG_CHECK(bgp);
777
778
0
  switch (argv[3]->arg[0]) {
779
0
  case 'n':
780
0
    newmode = VNC_REDIST_MODE_RFG;
781
0
    break;
782
783
0
  case 'p':
784
0
    newmode = VNC_REDIST_MODE_PLAIN;
785
0
    break;
786
787
0
  case 'r':
788
0
    newmode = VNC_REDIST_MODE_RESOLVE_NVE;
789
0
    break;
790
791
0
  default:
792
0
    vty_out(vty, "unknown redistribute mode\n");
793
0
    return CMD_WARNING_CONFIG_FAILED;
794
0
  }
795
796
0
  if (newmode != bgp->rfapi_cfg->redist_mode) {
797
0
    vnc_redistribute_prechange(bgp);
798
0
    bgp->rfapi_cfg->redist_mode = newmode;
799
0
    vnc_redistribute_postchange(bgp);
800
0
  }
801
802
0
  return CMD_SUCCESS;
803
0
}
804
805
DEFUN (vnc_redistribute_protocol,
806
       vnc_redistribute_protocol_cmd,
807
       "vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
808
       VNC_CONFIG_STR
809
       "Redistribute routes into VNC\n"
810
       "IPv4 routes\n"
811
       "IPv6 routes\n"
812
       "From BGP\n"
813
       "From BGP without Zebra\n"
814
       "From BGP without Zebra, only to configured NVE groups\n"
815
       "Connected interfaces\n"
816
       "From kernel routes\n"
817
       "From Open Shortest Path First (OSPF)\n"
818
       "From Routing Information Protocol (RIP)\n" "From Static routes\n")
819
0
{
820
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
821
0
  int type = ZEBRA_ROUTE_MAX; /* init to bogus value */
822
0
  afi_t afi;
823
824
0
  VNC_VTY_CONFIG_CHECK(bgp);
825
826
0
  if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) {
827
0
    vty_out(vty, "%% Invalid route type\n");
828
0
    return CMD_WARNING_CONFIG_FAILED;
829
0
  }
830
831
0
  if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
832
0
    if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
833
0
      VNC_REDIST_DISABLE(bgp, afi,
834
0
             type); /* disabled view implicitly */
835
0
      free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
836
0
      bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
837
0
    }
838
0
    bgp->rfapi_cfg->redist_bgp_exterior_view = bgp;
839
0
  }
840
841
0
  VNC_REDIST_ENABLE(bgp, afi, type);
842
843
0
  return CMD_SUCCESS;
844
0
}
845
846
DEFUN (vnc_no_redistribute_protocol,
847
       vnc_no_redistribute_protocol_cmd,
848
       "no vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
849
       NO_STR
850
       VNC_CONFIG_STR
851
       "Redistribute from other protocol\n"
852
       "IPv4 routes\n"
853
       "IPv6 routes\n"
854
       "From BGP\n"
855
       "From BGP without Zebra\n"
856
       "From BGP without Zebra, only to configured NVE groups\n"
857
       "Connected interfaces\n"
858
       "From kernel routes\n"
859
       "From Open Shortest Path First (OSPF)\n"
860
       "From Routing Information Protocol (RIP)\n" "From Static routes\n")
861
0
{
862
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
863
0
  int type;
864
0
  afi_t afi;
865
866
0
  VNC_VTY_CONFIG_CHECK(bgp);
867
868
0
  if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) {
869
0
    vty_out(vty, "%% Invalid route type\n");
870
0
    return CMD_WARNING_CONFIG_FAILED;
871
0
  }
872
873
0
  VNC_REDIST_DISABLE(bgp, afi, type);
874
875
0
  if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
876
0
    if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
877
0
      free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
878
0
      bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
879
0
    }
880
0
    bgp->rfapi_cfg->redist_bgp_exterior_view = NULL;
881
0
  }
882
883
0
  return CMD_SUCCESS;
884
0
}
885
886
DEFUN (vnc_redistribute_bgp_exterior,
887
       vnc_redistribute_bgp_exterior_cmd,
888
       "vnc redistribute <ipv4|ipv6> bgp-direct-to-nve-groups view NAME",
889
       VNC_CONFIG_STR
890
       "Redistribute routes into VNC\n"
891
       "IPv4 routes\n"
892
       "IPv6 routes\n"
893
       "From BGP without Zebra, only to configured NVE groups\n"
894
       "From BGP view\n" "BGP view name\n")
895
0
{
896
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
897
0
  int type;
898
0
  afi_t afi;
899
900
0
  VNC_VTY_CONFIG_CHECK(bgp);
901
902
0
  if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi,
903
0
         &type)) {
904
0
    vty_out(vty, "%% Invalid route type\n");
905
0
    return CMD_WARNING_CONFIG_FAILED;
906
0
  }
907
908
0
  if (bgp->rfapi_cfg->redist_bgp_exterior_view_name)
909
0
    free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
910
0
  bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup(argv[5]->arg);
911
  /* could be NULL if name is not defined yet */
912
0
  bgp->rfapi_cfg->redist_bgp_exterior_view =
913
0
    bgp_lookup_by_name(argv[5]->arg);
914
915
0
  VNC_REDIST_ENABLE(bgp, afi, type);
916
917
0
  return CMD_SUCCESS;
918
0
}
919
920
DEFUN (vnc_redistribute_nvegroup,
921
       vnc_redistribute_nvegroup_cmd,
922
       "vnc redistribute nve-group NAME",
923
       VNC_CONFIG_STR
924
       "Assign a NVE group to routes redistributed from another routing protocol\n"
925
       "NVE group\n" "Group name\n")
926
0
{
927
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
928
0
  VNC_VTY_CONFIG_CHECK(bgp);
929
930
0
  vnc_redistribute_prechange(bgp);
931
932
  /*
933
   * OK if nve group doesn't exist yet; we'll set the pointer
934
   * when the group is defined later
935
   */
936
0
  bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname(
937
0
    bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE);
938
0
  if (bgp->rfapi_cfg->rfg_redist_name)
939
0
    free(bgp->rfapi_cfg->rfg_redist_name);
940
0
  bgp->rfapi_cfg->rfg_redist_name = strdup(argv[3]->arg);
941
942
0
  vnc_redistribute_postchange(bgp);
943
944
0
  return CMD_SUCCESS;
945
0
}
946
947
DEFUN (vnc_redistribute_no_nvegroup,
948
       vnc_redistribute_no_nvegroup_cmd,
949
       "no vnc redistribute nve-group",
950
       NO_STR
951
       VNC_CONFIG_STR
952
       "Redistribute from other protocol\n"
953
       "Assign a NVE group to routes redistributed from another routing protocol\n")
954
0
{
955
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
956
957
0
  VNC_VTY_CONFIG_CHECK(bgp);
958
959
0
  vnc_redistribute_prechange(bgp);
960
961
0
  bgp->rfapi_cfg->rfg_redist = NULL;
962
0
  if (bgp->rfapi_cfg->rfg_redist_name)
963
0
    free(bgp->rfapi_cfg->rfg_redist_name);
964
0
  bgp->rfapi_cfg->rfg_redist_name = NULL;
965
966
0
  vnc_redistribute_postchange(bgp);
967
968
0
  return CMD_SUCCESS;
969
0
}
970
971
972
DEFUN (vnc_redistribute_lifetime,
973
       vnc_redistribute_lifetime_cmd,
974
       "vnc redistribute lifetime <LIFETIME|infinite>",
975
       VNC_CONFIG_STR
976
       "Redistribute\n"
977
       "Assign a lifetime to routes redistributed from another routing protocol\n"
978
       "lifetime value (32 bit)\n"
979
       "Allow lifetime to never expire\n")
980
0
{
981
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
982
0
  VNC_VTY_CONFIG_CHECK(bgp);
983
984
0
  vnc_redistribute_prechange(bgp);
985
986
0
  if (strmatch(argv[3]->text, "infinite")) {
987
0
    bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME;
988
0
  } else {
989
0
    bgp->rfapi_cfg->redist_lifetime =
990
0
      strtoul(argv[3]->arg, NULL, 10);
991
0
  }
992
993
0
  vnc_redistribute_postchange(bgp);
994
995
0
  return CMD_SUCCESS;
996
0
}
997
998
/*-- redist policy, non-nvegroup start --*/
999
1000
DEFUN (vnc_redist_bgpdirect_no_prefixlist,
1001
       vnc_redist_bgpdirect_no_prefixlist_cmd,
1002
       "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list",
1003
       NO_STR
1004
       VNC_CONFIG_STR
1005
       "Redistribute from other protocol\n"
1006
       "Redistribute from BGP directly\n"
1007
       "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1008
       "IPv4 routes\n"
1009
       "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
1010
0
{
1011
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1012
0
  afi_t afi;
1013
0
  struct rfapi_cfg *hc;
1014
0
  uint8_t route_type = 0;
1015
1016
0
  VNC_VTY_CONFIG_CHECK(bgp);
1017
0
  hc = bgp->rfapi_cfg;
1018
1019
0
  if (strmatch(argv[3]->text, "bgp-direct")) {
1020
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT;
1021
0
  } else {
1022
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1023
0
  }
1024
1025
0
  if (strmatch(argv[4]->text, "ipv4")) {
1026
0
    afi = AFI_IP;
1027
0
  } else {
1028
0
    afi = AFI_IP6;
1029
0
  }
1030
1031
0
  vnc_redistribute_prechange(bgp);
1032
1033
0
  if (hc->plist_redist_name[route_type][afi])
1034
0
    free(hc->plist_redist_name[route_type][afi]);
1035
0
  hc->plist_redist_name[route_type][afi] = NULL;
1036
0
  hc->plist_redist[route_type][afi] = NULL;
1037
1038
0
  vnc_redistribute_postchange(bgp);
1039
1040
0
  return CMD_SUCCESS;
1041
0
}
1042
1043
DEFUN (vnc_redist_bgpdirect_prefixlist,
1044
       vnc_redist_bgpdirect_prefixlist_cmd,
1045
       "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list NAME",
1046
       VNC_CONFIG_STR
1047
       "Redistribute from other protocol\n"
1048
       "Redistribute from BGP directly\n"
1049
       "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1050
       "IPv4 routes\n"
1051
       "IPv6 routes\n"
1052
       "Prefix-list for filtering redistributed routes\n"
1053
       "prefix list name\n")
1054
0
{
1055
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1056
0
  struct rfapi_cfg *hc;
1057
0
  afi_t afi;
1058
0
  uint8_t route_type = 0;
1059
1060
0
  VNC_VTY_CONFIG_CHECK(bgp);
1061
0
  hc = bgp->rfapi_cfg;
1062
1063
0
  if (strmatch(argv[2]->text, "bgp-direct")) {
1064
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT;
1065
0
  } else {
1066
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1067
0
  }
1068
1069
0
  if (strmatch(argv[3]->text, "ipv4")) {
1070
0
    afi = AFI_IP;
1071
0
  } else {
1072
0
    afi = AFI_IP6;
1073
0
  }
1074
1075
0
  vnc_redistribute_prechange(bgp);
1076
1077
0
  if (hc->plist_redist_name[route_type][afi])
1078
0
    free(hc->plist_redist_name[route_type][afi]);
1079
0
  hc->plist_redist_name[route_type][afi] = strdup(argv[5]->arg);
1080
0
  hc->plist_redist[route_type][afi] =
1081
0
    prefix_list_lookup(afi, argv[5]->arg);
1082
1083
0
  vnc_redistribute_postchange(bgp);
1084
1085
0
  return CMD_SUCCESS;
1086
0
}
1087
1088
DEFUN (vnc_redist_bgpdirect_no_routemap,
1089
       vnc_redist_bgpdirect_no_routemap_cmd,
1090
       "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map",
1091
       NO_STR
1092
       VNC_CONFIG_STR
1093
       "Redistribute from other protocols\n"
1094
       "Redistribute from BGP directly\n"
1095
       "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1096
       "Route-map for filtering redistributed routes\n")
1097
0
{
1098
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1099
0
  struct rfapi_cfg *hc;
1100
0
  uint8_t route_type = 0;
1101
1102
0
  VNC_VTY_CONFIG_CHECK(bgp);
1103
0
  hc = bgp->rfapi_cfg;
1104
1105
0
  if (strmatch(argv[3]->text, "bgp-direct")) {
1106
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT;
1107
0
  } else {
1108
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1109
0
  }
1110
1111
0
  vnc_redistribute_prechange(bgp);
1112
1113
0
  if (hc->routemap_redist_name[route_type])
1114
0
    free(hc->routemap_redist_name[route_type]);
1115
0
  hc->routemap_redist_name[route_type] = NULL;
1116
0
  hc->routemap_redist[route_type] = NULL;
1117
1118
0
  vnc_redistribute_postchange(bgp);
1119
1120
0
  return CMD_SUCCESS;
1121
0
}
1122
1123
DEFUN (vnc_redist_bgpdirect_routemap,
1124
       vnc_redist_bgpdirect_routemap_cmd,
1125
       "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map NAME",
1126
       VNC_CONFIG_STR
1127
       "Redistribute from other protocols\n"
1128
       "Redistribute from BGP directly\n"
1129
       "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1130
       "Route-map for filtering exported routes\n" "route map name\n")
1131
0
{
1132
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1133
0
  struct rfapi_cfg *hc;
1134
0
  uint8_t route_type = 0;
1135
1136
0
  VNC_VTY_CONFIG_CHECK(bgp);
1137
0
  hc = bgp->rfapi_cfg;
1138
1139
0
  if (strmatch(argv[2]->text, "bgp-direct")) {
1140
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT;
1141
0
  } else {
1142
0
    route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1143
0
  }
1144
1145
0
  vnc_redistribute_prechange(bgp);
1146
1147
0
  if (hc->routemap_redist_name[route_type])
1148
0
    free(hc->routemap_redist_name[route_type]);
1149
1150
  /* If the old route map config overwrite with new
1151
   * route map config , old routemap counter have to be
1152
   * reduced.
1153
   */
1154
0
  route_map_counter_decrement(hc->routemap_redist[route_type]);
1155
0
  hc->routemap_redist_name[route_type] = strdup(argv[4]->arg);
1156
0
  hc->routemap_redist[route_type] =
1157
0
    route_map_lookup_by_name(argv[4]->arg);
1158
0
  route_map_counter_increment(hc->routemap_redist[route_type]);
1159
1160
0
  vnc_redistribute_postchange(bgp);
1161
1162
0
  return CMD_SUCCESS;
1163
0
}
1164
1165
/*-- redist policy, non-nvegroup end --*/
1166
1167
/*-- redist policy, nvegroup start --*/
1168
1169
DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
1170
       vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd,
1171
       "no redistribute bgp-direct <ipv4|ipv6> prefix-list",
1172
       NO_STR
1173
       "Redistribute from other protocol\n"
1174
       "Redistribute from BGP directly\n"
1175
       "IPv4 routes\n"
1176
       "IPv6 routes\n"
1177
       "Prefix-list for filtering redistributed routes\n")
1178
0
{
1179
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1180
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg)
1181
0
  afi_t afi;
1182
1183
0
  VNC_VTY_CONFIG_CHECK(bgp);
1184
1185
  /* make sure it's still in list */
1186
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1187
    /* Not in list anymore */
1188
0
    vty_out(vty, "Current NVE group no longer exists\n");
1189
0
    return CMD_WARNING_CONFIG_FAILED;
1190
0
  }
1191
1192
0
  if (strmatch(argv[3]->text, "ipv4")) {
1193
0
    afi = AFI_IP;
1194
0
  } else {
1195
0
    afi = AFI_IP6;
1196
0
  }
1197
1198
0
  vnc_redistribute_prechange(bgp);
1199
1200
0
  if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
1201
0
    free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
1202
0
  rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
1203
0
  rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
1204
1205
0
  vnc_redistribute_postchange(bgp);
1206
1207
0
  return CMD_SUCCESS;
1208
0
}
1209
1210
DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
1211
       vnc_nve_group_redist_bgpdirect_prefixlist_cmd,
1212
       "redistribute bgp-direct <ipv4|ipv6> prefix-list NAME",
1213
       "Redistribute from other protocol\n"
1214
       "Redistribute from BGP directly\n"
1215
       "IPv4 routes\n"
1216
       "IPv6 routes\n"
1217
       "Prefix-list for filtering redistributed routes\n"
1218
       "prefix list name\n")
1219
0
{
1220
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1221
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1222
0
  afi_t afi;
1223
1224
0
  VNC_VTY_CONFIG_CHECK(bgp);
1225
1226
  /* make sure it's still in list */
1227
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1228
    /* Not in list anymore */
1229
0
    vty_out(vty, "Current NVE group no longer exists\n");
1230
0
    return CMD_WARNING_CONFIG_FAILED;
1231
0
  }
1232
1233
0
  if (strmatch(argv[2]->text, "ipv4")) {
1234
0
    afi = AFI_IP;
1235
0
  } else {
1236
0
    afi = AFI_IP6;
1237
0
  }
1238
1239
0
  vnc_redistribute_prechange(bgp);
1240
1241
0
  if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
1242
0
    free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
1243
0
  rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] =
1244
0
    strdup(argv[4]->arg);
1245
0
  rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] =
1246
0
    prefix_list_lookup(afi, argv[4]->arg);
1247
1248
0
  vnc_redistribute_postchange(bgp);
1249
1250
0
  return CMD_SUCCESS;
1251
0
}
1252
1253
DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap,
1254
       vnc_nve_group_redist_bgpdirect_no_routemap_cmd,
1255
       "no redistribute bgp-direct route-map",
1256
       NO_STR
1257
       "Redistribute from other protocols\n"
1258
       "Redistribute from BGP directly\n"
1259
       "Route-map for filtering redistributed routes\n")
1260
0
{
1261
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1262
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1263
1264
0
  VNC_VTY_CONFIG_CHECK(bgp);
1265
1266
  /* make sure it's still in list */
1267
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1268
    /* Not in list anymore */
1269
0
    vty_out(vty, "Current NVE group no longer exists\n");
1270
0
    return CMD_WARNING_CONFIG_FAILED;
1271
0
  }
1272
1273
0
  vnc_redistribute_prechange(bgp);
1274
1275
0
  if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
1276
0
    free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
1277
0
  route_map_counter_decrement(
1278
0
    rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1279
0
  rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
1280
0
  rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
1281
1282
0
  vnc_redistribute_postchange(bgp);
1283
1284
0
  return CMD_SUCCESS;
1285
0
}
1286
1287
DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
1288
       vnc_nve_group_redist_bgpdirect_routemap_cmd,
1289
       "redistribute bgp-direct route-map NAME",
1290
       "Redistribute from other protocols\n"
1291
       "Redistribute from BGP directly\n"
1292
       "Route-map for filtering exported routes\n" "route map name\n")
1293
0
{
1294
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1295
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1296
1297
0
  VNC_VTY_CONFIG_CHECK(bgp);
1298
1299
  /* make sure it's still in list */
1300
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1301
    /* Not in list anymore */
1302
0
    vty_out(vty, "Current NVE group no longer exists\n");
1303
0
    return CMD_WARNING_CONFIG_FAILED;
1304
0
  }
1305
1306
0
  vnc_redistribute_prechange(bgp);
1307
1308
0
  if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
1309
0
    free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
1310
0
  route_map_counter_decrement(
1311
0
    rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1312
0
  rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] =
1313
0
    strdup(argv[3]->arg);
1314
0
  rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] =
1315
0
    route_map_lookup_by_name(argv[3]->arg);
1316
0
  route_map_counter_increment(
1317
0
    rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1318
1319
0
  vnc_redistribute_postchange(bgp);
1320
1321
0
  return CMD_SUCCESS;
1322
0
}
1323
1324
/*-- redist policy, nvegroup end --*/
1325
1326
/*-------------------------------------------------------------------------
1327
 *      export
1328
 *-----------------------------------------------------------------------*/
1329
1330
DEFUN (vnc_export_mode,
1331
       vnc_export_mode_cmd,
1332
       "vnc export <bgp|zebra> mode <group-nve|ce|none|registering-nve>",
1333
       VNC_CONFIG_STR
1334
       "Export to other protocols\n"
1335
       "Export to BGP\n"
1336
       "Export to Zebra (experimental)\n"
1337
       "Select export mode\n"
1338
       "Export routes with nve-group next-hops\n"
1339
       "Export routes with NVE connected router next-hops\n"
1340
       "Disable export\n" "Export routes with registering NVE as next-hop\n")
1341
0
{
1342
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1343
0
  uint32_t oldmode = 0;
1344
0
  uint32_t newmode = 0;
1345
1346
0
  VNC_VTY_CONFIG_CHECK(bgp);
1347
1348
0
  if (argv[2]->arg[0] == 'b') {
1349
0
    oldmode = bgp->rfapi_cfg->flags
1350
0
        & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
1351
0
    switch (argv[4]->arg[0]) {
1352
0
    case 'g':
1353
0
      newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP;
1354
0
      break;
1355
0
    case 'c':
1356
0
      newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE;
1357
0
      break;
1358
0
    case 'n':
1359
0
      newmode = 0;
1360
0
      break;
1361
0
    case 'r':
1362
0
      newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH;
1363
0
      break;
1364
0
    default:
1365
0
      vty_out(vty, "Invalid mode specified\n");
1366
0
      return CMD_WARNING_CONFIG_FAILED;
1367
0
    }
1368
1369
0
    if (newmode == oldmode) {
1370
0
      vty_out(vty, "Mode unchanged\n");
1371
0
      return CMD_SUCCESS;
1372
0
    }
1373
1374
0
    vnc_export_bgp_prechange(bgp);
1375
1376
0
    bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
1377
0
    bgp->rfapi_cfg->flags |= newmode;
1378
1379
0
    vnc_export_bgp_postchange(bgp);
1380
1381
1382
0
  } else {
1383
    /*
1384
     * export to zebra with RH mode is not yet implemented
1385
     */
1386
0
    vty_out(vty,
1387
0
      "Changing modes for zebra export not implemented yet\n");
1388
0
    return CMD_WARNING_CONFIG_FAILED;
1389
0
  }
1390
1391
0
  return CMD_SUCCESS;
1392
0
}
1393
1394
static struct rfapi_rfg_name *rfgn_new(void)
1395
0
{
1396
0
  return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name));
1397
0
}
1398
1399
static void rfgn_free(struct rfapi_rfg_name *rfgn)
1400
0
{
1401
0
  XFREE(MTYPE_RFAPI_RFG_NAME, rfgn);
1402
0
}
1403
1404
DEFUN (vnc_export_nvegroup,
1405
       vnc_export_nvegroup_cmd,
1406
       "vnc export <bgp|zebra> group-nve group NAME",
1407
       VNC_CONFIG_STR
1408
       "Export to other protocols\n"
1409
       "Export to BGP\n"
1410
       "Export to Zebra (experimental)\n"
1411
       "NVE group, used in 'group-nve' export mode\n"
1412
       "NVE group\n" "Group name\n")
1413
0
{
1414
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1415
0
  struct rfapi_nve_group_cfg *rfg_new;
1416
1417
0
  VNC_VTY_CONFIG_CHECK(bgp);
1418
1419
0
  rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
1420
0
               RFAPI_GROUP_CFG_NVE);
1421
0
  if (rfg_new == NULL) {
1422
0
    rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
1423
0
                 RFAPI_GROUP_CFG_VRF);
1424
0
    if (rfg_new)
1425
0
      vnc_add_vrf_opener(bgp, rfg_new);
1426
0
  }
1427
1428
0
  if (rfg_new == NULL) {
1429
0
    vty_out(vty, "Can't find group named \"%s\".\n", argv[5]->arg);
1430
0
    return CMD_WARNING_CONFIG_FAILED;
1431
0
  }
1432
1433
0
  if (argv[2]->arg[0] == 'b') {
1434
1435
0
    struct listnode *node;
1436
0
    struct rfapi_rfg_name *rfgn;
1437
1438
    /*
1439
     * Set group for export to BGP Direct
1440
     */
1441
1442
    /* see if group is already included in export list */
1443
0
    for (ALL_LIST_ELEMENTS_RO(
1444
0
           bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
1445
0
           rfgn)) {
1446
1447
0
      if (!strcmp(rfgn->name, argv[5]->arg)) {
1448
        /* already in the list: we're done */
1449
0
        return CMD_SUCCESS;
1450
0
      }
1451
0
    }
1452
1453
0
    rfgn = rfgn_new();
1454
0
    rfgn->name = strdup(argv[5]->arg);
1455
0
    rfgn->rfg = rfg_new; /* OK if not set yet */
1456
1457
0
    listnode_add(bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn);
1458
1459
0
    vnc_zlog_debug_verbose("%s: testing rfg_new", __func__);
1460
0
    if (rfg_new) {
1461
0
      vnc_zlog_debug_verbose(
1462
0
        "%s: testing bgp grp mode enabled", __func__);
1463
0
      if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg))
1464
0
        vnc_zlog_debug_verbose(
1465
0
          "%s: calling vnc_direct_bgp_add_group",
1466
0
          __func__);
1467
0
      vnc_direct_bgp_add_group(bgp, rfg_new);
1468
0
    }
1469
1470
0
  } else {
1471
1472
0
    struct listnode *node;
1473
0
    struct rfapi_rfg_name *rfgn;
1474
1475
    /*
1476
     * Set group for export to Zebra
1477
     */
1478
1479
    /* see if group is already included in export list */
1480
0
    for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l,
1481
0
            node, rfgn)) {
1482
1483
0
      if (!strcmp(rfgn->name, argv[5]->arg)) {
1484
        /* already in the list: we're done */
1485
0
        return CMD_SUCCESS;
1486
0
      }
1487
0
    }
1488
1489
0
    rfgn = rfgn_new();
1490
0
    rfgn->name = strdup(argv[5]->arg);
1491
0
    rfgn->rfg = rfg_new; /* OK if not set yet */
1492
1493
0
    listnode_add(bgp->rfapi_cfg->rfg_export_zebra_l, rfgn);
1494
1495
0
    if (rfg_new) {
1496
0
      if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp->rfapi_cfg))
1497
0
        vnc_zebra_add_group(bgp, rfg_new);
1498
0
    }
1499
0
  }
1500
1501
0
  return CMD_SUCCESS;
1502
0
}
1503
1504
/*
1505
 * This command applies to routes exported from VNC to BGP directly
1506
 * without going though zebra
1507
 */
1508
DEFUN (vnc_no_export_nvegroup,
1509
       vnc_no_export_nvegroup_cmd,
1510
       "vnc export <bgp|zebra> group-nve no group NAME",
1511
       VNC_CONFIG_STR
1512
       "Export to other protocols\n"
1513
       "Export to BGP\n"
1514
       "Export to Zebra (experimental)\n"
1515
       "NVE group, used in 'group-nve' export mode\n"
1516
       "Disable export of VNC routes\n" "NVE group\n" "Group name\n")
1517
0
{
1518
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1519
0
  struct listnode *node, *nnode;
1520
0
  struct rfapi_rfg_name *rfgn;
1521
1522
0
  VNC_VTY_CONFIG_CHECK(bgp);
1523
1524
0
  if (argv[2]->arg[0] == 'b') {
1525
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
1526
0
               node, nnode, rfgn)) {
1527
1528
0
      if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
1529
0
        vnc_zlog_debug_verbose("%s: matched \"%s\"",
1530
0
                   __func__, rfgn->name);
1531
0
        if (rfgn->rfg)
1532
0
          vnc_direct_bgp_del_group(bgp,
1533
0
                 rfgn->rfg);
1534
0
        free(rfgn->name);
1535
0
        list_delete_node(
1536
0
          bgp->rfapi_cfg->rfg_export_direct_bgp_l,
1537
0
          node);
1538
0
        rfgn_free(rfgn);
1539
0
        break;
1540
0
      }
1541
0
    }
1542
0
  } else {
1543
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
1544
0
               nnode, rfgn)) {
1545
1546
0
      vnc_zlog_debug_verbose("does rfg \"%s\" match?",
1547
0
                 rfgn->name);
1548
0
      if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
1549
0
        if (rfgn->rfg)
1550
0
          vnc_zebra_del_group(bgp, rfgn->rfg);
1551
0
        free(rfgn->name);
1552
0
        list_delete_node(
1553
0
          bgp->rfapi_cfg->rfg_export_zebra_l,
1554
0
          node);
1555
0
        rfgn_free(rfgn);
1556
0
        break;
1557
0
      }
1558
0
    }
1559
0
  }
1560
0
  return CMD_SUCCESS;
1561
0
}
1562
1563
DEFUN (vnc_nve_group_export_no_prefixlist,
1564
       vnc_nve_group_export_no_prefixlist_cmd,
1565
       "no export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1566
       NO_STR
1567
       "Export to other protocols\n"
1568
       "Export to BGP\n"
1569
       "Export to Zebra (experimental)\n"
1570
       "IPv4 routes\n"
1571
       "IPv6 routes\n"
1572
       "Prefix-list for filtering exported routes\n" "prefix list name\n")
1573
0
{
1574
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1575
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1576
0
  int idx = 0;
1577
0
  int is_bgp = 1;
1578
0
  afi_t afi;
1579
1580
0
  VNC_VTY_CONFIG_CHECK(bgp);
1581
1582
  /* make sure it's still in list */
1583
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1584
    /* Not in list anymore */
1585
0
    vty_out(vty, "Current NVE group no longer exists\n");
1586
0
    return CMD_WARNING_CONFIG_FAILED;
1587
0
  }
1588
1589
0
  if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1590
0
    vty_out(vty, "%% Malformed Address Family\n");
1591
0
    return CMD_WARNING_CONFIG_FAILED;
1592
0
  }
1593
1594
0
  if (argv[idx - 1]->text[0] == 'z')
1595
0
    is_bgp = 0;
1596
0
  idx += 2; /* skip afi and keyword */
1597
1598
0
  if (is_bgp) {
1599
0
    if (idx == argc
1600
0
        || (rfg->plist_export_bgp_name[afi]
1601
0
      && strmatch(argv[idx]->arg,
1602
0
            rfg->plist_export_bgp_name[afi]))) {
1603
0
      if (rfg->plist_export_bgp_name[afi])
1604
0
        free(rfg->plist_export_bgp_name[afi]);
1605
0
      rfg->plist_export_bgp_name[afi] = NULL;
1606
0
      rfg->plist_export_bgp[afi] = NULL;
1607
1608
0
      vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
1609
0
    }
1610
0
  } else {
1611
0
    if (idx == argc
1612
0
        || (rfg->plist_export_zebra_name[afi]
1613
0
      && strmatch(argv[idx]->arg,
1614
0
            rfg->plist_export_zebra_name[afi]))) {
1615
0
      if (rfg->plist_export_zebra_name[afi])
1616
0
        free(rfg->plist_export_zebra_name[afi]);
1617
0
      rfg->plist_export_zebra_name[afi] = NULL;
1618
0
      rfg->plist_export_zebra[afi] = NULL;
1619
1620
0
      vnc_zebra_reexport_group_afi(bgp, rfg, afi);
1621
0
    }
1622
0
  }
1623
0
  return CMD_SUCCESS;
1624
0
}
1625
1626
ALIAS (vnc_nve_group_export_no_prefixlist,
1627
       vnc_vrf_policy_export_no_prefixlist_cmd,
1628
       "no export <ipv4|ipv6> prefix-list [NAME]",
1629
       NO_STR
1630
       "Export to VRF\n"
1631
       "IPv4 routes\n"
1632
       "IPv6 routes\n"
1633
       "Prefix-list for filtering exported routes\n" "prefix list name\n")
1634
1635
DEFUN (vnc_nve_group_export_prefixlist,
1636
       vnc_nve_group_export_prefixlist_cmd,
1637
       "export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1638
       "Export to other protocols\n"
1639
       "Export to BGP\n"
1640
       "Export to Zebra (experimental)\n"
1641
       "IPv4 routes\n"
1642
       "IPv6 routes\n"
1643
       "Prefix-list for filtering exported routes\n" "prefix list name\n")
1644
0
{
1645
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1646
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1647
0
  int idx = 0;
1648
0
  int is_bgp = 1;
1649
0
  afi_t afi;
1650
1651
0
  VNC_VTY_CONFIG_CHECK(bgp);
1652
1653
  /* make sure it's still in list */
1654
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1655
    /* Not in list anymore */
1656
0
    vty_out(vty, "Current NVE group no longer exists\n");
1657
0
    return CMD_WARNING_CONFIG_FAILED;
1658
0
  }
1659
1660
0
  if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1661
0
    vty_out(vty, "%% Malformed Address Family\n");
1662
0
    return CMD_WARNING_CONFIG_FAILED;
1663
0
  }
1664
1665
0
  if (argv[idx - 1]->text[0] == 'z')
1666
0
    is_bgp = 0;
1667
0
  idx = argc - 1;
1668
1669
0
  if (is_bgp) {
1670
0
    if (rfg->plist_export_bgp_name[afi])
1671
0
      free(rfg->plist_export_bgp_name[afi]);
1672
0
    rfg->plist_export_bgp_name[afi] = strdup(argv[idx]->arg);
1673
0
    rfg->plist_export_bgp[afi] =
1674
0
      prefix_list_lookup(afi, argv[idx]->arg);
1675
1676
0
    vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
1677
1678
0
  } else {
1679
0
    if (rfg->plist_export_zebra_name[afi])
1680
0
      free(rfg->plist_export_zebra_name[afi]);
1681
0
    rfg->plist_export_zebra_name[afi] = strdup(argv[idx]->arg);
1682
0
    rfg->plist_export_zebra[afi] =
1683
0
      prefix_list_lookup(afi, argv[idx]->arg);
1684
1685
0
    vnc_zebra_reexport_group_afi(bgp, rfg, afi);
1686
0
  }
1687
0
  return CMD_SUCCESS;
1688
0
}
1689
1690
ALIAS (vnc_nve_group_export_prefixlist,
1691
       vnc_vrf_policy_export_prefixlist_cmd,
1692
       "export <ipv4|ipv6> prefix-list NAME",
1693
       "Export to VRF\n"
1694
       "IPv4 routes\n"
1695
       "IPv6 routes\n"
1696
       "Prefix-list for filtering exported routes\n" "prefix list name\n")
1697
1698
DEFUN (vnc_nve_group_export_no_routemap,
1699
       vnc_nve_group_export_no_routemap_cmd,
1700
       "no export <bgp|zebra> route-map [NAME]",
1701
       NO_STR
1702
       "Export to other protocols\n"
1703
       "Export to BGP\n"
1704
       "Export to Zebra (experimental)\n"
1705
       "Route-map for filtering exported routes\n" "route map name\n")
1706
0
{
1707
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1708
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1709
0
  int idx = 2;
1710
0
  int is_bgp = 1;
1711
1712
0
  VNC_VTY_CONFIG_CHECK(bgp);
1713
1714
  /* make sure it's still in list */
1715
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1716
    /* Not in list anymore */
1717
0
    vty_out(vty, "Current NVE group no longer exists\n");
1718
0
    return CMD_WARNING_CONFIG_FAILED;
1719
0
  }
1720
0
  switch (argv[idx]->text[0]) {
1721
0
  case 'z':
1722
0
    is_bgp = 0;
1723
  /* fall thru */
1724
0
  case 'b':
1725
0
    idx += 2;
1726
0
    break;
1727
0
  default: /* route-map */
1728
0
    idx++;
1729
0
    break;
1730
0
  }
1731
1732
0
  if (is_bgp) {
1733
0
    if (idx == argc
1734
0
        || (rfg->routemap_export_bgp_name
1735
0
      && strmatch(argv[idx]->arg,
1736
0
            rfg->routemap_export_bgp_name))) {
1737
0
      if (rfg->routemap_export_bgp_name)
1738
0
        free(rfg->routemap_export_bgp_name);
1739
0
      route_map_counter_decrement(rfg->routemap_export_bgp);
1740
0
      rfg->routemap_export_bgp_name = NULL;
1741
0
      rfg->routemap_export_bgp = NULL;
1742
1743
0
      vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
1744
0
      vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
1745
0
    }
1746
0
  } else {
1747
0
    if (idx == argc
1748
0
        || (rfg->routemap_export_zebra_name
1749
0
      && strmatch(argv[idx]->arg,
1750
0
            rfg->routemap_export_zebra_name))) {
1751
0
      if (rfg->routemap_export_zebra_name)
1752
0
        free(rfg->routemap_export_zebra_name);
1753
0
      route_map_counter_decrement(rfg->routemap_export_zebra);
1754
0
      rfg->routemap_export_zebra_name = NULL;
1755
0
      rfg->routemap_export_zebra = NULL;
1756
1757
0
      vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
1758
0
      vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
1759
0
    }
1760
0
  }
1761
0
  return CMD_SUCCESS;
1762
0
}
1763
1764
ALIAS (vnc_nve_group_export_no_routemap,
1765
       vnc_vrf_policy_export_no_routemap_cmd,
1766
       "no export route-map [NAME]",
1767
       NO_STR
1768
       "Export to VRF\n"
1769
       "Route-map for filtering exported routes\n" "route map name\n")
1770
1771
DEFUN (vnc_nve_group_export_routemap,
1772
       vnc_nve_group_export_routemap_cmd,
1773
       "export <bgp|zebra> route-map NAME",
1774
       "Export to other protocols\n"
1775
       "Export to BGP\n"
1776
       "Export to Zebra (experimental)\n"
1777
       "Route-map for filtering exported routes\n" "route map name\n")
1778
0
{
1779
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1780
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1781
0
  int idx = 0;
1782
0
  int is_bgp = 1;
1783
1784
0
  VNC_VTY_CONFIG_CHECK(bgp);
1785
1786
  /* make sure it's still in list */
1787
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1788
    /* Not in list anymore */
1789
0
    vty_out(vty, "Current NVE group no longer exists\n");
1790
0
    return CMD_WARNING_CONFIG_FAILED;
1791
0
  }
1792
1793
0
  if (argv[1]->text[0] == 'z')
1794
0
    is_bgp = 0;
1795
0
  idx = argc - 1;
1796
1797
0
  if (is_bgp) {
1798
0
    if (rfg->routemap_export_bgp_name)
1799
0
      free(rfg->routemap_export_bgp_name);
1800
0
    route_map_counter_decrement(rfg->routemap_export_bgp);
1801
0
    rfg->routemap_export_bgp_name = strdup(argv[idx]->arg);
1802
0
    rfg->routemap_export_bgp =
1803
0
      route_map_lookup_by_name(argv[idx]->arg);
1804
0
    route_map_counter_increment(rfg->routemap_export_bgp);
1805
0
    vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
1806
0
    vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
1807
0
  } else {
1808
0
    if (rfg->routemap_export_zebra_name)
1809
0
      free(rfg->routemap_export_zebra_name);
1810
0
    route_map_counter_decrement(rfg->routemap_export_zebra);
1811
0
    rfg->routemap_export_zebra_name = strdup(argv[idx]->arg);
1812
0
    rfg->routemap_export_zebra =
1813
0
      route_map_lookup_by_name(argv[idx]->arg);
1814
0
    route_map_counter_increment(rfg->routemap_export_zebra);
1815
0
    vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
1816
0
    vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
1817
0
  }
1818
0
  return CMD_SUCCESS;
1819
0
}
1820
1821
ALIAS (vnc_nve_group_export_routemap,
1822
       vnc_vrf_policy_export_routemap_cmd,
1823
       "export route-map NAME",
1824
       "Export to VRF\n"
1825
       "Route-map for filtering exported routes\n" "route map name\n")
1826
1827
DEFUN (vnc_nve_export_no_prefixlist,
1828
       vnc_nve_export_no_prefixlist_cmd,
1829
       "no vnc export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1830
       NO_STR
1831
       VNC_CONFIG_STR
1832
       "Export to other protocols\n"
1833
       "Export to BGP\n"
1834
       "Export to Zebra (experimental)\n"
1835
       "IPv4 prefixes\n"
1836
       "IPv6 prefixes\n"
1837
       "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1838
0
{
1839
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1840
0
  struct rfapi_cfg *hc;
1841
0
  afi_t afi;
1842
1843
0
  VNC_VTY_CONFIG_CHECK(bgp);
1844
0
  hc = bgp->rfapi_cfg;
1845
1846
0
  if (strmatch(argv[4]->text, "ipv4")) {
1847
0
    afi = AFI_IP;
1848
0
  } else {
1849
0
    afi = AFI_IP6;
1850
0
  }
1851
1852
0
  if (argv[3]->arg[0] == 'b') {
1853
0
    if (((argc > 6) && hc->plist_export_bgp_name[afi]
1854
0
         && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi]))
1855
0
        || (argc <= 6)) {
1856
1857
0
      free(hc->plist_export_bgp_name[afi]);
1858
0
      hc->plist_export_bgp_name[afi] = NULL;
1859
0
      hc->plist_export_bgp[afi] = NULL;
1860
0
      vnc_direct_bgp_reexport(bgp, afi);
1861
0
    }
1862
0
  } else {
1863
0
    if (((argc > 6) && hc->plist_export_zebra_name[afi]
1864
0
         && strmatch(argv[6]->text,
1865
0
         hc->plist_export_zebra_name[afi]))
1866
0
        || (argc <= 6)) {
1867
1868
0
      free(hc->plist_export_zebra_name[afi]);
1869
0
      hc->plist_export_zebra_name[afi] = NULL;
1870
0
      hc->plist_export_zebra[afi] = NULL;
1871
      /* TBD vnc_zebra_rh_reexport(bgp, afi); */
1872
0
    }
1873
0
  }
1874
0
  return CMD_SUCCESS;
1875
0
}
1876
1877
DEFUN (vnc_nve_export_prefixlist,
1878
       vnc_nve_export_prefixlist_cmd,
1879
       "vnc export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1880
       VNC_CONFIG_STR
1881
       "Export to other protocols\n"
1882
       "Export to BGP\n"
1883
       "Export to Zebra (experimental)\n"
1884
       "IPv4 prefixes\n"
1885
       "IPv6 prefixes\n"
1886
       "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1887
0
{
1888
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1889
0
  struct rfapi_cfg *hc;
1890
0
  afi_t afi;
1891
1892
0
  VNC_VTY_CONFIG_CHECK(bgp);
1893
0
  hc = bgp->rfapi_cfg;
1894
1895
0
  if (strmatch(argv[3]->text, "ipv4")) {
1896
0
    afi = AFI_IP;
1897
0
  } else {
1898
0
    afi = AFI_IP6;
1899
0
  }
1900
1901
0
  if (argv[2]->arg[0] == 'b') {
1902
0
    if (hc->plist_export_bgp_name[afi])
1903
0
      free(hc->plist_export_bgp_name[afi]);
1904
0
    hc->plist_export_bgp_name[afi] = strdup(argv[5]->arg);
1905
0
    hc->plist_export_bgp[afi] =
1906
0
      prefix_list_lookup(afi, argv[5]->arg);
1907
0
    vnc_direct_bgp_reexport(bgp, afi);
1908
0
  } else {
1909
0
    if (hc->plist_export_zebra_name[afi])
1910
0
      free(hc->plist_export_zebra_name[afi]);
1911
0
    hc->plist_export_zebra_name[afi] = strdup(argv[5]->arg);
1912
0
    hc->plist_export_zebra[afi] =
1913
0
      prefix_list_lookup(afi, argv[5]->arg);
1914
    /* TBD vnc_zebra_rh_reexport(bgp, afi); */
1915
0
  }
1916
0
  return CMD_SUCCESS;
1917
0
}
1918
1919
DEFUN (vnc_nve_export_no_routemap,
1920
       vnc_nve_export_no_routemap_cmd,
1921
       "no vnc export <bgp|zebra> route-map [NAME]",
1922
       NO_STR
1923
       VNC_CONFIG_STR
1924
       "Export to other protocols\n"
1925
       "Export to BGP\n"
1926
       "Export to Zebra (experimental)\n"
1927
       "Route-map for filtering exported routes\n" "Route map name\n")
1928
0
{
1929
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1930
0
  struct rfapi_cfg *hc;
1931
1932
0
  VNC_VTY_CONFIG_CHECK(bgp);
1933
0
  hc = bgp->rfapi_cfg;
1934
1935
0
  if (argv[3]->arg[0] == 'b') {
1936
0
    if (((argc > 5) && hc->routemap_export_bgp_name
1937
0
         && strmatch(argv[5]->text, hc->routemap_export_bgp_name))
1938
0
        || (argc <= 5)) {
1939
1940
0
      free(hc->routemap_export_bgp_name);
1941
0
      route_map_counter_decrement(hc->routemap_export_bgp);
1942
0
      hc->routemap_export_bgp_name = NULL;
1943
0
      hc->routemap_export_bgp = NULL;
1944
0
      vnc_direct_bgp_reexport(bgp, AFI_IP);
1945
0
      vnc_direct_bgp_reexport(bgp, AFI_IP6);
1946
0
    }
1947
0
  } else {
1948
0
    if (((argc > 5) && hc->routemap_export_zebra_name
1949
0
         && strmatch(argv[5]->text, hc->routemap_export_zebra_name))
1950
0
        || (argc <= 5)) {
1951
1952
0
      free(hc->routemap_export_zebra_name);
1953
0
      route_map_counter_decrement(hc->routemap_export_zebra);
1954
0
      hc->routemap_export_zebra_name = NULL;
1955
0
      hc->routemap_export_zebra = NULL;
1956
      /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
1957
      /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
1958
0
    }
1959
0
  }
1960
0
  return CMD_SUCCESS;
1961
0
}
1962
1963
DEFUN (vnc_nve_export_routemap,
1964
       vnc_nve_export_routemap_cmd,
1965
       "vnc export <bgp|zebra> route-map NAME",
1966
       VNC_CONFIG_STR
1967
       "Export to other protocols\n"
1968
       "Export to BGP\n"
1969
       "Export to Zebra (experimental)\n"
1970
       "Route-map for filtering exported routes\n" "Route map name\n")
1971
0
{
1972
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
1973
0
  struct rfapi_cfg *hc;
1974
1975
0
  VNC_VTY_CONFIG_CHECK(bgp);
1976
0
  hc = bgp->rfapi_cfg;
1977
1978
0
  if (argv[2]->arg[0] == 'b') {
1979
0
    if (hc->routemap_export_bgp_name)
1980
0
      free(hc->routemap_export_bgp_name);
1981
0
    route_map_counter_decrement(hc->routemap_export_bgp);
1982
0
    hc->routemap_export_bgp_name = strdup(argv[4]->arg);
1983
0
    hc->routemap_export_bgp =
1984
0
      route_map_lookup_by_name(argv[4]->arg);
1985
0
    route_map_counter_increment(hc->routemap_export_bgp);
1986
0
    vnc_direct_bgp_reexport(bgp, AFI_IP);
1987
0
    vnc_direct_bgp_reexport(bgp, AFI_IP6);
1988
0
  } else {
1989
0
    if (hc->routemap_export_zebra_name)
1990
0
      free(hc->routemap_export_zebra_name);
1991
0
    route_map_counter_decrement(hc->routemap_export_zebra);
1992
0
    hc->routemap_export_zebra_name = strdup(argv[4]->arg);
1993
0
    hc->routemap_export_zebra =
1994
0
      route_map_lookup_by_name(argv[4]->arg);
1995
0
    route_map_counter_increment(hc->routemap_export_zebra);
1996
    /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
1997
    /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
1998
0
  }
1999
0
  return CMD_SUCCESS;
2000
0
}
2001
2002
2003
/*
2004
 * respond to changes in the global prefix list configuration
2005
 */
2006
void vnc_prefix_list_update(struct bgp *bgp)
2007
0
{
2008
0
  afi_t afi;
2009
0
  struct listnode *n;
2010
0
  struct rfapi_nve_group_cfg *rfg;
2011
0
  struct rfapi_cfg *hc;
2012
0
  int i;
2013
2014
0
  if (!bgp) {
2015
0
    vnc_zlog_debug_verbose("%s: No BGP process is configured",
2016
0
               __func__);
2017
0
    return;
2018
0
  }
2019
2020
0
  if (!(hc = bgp->rfapi_cfg)) {
2021
0
    vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
2022
0
    return;
2023
0
  }
2024
2025
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2026
    /*
2027
     * Loop over nve groups
2028
     */
2029
0
    for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential,
2030
0
            n, rfg)) {
2031
2032
0
      if (rfg->plist_export_bgp_name[afi]) {
2033
0
        rfg->plist_export_bgp[afi] = prefix_list_lookup(
2034
0
          afi, rfg->plist_export_bgp_name[afi]);
2035
0
      }
2036
0
      if (rfg->plist_export_zebra_name[afi]) {
2037
0
        rfg->plist_export_zebra
2038
0
          [afi] = prefix_list_lookup(
2039
0
          afi, rfg->plist_export_zebra_name[afi]);
2040
0
      }
2041
0
      for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2042
0
        if (rfg->plist_redist_name[i][afi]) {
2043
0
          rfg->plist_redist
2044
0
            [i][afi] = prefix_list_lookup(
2045
0
            afi,
2046
0
            rfg->plist_redist_name[i][afi]);
2047
0
        }
2048
0
      }
2049
2050
0
      vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
2051
      /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2052
0
    }
2053
2054
    /*
2055
     * RH config, too
2056
     */
2057
0
    if (hc->plist_export_bgp_name[afi]) {
2058
0
      hc->plist_export_bgp[afi] = prefix_list_lookup(
2059
0
        afi, hc->plist_export_bgp_name[afi]);
2060
0
    }
2061
0
    if (hc->plist_export_zebra_name[afi]) {
2062
0
      hc->plist_export_zebra[afi] = prefix_list_lookup(
2063
0
        afi, hc->plist_export_zebra_name[afi]);
2064
0
    }
2065
2066
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2067
0
      if (hc->plist_redist_name[i][afi]) {
2068
0
        hc->plist_redist[i][afi] = prefix_list_lookup(
2069
0
          afi, hc->plist_redist_name[i][afi]);
2070
0
      }
2071
0
    }
2072
0
  }
2073
2074
0
  vnc_direct_bgp_reexport(bgp, AFI_IP);
2075
0
  vnc_direct_bgp_reexport(bgp, AFI_IP6);
2076
2077
  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2078
  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2079
2080
0
  vnc_redistribute_prechange(bgp);
2081
0
  vnc_redistribute_postchange(bgp);
2082
0
}
2083
2084
/*
2085
 * respond to changes in the global route map configuration
2086
 */
2087
void vnc_routemap_update(struct bgp *bgp, const char *unused)
2088
0
{
2089
0
  struct listnode *n;
2090
0
  struct rfapi_nve_group_cfg *rfg;
2091
0
  struct rfapi_cfg *hc;
2092
0
  int i;
2093
0
  struct route_map *old = NULL;
2094
2095
0
  vnc_zlog_debug_verbose("%s(arg=%s)", __func__, unused);
2096
2097
0
  if (!bgp) {
2098
0
    vnc_zlog_debug_verbose("%s: No BGP process is configured",
2099
0
               __func__);
2100
0
    return;
2101
0
  }
2102
2103
0
  if (!(hc = bgp->rfapi_cfg)) {
2104
0
    vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
2105
0
    return;
2106
0
  }
2107
2108
  /*
2109
   * Loop over nve groups
2110
   */
2111
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, n,
2112
0
          rfg)) {
2113
2114
0
    if (rfg->routemap_export_bgp_name) {
2115
0
      old = rfg->routemap_export_bgp;
2116
0
      rfg->routemap_export_bgp = route_map_lookup_by_name(
2117
0
        rfg->routemap_export_bgp_name);
2118
      /* old is NULL. i.e Route map creation event.
2119
       * So update applied_counter.
2120
       * If Old is not NULL, i.e It may be routemap
2121
       * updation or deletion.
2122
       * So no need to update the counter.
2123
       */
2124
0
      if (!old)
2125
0
        route_map_counter_increment(
2126
0
          rfg->routemap_export_bgp);
2127
0
    }
2128
0
    if (rfg->routemap_export_zebra_name) {
2129
0
      old = rfg->routemap_export_bgp;
2130
0
      rfg->routemap_export_bgp = route_map_lookup_by_name(
2131
0
        rfg->routemap_export_zebra_name);
2132
0
      if (!old)
2133
0
        route_map_counter_increment(
2134
0
          rfg->routemap_export_bgp);
2135
0
    }
2136
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2137
0
      if (rfg->routemap_redist_name[i]) {
2138
0
        old = rfg->routemap_redist[i];
2139
0
        rfg->routemap_redist[i] =
2140
0
          route_map_lookup_by_name(
2141
0
            rfg->routemap_redist_name[i]);
2142
0
        if (!old)
2143
0
          route_map_counter_increment(
2144
0
            rfg->routemap_redist[i]);
2145
0
      }
2146
0
    }
2147
2148
0
    vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
2149
0
    vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
2150
    /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2151
0
  }
2152
2153
  /*
2154
   * RH config, too
2155
   */
2156
0
  if (hc->routemap_export_bgp_name) {
2157
0
    old = hc->routemap_export_bgp;
2158
0
    hc->routemap_export_bgp =
2159
0
      route_map_lookup_by_name(hc->routemap_export_bgp_name);
2160
0
    if (!old)
2161
0
      route_map_counter_increment(hc->routemap_export_bgp);
2162
0
  }
2163
0
  if (hc->routemap_export_zebra_name) {
2164
0
    old  = hc->routemap_export_bgp;
2165
0
    hc->routemap_export_bgp = route_map_lookup_by_name(
2166
0
      hc->routemap_export_zebra_name);
2167
0
    if (!old)
2168
0
      route_map_counter_increment(hc->routemap_export_bgp);
2169
0
  }
2170
0
  for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2171
0
    if (hc->routemap_redist_name[i]) {
2172
0
      old = hc->routemap_redist[i];
2173
0
      hc->routemap_redist[i] = route_map_lookup_by_name(
2174
0
        hc->routemap_redist_name[i]);
2175
0
      if (!old)
2176
0
        route_map_counter_increment(
2177
0
          hc->routemap_redist[i]);
2178
0
    }
2179
0
  }
2180
2181
0
  vnc_direct_bgp_reexport(bgp, AFI_IP);
2182
0
  vnc_direct_bgp_reexport(bgp, AFI_IP6);
2183
2184
  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2185
  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2186
2187
0
  vnc_redistribute_prechange(bgp);
2188
0
  vnc_redistribute_postchange(bgp);
2189
2190
0
  vnc_zlog_debug_verbose("%s done", __func__);
2191
0
}
2192
2193
/*-------------------------------------------------------------------------
2194
 *      nve-group
2195
 *-----------------------------------------------------------------------*/
2196
2197
2198
DEFUN_NOSH (vnc_nve_group,
2199
       vnc_nve_group_cmd,
2200
       "vnc nve-group NAME",
2201
       VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n")
2202
0
{
2203
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2204
0
  struct rfapi_nve_group_cfg *rfg;
2205
0
  struct listnode *node, *nnode;
2206
0
  struct rfapi_rfg_name *rfgn;
2207
2208
0
  VNC_VTY_CONFIG_CHECK(bgp);
2209
2210
  /* Search for name */
2211
0
  rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg,
2212
0
           RFAPI_GROUP_CFG_NVE);
2213
2214
0
  if (!rfg) {
2215
0
    rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg);
2216
0
    if (!rfg) {
2217
      /* Error out of memory */
2218
0
      vty_out(vty, "Can't allocate memory for NVE group\n");
2219
0
      return CMD_WARNING_CONFIG_FAILED;
2220
0
    }
2221
2222
    /* Copy defaults from struct rfapi_cfg */
2223
0
    rfg->rd = bgp->rfapi_cfg->default_rd;
2224
0
    if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) {
2225
0
      rfg->l2rd = bgp->rfapi_cfg->default_l2rd;
2226
0
      rfg->flags |= RFAPI_RFG_L2RD;
2227
0
    }
2228
0
    rfg->rd = bgp->rfapi_cfg->default_rd;
2229
0
    rfg->response_lifetime =
2230
0
      bgp->rfapi_cfg->default_response_lifetime;
2231
2232
0
    if (bgp->rfapi_cfg->default_rt_export_list) {
2233
0
      rfg->rt_export_list = ecommunity_dup(
2234
0
        bgp->rfapi_cfg->default_rt_export_list);
2235
0
    }
2236
2237
0
    if (bgp->rfapi_cfg->default_rt_import_list) {
2238
0
      rfg->rt_import_list = ecommunity_dup(
2239
0
        bgp->rfapi_cfg->default_rt_import_list);
2240
0
      rfg->rfapi_import_table = rfapiImportTableRefAdd(
2241
0
        bgp, rfg->rt_import_list, rfg);
2242
0
    }
2243
2244
    /*
2245
     * If a redist nve group was named but the group was not
2246
     * defined,
2247
     * make the linkage now
2248
     */
2249
0
    if (!bgp->rfapi_cfg->rfg_redist) {
2250
0
      if (bgp->rfapi_cfg->rfg_redist_name
2251
0
          && !strcmp(bgp->rfapi_cfg->rfg_redist_name,
2252
0
               rfg->name)) {
2253
2254
0
        vnc_redistribute_prechange(bgp);
2255
0
        bgp->rfapi_cfg->rfg_redist = rfg;
2256
0
        vnc_redistribute_postchange(bgp);
2257
0
      }
2258
0
    }
2259
2260
    /*
2261
     * Same treatment for bgp-direct export group
2262
     */
2263
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
2264
0
               node, nnode, rfgn)) {
2265
2266
0
      if (!strcmp(rfgn->name, rfg->name)) {
2267
0
        rfgn->rfg = rfg;
2268
0
        vnc_direct_bgp_add_group(bgp, rfg);
2269
0
        break;
2270
0
      }
2271
0
    }
2272
2273
    /*
2274
     * Same treatment for zebra export group
2275
     */
2276
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2277
0
               nnode, rfgn)) {
2278
2279
0
      vnc_zlog_debug_verbose(
2280
0
        "%s: ezport zebra: checking if \"%s\" == \"%s\"",
2281
0
        __func__, rfgn->name, rfg->name);
2282
0
      if (!strcmp(rfgn->name, rfg->name)) {
2283
0
        rfgn->rfg = rfg;
2284
0
        vnc_zebra_add_group(bgp, rfg);
2285
0
        break;
2286
0
      }
2287
0
    }
2288
0
  }
2289
2290
  /*
2291
   * XXX subsequent calls will need to make sure this item is still
2292
   * in the linked list and has the same name
2293
   */
2294
0
  VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE, rfg);
2295
2296
0
  return CMD_SUCCESS;
2297
0
}
2298
2299
static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
2300
               struct bgp *bgp,
2301
               struct rfapi_nve_group_cfg *rfg)
2302
0
{
2303
0
  struct list *orphaned_nves = NULL;
2304
0
  struct listnode *node, *nnode;
2305
2306
  /*
2307
   * If there are currently-open NVEs that belong to this group,
2308
   * zero out their references to this group structure.
2309
   */
2310
0
  if (rfg->nves) {
2311
0
    struct rfapi_descriptor *rfd;
2312
0
    orphaned_nves = list_new();
2313
0
    while ((rfd = listnode_head(rfg->nves))) {
2314
0
      rfd->rfg = NULL;
2315
0
      listnode_delete(rfg->nves, rfd);
2316
0
      listnode_add(orphaned_nves, rfd);
2317
0
    }
2318
0
    list_delete(&rfg->nves);
2319
0
  }
2320
2321
  /* delete it */
2322
0
  free(rfg->name);
2323
0
  if (rfg->rfapi_import_table)
2324
0
    rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2325
0
  if (rfg->rt_import_list)
2326
0
    ecommunity_free(&rfg->rt_import_list);
2327
0
  if (rfg->rt_export_list)
2328
0
    ecommunity_free(&rfg->rt_export_list);
2329
2330
0
  if (rfg->vn_node) {
2331
0
    rfg->vn_node->info = NULL;
2332
0
    agg_unlock_node(rfg->vn_node); /* frees */
2333
0
  }
2334
0
  if (rfg->un_node) {
2335
0
    rfg->un_node->info = NULL;
2336
0
    agg_unlock_node(rfg->un_node); /* frees */
2337
0
  }
2338
0
  if (rfg->rfp_cfg)
2339
0
    XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
2340
0
  listnode_delete(bgp->rfapi_cfg->nve_groups_sequential, rfg);
2341
2342
0
  QOBJ_UNREG(rfg);
2343
0
  XFREE(MTYPE_RFAPI_GROUP_CFG, rfg);
2344
2345
  /*
2346
   * Attempt to reassign the orphaned nves to a new group. If
2347
   * a NVE can not be reassigned, its rfd->rfg will remain NULL
2348
   * and it will become a zombie until released by rfapi_close().
2349
   */
2350
0
  if (orphaned_nves) {
2351
0
    struct rfapi_descriptor *rfd;
2352
2353
0
    for (ALL_LIST_ELEMENTS(orphaned_nves, node, nnode, rfd)) {
2354
      /*
2355
       * 1. rfapi_close() equivalent except:
2356
       *          a. don't free original descriptor
2357
       *          b. remember query list
2358
       *          c. remember advertised route list
2359
       * 2. rfapi_open() equivalent except:
2360
       *          a. reuse original descriptor
2361
       * 3. rfapi_register() on remembered advertised route
2362
       * list
2363
       * 4. rfapi_query on rememebred query list
2364
       */
2365
2366
0
      int rc;
2367
2368
0
      rc = rfapi_reopen(rfd, bgp);
2369
2370
0
      if (!rc) {
2371
0
        list_delete_node(orphaned_nves, node);
2372
0
        if (vty)
2373
0
          vty_out(vty,
2374
0
            "WARNING: reassigned NVE vn=");
2375
0
        rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
2376
0
        if (vty)
2377
0
          vty_out(vty, " un=");
2378
0
        rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
2379
0
        if (vty)
2380
0
          vty_out(vty, " to new group \"%s\"\n",
2381
0
            rfd->rfg->name);
2382
0
      }
2383
0
    }
2384
2385
0
    for (ALL_LIST_ELEMENTS_RO(orphaned_nves, node, rfd)) {
2386
0
      if (vty)
2387
0
        vty_out(vty, "WARNING: orphaned NVE vn=");
2388
0
      rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
2389
0
      if (vty)
2390
0
        vty_out(vty, " un=");
2391
0
      rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
2392
0
      if (vty)
2393
0
        vty_out(vty, "\n");
2394
0
    }
2395
0
    list_delete(&orphaned_nves);
2396
0
  }
2397
0
}
2398
2399
static int
2400
bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */
2401
         struct bgp *bgp,
2402
         const char *rfg_name,  /* NULL = any */
2403
         rfapi_group_cfg_type_t type) /* _MAX = any */
2404
0
{
2405
0
  struct rfapi_nve_group_cfg *rfg = NULL;
2406
0
  struct listnode *node, *nnode;
2407
0
  struct rfapi_rfg_name *rfgn;
2408
2409
  /* Search for name */
2410
0
  if (rfg_name) {
2411
0
    rfg = bgp_rfapi_cfg_match_byname(bgp, rfg_name, type);
2412
0
    if (!rfg) {
2413
0
      if (vty)
2414
0
        vty_out(vty, "No NVE group named \"%s\"\n",
2415
0
          rfg_name);
2416
0
      return CMD_WARNING_CONFIG_FAILED;
2417
0
    }
2418
0
  }
2419
2420
  /*
2421
   * If this group is the redist nve group, unlink it
2422
   */
2423
0
  if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) {
2424
0
    vnc_redistribute_prechange(bgp);
2425
0
    bgp->rfapi_cfg->rfg_redist = NULL;
2426
0
    vnc_redistribute_postchange(bgp);
2427
0
  }
2428
2429
2430
  /*
2431
   * remove reference from bgp direct export list
2432
   */
2433
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2434
0
          rfgn)) {
2435
0
    if (rfgn->rfg == rfg) {
2436
0
      rfgn->rfg = NULL;
2437
      /* remove exported routes from this group */
2438
0
      vnc_direct_bgp_del_group(bgp, rfg);
2439
0
      break;
2440
0
    }
2441
0
  }
2442
2443
  /*
2444
   * remove reference from zebra export list
2445
   */
2446
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2447
0
          rfgn)) {
2448
0
    if (rfgn->rfg == rfg) {
2449
0
      rfgn->rfg = NULL;
2450
      /* remove exported routes from this group */
2451
0
      vnc_zebra_del_group(bgp, rfg);
2452
0
      break;
2453
0
    }
2454
0
  }
2455
0
  if (rfg) {
2456
0
    if (rfg->rfd)
2457
0
      clear_vnc_vrf_closer(rfg);
2458
0
    bgp_rfapi_delete_nve_group(vty, bgp, rfg);
2459
0
  } else /* must be delete all */
2460
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential,
2461
0
               node, nnode, rfg)) {
2462
0
      if (rfg->rfd)
2463
0
        clear_vnc_vrf_closer(rfg);
2464
0
      bgp_rfapi_delete_nve_group(vty, bgp, rfg);
2465
0
    }
2466
0
  return CMD_SUCCESS;
2467
0
}
2468
2469
DEFUN (vnc_no_nve_group,
2470
       vnc_no_nve_group_cmd,
2471
       "no vnc nve-group NAME",
2472
       NO_STR
2473
       VNC_CONFIG_STR
2474
       "Configure a NVE group\n"
2475
       "Group name\n")
2476
0
{
2477
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2478
2479
0
  return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[3]->arg,
2480
0
            RFAPI_GROUP_CFG_NVE);
2481
0
}
2482
2483
DEFUN (vnc_nve_group_prefix,
2484
       vnc_nve_group_prefix_cmd,
2485
       "prefix <vn|un> <A.B.C.D/M|X:X::X:X/M>",
2486
       "Specify prefixes matching NVE VN or UN interfaces\n"
2487
       "VN prefix\n"
2488
       "UN prefix\n"
2489
       "IPv4 prefix\n"
2490
       "IPv6 prefix\n")
2491
0
{
2492
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2493
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2494
0
  struct prefix p;
2495
0
  afi_t afi;
2496
0
  struct agg_table *rt;
2497
0
  struct agg_node *rn;
2498
0
  int is_un_prefix = 0;
2499
2500
  /* make sure it's still in list */
2501
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2502
    /* Not in list anymore */
2503
0
    vty_out(vty, "Current NVE group no longer exists\n");
2504
0
    return CMD_WARNING_CONFIG_FAILED;
2505
0
  }
2506
2507
0
  if (!str2prefix(argv[2]->arg, &p)) {
2508
0
    vty_out(vty, "Malformed prefix \"%s\"\n", argv[2]->arg);
2509
0
    return CMD_WARNING_CONFIG_FAILED;
2510
0
  }
2511
2512
0
  afi = family2afi(p.family);
2513
0
  if (!afi) {
2514
0
    vty_out(vty, "Unsupported address family\n");
2515
0
    return CMD_WARNING_CONFIG_FAILED;
2516
0
  }
2517
2518
0
  if (argv[1]->arg[0] == 'u') {
2519
0
    rt = bgp->rfapi_cfg->nve_groups_un[afi];
2520
0
    is_un_prefix = 1;
2521
0
  } else {
2522
0
    rt = bgp->rfapi_cfg->nve_groups_vn[afi];
2523
0
  }
2524
2525
0
  rn = agg_node_get(rt, &p); /* NB locks node */
2526
0
  if (rn->info) {
2527
    /*
2528
     * There is already a group with this prefix
2529
     */
2530
0
    agg_unlock_node(rn);
2531
0
    if (rn->info != rfg) {
2532
      /*
2533
       * different group name: fail
2534
       */
2535
0
      vty_out(vty,
2536
0
        "nve group \"%s\" already has \"%s\" prefix %s\n",
2537
0
        ((struct rfapi_nve_group_cfg *)(rn->info))
2538
0
          ->name,
2539
0
        argv[1]->arg, argv[2]->arg);
2540
0
      return CMD_WARNING_CONFIG_FAILED;
2541
0
    } else {
2542
      /*
2543
       * same group name: it's already in the correct place
2544
       * in the table, so we're done.
2545
       *
2546
       * Implies rfg->(vn|un)_prefix is already correct.
2547
       */
2548
0
      return CMD_SUCCESS;
2549
0
    }
2550
0
  }
2551
2552
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2553
0
    vnc_redistribute_prechange(bgp);
2554
0
  }
2555
2556
  /* New prefix, new node */
2557
2558
0
  if (is_un_prefix) {
2559
2560
    /* detach rfg from previous route table location */
2561
0
    if (rfg->un_node) {
2562
0
      rfg->un_node->info = NULL;
2563
0
      agg_unlock_node(rfg->un_node); /* frees */
2564
0
    }
2565
0
    rfg->un_node = rn; /* back ref */
2566
0
    rfg->un_prefix = p;
2567
2568
0
  } else {
2569
2570
    /* detach rfg from previous route table location */
2571
0
    if (rfg->vn_node) {
2572
0
      rfg->vn_node->info = NULL;
2573
0
      agg_unlock_node(rfg->vn_node); /* frees */
2574
0
    }
2575
0
    rfg->vn_node = rn; /* back ref */
2576
0
    rfg->vn_prefix = p;
2577
0
  }
2578
2579
  /* attach */
2580
0
  rn->info = rfg;
2581
2582
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2583
0
    vnc_redistribute_postchange(bgp);
2584
0
  }
2585
2586
0
  return CMD_SUCCESS;
2587
0
}
2588
2589
DEFUN (vnc_nve_group_rt_import,
2590
       vnc_nve_group_rt_import_cmd,
2591
       "rt import RTLIST...",
2592
       "Specify route targets\n"
2593
       "Import filter\n"
2594
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2595
0
{
2596
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2597
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2598
0
  int rc;
2599
0
  struct listnode *node;
2600
0
  struct rfapi_rfg_name *rfgn;
2601
0
  int is_export_bgp = 0;
2602
0
  int is_export_zebra = 0;
2603
2604
  /* make sure it's still in list */
2605
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2606
    /* Not in list anymore */
2607
0
    vty_out(vty, "Current NVE group no longer exists\n");
2608
0
    return CMD_WARNING_CONFIG_FAILED;
2609
0
  }
2610
2611
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
2612
0
  if (rc != CMD_SUCCESS)
2613
0
    return rc;
2614
2615
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2616
0
          rfgn)) {
2617
2618
0
    if (rfgn->rfg == rfg) {
2619
0
      is_export_bgp = 1;
2620
0
      break;
2621
0
    }
2622
0
  }
2623
2624
0
  if (is_export_bgp)
2625
0
    vnc_direct_bgp_del_group(bgp, rfg);
2626
2627
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2628
0
          rfgn)) {
2629
2630
0
    if (rfgn->rfg == rfg) {
2631
0
      is_export_zebra = 1;
2632
0
      break;
2633
0
    }
2634
0
  }
2635
2636
0
  if (is_export_zebra)
2637
0
    vnc_zebra_del_group(bgp, rfg);
2638
2639
  /*
2640
   * stop referencing old import table, now reference new one
2641
   */
2642
0
  if (rfg->rfapi_import_table)
2643
0
    rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2644
0
  rfg->rfapi_import_table =
2645
0
    rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
2646
2647
0
  if (is_export_bgp)
2648
0
    vnc_direct_bgp_add_group(bgp, rfg);
2649
2650
0
  if (is_export_zebra)
2651
0
    vnc_zebra_add_group(bgp, rfg);
2652
2653
0
  return CMD_SUCCESS;
2654
0
}
2655
2656
DEFUN (vnc_nve_group_rt_export,
2657
       vnc_nve_group_rt_export_cmd,
2658
       "rt export RTLIST...",
2659
       "Specify route targets\n"
2660
       "Export filter\n"
2661
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2662
0
{
2663
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2664
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2665
0
  int rc;
2666
2667
  /* make sure it's still in list */
2668
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2669
    /* Not in list anymore */
2670
0
    vty_out(vty, "Current NVE group no longer exists\n");
2671
0
    return CMD_WARNING_CONFIG_FAILED;
2672
0
  }
2673
2674
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2675
0
    vnc_redistribute_prechange(bgp);
2676
0
  }
2677
2678
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
2679
2680
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2681
0
    vnc_redistribute_postchange(bgp);
2682
0
  }
2683
2684
0
  return rc;
2685
0
}
2686
2687
DEFUN (vnc_nve_group_rt_both,
2688
       vnc_nve_group_rt_both_cmd,
2689
       "rt both RTLIST...",
2690
       "Specify route targets\n"
2691
       "Export+import filters\n"
2692
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2693
0
{
2694
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2695
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2696
0
  int rc;
2697
0
  int is_export_bgp = 0;
2698
0
  int is_export_zebra = 0;
2699
0
  struct listnode *node;
2700
0
  struct rfapi_rfg_name *rfgn;
2701
2702
  /* make sure it's still in list */
2703
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2704
    /* Not in list anymore */
2705
0
    vty_out(vty, "Current NVE group no longer exists\n");
2706
0
    return CMD_WARNING_CONFIG_FAILED;
2707
0
  }
2708
2709
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
2710
0
  if (rc != CMD_SUCCESS)
2711
0
    return rc;
2712
2713
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2714
0
          rfgn)) {
2715
2716
0
    if (rfgn->rfg == rfg) {
2717
0
      is_export_bgp = 1;
2718
0
      break;
2719
0
    }
2720
0
  }
2721
2722
0
  if (is_export_bgp)
2723
0
    vnc_direct_bgp_del_group(bgp, rfg);
2724
2725
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2726
0
          rfgn)) {
2727
2728
0
    if (rfgn->rfg == rfg) {
2729
0
      is_export_zebra = 1;
2730
0
      break;
2731
0
    }
2732
0
  }
2733
2734
0
  if (is_export_zebra) {
2735
0
    vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
2736
0
    vnc_zebra_del_group(bgp, rfg);
2737
0
  }
2738
2739
  /*
2740
   * stop referencing old import table, now reference new one
2741
   */
2742
0
  if (rfg->rfapi_import_table)
2743
0
    rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2744
0
  rfg->rfapi_import_table =
2745
0
    rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
2746
2747
0
  if (is_export_bgp)
2748
0
    vnc_direct_bgp_add_group(bgp, rfg);
2749
2750
0
  if (is_export_zebra)
2751
0
    vnc_zebra_add_group(bgp, rfg);
2752
2753
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2754
0
    vnc_redistribute_prechange(bgp);
2755
0
  }
2756
2757
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
2758
2759
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2760
0
    vnc_redistribute_postchange(bgp);
2761
0
  }
2762
2763
0
  return rc;
2764
0
}
2765
2766
DEFUN (vnc_nve_group_l2rd,
2767
       vnc_nve_group_l2rd_cmd,
2768
       "l2rd <(1-255)|auto-vn>",
2769
       "Specify default Local Nve ID value to use in RD for L2 routes\n"
2770
       "Fixed value 1-255\n"
2771
       "use the low-order octet of the NVE's VN address\n")
2772
0
{
2773
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2774
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2775
2776
  /* make sure it's still in list */
2777
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2778
    /* Not in list anymore */
2779
0
    vty_out(vty, "Current NVE group no longer exists\n");
2780
0
    return CMD_WARNING_CONFIG_FAILED;
2781
0
  }
2782
2783
0
  if (strmatch(argv[1]->text, "auto:vn")) {
2784
0
    rfg->l2rd = 0;
2785
0
  } else {
2786
0
    char *end = NULL;
2787
0
    unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
2788
0
    uint8_t value = value_l & 0xff;
2789
2790
0
    if (!argv[1]->arg[0] || *end) {
2791
0
      vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
2792
0
        argv[1]->arg);
2793
0
      return CMD_WARNING_CONFIG_FAILED;
2794
0
    }
2795
0
    if ((value_l < 1) || (value_l > 0xff)) {
2796
0
      vty_out(vty,
2797
0
        "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
2798
0
        0x100);
2799
0
      return CMD_WARNING_CONFIG_FAILED;
2800
0
    }
2801
2802
0
    rfg->l2rd = value;
2803
0
  }
2804
0
  rfg->flags |= RFAPI_RFG_L2RD;
2805
2806
0
  return CMD_SUCCESS;
2807
0
}
2808
2809
DEFUN (vnc_nve_group_no_l2rd,
2810
       vnc_nve_group_no_l2rd_cmd,
2811
       "no l2rd",
2812
       NO_STR
2813
       "Specify default Local Nve ID value to use in RD for L2 routes\n")
2814
0
{
2815
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2816
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2817
2818
  /* make sure it's still in list */
2819
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2820
    /* Not in list anymore */
2821
0
    vty_out(vty, "Current NVE group no longer exists\n");
2822
0
    return CMD_WARNING_CONFIG_FAILED;
2823
0
  }
2824
2825
0
  rfg->l2rd = 0;
2826
0
  rfg->flags &= ~RFAPI_RFG_L2RD;
2827
2828
0
  return CMD_SUCCESS;
2829
0
}
2830
2831
DEFUN (vnc_nve_group_rd,
2832
       vnc_nve_group_rd_cmd,
2833
       "rd ASN:NN_OR_IP-ADDRESS:NN",
2834
       "Specify route distinguisher\n"
2835
       "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
2836
0
{
2837
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2838
0
  int ret;
2839
0
  struct prefix_rd prd;
2840
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2841
2842
  /* make sure it's still in list */
2843
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2844
    /* Not in list anymore */
2845
0
    vty_out(vty, "Current NVE group no longer exists\n");
2846
0
    return CMD_WARNING_CONFIG_FAILED;
2847
0
  }
2848
2849
0
  if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
2850
    /*
2851
     * use AF_UNIX to designate automatically-assigned RD
2852
     * auto:vn:nn where nn is a 2-octet quantity
2853
     */
2854
0
    char *end = NULL;
2855
0
    uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
2856
0
    uint16_t value = value32 & 0xffff;
2857
2858
0
    if (!argv[1]->arg[8] || *end) {
2859
0
      vty_out(vty, "%% Malformed rd\n");
2860
0
      return CMD_WARNING_CONFIG_FAILED;
2861
0
    }
2862
0
    if (value32 > 0xffff) {
2863
0
      vty_out(vty, "%% Malformed rd (must be less than %u\n",
2864
0
        0x0ffff);
2865
0
      return CMD_WARNING_CONFIG_FAILED;
2866
0
    }
2867
2868
0
    memset(&prd, 0, sizeof(prd));
2869
0
    prd.family = AF_UNIX;
2870
0
    prd.prefixlen = 64;
2871
0
    prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
2872
0
    prd.val[1] = RD_TYPE_IP & 0x0ff;
2873
0
    prd.val[6] = (value >> 8) & 0x0ff;
2874
0
    prd.val[7] = value & 0x0ff;
2875
2876
0
  } else {
2877
2878
    /* TODO: save RD format */
2879
0
    ret = str2prefix_rd(argv[1]->arg, &prd);
2880
0
    if (!ret) {
2881
0
      vty_out(vty, "%% Malformed rd\n");
2882
0
      return CMD_WARNING_CONFIG_FAILED;
2883
0
    }
2884
0
  }
2885
2886
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2887
0
    vnc_redistribute_prechange(bgp);
2888
0
  }
2889
2890
0
  rfg->rd = prd;
2891
2892
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
2893
0
    vnc_redistribute_postchange(bgp);
2894
0
  }
2895
0
  return CMD_SUCCESS;
2896
0
}
2897
2898
DEFUN (vnc_nve_group_responselifetime,
2899
       vnc_nve_group_responselifetime_cmd,
2900
       "response-lifetime <LIFETIME|infinite>",
2901
       "Specify response lifetime\n"
2902
       "Response lifetime in seconds\n" "Infinite response lifetime\n")
2903
0
{
2904
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2905
0
  unsigned int rspint;
2906
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2907
0
  struct rfapi_descriptor *rfd;
2908
0
  struct listnode *hdnode;
2909
2910
  /* make sure it's still in list */
2911
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2912
    /* Not in list anymore */
2913
0
    vty_out(vty, "Current NVE group no longer exists\n");
2914
0
    return CMD_WARNING_CONFIG_FAILED;
2915
0
  }
2916
2917
0
  if (strmatch(argv[1]->text, "infinite")) {
2918
0
    rspint = RFAPI_INFINITE_LIFETIME;
2919
0
  } else {
2920
0
    rspint = strtoul(argv[1]->arg, NULL, 10);
2921
0
  }
2922
2923
0
  rfg->response_lifetime = rspint;
2924
0
  rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME;
2925
0
  if (rfg->nves)
2926
0
    for (ALL_LIST_ELEMENTS_RO(rfg->nves, hdnode, rfd))
2927
0
      rfd->response_lifetime = rspint;
2928
0
  return CMD_SUCCESS;
2929
0
}
2930
2931
/*
2932
 * Sigh. This command, like exit-address-family, is a hack to deal
2933
 * with the lack of rigorous level control in the command handler.
2934
 * TBD fix command handler.
2935
 */
2936
DEFUN_NOSH (exit_vnc,
2937
       exit_vnc_cmd,
2938
       "exit-vnc",
2939
       "Exit VNC configuration mode\n")
2940
0
{
2941
0
  if (vty->node == BGP_VNC_DEFAULTS_NODE
2942
0
      || vty->node == BGP_VNC_NVE_GROUP_NODE
2943
0
      || vty->node == BGP_VNC_L2_GROUP_NODE) {
2944
2945
0
    vty->node = BGP_NODE;
2946
0
  }
2947
0
  return CMD_SUCCESS;
2948
0
}
2949
2950
static struct cmd_node bgp_vnc_defaults_node = {
2951
  .name = "bgp vnc defaults",
2952
  .node = BGP_VNC_DEFAULTS_NODE,
2953
  .parent_node = BGP_NODE,
2954
  .prompt = "%s(config-router-vnc-defaults)# ",
2955
};
2956
2957
static struct cmd_node bgp_vnc_nve_group_node = {
2958
  .name = "bgp vnc nve",
2959
  .node = BGP_VNC_NVE_GROUP_NODE,
2960
  .parent_node = BGP_NODE,
2961
  .prompt = "%s(config-router-vnc-nve-group)# ",
2962
};
2963
2964
/*-------------------------------------------------------------------------
2965
 *      VNC nve-group
2966
 * Note there are two types of NVEs, one for VPNs one for RFP NVEs
2967
 *-----------------------------------------------------------------------*/
2968
2969
DEFUN_NOSH (vnc_vrf_policy,
2970
       vnc_vrf_policy_cmd,
2971
       "vrf-policy NAME",
2972
       "Configure a VRF policy group\n"
2973
       "VRF name\n")
2974
0
{
2975
0
  struct rfapi_nve_group_cfg *rfg;
2976
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
2977
2978
0
  if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
2979
0
    vty_out(vty,
2980
0
      "Can't configure vrf-policy within a BGP VRF instance\n");
2981
0
    return CMD_WARNING_CONFIG_FAILED;
2982
0
  }
2983
2984
  /* Search for name */
2985
0
  rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg,
2986
0
           RFAPI_GROUP_CFG_VRF);
2987
2988
0
  if (!rfg) {
2989
0
    rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg);
2990
0
    if (!rfg) {
2991
      /* Error out of memory */
2992
0
      vty_out(vty, "Can't allocate memory for NVE group\n");
2993
0
      return CMD_WARNING_CONFIG_FAILED;
2994
0
    }
2995
0
  }
2996
  /*
2997
   * XXX subsequent calls will need to make sure this item is still
2998
   * in the linked list and has the same name
2999
   */
3000
0
  VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE, rfg);
3001
3002
0
  return CMD_SUCCESS;
3003
0
}
3004
3005
DEFUN (vnc_no_vrf_policy,
3006
       vnc_no_vrf_policy_cmd,
3007
       "no vrf-policy NAME",
3008
       NO_STR
3009
       "Remove a VRF policy group\n"
3010
       "VRF name\n")
3011
0
{
3012
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3013
3014
  /* silently return */
3015
0
  if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3016
0
    return CMD_SUCCESS;
3017
3018
0
  return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg,
3019
0
            RFAPI_GROUP_CFG_VRF);
3020
0
}
3021
3022
DEFUN (vnc_vrf_policy_label,
3023
       vnc_vrf_policy_label_cmd,
3024
       "label (0-1048575)",
3025
       "Default label value for VRF\n"
3026
       "Label Value <0-1048575>\n")
3027
0
{
3028
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3029
3030
0
  uint32_t label;
3031
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3032
3033
  /* make sure it's still in list */
3034
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3035
    /* Not in list anymore */
3036
0
    vty_out(vty, "Current NVE group no longer exists\n");
3037
0
    return CMD_WARNING_CONFIG_FAILED;
3038
0
  }
3039
3040
0
  label = strtoul(argv[1]->arg, NULL, 10);
3041
3042
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3043
0
    vnc_redistribute_prechange(bgp);
3044
0
  }
3045
3046
0
  rfg->label = label;
3047
3048
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3049
0
    vnc_redistribute_postchange(bgp);
3050
0
  }
3051
0
  return CMD_SUCCESS;
3052
0
}
3053
3054
DEFUN (vnc_vrf_policy_no_label,
3055
       vnc_vrf_policy_no_label_cmd,
3056
       "no label",
3057
       NO_STR
3058
       "Remove VRF default label\n")
3059
0
{
3060
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3061
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3062
3063
  /* make sure it's still in list */
3064
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3065
    /* Not in list anymore */
3066
0
    vty_out(vty, "Current VRF group no longer exists\n");
3067
0
    return CMD_WARNING_CONFIG_FAILED;
3068
0
  }
3069
3070
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3071
0
    vnc_redistribute_prechange(bgp);
3072
0
  }
3073
3074
0
  rfg->label = MPLS_LABEL_NONE;
3075
3076
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3077
0
    vnc_redistribute_postchange(bgp);
3078
0
  }
3079
0
  return CMD_SUCCESS;
3080
0
}
3081
3082
DEFUN (vnc_vrf_policy_nexthop,
3083
       vnc_vrf_policy_nexthop_cmd,
3084
       "nexthop <A.B.C.D|X:X::X:X|self>",
3085
       "Specify next hop to use for VRF advertised prefixes\n"
3086
       "IPv4 prefix\n"
3087
       "IPv6 prefix\n"
3088
       "Use configured router-id (default)\n")
3089
0
{
3090
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3091
0
  struct prefix p;
3092
3093
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3094
3095
  /* make sure it's still in list */
3096
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3097
    /* Not in list anymore */
3098
0
    vty_out(vty, "Current VRF no longer exists\n");
3099
0
    return CMD_WARNING_CONFIG_FAILED;
3100
0
  }
3101
3102
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3103
0
    vnc_redistribute_prechange(bgp);
3104
0
  }
3105
3106
0
  if (!str2prefix(argv[1]->arg, &p) && p.family) {
3107
    // vty_out (vty, "Nexthop set to self\n");
3108
0
    SET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
3109
0
    memset(&rfg->vn_prefix, 0, sizeof(struct prefix));
3110
0
  } else {
3111
0
    UNSET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
3112
0
    rfg->vn_prefix = p;
3113
0
    rfg->un_prefix = p;
3114
0
  }
3115
3116
  /* TBD handle router-id/ nexthop changes when have advertised prefixes
3117
   */
3118
3119
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3120
0
    vnc_redistribute_postchange(bgp);
3121
0
  }
3122
3123
0
  return CMD_SUCCESS;
3124
0
}
3125
3126
/* The RT code should be refactored/simplified with above... */
3127
DEFUN (vnc_vrf_policy_rt_import,
3128
       vnc_vrf_policy_rt_import_cmd,
3129
       "rt import RTLIST...",
3130
       "Specify route targets\n"
3131
       "Import filter\n"
3132
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3133
0
{
3134
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3135
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3136
0
  int rc;
3137
0
  struct listnode *node;
3138
0
  struct rfapi_rfg_name *rfgn;
3139
0
  int is_export_bgp = 0;
3140
0
  int is_export_zebra = 0;
3141
3142
  /* make sure it's still in list */
3143
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3144
    /* Not in list anymore */
3145
0
    vty_out(vty, "Current NVE group no longer exists\n");
3146
0
    return CMD_WARNING_CONFIG_FAILED;
3147
0
  }
3148
3149
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
3150
0
  if (rc != CMD_SUCCESS)
3151
0
    return rc;
3152
3153
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
3154
0
          rfgn)) {
3155
3156
0
    if (rfgn->rfg == rfg) {
3157
0
      is_export_bgp = 1;
3158
0
      break;
3159
0
    }
3160
0
  }
3161
3162
0
  if (is_export_bgp)
3163
0
    vnc_direct_bgp_del_group(bgp, rfg);
3164
3165
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
3166
0
          rfgn)) {
3167
3168
0
    if (rfgn->rfg == rfg) {
3169
0
      is_export_zebra = 1;
3170
0
      break;
3171
0
    }
3172
0
  }
3173
3174
0
  if (is_export_zebra)
3175
0
    vnc_zebra_del_group(bgp, rfg);
3176
3177
  /*
3178
   * stop referencing old import table, now reference new one
3179
   */
3180
0
  if (rfg->rfapi_import_table)
3181
0
    rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
3182
0
  rfg->rfapi_import_table =
3183
0
    rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
3184
3185
0
  if (is_export_bgp)
3186
0
    vnc_direct_bgp_add_group(bgp, rfg);
3187
3188
0
  if (is_export_zebra)
3189
0
    vnc_zebra_add_group(bgp, rfg);
3190
3191
0
  return CMD_SUCCESS;
3192
0
}
3193
3194
DEFUN (vnc_vrf_policy_rt_export,
3195
       vnc_vrf_policy_rt_export_cmd,
3196
       "rt export RTLIST...",
3197
       "Specify route targets\n"
3198
       "Export filter\n"
3199
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3200
0
{
3201
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3202
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3203
0
  int rc;
3204
3205
  /* make sure it's still in list */
3206
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3207
    /* Not in list anymore */
3208
0
    vty_out(vty, "Current NVE group no longer exists\n");
3209
0
    return CMD_WARNING_CONFIG_FAILED;
3210
0
  }
3211
3212
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3213
0
    vnc_redistribute_prechange(bgp);
3214
0
  }
3215
3216
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
3217
3218
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3219
0
    vnc_redistribute_postchange(bgp);
3220
0
  }
3221
3222
0
  return rc;
3223
0
}
3224
3225
DEFUN (vnc_vrf_policy_rt_both,
3226
       vnc_vrf_policy_rt_both_cmd,
3227
       "rt both RTLIST...",
3228
       "Specify route targets\n"
3229
       "Export+import filters\n"
3230
       "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3231
0
{
3232
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3233
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3234
0
  int rc;
3235
0
  int is_export_bgp = 0;
3236
0
  int is_export_zebra = 0;
3237
0
  struct listnode *node;
3238
0
  struct rfapi_rfg_name *rfgn;
3239
3240
  /* make sure it's still in list */
3241
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3242
    /* Not in list anymore */
3243
0
    vty_out(vty, "Current NVE group no longer exists\n");
3244
0
    return CMD_WARNING_CONFIG_FAILED;
3245
0
  }
3246
3247
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
3248
0
  if (rc != CMD_SUCCESS)
3249
0
    return rc;
3250
3251
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
3252
0
          rfgn)) {
3253
3254
0
    if (rfgn->rfg == rfg) {
3255
0
      is_export_bgp = 1;
3256
0
      break;
3257
0
    }
3258
0
  }
3259
3260
0
  if (is_export_bgp)
3261
0
    vnc_direct_bgp_del_group(bgp, rfg);
3262
3263
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
3264
0
          rfgn)) {
3265
3266
0
    if (rfgn->rfg == rfg) {
3267
0
      is_export_zebra = 1;
3268
0
      break;
3269
0
    }
3270
0
  }
3271
3272
0
  if (is_export_zebra) {
3273
0
    vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
3274
0
    vnc_zebra_del_group(bgp, rfg);
3275
0
  }
3276
3277
  /*
3278
   * stop referencing old import table, now reference new one
3279
   */
3280
0
  if (rfg->rfapi_import_table)
3281
0
    rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
3282
0
  rfg->rfapi_import_table =
3283
0
    rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
3284
3285
0
  if (is_export_bgp)
3286
0
    vnc_direct_bgp_add_group(bgp, rfg);
3287
3288
0
  if (is_export_zebra)
3289
0
    vnc_zebra_add_group(bgp, rfg);
3290
3291
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3292
0
    vnc_redistribute_prechange(bgp);
3293
0
  }
3294
3295
0
  rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
3296
3297
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3298
0
    vnc_redistribute_postchange(bgp);
3299
0
  }
3300
3301
0
  return rc;
3302
0
}
3303
3304
DEFUN (vnc_vrf_policy_rd,
3305
       vnc_vrf_policy_rd_cmd,
3306
       "rd ASN:NN_OR_IP-ADDRESS:NN",
3307
       "Specify default VRF route distinguisher\n"
3308
       "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
3309
0
{
3310
0
  int ret;
3311
0
  struct prefix_rd prd;
3312
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3313
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3314
3315
  /* make sure it's still in list */
3316
0
  if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3317
    /* Not in list anymore */
3318
0
    vty_out(vty, "Current NVE group no longer exists\n");
3319
0
    return CMD_WARNING_CONFIG_FAILED;
3320
0
  }
3321
3322
0
  if (!strncmp(argv[1]->arg, "auto:nh:", 8)) {
3323
    /*
3324
     * use AF_UNIX to designate automatically-assigned RD
3325
     * auto:vn:nn where nn is a 2-octet quantity
3326
     */
3327
0
    char *end = NULL;
3328
0
    uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
3329
0
    uint16_t value = value32 & 0xffff;
3330
3331
0
    if (!*(argv[1]->arg + 5) || *end) {
3332
0
      vty_out(vty, "%% Malformed rd\n");
3333
0
      return CMD_WARNING_CONFIG_FAILED;
3334
0
    }
3335
0
    if (value32 > 0xffff) {
3336
0
      vty_out(vty, "%% Malformed rd (must be less than %u\n",
3337
0
        0x0ffff);
3338
0
      return CMD_WARNING_CONFIG_FAILED;
3339
0
    }
3340
3341
0
    memset(&prd, 0, sizeof(prd));
3342
0
    prd.family = AF_UNIX;
3343
0
    prd.prefixlen = 64;
3344
0
    prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
3345
0
    prd.val[1] = RD_TYPE_IP & 0x0ff;
3346
0
    prd.val[6] = (value >> 8) & 0x0ff;
3347
0
    prd.val[7] = value & 0x0ff;
3348
3349
0
  } else {
3350
3351
    /* TODO: save RD format */
3352
0
    ret = str2prefix_rd(argv[1]->arg, &prd);
3353
0
    if (!ret) {
3354
0
      vty_out(vty, "%% Malformed rd\n");
3355
0
      return CMD_WARNING_CONFIG_FAILED;
3356
0
    }
3357
0
  }
3358
3359
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3360
0
    vnc_redistribute_prechange(bgp);
3361
0
  }
3362
3363
0
  rfg->rd = prd;
3364
3365
0
  if (bgp->rfapi_cfg->rfg_redist == rfg) {
3366
0
    vnc_redistribute_postchange(bgp);
3367
0
  }
3368
0
  return CMD_SUCCESS;
3369
0
}
3370
3371
DEFUN_NOSH (exit_vrf_policy,
3372
       exit_vrf_policy_cmd,
3373
       "exit-vrf-policy",
3374
       "Exit VRF policy configuration mode\n")
3375
0
{
3376
0
  if (vty->node == BGP_VRF_POLICY_NODE) {
3377
0
    vty->node = BGP_NODE;
3378
0
  }
3379
0
  return CMD_SUCCESS;
3380
0
}
3381
3382
static struct cmd_node bgp_vrf_policy_node = {
3383
  .name = "bgp vrf policy",
3384
  .node = BGP_VRF_POLICY_NODE,
3385
  .parent_node = BGP_NODE,
3386
  .prompt = "%s(config-router-vrf-policy)# ",
3387
};
3388
3389
/*-------------------------------------------------------------------------
3390
 *      vnc-l2-group
3391
 *-----------------------------------------------------------------------*/
3392
3393
3394
DEFUN_NOSH (vnc_l2_group,
3395
       vnc_l2_group_cmd,
3396
       "vnc l2-group NAME",
3397
       VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n")
3398
0
{
3399
0
  struct rfapi_l2_group_cfg *rfg;
3400
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3401
0
  VNC_VTY_CONFIG_CHECK(bgp);
3402
3403
  /* Search for name */
3404
0
  rfg = rfapi_l2_group_lookup_byname(bgp, argv[2]->arg);
3405
3406
0
  if (!rfg) {
3407
0
    rfg = rfapi_l2_group_new();
3408
0
    if (!rfg) {
3409
      /* Error out of memory */
3410
0
      vty_out(vty, "Can't allocate memory for L2 group\n");
3411
0
      return CMD_WARNING_CONFIG_FAILED;
3412
0
    }
3413
0
    rfg->name = strdup(argv[2]->arg);
3414
    /* add to tail of list */
3415
0
    listnode_add(bgp->rfapi_cfg->l2_groups, rfg);
3416
0
  }
3417
3418
  /*
3419
   * XXX subsequent calls will need to make sure this item is still
3420
   * in the linked list and has the same name
3421
   */
3422
0
  VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE, rfg);
3423
0
  return CMD_SUCCESS;
3424
0
}
3425
3426
static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */
3427
              struct bgp *bgp,
3428
              struct rfapi_l2_group_cfg *rfg)
3429
0
{
3430
  /* delete it */
3431
0
  free(rfg->name);
3432
0
  if (rfg->rt_import_list)
3433
0
    ecommunity_free(&rfg->rt_import_list);
3434
0
  if (rfg->rt_export_list)
3435
0
    ecommunity_free(&rfg->rt_export_list);
3436
0
  if (rfg->labels)
3437
0
    list_delete(&rfg->labels);
3438
0
  XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
3439
0
  listnode_delete(bgp->rfapi_cfg->l2_groups, rfg);
3440
3441
0
  rfapi_l2_group_del(rfg);
3442
0
}
3443
3444
static int
3445
bgp_rfapi_delete_named_l2_group(struct vty *vty, /* NULL = no output */
3446
        struct bgp *bgp,
3447
        const char *rfg_name) /* NULL = any */
3448
0
{
3449
0
  struct rfapi_l2_group_cfg *rfg = NULL;
3450
0
  struct listnode *node, *nnode;
3451
3452
  /* Search for name */
3453
0
  if (rfg_name) {
3454
0
    rfg = rfapi_l2_group_lookup_byname(bgp, rfg_name);
3455
0
    if (!rfg) {
3456
0
      if (vty)
3457
0
        vty_out(vty, "No L2 group named \"%s\"\n",
3458
0
          rfg_name);
3459
0
      return CMD_WARNING_CONFIG_FAILED;
3460
0
    }
3461
0
  }
3462
3463
0
  if (rfg)
3464
0
    bgp_rfapi_delete_l2_group(vty, bgp, rfg);
3465
0
  else /* must be delete all */
3466
0
    for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode,
3467
0
               rfg))
3468
0
      bgp_rfapi_delete_l2_group(vty, bgp, rfg);
3469
0
  return CMD_SUCCESS;
3470
0
}
3471
3472
DEFUN (vnc_no_l2_group,
3473
       vnc_no_l2_group_cmd,
3474
       "no vnc l2-group NAME",
3475
       NO_STR
3476
       VNC_CONFIG_STR
3477
       "Configure a L2 group\n"
3478
       "Group name\n")
3479
0
{
3480
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3481
3482
0
  return bgp_rfapi_delete_named_l2_group(vty, bgp, argv[3]->arg);
3483
0
}
3484
3485
3486
DEFUN (vnc_l2_group_lni,
3487
       vnc_l2_group_lni_cmd,
3488
       "logical-network-id (0-4294967295)",
3489
       "Specify Logical Network ID associated with group\n"
3490
       "value\n")
3491
0
{
3492
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3493
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3494
3495
  /* make sure it's still in list */
3496
0
  if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3497
    /* Not in list anymore */
3498
0
    vty_out(vty, "Current L2 group no longer exists\n");
3499
0
    return CMD_WARNING_CONFIG_FAILED;
3500
0
  }
3501
3502
0
  rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10);
3503
3504
0
  return CMD_SUCCESS;
3505
0
}
3506
3507
DEFUN (vnc_l2_group_labels,
3508
       vnc_l2_group_labels_cmd,
3509
       "labels (0-1048575)...",
3510
       "Specify label values associated with group\n"
3511
       "Space separated list of label values <0-1048575>\n")
3512
0
{
3513
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3514
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3515
0
  struct list *ll;
3516
3517
  /* make sure it's still in list */
3518
0
  if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3519
    /* Not in list anymore */
3520
0
    vty_out(vty, "Current L2 group no longer exists\n");
3521
0
    return CMD_WARNING_CONFIG_FAILED;
3522
0
  }
3523
3524
0
  ll = rfg->labels;
3525
0
  if (ll == NULL) {
3526
0
    ll = list_new();
3527
0
    rfg->labels = ll;
3528
0
  }
3529
0
  argc--;
3530
0
  argv++;
3531
0
  for (; argc; --argc, ++argv) {
3532
0
    uint32_t label;
3533
0
    label = strtoul(argv[0]->arg, NULL, 10);
3534
0
    if (!listnode_lookup(ll, (void *)(uintptr_t)label))
3535
0
      listnode_add(ll, (void *)(uintptr_t)label);
3536
0
  }
3537
3538
0
  return CMD_SUCCESS;
3539
0
}
3540
3541
DEFUN (vnc_l2_group_no_labels,
3542
       vnc_l2_group_no_labels_cmd,
3543
       "no labels (0-1048575)...",
3544
       NO_STR
3545
       "Specify label values associated with L2 group\n"
3546
       "Space separated list of label values <0-1048575>\n")
3547
0
{
3548
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3549
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3550
0
  struct list *ll;
3551
3552
  /* make sure it's still in list */
3553
0
  if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3554
    /* Not in list anymore */
3555
0
    vty_out(vty, "Current L2 group no longer exists\n");
3556
0
    return CMD_WARNING_CONFIG_FAILED;
3557
0
  }
3558
3559
0
  ll = rfg->labels;
3560
0
  if (ll == NULL) {
3561
0
    vty_out(vty, "Label no longer associated with group\n");
3562
0
    return CMD_WARNING_CONFIG_FAILED;
3563
0
  }
3564
3565
0
  argc -= 2;
3566
0
  argv += 2;
3567
0
  for (; argc; --argc, ++argv) {
3568
0
    uint32_t label;
3569
0
    label = strtoul(argv[0]->arg, NULL, 10);
3570
0
    listnode_delete(ll, (void *)(uintptr_t)label);
3571
0
  }
3572
3573
0
  return CMD_SUCCESS;
3574
0
}
3575
3576
DEFUN (vnc_l2_group_rt,
3577
       vnc_l2_group_rt_cmd,
3578
       "rt <both|export|import> ASN:NN_OR_IP-ADDRESS:NN",
3579
       "Specify route targets\n"
3580
       "Export+import filters\n"
3581
       "Export filters\n"
3582
       "Import filters\n"
3583
       "A route target\n")
3584
0
{
3585
0
  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3586
0
  VTY_DECLVAR_CONTEXT(bgp, bgp);
3587
0
  int rc = CMD_SUCCESS;
3588
0
  int do_import = 0;
3589
0
  int do_export = 0;
3590
3591
0
  switch (argv[1]->arg[0]) {
3592
0
  case 'b':
3593
0
    do_export = 1; /* fall through */
3594
0
  case 'i':
3595
0
    do_import = 1;
3596
0
    break;
3597
0
  case 'e':
3598
0
    do_export = 1;
3599
0
    break;
3600
0
  default:
3601
0
    vty_out(vty, "Unknown option, %s\n", argv[1]->arg);
3602
0
    return CMD_ERR_NO_MATCH;
3603
0
  }
3604
3605
  /* make sure it's still in list */
3606
0
  if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3607
    /* Not in list anymore */
3608
0
    vty_out(vty, "Current L2 group no longer exists\n");
3609
0
    return CMD_WARNING_CONFIG_FAILED;
3610
0
  }
3611
3612
0
  if (do_import)
3613
0
    rc = set_ecom_list(vty, argc - 2, argv + 2,
3614
0
           &rfg->rt_import_list);
3615
0
  if (rc == CMD_SUCCESS && do_export)
3616
0
    rc = set_ecom_list(vty, argc - 2, argv + 2,
3617
0
           &rfg->rt_export_list);
3618
0
  return rc;
3619
0
}
3620
3621
3622
static struct cmd_node bgp_vnc_l2_group_node = {
3623
  .name = "bgp vnc l2",
3624
  .node = BGP_VNC_L2_GROUP_NODE,
3625
  .parent_node = BGP_NODE,
3626
  .prompt = "%s(config-router-vnc-l2-group)# ",
3627
};
3628
3629
struct rfapi_l2_group_cfg *
3630
bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
3631
         uint32_t label)
3632
0
{
3633
0
  struct rfapi_l2_group_cfg *rfg;
3634
0
  struct listnode *node;
3635
3636
0
  if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
3637
0
    return NULL;
3638
3639
0
  label = label & 0xfffff; /* label is 20 bits! */
3640
3641
0
  for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) {
3642
0
    if (rfg->logical_net_id == logical_net_id) {
3643
0
      struct listnode *lnode;
3644
0
      void *data;
3645
0
      for (ALL_LIST_ELEMENTS_RO(rfg->labels, lnode, data))
3646
0
        if (((uint32_t)((uintptr_t)data))
3647
0
            == label) { /* match! */
3648
0
          return rfg;
3649
0
        }
3650
0
    }
3651
0
  }
3652
0
  return NULL;
3653
0
}
3654
3655
struct list *bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp,
3656
              uint32_t logical_net_id,
3657
              uint32_t label)
3658
0
{
3659
0
  struct rfapi_l2_group_cfg *rfg;
3660
0
  rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
3661
0
  if (rfg) {
3662
0
    return rfg->labels;
3663
0
  }
3664
0
  return NULL;
3665
0
}
3666
3667
struct ecommunity *
3668
bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import,
3669
              uint32_t logical_net_id, uint32_t label)
3670
0
{
3671
0
  struct rfapi_l2_group_cfg *rfg;
3672
0
  rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
3673
0
  if (rfg) {
3674
0
    if (is_import)
3675
0
      return rfg->rt_import_list;
3676
0
    else
3677
0
      return rfg->rt_export_list;
3678
0
  }
3679
0
  return NULL;
3680
0
}
3681
3682
void bgp_rfapi_cfg_init(void)
3683
0
{
3684
0
  install_node(&bgp_vnc_defaults_node);
3685
0
  install_node(&bgp_vnc_nve_group_node);
3686
0
  install_node(&bgp_vrf_policy_node);
3687
0
  install_node(&bgp_vnc_l2_group_node);
3688
0
  install_default(BGP_VRF_POLICY_NODE);
3689
0
  install_default(BGP_VNC_DEFAULTS_NODE);
3690
0
  install_default(BGP_VNC_NVE_GROUP_NODE);
3691
0
  install_default(BGP_VNC_L2_GROUP_NODE);
3692
3693
  /*
3694
   * Add commands
3695
   */
3696
0
  install_element(BGP_NODE, &vnc_defaults_cmd);
3697
0
  install_element(BGP_NODE, &vnc_nve_group_cmd);
3698
0
  install_element(BGP_NODE, &vnc_no_nve_group_cmd);
3699
0
  install_element(BGP_NODE, &vnc_vrf_policy_cmd);
3700
0
  install_element(BGP_NODE, &vnc_no_vrf_policy_cmd);
3701
0
  install_element(BGP_NODE, &vnc_l2_group_cmd);
3702
0
  install_element(BGP_NODE, &vnc_no_l2_group_cmd);
3703
0
  install_element(BGP_NODE, &vnc_advertise_un_method_cmd);
3704
0
  install_element(BGP_NODE, &vnc_export_mode_cmd);
3705
3706
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd);
3707
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd);
3708
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd);
3709
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd);
3710
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd);
3711
0
  install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd);
3712
0
  install_element(BGP_VNC_DEFAULTS_NODE,
3713
0
      &vnc_defaults_responselifetime_cmd);
3714
0
  install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd);
3715
3716
0
  install_element(BGP_NODE, &vnc_redistribute_protocol_cmd);
3717
0
  install_element(BGP_NODE, &vnc_no_redistribute_protocol_cmd);
3718
0
  install_element(BGP_NODE, &vnc_redistribute_nvegroup_cmd);
3719
0
  install_element(BGP_NODE, &vnc_redistribute_no_nvegroup_cmd);
3720
0
  install_element(BGP_NODE, &vnc_redistribute_lifetime_cmd);
3721
0
  install_element(BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd);
3722
0
  install_element(BGP_NODE, &vnc_redistribute_mode_cmd);
3723
0
  install_element(BGP_NODE, &vnc_redistribute_bgp_exterior_cmd);
3724
3725
0
  install_element(BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd);
3726
0
  install_element(BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd);
3727
0
  install_element(BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd);
3728
0
  install_element(BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd);
3729
3730
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3731
0
      &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd);
3732
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3733
0
      &vnc_nve_group_redist_bgpdirect_prefixlist_cmd);
3734
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3735
0
      &vnc_nve_group_redist_bgpdirect_no_routemap_cmd);
3736
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3737
0
      &vnc_nve_group_redist_bgpdirect_routemap_cmd);
3738
3739
0
  install_element(BGP_NODE, &vnc_export_nvegroup_cmd);
3740
0
  install_element(BGP_NODE, &vnc_no_export_nvegroup_cmd);
3741
0
  install_element(BGP_NODE, &vnc_nve_export_prefixlist_cmd);
3742
0
  install_element(BGP_NODE, &vnc_nve_export_routemap_cmd);
3743
0
  install_element(BGP_NODE, &vnc_nve_export_no_prefixlist_cmd);
3744
0
  install_element(BGP_NODE, &vnc_nve_export_no_routemap_cmd);
3745
3746
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd);
3747
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd);
3748
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd);
3749
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd);
3750
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd);
3751
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd);
3752
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd);
3753
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3754
0
      &vnc_nve_group_responselifetime_cmd);
3755
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3756
0
      &vnc_nve_group_export_prefixlist_cmd);
3757
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3758
0
      &vnc_nve_group_export_routemap_cmd);
3759
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3760
0
      &vnc_nve_group_export_no_prefixlist_cmd);
3761
0
  install_element(BGP_VNC_NVE_GROUP_NODE,
3762
0
      &vnc_nve_group_export_no_routemap_cmd);
3763
0
  install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd);
3764
3765
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd);
3766
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd);
3767
  // Reenable to support VRF controller use case and testing
3768
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd);
3769
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd);
3770
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd);
3771
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd);
3772
0
  install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd);
3773
0
  install_element(BGP_VRF_POLICY_NODE,
3774
0
      &vnc_vrf_policy_export_prefixlist_cmd);
3775
0
  install_element(BGP_VRF_POLICY_NODE,
3776
0
      &vnc_vrf_policy_export_routemap_cmd);
3777
0
  install_element(BGP_VRF_POLICY_NODE,
3778
0
      &vnc_vrf_policy_export_no_prefixlist_cmd);
3779
0
  install_element(BGP_VRF_POLICY_NODE,
3780
0
      &vnc_vrf_policy_export_no_routemap_cmd);
3781
0
  install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
3782
3783
0
  install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd);
3784
0
  install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd);
3785
0
  install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd);
3786
0
  install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd);
3787
0
  install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd);
3788
0
}
3789
3790
struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
3791
1
{
3792
1
  struct rfapi_cfg *h;
3793
1
  afi_t afi;
3794
3795
1
  h = XCALLOC(MTYPE_RFAPI_CFG, sizeof(struct rfapi_cfg));
3796
1
  assert(h);
3797
3798
1
  h->nve_groups_sequential = list_new();
3799
1
  assert(h->nve_groups_sequential);
3800
4
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3801
3
    h->nve_groups_vn[afi] = agg_table_init();
3802
3
    h->nve_groups_un[afi] = agg_table_init();
3803
3
  }
3804
1
  h->default_response_lifetime =
3805
1
    BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
3806
1
  h->rfg_export_direct_bgp_l = list_new();
3807
1
  h->rfg_export_zebra_l = list_new();
3808
1
  h->resolve_nve_roo_local_admin =
3809
1
    BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT;
3810
3811
1
  SET_FLAG(h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT);
3812
3813
1
  if (cfg == NULL) {
3814
0
    h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
3815
0
    h->rfp_cfg.ftd_advertisement_interval =
3816
0
      RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
3817
0
    h->rfp_cfg.holddown_factor =
3818
0
      RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR;
3819
0
    h->rfp_cfg.use_updated_response = 0;
3820
0
    h->rfp_cfg.use_removes = 0;
3821
1
  } else {
3822
1
    h->rfp_cfg.download_type = cfg->download_type;
3823
1
    h->rfp_cfg.ftd_advertisement_interval =
3824
1
      cfg->ftd_advertisement_interval;
3825
1
    h->rfp_cfg.holddown_factor = cfg->holddown_factor;
3826
1
    h->rfp_cfg.use_updated_response = cfg->use_updated_response;
3827
1
    h->rfp_cfg.use_removes = cfg->use_removes;
3828
1
    if (cfg->use_updated_response)
3829
1
      h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE;
3830
0
    else
3831
0
      h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE;
3832
1
    if (cfg->use_removes)
3833
1
      h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
3834
0
    else
3835
0
      h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
3836
1
  }
3837
1
  return h;
3838
1
}
3839
3840
static void bgp_rfapi_rfgn_list_delete(void *data)
3841
0
{
3842
0
  struct rfapi_rfg_name *rfgn = data;
3843
0
  free(rfgn->name);
3844
0
  rfgn_free(rfgn);
3845
0
}
3846
3847
void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
3848
0
{
3849
0
  afi_t afi;
3850
0
  if (h == NULL)
3851
0
    return;
3852
3853
0
  bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX);
3854
0
  bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL);
3855
0
  if (h->l2_groups != NULL)
3856
0
    list_delete(&h->l2_groups);
3857
0
  list_delete(&h->nve_groups_sequential);
3858
3859
0
  h->rfg_export_direct_bgp_l->del = bgp_rfapi_rfgn_list_delete;
3860
0
  list_delete(&h->rfg_export_direct_bgp_l);
3861
3862
0
  h->rfg_export_zebra_l->del = bgp_rfapi_rfgn_list_delete;
3863
0
  list_delete(&h->rfg_export_zebra_l);
3864
3865
0
  if (h->default_rt_export_list)
3866
0
    ecommunity_free(&h->default_rt_export_list);
3867
0
  if (h->default_rt_import_list)
3868
0
    ecommunity_free(&h->default_rt_import_list);
3869
0
  XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
3870
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3871
0
    agg_table_finish(h->nve_groups_vn[afi]);
3872
0
    agg_table_finish(h->nve_groups_un[afi]);
3873
0
  }
3874
0
  XFREE(MTYPE_RFAPI_CFG, h);
3875
0
}
3876
3877
int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
3878
0
{
3879
0
  struct listnode *node, *nnode;
3880
0
  struct rfapi_nve_group_cfg *rfg;
3881
0
  struct rfapi_cfg *hc = bgp->rfapi_cfg;
3882
0
  struct rfapi_rfg_name *rfgn;
3883
0
  int write = 0;
3884
0
  afi_t afi;
3885
0
  int type;
3886
0
  if (bgp->rfapi == NULL || hc == NULL)
3887
0
    return write;
3888
3889
0
  vty_out(vty, "!\n");
3890
0
  for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg))
3891
0
    if (rfg->type == RFAPI_GROUP_CFG_VRF) {
3892
0
      ++write;
3893
0
      vty_out(vty, " vrf-policy %s\n", rfg->name);
3894
0
      if (rfg->label <= MPLS_LABEL_MAX) {
3895
0
        vty_out(vty, "  label %u\n", rfg->label);
3896
0
      }
3897
0
      if (CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) {
3898
0
        vty_out(vty, "  nexthop self\n");
3899
3900
0
      } else {
3901
0
        if (rfg->vn_prefix.family) {
3902
0
          char buf[BUFSIZ];
3903
0
          buf[0] = buf[BUFSIZ - 1] = 0;
3904
0
          inet_ntop(rfg->vn_prefix.family,
3905
0
              &rfg->vn_prefix.u.prefix, buf,
3906
0
              sizeof(buf));
3907
0
          if (!buf[0] || buf[BUFSIZ - 1]) {
3908
            // vty_out (vty, "nexthop
3909
            // self\n");
3910
0
          } else {
3911
0
            vty_out(vty, "  nexthop %s\n",
3912
0
              buf);
3913
0
          }
3914
0
        }
3915
0
      }
3916
3917
0
      if (rfg->rd.prefixlen) {
3918
0
        if (AF_UNIX == rfg->rd.family) {
3919
3920
0
          uint16_t value = 0;
3921
3922
0
          value = ((rfg->rd.val[6] << 8)
3923
0
             & 0x0ff00)
3924
0
            | (rfg->rd.val[7] & 0x0ff);
3925
3926
0
          vty_out(vty, "  rd auto:nh:%d\n",
3927
0
            value);
3928
3929
0
        } else
3930
0
          vty_out(vty, "  rd %pRDP\n", &rfg->rd);
3931
0
      }
3932
3933
0
      if (rfg->rt_import_list && rfg->rt_export_list
3934
0
          && ecommunity_cmp(rfg->rt_import_list,
3935
0
                rfg->rt_export_list)) {
3936
0
        char *b = ecommunity_ecom2str(
3937
0
          rfg->rt_import_list,
3938
0
          ECOMMUNITY_FORMAT_ROUTE_MAP,
3939
0
          ECOMMUNITY_ROUTE_TARGET);
3940
0
        vty_out(vty, "  rt both %s\n", b);
3941
0
        XFREE(MTYPE_ECOMMUNITY_STR, b);
3942
0
      } else {
3943
0
        if (rfg->rt_import_list) {
3944
0
          char *b = ecommunity_ecom2str(
3945
0
            rfg->rt_import_list,
3946
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
3947
0
            ECOMMUNITY_ROUTE_TARGET);
3948
0
          vty_out(vty, "  rt import %s\n", b);
3949
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
3950
0
        }
3951
0
        if (rfg->rt_export_list) {
3952
0
          char *b = ecommunity_ecom2str(
3953
0
            rfg->rt_export_list,
3954
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
3955
0
            ECOMMUNITY_ROUTE_TARGET);
3956
0
          vty_out(vty, "  rt export %s\n", b);
3957
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
3958
0
        }
3959
0
      }
3960
3961
      /*
3962
       * route filtering: prefix-lists and route-maps
3963
       */
3964
0
      for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
3965
3966
0
        const char *afistr =
3967
0
          (afi == AFI_IP) ? "ipv4" : "ipv6";
3968
3969
0
        if (rfg->plist_export_bgp_name[afi]) {
3970
0
          vty_out(vty,
3971
0
            "  export %s%s prefix-list %s\n",
3972
0
            (rfg->type == RFAPI_GROUP_CFG_VRF
3973
0
               ? ""
3974
0
               : "bgp "),
3975
0
            afistr,
3976
0
            rfg->plist_export_bgp_name
3977
0
              [afi]);
3978
0
        }
3979
0
        if (rfg->plist_export_zebra_name[afi]) {
3980
0
          vty_out(vty,
3981
0
            "  export %s%s prefix-list %s\n",
3982
0
            (rfg->type == RFAPI_GROUP_CFG_VRF
3983
0
               ? ""
3984
0
               : "zebra "),
3985
0
            afistr,
3986
0
            rfg->plist_export_zebra_name
3987
0
              [afi]);
3988
0
        }
3989
        /*
3990
         * currently we only support redist plists for
3991
         * bgp-direct.
3992
         * If we later add plist support for
3993
         * redistributing other
3994
         * protocols, we'll need to loop over protocols
3995
         * here
3996
         */
3997
0
        if (rfg->plist_redist_name
3998
0
              [ZEBRA_ROUTE_BGP_DIRECT][afi]) {
3999
0
          vty_out(vty,
4000
0
            "  redistribute bgp-direct %s prefix-list %s\n",
4001
0
            afistr,
4002
0
            rfg->plist_redist_name
4003
0
              [ZEBRA_ROUTE_BGP_DIRECT]
4004
0
              [afi]);
4005
0
        }
4006
0
        if (rfg->plist_redist_name
4007
0
              [ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) {
4008
0
          vty_out(vty,
4009
0
            "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4010
0
            afistr,
4011
0
            rfg->plist_redist_name
4012
0
              [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4013
0
              [afi]);
4014
0
        }
4015
0
      }
4016
4017
0
      if (rfg->routemap_export_bgp_name) {
4018
0
        vty_out(vty, "  export %sroute-map %s\n",
4019
0
          (rfg->type == RFAPI_GROUP_CFG_VRF
4020
0
             ? ""
4021
0
             : "bgp "),
4022
0
          rfg->routemap_export_bgp_name);
4023
0
      }
4024
0
      if (rfg->routemap_export_zebra_name) {
4025
0
        vty_out(vty, "  export %sroute-map %s\n",
4026
0
          (rfg->type == RFAPI_GROUP_CFG_VRF
4027
0
             ? ""
4028
0
             : "zebra "),
4029
0
          rfg->routemap_export_zebra_name);
4030
0
      }
4031
0
      if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
4032
0
        vty_out(vty,
4033
0
          "  redistribute bgp-direct route-map %s\n",
4034
0
          rfg->routemap_redist_name
4035
0
            [ZEBRA_ROUTE_BGP_DIRECT]);
4036
0
      }
4037
0
      if (rfg->routemap_redist_name
4038
0
            [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
4039
0
        vty_out(vty,
4040
0
          "  redistribute bgp-direct-to-nve-groups route-map %s\n",
4041
0
          rfg->routemap_redist_name
4042
0
            [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
4043
0
      }
4044
0
      vty_out(vty, " exit-vrf-policy\n");
4045
0
      vty_out(vty, "!\n");
4046
0
    }
4047
0
  if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) {
4048
0
    vty_out(vty, " vnc advertise-un-method encap-safi\n");
4049
0
    write++;
4050
0
  }
4051
4052
0
  { /* was based on listen ports */
4053
    /* for now allow both old and new */
4054
0
    if (bgp->rfapi->rfp_methods.cfg_cb)
4055
0
      write += (bgp->rfapi->rfp_methods.cfg_cb)(
4056
0
        vty, bgp->rfapi->rfp);
4057
4058
0
    if (write)
4059
0
      vty_out(vty, "!\n");
4060
4061
0
    if (hc->l2_groups) {
4062
0
      struct rfapi_l2_group_cfg *rfgc = NULL;
4063
0
      struct listnode *gnode;
4064
0
      for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfgc)) {
4065
0
        struct listnode *lnode;
4066
0
        void *data;
4067
0
        ++write;
4068
0
        vty_out(vty, " vnc l2-group %s\n", rfgc->name);
4069
0
        if (rfgc->logical_net_id != 0)
4070
0
          vty_out(vty,
4071
0
            "   logical-network-id %u\n",
4072
0
            rfgc->logical_net_id);
4073
0
        if (rfgc->labels != NULL
4074
0
            && listhead(rfgc->labels) != NULL) {
4075
0
          vty_out(vty, "   labels ");
4076
0
          for (ALL_LIST_ELEMENTS_RO(rfgc->labels,
4077
0
                  lnode,
4078
0
                  data)) {
4079
0
            vty_out(vty, "%hu ",
4080
0
              (uint16_t)(
4081
0
                (uintptr_t)
4082
0
                  data));
4083
0
          }
4084
0
          vty_out(vty, "\n");
4085
0
        }
4086
4087
0
        if (rfgc->rt_import_list && rfgc->rt_export_list
4088
0
            && ecommunity_cmp(rfgc->rt_import_list,
4089
0
                  rfgc->rt_export_list)) {
4090
0
          char *b = ecommunity_ecom2str(
4091
0
            rfgc->rt_import_list,
4092
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
4093
0
            ECOMMUNITY_ROUTE_TARGET);
4094
0
          vty_out(vty, "   rt both %s\n", b);
4095
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
4096
0
        } else {
4097
0
          if (rfgc->rt_import_list) {
4098
0
            char *b = ecommunity_ecom2str(
4099
0
              rfgc->rt_import_list,
4100
0
              ECOMMUNITY_FORMAT_ROUTE_MAP,
4101
0
              ECOMMUNITY_ROUTE_TARGET);
4102
0
            vty_out(vty, "  rt import %s\n",
4103
0
              b);
4104
0
            XFREE(MTYPE_ECOMMUNITY_STR, b);
4105
0
          }
4106
0
          if (rfgc->rt_export_list) {
4107
0
            char *b = ecommunity_ecom2str(
4108
0
              rfgc->rt_export_list,
4109
0
              ECOMMUNITY_FORMAT_ROUTE_MAP,
4110
0
              ECOMMUNITY_ROUTE_TARGET);
4111
0
            vty_out(vty, "  rt export %s\n",
4112
0
              b);
4113
0
            XFREE(MTYPE_ECOMMUNITY_STR, b);
4114
0
          }
4115
0
        }
4116
0
        if (bgp->rfapi->rfp_methods.cfg_group_cb)
4117
0
          write += (bgp->rfapi->rfp_methods
4118
0
                .cfg_group_cb)(
4119
0
            vty, bgp->rfapi->rfp,
4120
0
            RFAPI_RFP_CFG_GROUP_L2,
4121
0
            rfgc->name, rfgc->rfp_cfg);
4122
0
        vty_out(vty, " exit-vnc\n");
4123
0
        vty_out(vty, "!\n");
4124
0
      }
4125
0
    }
4126
4127
0
    if (hc->default_rd.prefixlen
4128
0
        || hc->default_response_lifetime
4129
0
             != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
4130
0
        || hc->default_rt_import_list || hc->default_rt_export_list
4131
0
        || hc->nve_groups_sequential->count) {
4132
4133
4134
0
      ++write;
4135
0
      vty_out(vty, " vnc defaults\n");
4136
4137
0
      if (hc->default_rd.prefixlen) {
4138
0
        if (AF_UNIX == hc->default_rd.family) {
4139
0
          uint16_t value = 0;
4140
4141
0
          value = ((hc->default_rd.val[6] << 8)
4142
0
             & 0x0ff00)
4143
0
            | (hc->default_rd.val[7]
4144
0
               & 0x0ff);
4145
4146
0
          vty_out(vty, "  rd auto:vn:%d\n",
4147
0
            value);
4148
4149
0
        } else
4150
0
          vty_out(vty, "  rd %pRDP\n",
4151
0
            &hc->default_rd);
4152
0
      }
4153
0
      if (hc->default_response_lifetime
4154
0
          != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT) {
4155
0
        vty_out(vty, "  response-lifetime ");
4156
0
        if (hc->default_response_lifetime != UINT32_MAX)
4157
0
          vty_out(vty, "%d",
4158
0
            hc->default_response_lifetime);
4159
0
        else
4160
0
          vty_out(vty, "infinite");
4161
0
        vty_out(vty, "\n");
4162
0
      }
4163
0
      if (hc->default_rt_import_list
4164
0
          && hc->default_rt_export_list
4165
0
          && ecommunity_cmp(hc->default_rt_import_list,
4166
0
                hc->default_rt_export_list)) {
4167
0
        char *b = ecommunity_ecom2str(
4168
0
          hc->default_rt_import_list,
4169
0
          ECOMMUNITY_FORMAT_ROUTE_MAP,
4170
0
          ECOMMUNITY_ROUTE_TARGET);
4171
0
        vty_out(vty, "  rt both %s\n", b);
4172
0
        XFREE(MTYPE_ECOMMUNITY_STR, b);
4173
0
      } else {
4174
0
        if (hc->default_rt_import_list) {
4175
0
          char *b = ecommunity_ecom2str(
4176
0
            hc->default_rt_import_list,
4177
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
4178
0
            ECOMMUNITY_ROUTE_TARGET);
4179
0
          vty_out(vty, "  rt import %s\n", b);
4180
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
4181
0
        }
4182
0
        if (hc->default_rt_export_list) {
4183
0
          char *b = ecommunity_ecom2str(
4184
0
            hc->default_rt_export_list,
4185
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
4186
0
            ECOMMUNITY_ROUTE_TARGET);
4187
0
          vty_out(vty, "  rt export %s\n", b);
4188
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
4189
0
        }
4190
0
      }
4191
0
      if (bgp->rfapi->rfp_methods.cfg_group_cb)
4192
0
        write += (bgp->rfapi->rfp_methods.cfg_group_cb)(
4193
0
          vty, bgp->rfapi->rfp,
4194
0
          RFAPI_RFP_CFG_GROUP_DEFAULT, NULL,
4195
0
          bgp->rfapi_cfg->default_rfp_cfg);
4196
0
      vty_out(vty, " exit-vnc\n");
4197
0
      vty_out(vty, "!\n");
4198
0
    }
4199
4200
0
    for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode,
4201
0
               rfg))
4202
0
      if (rfg->type == RFAPI_GROUP_CFG_NVE) {
4203
0
        ++write;
4204
0
        vty_out(vty, " vnc nve-group %s\n", rfg->name);
4205
4206
0
        if (rfg->vn_prefix.family && rfg->vn_node)
4207
0
          vty_out(vty, "  prefix %s %pFX\n", "vn",
4208
0
            &rfg->vn_prefix);
4209
4210
0
        if (rfg->un_prefix.family && rfg->un_node)
4211
0
          vty_out(vty, "  prefix %s %pFX\n", "un",
4212
0
            &rfg->un_prefix);
4213
4214
4215
0
        if (rfg->rd.prefixlen) {
4216
0
          if (AF_UNIX == rfg->rd.family) {
4217
4218
0
            uint16_t value = 0;
4219
4220
0
            value = ((rfg->rd.val[6] << 8)
4221
0
               & 0x0ff00)
4222
0
              | (rfg->rd.val[7]
4223
0
                 & 0x0ff);
4224
4225
0
            vty_out(vty,
4226
0
              "  rd auto:vn:%d\n",
4227
0
              value);
4228
4229
0
          } else
4230
0
            vty_out(vty, "  rd %pRDP\n",
4231
0
              &rfg->rd);
4232
0
        }
4233
0
        if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
4234
0
          vty_out(vty, "  response-lifetime ");
4235
0
          if (rfg->response_lifetime
4236
0
              != UINT32_MAX)
4237
0
            vty_out(vty, "%d",
4238
0
              rfg->response_lifetime);
4239
0
          else
4240
0
            vty_out(vty, "infinite");
4241
0
          vty_out(vty, "\n");
4242
0
        }
4243
4244
0
        if (rfg->rt_import_list && rfg->rt_export_list
4245
0
            && ecommunity_cmp(rfg->rt_import_list,
4246
0
                  rfg->rt_export_list)) {
4247
0
          char *b = ecommunity_ecom2str(
4248
0
            rfg->rt_import_list,
4249
0
            ECOMMUNITY_FORMAT_ROUTE_MAP,
4250
0
            ECOMMUNITY_ROUTE_TARGET);
4251
0
          vty_out(vty, "  rt both %s\n", b);
4252
0
          XFREE(MTYPE_ECOMMUNITY_STR, b);
4253
0
        } else {
4254
0
          if (rfg->rt_import_list) {
4255
0
            char *b = ecommunity_ecom2str(
4256
0
              rfg->rt_import_list,
4257
0
              ECOMMUNITY_FORMAT_ROUTE_MAP,
4258
0
              ECOMMUNITY_ROUTE_TARGET);
4259
0
            vty_out(vty, "  rt import %s\n",
4260
0
              b);
4261
0
            XFREE(MTYPE_ECOMMUNITY_STR, b);
4262
0
          }
4263
0
          if (rfg->rt_export_list) {
4264
0
            char *b = ecommunity_ecom2str(
4265
0
              rfg->rt_export_list,
4266
0
              ECOMMUNITY_FORMAT_ROUTE_MAP,
4267
0
              ECOMMUNITY_ROUTE_TARGET);
4268
0
            vty_out(vty, "  rt export %s\n",
4269
0
              b);
4270
0
            XFREE(MTYPE_ECOMMUNITY_STR, b);
4271
0
          }
4272
0
        }
4273
4274
        /*
4275
         * route filtering: prefix-lists and route-maps
4276
         */
4277
0
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4278
4279
0
          const char *afistr = (afi == AFI_IP)
4280
0
                     ? "ipv4"
4281
0
                     : "ipv6";
4282
4283
0
          if (rfg->plist_export_bgp_name[afi]) {
4284
0
            vty_out(vty,
4285
0
              "  export bgp %s prefix-list %s\n",
4286
0
              afistr,
4287
0
              rfg->plist_export_bgp_name
4288
0
                [afi]);
4289
0
          }
4290
0
          if (rfg->plist_export_zebra_name[afi]) {
4291
0
            vty_out(vty,
4292
0
              "  export zebra %s prefix-list %s\n",
4293
0
              afistr,
4294
0
              rfg->plist_export_zebra_name
4295
0
                [afi]);
4296
0
          }
4297
          /*
4298
           * currently we only support redist
4299
           * plists for bgp-direct.
4300
           * If we later add plist support for
4301
           * redistributing other
4302
           * protocols, we'll need to loop over
4303
           * protocols here
4304
           */
4305
0
          if (rfg->plist_redist_name
4306
0
                [ZEBRA_ROUTE_BGP_DIRECT]
4307
0
                [afi]) {
4308
0
            vty_out(vty,
4309
0
              "  redistribute bgp-direct %s prefix-list %s\n",
4310
0
              afistr,
4311
0
              rfg->plist_redist_name
4312
0
                [ZEBRA_ROUTE_BGP_DIRECT]
4313
0
                [afi]);
4314
0
          }
4315
0
          if (rfg->plist_redist_name
4316
0
                [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4317
0
                [afi]) {
4318
0
            vty_out(vty,
4319
0
              "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4320
0
              afistr,
4321
0
              rfg->plist_redist_name
4322
0
                [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4323
0
                [afi]);
4324
0
          }
4325
0
        }
4326
4327
0
        if (rfg->routemap_export_bgp_name) {
4328
0
          vty_out(vty,
4329
0
            "  export bgp route-map %s\n",
4330
0
            rfg->routemap_export_bgp_name);
4331
0
        }
4332
0
        if (rfg->routemap_export_zebra_name) {
4333
0
          vty_out(vty,
4334
0
            "  export zebra route-map %s\n",
4335
0
            rfg->routemap_export_zebra_name);
4336
0
        }
4337
0
        if (rfg->routemap_redist_name
4338
0
              [ZEBRA_ROUTE_BGP_DIRECT]) {
4339
0
          vty_out(vty,
4340
0
            "  redistribute bgp-direct route-map %s\n",
4341
0
            rfg->routemap_redist_name
4342
0
              [ZEBRA_ROUTE_BGP_DIRECT]);
4343
0
        }
4344
0
        if (rfg->routemap_redist_name
4345
0
              [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
4346
0
          vty_out(vty,
4347
0
            "  redistribute bgp-direct-to-nve-groups route-map %s\n",
4348
0
            rfg->routemap_redist_name
4349
0
              [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
4350
0
        }
4351
0
        if (bgp->rfapi->rfp_methods.cfg_group_cb)
4352
0
          write += (bgp->rfapi->rfp_methods
4353
0
                .cfg_group_cb)(
4354
0
            vty, bgp->rfapi->rfp,
4355
0
            RFAPI_RFP_CFG_GROUP_NVE,
4356
0
            rfg->name, rfg->rfp_cfg);
4357
0
        vty_out(vty, " exit-vnc\n");
4358
0
        vty_out(vty, "!\n");
4359
0
      }
4360
0
  } /* have listen ports */
4361
4362
  /*
4363
   * route export to other protocols
4364
   */
4365
0
  if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
4366
0
    vty_out(vty, " vnc export bgp mode group-nve\n");
4367
0
  } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
4368
0
    vty_out(vty, " vnc export bgp mode registering-nve\n");
4369
0
  } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
4370
0
    vty_out(vty, " vnc export bgp mode ce\n");
4371
0
  }
4372
4373
0
  if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
4374
0
    vty_out(vty, " vnc export zebra mode group-nve\n");
4375
0
  } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
4376
0
    vty_out(vty, " vnc export zebra mode registering-nve\n");
4377
0
  }
4378
4379
0
  if (hc->rfg_export_direct_bgp_l) {
4380
0
    for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, node, nnode,
4381
0
               rfgn)) {
4382
4383
0
      vty_out(vty, " vnc export bgp group-nve group %s\n",
4384
0
        rfgn->name);
4385
0
    }
4386
0
  }
4387
4388
0
  if (hc->rfg_export_zebra_l) {
4389
0
    for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, nnode,
4390
0
               rfgn)) {
4391
4392
0
      vty_out(vty, " vnc export zebra group-nve group %s\n",
4393
0
        rfgn->name);
4394
0
    }
4395
0
  }
4396
4397
4398
0
  if (hc->rfg_redist_name) {
4399
0
    vty_out(vty, " vnc redistribute nve-group %s\n",
4400
0
      hc->rfg_redist_name);
4401
0
  }
4402
0
  if (hc->redist_lifetime) {
4403
0
    vty_out(vty, " vnc redistribute lifetime %d\n",
4404
0
      hc->redist_lifetime);
4405
0
  }
4406
0
  if (hc->resolve_nve_roo_local_admin
4407
0
      != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) {
4408
4409
0
    vty_out(vty,
4410
0
      " vnc redistribute resolve-nve roo-ec-local-admin %d\n",
4411
0
      hc->resolve_nve_roo_local_admin);
4412
0
  }
4413
4414
0
  if (hc->redist_mode) /* ! default */
4415
0
  {
4416
0
    const char *s = "";
4417
4418
0
    switch (hc->redist_mode) {
4419
0
    case VNC_REDIST_MODE_PLAIN:
4420
0
      s = "plain";
4421
0
      break;
4422
0
    case VNC_REDIST_MODE_RFG:
4423
0
      s = "nve-group";
4424
0
      break;
4425
0
    case VNC_REDIST_MODE_RESOLVE_NVE:
4426
0
      s = "resolve-nve";
4427
0
      break;
4428
0
    }
4429
0
    if (s) {
4430
0
      vty_out(vty, " vnc redistribute mode %s\n", s);
4431
0
    }
4432
0
  }
4433
4434
  /*
4435
   * route filtering: prefix-lists and route-maps
4436
   */
4437
0
  for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4438
4439
0
    const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6";
4440
4441
0
    if (hc->plist_export_bgp_name[afi]) {
4442
0
      vty_out(vty, " vnc export bgp %s prefix-list %s\n",
4443
0
        afistr, hc->plist_export_bgp_name[afi]);
4444
0
    }
4445
0
    if (hc->plist_export_zebra_name[afi]) {
4446
0
      vty_out(vty, " vnc export zebra %s prefix-list %s\n",
4447
0
        afistr, hc->plist_export_zebra_name[afi]);
4448
0
    }
4449
0
    if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) {
4450
0
      vty_out(vty,
4451
0
        " vnc redistribute bgp-direct %s prefix-list %s\n",
4452
0
        afistr,
4453
0
        hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT]
4454
0
                 [afi]);
4455
0
    }
4456
0
  }
4457
4458
0
  if (hc->routemap_export_bgp_name) {
4459
0
    vty_out(vty, " vnc export bgp route-map %s\n",
4460
0
      hc->routemap_export_bgp_name);
4461
0
  }
4462
0
  if (hc->routemap_export_zebra_name) {
4463
0
    vty_out(vty, " vnc export zebra route-map %s\n",
4464
0
      hc->routemap_export_zebra_name);
4465
0
  }
4466
0
  if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
4467
0
    vty_out(vty, " vnc redistribute bgp-direct route-map %s\n",
4468
0
      hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
4469
0
  }
4470
4471
0
  for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4472
0
    for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
4473
0
      if (hc->redist[afi][type]) {
4474
0
        if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT
4475
0
            && hc->redist_bgp_exterior_view_name) {
4476
0
          vty_out(vty,
4477
0
            " vnc redistribute %s %s view %s\n",
4478
0
            ((afi == AFI_IP) ? "ipv4"
4479
0
                 : "ipv6"),
4480
0
            zebra_route_string(type),
4481
0
            hc->redist_bgp_exterior_view_name);
4482
0
        } else {
4483
0
          vty_out(vty,
4484
0
            " vnc redistribute %s %s\n",
4485
0
            ((afi == AFI_IP) ? "ipv4"
4486
0
                 : "ipv6"),
4487
0
            zebra_route_string(type));
4488
0
        }
4489
0
      }
4490
0
    }
4491
0
  }
4492
0
  return write;
4493
0
}
4494
4495
void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
4496
0
{
4497
0
  struct rfapi_cfg *hc = bgp->rfapi_cfg;
4498
0
  afi_t afi;
4499
0
  int type, redist = 0;
4500
0
  char tmp[40];
4501
0
  if (hc == NULL)
4502
0
    return;
4503
4504
0
  vty_out(vty, "%-39s %-19s %s\n", "VNC Advertise method:",
4505
0
    (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4506
0
       ? "Encapsulation SAFI"
4507
0
       : "Tunnel Encap attribute"),
4508
0
    ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)
4509
0
         == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4510
0
             & BGP_VNC_CONFIG_FLAGS_DEFAULT)
4511
0
       ? "(default)"
4512
0
       : ""));
4513
  /* export */
4514
0
  vty_out(vty, "%-39s ", "Export from VNC:");
4515
  /*
4516
   * route export to other protocols
4517
   */
4518
0
  if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
4519
0
    redist++;
4520
0
    vty_out(vty, "ToBGP Groups={");
4521
0
    if (hc->rfg_export_direct_bgp_l) {
4522
0
      int cnt = 0;
4523
0
      struct listnode *node, *nnode;
4524
0
      struct rfapi_rfg_name *rfgn;
4525
0
      for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l,
4526
0
                 node, nnode, rfgn)) {
4527
0
        if (cnt++ != 0)
4528
0
          vty_out(vty, ",");
4529
4530
0
        vty_out(vty, "%s", rfgn->name);
4531
0
      }
4532
0
    }
4533
0
    vty_out(vty, "}");
4534
0
  } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
4535
0
    redist++;
4536
0
    vty_out(vty, "ToBGP {Registering NVE}");
4537
    /* note filters, route-maps not shown */
4538
0
  } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
4539
0
    redist++;
4540
0
    vty_out(vty, "ToBGP {NVE connected router:%d}",
4541
0
      hc->resolve_nve_roo_local_admin);
4542
    /* note filters, route-maps not shown */
4543
0
  }
4544
4545
0
  if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
4546
0
    redist++;
4547
0
    vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " "));
4548
0
    if (hc->rfg_export_zebra_l) {
4549
0
      int cnt = 0;
4550
0
      struct listnode *node, *nnode;
4551
0
      struct rfapi_rfg_name *rfgn;
4552
0
      for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node,
4553
0
                 nnode, rfgn)) {
4554
0
        if (cnt++ != 0)
4555
0
          vty_out(vty, ",");
4556
0
        vty_out(vty, "%s", rfgn->name);
4557
0
      }
4558
0
    }
4559
0
    vty_out(vty, "}");
4560
0
  } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
4561
0
    redist++;
4562
0
    vty_out(vty, "%sToZebra {Registering NVE}",
4563
0
      (redist == 1 ? "" : " "));
4564
    /* note filters, route-maps not shown */
4565
0
  }
4566
0
  vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
4567
0
    (redist ? "" : "(default)"));
4568
4569
  /* Redistribution */
4570
0
  redist = 0;
4571
0
  vty_out(vty, "%-39s ", "Redistribution into VNC:");
4572
0
  for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4573
0
    for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
4574
0
      if (hc->redist[afi][type]) {
4575
0
        vty_out(vty, "{%s,%s} ",
4576
0
          ((afi == AFI_IP) ? "ipv4" : "ipv6"),
4577
0
          zebra_route_string(type));
4578
0
        redist++;
4579
0
      }
4580
0
    }
4581
0
  }
4582
0
  vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
4583
0
    (redist ? "" : "(default)"));
4584
4585
0
  vty_out(vty, "%-39s %3u%-16s %s\n",
4586
0
    "RFP Registration Hold-Down Factor:",
4587
0
    hc->rfp_cfg.holddown_factor, "%",
4588
0
    (hc->rfp_cfg.holddown_factor
4589
0
         == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
4590
0
       ? "(default)"
4591
0
       : ""));
4592
0
  vty_out(vty, "%-39s %-19s %s\n", "RFP Updated responses:",
4593
0
    (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"),
4594
0
    (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : ""));
4595
0
  vty_out(vty, "%-39s %-19s %s\n", "RFP Removal responses:",
4596
0
    (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"),
4597
0
    (hc->rfp_cfg.use_removes == 0 ? "(default)" : ""));
4598
0
  vty_out(vty, "%-39s %-19s %s\n", "RFP Full table download:",
4599
0
    (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL ? "On"
4600
0
                      : "Off"),
4601
0
    (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL
4602
0
       ? "(default)"
4603
0
       : ""));
4604
0
  snprintf(tmp, sizeof(tmp), "%u seconds",
4605
0
     hc->rfp_cfg.ftd_advertisement_interval);
4606
0
  vty_out(vty, "%-39s %-19s %s\n", "    Advertisement Interval:", tmp,
4607
0
    (hc->rfp_cfg.ftd_advertisement_interval
4608
0
         == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
4609
0
       ? "(default)"
4610
0
       : ""));
4611
0
  vty_out(vty, "%-39s %d seconds\n", "Default RFP response lifetime:",
4612
0
    hc->default_response_lifetime);
4613
0
  vty_out(vty, "\n");
4614
0
  return;
4615
0
}
4616
4617
struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp)
4618
0
{
4619
0
  struct rfapi_cfg *hc = NULL;
4620
0
  if (bgp == NULL)
4621
0
    bgp = bgp_get_default();
4622
0
  if (bgp != NULL)
4623
0
    hc = bgp->rfapi_cfg;
4624
0
  return hc;
4625
0
}
4626
4627
#endif /* ENABLE_BGP_VNC */