Coverage Report

Created: 2026-03-21 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/bgpd/bgp_mplsvpn.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* MPLS-VPN
3
 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4
 */
5
6
#include <zebra.h>
7
8
#include "command.h"
9
#include "prefix.h"
10
#include "log.h"
11
#include "memory.h"
12
#include "stream.h"
13
#include "queue.h"
14
#include "filter.h"
15
#include "mpls.h"
16
#include "json.h"
17
#include "zclient.h"
18
19
#include "bgpd/bgpd.h"
20
#include "bgpd/bgp_debug.h"
21
#include "bgpd/bgp_errors.h"
22
#include "bgpd/bgp_table.h"
23
#include "bgpd/bgp_route.h"
24
#include "bgpd/bgp_attr.h"
25
#include "bgpd/bgp_label.h"
26
#include "bgpd/bgp_mplsvpn.h"
27
#include "bgpd/bgp_packet.h"
28
#include "bgpd/bgp_vty.h"
29
#include "bgpd/bgp_vpn.h"
30
#include "bgpd/bgp_community.h"
31
#include "bgpd/bgp_ecommunity.h"
32
#include "bgpd/bgp_zebra.h"
33
#include "bgpd/bgp_nexthop.h"
34
#include "bgpd/bgp_nht.h"
35
#include "bgpd/bgp_evpn.h"
36
#include "bgpd/bgp_memory.h"
37
38
#ifdef ENABLE_BGP_VNC
39
#include "bgpd/rfapi/rfapi_backend.h"
40
#endif
41
42
/*
43
 * Definitions and external declarations.
44
 */
45
extern struct zclient *zclient;
46
47
extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
48
             int *index, afi_t *afi)
49
0
{
50
0
  int ret = 0;
51
0
  if (argv_find(argv, argc, "vpnv4", index)) {
52
0
    ret = 1;
53
0
    if (afi)
54
0
      *afi = AFI_IP;
55
0
  } else if (argv_find(argv, argc, "vpnv6", index)) {
56
0
    ret = 1;
57
0
    if (afi)
58
0
      *afi = AFI_IP6;
59
0
  }
60
0
  return ret;
61
0
}
62
63
uint32_t decode_label(mpls_label_t *label_pnt)
64
0
{
65
0
  uint32_t l;
66
0
  uint8_t *pnt = (uint8_t *)label_pnt;
67
68
0
  l = ((uint32_t)*pnt++ << 12);
69
0
  l |= (uint32_t)*pnt++ << 4;
70
0
  l |= (uint32_t)((*pnt & 0xf0) >> 4);
71
0
  return l;
72
0
}
73
74
void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
75
0
{
76
0
  uint8_t *pnt = (uint8_t *)label_pnt;
77
0
  if (pnt == NULL)
78
0
    return;
79
0
  if (label == BGP_PREVENT_VRF_2_VRF_LEAK) {
80
0
    *label_pnt = label;
81
0
    return;
82
0
  }
83
0
  *pnt++ = (label >> 12) & 0xff;
84
0
  *pnt++ = (label >> 4) & 0xff;
85
0
  *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
86
0
}
87
88
int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
89
           struct bgp_nlri *packet)
90
13
{
91
13
  struct prefix p;
92
13
  uint8_t psize = 0;
93
13
  uint8_t prefixlen;
94
13
  uint16_t type;
95
13
  struct rd_as rd_as;
96
13
  struct rd_ip rd_ip;
97
13
  struct prefix_rd prd = {0};
98
13
  mpls_label_t label = {0};
99
13
  afi_t afi;
100
13
  safi_t safi;
101
13
  bool addpath_capable;
102
13
  uint32_t addpath_id;
103
13
  int ret = 0;
104
105
  /* Make prefix_rd */
106
13
  prd.family = AF_UNSPEC;
107
13
  prd.prefixlen = 64;
108
109
13
  struct stream *data = stream_new(packet->length);
110
13
  stream_put(data, packet->nlri, packet->length);
111
13
  afi = packet->afi;
112
13
  safi = packet->safi;
113
13
  addpath_id = 0;
114
115
13
  addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
116
117
803
#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
118
209
  while (STREAM_READABLE(data) > 0) {
119
    /* Clear prefix structure. */
120
209
    memset(&p, 0, sizeof(p));
121
122
209
    if (addpath_capable) {
123
209
      STREAM_GET(&addpath_id, data, BGP_ADDPATH_ID_LEN);
124
208
      addpath_id = ntohl(addpath_id);
125
208
    }
126
127
208
    if (STREAM_READABLE(data) < 1) {
128
1
      flog_err(
129
1
        EC_BGP_UPDATE_RCV,
130
1
        "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
131
1
        peer->host, packet->length);
132
1
      ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
133
1
      goto done;
134
1
    }
135
136
    /* Fetch prefix length. */
137
207
    STREAM_GETC(data, prefixlen);
138
207
    p.family = afi2family(packet->afi);
139
207
    psize = PSIZE(prefixlen);
140
141
207
    if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
142
6
      flog_err(
143
6
        EC_BGP_UPDATE_RCV,
144
6
        "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
145
6
        peer->host, prefixlen);
146
6
      ret = BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
147
6
      goto done;
148
6
    }
149
150
    /* sanity check against packet data */
151
201
    if (STREAM_READABLE(data) < psize) {
152
1
      flog_err(
153
1
        EC_BGP_UPDATE_RCV,
154
1
        "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
155
1
        peer->host, prefixlen, packet->length);
156
1
      ret = BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
157
1
      goto done;
158
1
    }
159
160
    /* sanity check against storage for the IP address portion */
161
200
    if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
162
0
      flog_err(
163
0
        EC_BGP_UPDATE_RCV,
164
0
        "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
165
0
        peer->host,
166
0
        prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
167
0
        sizeof(p.u));
168
0
      ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
169
0
      goto done;
170
0
    }
171
172
    /* Sanity check against max bitlen of the address family */
173
200
    if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
174
4
      flog_err(
175
4
        EC_BGP_UPDATE_RCV,
176
4
        "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
177
4
        peer->host,
178
4
        prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
179
4
        p.family, prefix_blen(&p));
180
4
      ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
181
4
      goto done;
182
4
    }
183
184
    /* Copy label to prefix. */
185
196
    if (STREAM_READABLE(data) < BGP_LABEL_BYTES) {
186
0
      flog_err(
187
0
        EC_BGP_UPDATE_RCV,
188
0
        "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
189
0
        peer->host, packet->length);
190
0
      ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
191
0
      goto done;
192
0
    }
193
194
196
    STREAM_GET(&label, data, BGP_LABEL_BYTES);
195
196
    bgp_set_valid_label(&label);
196
197
    /* Copy routing distinguisher to rd. */
198
196
    if (STREAM_READABLE(data) < 8) {
199
0
      flog_err(
200
0
        EC_BGP_UPDATE_RCV,
201
0
        "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
202
0
        peer->host, packet->length);
203
0
      ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
204
0
      goto done;
205
0
    }
206
196
    STREAM_GET(&prd.val, data, 8);
207
208
    /* Decode RD type. */
209
196
    type = decode_rd_type(prd.val);
210
211
196
    switch (type) {
212
22
    case RD_TYPE_AS:
213
22
      decode_rd_as(&prd.val[2], &rd_as);
214
22
      break;
215
216
34
    case RD_TYPE_AS4:
217
34
      decode_rd_as4(&prd.val[2], &rd_as);
218
34
      break;
219
220
2
    case RD_TYPE_IP:
221
2
      decode_rd_ip(&prd.val[2], &rd_ip);
222
2
      break;
223
224
0
#ifdef ENABLE_BGP_VNC
225
25
    case RD_TYPE_VNC_ETH:
226
25
      break;
227
0
#endif
228
229
113
    default:
230
113
      flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
231
113
      break; /* just report */
232
196
    }
233
234
    /* exclude label & RD */
235
196
    p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8;
236
196
    STREAM_GET(p.u.val, data, psize - VPN_PREFIXLEN_MIN_BYTES);
237
238
196
    if (attr) {
239
0
      bgp_update(peer, &p, addpath_id, attr, packet->afi,
240
0
           SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
241
0
           BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
242
196
    } else {
243
196
      bgp_withdraw(peer, &p, addpath_id, packet->afi,
244
196
             SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
245
196
             BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
246
196
    }
247
196
  }
248
  /* Packet length consistency check. */
249
0
  if (STREAM_READABLE(data) != 0) {
250
0
    flog_err(
251
0
      EC_BGP_UPDATE_RCV,
252
0
      "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
253
0
      peer->host, STREAM_READABLE(data));
254
0
    return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
255
0
  }
256
257
0
  goto done;
258
259
1
stream_failure:
260
1
  flog_err(
261
1
    EC_BGP_UPDATE_RCV,
262
1
    "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
263
1
    peer->host, packet->length);
264
1
  ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
265
266
13
done:
267
13
  stream_free(data);
268
13
  return ret;
269
270
1
#undef VPN_PREFIXLEN_MIN_BYTES
271
1
}
272
273
/*
274
 * This function informs zebra of the label this vrf sets on routes
275
 * leaked to VPN. Zebra should install this label in the kernel with
276
 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
277
 *
278
 * Sending this vrf-label association is qualified by a) whether vrf->vpn
279
 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
280
 * are set) and b) whether vpn-policy label is set.
281
 *
282
 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
283
 * for this vrf, which zebra interprets to mean "delete this vrf-label
284
 * association."
285
 */
286
void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
287
0
{
288
0
  mpls_label_t label = MPLS_LABEL_NONE;
289
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
290
291
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
292
0
    if (debug) {
293
0
      zlog_debug(
294
0
        "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
295
0
        __func__, bgp->name_pretty, afi2str(afi));
296
0
    }
297
0
    return;
298
0
  }
299
300
0
  if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
301
0
    label = bgp->vpn_policy[afi].tovpn_label;
302
0
  }
303
304
0
  if (debug) {
305
0
    zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
306
0
         __func__, bgp->name_pretty, afi2str(afi), label,
307
0
         bgp->vrf_id);
308
0
  }
309
310
0
  if (label == BGP_PREVENT_VRF_2_VRF_LEAK)
311
0
    label = MPLS_LABEL_NONE;
312
0
  zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
313
0
  bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
314
0
}
315
316
/*
317
 * If zebra tells us vrf has become unconfigured, tell zebra not to
318
 * use this label to forward to the vrf anymore
319
 */
320
void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
321
0
{
322
0
  mpls_label_t label = MPLS_LABEL_NONE;
323
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
324
325
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
326
0
    if (debug) {
327
0
      zlog_debug(
328
0
        "%s: vrf_id not set, can't delete zebra vrf label",
329
0
        __func__);
330
0
    }
331
0
    return;
332
0
  }
333
334
0
  if (debug) {
335
0
    zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
336
0
         bgp->name_pretty, bgp->vrf_id);
337
0
  }
338
339
0
  zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
340
0
  bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
341
0
}
342
343
/*
344
 * This function informs zebra of the srv6-function this vrf sets on routes
345
 * leaked to VPN. Zebra should install this srv6-function in the kernel with
346
 * an action of "End.DT4/6's IP FIB to route the PDU."
347
 */
348
void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi)
349
0
{
350
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
351
0
  enum seg6local_action_t act;
352
0
  struct seg6local_context ctx = {};
353
0
  struct in6_addr *tovpn_sid = NULL;
354
0
  struct in6_addr *tovpn_sid_ls = NULL;
355
0
  struct vrf *vrf;
356
357
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
358
0
    if (debug)
359
0
      zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
360
0
           __func__, bgp->name_pretty, afi2str(afi));
361
0
    return;
362
0
  }
363
364
0
  tovpn_sid = bgp->vpn_policy[afi].tovpn_sid;
365
0
  if (!tovpn_sid) {
366
0
    if (debug)
367
0
      zlog_debug("%s: vrf %s: afi %s: sid not set", __func__,
368
0
           bgp->name_pretty, afi2str(afi));
369
0
    return;
370
0
  }
371
372
0
  if (debug)
373
0
    zlog_debug("%s: vrf %s: afi %s: setting sid %pI6 for vrf id %d",
374
0
         __func__, bgp->name_pretty, afi2str(afi), tovpn_sid,
375
0
         bgp->vrf_id);
376
377
0
  vrf = vrf_lookup_by_id(bgp->vrf_id);
378
0
  if (!vrf)
379
0
    return;
380
381
0
  ctx.table = vrf->data.l.table_id;
382
0
  act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
383
0
    : ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
384
0
  zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
385
386
0
  tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
387
0
  *tovpn_sid_ls = *tovpn_sid;
388
0
  bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent = tovpn_sid_ls;
389
0
}
390
391
/*
392
 * This function informs zebra of the srv6-function this vrf sets on routes
393
 * leaked to VPN. Zebra should install this srv6-function in the kernel with
394
 * an action of "End.DT46's IP FIB to route the PDU."
395
 */
396
void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp)
397
0
{
398
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
399
0
  enum seg6local_action_t act;
400
0
  struct seg6local_context ctx = {};
401
0
  struct in6_addr *tovpn_sid = NULL;
402
0
  struct in6_addr *tovpn_sid_ls = NULL;
403
0
  struct vrf *vrf;
404
405
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
406
0
    if (debug)
407
0
      zlog_debug(
408
0
        "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
409
0
        __func__, bgp->name_pretty);
410
0
    return;
411
0
  }
412
413
0
  tovpn_sid = bgp->tovpn_sid;
414
0
  if (!tovpn_sid) {
415
0
    if (debug)
416
0
      zlog_debug("%s: vrf %s: sid not set", __func__,
417
0
           bgp->name_pretty);
418
0
    return;
419
0
  }
420
421
0
  if (debug)
422
0
    zlog_debug("%s: vrf %s: setting sid %pI6 for vrf id %d",
423
0
         __func__, bgp->name_pretty, tovpn_sid, bgp->vrf_id);
424
425
0
  vrf = vrf_lookup_by_id(bgp->vrf_id);
426
0
  if (!vrf)
427
0
    return;
428
429
0
  ctx.table = vrf->data.l.table_id;
430
0
  act = ZEBRA_SEG6_LOCAL_ACTION_END_DT46;
431
0
  zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
432
433
0
  tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
434
0
  *tovpn_sid_ls = *tovpn_sid;
435
0
  bgp->tovpn_zebra_vrf_sid_last_sent = tovpn_sid_ls;
436
0
}
437
438
/*
439
 * This function informs zebra of the srv6-function this vrf sets on routes
440
 * leaked to VPN. Zebra should install this srv6-function in the kernel with
441
 * an action of "End.DT4/6/46's IP FIB to route the PDU."
442
 */
443
void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi)
444
0
{
445
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
446
447
0
  if (bgp->vpn_policy[afi].tovpn_sid)
448
0
    return vpn_leak_zebra_vrf_sid_update_per_af(bgp, afi);
449
450
0
  if (bgp->tovpn_sid)
451
0
    return vpn_leak_zebra_vrf_sid_update_per_vrf(bgp);
452
453
0
  if (debug)
454
0
    zlog_debug("%s: vrf %s: afi %s: sid not set", __func__,
455
0
         bgp->name_pretty, afi2str(afi));
456
0
}
457
458
/*
459
 * If zebra tells us vrf has become unconfigured, tell zebra not to
460
 * use this srv6-function to forward to the vrf anymore
461
 */
462
void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi)
463
0
{
464
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
465
466
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
467
0
    if (debug)
468
0
      zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
469
0
           __func__, bgp->name_pretty, afi2str(afi));
470
0
    return;
471
0
  }
472
473
0
  if (debug)
474
0
    zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__,
475
0
         bgp->name_pretty, bgp->vrf_id);
476
477
0
  zclient_send_localsid(zclient,
478
0
    bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent,
479
0
    bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, NULL);
480
0
  XFREE(MTYPE_BGP_SRV6_SID,
481
0
        bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent);
482
0
}
483
484
/*
485
 * If zebra tells us vrf has become unconfigured, tell zebra not to
486
 * use this srv6-function to forward to the vrf anymore
487
 */
488
void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp)
489
0
{
490
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
491
492
0
  if (bgp->vrf_id == VRF_UNKNOWN) {
493
0
    if (debug)
494
0
      zlog_debug(
495
0
        "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
496
0
        __func__, bgp->name_pretty);
497
0
    return;
498
0
  }
499
500
0
  if (debug)
501
0
    zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__,
502
0
         bgp->name_pretty, bgp->vrf_id);
503
504
0
  zclient_send_localsid(zclient, bgp->tovpn_zebra_vrf_sid_last_sent,
505
0
            bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC,
506
0
            NULL);
507
0
  XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent);
508
0
}
509
510
/*
511
 * If zebra tells us vrf has become unconfigured, tell zebra not to
512
 * use this srv6-function to forward to the vrf anymore
513
 */
514
void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi)
515
0
{
516
0
  if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent)
517
0
    vpn_leak_zebra_vrf_sid_withdraw_per_af(bgp, afi);
518
519
0
  if (bgp->tovpn_zebra_vrf_sid_last_sent)
520
0
    vpn_leak_zebra_vrf_sid_withdraw_per_vrf(bgp);
521
0
}
522
523
int vpn_leak_label_callback(
524
  mpls_label_t label,
525
  void *labelid,
526
  bool allocated)
527
0
{
528
0
  struct vpn_policy *vp = (struct vpn_policy *)labelid;
529
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
530
531
0
  if (debug)
532
0
    zlog_debug("%s: label=%u, allocated=%d",
533
0
      __func__, label, allocated);
534
535
0
  if (!allocated) {
536
    /*
537
     * previously-allocated label is now invalid
538
     */
539
0
    if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
540
0
      (vp->tovpn_label != MPLS_LABEL_NONE)) {
541
542
0
      vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
543
0
        vp->afi, bgp_get_default(), vp->bgp);
544
0
      vp->tovpn_label = MPLS_LABEL_NONE;
545
0
      vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
546
0
        vp->afi, bgp_get_default(), vp->bgp);
