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