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