547
0
    }
548
0
    return 0;
549
0
  }
550
551
  /*
552
   * New label allocation
553
   */
554
0
  if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
555
556
    /*
557
     * not currently configured for auto label, reject allocation
558
     */
559
0
    return -1;
560
0
  }
561
562
0
  if (vp->tovpn_label != MPLS_LABEL_NONE) {
563
0
    if (label == vp->tovpn_label) {
564
      /* already have same label, accept but do nothing */
565
0
      return 0;
566
0
    }
567
    /* Shouldn't happen: different label allocation */
568
0
    flog_err(EC_BGP_LABEL,
569
0
       "%s: %s had label %u but got new assignment %u",
570
0
       __func__, vp->bgp->name_pretty, vp->tovpn_label,
571
0
       label);
572
    /* use new one */
573
0
  }
574
575
0
  vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
576
0
    vp->afi, bgp_get_default(), vp->bgp);
577
0
  vp->tovpn_label = label;
578
0
  vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
579
0
    vp->afi, bgp_get_default(), vp->bgp);
580
581
0
  return 0;
582
0
}
583
584
static void sid_register(struct bgp *bgp, const struct in6_addr *sid,
585
       const char *locator_name)
586
0
{
587
0
  struct bgp_srv6_function *func;
588
0
  func = XCALLOC(MTYPE_BGP_SRV6_FUNCTION,
589
0
           sizeof(struct bgp_srv6_function));
590
0
  func->sid = *sid;
591
0
  snprintf(func->locator_name, sizeof(func->locator_name),
592
0
     "%s", locator_name);
593
0
  listnode_add(bgp->srv6_functions, func);
594
0
}
595
596
void sid_unregister(struct bgp *bgp, const struct in6_addr *sid)
597
0
{
598
0
  struct listnode *node, *nnode;
599
0
  struct bgp_srv6_function *func;
600
601
0
  for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func))
602
0
    if (sid_same(&func->sid, sid)) {
603
0
      listnode_delete(bgp->srv6_functions, func);
604
0
      XFREE(MTYPE_BGP_SRV6_FUNCTION, func);
605
0
    }
606
0
}
607
608
static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
609
0
{
610
0
  struct listnode *node;
611
0
  struct bgp_srv6_function *func;
612
613
0
  for (ALL_LIST_ELEMENTS_RO(bgp->srv6_functions, node, func))
614
0
    if (sid_same(&func->sid, sid))
615
0
      return true;
616
0
  return false;
617
0
}
618
619
/*
620
 * This function generates a new SID based on bgp->srv6_locator_chunks and
621
 * index. The locator and generated SID are stored in arguments sid_locator
622
 * and sid, respectively.
623
 *
624
 * if index != 0: try to allocate as index-mode
625
 * else: try to allocate as auto-mode
626
 */
627
static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
628
            struct srv6_locator_chunk *sid_locator_chunk,
629
            struct in6_addr *sid)
630
0
{
631
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
632
0
  struct listnode *node;
633
0
  struct srv6_locator_chunk *chunk;
634
0
  bool alloced = false;
635
0
  int label = 0;
636
0
  uint8_t offset = 0;
637
0
  uint8_t func_len = 0, shift_len = 0;
638
0
  uint32_t index_max = 0;
639
640
0
  if (!bgp || !sid_locator_chunk || !sid)
641
0
    return false;
642
643
0
  for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
644
0
    if (chunk->function_bits_length >
645
0
        BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH) {
646
0
      if (debug)
647
0
        zlog_debug(
648
0
          "%s: invalid SRv6 Locator chunk (%pFX): Function Length must be less or equal to %d",
649
0
          __func__, &chunk->prefix,
650
0
          BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH);
651
0
      continue;
652
0
    }
653
654
0
    index_max = (1 << chunk->function_bits_length) - 1;
655
656
0
    if (index > index_max) {
657
0
      if (debug)
658
0
        zlog_debug(
659
0
          "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
660
0
          __func__, &chunk->prefix, index);
661
0
      continue;
662
0
    }
663
664
0
    *sid = chunk->prefix.prefix;
665
0
    *sid_locator_chunk = *chunk;
666
0
    offset = chunk->block_bits_length + chunk->node_bits_length;
667
0
    func_len = chunk->function_bits_length;
668
0
    shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH - func_len;
669
670
0
    if (index != 0) {
671
0
      label = index << shift_len;
672
0
      if (label < MPLS_LABEL_UNRESERVED_MIN) {
673
0
        if (debug)
674
0
          zlog_debug(
675
0
            "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
676
0
            __func__, &chunk->prefix,
677
0
            label);
678
0
        continue;
679
0
      }
680
681
0
      transpose_sid(sid, label, offset, func_len);
682
0
      if (sid_exist(bgp, sid))
683
0
        continue;
684
0
      alloced = true;
685
0
      break;
686
0
    }
687
688
0
    for (uint32_t i = 1; i < index_max; i++) {
689
0
      label = i << shift_len;
690
0
      if (label < MPLS_LABEL_UNRESERVED_MIN) {
691
0
        if (debug)
692
0
          zlog_debug(
693
0
            "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
694
0
            __func__, &chunk->prefix,
695
0
            label);
696
0
        continue;
697
0
      }
698
0
      transpose_sid(sid, label, offset, func_len);
699
0
      if (sid_exist(bgp, sid))
700
0
        continue;
701
0
      alloced = true;
702
0
      break;
703
0
    }
704
0
  }
705
706
0
  if (!alloced)
707
0
    return 0;
708
709
0
  sid_register(bgp, sid, bgp->srv6_locator_name);
710
0
  return label;
711
0
}
712
713
void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
714
         afi_t afi)
715
0
{
716
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
717
0
  struct srv6_locator_chunk *tovpn_sid_locator;
718
0
  struct in6_addr *tovpn_sid;
719
0
  uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
720
0
  bool tovpn_sid_auto = false;
721
722
0
  if (debug)
723
0
    zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
724
0
         __func__, bgp_vrf->name_pretty, afi2str(afi));
725
726
  /* skip when tovpn sid is already allocated on vrf instance */
727
0
  if (bgp_vrf->vpn_policy[afi].tovpn_sid)
728
0
    return;
729
730
  /*
731
   * skip when bgp vpn instance ins't allocated
732
   * or srv6 locator chunk isn't allocated
733
   */
734
0
  if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
735
0
    return;
736
737
0
  tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
738
0
  tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
739
0
            BGP_VPN_POLICY_TOVPN_SID_AUTO);
740
741
  /* skip when VPN isn't configured on vrf-instance */
742
0
  if (tovpn_sid_index == 0 && !tovpn_sid_auto)
743
0
    return;
744
745
  /* check invalid case both configured index and auto */
746
0
  if (tovpn_sid_index != 0 && tovpn_sid_auto) {
747
0
    zlog_err("%s: index-mode and auto-mode both selected. ignored.",
748
0
       __func__);
749
0
    return;
750
0
  }
751
752
0
  tovpn_sid_locator = srv6_locator_chunk_alloc();
753
0
  tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
754
755
0
  tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
756
0
              tovpn_sid_locator, tovpn_sid);
757
758
0
  if (tovpn_sid_transpose_label == 0) {
759
0
    if (debug)
760
0
      zlog_debug(
761
0
        "%s: not allocated new sid for vrf %s: afi %s",
762
0
        __func__, bgp_vrf->name_pretty, afi2str(afi));
763
0
    srv6_locator_chunk_free(&tovpn_sid_locator);
764
0
    XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
765
0
    return;
766
0
  }
767
768
0
  if (debug)
769
0
    zlog_debug("%s: new sid %pI6 allocated for vrf %s: afi %s",
770
0
         __func__, tovpn_sid, bgp_vrf->name_pretty,
771
0
         afi2str(afi));
772
773
0
  bgp_vrf->vpn_policy[afi].tovpn_sid = tovpn_sid;
774
0
  bgp_vrf->vpn_policy[afi].tovpn_sid_locator = tovpn_sid_locator;
775
0
  bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label =
776
0
    tovpn_sid_transpose_label;
777
0
}
778
779
void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
780
0
{
781
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
782
0
  struct srv6_locator_chunk *tovpn_sid_locator;
783
0
  struct in6_addr *tovpn_sid;
784
0
  uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
785
0
  bool tovpn_sid_auto = false;
786
787
0
  if (debug)
788
0
    zlog_debug("%s: try to allocate new SID for vrf %s", __func__,
789
0
         bgp_vrf->name_pretty);
790
791
  /* skip when tovpn sid is already allocated on vrf instance */
792
0
  if (bgp_vrf->tovpn_sid)
793
0
    return;
794
795
  /*
796
   * skip when bgp vpn instance ins't allocated
797
   * or srv6 locator chunk isn't allocated
798
   */
799
0
  if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
800
0
    return;
801
802
0
  tovpn_sid_index = bgp_vrf->tovpn_sid_index;
803
0
  tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO);
804
805
  /* skip when VPN isn't configured on vrf-instance */
806
0
  if (tovpn_sid_index == 0 && !tovpn_sid_auto)
807
0
    return;
808
809
  /* check invalid case both configured index and auto */
810
0
  if (tovpn_sid_index != 0 && tovpn_sid_auto) {
811
0
    zlog_err("%s: index-mode and auto-mode both selected. ignored.",
812
0
       __func__);
813
0
    return;
814
0
  }
815
816
0
  tovpn_sid_locator = srv6_locator_chunk_alloc();
817
0
  tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
818
819
0
  tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
820
0
              tovpn_sid_locator, tovpn_sid);
821
822
0
  if (tovpn_sid_transpose_label == 0) {
823
0
    if (debug)
824
0
      zlog_debug("%s: not allocated new sid for vrf %s",
825
0
           __func__, bgp_vrf->name_pretty);
826
0
    srv6_locator_chunk_free(&tovpn_sid_locator);
827
0
    XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
828
0
    return;
829
0
  }
830
831
0
  if (debug)
832
0
    zlog_debug("%s: new sid %pI6 allocated for vrf %s", __func__,
833
0
         tovpn_sid, bgp_vrf->name_pretty);
834
835
0
  bgp_vrf->tovpn_sid = tovpn_sid;
836
0
  bgp_vrf->tovpn_sid_locator = tovpn_sid_locator;
837
0
  bgp_vrf->tovpn_sid_transpose_label = tovpn_sid_transpose_label;
838
0
}
839
840
void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
841
0
{
842
  /* per-af sid */
843
0
  if (bgp_vrf->vpn_policy[afi].tovpn_sid_index != 0 ||
844
0
      CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
845
0
           BGP_VPN_POLICY_TOVPN_SID_AUTO))
846
0
    return ensure_vrf_tovpn_sid_per_af(bgp_vpn, bgp_vrf, afi);
847
848
  /* per-vrf sid */
849
0
  if (bgp_vrf->tovpn_sid_index != 0 ||
850
0
      CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
851
0
    return ensure_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
852
0
}
853
854
void delete_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
855
         afi_t afi)
856
0
{
857
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
858
0
  uint32_t tovpn_sid_index = 0;
859
0
  bool tovpn_sid_auto = false;
860
861
0
  if (debug)
862
0
    zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__,
863
0
         bgp_vrf->name_pretty, afi2str(afi));
864
865
0
  tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
866
0
  tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
867
0
            BGP_VPN_POLICY_TOVPN_SID_AUTO);
868
869
  /* skip when VPN is configured on vrf-instance */
870
0
  if (tovpn_sid_index != 0 || tovpn_sid_auto)
871
0
    return;
872
873
0
  srv6_locator_chunk_free(&bgp_vrf->vpn_policy[afi].tovpn_sid_locator);
874
875
0
  if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
876
0
    sid_unregister(bgp_vpn, bgp_vrf->vpn_policy[afi].tovpn_sid);
877
0
    XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->vpn_policy[afi].tovpn_sid);
878
0
  }
879
0
  bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label = 0;
880
0
}
881
882
void delete_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
883
0
{
884
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
885
0
  uint32_t tovpn_sid_index = 0;
886
0
  bool tovpn_sid_auto = false;
887
888
0
  if (debug)
889
0
    zlog_debug("%s: try to remove SID for vrf %s", __func__,
890
0
         bgp_vrf->name_pretty);
891
892
0
  tovpn_sid_index = bgp_vrf->tovpn_sid_index;
893
0
  tovpn_sid_auto =
894
0
    CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VPN_POLICY_TOVPN_SID_AUTO);
895
896
  /* skip when VPN is configured on vrf-instance */
897
0
  if (tovpn_sid_index != 0 || tovpn_sid_auto)
898
0
    return;
899
900
0
  srv6_locator_chunk_free(&bgp_vrf->tovpn_sid_locator);
901
902
0
  if (bgp_vrf->tovpn_sid) {
903
0
    sid_unregister(bgp_vpn, bgp_vrf->tovpn_sid);
904
0
    XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
905
0
  }
906
0
  bgp_vrf->tovpn_sid_transpose_label = 0;
907
0
}
908
909
void delete_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
910
0
{
911
0
  delete_vrf_tovpn_sid_per_af(bgp_vpn, bgp_vrf, afi);
912
0
  delete_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
913
0
}
914
915
/*
916
 * This function embeds upper `len` bits of `label` in `sid`,
917
 * starting at offset `offset` as seen from the MSB of `sid`.
918
 *
919
 * e.g. Given that `label` is 0x12345 and `len` is 16,
920
 * then `label` will be embedded in `sid` as follows:
921
 *
922
 *                 <----   len  ----->
923
 *         label:  0001 0002 0003 0004 0005
924
 *         sid:    .... 0001 0002 0003 0004
925
 *                      <----   len  ----->
926
 *                    ^
927
 *                    |
928
 *                 offset from MSB
929
 *
930
 * e.g. Given that `label` is 0x12345 and `len` is 8,
931
 * `label` will be embedded in `sid` as follows:
932
 *
933
 *                 <- len ->
934
 *         label:  0001 0002 0003 0004 0005
935
 *         sid:    .... 0001 0002 0000 0000
936
 *                      <- len ->
937
 *                    ^
938
 *                    |
939
 *                 offset from MSB
940
 */
941
void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
942
       uint8_t len)
943
0
{
944
0
  for (uint8_t idx = 0; idx < len; idx++) {
945
0
    uint8_t tidx = offset + idx;
946
0
    sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8));
947
0
    if (label >> (19 - idx) & 0x1)
948
0
      sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8);
949
0
  }
950
0
}
951
952
static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
953
      uint32_t n)
954
0
{
955
0
  uint32_t i;
956
957
0
  if (!bpi->extra) {
958
0
    if (!n)
959
0
      return true;
960
0
    else
961
0
      return false;
962
0
  }
963
964
0
  if (n != bpi->extra->num_labels)
965
0
    return false;
966
967
0
  for (i = 0; i < n; ++i) {
968
0
    if (label[i] != bpi->extra->label[i])
969
0
      return false;
970
0
  }
971
0
  return true;
972
0
}
973
974
/*
975
 * make encoded route labels match specified encoded label set
976
 */
977
static void setlabels(struct bgp_path_info *bpi,
978
          mpls_label_t *label, /* array of labels */
979
          uint32_t num_labels)
980
0
{
981
0
  if (num_labels)
982
0
    assert(label);
983
0
  assert(num_labels <= BGP_MAX_LABELS);
984
985
0
  if (!num_labels) {
986
0
    if (bpi->extra)
987
0
      bpi->extra->num_labels = 0;
988
0
    return;
989
0
  }
990
991
0
  struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
992
0
  uint32_t i;
993
994
0
  for (i = 0; i < num_labels; ++i) {
995
0
    extra->label[i] = label[i];
996
0
    if (!bgp_is_valid_label(&label[i])) {
997
0
      bgp_set_valid_label(&extra->label[i]);
998
0
    }
999
0
  }
1000
0
  extra->num_labels = num_labels;
1001
0
}
1002
1003
/*
1004
 * make encoded route SIDs match specified encoded sid set
1005
 */
1006
static void setsids(struct bgp_path_info *bpi,
1007
          struct in6_addr *sid,
1008
          uint32_t num_sids)
1009
0
{
1010
0
  uint32_t i;
1011
0
  struct bgp_path_info_extra *extra;
1012
1013
0
  if (num_sids)
1014
0
    assert(sid);
1015
0
  assert(num_sids <= BGP_MAX_SIDS);
1016
1017
0
  if (!num_sids) {
1018
0
    if (bpi->extra)
1019
0
      bpi->extra->num_sids = 0;
1020
0
    return;
1021
0
  }
1022
1023
0
  extra = bgp_path_info_extra_get(bpi);
1024
0
  for (i = 0; i < num_sids; i++)
1025
0
    memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr));
1026
0
  extra->num_sids = num_sids;
1027
0
}
1028
1029
static void unsetsids(struct bgp_path_info *bpi)
1030
0
{
1031
0
  struct bgp_path_info_extra *extra;
1032
1033
0
  extra = bgp_path_info_extra_get(bpi);
1034
0
  extra->num_sids = 0;
1035
0
  memset(extra->sid, 0, sizeof(extra->sid));
1036
0
}
1037
1038
static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
1039
              struct attr *new_attr, afi_t afi,
1040
              safi_t safi,
1041
              struct bgp_path_info *source_bpi,
1042
              struct bgp_path_info *bpi,
1043
              struct bgp *bgp_orig,
1044
              const struct prefix *p, int debug)
1045
0
{
1046
0
  struct bgp_path_info *bpi_ultimate;
1047
0
  struct bgp *bgp_nexthop;
1048
0
  bool nh_valid;
1049
1050
0
  bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi);
1051
1052
0
  if (bpi->extra && bpi->extra->bgp_orig)
