]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Merge pull request #13183 from Pdoijode/pdoijode/pim-json-changes
[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
1119 * nexthop tracking. However, if those routes are subsequently
1120 * imported to other RIBs within BGP, the leaked routes do not
1121 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
1122 * in order to determine if the route we are currently leaking
1123 * should have nexthop tracking, we must find the ultimate
1124 * parent so we can check its sub_type.
1125 *
40381db7 1126 * As of now, source_bpi may at most be a second-generation route
f46d45c1
PZ
1127 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1128 * Using a loop here supports more complex intra-bgp import-export
1129 * schemes that could be implemented in the future.
3bd70bf8 1130 *
f46d45c1 1131 */
f46d45c1 1132
ddb5b488
PZ
1133 /*
1134 * match parent
1135 */
9bcb3eef 1136 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
40381db7 1137 if (bpi->extra && bpi->extra->parent == parent)
ddb5b488
PZ
1138 break;
1139 }
1140
40381db7
DS
1141 if (bpi) {
1142 bool labelssame = labels_same(bpi, label, num_labels);
e37fb4bf 1143
8fac400c
AR
1144 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
1145 && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
1146 if (debug) {
1147 zlog_debug(
1148 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
02212dee 1149 __func__, to_bgp->name_pretty,
8fac400c
AR
1150 source_bpi->flags, bpi->flags, p);
1151 }
1152 return NULL;
1153 }
1154
40381db7
DS
1155 if (attrhash_cmp(bpi->attr, new_attr) && labelssame
1156 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
ddb5b488
PZ
1157
1158 bgp_attr_unintern(&new_attr);
1159 if (debug)
1160 zlog_debug(
56ca3b5b 1161 "%s: ->%s: %pBD: Found route, no change",
02212dee 1162 __func__, to_bgp->name_pretty, bn);
ddb5b488
PZ
1163 return NULL;
1164 }
1165
3840a819
DA
1166 /* If the RT was changed via extended communities as an
1167 * import/export list, we should withdraw implicitly the old
1168 * path from VRFs.
1169 * For instance, RT list was modified using route-maps:
1170 * route-map test permit 10
1171 * set extcommunity rt none
1172 */
1173 if (CHECK_FLAG(bpi->attr->flag,
1174 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
1175 CHECK_FLAG(new_attr->flag,
1176 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
1177 if (!ecommunity_cmp(
1178 bgp_attr_get_ecommunity(bpi->attr),
1179 bgp_attr_get_ecommunity(new_attr))) {
1aa2c93e 1180 vpn_leak_to_vrf_withdraw(bpi);
02212dee
LS
1181 bgp_aggregate_decrement(to_bgp, p, bpi, afi,
1182 safi);
3840a819
DA
1183 bgp_path_info_delete(bn, bpi);
1184 }
1185 }
1186
ddb5b488 1187 /* attr is changed */
40381db7 1188 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
ddb5b488
PZ
1189
1190 /* Rewrite BGP route information. */
40381db7
DS
1191 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
1192 bgp_path_info_restore(bn, bpi);
ddb5b488 1193 else
02212dee 1194 bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
40381db7
DS
1195 bgp_attr_unintern(&bpi->attr);
1196 bpi->attr = new_attr;
083ec940 1197 bpi->uptime = monotime(NULL);
ddb5b488 1198
e37fb4bf
PZ
1199 /*
1200 * rewrite labels
1201 */
1202 if (!labelssame)
40381db7 1203 setlabels(bpi, label, num_labels);
e37fb4bf 1204
dbcf19b8
HS
1205 /*
1206 * rewrite sid
1207 */
1208 if (num_sids) {
16f3db2d 1209 if (new_attr->srv6_l3vpn) {
7de4c885
HS
1210 setsids(bpi, &new_attr->srv6_l3vpn->sid,
1211 num_sids);
16f3db2d
RS
1212
1213 extra = bgp_path_info_extra_get(bpi);
1214
1215 extra->sid[0].loc_block_len =
1216 new_attr->srv6_l3vpn->loc_block_len;
1217 extra->sid[0].loc_node_len =
1218 new_attr->srv6_l3vpn->loc_node_len;
1219 extra->sid[0].func_len =
1220 new_attr->srv6_l3vpn->func_len;
1221 extra->sid[0].arg_len =
1222 new_attr->srv6_l3vpn->arg_len;
ea7cd161
RS
1223 extra->sid[0].transposition_len =
1224 new_attr->srv6_l3vpn->transposition_len;
1225 extra->sid[0].transposition_offset =
1226 new_attr->srv6_l3vpn
1227 ->transposition_offset;
16f3db2d 1228 } else if (new_attr->srv6_vpn)
7de4c885
HS
1229 setsids(bpi, &new_attr->srv6_vpn->sid,
1230 num_sids);
d79ff732
HS
1231 } else
1232 unsetsids(bpi);
dbcf19b8 1233
960035b2 1234 if (nexthop_self_flag)
40381db7 1235 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
960035b2 1236
46dbf9d0
DA
1237 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1238 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ACCEPT_OWN);
1239
02212dee 1240 if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
b3e97f08
LS
1241 source_bpi, bpi, bgp_orig, p,
1242 debug))
659251db
LS
1243 bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
1244 else
1245 bgp_path_info_unset_flag(bn, bpi, BGP_PATH_VALID);
960035b2 1246
ddb5b488 1247 /* Process change. */
02212dee
LS
1248 bgp_aggregate_increment(to_bgp, p, bpi, afi, safi);
1249 bgp_process(to_bgp, bn, afi, safi);
9bcb3eef 1250 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1251
1252 if (debug)
56ca3b5b 1253 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
02212dee 1254 __func__, to_bgp->name_pretty, bn);
ddb5b488 1255
40381db7 1256 return bpi;
ddb5b488
PZ
1257 }
1258
8fac400c
AR
1259 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
1260 if (debug) {
1261 zlog_debug(
1262 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
02212dee 1263 __func__, to_bgp->name_pretty,
8fac400c
AR
1264 source_bpi->flags, p);
1265 }
1266 return NULL;
1267 }
1268
be180f97 1269 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
02212dee 1270 to_bgp->peer_self, new_attr, bn);
960035b2 1271
4cd690ae
PG
1272 if (source_bpi->peer) {
1273 extra = bgp_path_info_extra_get(new);
1274 extra->peer_orig = peer_lock(source_bpi->peer);
1275 }
1276
960035b2 1277 if (nexthop_self_flag)
18ee8310 1278 bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
ddb5b488 1279
46dbf9d0
DA
1280 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1281 bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN);
1282
18ee8310 1283 bgp_path_info_extra_get(new);
4b85140f 1284
dbcf19b8
HS
1285 /*
1286 * rewrite sid
1287 */
1288 if (num_sids) {
16f3db2d 1289 if (new_attr->srv6_l3vpn) {
dbcf19b8 1290 setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
16f3db2d
RS
1291
1292 extra = bgp_path_info_extra_get(new);
1293
1294 extra->sid[0].loc_block_len =
1295 new_attr->srv6_l3vpn->loc_block_len;
1296 extra->sid[0].loc_node_len =
1297 new_attr->srv6_l3vpn->loc_node_len;
1298 extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len;
1299 extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len;
ea7cd161
RS
1300 extra->sid[0].transposition_len =
1301 new_attr->srv6_l3vpn->transposition_len;
1302 extra->sid[0].transposition_offset =
1303 new_attr->srv6_l3vpn->transposition_offset;
16f3db2d 1304 } else if (new_attr->srv6_vpn)
dbcf19b8 1305 setsids(new, &new_attr->srv6_vpn->sid, num_sids);
d79ff732
HS
1306 } else
1307 unsetsids(new);
dbcf19b8 1308
e37fb4bf
PZ
1309 if (num_labels)
1310 setlabels(new, label, num_labels);
1311
18ee8310 1312 new->extra->parent = bgp_path_info_lock(parent);
9bcb3eef 1313 bgp_dest_lock_node(
ef96e375 1314 (struct bgp_dest *)parent->net);
ddb5b488 1315 if (bgp_orig)
21d88ef7 1316 new->extra->bgp_orig = bgp_lock(bgp_orig);
ddb5b488
PZ
1317 if (nexthop_orig)
1318 new->extra->nexthop_orig = *nexthop_orig;
1319
02212dee 1320 if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
b3e97f08 1321 source_bpi, new, bgp_orig, p, debug))
659251db
LS
1322 bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
1323 else
1324 bgp_path_info_unset_flag(bn, new, BGP_PATH_VALID);
960035b2 1325
02212dee 1326 bgp_aggregate_increment(to_bgp, p, new, afi, safi);
18ee8310 1327 bgp_path_info_add(bn, new);
ddb5b488 1328
9bcb3eef 1329 bgp_dest_unlock_node(bn);
02212dee 1330 bgp_process(to_bgp, bn, afi, safi);
ddb5b488
PZ
1331
1332 if (debug)
56ca3b5b 1333 zlog_debug("%s: ->%s: %pBD: Added new route", __func__,
02212dee 1334 to_bgp->name_pretty, bn);
ddb5b488
PZ
1335
1336 return new;
1337}
1338
1339/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
02212dee
LS
1340void vpn_leak_from_vrf_update(struct bgp *to_bgp, /* to */
1341 struct bgp *from_bgp, /* from */
40381db7 1342 struct bgp_path_info *path_vrf) /* route */
ddb5b488
PZ
1343{
1344 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1345 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
ddb5b488
PZ
1346 afi_t afi = family2afi(p->family);
1347 struct attr static_attr = {0};
1348 struct attr *new_attr = NULL;
1349 safi_t safi = SAFI_MPLS_VPN;
1350 mpls_label_t label_val;
1351 mpls_label_t label;
9bcb3eef 1352 struct bgp_dest *bn;
ddb5b488 1353 const char *debugmsg;
960035b2
PZ
1354 int nexthop_self_flag = 0;
1355
1356 if (debug)
02212dee 1357 zlog_debug("%s: from vrf %s", __func__, from_bgp->name_pretty);
ddb5b488 1358
b53e67a3
DA
1359 if (debug && bgp_attr_get_ecommunity(path_vrf->attr)) {
1360 char *s = ecommunity_ecom2str(
1361 bgp_attr_get_ecommunity(path_vrf->attr),
1362 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1363
40381db7 1364 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
02212dee 1365 from_bgp->name, path_vrf->type, s);
c8f57349 1366 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1367 }
1368
02212dee 1369 if (!to_bgp)
ddb5b488
PZ
1370 return;
1371
1372 if (!afi) {
1373 if (debug)
1374 zlog_debug("%s: can't get afi of prefix", __func__);
1375 return;
1376 }
1377
12d6100c 1378 /* Is this route exportable into the VPN table? */
1379 if (!is_route_injectable_into_vpn(path_vrf))
ddb5b488
PZ
1380 return;
1381
02212dee 1382 if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
ddb5b488 1383 if (debug)
12a844a5 1384 zlog_debug("%s: %s skipping: %s", __func__,
02212dee 1385 from_bgp->name, debugmsg);
ddb5b488
PZ
1386 return;
1387 }
1388
6f4f49b2
QY
1389 /* shallow copy */
1390 static_attr = *path_vrf->attr;
ddb5b488
PZ
1391
1392 /*
1393 * route map handling
1394 */
02212dee 1395 if (from_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
4b7e6066 1396 struct bgp_path_info info;
ddb5b488
PZ
1397 route_map_result_t ret;
1398
1399 memset(&info, 0, sizeof(info));
02212dee 1400 info.peer = to_bgp->peer_self;
ddb5b488 1401 info.attr = &static_attr;
02212dee
LS
1402 ret = route_map_apply(from_bgp->vpn_policy[afi]
1403 .rmap[BGP_VPN_POLICY_DIR_TOVPN],
1404 p, &info);
ddb5b488
PZ
1405 if (RMAP_DENYMATCH == ret) {
1406 bgp_attr_flush(&static_attr); /* free any added parts */
1407 if (debug)
1408 zlog_debug(
1409 "%s: vrf %s route map \"%s\" says DENY, returning",
02212dee
LS
1410 __func__, from_bgp->name_pretty,
1411 from_bgp->vpn_policy[afi]
ddb5b488
PZ
1412 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
1413 ->name);
1414 return;
1415 }
1416 }
1417
b53e67a3
DA
1418 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1419 char *s = ecommunity_ecom2str(
1420 bgp_attr_get_ecommunity(&static_attr),
1421 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1422
ddb5b488
PZ
1423 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1424 __func__, s);
c8f57349 1425 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1426 }
1427
1428 /*
1429 * Add the vpn-policy rt-list
1430 */
1431 struct ecommunity *old_ecom;
1432 struct ecommunity *new_ecom;
1433
e8bfa90e 1434 /* Export with the 'from' instance's export RTs. */
1435 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
b53e67a3 1436 old_ecom = bgp_attr_get_ecommunity(&static_attr);
ddb5b488 1437 if (old_ecom) {
e8bfa90e 1438 new_ecom = ecommunity_dup(old_ecom);
02212dee
LS
1439 if (CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
1440 BGP_CONFIG_VRF_TO_VRF_EXPORT))
e8bfa90e 1441 ecommunity_strip_rts(new_ecom);
02212dee
LS
1442 new_ecom = ecommunity_merge(
1443 new_ecom, from_bgp->vpn_policy[afi]
1444 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
ddb5b488
PZ
1445 if (!old_ecom->refcnt)
1446 ecommunity_free(&old_ecom);
1447 } else {
1448 new_ecom = ecommunity_dup(
02212dee 1449 from_bgp->vpn_policy[afi]
ddb5b488
PZ
1450 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1451 }
b53e67a3 1452 bgp_attr_set_ecommunity(&static_attr, new_ecom);
ddb5b488 1453
b53e67a3
DA
1454 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1455 char *s = ecommunity_ecom2str(
1456 bgp_attr_get_ecommunity(&static_attr),
1457 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1458
ddb5b488
PZ
1459 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1460 __func__, s);
c8f57349 1461 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1462 }
1463
46dbf9d0
DA
1464 community_strip_accept_own(&static_attr);
1465
ddb5b488
PZ
1466 /* Nexthop */
1467 /* if policy nexthop not set, use 0 */
02212dee 1468 if (CHECK_FLAG(from_bgp->vpn_policy[afi].flags,
ddb5b488 1469 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
ddb5b488 1470 struct prefix *nexthop =
02212dee 1471 &from_bgp->vpn_policy[afi].tovpn_nexthop;
12a844a5 1472
ddb5b488
PZ
1473 switch (nexthop->family) {
1474 case AF_INET:
1475 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1476 */
1477 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
1478
1479 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
0606039c 1480 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
ddb5b488
PZ
1481 break;
1482
1483 case AF_INET6:
1484 static_attr.mp_nexthop_global = nexthop->u.prefix6;
0606039c 1485 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
ddb5b488
PZ
1486 break;
1487
1488 default:
1489 assert(0);
1490 }
1491 } else {
02212dee 1492 if (!CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
12a844a5 1493 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
f784007d
RS
1494 if (afi == AFI_IP &&
1495 !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
020a3f60
DS
1496 /*
1497 * For ipv4, copy to multiprotocol
1498 * nexthop field
1499 */
1500 static_attr.mp_nexthop_global_in =
1501 static_attr.nexthop;
0606039c
DA
1502 static_attr.mp_nexthop_len =
1503 BGP_ATTR_NHLEN_IPV4;
020a3f60
DS
1504 /*
1505 * XXX Leave static_attr.nexthop
1506 * intact for NHT
1507 */
1508 static_attr.flag &=
1509 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5
DS
1510 }
1511 } else {
77e62f2b 1512 /* Update based on next-hop family to account for
1513 * RFC 5549 (BGP unnumbered) scenario. Note that
1514 * specific action is only needed for the case of
1515 * IPv4 nexthops as the attr has been copied
1516 * otherwise.
1517 */
40381db7
DS
1518 if (afi == AFI_IP
1519 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
12a844a5
DS
1520 static_attr.mp_nexthop_global_in.s_addr =
1521 static_attr.nexthop.s_addr;
0606039c
DA
1522 static_attr.mp_nexthop_len =
1523 BGP_ATTR_NHLEN_IPV4;
12a844a5
DS
1524 static_attr.flag |=
1525 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5 1526 }
ddb5b488 1527 }
960035b2 1528 nexthop_self_flag = 1;
ddb5b488
PZ
1529 }
1530
02212dee 1531 label_val = from_bgp->vpn_policy[afi].tovpn_label;
ddb5b488 1532 if (label_val == MPLS_LABEL_NONE) {
291e32c3 1533 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
1534 } else {
1535 encode_label(label_val, &label);
1536 }
1537
1538 /* Set originator ID to "me" */
1539 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
02212dee 1540 static_attr.originator_id = to_bgp->router_id;
ddb5b488 1541
dbcf19b8 1542 /* Set SID for SRv6 VPN */
02212dee 1543 if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
05d99980
CS
1544 struct srv6_locator_chunk *locator =
1545 from_bgp->vpn_policy[afi].tovpn_sid_locator;
02212dee
LS
1546 encode_label(
1547 from_bgp->vpn_policy[afi].tovpn_sid_transpose_label,
1548 &label);
dbcf19b8 1549 static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
537b608a 1550 sizeof(struct bgp_attr_srv6_l3vpn));
dbcf19b8 1551 static_attr.srv6_l3vpn->sid_flags = 0x00;
05d99980
CS
1552 static_attr.srv6_l3vpn->endpoint_behavior =
1553 afi == AFI_IP
1554 ? (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1555 ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1556 : SRV6_ENDPOINT_BEHAVIOR_END_DT4)
1557 : (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1558 ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1559 : SRV6_ENDPOINT_BEHAVIOR_END_DT6);
9299fd00 1560 static_attr.srv6_l3vpn->loc_block_len =
bee2e7d0
RS
1561 from_bgp->vpn_policy[afi]
1562 .tovpn_sid_locator->block_bits_length;
9299fd00 1563 static_attr.srv6_l3vpn->loc_node_len =
bee2e7d0
RS
1564 from_bgp->vpn_policy[afi]
1565 .tovpn_sid_locator->node_bits_length;
9299fd00 1566 static_attr.srv6_l3vpn->func_len =
bee2e7d0
RS
1567 from_bgp->vpn_policy[afi]
1568 .tovpn_sid_locator->function_bits_length;
9299fd00 1569 static_attr.srv6_l3vpn->arg_len =
bee2e7d0
RS
1570 from_bgp->vpn_policy[afi]
1571 .tovpn_sid_locator->argument_bits_length;
9299fd00 1572 static_attr.srv6_l3vpn->transposition_len =
bee2e7d0
RS
1573 from_bgp->vpn_policy[afi]
1574 .tovpn_sid_locator->function_bits_length;
9299fd00 1575 static_attr.srv6_l3vpn->transposition_offset =
bee2e7d0
RS
1576 from_bgp->vpn_policy[afi]
1577 .tovpn_sid_locator->block_bits_length +
1578 from_bgp->vpn_policy[afi]
1579 .tovpn_sid_locator->node_bits_length;
1580 ;
dbcf19b8 1581 memcpy(&static_attr.srv6_l3vpn->sid,
bee2e7d0
RS
1582 &from_bgp->vpn_policy[afi]
1583 .tovpn_sid_locator->prefix.prefix,
69fe7874 1584 sizeof(struct in6_addr));
527588aa 1585 } else if (from_bgp->tovpn_sid_locator) {
05d99980
CS
1586 struct srv6_locator_chunk *locator =
1587 from_bgp->tovpn_sid_locator;
527588aa
CS
1588 encode_label(from_bgp->tovpn_sid_transpose_label, &label);
1589 static_attr.srv6_l3vpn =
1590 XCALLOC(MTYPE_BGP_SRV6_L3VPN,
1591 sizeof(struct bgp_attr_srv6_l3vpn));
1592 static_attr.srv6_l3vpn->sid_flags = 0x00;
05d99980
CS
1593 static_attr.srv6_l3vpn->endpoint_behavior =
1594 CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1595 ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1596 : SRV6_ENDPOINT_BEHAVIOR_END_DT46;
527588aa
CS
1597 static_attr.srv6_l3vpn->loc_block_len =
1598 from_bgp->tovpn_sid_locator->block_bits_length;
1599 static_attr.srv6_l3vpn->loc_node_len =
1600 from_bgp->tovpn_sid_locator->node_bits_length;
1601 static_attr.srv6_l3vpn->func_len =
1602 from_bgp->tovpn_sid_locator->function_bits_length;
1603 static_attr.srv6_l3vpn->arg_len =
1604 from_bgp->tovpn_sid_locator->argument_bits_length;
1605 static_attr.srv6_l3vpn->transposition_len =
1606 from_bgp->tovpn_sid_locator->function_bits_length;
1607 static_attr.srv6_l3vpn->transposition_offset =
1608 from_bgp->tovpn_sid_locator->block_bits_length +
1609 from_bgp->tovpn_sid_locator->node_bits_length;
1610 memcpy(&static_attr.srv6_l3vpn->sid,
1611 &from_bgp->tovpn_sid_locator->prefix.prefix,
1612 sizeof(struct in6_addr));
dbcf19b8
HS
1613 }
1614
ddb5b488
PZ
1615
1616 new_attr = bgp_attr_intern(
1617 &static_attr); /* hashed refcounted everything */
1618 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
1619
b53e67a3
DA
1620 if (debug && bgp_attr_get_ecommunity(new_attr)) {
1621 char *s = ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr),
c3e345b1 1622 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1623
ddb5b488 1624 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 1625 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1626 }
1627
1628 /* Now new_attr is an allocated interned attr */
1629
02212dee
LS
1630 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1631 &(from_bgp->vpn_policy[afi].tovpn_rd));
ddb5b488 1632
4b7e6066 1633 struct bgp_path_info *new_info;
ddb5b488 1634
88ef2991 1635 new_info =
02212dee
LS
1636 leak_update(to_bgp, bn, new_attr, afi, safi, path_vrf, &label,
1637 1, from_bgp, NULL, nexthop_self_flag, debug);
ddb5b488
PZ
1638
1639 /*
1640 * Routes actually installed in the vpn RIB must also be
1641 * offered to all vrfs (because now they originate from
1642 * the vpn RIB).
1643 *
1644 * Acceptance into other vrfs depends on rt-lists.
1645 * Originating vrf will not accept the looped back route
1646 * because of loop checking.
1647 */
1648 if (new_info)
46dbf9d0 1649 vpn_leak_to_vrf_update(from_bgp, new_info, NULL);
8ea624a4
DA
1650 else
1651 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1652}
1653
02212dee
LS
1654void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */
1655 struct bgp *from_bgp, /* from */
40381db7 1656 struct bgp_path_info *path_vrf) /* route */
ddb5b488
PZ
1657{
1658 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1659 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
ddb5b488
PZ
1660 afi_t afi = family2afi(p->family);
1661 safi_t safi = SAFI_MPLS_VPN;
40381db7 1662 struct bgp_path_info *bpi;
9bcb3eef 1663 struct bgp_dest *bn;
ddb5b488 1664 const char *debugmsg;
960035b2
PZ
1665
1666 if (debug) {
960035b2 1667 zlog_debug(
56ca3b5b 1668 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
02212dee 1669 __func__, from_bgp->name_pretty, path_vrf->net,
40381db7 1670 path_vrf->type, path_vrf->sub_type);
960035b2 1671 }
ddb5b488 1672
02212dee 1673 if (!to_bgp)
ddb5b488
PZ
1674 return;
1675
1676 if (!afi) {
1677 if (debug)
1678 zlog_debug("%s: can't get afi of prefix", __func__);
1679 return;
1680 }
1681
12d6100c 1682 /* Is this route exportable into the VPN table? */
1683 if (!is_route_injectable_into_vpn(path_vrf))
1684 return;
1685
02212dee 1686 if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
ddb5b488
PZ
1687 if (debug)
1688 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1689 return;
1690 }
1691
1692 if (debug)
40381db7 1693 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
ddb5b488 1694
02212dee
LS
1695 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1696 &(from_bgp->vpn_policy[afi].tovpn_rd));
ddb5b488 1697
6f94b685
DS
1698 if (!bn)
1699 return;
ddb5b488
PZ
1700 /*
1701 * vrf -> vpn
40381db7 1702 * match original bpi imported from
ddb5b488 1703 */
9bcb3eef 1704 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
40381db7 1705 if (bpi->extra && bpi->extra->parent == path_vrf) {
ddb5b488
PZ
1706 break;
1707 }
1708 }
1709
40381db7 1710 if (bpi) {
ddb5b488 1711 /* withdraw from looped vrfs as well */
1aa2c93e 1712 vpn_leak_to_vrf_withdraw(bpi);
ddb5b488 1713
02212dee 1714 bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
40381db7 1715 bgp_path_info_delete(bn, bpi);
02212dee 1716 bgp_process(to_bgp, bn, afi, safi);
ddb5b488 1717 }
9bcb3eef 1718 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1719}
1720
02212dee 1721void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,
ddb5b488
PZ
1722 afi_t afi)
1723{
1724 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1725 struct bgp_dest *pdest;
ddb5b488
PZ
1726 safi_t safi = SAFI_MPLS_VPN;
1727
1728 /*
02212dee 1729 * Walk vpn table, delete bpi with bgp_orig == from_bgp
ddb5b488 1730 */
02212dee 1731 for (pdest = bgp_table_top(to_bgp->rib[afi][safi]); pdest;
9bcb3eef 1732 pdest = bgp_route_next(pdest)) {
ddb5b488
PZ
1733
1734 struct bgp_table *table;
9bcb3eef 1735 struct bgp_dest *bn;
40381db7 1736 struct bgp_path_info *bpi;
ddb5b488
PZ
1737
1738 /* This is the per-RD table of prefixes */
9bcb3eef 1739 table = bgp_dest_get_bgp_table_info(pdest);
ddb5b488
PZ
1740
1741 if (!table)
1742 continue;
1743
1744 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
9bcb3eef 1745 bpi = bgp_dest_get_bgp_path_info(bn);
6f94b685 1746 if (debug && bpi) {
56ca3b5b 1747 zlog_debug("%s: looking at prefix %pBD",
b54892e0 1748 __func__, bn);
ddb5b488
PZ
1749 }
1750
6f94b685 1751 for (; bpi; bpi = bpi->next) {
ddb5b488
PZ
1752 if (debug)
1753 zlog_debug("%s: type %d, sub_type %d",
40381db7
DS
1754 __func__, bpi->type,
1755 bpi->sub_type);
1756 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
ddb5b488 1757 continue;
40381db7 1758 if (!bpi->extra)
ddb5b488 1759 continue;
02212dee
LS
1760 if ((struct bgp *)bpi->extra->bgp_orig ==
1761 from_bgp) {
ddb5b488
PZ
1762 /* delete route */
1763 if (debug)
9165c5f5 1764 zlog_debug("%s: deleting it",
ddb5b488 1765 __func__);
b19c4f08 1766 /* withdraw from leak-to vrfs as well */
1aa2c93e 1767 vpn_leak_to_vrf_withdraw(bpi);
b54892e0 1768 bgp_aggregate_decrement(
02212dee
LS
1769 to_bgp, bgp_dest_get_prefix(bn),
1770 bpi, afi, safi);
40381db7 1771 bgp_path_info_delete(bn, bpi);
02212dee 1772 bgp_process(to_bgp, bn, afi, safi);
ddb5b488
PZ
1773 }
1774 }
1775 }
1776 }
1777}
1778
02212dee 1779void vpn_leak_from_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
ddb5b488
PZ
1780 afi_t afi)
1781{
9bcb3eef 1782 struct bgp_dest *bn;
40381db7 1783 struct bgp_path_info *bpi;
ddb5b488
PZ
1784 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1785
1786 if (debug)
1787 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
02212dee 1788 from_bgp->name_pretty);
ddb5b488 1789
02212dee 1790 for (bn = bgp_table_top(from_bgp->rib[afi][SAFI_UNICAST]); bn;
ddb5b488
PZ
1791 bn = bgp_route_next(bn)) {
1792
1793 if (debug)
1794 zlog_debug("%s: node=%p", __func__, bn);
1795
9bcb3eef 1796 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 1797 bpi = bpi->next) {
ddb5b488
PZ
1798 if (debug)
1799 zlog_debug(
1800 "%s: calling vpn_leak_from_vrf_update",
1801 __func__);
02212dee 1802 vpn_leak_from_vrf_update(to_bgp, from_bgp, bpi);
ddb5b488
PZ
1803 }
1804 }
1805}
1806
46dbf9d0
DA
1807static struct bgp *bgp_lookup_by_rd(struct bgp_path_info *bpi,
1808 struct prefix_rd *rd, afi_t afi)
1809{
1810 struct listnode *node, *nnode;
1811 struct bgp *bgp;
1812
1813 if (!rd)
1814 return NULL;
1815
1816 /* If ACCEPT_OWN is not enabled for this path - return. */
1817 if (!CHECK_FLAG(bpi->flags, BGP_PATH_ACCEPT_OWN))
1818 return NULL;
1819
1820 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
1821 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1822 continue;
1823
1824 if (!CHECK_FLAG(bgp->vpn_policy[afi].flags,
1825 BGP_VPN_POLICY_TOVPN_RD_SET))
1826 continue;
1827
1828 /* Check if we have source VRF by RD value */
1829 if (memcmp(&bgp->vpn_policy[afi].tovpn_rd.val, rd->val,
1830 ECOMMUNITY_SIZE) == 0)
1831 return bgp;
1832 }
1833
1834 return NULL;
1835}
1836
1837static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
1838 struct bgp *from_bgp, /* from */
1839 struct bgp_path_info *path_vpn,
1840 struct prefix_rd *prd)
ddb5b488 1841{
9bcb3eef 1842 const struct prefix *p = bgp_dest_get_prefix(path_vpn->net);
ddb5b488
PZ
1843 afi_t afi = family2afi(p->family);
1844
ddb5b488
PZ
1845 struct attr static_attr = {0};
1846 struct attr *new_attr = NULL;
9bcb3eef 1847 struct bgp_dest *bn;
ddb5b488
PZ
1848 safi_t safi = SAFI_UNICAST;
1849 const char *debugmsg;
1850 struct prefix nexthop_orig;
1851 mpls_label_t *pLabels = NULL;
e37fb4bf 1852 uint32_t num_labels = 0;
960035b2 1853 int nexthop_self_flag = 1;
40381db7 1854 struct bgp_path_info *bpi_ultimate = NULL;
513bf8d6 1855 int origin_local = 0;
d6632478 1856 struct bgp *src_vrf;
8a02d9fe 1857 struct interface *ifp;
4a8cd6ad 1858 char rd_buf[RD_ADDRSTRLEN];
ddb5b488
PZ
1859 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1860
02212dee 1861 if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
ddb5b488 1862 if (debug)
4ee5265a
DA
1863 zlog_debug(
1864 "%s: from vpn (%s) to vrf (%s), skipping: %s",
1865 __func__, from_bgp->name_pretty,
1866 to_bgp->name_pretty, debugmsg);
a486300b 1867 return false;
ddb5b488
PZ
1868 }
1869
c479b28e
DA
1870 /*
1871 * For VRF-2-VRF route-leaking,
1872 * the source will be the originating VRF.
1873 *
1874 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
1875 * get the source VRF (BGP) by looking at the RD.
1876 */
1877 struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi);
1878
1879 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1880 src_vrf = path_vpn->extra->bgp_orig;
1881 else if (src_bgp)
1882 src_vrf = src_bgp;
1883 else
1884 src_vrf = from_bgp;
1885
ddb5b488 1886 /* Check for intersection of route targets */
2d7cdc5b 1887 if (!ecommunity_include(
02212dee 1888 to_bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
b53e67a3 1889 bgp_attr_get_ecommunity(path_vpn->attr))) {
de7cee09
AR
1890 if (debug)
1891 zlog_debug(
ba9dce1c 1892 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
02212dee 1893 from_bgp->name_pretty, to_bgp->name_pretty);
a486300b 1894 return false;
ddb5b488
PZ
1895 }
1896
616e9f0d
PG
1897 rd_buf[0] = '\0';
1898 if (debug && prd)
4a8cd6ad
PG
1899 prefix_rd2str(prd, rd_buf, sizeof(rd_buf), to_bgp->asnotation);
1900
46dbf9d0
DA
1901 /* A route MUST NOT ever be accepted back into its source VRF, even if
1902 * it carries one or more RTs that match that VRF.
1903 */
dd2d28ea
RS
1904 if (CHECK_FLAG(path_vpn->flags, BGP_PATH_ACCEPT_OWN) && prd &&
1905 memcmp(&prd->val, &to_bgp->vpn_policy[afi].tovpn_rd.val,
1906 ECOMMUNITY_SIZE) == 0) {
46dbf9d0
DA
1907 if (debug)
1908 zlog_debug(
4a8cd6ad
PG
1909 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
1910 __func__, rd_buf, to_bgp->name_pretty, p);
46dbf9d0
DA
1911 return false;
1912 }
1913
2dbe669b 1914 if (debug)
4a8cd6ad
PG
1915 zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
1916 p, to_bgp->name_pretty);
ddb5b488 1917
6f4f49b2
QY
1918 /* shallow copy */
1919 static_attr = *path_vpn->attr;
ddb5b488 1920
e8bfa90e 1921 struct ecommunity *old_ecom;
1922 struct ecommunity *new_ecom;
1923
1924 /* If doing VRF-to-VRF leaking, strip RTs. */
b53e67a3 1925 old_ecom = bgp_attr_get_ecommunity(&static_attr);
02212dee
LS
1926 if (old_ecom && CHECK_FLAG(to_bgp->af_flags[afi][safi],
1927 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
e8bfa90e 1928 new_ecom = ecommunity_dup(old_ecom);
1929 ecommunity_strip_rts(new_ecom);
b53e67a3 1930 bgp_attr_set_ecommunity(&static_attr, new_ecom);
1995cb77
DS
1931
1932 if (new_ecom->size == 0) {
1995cb77 1933 ecommunity_free(&new_ecom);
b53e67a3 1934 bgp_attr_set_ecommunity(&static_attr, NULL);
1995cb77
DS
1935 }
1936
e8bfa90e 1937 if (!old_ecom->refcnt)
1938 ecommunity_free(&old_ecom);
1939 }
1940
46dbf9d0
DA
1941 community_strip_accept_own(&static_attr);
1942
ddb5b488
PZ
1943 /*
1944 * Nexthop: stash and clear
1945 *
1946 * Nexthop is valid in context of VPN core, but not in destination vrf.
1947 * Stash it for later label resolution by vrf ingress path and then
1948 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1949 */
40381db7 1950 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
ddb5b488
PZ
1951
1952 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1953 nexthop_orig.family = nhfamily;
1954
c479b28e
DA
1955 /* If the path has accept-own community and the source VRF
1956 * is valid, reset next-hop to self, to allow importing own
1957 * routes between different VRFs on the same node.
8a02d9fe
DA
1958 * Set the nh ifindex to VRF's interface, not the real interface.
1959 * Let the kernel to decide with double lookup the real next-hop
1960 * interface when installing the route.
c479b28e 1961 */
8a02d9fe 1962 if (src_bgp) {
c479b28e 1963 subgroup_announce_reset_nhop(nhfamily, &static_attr);
8a02d9fe
DA
1964 ifp = if_get_vrf_loopback(src_vrf->vrf_id);
1965 if (ifp)
1966 static_attr.nh_ifindex = ifp->ifindex;
1967 }
c479b28e 1968
ddb5b488 1969 switch (nhfamily) {
ddb5b488
PZ
1970 case AF_INET:
1971 /* save */
40381db7 1972 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
12256b84 1973 nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
12a844a5 1974
02212dee 1975 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
12a844a5
DS
1976 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1977 static_attr.nexthop.s_addr =
1978 nexthop_orig.u.prefix4.s_addr;
1979
1980 static_attr.mp_nexthop_global_in =
40381db7 1981 path_vpn->attr->mp_nexthop_global_in;
12a844a5 1982 static_attr.mp_nexthop_len =
40381db7 1983 path_vpn->attr->mp_nexthop_len;
12a844a5 1984 }
de4d0a51 1985 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1986 break;
ddb5b488
PZ
1987 case AF_INET6:
1988 /* save */
40381db7 1989 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
13ccce6e 1990 nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
12a844a5 1991
02212dee 1992 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
12a844a5
DS
1993 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1994 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1995 }
ddb5b488
PZ
1996 break;
1997 }
1998
ddb5b488
PZ
1999 /*
2000 * route map handling
ddb5b488 2001 */
02212dee 2002 if (to_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
4b7e6066 2003 struct bgp_path_info info;
ddb5b488
PZ
2004 route_map_result_t ret;
2005
2006 memset(&info, 0, sizeof(info));
02212dee 2007 info.peer = to_bgp->peer_self;
ddb5b488 2008 info.attr = &static_attr;
1dcc9e5b 2009 info.extra = path_vpn->extra; /* Used for source-vrf filter */
02212dee 2010 ret = route_map_apply(to_bgp->vpn_policy[afi]
ddb5b488 2011 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1782514f 2012 p, &info);
ddb5b488
PZ
2013 if (RMAP_DENYMATCH == ret) {
2014 bgp_attr_flush(&static_attr); /* free any added parts */
2015 if (debug)
2016 zlog_debug(
2017 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
02212dee
LS
2018 __func__, to_bgp->name_pretty,
2019 to_bgp->vpn_policy[afi]
ddb5b488
PZ
2020 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
2021 ->name);
a486300b 2022 return false;
ddb5b488 2023 }
960035b2
PZ
2024 /*
2025 * if route-map changed nexthop, don't nexthop-self on output
2026 */
2027 if (!CHECK_FLAG(static_attr.rmap_change_flags,
2028 BATTR_RMAP_NEXTHOP_UNCHANGED))
2029 nexthop_self_flag = 0;
ddb5b488
PZ
2030 }
2031
2032 new_attr = bgp_attr_intern(&static_attr);
2033 bgp_attr_flush(&static_attr);
2034
02212dee 2035 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
ddb5b488
PZ
2036
2037 /*
2038 * ensure labels are copied
513bf8d6
PZ
2039 *
2040 * However, there is a special case: if the route originated in
2041 * another local VRF (as opposed to arriving via VPN), then the
2042 * nexthop is reached by hairpinning through this router (me)
2043 * using IP forwarding only (no LSP). Therefore, the route
2044 * imported to the VRF should not have labels attached. Note
2045 * that nexthop tracking is also involved: eliminating the
2046 * labels for these routes enables the non-labeled nexthops
2047 * from the originating VRF to be considered valid for this route.
ddb5b488 2048 */
02212dee 2049 if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
12a844a5
DS
2050 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2051 /* work back to original route */
da0c0ef7 2052 bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
513bf8d6 2053
12a844a5
DS
2054 /*
2055 * if original route was unicast,
2056 * then it did not arrive over vpn
2057 */
40381db7 2058 if (bpi_ultimate->net) {
12a844a5 2059 struct bgp_table *table;
513bf8d6 2060
9bcb3eef 2061 table = bgp_dest_table(bpi_ultimate->net);
12a844a5
DS
2062 if (table && (table->safi == SAFI_UNICAST))
2063 origin_local = 1;
2064 }
513bf8d6 2065
12a844a5 2066 /* copy labels */
40381db7
DS
2067 if (!origin_local && path_vpn->extra
2068 && path_vpn->extra->num_labels) {
2069 num_labels = path_vpn->extra->num_labels;
12a844a5
DS
2070 if (num_labels > BGP_MAX_LABELS)
2071 num_labels = BGP_MAX_LABELS;
40381db7 2072 pLabels = path_vpn->extra->label;
12a844a5 2073 }
ddb5b488 2074 }
513bf8d6 2075
b54892e0 2076 if (debug)
56ca3b5b 2077 zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
b54892e0 2078 path_vpn->net, num_labels);
ddb5b488 2079
8ea624a4
DA
2080 if (!leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels,
2081 num_labels, src_vrf, &nexthop_orig, nexthop_self_flag,
2082 debug))
2083 bgp_dest_unlock_node(bn);
2084
a486300b 2085 return true;
ddb5b488
PZ
2086}
2087
46dbf9d0
DA
2088bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
2089 struct bgp_path_info *path_vpn,
2090 struct prefix_rd *prd)
ddb5b488
PZ
2091{
2092 struct listnode *mnode, *mnnode;
2093 struct bgp *bgp;
a486300b 2094 bool leak_success = false;
ddb5b488
PZ
2095
2096 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2097
2098 if (debug)
40381db7 2099 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488
PZ
2100
2101 /* Loop over VRFs */
2102 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2103
40381db7
DS
2104 if (!path_vpn->extra
2105 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
a486300b 2106 leak_success |= vpn_leak_to_vrf_update_onevrf(
46dbf9d0 2107 bgp, from_bgp, path_vpn, prd);
ddb5b488
PZ
2108 }
2109 }
a486300b 2110 return leak_success;
ddb5b488
PZ
2111}
2112
1aa2c93e 2113void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn)
ddb5b488 2114{
b54892e0 2115 const struct prefix *p;
1b3510a0 2116 afi_t afi;
ddb5b488
PZ
2117 safi_t safi = SAFI_UNICAST;
2118 struct bgp *bgp;
2119 struct listnode *mnode, *mnnode;
9bcb3eef 2120 struct bgp_dest *bn;
40381db7 2121 struct bgp_path_info *bpi;
ddb5b488
PZ
2122 const char *debugmsg;
2123
2124 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2125
b54892e0 2126 if (debug)
56ca3b5b 2127 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
b54892e0 2128 path_vpn->net, path_vpn->type, path_vpn->sub_type);
960035b2 2129
ddb5b488 2130 if (debug)
40381db7 2131 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488 2132
40381db7 2133 if (!path_vpn->net) {
49e5a4a0 2134#ifdef ENABLE_BGP_VNC
40381db7
DS
2135 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2136 if (path_vpn->type == ZEBRA_ROUTE_BGP
2137 && path_vpn->sub_type == BGP_ROUTE_RFP) {
1b3510a0
PZ
2138
2139 return;
2140 }
56c2c080 2141#endif
1b3510a0 2142 if (debug)
40381db7
DS
2143 zlog_debug(
2144 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1b3510a0
PZ
2145 __func__);
2146 return;
2147 }
2148
9bcb3eef 2149 p = bgp_dest_get_prefix(path_vpn->net);
1b3510a0 2150 afi = family2afi(p->family);
ddb5b488
PZ
2151
2152 /* Loop over VRFs */
2153 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 2154 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488 2155 if (debug)
4ee5265a
DA
2156 zlog_debug("%s: from %s, skipping: %s",
2157 __func__, bgp->name_pretty,
ddb5b488
PZ
2158 debugmsg);
2159 continue;
2160 }
2161
2162 /* Check for intersection of route targets */
2d7cdc5b
DA
2163 if (!ecommunity_include(
2164 bgp->vpn_policy[afi]
2165 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
2166 bgp_attr_get_ecommunity(path_vpn->attr))) {
ddb5b488
PZ
2167
2168 continue;
2169 }
2170
2171 if (debug)
2172 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 2173 bgp->name_pretty);
ddb5b488
PZ
2174
2175 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6f94b685 2176
9bcb3eef 2177 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 2178 bpi = bpi->next) {
40381db7
DS
2179 if (bpi->extra
2180 && (struct bgp_path_info *)bpi->extra->parent
2181 == path_vpn) {
ddb5b488
PZ
2182 break;
2183 }
2184 }
2185
40381db7 2186 if (bpi) {
ddb5b488 2187 if (debug)
40381db7
DS
2188 zlog_debug("%s: deleting bpi %p", __func__,
2189 bpi);
2190 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
2191 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
2192 bgp_process(bgp, bn, afi, safi);
2193 }
9bcb3eef 2194 bgp_dest_unlock_node(bn);
ddb5b488
PZ
2195 }
2196}
2197
02212dee 2198void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)
ddb5b488 2199{
9bcb3eef 2200 struct bgp_dest *bn;
40381db7 2201 struct bgp_path_info *bpi;
ddb5b488
PZ
2202 safi_t safi = SAFI_UNICAST;
2203 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
2204
2205 if (debug)
2206 zlog_debug("%s: entry", __func__);
2207 /*
40381db7 2208 * Walk vrf table, delete bpi with bgp_orig in a different vrf
ddb5b488 2209 */
02212dee 2210 for (bn = bgp_table_top(to_bgp->rib[afi][safi]); bn;
ddb5b488
PZ
2211 bn = bgp_route_next(bn)) {
2212
9bcb3eef 2213 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 2214 bpi = bpi->next) {
02212dee
LS
2215 if (bpi->extra && bpi->extra->bgp_orig != to_bgp &&
2216 bpi->extra->parent &&
2217 is_pi_family_vpn(bpi->extra->parent)) {
ddb5b488
PZ
2218
2219 /* delete route */
02212dee 2220 bgp_aggregate_decrement(to_bgp,
9bcb3eef 2221 bgp_dest_get_prefix(bn),
b54892e0 2222 bpi, afi, safi);
40381db7 2223 bgp_path_info_delete(bn, bpi);
02212dee 2224 bgp_process(to_bgp, bn, afi, safi);
ddb5b488
PZ
2225 }
2226 }
2227 }
2228}
2229
02212dee 2230void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,
ddb5b488
PZ
2231 afi_t afi)
2232{
9bcb3eef 2233 struct bgp_dest *pdest;
ddb5b488
PZ
2234 safi_t safi = SAFI_MPLS_VPN;
2235
02212dee 2236 assert(vpn_from);
73aed584 2237
ddb5b488
PZ
2238 /*
2239 * Walk vpn table
2240 */
02212dee 2241 for (pdest = bgp_table_top(vpn_from->rib[afi][safi]); pdest;
9bcb3eef 2242 pdest = bgp_route_next(pdest)) {
ddb5b488 2243 struct bgp_table *table;
9bcb3eef 2244 struct bgp_dest *bn;
40381db7 2245 struct bgp_path_info *bpi;
ddb5b488 2246
ddb5b488 2247 /* This is the per-RD table of prefixes */
9bcb3eef 2248 table = bgp_dest_get_bgp_table_info(pdest);
ddb5b488
PZ
2249
2250 if (!table)
2251 continue;
2252
2253 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
2254
9bcb3eef 2255 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 2256 bpi = bpi->next) {
ddb5b488 2257
02212dee
LS
2258 if (bpi->extra &&
2259 bpi->extra->bgp_orig == to_bgp)
ddb5b488
PZ
2260 continue;
2261
02212dee 2262 vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
46dbf9d0 2263 bpi, NULL);
ddb5b488
PZ
2264 }
2265 }
2266 }
2267}
2268
d92a55df
PZ
2269/*
2270 * This function is called for definition/deletion/change to a route-map
2271 */
ddb5b488
PZ
2272static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
2273{
2274 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2275 afi_t afi;
2276 struct route_map *rmap;
2277
2278 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2279 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
2280
2281 return;
2282 }
2283
2284 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
2285
2286 for (afi = 0; afi < AFI_MAX; ++afi) {
2287
d92a55df
PZ
2288 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
2289 && !strcmp(rmap_name,
ddb5b488
PZ
2290 bgp->vpn_policy[afi]
2291 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
2292
2293 if (debug)
2294 zlog_debug(
2295 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2296 __func__, rmap_name, bgp->as,
2297 afi2str(afi));
2298
2299 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2300 bgp_get_default(), bgp);
2301 if (debug)
2302 zlog_debug("%s: after vpn_leak_prechange",
2303 __func__);
2304
d92a55df
PZ
2305 /* in case of definition/deletion */
2306 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
2307 rmap;
ddb5b488
PZ
2308
2309 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2310 bgp_get_default(), bgp);
d92a55df 2311
ddb5b488
PZ
2312 if (debug)
2313 zlog_debug("%s: after vpn_leak_postchange",
2314 __func__);
2315 }
2316
d92a55df
PZ
2317 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
2318 && !strcmp(rmap_name,
2319 bgp->vpn_policy[afi]
2320 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
2321
2322 if (debug) {
2323 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
2324 __func__, rmap_name, bgp->as,
2325 afi2str(afi));
b9c7bc5a 2326 }
ddb5b488
PZ
2327
2328 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2329 bgp_get_default(), bgp);
2330
d92a55df
PZ
2331 /* in case of definition/deletion */
2332 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
2333 rmap;
ddb5b488
PZ
2334
2335 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2336 bgp_get_default(), bgp);
2337 }
2338 }
2339}
2340
636f7608
CS
2341/* This API is used during router-id change, reflect VPNs
2342 * auto RD and RT values and readvertise routes to VPN table.
2343 */
e65fe398
MS
2344void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
2345 bool is_config)
636f7608
CS
2346{
2347 afi_t afi;
de7cee09
AR
2348 int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
2349 | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
636f7608
CS
2350 char *vname;
2351 const char *export_name;
2352 char buf[RD_ADDRSTRLEN];
2353 struct bgp *bgp_import;
2354 struct listnode *node;
2355 struct ecommunity *ecom;
9c2fd3fe 2356 enum vpn_policy_direction idir, edir;
636f7608 2357
de7cee09
AR
2358 /*
2359 * Router-id change that is not explicitly configured
2360 * (a change from zebra, frr restart for example)
2361 * should not replace a configured vpn RD/RT.
2362 */
2363 if (!is_config) {
2364 if (debug)
2365 zlog_debug("%s: skipping non explicit router-id change",
2366 __func__);
2367 return;
2368 }
2369
636f7608
CS
2370 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2371 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2372 return;
2373
2374 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
636f7608
CS
2375 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2376 edir = BGP_VPN_POLICY_DIR_TOVPN;
2377
2378 for (afi = 0; afi < AFI_MAX; ++afi) {
2379 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
2380 continue;
2381
2382 if (withdraw) {
2383 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
2384 afi, bgp_get_default(), bgp);
2385 if (debug)
2386 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2387 __func__, export_name);
2388
2389 /* Remove import RT from VRFs */
2390 ecom = bgp->vpn_policy[afi].rtlist[edir];
2391 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2392 export_vrf, node, vname)) {
67bd620c 2393 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2394 bgp_import = bgp_get_default();
2395 else
2396 bgp_import = bgp_lookup_by_name(vname);
636f7608
CS
2397 if (!bgp_import)
2398 continue;
2399
de7cee09
AR
2400 ecommunity_del_val(
2401 bgp_import->vpn_policy[afi]
2402 .rtlist[idir],
636f7608 2403 (struct ecommunity_val *)ecom->val);
636f7608
CS
2404 }
2405 } else {
2406 /* New router-id derive auto RD and RT and export
2407 * to VPN
2408 */
2409 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
2410 &bgp->vrf_prd_auto);
2411 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
2412 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
4a8cd6ad 2413 sizeof(buf), bgp->asnotation);
f6a460f9
SB
2414
2415 /* free up pre-existing memory if any and allocate
2416 * the ecommunity attribute with new RD/RT
2417 */
2418 if (bgp->vpn_policy[afi].rtlist[edir])
2419 ecommunity_free(
2420 &bgp->vpn_policy[afi].rtlist[edir]);
2421 bgp->vpn_policy[afi].rtlist[edir] = ecommunity_str2com(
2422 buf, ECOMMUNITY_ROUTE_TARGET, 0);
636f7608
CS
2423
2424 /* Update import_vrf rt_list */
2425 ecom = bgp->vpn_policy[afi].rtlist[edir];
2426 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2427 export_vrf, node, vname)) {
67bd620c 2428 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2429 bgp_import = bgp_get_default();
2430 else
2431 bgp_import = bgp_lookup_by_name(vname);
636f7608
CS
2432 if (!bgp_import)
2433 continue;
2434 if (bgp_import->vpn_policy[afi].rtlist[idir])
2435 bgp_import->vpn_policy[afi].rtlist[idir]
2436 = ecommunity_merge(
2437 bgp_import->vpn_policy[afi]
2438 .rtlist[idir], ecom);
2439 else
2440 bgp_import->vpn_policy[afi].rtlist[idir]
2441 = ecommunity_dup(ecom);
636f7608 2442 }
e65fe398 2443
636f7608
CS
2444 /* Update routes to VPN */
2445 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
2446 afi, bgp_get_default(),
2447 bgp);
2448 if (debug)
2449 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2450 __func__, export_name);
2451 }
2452 }
2453}
2454
ddb5b488
PZ
2455void vpn_policy_routemap_event(const char *rmap_name)
2456{
2457 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2458 struct listnode *mnode, *mnnode;
2459 struct bgp *bgp;
2460
2461 if (debug)
2462 zlog_debug("%s: entry", __func__);
2463
2464 if (bm->bgp == NULL) /* may be called during cleanup */
2465 return;
2466
2467 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
2468 vpn_policy_routemap_update(bgp, rmap_name);
2469}
2470
1d4e8b0d 2471void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 2472 afi_t afi, safi_t safi)
2473{
2474 const char *export_name;
9c2fd3fe 2475 enum vpn_policy_direction idir, edir;
9ecf931b
CS
2476 char *vname, *tmp_name;
2477 char buf[RD_ADDRSTRLEN];
44338987 2478 struct ecommunity *ecom;
2479 bool first_export = false;
636f7608 2480 int debug;
9ecf931b
CS
2481 struct listnode *node;
2482 bool is_inst_match = false;
44338987 2483
5742e42b 2484 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
44338987 2485 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2486 edir = BGP_VPN_POLICY_DIR_TOVPN;
2487
636f7608
CS
2488 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2489 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2490
1d4e8b0d
DS
2491 /*
2492 * Cross-ref both VRFs. Also, note if this is the first time
44338987 2493 * any VRF is importing from "import_vrf".
2494 */
a8dadcf6 2495 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
5742e42b 2496 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
a8dadcf6 2497
9ecf931b
CS
2498 /* Check the import_vrf list of destination vrf for the source vrf name,
2499 * insert otherwise.
2500 */
2501 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
2502 node, tmp_name)) {
2503 if (strcmp(vname, tmp_name) == 0) {
2504 is_inst_match = true;
2505 break;
2506 }
2507 }
2508 if (!is_inst_match)
2509 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2510 vname);
b9d45462
DS
2511 else
2512 XFREE(MTYPE_TMP, vname);
44338987 2513
9ecf931b
CS
2514 /* Check if the source vrf already exports to any vrf,
2515 * first time export requires to setup auto derived RD/RT values.
2516 * Add the destination vrf name to export vrf list if it is
2517 * not present.
2518 */
2519 is_inst_match = false;
44338987 2520 vname = XSTRDUP(MTYPE_TMP, export_name);
9ecf931b
CS
2521 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2522 first_export = true;
2523 } else {
2524 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2525 node, tmp_name)) {
2526 if (strcmp(vname, tmp_name) == 0) {
2527 is_inst_match = true;
2528 break;
2529 }
2530 }
2531 }
2532 if (!is_inst_match)
2533 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
2534 vname);
b9d45462
DS
2535 else
2536 XFREE(MTYPE_TMP, vname);
2537
44338987 2538 /* Update import RT for current VRF using export RT of the VRF we're
2539 * importing from. First though, make sure "import_vrf" has that
2540 * set.
2541 */
2542 if (first_export) {
1d4e8b0d
DS
2543 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
2544 &from_bgp->vrf_prd_auto);
2545 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
2546 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 2547 BGP_VPN_POLICY_TOVPN_RD_SET);
4a8cd6ad
PG
2548 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd, buf,
2549 sizeof(buf), from_bgp->asnotation);
1d4e8b0d 2550 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 2551 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 2552 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 2553 BGP_CONFIG_VRF_TO_VRF_EXPORT);
13b7e7f0
DS
2554 from_bgp->vpn_policy[afi].tovpn_label =
2555 BGP_PREVENT_VRF_2_VRF_LEAK;
44338987 2556 }
1d4e8b0d
DS
2557 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2558 if (to_bgp->vpn_policy[afi].rtlist[idir])
2559 to_bgp->vpn_policy[afi].rtlist[idir] =
2560 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 2561 .rtlist[idir], ecom);
2562 else
1d4e8b0d
DS
2563 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
2564 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 2565
636f7608
CS
2566 if (debug) {
2567 const char *from_name;
6a37bfb7 2568 char *ecom1, *ecom2;
636f7608
CS
2569
2570 from_name = from_bgp->name ? from_bgp->name :
2571 VRF_DEFAULT_NAME;
6a37bfb7
DS
2572
2573 ecom1 = ecommunity_ecom2str(
2574 to_bgp->vpn_policy[afi].rtlist[idir],
2575 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2576
2577 ecom2 = ecommunity_ecom2str(
2578 to_bgp->vpn_policy[afi].rtlist[edir],
2579 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2580
2581 zlog_debug(
2582 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2583 __func__, from_name, export_name, first_export, ecom1,
2584 ecom2);
2585
2586 ecommunity_strfree(&ecom1);
2587 ecommunity_strfree(&ecom2);
636f7608
CS
2588 }
2589
44338987 2590 /* Does "import_vrf" first need to export its routes or that
2591 * is already done and we just need to import those routes
2592 * from the global table?
2593 */
2594 if (first_export)
1d4e8b0d 2595 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 2596 else
1d4e8b0d 2597 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 2598}
2599
1d4e8b0d 2600void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 2601 afi_t afi, safi_t safi)
2602{
a8dadcf6 2603 const char *export_name, *tmp_name;
9c2fd3fe 2604 enum vpn_policy_direction idir, edir;
44338987 2605 char *vname;
9ecf931b 2606 struct ecommunity *ecom = NULL;
44338987 2607 struct listnode *node;
636f7608 2608 int debug;
44338987 2609
5742e42b
DS
2610 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2611 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
44338987 2612 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2613 edir = BGP_VPN_POLICY_DIR_TOVPN;
2614
636f7608
CS
2615 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2616 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2617
44338987 2618 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
2619 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
2620 vname)) {
a8dadcf6 2621 if (strcmp(vname, tmp_name) == 0)
020a3f60 2622 break;
44338987 2623 }
1d4e8b0d
DS
2624
2625 /*
2626 * We do not check in the cli if the passed in bgp
2627 * instance is actually imported into us before
2628 * we call this function. As such if we do not
2629 * find this in the import_vrf list than
2630 * we just need to return safely.
2631 */
44338987 2632 if (!vname)
2633 return;
2634
636f7608
CS
2635 if (debug)
2636 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
2637
44338987 2638 /* Remove "import_vrf" from our import list. */
1d4e8b0d 2639 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 2640 XFREE(MTYPE_TMP, vname);
2641
2642 /* Remove routes imported from "import_vrf". */
2643 /* TODO: In the current logic, we have to first remove all
2644 * imported routes and then (if needed) import back routes
2645 */
1d4e8b0d 2646 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 2647
1d4e8b0d 2648 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
ae6a6fb4
DS
2649 if (!to_bgp->vpn_policy[afi].rmap[idir])
2650 UNSET_FLAG(to_bgp->af_flags[afi][safi],
2651 BGP_CONFIG_VRF_TO_VRF_IMPORT);
9ecf931b
CS
2652 if (to_bgp->vpn_policy[afi].rtlist[idir])
2653 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 2654 } else {
1d4e8b0d 2655 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
9ecf931b
CS
2656 if (ecom)
2657 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 2658 (struct ecommunity_val *)ecom->val);
1d4e8b0d 2659 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 2660 }
2661
89d59347
DS
2662 /*
2663 * What?
2664 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2665 * below is checking for NULL that export_vrf can be
2666 * NULL, consequently it is complaining( like a cabbage )
2667 * that we could dereference and crash in the listcount(..)
2668 * check below.
2669 * So make it happy, under protest, with liberty and justice
2670 * for all.
2671 */
1d4e8b0d 2672 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 2673
44338987 2674 /* Remove us from "import_vrf's" export list. If no other VRF
2675 * is importing from "import_vrf", cleanup appropriately.
2676 */
1d4e8b0d 2677 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 2678 node, vname)) {
2679 if (strcmp(vname, export_name) == 0)
2680 break;
2681 }
2682
1d4e8b0d
DS
2683 /*
2684 * If we have gotten to this point then the vname must
2685 * exist. If not, we are in a world of trouble and
2686 * have slag sitting around.
2687 *
2688 * import_vrf and export_vrf must match in having
2689 * the in/out names as appropriate.
9ecf931b
CS
2690 * export_vrf list could have been cleaned up
2691 * as part of no router bgp source instnace.
1d4e8b0d 2692 */
9ecf931b
CS
2693 if (!vname)
2694 return;
1d4e8b0d
DS
2695
2696 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 2697 XFREE(MTYPE_TMP, vname);
2698
1d4e8b0d
DS
2699 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2700 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
2701 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
2702 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 2703 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 2704 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 2705 sizeof(struct prefix_rd));
1d4e8b0d 2706 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 2707 BGP_VPN_POLICY_TOVPN_RD_SET);
13b7e7f0
DS
2708 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2709
44338987 2710 }
2711}
2712
718e3744 2713/* For testing purpose, static route of MPLS-VPN. */
2714DEFUN (vpnv4_network,
2715 vpnv4_network_cmd,
d114b977 2716 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 2717 "Specify a network to announce via BGP\n"
0c7b1b01 2718 "IPv4 prefix\n"
718e3744 2719 "Specify Route Distinguisher\n"
2720 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2721 "VPN NLRI label (tag)\n"
2722 "VPN NLRI label (tag)\n"
2723 "Label value\n")
718e3744 2724{
d62a17ae 2725 int idx_ipv4_prefixlen = 1;
2726 int idx_ext_community = 3;
2727 int idx_label = 5;
2728 return bgp_static_set_safi(
2729 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2730 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
2731 NULL, NULL, NULL, NULL);
137446f9
LB
2732}
2733
2734DEFUN (vpnv4_network_route_map,
2735 vpnv4_network_route_map_cmd,
70dd370f 2736 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
137446f9 2737 "Specify a network to announce via BGP\n"
0c7b1b01 2738 "IPv4 prefix\n"
137446f9
LB
2739 "Specify Route Distinguisher\n"
2740 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2741 "VPN NLRI label (tag)\n"
2742 "VPN NLRI label (tag)\n"
2743 "Label value\n"
137446f9
LB
2744 "route map\n"
2745 "route map name\n")
2746{
d62a17ae 2747 int idx_ipv4_prefixlen = 1;
2748 int idx_ext_community = 3;
2749 int idx_label = 5;
2750 int idx_word_2 = 7;
2751 return bgp_static_set_safi(
2752 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2753 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2754 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 2755}
2756
2757/* For testing purpose, static route of MPLS-VPN. */
2758DEFUN (no_vpnv4_network,
2759 no_vpnv4_network_cmd,
d114b977 2760 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 2761 NO_STR
2762 "Specify a network to announce via BGP\n"
0c7b1b01 2763 "IPv4 prefix\n"
718e3744 2764 "Specify Route Distinguisher\n"
2765 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2766 "VPN NLRI label (tag)\n"
2767 "VPN NLRI label (tag)\n"
2768 "Label value\n")
718e3744 2769{
d62a17ae 2770 int idx_ipv4_prefixlen = 2;
2771 int idx_ext_community = 4;
2772 int idx_label = 6;
2773 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
2774 argv[idx_ipv4_prefixlen]->arg,
2775 argv[idx_ext_community]->arg,
2776 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 2777}
2778
c286be96
LX
2779DEFUN (vpnv6_network,
2780 vpnv6_network_cmd,
70dd370f 2781 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
c286be96
LX
2782 "Specify a network to announce via BGP\n"
2783 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2784 "Specify Route Distinguisher\n"
2785 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2786 "VPN NLRI label (tag)\n"
2787 "VPN NLRI label (tag)\n"
2788 "Label value\n"
11daee81
DS
2789 "route map\n"
2790 "route map name\n")
c286be96 2791{
d62a17ae 2792 int idx_ipv6_prefix = 1;
2793 int idx_ext_community = 3;
2794 int idx_label = 5;
2795 int idx_word_2 = 7;
2796 if (argc == 8)
2797 return bgp_static_set_safi(
2798 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2799 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2800 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2801 else
2802 return bgp_static_set_safi(
2803 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2804 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2805 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
2806}
2807
2808/* For testing purpose, static route of MPLS-VPN. */
2809DEFUN (no_vpnv6_network,
2810 no_vpnv6_network_cmd,
d114b977 2811 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
2812 NO_STR
2813 "Specify a network to announce via BGP\n"
2814 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2815 "Specify Route Distinguisher\n"
2816 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2817 "VPN NLRI label (tag)\n"
2818 "VPN NLRI label (tag)\n"
2819 "Label value\n")
c286be96 2820{
d62a17ae 2821 int idx_ipv6_prefix = 2;
2822 int idx_ext_community = 4;
2823 int idx_label = 6;
2824 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
2825 argv[idx_ipv6_prefix]->arg,
2826 argv[idx_ext_community]->arg,
2827 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
2828}
2829
d62a17ae 2830int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
2831 enum bgp_show_type type, void *output_arg, int tags,
9f049418 2832 bool use_json)
718e3744 2833{
d62a17ae 2834 struct bgp *bgp;
2835 struct bgp_table *table;
27bb782a
DA
2836 uint16_t show_flags = 0;
2837
2838 if (use_json)
2839 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
d62a17ae 2840
2841 bgp = bgp_get_default();
2842 if (bgp == NULL) {
2843 if (!use_json)
2844 vty_out(vty, "No BGP process is configured\n");
16307668
RW
2845 else
2846 vty_out(vty, "{}\n");
d62a17ae 2847 return CMD_WARNING;
2848 }
1ae44dfc 2849 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a 2850 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
27bb782a 2851 output_arg, show_flags);
718e3744 2852}
2853
4f280b15
LB
2854DEFUN (show_bgp_ip_vpn_all_rd,
2855 show_bgp_ip_vpn_all_rd_cmd,
a111dd97 2856 "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
e3e29b32
LB
2857 SHOW_STR
2858 BGP_STR
05e588f4 2859 BGP_VPNVX_HELP_STR
e3e29b32 2860 "Display VPN NLRI specific information\n"
af8528fa 2861 "Display VPN NLRI specific information\n"
e3e29b32
LB
2862 "Display information for a route distinguisher\n"
2863 "VPN Route Distinguisher\n"
a111dd97 2864 "All VPN Route Distinguishers\n"
e3e29b32
LB
2865 JSON_STR)
2866{
d62a17ae 2867 int ret;
2868 struct prefix_rd prd;
2869 afi_t afi;
2870 int idx = 0;
2871
2872 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
a111dd97
TA
2873 /* Constrain search if user supplies RD && RD != "all" */
2874 if (argv_find(argv, argc, "rd", &idx)
2875 && strcmp(argv[idx + 1]->arg, "all")) {
a4d82a8a 2876 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 2877 if (!ret) {
2878 vty_out(vty,
2879 "%% Malformed Route Distinguisher\n");
2880 return CMD_WARNING;
2881 }
2882 return bgp_show_mpls_vpn(vty, afi, &prd,
2883 bgp_show_type_normal, NULL, 0,
2884 use_json(argc, argv));
2885 } else {
2886 return bgp_show_mpls_vpn(vty, afi, NULL,
2887 bgp_show_type_normal, NULL, 0,
2888 use_json(argc, argv));
2889 }
2890 }
2891 return CMD_SUCCESS;
718e3744 2892}
2893
af8528fa
LB
2894ALIAS(show_bgp_ip_vpn_all_rd,
2895 show_bgp_ip_vpn_rd_cmd,
a111dd97 2896 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
af8528fa
LB
2897 SHOW_STR
2898 BGP_STR
2899 BGP_VPNVX_HELP_STR
2900 "Display VPN NLRI specific information\n"
2901 "Display information for a route distinguisher\n"
2902 "VPN Route Distinguisher\n"
a111dd97 2903 "All VPN Route Distinguishers\n"
af8528fa
LB
2904 JSON_STR)
2905
2906#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
2907DEFUN (show_ip_bgp_vpn_rd,
2908 show_ip_bgp_vpn_rd_cmd,
a111dd97 2909 "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
718e3744 2910 SHOW_STR
2911 IP_STR
2912 BGP_STR
4f280b15 2913 BGP_AFI_HELP_STR
00e6edb9 2914 BGP_AF_MODIFIER_STR
718e3744 2915 "Display information for a route distinguisher\n"
a111dd97
TA
2916 "VPN Route Distinguisher\n"
2917 "All VPN Route Distinguishers\n")
718e3744 2918{
d62a17ae 2919 int idx_ext_community = argc - 1;
2920 int ret;
2921 struct prefix_rd prd;
2922 afi_t afi;
2923 int idx = 0;
2924
2925 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
2926 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2927 return bgp_show_mpls_vpn(vty, afi, NULL,
2928 bgp_show_type_normal, NULL, 0,
2929 0);
d62a17ae 2930 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2931 if (!ret) {
2932 vty_out(vty, "%% Malformed Route Distinguisher\n");
2933 return CMD_WARNING;
2934 }
2935 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2936 NULL, 0, 0);
2937 }
2938 return CMD_SUCCESS;
2939}
718e3744 2940
4f280b15
LB
2941DEFUN (show_ip_bgp_vpn_all,
2942 show_ip_bgp_vpn_all_cmd,
2943 "show [ip] bgp <vpnv4|vpnv6>",
2944 SHOW_STR
2945 IP_STR
2946 BGP_STR
2947 BGP_VPNVX_HELP_STR)
2948{
d62a17ae 2949 afi_t afi;
2950 int idx = 0;
4f280b15 2951
d62a17ae 2952 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2953 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2954 NULL, 0, 0);
2955 return CMD_SUCCESS;
4f280b15
LB
2956}
2957
3f227172
PG
2958DEFUN (show_ip_bgp_vpn_all_tags,
2959 show_ip_bgp_vpn_all_tags_cmd,
2960 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 2961 SHOW_STR
2962 IP_STR
2963 BGP_STR
3f227172
PG
2964 BGP_VPNVX_HELP_STR
2965 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 2966 "Display BGP tags for prefixes\n")
2967{
d62a17ae 2968 afi_t afi;
2969 int idx = 0;
3f227172 2970
d62a17ae 2971 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2972 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2973 NULL, 1, 0);
2974 return CMD_SUCCESS;
718e3744 2975}
2976
3f227172
PG
2977DEFUN (show_ip_bgp_vpn_rd_tags,
2978 show_ip_bgp_vpn_rd_tags_cmd,
a111dd97 2979 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
718e3744 2980 SHOW_STR
2981 IP_STR
2982 BGP_STR
3f227172 2983 BGP_VPNVX_HELP_STR
718e3744 2984 "Display information for a route distinguisher\n"
2985 "VPN Route Distinguisher\n"
a111dd97 2986 "All VPN Route Distinguishers\n"
718e3744 2987 "Display BGP tags for prefixes\n")
2988{
d62a17ae 2989 int idx_ext_community = 5;
2990 int ret;
2991 struct prefix_rd prd;
2992 afi_t afi;
2993 int idx = 0;
2994
2995 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
2996 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2997 return bgp_show_mpls_vpn(vty, afi, NULL,
2998 bgp_show_type_normal, NULL, 1,
2999 0);
d62a17ae 3000 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3001 if (!ret) {
3002 vty_out(vty, "%% Malformed Route Distinguisher\n");
3003 return CMD_WARNING;
3004 }
3005 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
3006 NULL, 1, 0);
3007 }
3008 return CMD_SUCCESS;
718e3744 3009}
3010
3f227172
PG
3011DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
3012 show_ip_bgp_vpn_all_neighbor_routes_cmd,
3013 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 3014 SHOW_STR
3015 IP_STR
3016 BGP_STR
3f227172
PG
3017 BGP_VPNVX_HELP_STR
3018 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 3019 "Detailed information on TCP and BGP neighbor connections\n"
3020 "Neighbor to display information about\n"
856ca177 3021 "Display routes learned from neighbor\n"
9973d184 3022 JSON_STR)
718e3744 3023{
d62a17ae 3024 int idx_ipv4 = 6;
3025 union sockunion su;
3026 struct peer *peer;
3027 int ret;
9f049418 3028 bool uj = use_json(argc, argv);
d62a17ae 3029 afi_t afi;
3030 int idx = 0;
3031
3032 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3033 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3034 if (ret < 0) {
3035 if (uj) {
3036 json_object *json_no = NULL;
3037 json_no = json_object_new_object();
3038 json_object_string_add(json_no, "warning",
3039 "Malformed address");
3040 vty_out(vty, "%s\n",
3041 json_object_to_json_string(json_no));
3042 json_object_free(json_no);
3043 } else
3044 vty_out(vty, "Malformed address: %s\n",
3045 argv[idx_ipv4]->arg);
3046 return CMD_WARNING;
3047 }
3048
3049 peer = peer_lookup(NULL, &su);
3050 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3051 if (uj) {
3052 json_object *json_no = NULL;
3053 json_no = json_object_new_object();
3054 json_object_string_add(
3055 json_no, "warning",
3056 "No such neighbor or address family");
3057 vty_out(vty, "%s\n",
3058 json_object_to_json_string(json_no));
3059 json_object_free(json_no);
3060 } else
3061 vty_out(vty,
3062 "%% No such neighbor or address family\n");
3063 return CMD_WARNING;
3064 }
3065
3066 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
3067 &su, 0, uj);
3068 }
3069 return CMD_SUCCESS;
718e3744 3070}
3071
3f227172
PG
3072DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
3073 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
a111dd97 3074 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
718e3744 3075 SHOW_STR
3076 IP_STR
3077 BGP_STR
3f227172 3078 BGP_VPNVX_HELP_STR
718e3744 3079 "Display information for a route distinguisher\n"
3080 "VPN Route Distinguisher\n"
a111dd97 3081 "All VPN Route Distinguishers\n"
718e3744 3082 "Detailed information on TCP and BGP neighbor connections\n"
3083 "Neighbor to display information about\n"
856ca177 3084 "Display routes learned from neighbor\n"
9973d184 3085 JSON_STR)
718e3744 3086{
d62a17ae 3087 int idx_ext_community = 5;
3088 int idx_ipv4 = 7;
3089 int ret;
3090 union sockunion su;
3091 struct peer *peer;
3092 struct prefix_rd prd;
a111dd97 3093 bool prefix_rd_all = false;
9f049418 3094 bool uj = use_json(argc, argv);
d62a17ae 3095 afi_t afi;
3096 int idx = 0;
3097
3098 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
3099 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3100 prefix_rd_all = true;
3101 else {
3102 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3103 if (!ret) {
3104 if (uj) {
3105 json_object *json_no = NULL;
3106 json_no = json_object_new_object();
3107 json_object_string_add(
3108 json_no, "warning",
3109 "Malformed Route Distinguisher");
3110 vty_out(vty, "%s\n",
3111 json_object_to_json_string(
3112 json_no));
3113 json_object_free(json_no);
3114 } else
3115 vty_out(vty,
3116 "%% Malformed Route Distinguisher\n");
3117 return CMD_WARNING;
3118 }
d62a17ae 3119 }
3120
3121 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3122 if (ret < 0) {
3123 if (uj) {
3124 json_object *json_no = NULL;
3125 json_no = json_object_new_object();
3126 json_object_string_add(json_no, "warning",
3127 "Malformed address");
3128 vty_out(vty, "%s\n",
3129 json_object_to_json_string(json_no));
3130 json_object_free(json_no);
3131 } else
3132 vty_out(vty, "Malformed address: %s\n",
3133 argv[idx_ext_community]->arg);
3134 return CMD_WARNING;
3135 }
3136
3137 peer = peer_lookup(NULL, &su);
3138 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3139 if (uj) {
3140 json_object *json_no = NULL;
3141 json_no = json_object_new_object();
3142 json_object_string_add(
3143 json_no, "warning",
3144 "No such neighbor or address family");
3145 vty_out(vty, "%s\n",
3146 json_object_to_json_string(json_no));
3147 json_object_free(json_no);
3148 } else
3149 vty_out(vty,
3150 "%% No such neighbor or address family\n");
3151 return CMD_WARNING;
3152 }
3153
a111dd97
TA
3154 if (prefix_rd_all)
3155 return bgp_show_mpls_vpn(vty, afi, NULL,
3156 bgp_show_type_neighbor, &su, 0,
3157 uj);
3158 else
3159 return bgp_show_mpls_vpn(vty, afi, &prd,
3160 bgp_show_type_neighbor, &su, 0,
3161 uj);
d62a17ae 3162 }
3163 return CMD_SUCCESS;
718e3744 3164}
3165
3f227172
PG
3166DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
3167 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
3168 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 3169 SHOW_STR
3170 IP_STR
3171 BGP_STR
3f227172
PG
3172 BGP_VPNVX_HELP_STR
3173 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 3174 "Detailed information on TCP and BGP neighbor connections\n"
3175 "Neighbor to display information about\n"
856ca177 3176 "Display the routes advertised to a BGP neighbor\n"
9973d184 3177 JSON_STR)
718e3744 3178{
d62a17ae 3179 int idx_ipv4 = 6;
3180 int ret;
3181 struct peer *peer;
3182 union sockunion su;
9f049418 3183 bool uj = use_json(argc, argv);
d62a17ae 3184 afi_t afi;
3185 int idx = 0;
3186
3187 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3188 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3189 if (ret < 0) {
3190 if (uj) {
3191 json_object *json_no = NULL;
3192 json_no = json_object_new_object();
3193 json_object_string_add(json_no, "warning",
3194 "Malformed address");
3195 vty_out(vty, "%s\n",
3196 json_object_to_json_string(json_no));
3197 json_object_free(json_no);
3198 } else
3199 vty_out(vty, "Malformed address: %s\n",
3200 argv[idx_ipv4]->arg);
3201 return CMD_WARNING;
3202 }
3203 peer = peer_lookup(NULL, &su);
3204 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3205 if (uj) {
3206 json_object *json_no = NULL;
3207 json_no = json_object_new_object();
3208 json_object_string_add(
3209 json_no, "warning",
3210 "No such neighbor or address family");
3211 vty_out(vty, "%s\n",
3212 json_object_to_json_string(json_no));
3213 json_object_free(json_no);
3214 } else
3215 vty_out(vty,
3216 "%% No such neighbor or address family\n");
3217 return CMD_WARNING;
3218 }
3219 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3220 SAFI_MPLS_VPN, uj);
3221 }
3222 return CMD_SUCCESS;
718e3744 3223}
3224
3f227172
PG
3225DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
3226 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
a111dd97 3227 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
718e3744 3228 SHOW_STR
3229 IP_STR
3230 BGP_STR
3f227172 3231 BGP_VPNVX_HELP_STR
718e3744 3232 "Display information for a route distinguisher\n"
3233 "VPN Route Distinguisher\n"
a111dd97 3234 "All VPN Route Distinguishers\n"
718e3744 3235 "Detailed information on TCP and BGP neighbor connections\n"
3236 "Neighbor to display information about\n"
856ca177 3237 "Display the routes advertised to a BGP neighbor\n"
9973d184 3238 JSON_STR)
718e3744 3239{
d62a17ae 3240 int idx_ext_community = 5;
3241 int idx_ipv4 = 7;
3242 int ret;
3243 struct peer *peer;
3244 struct prefix_rd prd;
3245 union sockunion su;
9f049418 3246 bool uj = use_json(argc, argv);
d62a17ae 3247 afi_t afi;
3248 int idx = 0;
3249
3250 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3251 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3252 if (ret < 0) {
3253 if (uj) {
3254 json_object *json_no = NULL;
3255 json_no = json_object_new_object();
3256 json_object_string_add(json_no, "warning",
3257 "Malformed address");
3258 vty_out(vty, "%s\n",
3259 json_object_to_json_string(json_no));
3260 json_object_free(json_no);
3261 } else
3262 vty_out(vty, "Malformed address: %s\n",
3263 argv[idx_ext_community]->arg);
3264 return CMD_WARNING;
3265 }
3266 peer = peer_lookup(NULL, &su);
3267 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3268 if (uj) {
3269 json_object *json_no = NULL;
3270 json_no = json_object_new_object();
3271 json_object_string_add(
3272 json_no, "warning",
3273 "No such neighbor or address family");
3274 vty_out(vty, "%s\n",
3275 json_object_to_json_string(json_no));
3276 json_object_free(json_no);
3277 } else
3278 vty_out(vty,
3279 "%% No such neighbor or address family\n");
3280 return CMD_WARNING;
3281 }
3282
a111dd97
TA
3283 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3284 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3285 SAFI_MPLS_VPN, uj);
d62a17ae 3286 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3287 if (!ret) {
3288 if (uj) {
3289 json_object *json_no = NULL;
3290 json_no = json_object_new_object();
3291 json_object_string_add(
3292 json_no, "warning",
3293 "Malformed Route Distinguisher");
3294 vty_out(vty, "%s\n",
3295 json_object_to_json_string(json_no));
3296 json_object_free(json_no);
3297 } else
3298 vty_out(vty,
3299 "%% Malformed Route Distinguisher\n");
3300 return CMD_WARNING;
3301 }
3302
3303 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
3304 SAFI_MPLS_VPN, uj);
3305 }
3306 return CMD_SUCCESS;
718e3744 3307}
d6902373 3308#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 3309
d62a17ae 3310void bgp_mplsvpn_init(void)
718e3744 3311{
d62a17ae 3312 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
3313 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
3314 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 3315
d62a17ae 3316 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
3317 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 3318
d62a17ae 3319 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 3320 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 3321#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 3322 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 3323 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
3324 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
3325 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
3326 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
3327 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
3328 install_element(VIEW_NODE,
3329 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
3330 install_element(VIEW_NODE,
3331 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 3332#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 3333}
301ad80a
PG
3334
3335vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
3336{
3337 struct listnode *mnode, *mnnode;
3338 struct bgp *bgp;
9a659715
PG
3339 afi_t afi = AFI_IP;
3340
3341 if (eckey->unit_size == IPV6_ECOMMUNITY_SIZE)
3342 afi = AFI_IP6;
301ad80a
PG
3343
3344 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
3345 struct ecommunity *ec;
3346
3347 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3348 continue;
3349
9a659715
PG
3350 ec = bgp->vpn_policy[afi].import_redirect_rtlist;
3351
3352 if (ec && eckey->unit_size != ec->unit_size)
3353 continue;
301ad80a 3354
2d7cdc5b 3355 if (ecommunity_include(ec, eckey))
301ad80a
PG
3356 return bgp->vrf_id;
3357 }
3358 return VRF_UNKNOWN;
3359}
3bd70bf8
PZ
3360
3361/*
3362 * The purpose of this function is to process leaks that were deferred
3363 * from earlier per-vrf configuration due to not-yet-existing default
3364 * vrf, in other words, configuration such as:
3365 *
3366 * router bgp MMM vrf FOO
3367 * address-family ipv4 unicast
3368 * rd vpn export 1:1
3369 * exit-address-family
3370 *
3371 * router bgp NNN
3372 * ...
3373 *
3374 * This function gets called when the default instance ("router bgp NNN")
3375 * is created.
3376 */
3377void vpn_leak_postchange_all(void)
3378{
3379 struct listnode *next;
3380 struct bgp *bgp;
3381 struct bgp *bgp_default = bgp_get_default();
3382
3383 assert(bgp_default);
3384
3385 /* First, do any exporting from VRFs to the single VPN RIB */
3386 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3387
3388 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3389 continue;
3390
3391 vpn_leak_postchange(
3392 BGP_VPN_POLICY_DIR_TOVPN,
3393 AFI_IP,
3394 bgp_default,
3395 bgp);
3396
3397 vpn_leak_postchange(
3398 BGP_VPN_POLICY_DIR_TOVPN,
3399 AFI_IP6,
3400 bgp_default,
3401 bgp);
3402 }
3403
3404 /* Now, do any importing to VRFs from the single VPN RIB */
3405 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3406
3407 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3408 continue;
3409
3410 vpn_leak_postchange(
3411 BGP_VPN_POLICY_DIR_FROMVPN,
3412 AFI_IP,
3413 bgp_default,
3414 bgp);
3415
3416 vpn_leak_postchange(
3417 BGP_VPN_POLICY_DIR_FROMVPN,
3418 AFI_IP6,
3419 bgp_default,
3420 bgp);
3421 }
3422}
9ecf931b
CS
3423
3424/* When a bgp vrf instance is unconfigured, remove its routes
3425 * from the VPN table and this vrf could be importing routes from other
3426 * bgp vrf instnaces, unimport them.
3427 * VRF X and VRF Y are exporting routes to each other.
3428 * When VRF X is deleted, unimport its routes from all target vrfs,
3429 * also VRF Y should unimport its routes from VRF X table.
3430 * This will ensure VPN table is cleaned up appropriately.
3431 */
ff8a8a7a 3432void bgp_vpn_leak_unimport(struct bgp *from_bgp)
9ecf931b
CS
3433{
3434 struct bgp *to_bgp;
3435 const char *tmp_name;
3436 char *vname;
3437 struct listnode *node, *next;
3438 safi_t safi = SAFI_UNICAST;
3439 afi_t afi;
3440 bool is_vrf_leak_bind;
3441 int debug;
3442
3443 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
ff8a8a7a 3444 return;
9ecf931b
CS
3445
3446 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3447 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3448
3449 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3450
3451 for (afi = 0; afi < AFI_MAX; ++afi) {
3452 /* vrf leak is for IPv4 and IPv6 Unicast only */
3453 if (afi != AFI_IP && afi != AFI_IP6)
3454 continue;
3455
3456 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3457 if (from_bgp == to_bgp)
3458 continue;
3459
3460 /* Unimport and remove source vrf from the
3461 * other vrfs import list.
3462 */
3463 struct vpn_policy *to_vpolicy;
3464
3465 is_vrf_leak_bind = false;
3466 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3467 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
3468 vname)) {
3469 if (strcmp(vname, tmp_name) == 0) {
3470 is_vrf_leak_bind = true;
3471 break;
3472 }
3473 }
3474 /* skip this bgp instance as there is no leak to this
3475 * vrf instance.
3476 */
3477 if (!is_vrf_leak_bind)
3478 continue;
3479
3480 if (debug)
3481 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3482 __func__, from_bgp->name_pretty,
3483 to_bgp->name_pretty, afi2str(afi),
3484 to_vpolicy->import_vrf->count);
3485
3486 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
3487
3488 /* readd vrf name as unimport removes import vrf name
3489 * from the destination vrf's import list where the
3490 * `import vrf` configuration still exist.
3491 */
3492 vname = XSTRDUP(MTYPE_TMP, tmp_name);
3493 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
3494 vname);
3495 SET_FLAG(to_bgp->af_flags[afi][safi],
3496 BGP_CONFIG_VRF_TO_VRF_IMPORT);
3497
3498 /* If to_bgp exports its routes to the bgp vrf
3499 * which is being deleted, un-import the
3500 * to_bgp routes from VPN.
3501 */
3502 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
3503 .export_vrf, node,
3504 vname)) {
3505 if (strcmp(vname, tmp_name) == 0) {
3506 vrf_unimport_from_vrf(from_bgp, to_bgp,
3507 afi, safi);
3508 break;
3509 }
3510 }
3511 }
3512 }
ff8a8a7a 3513 return;
9ecf931b 3514}
48381346
CS
3515
3516/* When a router bgp is configured, there could be a bgp vrf
3517 * instance importing routes from this newly configured
3518 * bgp vrf instance. Export routes from configured
3519 * bgp vrf to VPN.
3520 * VRF Y has import from bgp vrf x,
3521 * when a bgp vrf x instance is created, export its routes
3522 * to VRF Y instance.
3523 */
3524void bgp_vpn_leak_export(struct bgp *from_bgp)
3525{
3526 afi_t afi;
3527 const char *export_name;
3528 char *vname;
3529 struct listnode *node, *next;
3530 struct ecommunity *ecom;
9c2fd3fe 3531 enum vpn_policy_direction idir, edir;
48381346
CS
3532 safi_t safi = SAFI_UNICAST;
3533 struct bgp *to_bgp;
3534 int debug;
3535
3536 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3537 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3538
3539 idir = BGP_VPN_POLICY_DIR_FROMVPN;
3540 edir = BGP_VPN_POLICY_DIR_TOVPN;
3541
00d968c4 3542 export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
48381346
CS
3543
3544 for (afi = 0; afi < AFI_MAX; ++afi) {
3545 /* vrf leak is for IPv4 and IPv6 Unicast only */
3546 if (afi != AFI_IP && afi != AFI_IP6)
3547 continue;
3548
3549 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3550 if (from_bgp == to_bgp)
3551 continue;
3552
3553 /* bgp instance has import list, check to see if newly
3554 * configured bgp instance is the list.
3555 */
3556 struct vpn_policy *to_vpolicy;
3557
3558 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3559 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
3560 node, vname)) {
3561 if (strcmp(vname, export_name) != 0)
3562 continue;
3563
3564 if (debug)
3565 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3566 __func__,
3567 export_name, to_bgp->name_pretty);
3568
3569 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
3570 /* remove import rt, it will be readded
3571 * as part of import from vrf.
3572 */
3573 if (ecom)
3574 ecommunity_del_val(
3575 to_vpolicy->rtlist[idir],
3576 (struct ecommunity_val *)
3577 ecom->val);
3578 vrf_import_from_vrf(to_bgp, from_bgp,
3579 afi, safi);
3580 break;
3581
3582 }
3583 }
3584 }
3585}