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