1053
0
    bgp_nexthop = bpi->extra->bgp_orig;
1054
0
  else
1055
0
    bgp_nexthop = bgp_orig;
1056
1057
  /*
1058
   * No nexthop tracking for redistributed routes, for
1059
   * EVPN-imported routes that get leaked, or for routes
1060
   * leaked between VRFs with accept-own community.
1061
   */
1062
0
  if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
1063
0
      is_pi_family_evpn(bpi_ultimate) ||
1064
0
      CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_ACCEPT_OWN))
1065
0
    nh_valid = true;
1066
0
  else
1067
    /*
1068
     * TBD do we need to do anything about the
1069
     * 'connected' parameter?
1070
     */
1071
0
    nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi,
1072
0
               safi, bpi, NULL, 0, p);
1073
1074
  /*
1075
   * If you are using SRv6 VPN instead of MPLS, it need to check
1076
   * the SID allocation. If the sid is not allocated, the rib
1077
   * will be invalid.
1078
   */
1079
0
  if (to_bgp->srv6_enabled &&
1080
0
      (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
1081
0
    nh_valid = false;
1082
0
  }
1083
1084
0
  if (debug)
1085
0
    zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p,
1086
0
         (nh_valid ? "" : "not "), bgp_nexthop->name_pretty);
1087
1088
0
  return nh_valid;
1089
0
}
1090
1091
/*
1092
 * returns pointer to new bgp_path_info upon success
1093
 */
1094
static struct bgp_path_info *
1095
leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
1096
      struct attr *new_attr, /* already interned */
1097
      afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
1098
      mpls_label_t *label, uint32_t num_labels, struct bgp *bgp_orig,
1099
      struct prefix *nexthop_orig, int nexthop_self_flag, int debug)
1100
0
{
1101
0
  const struct prefix *p = bgp_dest_get_prefix(bn);
1102
0
  struct bgp_path_info *bpi;
1103
0
  struct bgp_path_info *new;
1104
0
  struct bgp_path_info_extra *extra;
1105
0
  uint32_t num_sids = 0;
1106
0
  struct bgp_path_info *parent = source_bpi;
1107
1108
0
  if (new_attr->srv6_l3vpn || new_attr->srv6_vpn)
1109
0
    num_sids = 1;
1110
1111
0
  if (debug)
1112
0
    zlog_debug(
1113
0
      "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
1114
0
      __func__, to_bgp->name_pretty, bn, source_bpi->type,
1115
0
      source_bpi->sub_type);
1116
1117
  /*
1118
   * Routes that are redistributed into BGP from zebra do not get
1119
   * nexthop tracking, unless MPLS allocation per nexthop is
1120
   * performed. In the default case nexthop tracking does not apply,
1121
   * if those routes are subsequently imported to other RIBs within
1122
   * BGP, the leaked routes do not carry the original
1123
   * BGP_ROUTE_REDISTRIBUTE sub_type. Therefore, in order to determine
1124
   * if the route we are currently leaking should have nexthop
1125
   * tracking, we must find the ultimate parent so we can check its
1126
   * sub_type.
1127
   *
1128
   * As of now, source_bpi may at most be a second-generation route
1129
   * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1130
   * Using a loop here supports more complex intra-bgp import-export
1131
   * schemes that could be implemented in the future.
1132
   *
1133
   */
1134
1135
  /*
1136
   * match parent
1137
   */
1138
0
  for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
1139
0
    if (bpi->extra && bpi->extra->parent == parent)
1140
0
      break;
1141
0
  }
1142
1143
0
  if (bpi) {
1144
0
    bool labelssame = labels_same(bpi, label, num_labels);
1145
1146
0
    if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
1147
0
        && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
1148
0
      if (debug) {
1149
0
        zlog_debug(
1150
0
          "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
1151
0
          __func__, to_bgp->name_pretty,
1152
0
          source_bpi->flags, bpi->flags, p);
1153
0
      }
1154
0
      return NULL;
1155
0
    }
1156
1157
0
    if (attrhash_cmp(bpi->attr, new_attr) && labelssame
1158
0
        && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
1159
1160
0
      bgp_attr_unintern(&new_attr);
1161
0
      if (debug)
1162
0
        zlog_debug(
1163
0
          "%s: ->%s: %pBD: Found route, no change",
1164
0
          __func__, to_bgp->name_pretty, bn);
1165
0
      return NULL;
1166
0
    }
1167
1168
    /* If the RT was changed via extended communities as an
1169
     * import/export list, we should withdraw implicitly the old
1170
     * path from VRFs.
1171
     * For instance, RT list was modified using route-maps:
1172
     * route-map test permit 10
1173
     *   set extcommunity rt none
1174
     */
1175
0
    if (CHECK_FLAG(bpi->attr->flag,
1176
0
             ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
1177
0
        CHECK_FLAG(new_attr->flag,
1178
0
             ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
1179
0
      if (!ecommunity_cmp(
1180
0
            bgp_attr_get_ecommunity(bpi->attr),
1181
0
            bgp_attr_get_ecommunity(new_attr))) {
1182
0
        vpn_leak_to_vrf_withdraw(bpi);
1183
0
        bgp_aggregate_decrement(to_bgp, p, bpi, afi,
1184
0
              safi);
1185
0
        bgp_path_info_delete(bn, bpi);
1186
0
      }
1187
0
    }
1188
1189
    /* attr is changed */
1190
0
    bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
1191
1192
    /* Rewrite BGP route information. */
1193
0
    if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
1194
0
      bgp_path_info_restore(bn, bpi);
1195
0
    else
1196
0
      bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
1197
0
    bgp_attr_unintern(&bpi->attr);
1198
0
    bpi->attr = new_attr;
1199
0
    bpi->uptime = monotime(NULL);
1200
1201
    /*
1202
     * rewrite labels
1203
     */
1204
0
    if (!labelssame)
1205
0
      setlabels(bpi, label, num_labels);
1206
1207
    /*
1208
     * rewrite sid
1209
     */
1210
0
    if (num_sids) {
1211
0
      if (new_attr->srv6_l3vpn) {
1212
0
        setsids(bpi, &new_attr->srv6_l3vpn->sid,
1213
0
          num_sids);
1214
1215
0
        extra = bgp_path_info_extra_get(bpi);
1216
1217
0
        extra->sid[0].loc_block_len =
1218
0
          new_attr->srv6_l3vpn->loc_block_len;
1219
0
        extra->sid[0].loc_node_len =
1220
0
          new_attr->srv6_l3vpn->loc_node_len;
1221
0
        extra->sid[0].func_len =
1222
0
          new_attr->srv6_l3vpn->func_len;
1223
0
        extra->sid[0].arg_len =
1224
0
          new_attr->srv6_l3vpn->arg_len;
1225
0
        extra->sid[0].transposition_len =
1226
0
          new_attr->srv6_l3vpn->transposition_len;
1227
0
        extra->sid[0].transposition_offset =
1228
0
          new_attr->srv6_l3vpn
1229
0
            ->transposition_offset;
1230
0
      } else if (new_attr->srv6_vpn)
1231
0
        setsids(bpi, &new_attr->srv6_vpn->sid,
1232
0
          num_sids);
1233
0
    } else
1234
0
      unsetsids(bpi);
1235
1236
0
    if (nexthop_self_flag)
1237
0
      bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
1238
1239
0
    if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1240
0
      bgp_path_info_set_flag(bn, bpi, BGP_PATH_ACCEPT_OWN);
1241
1242
0
    if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
1243
0
                source_bpi, bpi, bgp_orig, p,
1244
0
                debug))
1245
0
      bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
1246
0
    else
1247
0
      bgp_path_info_unset_flag(bn, bpi, BGP_PATH_VALID);
1248
1249
    /* Process change. */
1250
0
    bgp_aggregate_increment(to_bgp, p, bpi, afi, safi);
1251
0
    bgp_process(to_bgp, bn, afi, safi);
1252
0
    bgp_dest_unlock_node(bn);
1253
1254
0
    if (debug)
1255
0
      zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1256
0
           __func__, to_bgp->name_pretty, bn);
1257
1258
0
    return bpi;
1259
0
  }
1260
1261
0
  if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
1262
0
    if (debug) {
1263
0
      zlog_debug(
1264
0
        "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1265
0
        __func__, to_bgp->name_pretty,
1266
0
        source_bpi->flags, p);
1267
0
    }
1268
0
    return NULL;
1269
0
  }
1270
1271
0
  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
1272
0
      to_bgp->peer_self, new_attr, bn);
1273
1274
0
  if (source_bpi->peer) {
1275
0
    extra = bgp_path_info_extra_get(new);
1276
0
    extra->peer_orig = peer_lock(source_bpi->peer);
1277
0
  }
1278
1279
0
  if (nexthop_self_flag)
1280
0
    bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
1281
1282
0
  if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1283
0
    bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN);
1284
1285
0
  bgp_path_info_extra_get(new);
1286
1287
  /*
1288
   * rewrite sid
1289
   */
1290
0
  if (num_sids) {
1291
0
    if (new_attr->srv6_l3vpn) {
1292
0
      setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
1293
1294
0
      extra = bgp_path_info_extra_get(new);
1295
1296
0
      extra->sid[0].loc_block_len =
1297
0
        new_attr->srv6_l3vpn->loc_block_len;
1298
0
      extra->sid[0].loc_node_len =
1299
0
        new_attr->srv6_l3vpn->loc_node_len;
1300
0
      extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len;
1301
0
      extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len;
1302
0
      extra->sid[0].transposition_len =
1303
0
        new_attr->srv6_l3vpn->transposition_len;
1304
0
      extra->sid[0].transposition_offset =
1305
0
        new_attr->srv6_l3vpn->transposition_offset;
1306
0
    } else if (new_attr->srv6_vpn)
1307
0
      setsids(new, &new_attr->srv6_vpn->sid, num_sids);
1308
0
  } else
1309
0
    unsetsids(new);
1310
1311
0
  if (num_labels)
1312
0
    setlabels(new, label, num_labels);
1313
1314
0
  new->extra->parent = bgp_path_info_lock(parent);
1315
0
  bgp_dest_lock_node(
1316
0
    (struct bgp_dest *)parent->net);
1317
0
  if (bgp_orig)
1318
0
    new->extra->bgp_orig = bgp_lock(bgp_orig);
1319
0
  if (nexthop_orig)
1320
0
    new->extra->nexthop_orig = *nexthop_orig;
1321
1322
0
  if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
1323
0
              source_bpi, new, bgp_orig, p, debug))
1324
0
    bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
1325
0
  else
1326
0
    bgp_path_info_unset_flag(bn, new, BGP_PATH_VALID);
1327
1328
0
  bgp_aggregate_increment(to_bgp, p, new, afi, safi);
1329
0
  bgp_path_info_add(bn, new);
1330
1331
0
  bgp_dest_unlock_node(bn);
1332
0
  bgp_process(to_bgp, bn, afi, safi);
1333
1334
0
  if (debug)
1335
0
    zlog_debug("%s: ->%s: %pBD: Added new route", __func__,
1336
0
         to_bgp->name_pretty, bn);
1337
1338
0
  return new;
1339
0
}
1340
1341
void bgp_mplsvpn_path_nh_label_unlink(struct bgp_path_info *pi)
1342
0
{
1343
0
  struct bgp_label_per_nexthop_cache *blnc;
1344
1345
0
  if (!pi)
1346
0
    return;
1347
1348
0
  blnc = pi->label_nexthop_cache;
1349
1350
0
  if (!blnc)
1351
0
    return;
1352
1353
0
  LIST_REMOVE(pi, label_nh_thread);
1354
0
  pi->label_nexthop_cache->path_count--;
1355
0
  pi->label_nexthop_cache = NULL;
1356
1357
0
  if (LIST_EMPTY(&(blnc->paths)))
1358
0
    bgp_label_per_nexthop_free(blnc);
1359
0
}
1360
1361
/* Called upon reception of a ZAPI Message from zebra, about
1362
 * a new available label.
1363
 */
1364
static int bgp_mplsvpn_get_label_per_nexthop_cb(mpls_label_t label,
1365
            void *context, bool allocated)
1366
0
{
1367
0
  struct bgp_label_per_nexthop_cache *blnc = context;
1368
0
  mpls_label_t old_label;
1369
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
1370
0
  struct bgp_path_info *pi;
1371
0
  struct bgp_table *table;
1372
1373
0
  old_label = blnc->label;
1374
1375
0
  if (debug)
1376
0
    zlog_debug("%s: label=%u, allocated=%d, nexthop=%pFX", __func__,
1377
0
         label, allocated, &blnc->nexthop);
1378
0
  if (allocated)
1379
    /* update the entry with the new label */
1380
0
    blnc->label = label;
1381
0
  else
1382
    /*
1383
     * previously-allocated label is now invalid
1384
     * eg: zebra deallocated the labels and notifies it
1385
     */
1386
0
    blnc->label = MPLS_INVALID_LABEL;
1387
1388
0
  if (old_label == blnc->label)
1389
0
    return 0; /* no change */
1390
1391
  /* update paths */
1392
0
  if (blnc->label != MPLS_INVALID_LABEL)
1393
0
    bgp_zebra_send_nexthop_label(
1394
0
      ZEBRA_MPLS_LABELS_ADD, blnc->label, blnc->nh->ifindex,
1395
0
      blnc->nh->vrf_id, ZEBRA_LSP_BGP, &blnc->nexthop);
1396
1397
0
  LIST_FOREACH (pi, &(blnc->paths), label_nh_thread) {
1398
0
    if (!pi->net)
1399
0
      continue;
1400
0
    table = bgp_dest_table(pi->net);
1401
0
    if (!table)
1402
0
      continue;
1403
0
    vpn_leak_from_vrf_update(blnc->to_bgp, table->bgp, pi);
1404
0
  }
1405
1406
0
  return 0;
1407
0
}
1408
1409
/* Get a per label nexthop value:
1410
 *  - Find and return a per label nexthop from the cache
1411
 *  - else allocate a new per label nexthop cache entry and request a
1412
 *    label to zebra. Return MPLS_INVALID_LABEL
1413
 */
1414
static mpls_label_t _vpn_leak_from_vrf_get_per_nexthop_label(
1415
  struct bgp_path_info *pi, struct bgp *to_bgp, struct bgp *from_bgp,
1416
  afi_t afi, safi_t safi)
1417
0
{
1418
0
  struct bgp_nexthop_cache *bnc = pi->nexthop;
1419
0
  struct bgp_label_per_nexthop_cache *blnc;
1420
0
  struct bgp_label_per_nexthop_cache_head *tree;
1421
0
  struct prefix *nh_pfx = NULL;
1422
0
  struct prefix nh_gate = {0};
1423
1424
  /* extract the nexthop from the BNC nexthop cache */
1425
0
  switch (bnc->nexthop->type) {
1426
0
  case NEXTHOP_TYPE_IPV4:
1427
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
1428
    /* the nexthop is recursive */
1429
0
    nh_gate.family = AF_INET;
1430
0
    nh_gate.prefixlen = IPV4_MAX_BITLEN;
1431
0
    IPV4_ADDR_COPY(&nh_gate.u.prefix4, &bnc->nexthop->gate.ipv4);
1432
0
    nh_pfx = &nh_gate;
1433
0
    break;
1434
0
  case NEXTHOP_TYPE_IPV6:
1435
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
1436
    /* the nexthop is recursive */
1437
0
    nh_gate.family = AF_INET6;
1438
0
    nh_gate.prefixlen = IPV6_MAX_BITLEN;
1439
0
    IPV6_ADDR_COPY(&nh_gate.u.prefix6, &bnc->nexthop->gate.ipv6);
1440
0
    nh_pfx = &nh_gate;
1441
0
    break;
1442
0
  case NEXTHOP_TYPE_IFINDEX:
1443
    /* the nexthop is direcly connected */
1444
0
    nh_pfx = &bnc->prefix;
1445
0
    break;
1446
0
  case NEXTHOP_TYPE_BLACKHOLE:
1447
0
    assert(!"Blackhole nexthop. Already checked by the caller.");
1448
0
  }
1449
1450
  /* find or allocate a nexthop label cache entry */
1451
0
  tree = &from_bgp->mpls_labels_per_nexthop[family2afi(nh_pfx->family)];
1452
0
  blnc = bgp_label_per_nexthop_find(tree, nh_pfx);
1453
0
  if (!blnc) {
1454
0
    blnc = bgp_label_per_nexthop_new(tree, nh_pfx);
1455
0
    blnc->to_bgp = to_bgp;
1456
    /* request a label to zebra for this nexthop
1457
     * the response from zebra will trigger the callback
1458
     */
1459
0
    bgp_lp_get(LP_TYPE_NEXTHOP, blnc,
1460
0
         bgp_mplsvpn_get_label_per_nexthop_cb);
1461
0
  }
1462
1463
0
  if (pi->label_nexthop_cache == blnc)
1464
    /* no change */
1465
0
    return blnc->label;
1466
1467
  /* Unlink from any existing nexthop cache. Free the entry if unused.
1468
   */
1469
0
  bgp_mplsvpn_path_nh_label_unlink(pi);
1470
1471
  /* updates NHT pi list reference */
1472
0
  LIST_INSERT_HEAD(&(blnc->paths), pi, label_nh_thread);
1473
0
  pi->label_nexthop_cache = blnc;
1474
0
  pi->label_nexthop_cache->path_count++;
1475
0
  blnc->last_update = monotime(NULL);
1476
1477
  /* then add or update the selected nexthop */
1478
0
  if (!blnc->nh)
1479
0
    blnc->nh = nexthop_dup(bnc->nexthop, NULL);
1480
0
  else if (!nexthop_same(bnc->nexthop, blnc->nh)) {
1481
0
    nexthop_free(blnc->nh);
1482
0
    blnc->nh = nexthop_dup(bnc->nexthop, NULL);
1483
0
    if (blnc->label != MPLS_INVALID_LABEL) {
1484
0
      bgp_zebra_send_nexthop_label(
1485
0
        ZEBRA_MPLS_LABELS_REPLACE, blnc->label,
1486
0
        bnc->nexthop->ifindex, bnc->nexthop->vrf_id,
1487
0
        ZEBRA_LSP_BGP, &blnc->nexthop);
1488
0
    }
1489
0
  }
1490
1491
0
  return blnc->label;
1492
0
}
1493
1494
/* Filter out all the cases where a per nexthop label is not possible:
1495
 * - return an invalid label when the nexthop is invalid
1496
 * - return the per VRF label when the per nexthop label is not supported
1497
 * Otherwise, find or request a per label nexthop.
1498
 */
