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