]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Merge pull request #10447 from ton31337/fix/json_with_whitespaces
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
CommitLineData
718e3744 1/* MPLS-VPN
896014f4
DL
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#include <zebra.h>
22
23#include "command.h"
24#include "prefix.h"
25#include "log.h"
26#include "memory.h"
27#include "stream.h"
3f9c7369 28#include "queue.h"
039f3a34 29#include "filter.h"
ddb5b488 30#include "mpls.h"
b9c7bc5a
PZ
31#include "json.h"
32#include "zclient.h"
9bedbb1e 33
718e3744 34#include "bgpd/bgpd.h"
ddb5b488 35#include "bgpd/bgp_debug.h"
14454c9f 36#include "bgpd/bgp_errors.h"
718e3744 37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_route.h"
39#include "bgpd/bgp_attr.h"
9bedbb1e 40#include "bgpd/bgp_label.h"
718e3744 41#include "bgpd/bgp_mplsvpn.h"
48a5452b 42#include "bgpd/bgp_packet.h"
3f227172 43#include "bgpd/bgp_vty.h"
784d3a42 44#include "bgpd/bgp_vpn.h"
ddb5b488
PZ
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_zebra.h"
47#include "bgpd/bgp_nexthop.h"
960035b2 48#include "bgpd/bgp_nht.h"
0a2f9ac1 49#include "bgpd/bgp_evpn.h"
b72c9e14 50#include "bgpd/bgp_memory.h"
718e3744 51
49e5a4a0 52#ifdef ENABLE_BGP_VNC
f8b6f499 53#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
54#endif
55
ddb5b488
PZ
56/*
57 * Definitions and external declarations.
58 */
59extern struct zclient *zclient;
60
d62a17ae 61extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
62 int *index, afi_t *afi)
3f227172 63{
d62a17ae 64 int ret = 0;
65 if (argv_find(argv, argc, "vpnv4", index)) {
66 ret = 1;
67 if (afi)
68 *afi = AFI_IP;
69 } else if (argv_find(argv, argc, "vpnv6", index)) {
70 ret = 1;
71 if (afi)
72 *afi = AFI_IP6;
73 }
74 return ret;
3f227172
PG
75}
76
d7c0a89a 77uint32_t decode_label(mpls_label_t *label_pnt)
718e3744 78{
d7c0a89a
QY
79 uint32_t l;
80 uint8_t *pnt = (uint8_t *)label_pnt;
718e3744 81
d7c0a89a
QY
82 l = ((uint32_t)*pnt++ << 12);
83 l |= (uint32_t)*pnt++ << 4;
84 l |= (uint32_t)((*pnt & 0xf0) >> 4);
d62a17ae 85 return l;
718e3744 86}
87
d62a17ae 88void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
65efcfce 89{
d7c0a89a 90 uint8_t *pnt = (uint8_t *)label_pnt;
d62a17ae 91 if (pnt == NULL)
92 return;
13b7e7f0
DS
93 if (label == BGP_PREVENT_VRF_2_VRF_LEAK) {
94 *label_pnt = label;
95 return;
96 }
d62a17ae 97 *pnt++ = (label >> 12) & 0xff;
98 *pnt++ = (label >> 4) & 0xff;
99 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
65efcfce
LB
100}
101
d62a17ae 102int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
103 struct bgp_nlri *packet)
718e3744 104{
d62a17ae 105 struct prefix p;
506dbcc8
QY
106 uint8_t psize = 0;
107 uint8_t prefixlen;
d7c0a89a 108 uint16_t type;
d62a17ae 109 struct rd_as rd_as;
110 struct rd_ip rd_ip;
ef1af5e5 111 struct prefix_rd prd = {0};
ddb5b488 112 mpls_label_t label = {0};
d62a17ae 113 afi_t afi;
114 safi_t safi;
be92fc9f 115 bool addpath_capable;
d7c0a89a 116 uint32_t addpath_id;
506dbcc8 117 int ret = 0;
d62a17ae 118
d62a17ae 119 /* Make prefix_rd */
120 prd.family = AF_UNSPEC;
121 prd.prefixlen = 64;
122
506dbcc8
QY
123 struct stream *data = stream_new(packet->length);
124 stream_put(data, packet->nlri, packet->length);
d62a17ae 125 afi = packet->afi;
126 safi = packet->safi;
127 addpath_id = 0;
128
be92fc9f 129 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
718e3744 130
50905aa2 131#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
506dbcc8 132 while (STREAM_READABLE(data) > 0) {
d62a17ae 133 /* Clear prefix structure. */
134 memset(&p, 0, sizeof(struct prefix));
135
be92fc9f 136 if (addpath_capable) {
506dbcc8 137 STREAM_GET(&addpath_id, data, BGP_ADDPATH_ID_LEN);
a3a850a1 138 addpath_id = ntohl(addpath_id);
506dbcc8
QY
139 }
140
141 if (STREAM_READABLE(data) < 1) {
142 flog_err(
143 EC_BGP_UPDATE_RCV,
144 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
145 peer->host, packet->length);
146 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
147 goto done;
d62a17ae 148 }
149
150 /* Fetch prefix length. */
506dbcc8 151 STREAM_GETC(data, prefixlen);
d62a17ae 152 p.family = afi2family(packet->afi);
153 psize = PSIZE(prefixlen);
154
155 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
af4c2728 156 flog_err(
e50f7cfd 157 EC_BGP_UPDATE_RCV,
d62a17ae 158 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
159 peer->host, prefixlen);
506dbcc8
QY
160 ret = BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
161 goto done;
d62a17ae 162 }
163
164 /* sanity check against packet data */
506dbcc8 165 if (STREAM_READABLE(data) < psize) {
af4c2728 166 flog_err(
e50f7cfd 167 EC_BGP_UPDATE_RCV,
d62a17ae 168 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
506dbcc8
QY
169 peer->host, prefixlen, packet->length);
170 ret = BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
171 goto done;
d62a17ae 172 }
173
174 /* sanity check against storage for the IP address portion */
175 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
af4c2728 176 flog_err(
e50f7cfd 177 EC_BGP_UPDATE_RCV,
d62a17ae 178 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
179 peer->host,
180 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
181 sizeof(p.u));
506dbcc8
QY
182 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
183 goto done;
d62a17ae 184 }
185
186 /* Sanity check against max bitlen of the address family */
187 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
af4c2728 188 flog_err(
e50f7cfd 189 EC_BGP_UPDATE_RCV,
d62a17ae 190 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
191 peer->host,
192 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
193 p.family, prefix_blen(&p));
506dbcc8
QY
194 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
195 goto done;
d62a17ae 196 }
197
198 /* Copy label to prefix. */
506dbcc8
QY
199 if (STREAM_READABLE(data) < BGP_LABEL_BYTES) {
200 flog_err(
201 EC_BGP_UPDATE_RCV,
202 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
203 peer->host, packet->length);
204 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
205 goto done;
206 }
207
208 STREAM_GET(&label, data, BGP_LABEL_BYTES);
d62a17ae 209 bgp_set_valid_label(&label);
210
211 /* Copy routing distinguisher to rd. */
506dbcc8
QY
212 if (STREAM_READABLE(data) < 8) {
213 flog_err(
214 EC_BGP_UPDATE_RCV,
215 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
216 peer->host, packet->length);
217 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
218 goto done;
219 }
220 STREAM_GET(&prd.val, data, 8);
d62a17ae 221
222 /* Decode RD type. */
506dbcc8 223 type = decode_rd_type(prd.val);
d62a17ae 224
225 switch (type) {
226 case RD_TYPE_AS:
506dbcc8 227 decode_rd_as(&prd.val[2], &rd_as);
d62a17ae 228 break;
229
230 case RD_TYPE_AS4:
506dbcc8 231 decode_rd_as4(&prd.val[2], &rd_as);
d62a17ae 232 break;
233
234 case RD_TYPE_IP:
506dbcc8 235 decode_rd_ip(&prd.val[2], &rd_ip);
d62a17ae 236 break;
fe770c88 237
49e5a4a0 238#ifdef ENABLE_BGP_VNC
d62a17ae 239 case RD_TYPE_VNC_ETH:
240 break;
65efcfce
LB
241#endif
242
d62a17ae 243 default:
1c50c1c0 244 flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
d62a17ae 245 break; /* just report */
246 }
247
506dbcc8
QY
248 /* exclude label & RD */
249 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8;
250 STREAM_GET(p.u.val, data, psize - VPN_PREFIXLEN_MIN_BYTES);
d62a17ae 251
252 if (attr) {
253 bgp_update(peer, &p, addpath_id, attr, packet->afi,
254 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 255 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
d62a17ae 256 } else {
257 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
258 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 259 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
d62a17ae 260 }
261 }
262 /* Packet length consistency check. */
506dbcc8 263 if (STREAM_READABLE(data) != 0) {
af4c2728 264 flog_err(
e50f7cfd 265 EC_BGP_UPDATE_RCV,
72327cf3 266 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
506dbcc8 267 peer->host, STREAM_READABLE(data));
513386b5 268 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
d62a17ae 269 }
270
506dbcc8
QY
271 goto done;
272
273stream_failure:
274 flog_err(
275 EC_BGP_UPDATE_RCV,
276 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
277 peer->host, packet->length);
278 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
279
280done:
281 stream_free(data);
282 return ret;
283
50905aa2 284#undef VPN_PREFIXLEN_MIN_BYTES
718e3744 285}
286
ddb5b488
PZ
287/*
288 * This function informs zebra of the label this vrf sets on routes
289 * leaked to VPN. Zebra should install this label in the kernel with
290 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
291 *
292 * Sending this vrf-label association is qualified by a) whether vrf->vpn
293 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
294 * are set) and b) whether vpn-policy label is set.
295 *
296 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
297 * for this vrf, which zebra interprets to mean "delete this vrf-label
298 * association."
299 */
300void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
301{
302 mpls_label_t label = MPLS_LABEL_NONE;
ddb5b488
PZ
303 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
304
ddb5b488
PZ
305 if (bgp->vrf_id == VRF_UNKNOWN) {
306 if (debug) {
307 zlog_debug(
3efd0893 308 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
960035b2 309 __func__, bgp->name_pretty, afi2str(afi));
ddb5b488
PZ
310 }
311 return;
312 }
313
314 if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
315 label = bgp->vpn_policy[afi].tovpn_label;
316 }
317
318 if (debug) {
319 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
960035b2
PZ
320 __func__, bgp->name_pretty, afi2str(afi), label,
321 bgp->vrf_id);
ddb5b488
PZ
322 }
323
3f518d59
DS
324 if (label == BGP_PREVENT_VRF_2_VRF_LEAK)
325 label = MPLS_LABEL_NONE;
ddb5b488
PZ
326 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
327 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
328}
329
330/*
331 * If zebra tells us vrf has become unconfigured, tell zebra not to
332 * use this label to forward to the vrf anymore
333 */
334void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
335{
336 mpls_label_t label = MPLS_LABEL_NONE;
337 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
338
339 if (bgp->vrf_id == VRF_UNKNOWN) {
340 if (debug) {
341 zlog_debug(
342 "%s: vrf_id not set, can't delete zebra vrf label",
343 __func__);
344 }
345 return;
346 }
347
348 if (debug) {
349 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
960035b2 350 bgp->name_pretty, bgp->vrf_id);
ddb5b488
PZ
351 }
352
353 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
354 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
355}
356
b72c9e14
HS
357/*
358 * This function informs zebra of the srv6-function this vrf sets on routes
359 * leaked to VPN. Zebra should install this srv6-function in the kernel with
360 * an action of "End.DT4/6's IP FIB to route the PDU."
361 */
362void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi)
363{
364 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
365 enum seg6local_action_t act;
1bda3e62 366 struct seg6local_context ctx = {};
b72c9e14
HS
367 struct in6_addr *tovpn_sid = NULL;
368 struct in6_addr *tovpn_sid_ls = NULL;
369 struct vrf *vrf;
370 char buf[256] = {0};
371
372 if (bgp->vrf_id == VRF_UNKNOWN) {
373 if (debug)
7de4c885 374 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
b72c9e14
HS
375 __func__, bgp->name_pretty, afi2str(afi));
376 return;
377 }
378
379 tovpn_sid = bgp->vpn_policy[afi].tovpn_sid;
380 if (!tovpn_sid) {
381 if (debug)
382 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__,
383 bgp->name_pretty, afi2str(afi));
384 return;
385 }
386
387 if (debug) {
388 inet_ntop(AF_INET6, tovpn_sid, buf, sizeof(buf));
389 zlog_debug("%s: vrf %s: afi %s: setting sid %s for vrf id %d",
390 __func__, bgp->name_pretty, afi2str(afi), buf,
391 bgp->vrf_id);
392 }
393
394 vrf = vrf_lookup_by_id(bgp->vrf_id);
395 if (!vrf)
396 return;
397
398 ctx.table = vrf->data.l.table_id;
399 act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
400 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
401 zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
402
403 tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
404 *tovpn_sid_ls = *tovpn_sid;
405 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent = tovpn_sid_ls;
406}
407
408/*
409 * If zebra tells us vrf has become unconfigured, tell zebra not to
410 * use this srv6-function to forward to the vrf anymore
411 */
412void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi)
413{
414 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
415
416 if (bgp->vrf_id == VRF_UNKNOWN) {
417 if (debug)
7de4c885 418 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
b72c9e14
HS
419 __func__, bgp->name_pretty, afi2str(afi));
420 return;
421 }
422
423 if (debug)
424 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__,
425 bgp->name_pretty, bgp->vrf_id);
426
427 zclient_send_localsid(zclient,
428 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent,
429 bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, NULL);
430 XFREE(MTYPE_BGP_SRV6_SID,
431 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent);
432}
433
e70e9f8e
PZ
434int vpn_leak_label_callback(
435 mpls_label_t label,
436 void *labelid,
437 bool allocated)
438{
439 struct vpn_policy *vp = (struct vpn_policy *)labelid;
440 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
441
442 if (debug)
443 zlog_debug("%s: label=%u, allocated=%d",
444 __func__, label, allocated);
445
446 if (!allocated) {
447 /*
448 * previously-allocated label is now invalid
449 */
450 if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
451 (vp->tovpn_label != MPLS_LABEL_NONE)) {
452
453 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
454 vp->afi, bgp_get_default(), vp->bgp);
455 vp->tovpn_label = MPLS_LABEL_NONE;
456 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
457 vp->afi, bgp_get_default(), vp->bgp);
458 }
459 return 0;
460 }
461
462 /*
463 * New label allocation
464 */
465 if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
466
467 /*
468 * not currently configured for auto label, reject allocation
469 */
470 return -1;
471 }
472
473 if (vp->tovpn_label != MPLS_LABEL_NONE) {
474 if (label == vp->tovpn_label) {
475 /* already have same label, accept but do nothing */
476 return 0;
477 }
478 /* Shouldn't happen: different label allocation */
e50f7cfd 479 flog_err(EC_BGP_LABEL,
1c50c1c0
QY
480 "%s: %s had label %u but got new assignment %u",
481 __func__, vp->bgp->name_pretty, vp->tovpn_label,
482 label);
e70e9f8e
PZ
483 /* use new one */
484 }
485
486 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
487 vp->afi, bgp_get_default(), vp->bgp);
488 vp->tovpn_label = label;
489 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
490 vp->afi, bgp_get_default(), vp->bgp);
491
492 return 0;
493}
494
b72c9e14
HS
495static void sid_register(struct bgp *bgp, const struct in6_addr *sid,
496 const char *locator_name)
497{
498 struct bgp_srv6_function *func;
499 func = XCALLOC(MTYPE_BGP_SRV6_FUNCTION,
500 sizeof(struct bgp_srv6_function));
501 func->sid = *sid;
502 snprintf(func->locator_name, sizeof(func->locator_name),
503 "%s", locator_name);
504 listnode_add(bgp->srv6_functions, func);
505}
506
507static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
508{
509 struct listnode *node;
510 struct bgp_srv6_function *func;
7de4c885 511
b72c9e14
HS
512 for (ALL_LIST_ELEMENTS_RO(bgp->srv6_functions, node, func))
513 if (sid_same(&func->sid, sid))
514 return true;
515 return false;
516}
517
7de4c885
HS
518/*
519 * if index != 0: try to allocate as index-mode
520 * else: try to allocate as auto-mode
521 */
a45cd34e 522static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
921c7e77 523 struct in6_addr *sid_locator)
b72c9e14
HS
524{
525 struct listnode *node;
526 struct prefix_ipv6 *chunk;
527 struct in6_addr sid_buf;
528 bool alloced = false;
73e770b7 529 int label = 0;
b72c9e14 530
921c7e77 531 if (!bgp || !sid_locator)
b72c9e14
HS
532 return false;
533
534 for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
921c7e77 535 *sid_locator = chunk->prefix;
b72c9e14
HS
536 sid_buf = chunk->prefix;
537 if (index != 0) {
a45cd34e
RS
538 label = index << 12;
539 transpose_sid(&sid_buf, label, 64, 16);
b72c9e14
HS
540 if (sid_exist(bgp, &sid_buf))
541 return false;
542 alloced = true;
543 break;
7de4c885
HS
544 }
545
546 for (size_t i = 1; i < 255; i++) {
a45cd34e
RS
547 label = i << 12;
548 transpose_sid(&sid_buf, label, 64, 16);
7de4c885
HS
549 if (sid_exist(bgp, &sid_buf))
550 continue;
551 alloced = true;
552 break;
b72c9e14
HS
553 }
554 }
555
556 if (!alloced)
a45cd34e 557 return 0;
b72c9e14
HS
558
559 sid_register(bgp, &sid_buf, bgp->srv6_locator_name);
a45cd34e 560 return label;
b72c9e14
HS
561}
562
563void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
564{
565 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
b72c9e14 566 char buf[256];
921c7e77 567 struct in6_addr *tovpn_sid, *tovpn_sid_locator;
a45cd34e 568 uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
b72c9e14
HS
569 bool tovpn_sid_auto = false;
570
571 if (debug)
572 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
573 __func__, bgp_vrf->name_pretty, afi2str(afi));
574
575 /* skip when tovpn sid is already allocated on vrf instance */
576 if (bgp_vrf->vpn_policy[afi].tovpn_sid)
577 return;
578
7de4c885
HS
579 /*
580 * skip when bgp vpn instance ins't allocated
581 * or srv6 locator chunk isn't allocated
582 */
c0d950a0 583 if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
b72c9e14
HS
584 return;
585
586 tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
587 tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
588 BGP_VPN_POLICY_TOVPN_SID_AUTO);
589
590 /* skip when VPN isn't configured on vrf-instance */
591 if (tovpn_sid_index == 0 && !tovpn_sid_auto)
592 return;
593
594 /* check invalid case both configured index and auto */
f7cafbb7 595 if (tovpn_sid_index != 0 && tovpn_sid_auto) {
b72c9e14
HS
596 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
597 __func__);
598 return;
599 }
600
921c7e77
RS
601 tovpn_sid_locator =
602 XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
a45cd34e 603 tovpn_sid_transpose_label =
921c7e77 604 alloc_new_sid(bgp_vpn, tovpn_sid_index, tovpn_sid_locator);
a45cd34e 605 if (tovpn_sid_transpose_label == 0) {
b72c9e14
HS
606 zlog_debug("%s: not allocated new sid for vrf %s: afi %s",
607 __func__, bgp_vrf->name_pretty, afi2str(afi));
608 return;
609 }
610
921c7e77
RS
611 tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
612 *tovpn_sid = *tovpn_sid_locator;
613 transpose_sid(tovpn_sid, tovpn_sid_transpose_label,
614 BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET,
615 BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH);
616
b72c9e14 617 if (debug) {
921c7e77 618 inet_ntop(AF_INET6, tovpn_sid, buf, sizeof(buf));
b72c9e14
HS
619 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
620 __func__, buf, bgp_vrf->name_pretty,
621 afi2str(afi));
622 }
921c7e77
RS
623
624 bgp_vrf->vpn_policy[afi].tovpn_sid = tovpn_sid;
625 bgp_vrf->vpn_policy[afi].tovpn_sid_locator = tovpn_sid_locator;
a45cd34e
RS
626 bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label =
627 tovpn_sid_transpose_label;
b72c9e14
HS
628}
629
a45cd34e
RS
630void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
631 uint8_t len)
632{
633 for (uint8_t idx = 0; idx < len; idx++) {
634 uint8_t tidx = offset + idx;
635 sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8));
636 if (label >> (19 - idx) & 0x1)
637 sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8);
638 }
639}
640
3dc339cd 641static bool ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
ddb5b488 642{
f6e07e1b 643 uint32_t i, j;
ddb5b488
PZ
644
645 if (!e1 || !e2)
3dc339cd 646 return false;
ddb5b488
PZ
647 for (i = 0; i < e1->size; ++i) {
648 for (j = 0; j < e2->size; ++j) {
9a659715
PG
649 if (!memcmp(e1->val + (i * e1->unit_size),
650 e2->val + (j * e2->unit_size),
651 e1->unit_size)) {
ddb5b488 652
3dc339cd 653 return true;
ddb5b488
PZ
654 }
655 }
656 }
3dc339cd 657 return false;
ddb5b488
PZ
658}
659
40381db7 660static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
4b7e6066 661 uint32_t n)
e37fb4bf
PZ
662{
663 uint32_t i;
664
40381db7 665 if (!bpi->extra) {
e37fb4bf
PZ
666 if (!n)
667 return true;
668 else
669 return false;
670 }
671
40381db7 672 if (n != bpi->extra->num_labels)
e37fb4bf
PZ
673 return false;
674
675 for (i = 0; i < n; ++i) {
40381db7 676 if (label[i] != bpi->extra->label[i])
e37fb4bf
PZ
677 return false;
678 }
679 return true;
680}
681
682/*
683 * make encoded route labels match specified encoded label set
684 */
40381db7 685static void setlabels(struct bgp_path_info *bpi,
4b7e6066
DS
686 mpls_label_t *label, /* array of labels */
687 uint32_t num_labels)
e37fb4bf
PZ
688{
689 if (num_labels)
690 assert(label);
691 assert(num_labels <= BGP_MAX_LABELS);
692
693 if (!num_labels) {
40381db7
DS
694 if (bpi->extra)
695 bpi->extra->num_labels = 0;
e37fb4bf
PZ
696 return;
697 }
698
40381db7 699 struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
e37fb4bf
PZ
700 uint32_t i;
701
702 for (i = 0; i < num_labels; ++i) {
703 extra->label[i] = label[i];
704 if (!bgp_is_valid_label(&label[i])) {
705 bgp_set_valid_label(&extra->label[i]);
706 }
707 }
708 extra->num_labels = num_labels;
709}
710
dbcf19b8
HS
711/*
712 * make encoded route SIDs match specified encoded sid set
713 */
714static void setsids(struct bgp_path_info *bpi,
715 struct in6_addr *sid,
716 uint32_t num_sids)
717{
718 uint32_t i;
719 struct bgp_path_info_extra *extra;
720
721 if (num_sids)
722 assert(sid);
723 assert(num_sids <= BGP_MAX_SIDS);
724
725 if (!num_sids) {
726 if (bpi->extra)
727 bpi->extra->num_sids = 0;
728 return;
729 }
730
731 extra = bgp_path_info_extra_get(bpi);
7de4c885 732 for (i = 0; i < num_sids; i++)
16f3db2d 733 memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr));
dbcf19b8
HS
734 extra->num_sids = num_sids;
735}
736
d79ff732
HS
737static void unsetsids(struct bgp_path_info *bpi)
738{
739 struct bgp_path_info_extra *extra;
740
741 extra = bgp_path_info_extra_get(bpi);
742 extra->num_sids = 0;
743 memset(extra->sid, 0, sizeof(extra->sid));
744}
745
ddb5b488 746/*
18ee8310 747 * returns pointer to new bgp_path_info upon success
ddb5b488 748 */
4b7e6066
DS
749static struct bgp_path_info *
750leak_update(struct bgp *bgp, /* destination bgp instance */
9bcb3eef 751 struct bgp_dest *bn, struct attr *new_attr, /* already interned */
40381db7 752 afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
4b7e6066
DS
753 mpls_label_t *label, uint32_t num_labels, void *parent,
754 struct bgp *bgp_orig, struct prefix *nexthop_orig,
755 int nexthop_self_flag, int debug)
ddb5b488 756{
9bcb3eef 757 const struct prefix *p = bgp_dest_get_prefix(bn);
40381db7
DS
758 struct bgp_path_info *bpi;
759 struct bgp_path_info *bpi_ultimate;
4b7e6066 760 struct bgp_path_info *new;
16f3db2d 761 struct bgp_path_info_extra *extra;
dbcf19b8 762 uint32_t num_sids = 0;
7de4c885 763
dbcf19b8
HS
764 if (new_attr->srv6_l3vpn || new_attr->srv6_vpn)
765 num_sids = 1;
766
b54892e0
DS
767 if (debug)
768 zlog_debug(
56ca3b5b 769 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
b54892e0
DS
770 __func__, bgp->name_pretty, bn, source_bpi->type,
771 source_bpi->sub_type);
ddb5b488 772
f46d45c1
PZ
773 /*
774 * Routes that are redistributed into BGP from zebra do not get
775 * nexthop tracking. However, if those routes are subsequently
776 * imported to other RIBs within BGP, the leaked routes do not
777 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
778 * in order to determine if the route we are currently leaking
779 * should have nexthop tracking, we must find the ultimate
780 * parent so we can check its sub_type.
781 *
40381db7 782 * As of now, source_bpi may at most be a second-generation route
f46d45c1
PZ
783 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
784 * Using a loop here supports more complex intra-bgp import-export
785 * schemes that could be implemented in the future.
3bd70bf8 786 *
f46d45c1 787 */
da0c0ef7 788 bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi);
f46d45c1 789
ddb5b488
PZ
790 /*
791 * match parent
792 */
9bcb3eef 793 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
40381db7 794 if (bpi->extra && bpi->extra->parent == parent)
ddb5b488
PZ
795 break;
796 }
797
40381db7
DS
798 if (bpi) {
799 bool labelssame = labels_same(bpi, label, num_labels);
e37fb4bf 800
8fac400c
AR
801 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
802 && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
803 if (debug) {
804 zlog_debug(
805 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
806 __func__, bgp->name_pretty,
807 source_bpi->flags, bpi->flags, p);
808 }
809 return NULL;
810 }
811
40381db7
DS
812 if (attrhash_cmp(bpi->attr, new_attr) && labelssame
813 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
ddb5b488
PZ
814
815 bgp_attr_unintern(&new_attr);
816 if (debug)
817 zlog_debug(
56ca3b5b 818 "%s: ->%s: %pBD: Found route, no change",
b54892e0 819 __func__, bgp->name_pretty, bn);
ddb5b488
PZ
820 return NULL;
821 }
822
823 /* attr is changed */
40381db7 824 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
ddb5b488
PZ
825
826 /* Rewrite BGP route information. */
40381db7
DS
827 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
828 bgp_path_info_restore(bn, bpi);
ddb5b488 829 else
40381db7
DS
830 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
831 bgp_attr_unintern(&bpi->attr);
832 bpi->attr = new_attr;
833 bpi->uptime = bgp_clock();
ddb5b488 834
e37fb4bf
PZ
835 /*
836 * rewrite labels
837 */
838 if (!labelssame)
40381db7 839 setlabels(bpi, label, num_labels);
e37fb4bf 840
dbcf19b8
HS
841 /*
842 * rewrite sid
843 */
844 if (num_sids) {
16f3db2d 845 if (new_attr->srv6_l3vpn) {
7de4c885
HS
846 setsids(bpi, &new_attr->srv6_l3vpn->sid,
847 num_sids);
16f3db2d
RS
848
849 extra = bgp_path_info_extra_get(bpi);
850
851 extra->sid[0].loc_block_len =
852 new_attr->srv6_l3vpn->loc_block_len;
853 extra->sid[0].loc_node_len =
854 new_attr->srv6_l3vpn->loc_node_len;
855 extra->sid[0].func_len =
856 new_attr->srv6_l3vpn->func_len;
857 extra->sid[0].arg_len =
858 new_attr->srv6_l3vpn->arg_len;
ea7cd161
RS
859 extra->sid[0].transposition_len =
860 new_attr->srv6_l3vpn->transposition_len;
861 extra->sid[0].transposition_offset =
862 new_attr->srv6_l3vpn
863 ->transposition_offset;
16f3db2d 864 } else if (new_attr->srv6_vpn)
7de4c885
HS
865 setsids(bpi, &new_attr->srv6_vpn->sid,
866 num_sids);
d79ff732
HS
867 } else
868 unsetsids(bpi);
dbcf19b8 869
960035b2 870 if (nexthop_self_flag)
40381db7 871 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
960035b2
PZ
872
873 struct bgp *bgp_nexthop = bgp;
874 int nh_valid;
875
40381db7
DS
876 if (bpi->extra && bpi->extra->bgp_orig)
877 bgp_nexthop = bpi->extra->bgp_orig;
960035b2 878
0a2f9ac1 879 /*
880 * No nexthop tracking for redistributed routes or for
881 * EVPN-imported routes that get leaked.
882 */
883 if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
884 is_pi_family_evpn(bpi_ultimate))
960035b2
PZ
885 nh_valid = 1;
886 else
887 /*
888 * TBD do we need to do anything about the
889 * 'connected' parameter?
890 */
4053e952 891 nh_valid = bgp_find_or_add_nexthop(
654a5978 892 bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p);
960035b2 893
d79ff732
HS
894 /*
895 * If you are using SRv6 VPN instead of MPLS, it need to check
896 * the SID allocation. If the sid is not allocated, the rib
897 * will be invalid.
898 */
899 if (bgp->srv6_enabled
900 && (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
901 bgp_path_info_unset_flag(bn, bpi, BGP_PATH_VALID);
902 nh_valid = false;
903 }
904
960035b2
PZ
905 if (debug)
906 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
907 __func__, (nh_valid ? "" : "not "),
908 bgp_nexthop->name_pretty);
909
910 if (nh_valid)
40381db7 911 bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
960035b2 912
ddb5b488 913 /* Process change. */
40381db7 914 bgp_aggregate_increment(bgp, p, bpi, afi, safi);
ddb5b488 915 bgp_process(bgp, bn, afi, safi);
9bcb3eef 916 bgp_dest_unlock_node(bn);
ddb5b488
PZ
917
918 if (debug)
56ca3b5b 919 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
b54892e0 920 __func__, bgp->name_pretty, bn);
ddb5b488 921
40381db7 922 return bpi;
ddb5b488
PZ
923 }
924
8fac400c
AR
925 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
926 if (debug) {
927 zlog_debug(
928 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
929 __func__, bgp->name_pretty,
930 source_bpi->flags, p);
931 }
932 return NULL;
933 }
934
be180f97 935 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
960035b2
PZ
936 bgp->peer_self, new_attr, bn);
937
938 if (nexthop_self_flag)
18ee8310 939 bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
ddb5b488 940
18ee8310 941 bgp_path_info_extra_get(new);
4b85140f 942
dbcf19b8
HS
943 /*
944 * rewrite sid
945 */
946 if (num_sids) {
16f3db2d 947 if (new_attr->srv6_l3vpn) {
dbcf19b8 948 setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
16f3db2d
RS
949
950 extra = bgp_path_info_extra_get(new);
951
952 extra->sid[0].loc_block_len =
953 new_attr->srv6_l3vpn->loc_block_len;
954 extra->sid[0].loc_node_len =
955 new_attr->srv6_l3vpn->loc_node_len;
956 extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len;
957 extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len;
ea7cd161
RS
958 extra->sid[0].transposition_len =
959 new_attr->srv6_l3vpn->transposition_len;
960 extra->sid[0].transposition_offset =
961 new_attr->srv6_l3vpn->transposition_offset;
16f3db2d 962 } else if (new_attr->srv6_vpn)
dbcf19b8 963 setsids(new, &new_attr->srv6_vpn->sid, num_sids);
d79ff732
HS
964 } else
965 unsetsids(new);
dbcf19b8 966
e37fb4bf
PZ
967 if (num_labels)
968 setlabels(new, label, num_labels);
969
18ee8310 970 new->extra->parent = bgp_path_info_lock(parent);
9bcb3eef
DS
971 bgp_dest_lock_node(
972 (struct bgp_dest *)((struct bgp_path_info *)parent)->net);
ddb5b488 973 if (bgp_orig)
21d88ef7 974 new->extra->bgp_orig = bgp_lock(bgp_orig);
ddb5b488
PZ
975 if (nexthop_orig)
976 new->extra->nexthop_orig = *nexthop_orig;
977
960035b2
PZ
978 /*
979 * nexthop tracking for unicast routes
980 */
981 struct bgp *bgp_nexthop = bgp;
982 int nh_valid;
983
4b85140f 984 if (new->extra->bgp_orig)
960035b2
PZ
985 bgp_nexthop = new->extra->bgp_orig;
986
987 /*
988 * No nexthop tracking for redistributed routes because
989 * their originating protocols will do the tracking and
990 * withdraw those routes if the nexthops become unreachable
0a2f9ac1 991 * This also holds good for EVPN-imported routes that get
992 * leaked.
960035b2 993 */
0a2f9ac1 994 if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
995 is_pi_family_evpn(bpi_ultimate))
960035b2
PZ
996 nh_valid = 1;
997 else
998 /*
999 * TBD do we need to do anything about the
1000 * 'connected' parameter?
1001 */
4053e952 1002 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
654a5978 1003 new, NULL, 0, p);
960035b2 1004
d79ff732
HS
1005 /*
1006 * If you are using SRv6 VPN instead of MPLS, it need to check
1007 * the SID allocation. If the sid is not allocated, the rib
1008 * will be invalid.
1009 */
1010 if (bgp->srv6_enabled
1011 && (!new->attr->srv6_l3vpn && !new->attr->srv6_vpn)) {
1012 bgp_path_info_unset_flag(bn, new, BGP_PATH_VALID);
1013 nh_valid = false;
1014 }
1015
960035b2
PZ
1016 if (debug)
1017 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
1018 __func__, (nh_valid ? "" : "not "),
1019 bgp_nexthop->name_pretty);
1020 if (nh_valid)
18ee8310 1021 bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
960035b2 1022
ddb5b488 1023 bgp_aggregate_increment(bgp, p, new, afi, safi);
18ee8310 1024 bgp_path_info_add(bn, new);
ddb5b488 1025
9bcb3eef 1026 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1027 bgp_process(bgp, bn, afi, safi);
1028
1029 if (debug)
56ca3b5b 1030 zlog_debug("%s: ->%s: %pBD: Added new route", __func__,
b54892e0 1031 bgp->name_pretty, bn);
ddb5b488
PZ
1032
1033 return new;
1034}
1035
1036/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
4b7e6066
DS
1037void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
1038 struct bgp *bgp_vrf, /* from */
40381db7 1039 struct bgp_path_info *path_vrf) /* route */
ddb5b488
PZ
1040{
1041 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1042 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
ddb5b488
PZ
1043 afi_t afi = family2afi(p->family);
1044 struct attr static_attr = {0};
1045 struct attr *new_attr = NULL;
1046 safi_t safi = SAFI_MPLS_VPN;
1047 mpls_label_t label_val;
1048 mpls_label_t label;
9bcb3eef 1049 struct bgp_dest *bn;
ddb5b488 1050 const char *debugmsg;
960035b2
PZ
1051 int nexthop_self_flag = 0;
1052
1053 if (debug)
1054 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
ddb5b488 1055
b53e67a3
DA
1056 if (debug && bgp_attr_get_ecommunity(path_vrf->attr)) {
1057 char *s = ecommunity_ecom2str(
1058 bgp_attr_get_ecommunity(path_vrf->attr),
1059 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1060
40381db7
DS
1061 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
1062 bgp_vrf->name, path_vrf->type, s);
c8f57349 1063 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1064 }
1065
1066 if (!bgp_vpn)
1067 return;
1068
1069 if (!afi) {
1070 if (debug)
1071 zlog_debug("%s: can't get afi of prefix", __func__);
1072 return;
1073 }
1074
12d6100c 1075 /* Is this route exportable into the VPN table? */
1076 if (!is_route_injectable_into_vpn(path_vrf))
ddb5b488
PZ
1077 return;
1078
ddb5b488
PZ
1079 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
1080 if (debug)
12a844a5
DS
1081 zlog_debug("%s: %s skipping: %s", __func__,
1082 bgp_vrf->name, debugmsg);
ddb5b488
PZ
1083 return;
1084 }
1085
6f4f49b2
QY
1086 /* shallow copy */
1087 static_attr = *path_vrf->attr;
ddb5b488
PZ
1088
1089 /*
1090 * route map handling
1091 */
1092 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
4b7e6066 1093 struct bgp_path_info info;
ddb5b488
PZ
1094 route_map_result_t ret;
1095
1096 memset(&info, 0, sizeof(info));
1097 info.peer = bgp_vpn->peer_self;
1098 info.attr = &static_attr;
1099 ret = route_map_apply(
1100 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
1782514f 1101 p, &info);
ddb5b488
PZ
1102 if (RMAP_DENYMATCH == ret) {
1103 bgp_attr_flush(&static_attr); /* free any added parts */
1104 if (debug)
1105 zlog_debug(
1106 "%s: vrf %s route map \"%s\" says DENY, returning",
960035b2 1107 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1108 bgp_vrf->vpn_policy[afi]
1109 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
1110 ->name);
1111 return;
1112 }
1113 }
1114
b53e67a3
DA
1115 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1116 char *s = ecommunity_ecom2str(
1117 bgp_attr_get_ecommunity(&static_attr),
1118 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1119
ddb5b488
PZ
1120 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1121 __func__, s);
c8f57349 1122 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1123 }
1124
1125 /*
1126 * Add the vpn-policy rt-list
1127 */
1128 struct ecommunity *old_ecom;
1129 struct ecommunity *new_ecom;
1130
e8bfa90e 1131 /* Export with the 'from' instance's export RTs. */
1132 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
b53e67a3 1133 old_ecom = bgp_attr_get_ecommunity(&static_attr);
ddb5b488 1134 if (old_ecom) {
e8bfa90e 1135 new_ecom = ecommunity_dup(old_ecom);
1136 if (CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
1137 BGP_CONFIG_VRF_TO_VRF_EXPORT))
1138 ecommunity_strip_rts(new_ecom);
1139 new_ecom = ecommunity_merge(new_ecom,
ddb5b488
PZ
1140 bgp_vrf->vpn_policy[afi]
1141 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1142 if (!old_ecom->refcnt)
1143 ecommunity_free(&old_ecom);
1144 } else {
1145 new_ecom = ecommunity_dup(
1146 bgp_vrf->vpn_policy[afi]
1147 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1148 }
b53e67a3 1149 bgp_attr_set_ecommunity(&static_attr, new_ecom);
ddb5b488
PZ
1150 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
1151
b53e67a3
DA
1152 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1153 char *s = ecommunity_ecom2str(
1154 bgp_attr_get_ecommunity(&static_attr),
1155 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1156
ddb5b488
PZ
1157 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1158 __func__, s);
c8f57349 1159 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1160 }
1161
1162 /* Nexthop */
1163 /* if policy nexthop not set, use 0 */
1164 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
1165 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
ddb5b488
PZ
1166 struct prefix *nexthop =
1167 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
12a844a5 1168
ddb5b488
PZ
1169 switch (nexthop->family) {
1170 case AF_INET:
1171 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1172 */
1173 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
1174
1175 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
0606039c 1176 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
ddb5b488
PZ
1177 break;
1178
1179 case AF_INET6:
1180 static_attr.mp_nexthop_global = nexthop->u.prefix6;
0606039c 1181 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
ddb5b488
PZ
1182 break;
1183
1184 default:
1185 assert(0);
1186 }
1187 } else {
12a844a5
DS
1188 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
1189 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
1190 if (afi == AFI_IP) {
020a3f60
DS
1191 /*
1192 * For ipv4, copy to multiprotocol
1193 * nexthop field
1194 */
1195 static_attr.mp_nexthop_global_in =
1196 static_attr.nexthop;
0606039c
DA
1197 static_attr.mp_nexthop_len =
1198 BGP_ATTR_NHLEN_IPV4;
020a3f60
DS
1199 /*
1200 * XXX Leave static_attr.nexthop
1201 * intact for NHT
1202 */
1203 static_attr.flag &=
1204 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5
DS
1205 }
1206 } else {
77e62f2b 1207 /* Update based on next-hop family to account for
1208 * RFC 5549 (BGP unnumbered) scenario. Note that
1209 * specific action is only needed for the case of
1210 * IPv4 nexthops as the attr has been copied
1211 * otherwise.
1212 */
40381db7
DS
1213 if (afi == AFI_IP
1214 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
12a844a5
DS
1215 static_attr.mp_nexthop_global_in.s_addr =
1216 static_attr.nexthop.s_addr;
0606039c
DA
1217 static_attr.mp_nexthop_len =
1218 BGP_ATTR_NHLEN_IPV4;
12a844a5
DS
1219 static_attr.flag |=
1220 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5 1221 }
ddb5b488 1222 }
960035b2 1223 nexthop_self_flag = 1;
ddb5b488
PZ
1224 }
1225
1226 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
1227 if (label_val == MPLS_LABEL_NONE) {
291e32c3 1228 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
1229 } else {
1230 encode_label(label_val, &label);
1231 }
1232
1233 /* Set originator ID to "me" */
1234 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
1235 static_attr.originator_id = bgp_vpn->router_id;
1236
dbcf19b8 1237 /* Set SID for SRv6 VPN */
69fe7874 1238 if (bgp_vrf->vpn_policy[afi].tovpn_sid_locator) {
9299fd00
RS
1239 encode_label(bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label,
1240 &label);
dbcf19b8 1241 static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
537b608a 1242 sizeof(struct bgp_attr_srv6_l3vpn));
dbcf19b8
HS
1243 static_attr.srv6_l3vpn->sid_flags = 0x00;
1244 static_attr.srv6_l3vpn->endpoint_behavior = 0xffff;
9299fd00
RS
1245 static_attr.srv6_l3vpn->loc_block_len =
1246 BGP_PREFIX_SID_SRV6_LOCATOR_BLOCK_LENGTH;
1247 static_attr.srv6_l3vpn->loc_node_len =
1248 BGP_PREFIX_SID_SRV6_LOCATOR_NODE_LENGTH;
1249 static_attr.srv6_l3vpn->func_len =
1250 BGP_PREFIX_SID_SRV6_FUNCTION_LENGTH;
1251 static_attr.srv6_l3vpn->arg_len =
1252 BGP_PREFIX_SID_SRV6_ARGUMENT_LENGTH;
1253 static_attr.srv6_l3vpn->transposition_len =
1254 BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH;
1255 static_attr.srv6_l3vpn->transposition_offset =
1256 BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET;
dbcf19b8 1257 memcpy(&static_attr.srv6_l3vpn->sid,
69fe7874
RS
1258 bgp_vrf->vpn_policy[afi].tovpn_sid_locator,
1259 sizeof(struct in6_addr));
dbcf19b8
HS
1260 }
1261
ddb5b488
PZ
1262
1263 new_attr = bgp_attr_intern(
1264 &static_attr); /* hashed refcounted everything */
1265 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
1266
b53e67a3
DA
1267 if (debug && bgp_attr_get_ecommunity(new_attr)) {
1268 char *s = ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr),
c3e345b1 1269 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 1270
ddb5b488 1271 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 1272 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
1273 }
1274
1275 /* Now new_attr is an allocated interned attr */
1276
1277 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
1278 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
1279
4b7e6066 1280 struct bgp_path_info *new_info;
ddb5b488 1281
40381db7
DS
1282 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
1283 &label, 1, path_vrf, bgp_vrf, NULL,
960035b2 1284 nexthop_self_flag, debug);
ddb5b488
PZ
1285
1286 /*
1287 * Routes actually installed in the vpn RIB must also be
1288 * offered to all vrfs (because now they originate from
1289 * the vpn RIB).
1290 *
1291 * Acceptance into other vrfs depends on rt-lists.
1292 * Originating vrf will not accept the looped back route
1293 * because of loop checking.
1294 */
1295 if (new_info)
321b4bc9 1296 vpn_leak_to_vrf_update(bgp_vrf, new_info);
ddb5b488
PZ
1297}
1298
4b7e6066
DS
1299void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
1300 struct bgp *bgp_vrf, /* from */
40381db7 1301 struct bgp_path_info *path_vrf) /* route */
ddb5b488
PZ
1302{
1303 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1304 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
ddb5b488
PZ
1305 afi_t afi = family2afi(p->family);
1306 safi_t safi = SAFI_MPLS_VPN;
40381db7 1307 struct bgp_path_info *bpi;
9bcb3eef 1308 struct bgp_dest *bn;
ddb5b488 1309 const char *debugmsg;
960035b2
PZ
1310
1311 if (debug) {
960035b2 1312 zlog_debug(
56ca3b5b 1313 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
b54892e0 1314 __func__, bgp_vrf->name_pretty, path_vrf->net,
40381db7 1315 path_vrf->type, path_vrf->sub_type);
960035b2 1316 }
ddb5b488 1317
ddb5b488
PZ
1318 if (!bgp_vpn)
1319 return;
1320
1321 if (!afi) {
1322 if (debug)
1323 zlog_debug("%s: can't get afi of prefix", __func__);
1324 return;
1325 }
1326
12d6100c 1327 /* Is this route exportable into the VPN table? */
1328 if (!is_route_injectable_into_vpn(path_vrf))
1329 return;
1330
ddb5b488
PZ
1331 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
1332 if (debug)
1333 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1334 return;
1335 }
1336
1337 if (debug)
40381db7 1338 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
ddb5b488
PZ
1339
1340 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
1341 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
1342
6f94b685
DS
1343 if (!bn)
1344 return;
ddb5b488
PZ
1345 /*
1346 * vrf -> vpn
40381db7 1347 * match original bpi imported from
ddb5b488 1348 */
9bcb3eef 1349 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
40381db7 1350 if (bpi->extra && bpi->extra->parent == path_vrf) {
ddb5b488
PZ
1351 break;
1352 }
1353 }
1354
40381db7 1355 if (bpi) {
ddb5b488 1356 /* withdraw from looped vrfs as well */
40381db7 1357 vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
ddb5b488 1358
40381db7
DS
1359 bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
1360 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1361 bgp_process(bgp_vpn, bn, afi, safi);
1362 }
9bcb3eef 1363 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1364}
1365
1366void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
1367 struct bgp *bgp_vrf, /* from */
1368 afi_t afi)
1369{
1370 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
9bcb3eef 1371 struct bgp_dest *pdest;
ddb5b488
PZ
1372 safi_t safi = SAFI_MPLS_VPN;
1373
1374 /*
40381db7 1375 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
ddb5b488 1376 */
9bcb3eef
DS
1377 for (pdest = bgp_table_top(bgp_vpn->rib[afi][safi]); pdest;
1378 pdest = bgp_route_next(pdest)) {
ddb5b488
PZ
1379
1380 struct bgp_table *table;
9bcb3eef 1381 struct bgp_dest *bn;
40381db7 1382 struct bgp_path_info *bpi;
ddb5b488
PZ
1383
1384 /* This is the per-RD table of prefixes */
9bcb3eef 1385 table = bgp_dest_get_bgp_table_info(pdest);
ddb5b488
PZ
1386
1387 if (!table)
1388 continue;
1389
1390 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
9bcb3eef 1391 bpi = bgp_dest_get_bgp_path_info(bn);
6f94b685 1392 if (debug && bpi) {
56ca3b5b 1393 zlog_debug("%s: looking at prefix %pBD",
b54892e0 1394 __func__, bn);
ddb5b488
PZ
1395 }
1396
6f94b685 1397 for (; bpi; bpi = bpi->next) {
ddb5b488
PZ
1398 if (debug)
1399 zlog_debug("%s: type %d, sub_type %d",
40381db7
DS
1400 __func__, bpi->type,
1401 bpi->sub_type);
1402 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
ddb5b488 1403 continue;
40381db7 1404 if (!bpi->extra)
ddb5b488 1405 continue;
40381db7 1406 if ((struct bgp *)bpi->extra->bgp_orig
ddb5b488
PZ
1407 == bgp_vrf) {
1408 /* delete route */
1409 if (debug)
9165c5f5 1410 zlog_debug("%s: deleting it",
ddb5b488 1411 __func__);
b19c4f08
AR
1412 /* withdraw from leak-to vrfs as well */
1413 vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
b54892e0
DS
1414 bgp_aggregate_decrement(
1415 bgp_vpn,
9bcb3eef 1416 bgp_dest_get_prefix(bn), bpi,
b54892e0 1417 afi, safi);
40381db7 1418 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1419 bgp_process(bgp_vpn, bn, afi, safi);
1420 }
1421 }
1422 }
1423 }
1424}
1425
1426void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
1427 struct bgp *bgp_vrf, /* from */
1428 afi_t afi)
1429{
9bcb3eef 1430 struct bgp_dest *bn;
40381db7 1431 struct bgp_path_info *bpi;
ddb5b488
PZ
1432 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1433
1434 if (debug)
1435 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
960035b2 1436 bgp_vrf->name_pretty);
ddb5b488
PZ
1437
1438 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
1439 bn = bgp_route_next(bn)) {
1440
1441 if (debug)
1442 zlog_debug("%s: node=%p", __func__, bn);
1443
9bcb3eef 1444 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 1445 bpi = bpi->next) {
ddb5b488
PZ
1446 if (debug)
1447 zlog_debug(
1448 "%s: calling vpn_leak_from_vrf_update",
1449 __func__);
40381db7 1450 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bpi);
ddb5b488
PZ
1451 }
1452 }
1453}
1454
4b7e6066
DS
1455static void
1456vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1457 struct bgp *bgp_vpn, /* from */
40381db7 1458 struct bgp_path_info *path_vpn) /* route */
ddb5b488 1459{
9bcb3eef 1460 const struct prefix *p = bgp_dest_get_prefix(path_vpn->net);
ddb5b488
PZ
1461 afi_t afi = family2afi(p->family);
1462
ddb5b488
PZ
1463 struct attr static_attr = {0};
1464 struct attr *new_attr = NULL;
9bcb3eef 1465 struct bgp_dest *bn;
ddb5b488
PZ
1466 safi_t safi = SAFI_UNICAST;
1467 const char *debugmsg;
1468 struct prefix nexthop_orig;
1469 mpls_label_t *pLabels = NULL;
e37fb4bf 1470 uint32_t num_labels = 0;
960035b2 1471 int nexthop_self_flag = 1;
40381db7 1472 struct bgp_path_info *bpi_ultimate = NULL;
513bf8d6 1473 int origin_local = 0;
d6632478 1474 struct bgp *src_vrf;
ddb5b488
PZ
1475
1476 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1477
b9c7bc5a 1478 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
1479 if (debug)
1480 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1481 return;
1482 }
1483
1484 /* Check for intersection of route targets */
1485 if (!ecom_intersect(
1486 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
b53e67a3 1487 bgp_attr_get_ecommunity(path_vpn->attr))) {
de7cee09
AR
1488 if (debug)
1489 zlog_debug(
1490 "from vpn to vrf %s, skipping after no intersection of route targets",
1491 bgp_vrf->name_pretty);
ddb5b488
PZ
1492 return;
1493 }
1494
2dbe669b
DA
1495 if (debug)
1496 zlog_debug("%s: updating %pFX to vrf %s", __func__, p,
1497 bgp_vrf->name_pretty);
ddb5b488 1498
6f4f49b2
QY
1499 /* shallow copy */
1500 static_attr = *path_vpn->attr;
ddb5b488 1501
e8bfa90e 1502 struct ecommunity *old_ecom;
1503 struct ecommunity *new_ecom;
1504
1505 /* If doing VRF-to-VRF leaking, strip RTs. */
b53e67a3 1506 old_ecom = bgp_attr_get_ecommunity(&static_attr);
e8bfa90e 1507 if (old_ecom && CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1508 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1509 new_ecom = ecommunity_dup(old_ecom);
1510 ecommunity_strip_rts(new_ecom);
b53e67a3 1511 bgp_attr_set_ecommunity(&static_attr, new_ecom);
1995cb77
DS
1512
1513 if (new_ecom->size == 0) {
1514 UNSET_FLAG(static_attr.flag,
1515 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
1516 ecommunity_free(&new_ecom);
b53e67a3 1517 bgp_attr_set_ecommunity(&static_attr, NULL);
1995cb77
DS
1518 }
1519
e8bfa90e 1520 if (!old_ecom->refcnt)
1521 ecommunity_free(&old_ecom);
1522 }
1523
ddb5b488
PZ
1524 /*
1525 * Nexthop: stash and clear
1526 *
1527 * Nexthop is valid in context of VPN core, but not in destination vrf.
1528 * Stash it for later label resolution by vrf ingress path and then
1529 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1530 */
40381db7 1531 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
ddb5b488
PZ
1532
1533 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1534 nexthop_orig.family = nhfamily;
1535
1536 switch (nhfamily) {
ddb5b488
PZ
1537 case AF_INET:
1538 /* save */
40381db7 1539 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
12256b84 1540 nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
12a844a5
DS
1541
1542 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1543 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1544 static_attr.nexthop.s_addr =
1545 nexthop_orig.u.prefix4.s_addr;
1546
1547 static_attr.mp_nexthop_global_in =
40381db7 1548 path_vpn->attr->mp_nexthop_global_in;
12a844a5 1549 static_attr.mp_nexthop_len =
40381db7 1550 path_vpn->attr->mp_nexthop_len;
12a844a5 1551 }
de4d0a51 1552 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1553 break;
ddb5b488
PZ
1554 case AF_INET6:
1555 /* save */
40381db7 1556 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
13ccce6e 1557 nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
12a844a5
DS
1558
1559 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1560 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1561 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1562 }
ddb5b488
PZ
1563 break;
1564 }
1565
ddb5b488
PZ
1566 /*
1567 * route map handling
ddb5b488 1568 */
ddb5b488 1569 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
4b7e6066 1570 struct bgp_path_info info;
ddb5b488
PZ
1571 route_map_result_t ret;
1572
1573 memset(&info, 0, sizeof(info));
1574 info.peer = bgp_vrf->peer_self;
1575 info.attr = &static_attr;
1dcc9e5b 1576 info.extra = path_vpn->extra; /* Used for source-vrf filter */
ddb5b488
PZ
1577 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1578 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1782514f 1579 p, &info);
ddb5b488
PZ
1580 if (RMAP_DENYMATCH == ret) {
1581 bgp_attr_flush(&static_attr); /* free any added parts */
1582 if (debug)
1583 zlog_debug(
1584 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1585 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1586 bgp_vrf->vpn_policy[afi]
1587 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1588 ->name);
1589 return;
1590 }
960035b2
PZ
1591 /*
1592 * if route-map changed nexthop, don't nexthop-self on output
1593 */
1594 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1595 BATTR_RMAP_NEXTHOP_UNCHANGED))
1596 nexthop_self_flag = 0;
ddb5b488
PZ
1597 }
1598
1599 new_attr = bgp_attr_intern(&static_attr);
1600 bgp_attr_flush(&static_attr);
1601
1602 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1603
1604 /*
1605 * ensure labels are copied
513bf8d6
PZ
1606 *
1607 * However, there is a special case: if the route originated in
1608 * another local VRF (as opposed to arriving via VPN), then the
1609 * nexthop is reached by hairpinning through this router (me)
1610 * using IP forwarding only (no LSP). Therefore, the route
1611 * imported to the VRF should not have labels attached. Note
1612 * that nexthop tracking is also involved: eliminating the
1613 * labels for these routes enables the non-labeled nexthops
1614 * from the originating VRF to be considered valid for this route.
ddb5b488 1615 */
12a844a5
DS
1616 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1617 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1618 /* work back to original route */
da0c0ef7 1619 bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
513bf8d6 1620
12a844a5
DS
1621 /*
1622 * if original route was unicast,
1623 * then it did not arrive over vpn
1624 */
40381db7 1625 if (bpi_ultimate->net) {
12a844a5 1626 struct bgp_table *table;
513bf8d6 1627
9bcb3eef 1628 table = bgp_dest_table(bpi_ultimate->net);
12a844a5
DS
1629 if (table && (table->safi == SAFI_UNICAST))
1630 origin_local = 1;
1631 }
513bf8d6 1632
12a844a5 1633 /* copy labels */
40381db7
DS
1634 if (!origin_local && path_vpn->extra
1635 && path_vpn->extra->num_labels) {
1636 num_labels = path_vpn->extra->num_labels;
12a844a5
DS
1637 if (num_labels > BGP_MAX_LABELS)
1638 num_labels = BGP_MAX_LABELS;
40381db7 1639 pLabels = path_vpn->extra->label;
12a844a5 1640 }
ddb5b488 1641 }
513bf8d6 1642
b54892e0 1643 if (debug)
56ca3b5b 1644 zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
b54892e0 1645 path_vpn->net, num_labels);
ddb5b488 1646
44338987 1647 /*
1d4e8b0d
DS
1648 * For VRF-2-VRF route-leaking,
1649 * the source will be the originating VRF.
44338987 1650 */
40381db7
DS
1651 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1652 src_vrf = path_vpn->extra->bgp_orig;
d6632478
PZ
1653 else
1654 src_vrf = bgp_vpn;
1655
40381db7
DS
1656 leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
1657 num_labels, path_vpn, /* parent */
1658 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1659}
1660
4b7e6066 1661void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
40381db7 1662 struct bgp_path_info *path_vpn) /* route */
ddb5b488
PZ
1663{
1664 struct listnode *mnode, *mnnode;
1665 struct bgp *bgp;
1666
1667 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1668
1669 if (debug)
40381db7 1670 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488
PZ
1671
1672 /* Loop over VRFs */
1673 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1674
40381db7
DS
1675 if (!path_vpn->extra
1676 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
1677 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
ddb5b488
PZ
1678 }
1679 }
1680}
1681
4b7e6066 1682void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
40381db7 1683 struct bgp_path_info *path_vpn) /* route */
ddb5b488 1684{
b54892e0 1685 const struct prefix *p;
1b3510a0 1686 afi_t afi;
ddb5b488
PZ
1687 safi_t safi = SAFI_UNICAST;
1688 struct bgp *bgp;
1689 struct listnode *mnode, *mnnode;
9bcb3eef 1690 struct bgp_dest *bn;
40381db7 1691 struct bgp_path_info *bpi;
ddb5b488
PZ
1692 const char *debugmsg;
1693
1694 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1695
b54892e0 1696 if (debug)
56ca3b5b 1697 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
b54892e0 1698 path_vpn->net, path_vpn->type, path_vpn->sub_type);
960035b2 1699
ddb5b488 1700 if (debug)
40381db7 1701 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488 1702
40381db7 1703 if (!path_vpn->net) {
49e5a4a0 1704#ifdef ENABLE_BGP_VNC
40381db7
DS
1705 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1706 if (path_vpn->type == ZEBRA_ROUTE_BGP
1707 && path_vpn->sub_type == BGP_ROUTE_RFP) {
1b3510a0
PZ
1708
1709 return;
1710 }
56c2c080 1711#endif
1b3510a0 1712 if (debug)
40381db7
DS
1713 zlog_debug(
1714 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1b3510a0
PZ
1715 __func__);
1716 return;
1717 }
1718
9bcb3eef 1719 p = bgp_dest_get_prefix(path_vpn->net);
1b3510a0 1720 afi = family2afi(p->family);
ddb5b488
PZ
1721
1722 /* Loop over VRFs */
1723 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1724 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1725 if (debug)
1726 zlog_debug("%s: skipping: %s", __func__,
1727 debugmsg);
1728 continue;
1729 }
1730
1731 /* Check for intersection of route targets */
1732 if (!ecom_intersect(bgp->vpn_policy[afi]
1733 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
b53e67a3 1734 bgp_attr_get_ecommunity(path_vpn->attr))) {
ddb5b488
PZ
1735
1736 continue;
1737 }
1738
1739 if (debug)
1740 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1741 bgp->name_pretty);
ddb5b488
PZ
1742
1743 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6f94b685 1744
9bcb3eef 1745 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 1746 bpi = bpi->next) {
40381db7
DS
1747 if (bpi->extra
1748 && (struct bgp_path_info *)bpi->extra->parent
1749 == path_vpn) {
ddb5b488
PZ
1750 break;
1751 }
1752 }
1753
40381db7 1754 if (bpi) {
ddb5b488 1755 if (debug)
40381db7
DS
1756 zlog_debug("%s: deleting bpi %p", __func__,
1757 bpi);
1758 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
1759 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1760 bgp_process(bgp, bn, afi, safi);
1761 }
9bcb3eef 1762 bgp_dest_unlock_node(bn);
ddb5b488
PZ
1763 }
1764}
1765
1766void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1767 afi_t afi)
1768{
9bcb3eef 1769 struct bgp_dest *bn;
40381db7 1770 struct bgp_path_info *bpi;
ddb5b488
PZ
1771 safi_t safi = SAFI_UNICAST;
1772 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1773
1774 if (debug)
1775 zlog_debug("%s: entry", __func__);
1776 /*
40381db7 1777 * Walk vrf table, delete bpi with bgp_orig in a different vrf
ddb5b488
PZ
1778 */
1779 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1780 bn = bgp_route_next(bn)) {
1781
9bcb3eef 1782 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 1783 bpi = bpi->next) {
9544ddb2 1784 if (bpi->extra
1785 && bpi->extra->bgp_orig != bgp_vrf
1786 && bpi->extra->parent
1787 && is_pi_family_vpn(bpi->extra->parent)) {
ddb5b488
PZ
1788
1789 /* delete route */
b54892e0 1790 bgp_aggregate_decrement(bgp_vrf,
9bcb3eef 1791 bgp_dest_get_prefix(bn),
b54892e0 1792 bpi, afi, safi);
40381db7 1793 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1794 bgp_process(bgp_vrf, bn, afi, safi);
1795 }
1796 }
1797 }
1798}
1799
1800void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1801 struct bgp *bgp_vpn, /* from */
1802 afi_t afi)
1803{
9bcb3eef 1804 struct bgp_dest *pdest;
ddb5b488
PZ
1805 safi_t safi = SAFI_MPLS_VPN;
1806
3bd70bf8 1807 assert(bgp_vpn);
73aed584 1808
ddb5b488
PZ
1809 /*
1810 * Walk vpn table
1811 */
9bcb3eef
DS
1812 for (pdest = bgp_table_top(bgp_vpn->rib[afi][safi]); pdest;
1813 pdest = bgp_route_next(pdest)) {
ddb5b488 1814 struct bgp_table *table;
9bcb3eef 1815 struct bgp_dest *bn;
40381db7 1816 struct bgp_path_info *bpi;
ddb5b488 1817
ddb5b488 1818 /* This is the per-RD table of prefixes */
9bcb3eef 1819 table = bgp_dest_get_bgp_table_info(pdest);
ddb5b488
PZ
1820
1821 if (!table)
1822 continue;
1823
1824 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1825
9bcb3eef 1826 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
6f94b685 1827 bpi = bpi->next) {
ddb5b488 1828
40381db7
DS
1829 if (bpi->extra
1830 && bpi->extra->bgp_orig == bgp_vrf)
ddb5b488
PZ
1831 continue;
1832
1833 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
40381db7 1834 bpi);
ddb5b488
PZ
1835 }
1836 }
1837 }
1838}
1839
d92a55df
PZ
1840/*
1841 * This function is called for definition/deletion/change to a route-map
1842 */
ddb5b488
PZ
1843static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1844{
1845 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1846 afi_t afi;
1847 struct route_map *rmap;
1848
1849 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1850 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1851
1852 return;
1853 }
1854
1855 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1856
1857 for (afi = 0; afi < AFI_MAX; ++afi) {
1858
d92a55df
PZ
1859 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1860 && !strcmp(rmap_name,
ddb5b488
PZ
1861 bgp->vpn_policy[afi]
1862 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1863
1864 if (debug)
1865 zlog_debug(
1866 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1867 __func__, rmap_name, bgp->as,
1868 afi2str(afi));
1869
1870 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1871 bgp_get_default(), bgp);
1872 if (debug)
1873 zlog_debug("%s: after vpn_leak_prechange",
1874 __func__);
1875
d92a55df
PZ
1876 /* in case of definition/deletion */
1877 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1878 rmap;
ddb5b488
PZ
1879
1880 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1881 bgp_get_default(), bgp);
d92a55df 1882
ddb5b488
PZ
1883 if (debug)
1884 zlog_debug("%s: after vpn_leak_postchange",
1885 __func__);
1886 }
1887
d92a55df
PZ
1888 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1889 && !strcmp(rmap_name,
1890 bgp->vpn_policy[afi]
1891 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1892
1893 if (debug) {
1894 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1895 __func__, rmap_name, bgp->as,
1896 afi2str(afi));
b9c7bc5a 1897 }
ddb5b488
PZ
1898
1899 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1900 bgp_get_default(), bgp);
1901
d92a55df
PZ
1902 /* in case of definition/deletion */
1903 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1904 rmap;
ddb5b488
PZ
1905
1906 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1907 bgp_get_default(), bgp);
1908 }
1909 }
1910}
1911
636f7608
CS
1912/* This API is used during router-id change, reflect VPNs
1913 * auto RD and RT values and readvertise routes to VPN table.
1914 */
e65fe398
MS
1915void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
1916 bool is_config)
636f7608
CS
1917{
1918 afi_t afi;
de7cee09
AR
1919 int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
1920 | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
636f7608
CS
1921 char *vname;
1922 const char *export_name;
1923 char buf[RD_ADDRSTRLEN];
1924 struct bgp *bgp_import;
1925 struct listnode *node;
1926 struct ecommunity *ecom;
1927 vpn_policy_direction_t idir, edir;
1928
de7cee09
AR
1929 /*
1930 * Router-id change that is not explicitly configured
1931 * (a change from zebra, frr restart for example)
1932 * should not replace a configured vpn RD/RT.
1933 */
1934 if (!is_config) {
1935 if (debug)
1936 zlog_debug("%s: skipping non explicit router-id change",
1937 __func__);
1938 return;
1939 }
1940
636f7608
CS
1941 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1942 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1943 return;
1944
1945 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
636f7608
CS
1946 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1947 edir = BGP_VPN_POLICY_DIR_TOVPN;
1948
1949 for (afi = 0; afi < AFI_MAX; ++afi) {
1950 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
1951 continue;
1952
1953 if (withdraw) {
1954 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
1955 afi, bgp_get_default(), bgp);
1956 if (debug)
1957 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1958 __func__, export_name);
1959
1960 /* Remove import RT from VRFs */
1961 ecom = bgp->vpn_policy[afi].rtlist[edir];
1962 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1963 export_vrf, node, vname)) {
67bd620c 1964 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
1965 bgp_import = bgp_get_default();
1966 else
1967 bgp_import = bgp_lookup_by_name(vname);
636f7608
CS
1968 if (!bgp_import)
1969 continue;
1970
de7cee09
AR
1971 ecommunity_del_val(
1972 bgp_import->vpn_policy[afi]
1973 .rtlist[idir],
636f7608 1974 (struct ecommunity_val *)ecom->val);
636f7608
CS
1975 }
1976 } else {
1977 /* New router-id derive auto RD and RT and export
1978 * to VPN
1979 */
1980 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
1981 &bgp->vrf_prd_auto);
1982 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
1983 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
1984 sizeof(buf));
1985 bgp->vpn_policy[afi].rtlist[edir] =
1986 ecommunity_str2com(buf,
1987 ECOMMUNITY_ROUTE_TARGET, 0);
1988
1989 /* Update import_vrf rt_list */
1990 ecom = bgp->vpn_policy[afi].rtlist[edir];
1991 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1992 export_vrf, node, vname)) {
67bd620c 1993 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
1994 bgp_import = bgp_get_default();
1995 else
1996 bgp_import = bgp_lookup_by_name(vname);
636f7608
CS
1997 if (!bgp_import)
1998 continue;
1999 if (bgp_import->vpn_policy[afi].rtlist[idir])
2000 bgp_import->vpn_policy[afi].rtlist[idir]
2001 = ecommunity_merge(
2002 bgp_import->vpn_policy[afi]
2003 .rtlist[idir], ecom);
2004 else
2005 bgp_import->vpn_policy[afi].rtlist[idir]
2006 = ecommunity_dup(ecom);
636f7608 2007 }
e65fe398 2008
636f7608
CS
2009 /* Update routes to VPN */
2010 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
2011 afi, bgp_get_default(),
2012 bgp);
2013 if (debug)
2014 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2015 __func__, export_name);
2016 }
2017 }
2018}
2019
ddb5b488
PZ
2020void vpn_policy_routemap_event(const char *rmap_name)
2021{
2022 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2023 struct listnode *mnode, *mnnode;
2024 struct bgp *bgp;
2025
2026 if (debug)
2027 zlog_debug("%s: entry", __func__);
2028
2029 if (bm->bgp == NULL) /* may be called during cleanup */
2030 return;
2031
2032 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
2033 vpn_policy_routemap_update(bgp, rmap_name);
2034}
2035
1d4e8b0d 2036void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 2037 afi_t afi, safi_t safi)
2038{
2039 const char *export_name;
2040 vpn_policy_direction_t idir, edir;
9ecf931b
CS
2041 char *vname, *tmp_name;
2042 char buf[RD_ADDRSTRLEN];
44338987 2043 struct ecommunity *ecom;
2044 bool first_export = false;
636f7608 2045 int debug;
9ecf931b
CS
2046 struct listnode *node;
2047 bool is_inst_match = false;
44338987 2048
5742e42b 2049 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
44338987 2050 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2051 edir = BGP_VPN_POLICY_DIR_TOVPN;
2052
636f7608
CS
2053 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2054 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2055
1d4e8b0d
DS
2056 /*
2057 * Cross-ref both VRFs. Also, note if this is the first time
44338987 2058 * any VRF is importing from "import_vrf".
2059 */
a8dadcf6 2060 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
5742e42b 2061 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
a8dadcf6 2062
9ecf931b
CS
2063 /* Check the import_vrf list of destination vrf for the source vrf name,
2064 * insert otherwise.
2065 */
2066 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
2067 node, tmp_name)) {
2068 if (strcmp(vname, tmp_name) == 0) {
2069 is_inst_match = true;
2070 break;
2071 }
2072 }
2073 if (!is_inst_match)
2074 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2075 vname);
b9d45462
DS
2076 else
2077 XFREE(MTYPE_TMP, vname);
44338987 2078
9ecf931b
CS
2079 /* Check if the source vrf already exports to any vrf,
2080 * first time export requires to setup auto derived RD/RT values.
2081 * Add the destination vrf name to export vrf list if it is
2082 * not present.
2083 */
2084 is_inst_match = false;
44338987 2085 vname = XSTRDUP(MTYPE_TMP, export_name);
9ecf931b
CS
2086 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2087 first_export = true;
2088 } else {
2089 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2090 node, tmp_name)) {
2091 if (strcmp(vname, tmp_name) == 0) {
2092 is_inst_match = true;
2093 break;
2094 }
2095 }
2096 }
2097 if (!is_inst_match)
2098 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
2099 vname);
b9d45462
DS
2100 else
2101 XFREE(MTYPE_TMP, vname);
2102
44338987 2103 /* Update import RT for current VRF using export RT of the VRF we're
2104 * importing from. First though, make sure "import_vrf" has that
2105 * set.
2106 */
2107 if (first_export) {
1d4e8b0d
DS
2108 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
2109 &from_bgp->vrf_prd_auto);
2110 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
2111 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 2112 BGP_VPN_POLICY_TOVPN_RD_SET);
1d4e8b0d 2113 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
44338987 2114 buf, sizeof(buf));
1d4e8b0d 2115 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 2116 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 2117 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 2118 BGP_CONFIG_VRF_TO_VRF_EXPORT);
13b7e7f0
DS
2119 from_bgp->vpn_policy[afi].tovpn_label =
2120 BGP_PREVENT_VRF_2_VRF_LEAK;
44338987 2121 }
1d4e8b0d
DS
2122 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2123 if (to_bgp->vpn_policy[afi].rtlist[idir])
2124 to_bgp->vpn_policy[afi].rtlist[idir] =
2125 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 2126 .rtlist[idir], ecom);
2127 else
1d4e8b0d
DS
2128 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
2129 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 2130
636f7608
CS
2131 if (debug) {
2132 const char *from_name;
6a37bfb7 2133 char *ecom1, *ecom2;
636f7608
CS
2134
2135 from_name = from_bgp->name ? from_bgp->name :
2136 VRF_DEFAULT_NAME;
6a37bfb7
DS
2137
2138 ecom1 = ecommunity_ecom2str(
2139 to_bgp->vpn_policy[afi].rtlist[idir],
2140 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2141
2142 ecom2 = ecommunity_ecom2str(
2143 to_bgp->vpn_policy[afi].rtlist[edir],
2144 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2145
2146 zlog_debug(
2147 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2148 __func__, from_name, export_name, first_export, ecom1,
2149 ecom2);
2150
2151 ecommunity_strfree(&ecom1);
2152 ecommunity_strfree(&ecom2);
636f7608
CS
2153 }
2154
44338987 2155 /* Does "import_vrf" first need to export its routes or that
2156 * is already done and we just need to import those routes
2157 * from the global table?
2158 */
2159 if (first_export)
1d4e8b0d 2160 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 2161 else
1d4e8b0d 2162 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 2163}
2164
1d4e8b0d 2165void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 2166 afi_t afi, safi_t safi)
2167{
a8dadcf6 2168 const char *export_name, *tmp_name;
44338987 2169 vpn_policy_direction_t idir, edir;
2170 char *vname;
9ecf931b 2171 struct ecommunity *ecom = NULL;
44338987 2172 struct listnode *node;
636f7608 2173 int debug;
44338987 2174
5742e42b
DS
2175 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2176 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
44338987 2177 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2178 edir = BGP_VPN_POLICY_DIR_TOVPN;
2179
636f7608
CS
2180 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2181 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2182
44338987 2183 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
2184 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
2185 vname)) {
a8dadcf6 2186 if (strcmp(vname, tmp_name) == 0)
020a3f60 2187 break;
44338987 2188 }
1d4e8b0d
DS
2189
2190 /*
2191 * We do not check in the cli if the passed in bgp
2192 * instance is actually imported into us before
2193 * we call this function. As such if we do not
2194 * find this in the import_vrf list than
2195 * we just need to return safely.
2196 */
44338987 2197 if (!vname)
2198 return;
2199
636f7608
CS
2200 if (debug)
2201 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
2202
44338987 2203 /* Remove "import_vrf" from our import list. */
1d4e8b0d 2204 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 2205 XFREE(MTYPE_TMP, vname);
2206
2207 /* Remove routes imported from "import_vrf". */
2208 /* TODO: In the current logic, we have to first remove all
2209 * imported routes and then (if needed) import back routes
2210 */
1d4e8b0d 2211 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 2212
1d4e8b0d 2213 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
ae6a6fb4
DS
2214 if (!to_bgp->vpn_policy[afi].rmap[idir])
2215 UNSET_FLAG(to_bgp->af_flags[afi][safi],
2216 BGP_CONFIG_VRF_TO_VRF_IMPORT);
9ecf931b
CS
2217 if (to_bgp->vpn_policy[afi].rtlist[idir])
2218 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 2219 } else {
1d4e8b0d 2220 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
9ecf931b
CS
2221 if (ecom)
2222 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 2223 (struct ecommunity_val *)ecom->val);
1d4e8b0d 2224 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 2225 }
2226
89d59347
DS
2227 /*
2228 * What?
2229 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2230 * below is checking for NULL that export_vrf can be
2231 * NULL, consequently it is complaining( like a cabbage )
2232 * that we could dereference and crash in the listcount(..)
2233 * check below.
2234 * So make it happy, under protest, with liberty and justice
2235 * for all.
2236 */
1d4e8b0d 2237 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 2238
44338987 2239 /* Remove us from "import_vrf's" export list. If no other VRF
2240 * is importing from "import_vrf", cleanup appropriately.
2241 */
1d4e8b0d 2242 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 2243 node, vname)) {
2244 if (strcmp(vname, export_name) == 0)
2245 break;
2246 }
2247
1d4e8b0d
DS
2248 /*
2249 * If we have gotten to this point then the vname must
2250 * exist. If not, we are in a world of trouble and
2251 * have slag sitting around.
2252 *
2253 * import_vrf and export_vrf must match in having
2254 * the in/out names as appropriate.
9ecf931b
CS
2255 * export_vrf list could have been cleaned up
2256 * as part of no router bgp source instnace.
1d4e8b0d 2257 */
9ecf931b
CS
2258 if (!vname)
2259 return;
1d4e8b0d
DS
2260
2261 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 2262 XFREE(MTYPE_TMP, vname);
2263
1d4e8b0d
DS
2264 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2265 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
2266 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
2267 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 2268 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 2269 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 2270 sizeof(struct prefix_rd));
1d4e8b0d 2271 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 2272 BGP_VPN_POLICY_TOVPN_RD_SET);
13b7e7f0
DS
2273 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2274
44338987 2275 }
2276}
2277
718e3744 2278/* For testing purpose, static route of MPLS-VPN. */
2279DEFUN (vpnv4_network,
2280 vpnv4_network_cmd,
d114b977 2281 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 2282 "Specify a network to announce via BGP\n"
0c7b1b01 2283 "IPv4 prefix\n"
718e3744 2284 "Specify Route Distinguisher\n"
2285 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2286 "VPN NLRI label (tag)\n"
2287 "VPN NLRI label (tag)\n"
2288 "Label value\n")
718e3744 2289{
d62a17ae 2290 int idx_ipv4_prefixlen = 1;
2291 int idx_ext_community = 3;
2292 int idx_label = 5;
2293 return bgp_static_set_safi(
2294 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2295 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
2296 NULL, NULL, NULL, NULL);
137446f9
LB
2297}
2298
2299DEFUN (vpnv4_network_route_map,
2300 vpnv4_network_route_map_cmd,
d114b977 2301 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 2302 "Specify a network to announce via BGP\n"
0c7b1b01 2303 "IPv4 prefix\n"
137446f9
LB
2304 "Specify Route Distinguisher\n"
2305 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2306 "VPN NLRI label (tag)\n"
2307 "VPN NLRI label (tag)\n"
2308 "Label value\n"
137446f9
LB
2309 "route map\n"
2310 "route map name\n")
2311{
d62a17ae 2312 int idx_ipv4_prefixlen = 1;
2313 int idx_ext_community = 3;
2314 int idx_label = 5;
2315 int idx_word_2 = 7;
2316 return bgp_static_set_safi(
2317 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2318 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2319 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 2320}
2321
2322/* For testing purpose, static route of MPLS-VPN. */
2323DEFUN (no_vpnv4_network,
2324 no_vpnv4_network_cmd,
d114b977 2325 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 2326 NO_STR
2327 "Specify a network to announce via BGP\n"
0c7b1b01 2328 "IPv4 prefix\n"
718e3744 2329 "Specify Route Distinguisher\n"
2330 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2331 "VPN NLRI label (tag)\n"
2332 "VPN NLRI label (tag)\n"
2333 "Label value\n")
718e3744 2334{
d62a17ae 2335 int idx_ipv4_prefixlen = 2;
2336 int idx_ext_community = 4;
2337 int idx_label = 6;
2338 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
2339 argv[idx_ipv4_prefixlen]->arg,
2340 argv[idx_ext_community]->arg,
2341 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 2342}
2343
c286be96
LX
2344DEFUN (vpnv6_network,
2345 vpnv6_network_cmd,
d114b977 2346 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
2347 "Specify a network to announce via BGP\n"
2348 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2349 "Specify Route Distinguisher\n"
2350 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2351 "VPN NLRI label (tag)\n"
2352 "VPN NLRI label (tag)\n"
2353 "Label value\n"
11daee81
DS
2354 "route map\n"
2355 "route map name\n")
c286be96 2356{
d62a17ae 2357 int idx_ipv6_prefix = 1;
2358 int idx_ext_community = 3;
2359 int idx_label = 5;
2360 int idx_word_2 = 7;
2361 if (argc == 8)
2362 return bgp_static_set_safi(
2363 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2364 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2365 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2366 else
2367 return bgp_static_set_safi(
2368 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2369 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2370 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
2371}
2372
2373/* For testing purpose, static route of MPLS-VPN. */
2374DEFUN (no_vpnv6_network,
2375 no_vpnv6_network_cmd,
d114b977 2376 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
2377 NO_STR
2378 "Specify a network to announce via BGP\n"
2379 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2380 "Specify Route Distinguisher\n"
2381 "VPN Route Distinguisher\n"
fb1d2a2d
LB
2382 "VPN NLRI label (tag)\n"
2383 "VPN NLRI label (tag)\n"
2384 "Label value\n")
c286be96 2385{
d62a17ae 2386 int idx_ipv6_prefix = 2;
2387 int idx_ext_community = 4;
2388 int idx_label = 6;
2389 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
2390 argv[idx_ipv6_prefix]->arg,
2391 argv[idx_ext_community]->arg,
2392 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
2393}
2394
d62a17ae 2395int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
2396 enum bgp_show_type type, void *output_arg, int tags,
9f049418 2397 bool use_json)
718e3744 2398{
d62a17ae 2399 struct bgp *bgp;
2400 struct bgp_table *table;
d62a17ae 2401
2402 bgp = bgp_get_default();
2403 if (bgp == NULL) {
2404 if (!use_json)
2405 vty_out(vty, "No BGP process is configured\n");
16307668
RW
2406 else
2407 vty_out(vty, "{}\n");
d62a17ae 2408 return CMD_WARNING;
2409 }
1ae44dfc 2410 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
2411 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
2412 output_arg, use_json);
718e3744 2413}
2414
4f280b15
LB
2415DEFUN (show_bgp_ip_vpn_all_rd,
2416 show_bgp_ip_vpn_all_rd_cmd,
a111dd97 2417 "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
e3e29b32
LB
2418 SHOW_STR
2419 BGP_STR
05e588f4 2420 BGP_VPNVX_HELP_STR
e3e29b32 2421 "Display VPN NLRI specific information\n"
af8528fa 2422 "Display VPN NLRI specific information\n"
e3e29b32
LB
2423 "Display information for a route distinguisher\n"
2424 "VPN Route Distinguisher\n"
a111dd97 2425 "All VPN Route Distinguishers\n"
e3e29b32
LB
2426 JSON_STR)
2427{
d62a17ae 2428 int ret;
2429 struct prefix_rd prd;
2430 afi_t afi;
2431 int idx = 0;
2432
2433 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
a111dd97
TA
2434 /* Constrain search if user supplies RD && RD != "all" */
2435 if (argv_find(argv, argc, "rd", &idx)
2436 && strcmp(argv[idx + 1]->arg, "all")) {
a4d82a8a 2437 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 2438 if (!ret) {
2439 vty_out(vty,
2440 "%% Malformed Route Distinguisher\n");
2441 return CMD_WARNING;
2442 }
2443 return bgp_show_mpls_vpn(vty, afi, &prd,
2444 bgp_show_type_normal, NULL, 0,
2445 use_json(argc, argv));
2446 } else {
2447 return bgp_show_mpls_vpn(vty, afi, NULL,
2448 bgp_show_type_normal, NULL, 0,
2449 use_json(argc, argv));
2450 }
2451 }
2452 return CMD_SUCCESS;
718e3744 2453}
2454
af8528fa
LB
2455ALIAS(show_bgp_ip_vpn_all_rd,
2456 show_bgp_ip_vpn_rd_cmd,
a111dd97 2457 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
af8528fa
LB
2458 SHOW_STR
2459 BGP_STR
2460 BGP_VPNVX_HELP_STR
2461 "Display VPN NLRI specific information\n"
2462 "Display information for a route distinguisher\n"
2463 "VPN Route Distinguisher\n"
a111dd97 2464 "All VPN Route Distinguishers\n"
af8528fa
LB
2465 JSON_STR)
2466
2467#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
2468DEFUN (show_ip_bgp_vpn_rd,
2469 show_ip_bgp_vpn_rd_cmd,
a111dd97 2470 "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
718e3744 2471 SHOW_STR
2472 IP_STR
2473 BGP_STR
4f280b15 2474 BGP_AFI_HELP_STR
3517059b 2475 "Address Family modifier\n"
718e3744 2476 "Display information for a route distinguisher\n"
a111dd97
TA
2477 "VPN Route Distinguisher\n"
2478 "All VPN Route Distinguishers\n")
718e3744 2479{
d62a17ae 2480 int idx_ext_community = argc - 1;
2481 int ret;
2482 struct prefix_rd prd;
2483 afi_t afi;
2484 int idx = 0;
2485
2486 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
2487 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2488 return bgp_show_mpls_vpn(vty, afi, NULL,
2489 bgp_show_type_normal, NULL, 0,
2490 0);
d62a17ae 2491 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2492 if (!ret) {
2493 vty_out(vty, "%% Malformed Route Distinguisher\n");
2494 return CMD_WARNING;
2495 }
2496 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2497 NULL, 0, 0);
2498 }
2499 return CMD_SUCCESS;
2500}
718e3744 2501
4f280b15
LB
2502DEFUN (show_ip_bgp_vpn_all,
2503 show_ip_bgp_vpn_all_cmd,
2504 "show [ip] bgp <vpnv4|vpnv6>",
2505 SHOW_STR
2506 IP_STR
2507 BGP_STR
2508 BGP_VPNVX_HELP_STR)
2509{
d62a17ae 2510 afi_t afi;
2511 int idx = 0;
4f280b15 2512
d62a17ae 2513 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2514 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2515 NULL, 0, 0);
2516 return CMD_SUCCESS;
4f280b15
LB
2517}
2518
3f227172
PG
2519DEFUN (show_ip_bgp_vpn_all_tags,
2520 show_ip_bgp_vpn_all_tags_cmd,
2521 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 2522 SHOW_STR
2523 IP_STR
2524 BGP_STR
3f227172
PG
2525 BGP_VPNVX_HELP_STR
2526 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 2527 "Display BGP tags for prefixes\n")
2528{
d62a17ae 2529 afi_t afi;
2530 int idx = 0;
3f227172 2531
d62a17ae 2532 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2533 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2534 NULL, 1, 0);
2535 return CMD_SUCCESS;
718e3744 2536}
2537
3f227172
PG
2538DEFUN (show_ip_bgp_vpn_rd_tags,
2539 show_ip_bgp_vpn_rd_tags_cmd,
a111dd97 2540 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
718e3744 2541 SHOW_STR
2542 IP_STR
2543 BGP_STR
3f227172 2544 BGP_VPNVX_HELP_STR
718e3744 2545 "Display information for a route distinguisher\n"
2546 "VPN Route Distinguisher\n"
a111dd97 2547 "All VPN Route Distinguishers\n"
718e3744 2548 "Display BGP tags for prefixes\n")
2549{
d62a17ae 2550 int idx_ext_community = 5;
2551 int ret;
2552 struct prefix_rd prd;
2553 afi_t afi;
2554 int idx = 0;
2555
2556 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
2557 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2558 return bgp_show_mpls_vpn(vty, afi, NULL,
2559 bgp_show_type_normal, NULL, 1,
2560 0);
d62a17ae 2561 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2562 if (!ret) {
2563 vty_out(vty, "%% Malformed Route Distinguisher\n");
2564 return CMD_WARNING;
2565 }
2566 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2567 NULL, 1, 0);
2568 }
2569 return CMD_SUCCESS;
718e3744 2570}
2571
3f227172
PG
2572DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
2573 show_ip_bgp_vpn_all_neighbor_routes_cmd,
2574 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 2575 SHOW_STR
2576 IP_STR
2577 BGP_STR
3f227172
PG
2578 BGP_VPNVX_HELP_STR
2579 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2580 "Detailed information on TCP and BGP neighbor connections\n"
2581 "Neighbor to display information about\n"
856ca177 2582 "Display routes learned from neighbor\n"
9973d184 2583 JSON_STR)
718e3744 2584{
d62a17ae 2585 int idx_ipv4 = 6;
2586 union sockunion su;
2587 struct peer *peer;
2588 int ret;
9f049418 2589 bool uj = use_json(argc, argv);
d62a17ae 2590 afi_t afi;
2591 int idx = 0;
2592
2593 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2594 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2595 if (ret < 0) {
2596 if (uj) {
2597 json_object *json_no = NULL;
2598 json_no = json_object_new_object();
2599 json_object_string_add(json_no, "warning",
2600 "Malformed address");
2601 vty_out(vty, "%s\n",
2602 json_object_to_json_string(json_no));
2603 json_object_free(json_no);
2604 } else
2605 vty_out(vty, "Malformed address: %s\n",
2606 argv[idx_ipv4]->arg);
2607 return CMD_WARNING;
2608 }
2609
2610 peer = peer_lookup(NULL, &su);
2611 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2612 if (uj) {
2613 json_object *json_no = NULL;
2614 json_no = json_object_new_object();
2615 json_object_string_add(
2616 json_no, "warning",
2617 "No such neighbor or address family");
2618 vty_out(vty, "%s\n",
2619 json_object_to_json_string(json_no));
2620 json_object_free(json_no);
2621 } else
2622 vty_out(vty,
2623 "%% No such neighbor or address family\n");
2624 return CMD_WARNING;
2625 }
2626
2627 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
2628 &su, 0, uj);
2629 }
2630 return CMD_SUCCESS;
718e3744 2631}
2632
3f227172
PG
2633DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
2634 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
a111dd97 2635 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
718e3744 2636 SHOW_STR
2637 IP_STR
2638 BGP_STR
3f227172 2639 BGP_VPNVX_HELP_STR
718e3744 2640 "Display information for a route distinguisher\n"
2641 "VPN Route Distinguisher\n"
a111dd97 2642 "All VPN Route Distinguishers\n"
718e3744 2643 "Detailed information on TCP and BGP neighbor connections\n"
2644 "Neighbor to display information about\n"
856ca177 2645 "Display routes learned from neighbor\n"
9973d184 2646 JSON_STR)
718e3744 2647{
d62a17ae 2648 int idx_ext_community = 5;
2649 int idx_ipv4 = 7;
2650 int ret;
2651 union sockunion su;
2652 struct peer *peer;
2653 struct prefix_rd prd;
a111dd97 2654 bool prefix_rd_all = false;
9f049418 2655 bool uj = use_json(argc, argv);
d62a17ae 2656 afi_t afi;
2657 int idx = 0;
2658
2659 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
a111dd97
TA
2660 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2661 prefix_rd_all = true;
2662 else {
2663 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2664 if (!ret) {
2665 if (uj) {
2666 json_object *json_no = NULL;
2667 json_no = json_object_new_object();
2668 json_object_string_add(
2669 json_no, "warning",
2670 "Malformed Route Distinguisher");
2671 vty_out(vty, "%s\n",
2672 json_object_to_json_string(
2673 json_no));
2674 json_object_free(json_no);
2675 } else
2676 vty_out(vty,
2677 "%% Malformed Route Distinguisher\n");
2678 return CMD_WARNING;
2679 }
d62a17ae 2680 }
2681
2682 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2683 if (ret < 0) {
2684 if (uj) {
2685 json_object *json_no = NULL;
2686 json_no = json_object_new_object();
2687 json_object_string_add(json_no, "warning",
2688 "Malformed address");
2689 vty_out(vty, "%s\n",
2690 json_object_to_json_string(json_no));
2691 json_object_free(json_no);
2692 } else
2693 vty_out(vty, "Malformed address: %s\n",
2694 argv[idx_ext_community]->arg);
2695 return CMD_WARNING;
2696 }
2697
2698 peer = peer_lookup(NULL, &su);
2699 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2700 if (uj) {
2701 json_object *json_no = NULL;
2702 json_no = json_object_new_object();
2703 json_object_string_add(
2704 json_no, "warning",
2705 "No such neighbor or address family");
2706 vty_out(vty, "%s\n",
2707 json_object_to_json_string(json_no));
2708 json_object_free(json_no);
2709 } else
2710 vty_out(vty,
2711 "%% No such neighbor or address family\n");
2712 return CMD_WARNING;
2713 }
2714
a111dd97
TA
2715 if (prefix_rd_all)
2716 return bgp_show_mpls_vpn(vty, afi, NULL,
2717 bgp_show_type_neighbor, &su, 0,
2718 uj);
2719 else
2720 return bgp_show_mpls_vpn(vty, afi, &prd,
2721 bgp_show_type_neighbor, &su, 0,
2722 uj);
d62a17ae 2723 }
2724 return CMD_SUCCESS;
718e3744 2725}
2726
3f227172
PG
2727DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2728 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2729 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2730 SHOW_STR
2731 IP_STR
2732 BGP_STR
3f227172
PG
2733 BGP_VPNVX_HELP_STR
2734 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2735 "Detailed information on TCP and BGP neighbor connections\n"
2736 "Neighbor to display information about\n"
856ca177 2737 "Display the routes advertised to a BGP neighbor\n"
9973d184 2738 JSON_STR)
718e3744 2739{
d62a17ae 2740 int idx_ipv4 = 6;
2741 int ret;
2742 struct peer *peer;
2743 union sockunion su;
9f049418 2744 bool uj = use_json(argc, argv);
d62a17ae 2745 afi_t afi;
2746 int idx = 0;
2747
2748 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2749 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2750 if (ret < 0) {
2751 if (uj) {
2752 json_object *json_no = NULL;
2753 json_no = json_object_new_object();
2754 json_object_string_add(json_no, "warning",
2755 "Malformed address");
2756 vty_out(vty, "%s\n",
2757 json_object_to_json_string(json_no));
2758 json_object_free(json_no);
2759 } else
2760 vty_out(vty, "Malformed address: %s\n",
2761 argv[idx_ipv4]->arg);
2762 return CMD_WARNING;
2763 }
2764 peer = peer_lookup(NULL, &su);
2765 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2766 if (uj) {
2767 json_object *json_no = NULL;
2768 json_no = json_object_new_object();
2769 json_object_string_add(
2770 json_no, "warning",
2771 "No such neighbor or address family");
2772 vty_out(vty, "%s\n",
2773 json_object_to_json_string(json_no));
2774 json_object_free(json_no);
2775 } else
2776 vty_out(vty,
2777 "%% No such neighbor or address family\n");
2778 return CMD_WARNING;
2779 }
2780 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2781 SAFI_MPLS_VPN, uj);
2782 }
2783 return CMD_SUCCESS;
718e3744 2784}
2785
3f227172
PG
2786DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2787 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
a111dd97 2788 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
718e3744 2789 SHOW_STR
2790 IP_STR
2791 BGP_STR
3f227172 2792 BGP_VPNVX_HELP_STR
718e3744 2793 "Display information for a route distinguisher\n"
2794 "VPN Route Distinguisher\n"
a111dd97 2795 "All VPN Route Distinguishers\n"
718e3744 2796 "Detailed information on TCP and BGP neighbor connections\n"
2797 "Neighbor to display information about\n"
856ca177 2798 "Display the routes advertised to a BGP neighbor\n"
9973d184 2799 JSON_STR)
718e3744 2800{
d62a17ae 2801 int idx_ext_community = 5;
2802 int idx_ipv4 = 7;
2803 int ret;
2804 struct peer *peer;
2805 struct prefix_rd prd;
2806 union sockunion su;
9f049418 2807 bool uj = use_json(argc, argv);
d62a17ae 2808 afi_t afi;
2809 int idx = 0;
2810
2811 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2812 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2813 if (ret < 0) {
2814 if (uj) {
2815 json_object *json_no = NULL;
2816 json_no = json_object_new_object();
2817 json_object_string_add(json_no, "warning",
2818 "Malformed address");
2819 vty_out(vty, "%s\n",
2820 json_object_to_json_string(json_no));
2821 json_object_free(json_no);
2822 } else
2823 vty_out(vty, "Malformed address: %s\n",
2824 argv[idx_ext_community]->arg);
2825 return CMD_WARNING;
2826 }
2827 peer = peer_lookup(NULL, &su);
2828 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2829 if (uj) {
2830 json_object *json_no = NULL;
2831 json_no = json_object_new_object();
2832 json_object_string_add(
2833 json_no, "warning",
2834 "No such neighbor or address family");
2835 vty_out(vty, "%s\n",
2836 json_object_to_json_string(json_no));
2837 json_object_free(json_no);
2838 } else
2839 vty_out(vty,
2840 "%% No such neighbor or address family\n");
2841 return CMD_WARNING;
2842 }
2843
a111dd97
TA
2844 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2845 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2846 SAFI_MPLS_VPN, uj);
d62a17ae 2847 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2848 if (!ret) {
2849 if (uj) {
2850 json_object *json_no = NULL;
2851 json_no = json_object_new_object();
2852 json_object_string_add(
2853 json_no, "warning",
2854 "Malformed Route Distinguisher");
2855 vty_out(vty, "%s\n",
2856 json_object_to_json_string(json_no));
2857 json_object_free(json_no);
2858 } else
2859 vty_out(vty,
2860 "%% Malformed Route Distinguisher\n");
2861 return CMD_WARNING;
2862 }
2863
2864 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2865 SAFI_MPLS_VPN, uj);
2866 }
2867 return CMD_SUCCESS;
718e3744 2868}
d6902373 2869#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2870
d62a17ae 2871void bgp_mplsvpn_init(void)
718e3744 2872{
d62a17ae 2873 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2874 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2875 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2876
d62a17ae 2877 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2878 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2879
d62a17ae 2880 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2881 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2882#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2883 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2884 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2885 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2886 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2887 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2888 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2889 install_element(VIEW_NODE,
2890 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2891 install_element(VIEW_NODE,
2892 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2893#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2894}
301ad80a
PG
2895
2896vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2897{
2898 struct listnode *mnode, *mnnode;
2899 struct bgp *bgp;
9a659715
PG
2900 afi_t afi = AFI_IP;
2901
2902 if (eckey->unit_size == IPV6_ECOMMUNITY_SIZE)
2903 afi = AFI_IP6;
301ad80a
PG
2904
2905 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2906 struct ecommunity *ec;
2907
2908 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2909 continue;
2910
9a659715
PG
2911 ec = bgp->vpn_policy[afi].import_redirect_rtlist;
2912
2913 if (ec && eckey->unit_size != ec->unit_size)
2914 continue;
301ad80a
PG
2915
2916 if (ecom_intersect(ec, eckey))
2917 return bgp->vrf_id;
2918 }
2919 return VRF_UNKNOWN;
2920}
3bd70bf8
PZ
2921
2922/*
2923 * The purpose of this function is to process leaks that were deferred
2924 * from earlier per-vrf configuration due to not-yet-existing default
2925 * vrf, in other words, configuration such as:
2926 *
2927 * router bgp MMM vrf FOO
2928 * address-family ipv4 unicast
2929 * rd vpn export 1:1
2930 * exit-address-family
2931 *
2932 * router bgp NNN
2933 * ...
2934 *
2935 * This function gets called when the default instance ("router bgp NNN")
2936 * is created.
2937 */
2938void vpn_leak_postchange_all(void)
2939{
2940 struct listnode *next;
2941 struct bgp *bgp;
2942 struct bgp *bgp_default = bgp_get_default();
2943
2944 assert(bgp_default);
2945
2946 /* First, do any exporting from VRFs to the single VPN RIB */
2947 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2948
2949 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2950 continue;
2951
2952 vpn_leak_postchange(
2953 BGP_VPN_POLICY_DIR_TOVPN,
2954 AFI_IP,
2955 bgp_default,
2956 bgp);
2957
2958 vpn_leak_postchange(
2959 BGP_VPN_POLICY_DIR_TOVPN,
2960 AFI_IP6,
2961 bgp_default,
2962 bgp);
2963 }
2964
2965 /* Now, do any importing to VRFs from the single VPN RIB */
2966 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2967
2968 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2969 continue;
2970
2971 vpn_leak_postchange(
2972 BGP_VPN_POLICY_DIR_FROMVPN,
2973 AFI_IP,
2974 bgp_default,
2975 bgp);
2976
2977 vpn_leak_postchange(
2978 BGP_VPN_POLICY_DIR_FROMVPN,
2979 AFI_IP6,
2980 bgp_default,
2981 bgp);
2982 }
2983}
9ecf931b
CS
2984
2985/* When a bgp vrf instance is unconfigured, remove its routes
2986 * from the VPN table and this vrf could be importing routes from other
2987 * bgp vrf instnaces, unimport them.
2988 * VRF X and VRF Y are exporting routes to each other.
2989 * When VRF X is deleted, unimport its routes from all target vrfs,
2990 * also VRF Y should unimport its routes from VRF X table.
2991 * This will ensure VPN table is cleaned up appropriately.
2992 */
ff8a8a7a 2993void bgp_vpn_leak_unimport(struct bgp *from_bgp)
9ecf931b
CS
2994{
2995 struct bgp *to_bgp;
2996 const char *tmp_name;
2997 char *vname;
2998 struct listnode *node, *next;
2999 safi_t safi = SAFI_UNICAST;
3000 afi_t afi;
3001 bool is_vrf_leak_bind;
3002 int debug;
3003
3004 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
ff8a8a7a 3005 return;
9ecf931b
CS
3006
3007 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3008 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3009
3010 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3011
3012 for (afi = 0; afi < AFI_MAX; ++afi) {
3013 /* vrf leak is for IPv4 and IPv6 Unicast only */
3014 if (afi != AFI_IP && afi != AFI_IP6)
3015 continue;
3016
3017 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3018 if (from_bgp == to_bgp)
3019 continue;
3020
3021 /* Unimport and remove source vrf from the
3022 * other vrfs import list.
3023 */
3024 struct vpn_policy *to_vpolicy;
3025
3026 is_vrf_leak_bind = false;
3027 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3028 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
3029 vname)) {
3030 if (strcmp(vname, tmp_name) == 0) {
3031 is_vrf_leak_bind = true;
3032 break;
3033 }
3034 }
3035 /* skip this bgp instance as there is no leak to this
3036 * vrf instance.
3037 */
3038 if (!is_vrf_leak_bind)
3039 continue;
3040
3041 if (debug)
3042 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3043 __func__, from_bgp->name_pretty,
3044 to_bgp->name_pretty, afi2str(afi),
3045 to_vpolicy->import_vrf->count);
3046
3047 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
3048
3049 /* readd vrf name as unimport removes import vrf name
3050 * from the destination vrf's import list where the
3051 * `import vrf` configuration still exist.
3052 */
3053 vname = XSTRDUP(MTYPE_TMP, tmp_name);
3054 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
3055 vname);
3056 SET_FLAG(to_bgp->af_flags[afi][safi],
3057 BGP_CONFIG_VRF_TO_VRF_IMPORT);
3058
3059 /* If to_bgp exports its routes to the bgp vrf
3060 * which is being deleted, un-import the
3061 * to_bgp routes from VPN.
3062 */
3063 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
3064 .export_vrf, node,
3065 vname)) {
3066 if (strcmp(vname, tmp_name) == 0) {
3067 vrf_unimport_from_vrf(from_bgp, to_bgp,
3068 afi, safi);
3069 break;
3070 }
3071 }
3072 }
3073 }
ff8a8a7a 3074 return;
9ecf931b 3075}
48381346
CS
3076
3077/* When a router bgp is configured, there could be a bgp vrf
3078 * instance importing routes from this newly configured
3079 * bgp vrf instance. Export routes from configured
3080 * bgp vrf to VPN.
3081 * VRF Y has import from bgp vrf x,
3082 * when a bgp vrf x instance is created, export its routes
3083 * to VRF Y instance.
3084 */
3085void bgp_vpn_leak_export(struct bgp *from_bgp)
3086{
3087 afi_t afi;
3088 const char *export_name;
3089 char *vname;
3090 struct listnode *node, *next;
3091 struct ecommunity *ecom;
3092 vpn_policy_direction_t idir, edir;
3093 safi_t safi = SAFI_UNICAST;
3094 struct bgp *to_bgp;
3095 int debug;
3096
3097 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3098 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3099
3100 idir = BGP_VPN_POLICY_DIR_FROMVPN;
3101 edir = BGP_VPN_POLICY_DIR_TOVPN;
3102
00d968c4 3103 export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
48381346
CS
3104
3105 for (afi = 0; afi < AFI_MAX; ++afi) {
3106 /* vrf leak is for IPv4 and IPv6 Unicast only */
3107 if (afi != AFI_IP && afi != AFI_IP6)
3108 continue;
3109
3110 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3111 if (from_bgp == to_bgp)
3112 continue;
3113
3114 /* bgp instance has import list, check to see if newly
3115 * configured bgp instance is the list.
3116 */
3117 struct vpn_policy *to_vpolicy;
3118
3119 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3120 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
3121 node, vname)) {
3122 if (strcmp(vname, export_name) != 0)
3123 continue;
3124
3125 if (debug)
3126 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3127 __func__,
3128 export_name, to_bgp->name_pretty);
3129
3130 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
3131 /* remove import rt, it will be readded
3132 * as part of import from vrf.
3133 */
3134 if (ecom)
3135 ecommunity_del_val(
3136 to_vpolicy->rtlist[idir],
3137 (struct ecommunity_val *)
3138 ecom->val);
3139 vrf_import_from_vrf(to_bgp, from_bgp,
3140 afi, safi);
3141 break;
3142
3143 }
3144 }
3145 }
3146}