1499
static mpls_label_t vpn_leak_from_vrf_get_per_nexthop_label(
1500
  afi_t afi, safi_t safi, struct bgp_path_info *pi, struct bgp *from_bgp,
1501
  struct bgp *to_bgp)
1502
0
{
1503
0
  struct bgp_path_info *bpi_ultimate = bgp_get_imported_bpi_ultimate(pi);
1504
0
  struct bgp *bgp_nexthop = NULL;
1505
0
  bool nh_valid;
1506
0
  afi_t nh_afi;
1507
0
  bool is_bgp_static_route;
1508
1509
0
  is_bgp_static_route = bpi_ultimate->sub_type == BGP_ROUTE_STATIC &&
1510
0
            bpi_ultimate->type == ZEBRA_ROUTE_BGP;
1511
1512
0
  if (is_bgp_static_route == false && afi == AFI_IP &&
1513
0
      CHECK_FLAG(pi->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) &&
1514
0
      (pi->attr->nexthop.s_addr == INADDR_ANY ||
1515
0
       !ipv4_unicast_valid(&pi->attr->nexthop))) {
1516
    /* IPv4 nexthop in standard BGP encoding format.
1517
     * Format of address is not valid (not any, not unicast).
1518
     * Fallback to the per VRF label.
1519
     */
1520
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1521
0
    return from_bgp->vpn_policy[afi].tovpn_label;
1522
0
  }
1523
1524
0
  if (is_bgp_static_route == false && afi == AFI_IP &&
1525
0
      pi->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4 &&
1526
0
      (pi->attr->mp_nexthop_global_in.s_addr == INADDR_ANY ||
1527
0
       !ipv4_unicast_valid(&pi->attr->mp_nexthop_global_in))) {
1528
    /* IPv4 nexthop is in MP-BGP encoding format.
1529
     * Format of address is not valid (not any, not unicast).
1530
     * Fallback to the per VRF label.
1531
     */
1532
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1533
0
    return from_bgp->vpn_policy[afi].tovpn_label;
1534
0
  }
1535
1536
0
  if (is_bgp_static_route == false && afi == AFI_IP6 &&
1537
0
      (pi->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL ||
1538
0
       pi->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) &&
1539
0
      (IN6_IS_ADDR_UNSPECIFIED(&pi->attr->mp_nexthop_global) ||
1540
0
       IN6_IS_ADDR_LOOPBACK(&pi->attr->mp_nexthop_global) ||
1541
0
       IN6_IS_ADDR_MULTICAST(&pi->attr->mp_nexthop_global))) {
1542
    /* IPv6 nexthop is in MP-BGP encoding format.
1543
     * Format of address is not valid
1544
     * Fallback to the per VRF label.
1545
     */
1546
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1547
0
    return from_bgp->vpn_policy[afi].tovpn_label;
1548
0
  }
1549
1550
  /* Check the next-hop reachability.
1551
   * Get the bgp instance where the bgp_path_info originates.
1552
   */
1553
0
  if (pi->extra && pi->extra->bgp_orig)
1554
0
    bgp_nexthop = pi->extra->bgp_orig;
1555
0
  else
1556
0
    bgp_nexthop = from_bgp;
1557
1558
0
  nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
1559
0
  nh_valid = bgp_find_or_add_nexthop(from_bgp, bgp_nexthop, nh_afi, safi,
1560
0
             pi, NULL, 0, NULL);
1561
1562
0
  if (!nh_valid && is_bgp_static_route &&
1563
0
      !CHECK_FLAG(from_bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
1564
    /* "network" prefixes not routable, but since 'no bgp network
1565
     * import-check' is configured, they are always valid in the BGP
1566
     * table. Fallback to the per-vrf label
1567
     */
1568
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1569
0
    return from_bgp->vpn_policy[afi].tovpn_label;
1570
0
  }
1571
1572
0
  if (!nh_valid || !pi->nexthop || pi->nexthop->nexthop_num == 0 ||
1573
0
      !pi->nexthop->nexthop) {
1574
    /* invalid next-hop:
1575
     * do not send the per-vrf label
1576
     * otherwise, when the next-hop becomes valid,
1577
     * we will have 2 BGP updates:
1578
     * - one with the per-vrf label
1579
     * - the second with the per-nexthop label
1580
     */
1581
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1582
0
    return MPLS_INVALID_LABEL;
1583
0
  }
1584
1585
0
  if (pi->nexthop->nexthop_num > 1 ||
1586
0
      pi->nexthop->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
1587
    /* Blackhole or ECMP routes
1588
     * is not compatible with per-nexthop label.
1589
     * Fallback to per-vrf label.
1590
     */
1591
0
    bgp_mplsvpn_path_nh_label_unlink(pi);
1592
0
    return from_bgp->vpn_policy[afi].tovpn_label;
1593
0
  }
1594
1595
0
  return _vpn_leak_from_vrf_get_per_nexthop_label(pi, to_bgp, from_bgp,
1596
0
              afi, safi);
1597
0
}
1598
1599
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1600
void vpn_leak_from_vrf_update(struct bgp *to_bgp,      /* to */
1601
            struct bgp *from_bgp,    /* from */
1602
            struct bgp_path_info *path_vrf) /* route */
1603
0
{
1604
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1605
0
  const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
1606
0
  afi_t afi = family2afi(p->family);
1607
0
  struct attr static_attr = {0};
1608
0
  struct attr *new_attr = NULL;
1609
0
  safi_t safi = SAFI_MPLS_VPN;
1610
0
  mpls_label_t label_val;
1611
0
  mpls_label_t label;
1612
0
  struct bgp_dest *bn;
1613
0
  const char *debugmsg;
1614
0
  int nexthop_self_flag = 0;
1615
1616
0
  if (debug)
1617
0
    zlog_debug("%s: from vrf %s", __func__, from_bgp->name_pretty);
1618
1619
0
  if (debug && bgp_attr_get_ecommunity(path_vrf->attr)) {
1620
0
    char *s = ecommunity_ecom2str(
1621
0
      bgp_attr_get_ecommunity(path_vrf->attr),
1622
0
      ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1623
1624
0
    zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
1625
0
         from_bgp->name, path_vrf->type, s);
1626
0
    XFREE(MTYPE_ECOMMUNITY_STR, s);
1627
0
  }
1628
1629
0
  if (!to_bgp)
1630
0
    return;
1631
1632
0
  if (!afi) {
1633
0
    if (debug)
1634
0
      zlog_debug("%s: can't get afi of prefix", __func__);
1635
0
    return;
1636
0
  }
1637
1638
  /* Is this route exportable into the VPN table? */
1639
0
  if (!is_route_injectable_into_vpn(path_vrf))
1640
0
    return;
1641
1642
0
  if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
1643
0
    if (debug)
1644
0
      zlog_debug("%s: %s skipping: %s", __func__,
1645
0
           from_bgp->name, debugmsg);
1646
0
    return;
1647
0
  }
1648
1649
  /* shallow copy */
1650
0
  static_attr = *path_vrf->attr;
1651
1652
  /*
1653
   * route map handling
1654
   */
1655
0
  if (from_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
1656
0
    struct bgp_path_info info;
1657
0
    route_map_result_t ret;
1658
1659
0
    memset(&info, 0, sizeof(info));
1660
0
    info.peer = to_bgp->peer_self;
1661
0
    info.attr = &static_attr;
1662
0
    ret = route_map_apply(from_bgp->vpn_policy[afi]
1663
0
                .rmap[BGP_VPN_POLICY_DIR_TOVPN],
1664
0
              p, &info);
1665
0
    if (RMAP_DENYMATCH == ret) {
1666
0
      bgp_attr_flush(&static_attr); /* free any added parts */
1667
0
      if (debug)
1668
0
        zlog_debug(
1669
0
          "%s: vrf %s route map \"%s\" says DENY, returning",
1670
0
          __func__, from_bgp->name_pretty,
1671
0
          from_bgp->vpn_policy[afi]
1672
0
            .rmap[BGP_VPN_POLICY_DIR_TOVPN]
1673
0
            ->name);
1674
0
      return;
1675
0
    }
1676
0
  }
1677
1678
0
  if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1679
0
    char *s = ecommunity_ecom2str(
1680
0
      bgp_attr_get_ecommunity(&static_attr),
1681
0
      ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1682
1683
0
    zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1684
0
         __func__, s);
1685
0
    XFREE(MTYPE_ECOMMUNITY_STR, s);
1686
0
  }
1687
1688
  /*
1689
   * Add the vpn-policy rt-list
1690
   */
1691
0
  struct ecommunity *old_ecom;
1692
0
  struct ecommunity *new_ecom;
1693
1694
  /* Export with the 'from' instance's export RTs. */
1695
  /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1696
0
  old_ecom = bgp_attr_get_ecommunity(&static_attr);
1697
0
  if (old_ecom) {
1698
0
    new_ecom = ecommunity_dup(old_ecom);
1699
0
    if (CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
1700
0
             BGP_CONFIG_VRF_TO_VRF_EXPORT))
1701
0
      ecommunity_strip_rts(new_ecom);
1702
0
    new_ecom = ecommunity_merge(
1703
0
      new_ecom, from_bgp->vpn_policy[afi]
1704
0
            .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1705
0
    if (!old_ecom->refcnt)
1706
0
      ecommunity_free(&old_ecom);
1707
0
  } else {
1708
0
    new_ecom = ecommunity_dup(
1709
0
      from_bgp->vpn_policy[afi]
1710
0
        .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1711
0
  }
1712
0
  bgp_attr_set_ecommunity(&static_attr, new_ecom);
1713
1714
0
  if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1715
0
    char *s = ecommunity_ecom2str(
1716
0
      bgp_attr_get_ecommunity(&static_attr),
1717
0
      ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1718
1719
0
    zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1720
0
         __func__, s);
1721
0
    XFREE(MTYPE_ECOMMUNITY_STR, s);
1722
0
  }
1723
1724
0
  community_strip_accept_own(&static_attr);
1725
1726
  /* Nexthop */
1727
  /* if policy nexthop not set, use 0 */
1728
0
  if (CHECK_FLAG(from_bgp->vpn_policy[afi].flags,
1729
0
           BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
1730
0
    struct prefix *nexthop =
1731
0
      &from_bgp->vpn_policy[afi].tovpn_nexthop;
1732
1733
0
    switch (nexthop->family) {
1734
0
    case AF_INET:
1735
      /* prevent mp_nexthop_global_in <- self in bgp_route.c
1736
       */
1737
0
      static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
1738
1739
0
      static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
1740
0
      static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1741
0
      break;
1742
1743
0
    case AF_INET6:
1744
0
      static_attr.mp_nexthop_global = nexthop->u.prefix6;
1745
0
      static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1746
0
      break;
1747
1748
0
    default:
1749
0
      assert(0);
1750
0
    }
1751
0
  } else {
1752
0
    if (!CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
1753
0
        BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
1754
0
      if (afi == AFI_IP &&
1755
0
          !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
1756
        /*
1757
         * For ipv4, copy to multiprotocol
1758
         * nexthop field
1759
         */
1760
0
        static_attr.mp_nexthop_global_in =
1761
0
          static_attr.nexthop;
1762
0
        static_attr.mp_nexthop_len =
1763
0
          BGP_ATTR_NHLEN_IPV4;
1764
        /*
1765
         * XXX Leave static_attr.nexthop
1766
         * intact for NHT
1767
         */
1768
0
        static_attr.flag &=
1769
0
          ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1770
0
      }
1771
0
    } else {
1772
      /* Update based on next-hop family to account for
1773
       * RFC 5549 (BGP unnumbered) scenario. Note that
1774
       * specific action is only needed for the case of
1775
       * IPv4 nexthops as the attr has been copied
1776
       * otherwise.
1777
       */
1778
0
      if (afi == AFI_IP
1779
0
          && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
1780
0
        static_attr.mp_nexthop_global_in.s_addr =
1781
0
          static_attr.nexthop.s_addr;
1782
0
        static_attr.mp_nexthop_len =
1783
0
          BGP_ATTR_NHLEN_IPV4;
1784
0
        static_attr.flag |=
1785
0
          ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1786
0
      }
1787
0
    }
1788
0
    nexthop_self_flag = 1;
1789
0
  }
1790
1791
0
  if (CHECK_FLAG(from_bgp->vpn_policy[afi].flags,
1792
0
           BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP))
1793
    /* per nexthop label mode */
1794
0
    label_val = vpn_leak_from_vrf_get_per_nexthop_label(
1795
0
      afi, safi, path_vrf, from_bgp, to_bgp);
1796
0
  else
1797
    /* per VRF label mode */
1798
0
    label_val = from_bgp->vpn_policy[afi].tovpn_label;
1799
1800
0
  if (label_val == MPLS_INVALID_LABEL &&
1801
0
      CHECK_FLAG(from_bgp->vpn_policy[afi].flags,
1802
0
           BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP)) {
1803
    /* no valid label for the moment
1804
     * when the 'bgp_mplsvpn_get_label_per_nexthop_cb' callback gets
1805
     * a valid label value, it will call the current function again.
1806
     */
1807
0
    if (debug)
1808
0
      zlog_debug(
1809
0
        "%s: %s skipping: waiting for a valid per-label nexthop.",
1810
0
        __func__, from_bgp->name_pretty);
1811
0
    return;
1812
0
  }
1813
0
  if (label_val == MPLS_LABEL_NONE)
1814
0
    encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
1815
0
  else
1816
0
    encode_label(label_val, &label);
1817
1818
  /* Set originator ID to "me" */
1819
0
  SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
1820
0
  static_attr.originator_id = to_bgp->router_id;
1821
1822
  /* Set SID for SRv6 VPN */
1823
0
  if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
1824
0
    struct srv6_locator_chunk *locator =
1825
0
      from_bgp->vpn_policy[afi].tovpn_sid_locator;
1826
0
    encode_label(
1827
0
      from_bgp->vpn_policy[afi].tovpn_sid_transpose_label,
1828
0
      &label);
1829
0
    static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
1830
0
        sizeof(struct bgp_attr_srv6_l3vpn));
1831
0
    static_attr.srv6_l3vpn->sid_flags = 0x00;
1832
0
    static_attr.srv6_l3vpn->endpoint_behavior =
1833
0
      afi == AFI_IP
1834
0
        ? (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1835
0
             ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1836
0
             : SRV6_ENDPOINT_BEHAVIOR_END_DT4)
1837
0
        : (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1838
0
             ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1839
0
             : SRV6_ENDPOINT_BEHAVIOR_END_DT6);
1840
0
    static_attr.srv6_l3vpn->loc_block_len =
1841
0
      from_bgp->vpn_policy[afi]
1842
0
        .tovpn_sid_locator->block_bits_length;
1843
0
    static_attr.srv6_l3vpn->loc_node_len =
1844
0
      from_bgp->vpn_policy[afi]
1845
0
        .tovpn_sid_locator->node_bits_length;
1846
0
    static_attr.srv6_l3vpn->func_len =
1847
0
      from_bgp->vpn_policy[afi]
1848
0
        .tovpn_sid_locator->function_bits_length;
1849
0
    static_attr.srv6_l3vpn->arg_len =
1850
0
      from_bgp->vpn_policy[afi]
1851
0
        .tovpn_sid_locator->argument_bits_length;
1852
0
    static_attr.srv6_l3vpn->transposition_len =
1853
0
      from_bgp->vpn_policy[afi]
1854
0
        .tovpn_sid_locator->function_bits_length;
1855
0
    static_attr.srv6_l3vpn->transposition_offset =
1856
0
      from_bgp->vpn_policy[afi]
1857
0
        .tovpn_sid_locator->block_bits_length +
1858
0
      from_bgp->vpn_policy[afi]
1859
0
        .tovpn_sid_locator->node_bits_length;
1860
0
    ;
1861
0
    memcpy(&static_attr.srv6_l3vpn->sid,
1862
0
           &from_bgp->vpn_policy[afi]
1863
0
        .tovpn_sid_locator->prefix.prefix,
1864
0
           sizeof(struct in6_addr));
1865
0
  } else if (from_bgp->tovpn_sid_locator) {
1866
0
    struct srv6_locator_chunk *locator =
1867
0
      from_bgp->tovpn_sid_locator;
1868
0
    encode_label(from_bgp->tovpn_sid_transpose_label, &label);
1869
0
    static_attr.srv6_l3vpn =
1870
0
      XCALLOC(MTYPE_BGP_SRV6_L3VPN,
1871
0
        sizeof(struct bgp_attr_srv6_l3vpn));
1872
0
    static_attr.srv6_l3vpn->sid_flags = 0x00;
1873
0
    static_attr.srv6_l3vpn->endpoint_behavior =
1874
0
      CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1875
0
        ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1876
0
        : SRV6_ENDPOINT_BEHAVIOR_END_DT46;
1877
0
    static_attr.srv6_l3vpn->loc_block_len =
1878
0
      from_bgp->tovpn_sid_locator->block_bits_length;
1879
0
    static_attr.srv6_l3vpn->loc_node_len =
1880
0
      from_bgp->tovpn_sid_locator->node_bits_length;
1881
0
    static_attr.srv6_l3vpn->func_len =
1882
0
      from_bgp->tovpn_sid_locator->function_bits_length;
1883
0
    static_attr.srv6_l3vpn->arg_len =
1884
0
      from_bgp->tovpn_sid_locator->argument_bits_length;
1885
0
    static_attr.srv6_l3vpn->transposition_len =
1886
0
      from_bgp->tovpn_sid_locator->function_bits_length;
1887
0
    static_attr.srv6_l3vpn->transposition_offset =
1888
0
      from_bgp->tovpn_sid_locator->block_bits_length +
1889
0
      from_bgp->tovpn_sid_locator->node_bits_length;
1890
0
    memcpy(&static_attr.srv6_l3vpn->sid,
1891
0
           &from_bgp->tovpn_sid_locator->prefix.prefix,
1892
0
           sizeof(struct in6_addr));
1893
0
  }
