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