1894
1895
1896
0
  new_attr = bgp_attr_intern(
1897
0
    &static_attr);  /* hashed refcounted everything */
1898
0
  bgp_attr_flush(&static_attr); /* free locally-allocated parts */
1899
1900
0
  if (debug && bgp_attr_get_ecommunity(new_attr)) {
1901
0
    char *s = ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr),
1902
0
                ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1903
1904
0
    zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
1905
0
    XFREE(MTYPE_ECOMMUNITY_STR, s);
1906
0
  }
1907
1908
  /* Now new_attr is an allocated interned attr */
1909
1910
0
  bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1911
0
            &(from_bgp->vpn_policy[afi].tovpn_rd));
1912
1913
0
  struct bgp_path_info *new_info;
1914
1915
0
  new_info =
1916
0
    leak_update(to_bgp, bn, new_attr, afi, safi, path_vrf, &label,
1917
0
          1, from_bgp, NULL, nexthop_self_flag, debug);
1918
1919
  /*
1920
   * Routes actually installed in the vpn RIB must also be
1921
   * offered to all vrfs (because now they originate from
1922
   * the vpn RIB).
1923
   *
1924
   * Acceptance into other vrfs depends on rt-lists.
1925
   * Originating vrf will not accept the looped back route
1926
   * because of loop checking.
1927
   */
1928
0
  if (new_info)
1929
0
    vpn_leak_to_vrf_update(from_bgp, new_info, NULL);
1930
0
  else
1931
0
    bgp_dest_unlock_node(bn);
1932
0
}
1933
1934
void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp,   /* to */
1935
        struct bgp *from_bgp,   /* from */
1936
        struct bgp_path_info *path_vrf) /* route */
1937
0
{
1938
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1939
0
  const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
1940
0
  afi_t afi = family2afi(p->family);
1941
0
  safi_t safi = SAFI_MPLS_VPN;
1942
0
  struct bgp_path_info *bpi;
1943
0
  struct bgp_dest *bn;
1944
0
  const char *debugmsg;
1945
1946
0
  if (debug) {
1947
0
    zlog_debug(
1948
0
      "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1949
0
      __func__, from_bgp->name_pretty, path_vrf->net,
1950
0
      path_vrf->type, path_vrf->sub_type);
1951
0
  }
1952
1953
0
  if (!to_bgp)
1954
0
    return;
1955
1956
0
  if (!afi) {
1957
0
    if (debug)
1958
0
      zlog_debug("%s: can't get afi of prefix", __func__);
1959
0
    return;
1960
0
  }
1961
1962
  /* Is this route exportable into the VPN table? */
1963
0
  if (!is_route_injectable_into_vpn(path_vrf))
1964
0
    return;
1965
1966
0
  if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
1967
0
    if (debug)
1968
0
      zlog_debug("%s: skipping: %s", __func__, debugmsg);
1969
0
    return;
1970
0
  }
1971
1972
0
  if (debug)
1973
0
    zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
1974
1975
0
  bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1976
0
            &(from_bgp->vpn_policy[afi].tovpn_rd));
1977
1978
0
  if (!bn)
1979
0
    return;
1980
  /*
1981
   * vrf -> vpn
1982
   * match original bpi imported from
1983
   */
1984
0
  for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
1985
0
    if (bpi->extra && bpi->extra->parent == path_vrf) {
1986
0
      break;
1987
0
    }
1988
0
  }
1989
1990
0
  if (bpi) {
1991
    /* withdraw from looped vrfs as well */
1992
0
    vpn_leak_to_vrf_withdraw(bpi);
1993
1994
0
    bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
1995
0
    bgp_path_info_delete(bn, bpi);
1996
0
    bgp_process(to_bgp, bn, afi, safi);
1997
0
  }
1998
0
  bgp_dest_unlock_node(bn);
1999
0
}
2000
2001
void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,
2002
            afi_t afi)
2003
0
{
2004
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
2005
0
  struct bgp_dest *pdest;
2006
0
  safi_t safi = SAFI_MPLS_VPN;
2007
2008
  /*
2009
   * Walk vpn table, delete bpi with bgp_orig == from_bgp
2010
   */
2011
0
  for (pdest = bgp_table_top(to_bgp->rib[afi][safi]); pdest;
2012
0
       pdest = bgp_route_next(pdest)) {
2013
2014
0
    struct bgp_table *table;
2015
0
    struct bgp_dest *bn;
2016
0
    struct bgp_path_info *bpi;
2017
2018
    /* This is the per-RD table of prefixes */
2019
0
    table = bgp_dest_get_bgp_table_info(pdest);
2020
2021
0
    if (!table)
2022
0
      continue;
2023
2024
0
    for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
2025
0
      bpi = bgp_dest_get_bgp_path_info(bn);
2026
0
      if (debug && bpi) {
2027
0
        zlog_debug("%s: looking at prefix %pBD",
2028
0
             __func__, bn);
2029
0
      }
2030
2031
0
      for (; bpi; bpi = bpi->next) {
2032
0
        if (debug)
2033
0
          zlog_debug("%s: type %d, sub_type %d",
2034
0
               __func__, bpi->type,
2035
0
               bpi->sub_type);
2036
0
        if (bpi->sub_type != BGP_ROUTE_IMPORTED)
2037
0
          continue;
2038
0
        if (!bpi->extra)
2039
0
          continue;
2040
0
        if ((struct bgp *)bpi->extra->bgp_orig ==
2041
0
            from_bgp) {
2042
          /* delete route */
2043
0
          if (debug)
2044
0
            zlog_debug("%s: deleting it",
2045
0
                 __func__);
2046
          /* withdraw from leak-to vrfs as well */
2047
0
          vpn_leak_to_vrf_withdraw(bpi);
2048
0
          bgp_aggregate_decrement(
2049
0
            to_bgp, bgp_dest_get_prefix(bn),
2050
0
            bpi, afi, safi);
2051
0
          bgp_path_info_delete(bn, bpi);
2052
0
          bgp_process(to_bgp, bn, afi, safi);
2053
0
          bgp_mplsvpn_path_nh_label_unlink(
2054
0
            bpi->extra->parent);
2055
0
        }
2056
0
      }
2057
0
    }
2058
0
  }
2059
0
}
2060
2061
void vpn_leak_from_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
2062
          afi_t afi)
2063
0
{
2064
0
  struct bgp_dest *bn;
2065
0
  struct bgp_path_info *bpi;
2066
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
2067
2068
0
  if (debug)
2069
0
    zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
2070
0
         from_bgp->name_pretty);
2071
2072
0
  for (bn = bgp_table_top(from_bgp->rib[afi][SAFI_UNICAST]); bn;
2073
0
       bn = bgp_route_next(bn)) {
2074
2075
0
    if (debug)
2076
0
      zlog_debug("%s: node=%p", __func__, bn);
2077
2078
0
    for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2079
0
         bpi = bpi->next) {
2080
0
      if (debug)
2081
0
        zlog_debug(
2082
0
          "%s: calling vpn_leak_from_vrf_update",
2083
0
          __func__);
2084
0
      vpn_leak_from_vrf_update(to_bgp, from_bgp, bpi);
2085
0
    }
2086
0
  }
2087
0
}
2088
2089
static struct bgp *bgp_lookup_by_rd(struct bgp_path_info *bpi,
2090
            struct prefix_rd *rd, afi_t afi)
2091
0
{
2092
0
  struct listnode *node, *nnode;
2093
0
  struct bgp *bgp;
2094
2095
0
  if (!rd)
2096
0
    return NULL;
2097
2098
  /* If ACCEPT_OWN is not enabled for this path - return. */
2099
0
  if (!CHECK_FLAG(bpi->flags, BGP_PATH_ACCEPT_OWN))
2100
0
    return NULL;
2101
2102
0
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
2103
0
    if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2104
0
      continue;
2105
2106
0
    if (!CHECK_FLAG(bgp->vpn_policy[afi].flags,
2107
0
        BGP_VPN_POLICY_TOVPN_RD_SET))
2108
0
      continue;
2109
2110
    /* Check if we have source VRF by RD value */
2111
0
    if (memcmp(&bgp->vpn_policy[afi].tovpn_rd.val, rd->val,
2112
0
         ECOMMUNITY_SIZE) == 0)
2113
0
      return bgp;
2114
0
  }
2115
2116
0
  return NULL;
2117
0
}
2118
2119
static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
2120
            struct bgp *from_bgp, /* from */
2121
            struct bgp_path_info *path_vpn,
2122
            struct prefix_rd *prd)
2123
0
{
2124
0
  const struct prefix *p = bgp_dest_get_prefix(path_vpn->net);
2125
0
  afi_t afi = family2afi(p->family);
2126
2127
0
  struct attr static_attr = {0};
2128
0
  struct attr *new_attr = NULL;
2129
0
  struct bgp_dest *bn;
2130
0
  safi_t safi = SAFI_UNICAST;
2131
0
  const char *debugmsg;
2132
0
  struct prefix nexthop_orig;
2133
0
  mpls_label_t *pLabels = NULL;
2134
0
  uint32_t num_labels = 0;
2135
0
  int nexthop_self_flag = 1;
2136
0
  struct bgp_path_info *bpi_ultimate = NULL;
2137
0
  int origin_local = 0;
2138
0
  struct bgp *src_vrf;
2139
0
  struct interface *ifp;
2140
0
  char rd_buf[RD_ADDRSTRLEN];
2141
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2142
2143
0
  if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
2144
0
    if (debug)
2145
0
      zlog_debug(
2146
0
        "%s: from vpn (%s) to vrf (%s), skipping: %s",
2147
0
        __func__, from_bgp->name_pretty,
2148
0
        to_bgp->name_pretty, debugmsg);
2149
0
    return false;
2150
0
  }
2151
2152
  /*
2153
   * For VRF-2-VRF route-leaking,
2154
   * the source will be the originating VRF.
2155
   *
2156
   * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
2157
   * get the source VRF (BGP) by looking at the RD.
2158
   */
2159
0
  struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi);
2160
2161
0
  if (path_vpn->extra && path_vpn->extra->bgp_orig)
2162
0
    src_vrf = path_vpn->extra->bgp_orig;
2163
0
  else if (src_bgp)
2164
0
    src_vrf = src_bgp;
2165
0
  else
2166
0
    src_vrf = from_bgp;
2167
2168
  /* Check for intersection of route targets */
2169
0
  if (!ecommunity_include(
2170
0
        to_bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
2171
0
        bgp_attr_get_ecommunity(path_vpn->attr))) {
2172
0
    if (debug)
2173
0
      zlog_debug(
2174
0
        "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
2175
0
        from_bgp->name_pretty, to_bgp->name_pretty);
2176
0
    return false;
2177
0
  }
2178
2179
0
  rd_buf[0] = '\0';
2180
0
  if (debug && prd)
2181
0
    prefix_rd2str(prd, rd_buf, sizeof(rd_buf), to_bgp->asnotation);
2182
2183
  /* A route MUST NOT ever be accepted back into its source VRF, even if
2184
   * it carries one or more RTs that match that VRF.
2185
   */
2186
0
  if (CHECK_FLAG(path_vpn->flags, BGP_PATH_ACCEPT_OWN) && prd &&
2187
0
      memcmp(&prd->val, &to_bgp->vpn_policy[afi].tovpn_rd.val,
2188
0
       ECOMMUNITY_SIZE) == 0) {
2189
0
    if (debug)
2190
0
      zlog_debug(
2191
0
        "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
2192
0
        __func__, rd_buf, to_bgp->name_pretty, p);
2193
0
    return false;
2194
0
  }
2195
2196
0
  if (debug)
2197
0
    zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
2198
0
         p, to_bgp->name_pretty);
2199
2200
  /* shallow copy */
2201
0
  static_attr = *path_vpn->attr;
2202
2203
0
  struct ecommunity *old_ecom;
2204
0
  struct ecommunity *new_ecom;
2205
2206
  /* If doing VRF-to-VRF leaking, strip RTs. */
2207
0
  old_ecom = bgp_attr_get_ecommunity(&static_attr);
2208
0
  if (old_ecom && CHECK_FLAG(to_bgp->af_flags[afi][safi],
2209
0
           BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2210
0
    new_ecom = ecommunity_dup(old_ecom);
2211
0
    ecommunity_strip_rts(new_ecom);
2212
0
    bgp_attr_set_ecommunity(&static_attr, new_ecom);
2213
2214
0
    if (new_ecom->size == 0) {
2215
0
      ecommunity_free(&new_ecom);
2216
0
      bgp_attr_set_ecommunity(&static_attr, NULL);
2217
0
    }
2218
2219
0
    if (!old_ecom->refcnt)
2220
0
      ecommunity_free(&old_ecom);
2221
0
  }
2222
2223
0
  community_strip_accept_own(&static_attr);
2224
2225
  /*
2226
   * Nexthop: stash and clear
2227
   *
2228
   * Nexthop is valid in context of VPN core, but not in destination vrf.
2229
   * Stash it for later label resolution by vrf ingress path and then
2230
   * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
2231
   */
2232
0
  uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
2233
2234
0
  memset(&nexthop_orig, 0, sizeof(nexthop_orig));
2235
0
  nexthop_orig.family = nhfamily;
2236
2237
  /* If the path has accept-own community and the source VRF
2238
   * is valid, reset next-hop to self, to allow importing own
2239
   * routes between different VRFs on the same node.
2240
   * Set the nh ifindex to VRF's interface, not the real interface.
2241
   * Let the kernel to decide with double lookup the real next-hop
2242
   * interface when installing the route.
2243
   */
2244
0
  if (src_bgp) {
2245
0
    subgroup_announce_reset_nhop(nhfamily, &static_attr);
2246
0
    ifp = if_get_vrf_loopback(src_vrf->vrf_id);
2247
0
    if (ifp)
2248
0
      static_attr.nh_ifindex = ifp->ifindex;
2249
0
  }
2250
2251
0
  switch (nhfamily) {
2252
0
  case AF_INET:
2253
    /* save */
2254
0
    nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
2255
0
    nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
2256
2257
0
    if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
2258
0
             BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2259
0
      static_attr.nexthop.s_addr =
2260
0
        nexthop_orig.u.prefix4.s_addr;
2261
2262
0
      static_attr.mp_nexthop_global_in =
2263
0
        path_vpn->attr->mp_nexthop_global_in;
2264
0
      static_attr.mp_nexthop_len =
2265
0
        path_vpn->attr->mp_nexthop_len;
2266
0
    }
2267
0
    static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
2268
0
    break;
2269
0
  case AF_INET6:
2270
    /* save */
2271
0
    nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
2272
0
    nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
2273
2274
0
    if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
2275
0
             BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2276
0
      static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
2277
0
    }
2278
0
    break;
2279
0
  }
2280
2281
  /*
2282
   * route map handling
2283
   */
2284
0
  if (to_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
2285
0
    struct bgp_path_info info;
2286
0
    route_map_result_t ret;
2287
2288
0
    memset(&info, 0, sizeof(info));
2289
0
    info.peer = to_bgp->peer_self;
2290
0
    info.attr = &static_attr;
2291
0
    info.extra = path_vpn->extra; /* Used for source-vrf filter */
2292
0
    ret = route_map_apply(to_bgp->vpn_policy[afi]
2293
0
                .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
2294
0
              p, &info);
2295
0
    if (RMAP_DENYMATCH == ret) {
2296
0
      bgp_attr_flush(&static_attr); /* free any added parts */
2297
0
      if (debug)
2298
0
        zlog_debug(
2299
0
          "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2300
0
          __func__, to_bgp->name_pretty,
2301
0
          to_bgp->vpn_policy[afi]
2302
0
            .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
2303
0
            ->name);
2304
0
      return false;
2305
0
    }
2306
    /*
2307
     * if route-map changed nexthop, don't nexthop-self on output
2308
     */
2309
0
    if (!CHECK_FLAG(static_attr.rmap_change_flags,
2310
0
            BATTR_RMAP_NEXTHOP_UNCHANGED))
2311
0
      nexthop_self_flag = 0;
2312
0
  }
2313
2314
0
  new_attr = bgp_attr_intern(&static_attr);
2315
0
  bgp_attr_flush(&static_attr);
2316
2317
0
  bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
2318
2319
  /*
2320
   * ensure labels are copied
2321
   *
2322
   * However, there is a special case: if the route originated in
2323
   * another local VRF (as opposed to arriving via VPN), then the
2324
   * nexthop is reached by hairpinning through this router (me)
2325
   * using IP forwarding only (no LSP). Therefore, the route
2326
   * imported to the VRF should not have labels attached. Note
2327
   * that nexthop tracking is also involved: eliminating the
2328
   * labels for these routes enables the non-labeled nexthops
2329
   * from the originating VRF to be considered valid for this route.
2330
   */
2331
0
  if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
2332
0
      BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2333
    /* work back to original route */
2334
0
    bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
2335
2336
    /*
2337
     * if original route was unicast,
2338
     * then it did not arrive over vpn
2339
     */
2340
0
    if (bpi_ultimate->net) {
2341
0
      struct bgp_table *table;
2342
2343
0
      table = bgp_dest_table(bpi_ultimate->net);
2344
0
      if (table && (table->safi == SAFI_UNICAST))
2345
0
        origin_local = 1;
2346
0
    }
2347
2348
    /* copy labels */
2349
0
    if (!origin_local && path_vpn->extra
2350
0
        && path_vpn->extra->num_labels) {
2351
0
      num_labels = path_vpn->extra->num_labels;
2352
0
      if (num_labels > BGP_MAX_LABELS)
2353
0
        num_labels = BGP_MAX_LABELS;
2354
0
      pLabels = path_vpn->extra->label;
2355
0
    }
2356
0
  }
2357
2358
0
  if (debug)
2359
0
    zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
2360
0
         path_vpn->net, num_labels);
2361
2362
0
  if (!leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels,
2363
0
       num_labels, src_vrf, &nexthop_orig, nexthop_self_flag,
2364
0
       debug))
2365
0
    bgp_dest_unlock_node(bn);
2366
2367
0
  return true;
2368
0
}
2369
2370
bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
2371
          struct bgp_path_info *path_vpn,
2372
          struct prefix_rd *prd)
2373
0
{
2374
0
  struct listnode *mnode, *mnnode;
2375
0
  struct bgp *bgp;
2376
0
  bool leak_success = false;
2377
2378
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2379
2380
0
  if (debug)
2381
0
    zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2382
2383
  /* Loop over VRFs */
2384
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2385
2386
0
    if (!path_vpn->extra
2387
0
        || path_vpn->extra->bgp_orig != bgp) { /* no loop */
2388
0
      leak_success |= vpn_leak_to_vrf_update_onevrf(
2389
0
        bgp, from_bgp, path_vpn, prd);
2390
0
    }
2391
0
  }
2392
0
  return leak_success;
2393
0
}
2394
2395
void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn)
2396
0
{
2397
0
  const struct prefix *p;
2398
0
  afi_t afi;
2399
0
  safi_t safi = SAFI_UNICAST;
2400
0
  struct bgp *bgp;
2401
0
  struct listnode *mnode, *mnnode;
2402
0
  struct bgp_dest *bn;
2403
0
  struct bgp_path_info *bpi;
2404
0
  const char *debugmsg;
2405
2406
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2407
2408
0
  if (debug)
2409
0
    zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
2410
0
         path_vpn->net, path_vpn->type, path_vpn->sub_type);
2411
2412
0
  if (debug)
2413
0
    zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2414
2415
0
  if (!path_vpn->net) {
2416
0
#ifdef ENABLE_BGP_VNC
2417
    /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2418
0
    if (path_vpn->type == ZEBRA_ROUTE_BGP
2419
0
        && path_vpn->sub_type == BGP_ROUTE_RFP) {
2420
2421
0
      return;
2422
0
    }
2423
0
#endif
2424
0
    if (debug)
2425
0
      zlog_debug(
2426
0
        "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2427
0
        __func__);
2428
0
    return;
2429
0
  }
2430
2431
0
  p = bgp_dest_get_prefix(path_vpn->net);
2432
0
  afi = family2afi(p->family);
2433
2434
  /* Loop over VRFs */
2435
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2436
0
    if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
2437
0
      if (debug)
2438
0
        zlog_debug("%s: from %s, skipping: %s",
2439
0
             __func__, bgp->name_pretty,
2440
0
             debugmsg);
2441
0
      continue;
2442
0
    }
2443
2444
    /* Check for intersection of route targets */
2445
0
    if (!ecommunity_include(
2446
0
          bgp->vpn_policy[afi]
2447
0
            .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
2448
0
          bgp_attr_get_ecommunity(path_vpn->attr))) {
2449
2450
0
      continue;
2451
0
    }
2452
2453
0
    if (debug)
2454
0
      zlog_debug("%s: withdrawing from vrf %s", __func__,
2455
0
           bgp->name_pretty);
2456
2457
0
    bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
2458
2459
0
    for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2460
0
         bpi = bpi->next) {
2461
0
      if (bpi->extra
2462
0
          && (struct bgp_path_info *)bpi->extra->parent
2463
0
               == path_vpn) {
2464
0
        break;
2465
0
      }
2466
0
    }
2467
2468
0
    if (bpi) {
2469
0
      if (debug)
2470
0
        zlog_debug("%s: deleting bpi %p", __func__,
2471
0
             bpi);
2472
0
      bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
2473
0
      bgp_path_info_delete(bn, bpi);
2474
0
      bgp_process(bgp, bn, afi, safi);
2475
0
    }
2476
0
    bgp_dest_unlock_node(bn);
2477
0
  }
2478
0
}
2479
2480
void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)
2481
0
{
2482
0
  struct bgp_dest *bn;
2483
0
  struct bgp_path_info *bpi;
2484
0
  safi_t safi = SAFI_UNICAST;
2485
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2486
2487
0
  if (debug)
2488
0
    zlog_debug("%s: entry", __func__);
2489
  /*
2490
   * Walk vrf table, delete bpi with bgp_orig in a different vrf
2491
   */
2492
0
  for (bn = bgp_table_top(to_bgp->rib[afi][safi]); bn;
2493
0
       bn = bgp_route_next(bn)) {
2494
2495
0
    for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2496
0
         bpi = bpi->next) {
2497
0
      if (bpi->extra && bpi->extra->bgp_orig != to_bgp &&
2498
0
          bpi->extra->parent &&
2499
0
          is_pi_family_vpn(bpi->extra->parent)) {
2500
2501
        /* delete route */
2502
0
        bgp_aggregate_decrement(to_bgp,
2503
0
              bgp_dest_get_prefix(bn),
2504
0
              bpi, afi, safi);
2505
0
        bgp_path_info_delete(bn, bpi);
2506
0
        bgp_process(to_bgp, bn, afi, safi);
2507
0
      }
2508
0
    }
2509
0
  }
2510
0
}
2511
2512
void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,
2513
        afi_t afi)
2514
0
{
2515
0
  struct bgp_dest *pdest;
2516
0
  safi_t safi = SAFI_MPLS_VPN;
2517
2518
0
  assert(vpn_from);
2519
2520
  /*
2521
   * Walk vpn table
2522
   */
2523
0
  for (pdest = bgp_table_top(vpn_from->rib[afi][safi]); pdest;
2524
0
       pdest = bgp_route_next(pdest)) {
2525
0
    struct bgp_table *table;
2526
0
    struct bgp_dest *bn;
2527
0
    struct bgp_path_info *bpi;
2528
2529
    /* This is the per-RD table of prefixes */
2530
0
    table = bgp_dest_get_bgp_table_info(pdest);
2531
2532
0
    if (!table)
2533
0
      continue;
2534
2535
0
    for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
2536
2537
0
      for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2538
0
           bpi = bpi->next) {
2539
2540
0
        if (bpi->extra &&
2541
0
            bpi->extra->bgp_orig == to_bgp)
2542
0
          continue;
2543
2544
0
        vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
2545
0
                    bpi, NULL);
2546
0
      }
2547
0
    }
2548
0
  }
2549
0
}
2550
2551
/*
2552
 * This function is called for definition/deletion/change to a route-map
2553
 */
2554
static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
2555
0
{
2556
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2557
0
  afi_t afi;
2558
0
  struct route_map *rmap;
2559
2560
0
  if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2561
0
      && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
2562
2563
0
    return;
2564
0
  }
2565
2566
0
  rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
2567
2568
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
2569
2570
0
    if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
2571
0
      && !strcmp(rmap_name,
2572
0
             bgp->vpn_policy[afi]
2573
0
               .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
2574
2575
0
      if (debug)
2576
0
        zlog_debug(
2577
0
          "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2578
0
          __func__, rmap_name, bgp->as,
2579
0
          afi2str(afi));
2580
2581
0
      vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2582
0
             bgp_get_default(), bgp);
2583
0
      if (debug)
2584
0
        zlog_debug("%s: after vpn_leak_prechange",
2585
0
             __func__);
2586
2587
      /* in case of definition/deletion */
2588
0
      bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
2589
0
        rmap;
2590
2591
0
      vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2592
0
              bgp_get_default(), bgp);
2593
2594
0
      if (debug)
2595
0
        zlog_debug("%s: after vpn_leak_postchange",
2596
0
             __func__);
2597
0
    }
2598
2599
0
    if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
2600
0
      && !strcmp(rmap_name,
2601
0
        bgp->vpn_policy[afi]
2602
0
        .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]))  {
2603
2604
0
      if (debug) {
2605
0
        zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2606
0
          __func__, rmap_name, bgp->as,
2607
0
          afi2str(afi));
2608
0
      }
2609
2610
0
      vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2611
0
             bgp_get_default(), bgp);
2612
2613
      /* in case of definition/deletion */
2614
0
      bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
2615
0
          rmap;
2616
2617
0
      vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2618
0
              bgp_get_default(), bgp);
2619
0
    }
2620
0
  }
2621
0
}
2622
2623
/* This API is used during router-id change, reflect VPNs
2624
 * auto RD and RT values and readvertise routes to VPN table.
2625
 */
2626
void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
2627
         bool is_config)
2628
0
{
2629
0
  afi_t afi;
2630
0
  int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
2631
0
         | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2632
0
  char *vname;
2633
0
  const char *export_name;
2634
0
  char buf[RD_ADDRSTRLEN];
2635
0
  struct bgp *bgp_import;
2636
0
  struct listnode *node;
2637
0
  struct ecommunity *ecom;
2638
0
  enum vpn_policy_direction idir, edir;
2639
2640
  /*
2641
   * Router-id change that is not explicitly configured
2642
   * (a change from zebra, frr restart for example)
2643
   * should not replace a configured vpn RD/RT.
2644
   */
2645
0
  if (!is_config) {
2646
0
    if (debug)
2647
0
      zlog_debug("%s: skipping non explicit router-id change",
2648
0
           __func__);
2649
0
    return;
2650
0
  }
2651
2652
0
  if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2653
0
      && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2654
0
    return;
2655
2656
0
  export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
2657
0
  idir = BGP_VPN_POLICY_DIR_FROMVPN;
2658
0
  edir = BGP_VPN_POLICY_DIR_TOVPN;
2659
2660
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
2661
0
    if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
2662
0
      continue;
2663
2664
0
    if (withdraw) {
2665
0
      vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
2666
0
             afi, bgp_get_default(), bgp);
2667
0
      if (debug)
2668
0
        zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2669
0
             __func__, export_name);
2670
2671
      /* Remove import RT from VRFs */
2672
0
      ecom = bgp->vpn_policy[afi].rtlist[edir];
2673
0
      for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2674
0
              export_vrf, node, vname)) {
2675
0
        if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2676
0
          bgp_import = bgp_get_default();
2677
0
        else
2678
0
          bgp_import = bgp_lookup_by_name(vname);
2679
0
        if (!bgp_import)
2680
0
          continue;
2681
2682
0
        ecommunity_del_val(
2683
0
          bgp_import->vpn_policy[afi]
2684
0
            .rtlist[idir],
2685
0
          (struct ecommunity_val *)ecom->val);
2686
0
      }
2687
0
    } else {
2688
      /* New router-id derive auto RD and RT and export
2689
       * to VPN
2690
       */
2691
0
      form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
2692
0
             &bgp->vrf_prd_auto);
2693
0
      bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
2694
0
      prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
2695
0
              sizeof(buf), bgp->asnotation);
2696
2697
      /* free up pre-existing memory if any and allocate
2698
       *  the ecommunity attribute with new RD/RT
2699
       */
2700
0
      if (bgp->vpn_policy[afi].rtlist[edir])
2701
0
        ecommunity_free(
2702
0
          &bgp->vpn_policy[afi].rtlist[edir]);
2703
0
      bgp->vpn_policy[afi].rtlist[edir] = ecommunity_str2com(
2704
0
        buf, ECOMMUNITY_ROUTE_TARGET, 0);
2705
2706
      /* Update import_vrf rt_list */
2707
0
      ecom = bgp->vpn_policy[afi].rtlist[edir];
2708
0
      for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2709
0
              export_vrf, node, vname)) {
2710
0
        if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2711
0
          bgp_import = bgp_get_default();
2712
0
        else
2713
0
          bgp_import = bgp_lookup_by_name(vname);
2714
0
        if (!bgp_import)
2715
0
          continue;
2716
0
        if (bgp_import->vpn_policy[afi].rtlist[idir])
2717
0
          bgp_import->vpn_policy[afi].rtlist[idir]
2718
0
            = ecommunity_merge(
2719
0
            bgp_import->vpn_policy[afi]
2720
0
            .rtlist[idir], ecom);
2721
0
        else
2722
0
          bgp_import->vpn_policy[afi].rtlist[idir]
2723
0
            = ecommunity_dup(ecom);
2724
0
      }
2725
2726
      /* Update routes to VPN */
2727
0
      vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
2728
0
              afi, bgp_get_default(),
2729
0
              bgp);
2730
0
      if (debug)
2731
0
        zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2732
0
             __func__, export_name);
2733
0
    }
2734
0
  }
2735
0
}
2736
2737
void vpn_policy_routemap_event(const char *rmap_name)
2738
0
{
2739
0
  int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2740
0
  struct listnode *mnode, *mnnode;
2741
0
  struct bgp *bgp;
2742
2743
0
  if (debug)
2744
0
    zlog_debug("%s: entry", __func__);
2745
2746
0
  if (bm->bgp == NULL) /* may be called during cleanup */
2747
0
    return;
2748
2749
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
2750
0
    vpn_policy_routemap_update(bgp, rmap_name);
2751
0
}
2752
2753
void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2754
       afi_t afi, safi_t safi)
2755
0
{
2756
0
  const char *export_name;
2757
0
  enum vpn_policy_direction idir, edir;
2758
0
  char *vname, *tmp_name;
2759
0
  char buf[RD_ADDRSTRLEN];
2760
0
  struct ecommunity *ecom;
2761
0
  bool first_export = false;
2762
0
  int debug;
2763
0
  struct listnode *node;
2764
0
  bool is_inst_match = false;
2765
2766
0
  export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2767
0
  idir = BGP_VPN_POLICY_DIR_FROMVPN;
2768
0
  edir = BGP_VPN_POLICY_DIR_TOVPN;
2769
2770
0
  debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2771
0
         BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2772
2773
  /*
2774
   * Cross-ref both VRFs. Also, note if this is the first time
2775
   * any VRF is importing from "import_vrf".
2776
   */
2777
0
  vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
2778
0
             : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
2779
2780
  /* Check the import_vrf list of destination vrf for the source vrf name,
2781
   * insert otherwise.
2782
   */
2783
0
  for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
2784
0
          node, tmp_name)) {
2785
0
    if (strcmp(vname, tmp_name) == 0) {
2786
0
      is_inst_match = true;
2787
0
      break;
2788
0
    }
2789
0
  }
2790
0
  if (!is_inst_match)
2791
0
    listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2792
0
             vname);
2793
0
  else
2794
0
    XFREE(MTYPE_TMP, vname);
2795
2796
  /* Check if the source vrf already exports to any vrf,
2797
   * first time export requires to setup auto derived RD/RT values.
2798
   * Add the destination vrf name to export vrf list if it is
2799
   * not present.
2800
   */
2801
0
  is_inst_match = false;
2802
0
  vname = XSTRDUP(MTYPE_TMP, export_name);
2803
0
  if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2804
0
    first_export = true;
2805
0
  } else {
2806
0
    for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2807
0
            node, tmp_name)) {
2808
0
      if (strcmp(vname, tmp_name) == 0) {
2809
0
        is_inst_match = true;
2810
0
        break;
2811
0
      }
2812
0
    }
2813
0
  }
2814
0
  if (!is_inst_match)
2815
0
    listnode_add(from_bgp->vpn_policy[afi].export_vrf,
2816
0
           vname);
2817
0
  else
2818
0
    XFREE(MTYPE_TMP, vname);
2819
2820
  /* Update import RT for current VRF using export RT of the VRF we're
2821
   * importing from. First though, make sure "import_vrf" has that
2822
   * set.
2823
   */
2824
0
  if (first_export) {
2825
0
    form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
2826
0
           &from_bgp->vrf_prd_auto);
2827
0
    from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
2828
0
    SET_FLAG(from_bgp->vpn_policy[afi].flags,
2829
0
       BGP_VPN_POLICY_TOVPN_RD_SET);
2830
0
    prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd, buf,
2831
0
            sizeof(buf), from_bgp->asnotation);
2832
0
    from_bgp->vpn_policy[afi].rtlist[edir] =
2833
0
      ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
2834
0
    SET_FLAG(from_bgp->af_flags[afi][safi],
2835
0
       BGP_CONFIG_VRF_TO_VRF_EXPORT);
2836
0
    from_bgp->vpn_policy[afi].tovpn_label =
2837
0
      BGP_PREVENT_VRF_2_VRF_LEAK;
2838
0
  }
2839
0
  ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2840
0
  if (to_bgp->vpn_policy[afi].rtlist[idir])
2841
0
    to_bgp->vpn_policy[afi].rtlist[idir] =
2842
0
      ecommunity_merge(to_bgp->vpn_policy[afi]
2843
0
           .rtlist[idir], ecom);
2844
0
  else
2845
0
    to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
2846
0
  SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
2847
2848
0
  if (debug) {
2849
0
    const char *from_name;
2850
0
    char *ecom1, *ecom2;
2851
2852
0
    from_name = from_bgp->name ? from_bgp->name :
2853
0
      VRF_DEFAULT_NAME;
2854
2855
0
    ecom1 = ecommunity_ecom2str(
2856
0
      to_bgp->vpn_policy[afi].rtlist[idir],
2857
0
      ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2858
2859
0
    ecom2 = ecommunity_ecom2str(
2860
0
      to_bgp->vpn_policy[afi].rtlist[edir],
2861
0
      ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2862
2863
0
    zlog_debug(
2864
0
      "%s from %s to %s first_export %u import-rt %s export-rt %s",
2865
0
      __func__, from_name, export_name, first_export, ecom1,
2866
0
      ecom2);
2867
2868
0
    ecommunity_strfree(&ecom1);
2869
0
    ecommunity_strfree(&ecom2);
2870
0
  }
2871
2872
  /* Does "import_vrf" first need to export its routes or that
2873
   * is already done and we just need to import those routes
2874
   * from the global table?
2875
   */
2876
0
  if (first_export)
2877
0
    vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
2878
0
  else
2879
0
    vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2880
0
}
2881
2882
void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2883
         afi_t afi, safi_t safi)
2884
0
{
2885
0
  const char *export_name, *tmp_name;
2886
0
  enum vpn_policy_direction idir, edir;
2887
0
  char *vname;
2888
0
  struct ecommunity *ecom = NULL;
2889
0
  struct listnode *node;
2890
0
  int debug;
2891
2892
0
  export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2893
0
  tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
2894
0
  idir = BGP_VPN_POLICY_DIR_FROMVPN;
2895
0
  edir = BGP_VPN_POLICY_DIR_TOVPN;
2896
2897
0
  debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2898
0
         BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2899
2900
  /* Were we importing from "import_vrf"? */
2901
0
  for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
2902
0
          vname)) {
2903
0
    if (strcmp(vname, tmp_name) == 0)
2904
0
      break;
2905
0
  }
2906
2907
  /*
2908
   * We do not check in the cli if the passed in bgp
2909
   * instance is actually imported into us before
2910
   * we call this function.  As such if we do not
2911
   * find this in the import_vrf list than
2912
   * we just need to return safely.
2913
   */
2914
0
  if (!vname)
2915
0
    return;
2916
2917
0
  if (debug)
2918
0
    zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
2919
2920
  /* Remove "import_vrf" from our import list. */
2921
0
  listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
2922
0
  XFREE(MTYPE_TMP, vname);
2923
2924
  /* Remove routes imported from "import_vrf". */
2925
  /* TODO: In the current logic, we have to first remove all
2926
   * imported routes and then (if needed) import back routes
2927
   */
2928
0
  vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
2929
2930
0
  if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
2931
0
    if (!to_bgp->vpn_policy[afi].rmap[idir])
2932
0
      UNSET_FLAG(to_bgp->af_flags[afi][safi],
2933
0
           BGP_CONFIG_VRF_TO_VRF_IMPORT);
2934
0
    if (to_bgp->vpn_policy[afi].rtlist[idir])
2935
0
      ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
2936
0
  } else {
2937
0
    ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2938
0
    if (ecom)
2939
0
      ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
2940
0
           (struct ecommunity_val *)ecom->val);
2941
0
    vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2942
0
  }
2943
2944
  /*
2945
   * What?
2946
   * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2947
   * below is checking for NULL that export_vrf can be
2948
   * NULL, consequently it is complaining( like a cabbage )
2949
   * that we could dereference and crash in the listcount(..)
2950
   * check below.
2951
   * So make it happy, under protest, with liberty and justice
2952
   * for all.
2953
   */
2954
0
  assert(from_bgp->vpn_policy[afi].export_vrf);
2955
2956
  /* Remove us from "import_vrf's" export list. If no other VRF
2957
   * is importing from "import_vrf", cleanup appropriately.
2958
   */
2959
0
  for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2960
0
          node, vname)) {
2961
0
    if (strcmp(vname, export_name) == 0)
2962
0
      break;
2963
0
  }
2964
2965
  /*
2966
   * If we have gotten to this point then the vname must
2967
   * exist.  If not, we are in a world of trouble and
2968
   * have slag sitting around.
2969
   *
2970
   * import_vrf and export_vrf must match in having
2971
   * the in/out names as appropriate.
2972
   * export_vrf list could have been cleaned up
2973
   * as part of no router bgp source instnace.
2974
   */
2975
0
  if (!vname)
2976
0
    return;
2977
2978
0
  listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
2979
0
  XFREE(MTYPE_TMP, vname);
2980
2981
0
  if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2982
0
    vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
2983
0
    ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
2984
0
    UNSET_FLAG(from_bgp->af_flags[afi][safi],
2985
0
         BGP_CONFIG_VRF_TO_VRF_EXPORT);
2986
0
    memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
2987
0
           sizeof(struct prefix_rd));
2988
0
    UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
2989
0
         BGP_VPN_POLICY_TOVPN_RD_SET);
2990
0
    from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2991
2992
0
  }
2993
0
}
2994
2995
/* For testing purpose, static route of MPLS-VPN. */
2996
DEFUN (vpnv4_network,
2997
       vpnv4_network_cmd,
2998
       "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2999
       "Specify a network to announce via BGP\n"
3000
       "IPv4 prefix\n"
3001
       "Specify Route Distinguisher\n"
3002
       "VPN Route Distinguisher\n"
3003
       "VPN NLRI label (tag)\n"
3004
       "VPN NLRI label (tag)\n"
3005
       "Label value\n")
3006
0
{
3007
0
  int idx_ipv4_prefixlen = 1;
3008
0
  int idx_ext_community = 3;
3009
0
  int idx_label = 5;
3010
0
  return bgp_static_set_safi(
3011
0
    AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
3012
0
    argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
3013
0
    NULL, NULL, NULL, NULL);
3014
0
}
3015
3016
DEFUN (vpnv4_network_route_map,
3017
       vpnv4_network_route_map_cmd,
3018
       "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
3019
       "Specify a network to announce via BGP\n"
3020
       "IPv4 prefix\n"
3021
       "Specify Route Distinguisher\n"
3022
       "VPN Route Distinguisher\n"
3023
       "VPN NLRI label (tag)\n"
3024
       "VPN NLRI label (tag)\n"
3025
       "Label value\n"
3026
       "route map\n"
3027
       "route map name\n")
3028
0
{
3029
0
  int idx_ipv4_prefixlen = 1;
3030
0
  int idx_ext_community = 3;
3031
0
  int idx_label = 5;
3032
0
  int idx_word_2 = 7;
3033
0
  return bgp_static_set_safi(
3034
0
    AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
3035
0
    argv[idx_ext_community]->arg, argv[idx_label]->arg,
3036
0
    argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
3037
0
}
3038
3039
/* For testing purpose, static route of MPLS-VPN. */
3040
DEFUN (no_vpnv4_network,
3041
       no_vpnv4_network_cmd,
3042
       "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3043
       NO_STR
3044
       "Specify a network to announce via BGP\n"
3045
       "IPv4 prefix\n"
3046
       "Specify Route Distinguisher\n"
3047
       "VPN Route Distinguisher\n"
3048
       "VPN NLRI label (tag)\n"
3049
       "VPN NLRI label (tag)\n"
3050
       "Label value\n")
3051
0
{
3052
0
  int idx_ipv4_prefixlen = 2;
3053
0
  int idx_ext_community = 4;
3054
0
  int idx_label = 6;
3055
0
  return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
3056
0
             argv[idx_ipv4_prefixlen]->arg,
3057
0
             argv[idx_ext_community]->arg,
3058
0
             argv[idx_label]->arg, 0, NULL, NULL, NULL);
3059
0
}
3060
3061
DEFUN (vpnv6_network,
3062
       vpnv6_network_cmd,
3063
       "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
3064
       "Specify a network to announce via BGP\n"
3065
       "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3066
       "Specify Route Distinguisher\n"
3067
       "VPN Route Distinguisher\n"
3068
       "VPN NLRI label (tag)\n"
3069
       "VPN NLRI label (tag)\n"
3070
       "Label value\n"
3071
       "route map\n"
3072
       "route map name\n")
3073
0
{
3074
0
  int idx_ipv6_prefix = 1;
3075
0
  int idx_ext_community = 3;
3076
0
  int idx_label = 5;
3077
0
  int idx_word_2 = 7;
3078
0
  if (argc == 8)
3079
0
    return bgp_static_set_safi(
3080
0
      AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
3081
0
      argv[idx_ext_community]->arg, argv[idx_label]->arg,
3082
0
      argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
3083
0
  else
3084
0
    return bgp_static_set_safi(
3085
0
      AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
3086
0
      argv[idx_ext_community]->arg, argv[idx_label]->arg,
3087
0
      NULL, 0, NULL, NULL, NULL, NULL);
3088
0
}
3089
3090
/* For testing purpose, static route of MPLS-VPN. */
3091
DEFUN (no_vpnv6_network,
3092
       no_vpnv6_network_cmd,
3093
       "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3094
       NO_STR
3095
       "Specify a network to announce via BGP\n"
3096
       "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3097
       "Specify Route Distinguisher\n"
3098
       "VPN Route Distinguisher\n"
3099
       "VPN NLRI label (tag)\n"
3100
       "VPN NLRI label (tag)\n"
3101
       "Label value\n")
3102
0
{
3103
0
  int idx_ipv6_prefix = 2;
3104
0
  int idx_ext_community = 4;
3105
0
  int idx_label = 6;
3106
0
  return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
3107
0
             argv[idx_ipv6_prefix]->arg,
3108
0
             argv[idx_ext_community]->arg,
3109
0
             argv[idx_label]->arg, 0, NULL, NULL, NULL);
3110
0
}
3111
3112
int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
3113
          enum bgp_show_type type, void *output_arg, int tags,
3114
          bool use_json)
3115
0
{
3116
0
  struct bgp *bgp;
3117
0
  struct bgp_table *table;
3118
0
  uint16_t show_flags = 0;
3119
3120
0
  if (use_json)
3121
0
    SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
3122
3123
0
  bgp = bgp_get_default();
3124
0
  if (bgp == NULL) {
3125
0
    if (!use_json)
3126
0
      vty_out(vty, "No BGP process is configured\n");
3127
0
    else
3128
0
      vty_out(vty, "{}\n");
3129
0
    return CMD_WARNING;
3130
0
  }
3131
0
  table = bgp->rib[afi][SAFI_MPLS_VPN];
3132
0
  return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
3133
0
         output_arg, show_flags);
3134
0
}
3135
3136
DEFUN (show_bgp_ip_vpn_all_rd,
3137
       show_bgp_ip_vpn_all_rd_cmd,
3138
       "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
3139
       SHOW_STR
3140
       BGP_STR
3141
       BGP_VPNVX_HELP_STR
3142
       "Display VPN NLRI specific information\n"
3143
       "Display VPN NLRI specific information\n"
3144
       "Display information for a route distinguisher\n"
3145
       "VPN Route Distinguisher\n"
3146
       "All VPN Route Distinguishers\n"
3147
       JSON_STR)
3148
0
{
3149
0
  int ret;
3150
0
  struct prefix_rd prd;
3151
0
  afi_t afi;
3152
0
  int idx = 0;
3153
3154
0
  if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3155
    /* Constrain search if user supplies RD && RD != "all" */
3156
0
    if (argv_find(argv, argc, "rd", &idx)
3157
0
        && strcmp(argv[idx + 1]->arg, "all")) {
3158
0
      ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
3159
0
      if (!ret) {
3160
0
        vty_out(vty,
3161
0
          "%% Malformed Route Distinguisher\n");
3162
0
        return CMD_WARNING;
3163
0
      }
3164
0
      return bgp_show_mpls_vpn(vty, afi, &prd,
3165
0
             bgp_show_type_normal, NULL, 0,
3166
0
             use_json(argc, argv));
3167
0
    } else {
3168
0
      return bgp_show_mpls_vpn(vty, afi, NULL,
3169
0
             bgp_show_type_normal, NULL, 0,
3170
0
             use_json(argc, argv));
3171
0
    }
3172
0
  }
3173
0
  return CMD_SUCCESS;
3174
0
}
3175
3176
ALIAS(show_bgp_ip_vpn_all_rd,
3177
      show_bgp_ip_vpn_rd_cmd,
3178
       "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
3179
       SHOW_STR
3180
       BGP_STR
3181
       BGP_VPNVX_HELP_STR
3182
       "Display VPN NLRI specific information\n"
3183
       "Display information for a route distinguisher\n"
3184
       "VPN Route Distinguisher\n"
3185
       "All VPN Route Distinguishers\n"
3186
       JSON_STR)
3187
3188
#ifdef KEEP_OLD_VPN_COMMANDS
3189
DEFUN (show_ip_bgp_vpn_rd,
3190
       show_ip_bgp_vpn_rd_cmd,
3191
       "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
3192
       SHOW_STR
3193
       IP_STR
3194
       BGP_STR
3195
       BGP_AFI_HELP_STR
3196
       BGP_AF_MODIFIER_STR
3197
       "Display information for a route distinguisher\n"
3198
       "VPN Route Distinguisher\n"
3199
       "All VPN Route Distinguishers\n")
3200
{
3201
  int idx_ext_community = argc - 1;
3202
  int ret;
3203
  struct prefix_rd prd;
3204
  afi_t afi;
3205
  int idx = 0;
3206
3207
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3208
    if (!strcmp(argv[idx_ext_community]->arg, "all"))
3209
      return bgp_show_mpls_vpn(vty, afi, NULL,
3210
             bgp_show_type_normal, NULL, 0,
3211
             0);
3212
    ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3213
    if (!ret) {
3214
      vty_out(vty, "%% Malformed Route Distinguisher\n");
3215
      return CMD_WARNING;
3216
    }
3217
    return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
3218
           NULL, 0, 0);
3219
  }
3220
  return CMD_SUCCESS;
3221
}
3222
3223
DEFUN (show_ip_bgp_vpn_all,
3224
       show_ip_bgp_vpn_all_cmd,
3225
       "show [ip] bgp <vpnv4|vpnv6>",
3226
       SHOW_STR
3227
       IP_STR
3228
       BGP_STR
3229
       BGP_VPNVX_HELP_STR)
3230
{
3231
  afi_t afi;
3232
  int idx = 0;
3233
3234
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
3235
    return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
3236
           NULL, 0, 0);
3237
  return CMD_SUCCESS;
3238
}
3239
3240
DEFUN (show_ip_bgp_vpn_all_tags,
3241
       show_ip_bgp_vpn_all_tags_cmd,
3242
       "show [ip] bgp <vpnv4|vpnv6> all tags",
3243
       SHOW_STR
3244
       IP_STR
3245
       BGP_STR
3246
       BGP_VPNVX_HELP_STR
3247
       "Display information about all VPNv4/VPNV6 NLRIs\n"
3248
       "Display BGP tags for prefixes\n")
3249
{
3250
  afi_t afi;
3251
  int idx = 0;
3252
3253
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
3254
    return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
3255
           NULL, 1, 0);
3256
  return CMD_SUCCESS;
3257
}
3258
3259
DEFUN (show_ip_bgp_vpn_rd_tags,
3260
       show_ip_bgp_vpn_rd_tags_cmd,
3261
       "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
3262
       SHOW_STR
3263
       IP_STR
3264
       BGP_STR
3265
       BGP_VPNVX_HELP_STR
3266
       "Display information for a route distinguisher\n"
3267
       "VPN Route Distinguisher\n"
3268
       "All VPN Route Distinguishers\n"
3269
       "Display BGP tags for prefixes\n")
3270
{
3271
  int idx_ext_community = 5;
3272
  int ret;
3273
  struct prefix_rd prd;
3274
  afi_t afi;
3275
  int idx = 0;
3276
3277
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3278
    if (!strcmp(argv[idx_ext_community]->arg, "all"))
3279
      return bgp_show_mpls_vpn(vty, afi, NULL,
3280
             bgp_show_type_normal, NULL, 1,
3281
             0);
3282
    ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3283
    if (!ret) {
3284
      vty_out(vty, "%% Malformed Route Distinguisher\n");
3285
      return CMD_WARNING;
3286
    }
3287
    return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
3288
           NULL, 1, 0);
3289
  }
3290
  return CMD_SUCCESS;
3291
}
3292
3293
DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
3294
       show_ip_bgp_vpn_all_neighbor_routes_cmd,
3295
       "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3296
       SHOW_STR
3297
       IP_STR
3298
       BGP_STR
3299
       BGP_VPNVX_HELP_STR
3300
       "Display information about all VPNv4/VPNv6 NLRIs\n"
3301
       "Detailed information on TCP and BGP neighbor connections\n"
3302
       "Neighbor to display information about\n"
3303
       "Display routes learned from neighbor\n"
3304
       JSON_STR)
3305
{
3306
  int idx_ipv4 = 6;
3307
  union sockunion su;
3308
  struct peer *peer;
3309
  int ret;
3310
  bool uj = use_json(argc, argv);
3311
  afi_t afi;
3312
  int idx = 0;
3313
3314
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3315
    ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3316
    if (ret < 0) {
3317
      if (uj) {
3318
        json_object *json_no = NULL;
3319
        json_no = json_object_new_object();
3320
        json_object_string_add(json_no, "warning",
3321
                   "Malformed address");
3322
        vty_out(vty, "%s\n",
3323
          json_object_to_json_string(json_no));
3324
        json_object_free(json_no);
3325
      } else
3326
        vty_out(vty, "Malformed address: %s\n",
3327
          argv[idx_ipv4]->arg);
3328
      return CMD_WARNING;
3329
    }
3330
3331
    peer = peer_lookup(NULL, &su);
3332
    if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3333
      if (uj) {
3334
        json_object *json_no = NULL;
3335
        json_no = json_object_new_object();
3336
        json_object_string_add(
3337
          json_no, "warning",
3338
          "No such neighbor or address family");
3339
        vty_out(vty, "%s\n",
3340
          json_object_to_json_string(json_no));
3341
        json_object_free(json_no);
3342
      } else
3343
        vty_out(vty,
3344
          "%% No such neighbor or address family\n");
3345
      return CMD_WARNING;
3346
    }
3347
3348
    return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
3349
           &su, 0, uj);
3350
  }
3351
  return CMD_SUCCESS;
3352
}
3353
3354
DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
3355
       show_ip_bgp_vpn_rd_neighbor_routes_cmd,
3356
       "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3357
       SHOW_STR
3358
       IP_STR
3359
       BGP_STR
3360
       BGP_VPNVX_HELP_STR
3361
       "Display information for a route distinguisher\n"
3362
       "VPN Route Distinguisher\n"
3363
       "All VPN Route Distinguishers\n"
3364
       "Detailed information on TCP and BGP neighbor connections\n"
3365
       "Neighbor to display information about\n"
3366
       "Display routes learned from neighbor\n"
3367
       JSON_STR)
3368
{
3369
  int idx_ext_community = 5;
3370
  int idx_ipv4 = 7;
3371
  int ret;
3372
  union sockunion su;
3373
  struct peer *peer;
3374
  struct prefix_rd prd;
3375
  bool prefix_rd_all = false;
3376
  bool uj = use_json(argc, argv);
3377
  afi_t afi;
3378
  int idx = 0;
3379
3380
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3381
    if (!strcmp(argv[idx_ext_community]->arg, "all"))
3382
      prefix_rd_all = true;
3383
    else {
3384
      ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3385
      if (!ret) {
3386
        if (uj) {
3387
          json_object *json_no = NULL;
3388
          json_no = json_object_new_object();
3389
          json_object_string_add(
3390
            json_no, "warning",
3391
            "Malformed Route Distinguisher");
3392
          vty_out(vty, "%s\n",
3393
            json_object_to_json_string(
3394
              json_no));
3395
          json_object_free(json_no);
3396
        } else
3397
          vty_out(vty,
3398
            "%% Malformed Route Distinguisher\n");
3399
        return CMD_WARNING;
3400
      }
3401
    }
3402
3403
    ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3404
    if (ret < 0) {
3405
      if (uj) {
3406
        json_object *json_no = NULL;
3407
        json_no = json_object_new_object();
3408
        json_object_string_add(json_no, "warning",
3409
                   "Malformed address");
3410
        vty_out(vty, "%s\n",
3411
          json_object_to_json_string(json_no));
3412
        json_object_free(json_no);
3413
      } else
3414
        vty_out(vty, "Malformed address: %s\n",
3415
          argv[idx_ext_community]->arg);
3416
      return CMD_WARNING;
3417
    }
3418
3419
    peer = peer_lookup(NULL, &su);
3420
    if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3421
      if (uj) {
3422
        json_object *json_no = NULL;
3423
        json_no = json_object_new_object();
3424
        json_object_string_add(
3425
          json_no, "warning",
3426
          "No such neighbor or address family");
3427
        vty_out(vty, "%s\n",
3428
          json_object_to_json_string(json_no));
3429
        json_object_free(json_no);
3430
      } else
3431
        vty_out(vty,
3432
          "%% No such neighbor or address family\n");
3433
      return CMD_WARNING;
3434
    }
3435
3436
    if (prefix_rd_all)
3437
      return bgp_show_mpls_vpn(vty, afi, NULL,
3438
             bgp_show_type_neighbor, &su, 0,
3439
             uj);
3440
    else
3441
      return bgp_show_mpls_vpn(vty, afi, &prd,
3442
             bgp_show_type_neighbor, &su, 0,
3443
             uj);
3444
  }
3445
  return CMD_SUCCESS;
3446
}
3447
3448
DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
3449
       show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
3450
       "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3451
       SHOW_STR
3452
       IP_STR
3453
       BGP_STR
3454
       BGP_VPNVX_HELP_STR
3455
       "Display information about all VPNv4/VPNv6 NLRIs\n"
3456
       "Detailed information on TCP and BGP neighbor connections\n"
3457
       "Neighbor to display information about\n"
3458
       "Display the routes advertised to a BGP neighbor\n"
3459
       JSON_STR)
3460
{
3461
  int idx_ipv4 = 6;
3462
  int ret;
3463
  struct peer *peer;
3464
  union sockunion su;
3465
  bool uj = use_json(argc, argv);
3466
  afi_t afi;
3467
  int idx = 0;
3468
3469
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3470
    ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3471
    if (ret < 0) {
3472
      if (uj) {
3473
        json_object *json_no = NULL;
3474
        json_no = json_object_new_object();
3475
        json_object_string_add(json_no, "warning",
3476
                   "Malformed address");
3477
        vty_out(vty, "%s\n",
3478
          json_object_to_json_string(json_no));
3479
        json_object_free(json_no);
3480
      } else
3481
        vty_out(vty, "Malformed address: %s\n",
3482
          argv[idx_ipv4]->arg);
3483
      return CMD_WARNING;
3484
    }
3485
    peer = peer_lookup(NULL, &su);
3486
    if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3487
      if (uj) {
3488
        json_object *json_no = NULL;
3489
        json_no = json_object_new_object();
3490
        json_object_string_add(
3491
          json_no, "warning",
3492
          "No such neighbor or address family");
3493
        vty_out(vty, "%s\n",
3494
          json_object_to_json_string(json_no));
3495
        json_object_free(json_no);
3496
      } else
3497
        vty_out(vty,
3498
          "%% No such neighbor or address family\n");
3499
      return CMD_WARNING;
3500
    }
3501
    return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3502
            SAFI_MPLS_VPN, uj);
3503
  }
3504
  return CMD_SUCCESS;
3505
}
3506
3507
DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
3508
       show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
3509
       "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3510
       SHOW_STR
3511
       IP_STR
3512
       BGP_STR
3513
       BGP_VPNVX_HELP_STR
3514
       "Display information for a route distinguisher\n"
3515
       "VPN Route Distinguisher\n"
3516
       "All VPN Route Distinguishers\n"
3517
       "Detailed information on TCP and BGP neighbor connections\n"
3518
       "Neighbor to display information about\n"
3519
       "Display the routes advertised to a BGP neighbor\n"
3520
       JSON_STR)
3521
{
3522
  int idx_ext_community = 5;
3523
  int idx_ipv4 = 7;
3524
  int ret;
3525
  struct peer *peer;
3526
  struct prefix_rd prd;
3527
  union sockunion su;
3528
  bool uj = use_json(argc, argv);
3529
  afi_t afi;
3530
  int idx = 0;
3531
3532
  if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3533
    ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3534
    if (ret < 0) {
3535
      if (uj) {
3536
        json_object *json_no = NULL;
3537
        json_no = json_object_new_object();
3538
        json_object_string_add(json_no, "warning",
3539
                   "Malformed address");
3540
        vty_out(vty, "%s\n",
3541
          json_object_to_json_string(json_no));
3542
        json_object_free(json_no);
3543
      } else
3544
        vty_out(vty, "Malformed address: %s\n",
3545
          argv[idx_ext_community]->arg);
3546
      return CMD_WARNING;
3547
    }
3548
    peer = peer_lookup(NULL, &su);
3549
    if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3550
      if (uj) {
3551
        json_object *json_no = NULL;
3552
        json_no = json_object_new_object();
3553
        json_object_string_add(
3554
          json_no, "warning",
3555
          "No such neighbor or address family");
3556
        vty_out(vty, "%s\n",
3557
          json_object_to_json_string(json_no));
3558
        json_object_free(json_no);
3559
      } else
3560
        vty_out(vty,
3561
          "%% No such neighbor or address family\n");
3562
      return CMD_WARNING;
3563
    }
3564
3565
    if (!strcmp(argv[idx_ext_community]->arg, "all"))
3566
      return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3567
              SAFI_MPLS_VPN, uj);
3568
    ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3569
    if (!ret) {
3570
      if (uj) {
3571
        json_object *json_no = NULL;
3572
        json_no = json_object_new_object();
3573
        json_object_string_add(
3574
          json_no, "warning",
3575
          "Malformed Route Distinguisher");
3576
        vty_out(vty, "%s\n",
3577
          json_object_to_json_string(json_no));
3578
        json_object_free(json_no);
3579
      } else
3580
        vty_out(vty,
3581
          "%% Malformed Route Distinguisher\n");
3582
      return CMD_WARNING;
3583
    }
3584
3585
    return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
3586
            SAFI_MPLS_VPN, uj);
3587
  }
3588
  return CMD_SUCCESS;
3589
}
3590
#endif /* KEEP_OLD_VPN_COMMANDS */
3591
3592
void bgp_mplsvpn_init(void)
3593
1
{
3594
1
  install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
3595
1
  install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
3596
1
  install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
3597
3598
1
  install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
3599
1
  install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
3600
3601
1
  install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
3602
1
  install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
3603
#ifdef KEEP_OLD_VPN_COMMANDS
3604
  install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
3605
  install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
3606
  install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
3607
  install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
3608
  install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
3609
  install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
3610
  install_element(VIEW_NODE,
3611
      &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
3612
  install_element(VIEW_NODE,
3613
      &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
3614
#endif /* KEEP_OLD_VPN_COMMANDS */
3615
1
}
3616
3617
vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
3618
0
{
3619
0
  struct listnode *mnode, *mnnode;
3620
0
  struct bgp *bgp;
3621
0
  afi_t afi = AFI_IP;
3622
3623
0
  if (eckey->unit_size == IPV6_ECOMMUNITY_SIZE)
3624
0
    afi = AFI_IP6;
3625
3626
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
3627
0
    struct ecommunity *ec;
3628
3629
0
    if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3630
0
      continue;
3631
3632
0
    ec = bgp->vpn_policy[afi].import_redirect_rtlist;
3633
3634
0
    if (ec && eckey->unit_size != ec->unit_size)
3635
0
      continue;
3636
3637
0
    if (ecommunity_include(ec, eckey))
3638
0
      return bgp->vrf_id;
3639
0
  }
3640
0
  return VRF_UNKNOWN;
3641
0
}
3642
3643
/*
3644
 * The purpose of this function is to process leaks that were deferred
3645
 * from earlier per-vrf configuration due to not-yet-existing default
3646
 * vrf, in other words, configuration such as:
3647
 *
3648
 *     router bgp MMM vrf FOO
3649
 *       address-family ipv4 unicast
3650
 *         rd vpn export 1:1
3651
 *       exit-address-family
3652
 *
3653
 *     router bgp NNN
3654
 *       ...
3655
 *
3656
 * This function gets called when the default instance ("router bgp NNN")
3657
 * is created.
3658
 */
3659
void vpn_leak_postchange_all(void)
3660
0
{
3661
0
  struct listnode *next;
3662
0
  struct bgp *bgp;
3663
0
  struct bgp *bgp_default = bgp_get_default();
3664
3665
0
  assert(bgp_default);
3666
3667
  /* First, do any exporting from VRFs to the single VPN RIB */
3668
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3669
3670
0
    if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3671
0
      continue;
3672
3673
0
    vpn_leak_postchange(
3674
0
      BGP_VPN_POLICY_DIR_TOVPN,
3675
0
      AFI_IP,
3676
0
      bgp_default,
3677
0
      bgp);
3678
3679
0
    vpn_leak_postchange(
3680
0
      BGP_VPN_POLICY_DIR_TOVPN,
3681
0
      AFI_IP6,
3682
0
      bgp_default,
3683
0
      bgp);
3684
0
  }
3685
3686
  /* Now, do any importing to VRFs from the single VPN RIB */
3687
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3688
3689
0
    if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3690
0
      continue;
3691
3692
0
    vpn_leak_postchange(
3693
0
      BGP_VPN_POLICY_DIR_FROMVPN,
3694
0
      AFI_IP,
3695
0
      bgp_default,
3696
0
      bgp);
3697
3698
0
    vpn_leak_postchange(
3699
0
      BGP_VPN_POLICY_DIR_FROMVPN,
3700
0
      AFI_IP6,
3701
0
      bgp_default,
3702
0
      bgp);
3703
0
  }
3704
0
}
3705
3706
/* When a bgp vrf instance is unconfigured, remove its routes
3707
 * from the VPN table and this vrf could be importing routes from other
3708
 * bgp vrf instnaces, unimport them.
3709
 * VRF X and VRF Y are exporting routes to each other.
3710
 * When VRF X is deleted, unimport its routes from all target vrfs,
3711
 * also VRF Y should unimport its routes from VRF X table.
3712
 * This will ensure VPN table is cleaned up appropriately.
3713
 */
3714
void bgp_vpn_leak_unimport(struct bgp *from_bgp)
3715
0
{
3716
0
  struct bgp *to_bgp;
3717
0
  const char *tmp_name;
3718
0
  char *vname;
3719
0
  struct listnode *node, *next;
3720
0
  safi_t safi = SAFI_UNICAST;
3721
0
  afi_t afi;
3722
0
  bool is_vrf_leak_bind;
3723
0
  int debug;
3724
3725
0
  if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3726
0
    return;
3727
3728
0
  debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3729
0
         BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3730
3731
0
  tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3732
3733
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
3734
    /* vrf leak is for IPv4 and IPv6 Unicast only */
3735
0
    if (afi != AFI_IP && afi != AFI_IP6)
3736
0
      continue;
3737
3738
0
    for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3739
0
      if (from_bgp == to_bgp)
3740
0
        continue;
3741
3742
      /* Unimport and remove source vrf from the
3743
       * other vrfs import list.
3744
       */
3745
0
      struct vpn_policy *to_vpolicy;
3746
3747
0
      is_vrf_leak_bind = false;
3748
0
      to_vpolicy = &(to_bgp->vpn_policy[afi]);
3749
0
      for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
3750
0
              vname)) {
3751
0
        if (strcmp(vname, tmp_name) == 0) {
3752
0
          is_vrf_leak_bind = true;
3753
0
          break;
3754
0
        }
3755
0
      }
3756
      /* skip this bgp instance as there is no leak to this
3757
       * vrf instance.
3758
       */
3759
0
      if (!is_vrf_leak_bind)
3760
0
        continue;
3761
3762
0
      if (debug)
3763
0
        zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3764
0
             __func__, from_bgp->name_pretty,
3765
0
             to_bgp->name_pretty, afi2str(afi),
3766
0
             to_vpolicy->import_vrf->count);
3767
3768
0
      vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
3769
3770
      /* readd vrf name as unimport removes import vrf name
3771
       * from the destination vrf's import list where the
3772
       * `import vrf` configuration still exist.
3773
       */
3774
0
      vname = XSTRDUP(MTYPE_TMP, tmp_name);
3775
0
      listnode_add(to_bgp->vpn_policy[afi].import_vrf,
3776
0
             vname);
3777
0
      SET_FLAG(to_bgp->af_flags[afi][safi],
3778
0
         BGP_CONFIG_VRF_TO_VRF_IMPORT);
3779
3780
      /* If to_bgp exports its routes to the bgp vrf
3781
       * which is being deleted, un-import the
3782
       * to_bgp routes from VPN.
3783
       */
3784
0
      for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
3785
0
              .export_vrf, node,
3786
0
              vname)) {
3787
0
        if (strcmp(vname, tmp_name) == 0) {
3788
0
          vrf_unimport_from_vrf(from_bgp, to_bgp,
3789
0
                  afi, safi);
3790
0
          break;
3791
0
        }
3792
0
      }
3793
0
    }
3794
0
  }
3795
0
  return;
3796
0
}
3797
3798
/* When a router bgp is configured, there could be a bgp vrf
3799
 * instance importing routes from this newly configured
3800
 * bgp vrf instance. Export routes from configured
3801
 * bgp vrf to VPN.
3802
 * VRF Y has import from bgp vrf x,
3803
 * when a bgp vrf x instance is created, export its routes
3804
 * to VRF Y instance.
3805
 */
3806
void bgp_vpn_leak_export(struct bgp *from_bgp)
3807
0
{
3808
0
  afi_t afi;
3809
0
  const char *export_name;
3810
0
  char *vname;
3811
0
  struct listnode *node, *next;
3812
0
  struct ecommunity *ecom;
3813
0
  enum vpn_policy_direction idir, edir;
3814
0
  safi_t safi = SAFI_UNICAST;
3815
0
  struct bgp *to_bgp;
3816
0
  int debug;
3817
3818
0
  debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3819
0
         BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3820
3821
0
  idir = BGP_VPN_POLICY_DIR_FROMVPN;
3822
0
  edir = BGP_VPN_POLICY_DIR_TOVPN;
3823
3824
0
  export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3825
3826
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
3827
    /* vrf leak is for IPv4 and IPv6 Unicast only */
3828
0
    if (afi != AFI_IP && afi != AFI_IP6)
3829
0
      continue;
3830
3831
0
    for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3832
0
      if (from_bgp == to_bgp)
3833
0
        continue;
3834
3835
      /* bgp instance has import list, check to see if newly
3836
       * configured bgp instance is the list.
3837
       */
3838
0
      struct vpn_policy *to_vpolicy;
3839
3840
0
      to_vpolicy = &(to_bgp->vpn_policy[afi]);
3841
0
      for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
3842
0
              node, vname)) {
3843
0
        if (strcmp(vname, export_name) != 0)
3844
0
          continue;
3845
3846
0
        if (debug)
3847
0
          zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3848
0
             __func__,
3849
0
             export_name, to_bgp->name_pretty);
3850
3851
0
        ecom = from_bgp->vpn_policy[afi].rtlist[edir];
3852
        /* remove import rt, it will be readded
3853
         * as part of import from vrf.
3854
         */
3855
0
        if (ecom)
3856
0
          ecommunity_del_val(
3857
0
            to_vpolicy->rtlist[idir],
3858
0
            (struct ecommunity_val *)
3859
0
              ecom->val);
3860
0
        vrf_import_from_vrf(to_bgp, from_bgp,
3861
0
                afi, safi);
3862
0
        break;
3863
3864
0
      }
3865
0
    }
3866
0
  }
3867
0
}