]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #1825 from chiragshah6/ospfv3_dev
[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
48 #if ENABLE_BGP_VNC
49 #include "bgpd/rfapi/rfapi_backend.h"
50 #endif
51
52 /*
53 * Definitions and external declarations.
54 */
55 extern struct zclient *zclient;
56
57 extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
58 int *index, afi_t *afi)
59 {
60 int ret = 0;
61 if (argv_find(argv, argc, "vpnv4", index)) {
62 ret = 1;
63 if (afi)
64 *afi = AFI_IP;
65 } else if (argv_find(argv, argc, "vpnv6", index)) {
66 ret = 1;
67 if (afi)
68 *afi = AFI_IP6;
69 }
70 return ret;
71 }
72
73 u_int32_t decode_label(mpls_label_t *label_pnt)
74 {
75 u_int32_t l;
76 u_char *pnt = (u_char *)label_pnt;
77
78 l = ((u_int32_t)*pnt++ << 12);
79 l |= (u_int32_t)*pnt++ << 4;
80 l |= (u_int32_t)((*pnt & 0xf0) >> 4);
81 return l;
82 }
83
84 void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
85 {
86 u_char *pnt = (u_char *)label_pnt;
87 if (pnt == NULL)
88 return;
89 *pnt++ = (label >> 12) & 0xff;
90 *pnt++ = (label >> 4) & 0xff;
91 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
92 }
93
94 int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
95 struct bgp_nlri *packet)
96 {
97 u_char *pnt;
98 u_char *lim;
99 struct prefix p;
100 int psize = 0;
101 int prefixlen;
102 u_int16_t type;
103 struct rd_as rd_as;
104 struct rd_ip rd_ip;
105 struct prefix_rd prd;
106 mpls_label_t label = {0};
107 afi_t afi;
108 safi_t safi;
109 int addpath_encoded;
110 u_int32_t addpath_id;
111
112 /* Make prefix_rd */
113 prd.family = AF_UNSPEC;
114 prd.prefixlen = 64;
115
116 pnt = packet->nlri;
117 lim = pnt + packet->length;
118 afi = packet->afi;
119 safi = packet->safi;
120 addpath_id = 0;
121
122 addpath_encoded =
123 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
124 && CHECK_FLAG(peer->af_cap[afi][safi],
125 PEER_CAP_ADDPATH_AF_TX_RCV));
126
127 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
128 for (; pnt < lim; pnt += psize) {
129 /* Clear prefix structure. */
130 memset(&p, 0, sizeof(struct prefix));
131
132 if (addpath_encoded) {
133
134 /* When packet overflow occurs return immediately. */
135 if (pnt + BGP_ADDPATH_ID_LEN > lim)
136 return -1;
137
138 addpath_id = ntohl(*((uint32_t *)pnt));
139 pnt += BGP_ADDPATH_ID_LEN;
140 }
141
142 /* Fetch prefix length. */
143 prefixlen = *pnt++;
144 p.family = afi2family(packet->afi);
145 psize = PSIZE(prefixlen);
146
147 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
148 zlog_err(
149 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
150 peer->host, prefixlen);
151 return -1;
152 }
153
154 /* sanity check against packet data */
155 if ((pnt + psize) > lim) {
156 zlog_err(
157 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
158 peer->host, prefixlen, (uint)(lim - pnt));
159 return -1;
160 }
161
162 /* sanity check against storage for the IP address portion */
163 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
164 zlog_err(
165 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
166 peer->host,
167 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
168 sizeof(p.u));
169 return -1;
170 }
171
172 /* Sanity check against max bitlen of the address family */
173 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
174 zlog_err(
175 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
176 peer->host,
177 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
178 p.family, prefix_blen(&p));
179 return -1;
180 }
181
182 /* Copy label to prefix. */
183 memcpy(&label, pnt, BGP_LABEL_BYTES);
184 bgp_set_valid_label(&label);
185
186 /* Copy routing distinguisher to rd. */
187 memcpy(&prd.val, pnt + BGP_LABEL_BYTES, 8);
188
189 /* Decode RD type. */
190 type = decode_rd_type(pnt + BGP_LABEL_BYTES);
191
192 switch (type) {
193 case RD_TYPE_AS:
194 decode_rd_as(pnt + 5, &rd_as);
195 break;
196
197 case RD_TYPE_AS4:
198 decode_rd_as4(pnt + 5, &rd_as);
199 break;
200
201 case RD_TYPE_IP:
202 decode_rd_ip(pnt + 5, &rd_ip);
203 break;
204
205 #if ENABLE_BGP_VNC
206 case RD_TYPE_VNC_ETH:
207 break;
208 #endif
209
210 default:
211 zlog_err("Unknown RD type %d", type);
212 break; /* just report */
213 }
214
215 p.prefixlen =
216 prefixlen
217 - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
218 memcpy(&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
219 psize - VPN_PREFIXLEN_MIN_BYTES);
220
221 if (attr) {
222 bgp_update(peer, &p, addpath_id, attr, packet->afi,
223 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
224 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
225 } else {
226 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
227 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
228 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
229 }
230 }
231 /* Packet length consistency check. */
232 if (pnt != lim) {
233 zlog_err(
234 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
235 peer->host, lim - pnt);
236 return -1;
237 }
238
239 return 0;
240 #undef VPN_PREFIXLEN_MIN_BYTES
241 }
242
243 /*
244 * This function informs zebra of the label this vrf sets on routes
245 * leaked to VPN. Zebra should install this label in the kernel with
246 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
247 *
248 * Sending this vrf-label association is qualified by a) whether vrf->vpn
249 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
250 * are set) and b) whether vpn-policy label is set.
251 *
252 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
253 * for this vrf, which zebra interprets to mean "delete this vrf-label
254 * association."
255 */
256 void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
257 {
258 mpls_label_t label = MPLS_LABEL_NONE;
259 const char *name = "default";
260 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
261
262 if (debug && (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)) {
263 name = bgp->name;
264 }
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__, name, 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__, name, afi2str(afi), label, bgp->vrf_id);
283 }
284
285 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
286 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
287 }
288
289 /*
290 * If zebra tells us vrf has become unconfigured, tell zebra not to
291 * use this label to forward to the vrf anymore
292 */
293 void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
294 {
295 mpls_label_t label = MPLS_LABEL_NONE;
296 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
297
298 if (bgp->vrf_id == VRF_UNKNOWN) {
299 if (debug) {
300 zlog_debug(
301 "%s: vrf_id not set, can't delete zebra vrf label",
302 __func__);
303 }
304 return;
305 }
306
307 if (debug) {
308 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
309 (bgp->name ? bgp->name : "default"), bgp->vrf_id);
310 }
311
312 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
313 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
314 }
315
316 static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
317 {
318 int i;
319 int j;
320
321 if (!e1 || !e2)
322 return 0;
323
324 for (i = 0; i < e1->size; ++i) {
325 for (j = 0; j < e2->size; ++j) {
326 if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE),
327 e2->val + (j * ECOMMUNITY_SIZE),
328 ECOMMUNITY_SIZE)) {
329
330 return 1;
331 }
332 }
333 }
334 return 0;
335 }
336
337 /*
338 * returns pointer to new bgp_info upon success
339 */
340 static struct bgp_info *
341 leak_update(struct bgp *bgp, /* destination bgp instance */
342 struct bgp_node *bn, struct attr *new_attr, /* already interned */
343 afi_t afi, safi_t safi, struct bgp_info *source_bi, u_char type,
344 u_char sub_type, mpls_label_t *label, int num_labels, void *parent,
345 struct bgp *bgp_orig, struct prefix *nexthop_orig, int debug)
346 {
347 struct prefix *p = &bn->p;
348 struct bgp_info *bi;
349 struct bgp_info *new;
350 char buf_prefix[PREFIX_STRLEN];
351 const char *pDestInstanceName = "default";
352
353 if (debug) {
354 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
355 if (bgp->name)
356 pDestInstanceName = bgp->name;
357 }
358
359 /*
360 * match parent
361 */
362 for (bi = bn->info; bi; bi = bi->next) {
363 if (bi->extra && bi->extra->parent == parent)
364 break;
365 }
366
367 if (bi) {
368 if (attrhash_cmp(bi->attr, new_attr)
369 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
370
371 bgp_attr_unintern(&new_attr);
372 if (debug)
373 zlog_debug(
374 "%s: ->%s: %s: Found route, no change",
375 __func__, pDestInstanceName,
376 buf_prefix);
377 return NULL;
378 }
379
380 /* attr is changed */
381 bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
382
383 /* Rewrite BGP route information. */
384 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
385 bgp_info_restore(bn, bi);
386 else
387 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
388 bgp_attr_unintern(&bi->attr);
389 bi->attr = new_attr;
390 bi->uptime = bgp_clock();
391
392 /* Process change. */
393 bgp_aggregate_increment(bgp, p, bi, afi, safi);
394 bgp_process(bgp, bn, afi, safi);
395 bgp_unlock_node(bn);
396
397 if (debug)
398 zlog_debug("%s: ->%s: %s Found route, changed attr",
399 __func__, pDestInstanceName, buf_prefix);
400
401 return NULL;
402 }
403
404 new = info_make(type, sub_type, 0, bgp->peer_self, new_attr, bn);
405 SET_FLAG(new->flags, BGP_INFO_VALID);
406
407 bgp_info_extra_get(new);
408 if (label) {
409 int i;
410
411 for (i = 0; i < num_labels; ++i) {
412 new->extra->label[i] = label[i];
413 if (!bgp_is_valid_label(&label[i])) {
414 if (debug) {
415 zlog_debug(
416 "%s: %s: marking label %d valid",
417 __func__, buf_prefix, i);
418 }
419 bgp_set_valid_label(&new->extra->label[i]);
420 }
421 }
422 new->extra->num_labels = num_labels;
423 }
424 new->extra->parent = parent;
425
426 if (bgp_orig)
427 new->extra->bgp_orig = bgp_orig;
428 if (nexthop_orig)
429 new->extra->nexthop_orig = *nexthop_orig;
430
431 bgp_aggregate_increment(bgp, p, new, afi, safi);
432 bgp_info_add(bn, new);
433
434 bgp_unlock_node(bn);
435 bgp_process(bgp, bn, afi, safi);
436
437 if (debug)
438 zlog_debug("%s: ->%s: %s: Added new route", __func__,
439 pDestInstanceName, buf_prefix);
440
441 return new;
442 }
443
444 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
445 void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
446 struct bgp *bgp_vrf, /* from */
447 struct bgp_info *info_vrf) /* route */
448 {
449 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
450 struct prefix *p = &info_vrf->net->p;
451 afi_t afi = family2afi(p->family);
452 struct attr static_attr = {0};
453 struct attr *new_attr = NULL;
454 safi_t safi = SAFI_MPLS_VPN;
455 mpls_label_t label_val;
456 mpls_label_t label;
457 struct bgp_node *bn;
458 const char *debugmsg;
459
460 if (debug) {
461 const char *s = "";
462
463 if (info_vrf->attr && info_vrf->attr->ecommunity) {
464 s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
465 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
466 }
467
468 zlog_debug("%s: info_vrf->type=%d, EC{%s}", __func__,
469 info_vrf->type, s);
470 }
471
472 if (!bgp_vpn)
473 return;
474
475 if (!afi) {
476 if (debug)
477 zlog_debug("%s: can't get afi of prefix", __func__);
478 return;
479 }
480
481 /* loop check */
482 if (info_vrf->extra && info_vrf->extra->bgp_orig == bgp_vpn)
483 return;
484
485
486 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
487 if (debug)
488 zlog_debug("%s: skipping: %s", __func__, debugmsg);
489 return;
490 }
491
492 bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
493
494 /*
495 * route map handling
496 */
497 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
498 struct bgp_info info;
499 route_map_result_t ret;
500
501 memset(&info, 0, sizeof(info));
502 info.peer = bgp_vpn->peer_self;
503 info.attr = &static_attr;
504 ret = route_map_apply(
505 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
506 p, RMAP_BGP, &info);
507 if (RMAP_DENYMATCH == ret) {
508 bgp_attr_flush(&static_attr); /* free any added parts */
509 if (debug)
510 zlog_debug(
511 "%s: vrf %s route map \"%s\" says DENY, returning",
512 __func__, bgp_vrf->name,
513 bgp_vrf->vpn_policy[afi]
514 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
515 ->name);
516 return;
517 }
518 }
519
520 if (debug) {
521 const char *s = "";
522
523 if (static_attr.ecommunity) {
524 s = ecommunity_ecom2str(static_attr.ecommunity,
525 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
526 }
527 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
528 __func__, s);
529 }
530
531 /*
532 * Add the vpn-policy rt-list
533 */
534 struct ecommunity *old_ecom;
535 struct ecommunity *new_ecom;
536
537 old_ecom = static_attr.ecommunity;
538 if (old_ecom) {
539 new_ecom = ecommunity_merge(
540 ecommunity_dup(old_ecom),
541 bgp_vrf->vpn_policy[afi]
542 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
543 if (!old_ecom->refcnt)
544 ecommunity_free(&old_ecom);
545 } else {
546 new_ecom = ecommunity_dup(
547 bgp_vrf->vpn_policy[afi]
548 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
549 }
550 static_attr.ecommunity = new_ecom;
551 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
552
553 if (debug) {
554 const char *s = "";
555
556 if (static_attr.ecommunity) {
557 s = ecommunity_ecom2str(static_attr.ecommunity,
558 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
559 }
560 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
561 __func__, s);
562 }
563
564 /* Nexthop */
565 /* if policy nexthop not set, use 0 */
566 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
567 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
568
569 struct prefix *nexthop =
570 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
571 switch (nexthop->family) {
572 case AF_INET:
573 /* prevent mp_nexthop_global_in <- self in bgp_route.c
574 */
575 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
576
577 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
578 static_attr.mp_nexthop_len = 4;
579 break;
580
581 case AF_INET6:
582 static_attr.mp_nexthop_global = nexthop->u.prefix6;
583 static_attr.mp_nexthop_len = 16;
584 break;
585
586 default:
587 assert(0);
588 }
589 } else {
590 switch (afi) {
591 case AFI_IP:
592 default:
593 /* Clear ipv4 */
594 static_attr.mp_nexthop_global_in.s_addr = 0;
595 static_attr.mp_nexthop_len = 4;
596 static_attr.nexthop.s_addr = 0; /* self */
597 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
598 break;
599
600 case AFI_IP6:
601 /* Clear ipv6 */
602 memset(&static_attr.mp_nexthop_global, 0,
603 sizeof(static_attr.mp_nexthop_global));
604 static_attr.mp_nexthop_len = 16; /* bytes */
605 break;
606 }
607 }
608
609 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
610 if (label_val == MPLS_LABEL_NONE) {
611 /* TBD get from label manager */
612 label = MPLS_LABEL_IMPLICIT_NULL;
613 } else {
614 encode_label(label_val, &label);
615 }
616
617 /* Set originator ID to "me" */
618 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
619 static_attr.originator_id = bgp_vpn->router_id;
620
621
622 new_attr = bgp_attr_intern(
623 &static_attr); /* hashed refcounted everything */
624 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
625
626 if (debug && new_attr->ecommunity) {
627 char *s = ecommunity_ecom2str(new_attr->ecommunity,
628 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
629
630 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
631 XFREE(MTYPE_ECOMMUNITY_STR, s);
632 }
633
634 /* Now new_attr is an allocated interned attr */
635
636 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
637 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
638
639 struct bgp_info *new_info;
640
641 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
642 ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, &label, 1,
643 info_vrf, bgp_vrf, NULL, debug);
644
645 /*
646 * Routes actually installed in the vpn RIB must also be
647 * offered to all vrfs (because now they originate from
648 * the vpn RIB).
649 *
650 * Acceptance into other vrfs depends on rt-lists.
651 * Originating vrf will not accept the looped back route
652 * because of loop checking.
653 */
654 if (new_info)
655 vpn_leak_to_vrf_update(bgp_vrf, new_info);
656 }
657
658 void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
659 struct bgp *bgp_vrf, /* from */
660 struct bgp_info *info_vrf) /* route */
661 {
662 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
663 struct prefix *p = &info_vrf->net->p;
664 afi_t afi = family2afi(p->family);
665 safi_t safi = SAFI_MPLS_VPN;
666 struct bgp_info *bi;
667 struct bgp_node *bn;
668 const char *debugmsg;
669
670 if (info_vrf->type != ZEBRA_ROUTE_BGP) {
671 if (debug)
672 zlog_debug("%s: wrong type %d", __func__,
673 info_vrf->type);
674 return;
675 }
676 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
677 && info_vrf->sub_type != BGP_ROUTE_STATIC) {
678
679 if (debug)
680 zlog_debug("%s: wrong sub_type %d", __func__,
681 info_vrf->sub_type);
682 return;
683 }
684 if (!bgp_vpn)
685 return;
686
687 if (!afi) {
688 if (debug)
689 zlog_debug("%s: can't get afi of prefix", __func__);
690 return;
691 }
692
693 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
694 if (debug)
695 zlog_debug("%s: skipping: %s", __func__, debugmsg);
696 return;
697 }
698
699 if (debug)
700 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
701
702 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
703 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
704
705 /*
706 * vrf -> vpn
707 * match original bi imported from
708 */
709 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
710 if (bi->extra && bi->extra->parent == info_vrf) {
711 break;
712 }
713 }
714
715 if (bi) {
716 /* withdraw from looped vrfs as well */
717 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
718
719 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
720 bgp_info_delete(bn, bi);
721 bgp_process(bgp_vpn, bn, afi, safi);
722 }
723 bgp_unlock_node(bn);
724 }
725
726 void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
727 struct bgp *bgp_vrf, /* from */
728 afi_t afi)
729 {
730 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
731 struct bgp_node *prn;
732 safi_t safi = SAFI_MPLS_VPN;
733
734 /*
735 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
736 */
737 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
738 prn = bgp_route_next(prn)) {
739
740 struct bgp_table *table;
741 struct bgp_node *bn;
742 struct bgp_info *bi;
743
744 /* This is the per-RD table of prefixes */
745 table = prn->info;
746
747 if (!table)
748 continue;
749
750 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
751
752 char buf[PREFIX2STR_BUFFER];
753
754 if (debug && bn->info) {
755 zlog_debug(
756 "%s: looking at prefix %s", __func__,
757 prefix2str(&bn->p, buf, sizeof(buf)));
758 }
759
760 for (bi = bn->info; bi; bi = bi->next) {
761 if (debug)
762 zlog_debug("%s: type %d, sub_type %d",
763 __func__, bi->type,
764 bi->sub_type);
765 if (bi->sub_type != BGP_ROUTE_IMPORTED)
766 continue;
767 if (!bi->extra)
768 continue;
769 if ((struct bgp *)bi->extra->bgp_orig
770 == bgp_vrf) {
771 /* delete route */
772 if (debug)
773 zlog_debug("%s: deleting it\n",
774 __func__);
775 bgp_aggregate_decrement(bgp_vpn, &bn->p,
776 bi, afi, safi);
777 bgp_info_delete(bn, bi);
778 bgp_process(bgp_vpn, bn, afi, safi);
779 }
780 }
781 }
782 }
783 }
784
785 void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
786 struct bgp *bgp_vrf, /* from */
787 afi_t afi)
788 {
789 struct bgp_node *bn;
790 struct bgp_info *bi;
791 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
792
793 if (debug)
794 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
795 bgp_vrf->name);
796
797 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
798 bn = bgp_route_next(bn)) {
799
800 if (debug)
801 zlog_debug("%s: node=%p", __func__, bn);
802
803 for (bi = bn->info; bi; bi = bi->next) {
804 if (debug)
805 zlog_debug(
806 "%s: calling vpn_leak_from_vrf_update",
807 __func__);
808 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
809 }
810 }
811 }
812
813 static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
814 struct bgp *bgp_vpn, /* from */
815 struct bgp_info *info_vpn) /* route */
816 {
817 struct prefix *p = &info_vpn->net->p;
818 afi_t afi = family2afi(p->family);
819
820 struct attr static_attr = {0};
821 struct attr *new_attr = NULL;
822 struct bgp_node *bn;
823 safi_t safi = SAFI_UNICAST;
824 const char *debugmsg;
825 struct prefix nexthop_orig;
826 mpls_label_t *pLabels = NULL;
827 int num_labels = 0;
828
829 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
830
831 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
832 if (debug)
833 zlog_debug("%s: skipping: %s", __func__, debugmsg);
834 return;
835 }
836
837 /* Check for intersection of route targets */
838 if (!ecom_intersect(
839 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
840 info_vpn->attr->ecommunity)) {
841
842 return;
843 }
844
845 if (debug)
846 zlog_debug("%s: updating to vrf %s", __func__, bgp_vrf->name);
847
848 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
849
850 /*
851 * Nexthop: stash and clear
852 *
853 * Nexthop is valid in context of VPN core, but not in destination vrf.
854 * Stash it for later label resolution by vrf ingress path and then
855 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
856 */
857 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
858
859 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
860 nexthop_orig.family = nhfamily;
861
862 switch (nhfamily) {
863
864 case AF_INET:
865 /* save */
866 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
867 nexthop_orig.prefixlen = 32;
868
869 static_attr.nexthop.s_addr = 0; /* self */
870 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
871
872 break;
873
874 case AF_INET6:
875 /* save */
876 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
877 nexthop_orig.prefixlen = 128;
878
879 memset(&static_attr.mp_nexthop_global, 0,
880 sizeof(static_attr.mp_nexthop_global)); /* clear */
881 static_attr.mp_nexthop_len = 16; /* bytes */
882 break;
883 }
884
885
886 /*
887 * route map handling
888 */
889 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
890 struct bgp_info info;
891 route_map_result_t ret;
892
893 memset(&info, 0, sizeof(info));
894 info.peer = bgp_vrf->peer_self;
895 info.attr = &static_attr;
896 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
897 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
898 p, RMAP_BGP, &info);
899 if (RMAP_DENYMATCH == ret) {
900 bgp_attr_flush(&static_attr); /* free any added parts */
901 if (debug)
902 zlog_debug(
903 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
904 __func__, bgp_vrf->name,
905 bgp_vrf->vpn_policy[afi]
906 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
907 ->name);
908 return;
909 }
910 }
911
912 new_attr = bgp_attr_intern(&static_attr);
913 bgp_attr_flush(&static_attr);
914
915 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
916
917 /*
918 * ensure labels are copied
919 */
920 if (info_vpn->extra && info_vpn->extra->num_labels) {
921 num_labels = info_vpn->extra->num_labels;
922 if (num_labels > BGP_MAX_LABELS)
923 num_labels = BGP_MAX_LABELS;
924 pLabels = info_vpn->extra->label;
925 }
926 if (debug) {
927 char buf_prefix[PREFIX_STRLEN];
928 prefix2str(p, buf_prefix, sizeof(buf_prefix));
929 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
930 num_labels);
931 }
932
933 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn, ZEBRA_ROUTE_BGP,
934 BGP_ROUTE_IMPORTED, pLabels, num_labels,
935 info_vpn, /* parent */
936 bgp_vpn, &nexthop_orig, debug);
937 }
938
939 void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
940 struct bgp_info *info_vpn) /* route */
941 {
942 struct listnode *mnode, *mnnode;
943 struct bgp *bgp;
944
945 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
946
947 if (debug)
948 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
949
950 /* Loop over VRFs */
951 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
952
953 if (!info_vpn->extra
954 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
955 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
956 }
957 }
958 }
959
960 void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
961 struct bgp_info *info_vpn) /* route */
962 {
963 struct prefix *p = &info_vpn->net->p;
964 afi_t afi = family2afi(p->family);
965 safi_t safi = SAFI_UNICAST;
966 struct bgp *bgp;
967 struct listnode *mnode, *mnnode;
968 struct bgp_node *bn;
969 struct bgp_info *bi;
970 const char *debugmsg;
971
972 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
973
974 if (debug)
975 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
976
977
978 /* Loop over VRFs */
979 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
980 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
981 if (debug)
982 zlog_debug("%s: skipping: %s", __func__,
983 debugmsg);
984 continue;
985 }
986
987 /* Check for intersection of route targets */
988 if (!ecom_intersect(bgp->vpn_policy[afi]
989 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
990 info_vpn->attr->ecommunity)) {
991
992 continue;
993 }
994
995 if (debug)
996 zlog_debug("%s: withdrawing from vrf %s", __func__,
997 bgp->name);
998
999 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1000 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1001 if (bi->extra
1002 && (struct bgp_info *)bi->extra->parent
1003 == info_vpn) {
1004 break;
1005 }
1006 }
1007
1008 if (bi) {
1009 if (debug)
1010 zlog_debug("%s: deleting bi %p", __func__, bi);
1011 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1012 bgp_info_delete(bn, bi);
1013 bgp_process(bgp, bn, afi, safi);
1014 }
1015 bgp_unlock_node(bn);
1016 }
1017 }
1018
1019 void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1020 afi_t afi)
1021 {
1022 struct bgp_node *bn;
1023 struct bgp_info *bi;
1024 safi_t safi = SAFI_UNICAST;
1025 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1026 struct bgp *bgp_vpn = bgp_get_default();
1027
1028 if (debug)
1029 zlog_debug("%s: entry", __func__);
1030 /*
1031 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1032 */
1033 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1034 bn = bgp_route_next(bn)) {
1035
1036 for (bi = bn->info; bi; bi = bi->next) {
1037 if (bi->extra && bi->extra->bgp_orig == bgp_vpn) {
1038
1039 /* delete route */
1040 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1041 afi, safi);
1042 bgp_info_delete(bn, bi);
1043 bgp_process(bgp_vrf, bn, afi, safi);
1044 }
1045 }
1046 }
1047 }
1048
1049 void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1050 struct bgp *bgp_vpn, /* from */
1051 afi_t afi)
1052 {
1053 struct prefix_rd prd;
1054 struct bgp_node *prn;
1055 safi_t safi = SAFI_MPLS_VPN;
1056
1057 /*
1058 * Walk vpn table
1059 */
1060 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1061 prn = bgp_route_next(prn)) {
1062
1063 struct bgp_table *table;
1064 struct bgp_node *bn;
1065 struct bgp_info *bi;
1066
1067 memset(&prd, 0, sizeof(prd));
1068 prd.family = AF_UNSPEC;
1069 prd.prefixlen = 64;
1070 memcpy(prd.val, prn->p.u.val, 8);
1071
1072 /* This is the per-RD table of prefixes */
1073 table = prn->info;
1074
1075 if (!table)
1076 continue;
1077
1078 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1079
1080 for (bi = bn->info; bi; bi = bi->next) {
1081
1082 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1083 continue;
1084
1085 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1086 bi);
1087 }
1088 }
1089 }
1090 }
1091
1092 static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1093 {
1094 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1095 afi_t afi;
1096 struct route_map *rmap;
1097
1098 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1099 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1100
1101 return;
1102 }
1103
1104 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1105
1106 for (afi = 0; afi < AFI_MAX; ++afi) {
1107
1108 if (vpn_leak_to_vpn_active(bgp, afi, NULL)
1109 && bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1110 && !strcmp(rmap_name,
1111 bgp->vpn_policy[afi]
1112 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1113
1114 if (debug)
1115 zlog_debug(
1116 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1117 __func__, rmap_name, bgp->as,
1118 afi2str(afi));
1119
1120 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1121 bgp_get_default(), bgp);
1122 if (debug)
1123 zlog_debug("%s: after vpn_leak_prechange",
1124 __func__);
1125
1126 if (!rmap)
1127 bgp->vpn_policy[afi]
1128 .rmap[BGP_VPN_POLICY_DIR_TOVPN] = NULL;
1129
1130 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1131 bgp_get_default(), bgp);
1132 if (debug)
1133 zlog_debug("%s: after vpn_leak_postchange",
1134 __func__);
1135 }
1136
1137 char *mapname = bgp->vpn_policy[afi]
1138 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN];
1139
1140 if (vpn_leak_from_vpn_active(bgp, afi, NULL) &&
1141 mapname &&
1142 !strcmp(rmap_name, mapname)) {
1143
1144 if (debug) {
1145 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1146 __func__, rmap_name, bgp->as,
1147 afi2str(afi));
1148 }
1149
1150 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1151 bgp_get_default(), bgp);
1152
1153 if (!rmap) {
1154 bgp->vpn_policy[afi]
1155 .rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1156 NULL;
1157 }
1158
1159 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1160 bgp_get_default(), bgp);
1161 }
1162 }
1163 }
1164
1165 void vpn_policy_routemap_event(const char *rmap_name)
1166 {
1167 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1168 struct listnode *mnode, *mnnode;
1169 struct bgp *bgp;
1170
1171 if (debug)
1172 zlog_debug("%s: entry", __func__);
1173
1174 if (bm->bgp == NULL) /* may be called during cleanup */
1175 return;
1176
1177 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1178 vpn_policy_routemap_update(bgp, rmap_name);
1179 }
1180
1181 /* For testing purpose, static route of MPLS-VPN. */
1182 DEFUN (vpnv4_network,
1183 vpnv4_network_cmd,
1184 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1185 "Specify a network to announce via BGP\n"
1186 "IPv4 prefix\n"
1187 "Specify Route Distinguisher\n"
1188 "VPN Route Distinguisher\n"
1189 "VPN NLRI label (tag)\n"
1190 "VPN NLRI label (tag)\n"
1191 "Label value\n")
1192 {
1193 int idx_ipv4_prefixlen = 1;
1194 int idx_ext_community = 3;
1195 int idx_label = 5;
1196 return bgp_static_set_safi(
1197 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1198 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1199 NULL, NULL, NULL, NULL);
1200 }
1201
1202 DEFUN (vpnv4_network_route_map,
1203 vpnv4_network_route_map_cmd,
1204 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1205 "Specify a network to announce via BGP\n"
1206 "IPv4 prefix\n"
1207 "Specify Route Distinguisher\n"
1208 "VPN Route Distinguisher\n"
1209 "VPN NLRI label (tag)\n"
1210 "VPN NLRI label (tag)\n"
1211 "Label value\n"
1212 "route map\n"
1213 "route map name\n")
1214 {
1215 int idx_ipv4_prefixlen = 1;
1216 int idx_ext_community = 3;
1217 int idx_label = 5;
1218 int idx_word_2 = 7;
1219 return bgp_static_set_safi(
1220 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1221 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1222 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1223 }
1224
1225 /* For testing purpose, static route of MPLS-VPN. */
1226 DEFUN (no_vpnv4_network,
1227 no_vpnv4_network_cmd,
1228 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1229 NO_STR
1230 "Specify a network to announce via BGP\n"
1231 "IPv4 prefix\n"
1232 "Specify Route Distinguisher\n"
1233 "VPN Route Distinguisher\n"
1234 "VPN NLRI label (tag)\n"
1235 "VPN NLRI label (tag)\n"
1236 "Label value\n")
1237 {
1238 int idx_ipv4_prefixlen = 2;
1239 int idx_ext_community = 4;
1240 int idx_label = 6;
1241 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1242 argv[idx_ipv4_prefixlen]->arg,
1243 argv[idx_ext_community]->arg,
1244 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1245 }
1246
1247 DEFUN (vpnv6_network,
1248 vpnv6_network_cmd,
1249 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1250 "Specify a network to announce via BGP\n"
1251 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1252 "Specify Route Distinguisher\n"
1253 "VPN Route Distinguisher\n"
1254 "VPN NLRI label (tag)\n"
1255 "VPN NLRI label (tag)\n"
1256 "Label value\n"
1257 "route map\n"
1258 "route map name\n")
1259 {
1260 int idx_ipv6_prefix = 1;
1261 int idx_ext_community = 3;
1262 int idx_label = 5;
1263 int idx_word_2 = 7;
1264 if (argc == 8)
1265 return bgp_static_set_safi(
1266 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1267 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1268 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1269 else
1270 return bgp_static_set_safi(
1271 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1272 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1273 NULL, 0, NULL, NULL, NULL, NULL);
1274 }
1275
1276 /* For testing purpose, static route of MPLS-VPN. */
1277 DEFUN (no_vpnv6_network,
1278 no_vpnv6_network_cmd,
1279 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1280 NO_STR
1281 "Specify a network to announce via BGP\n"
1282 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1283 "Specify Route Distinguisher\n"
1284 "VPN Route Distinguisher\n"
1285 "VPN NLRI label (tag)\n"
1286 "VPN NLRI label (tag)\n"
1287 "Label value\n")
1288 {
1289 int idx_ipv6_prefix = 2;
1290 int idx_ext_community = 4;
1291 int idx_label = 6;
1292 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1293 argv[idx_ipv6_prefix]->arg,
1294 argv[idx_ext_community]->arg,
1295 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1296 }
1297
1298 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1299 enum bgp_show_type type, void *output_arg, int tags,
1300 u_char use_json)
1301 {
1302 struct bgp *bgp;
1303 struct bgp_table *table;
1304
1305 bgp = bgp_get_default();
1306 if (bgp == NULL) {
1307 if (!use_json)
1308 vty_out(vty, "No BGP process is configured\n");
1309 else
1310 vty_out(vty, "{}\n");
1311 return CMD_WARNING;
1312 }
1313 table = bgp->rib[afi][SAFI_MPLS_VPN];
1314 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1315 output_arg, use_json);
1316 }
1317
1318 DEFUN (show_bgp_ip_vpn_all_rd,
1319 show_bgp_ip_vpn_all_rd_cmd,
1320 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1321 SHOW_STR
1322 BGP_STR
1323 BGP_VPNVX_HELP_STR
1324 "Display VPN NLRI specific information\n"
1325 "Display VPN NLRI specific information\n"
1326 "Display information for a route distinguisher\n"
1327 "VPN Route Distinguisher\n"
1328 JSON_STR)
1329 {
1330 int ret;
1331 struct prefix_rd prd;
1332 afi_t afi;
1333 int idx = 0;
1334
1335 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1336 if (argv_find(argv, argc, "rd", &idx)) {
1337 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
1338 if (!ret) {
1339 vty_out(vty,
1340 "%% Malformed Route Distinguisher\n");
1341 return CMD_WARNING;
1342 }
1343 return bgp_show_mpls_vpn(vty, afi, &prd,
1344 bgp_show_type_normal, NULL, 0,
1345 use_json(argc, argv));
1346 } else {
1347 return bgp_show_mpls_vpn(vty, afi, NULL,
1348 bgp_show_type_normal, NULL, 0,
1349 use_json(argc, argv));
1350 }
1351 }
1352 return CMD_SUCCESS;
1353 }
1354
1355 ALIAS(show_bgp_ip_vpn_all_rd,
1356 show_bgp_ip_vpn_rd_cmd,
1357 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1358 SHOW_STR
1359 BGP_STR
1360 BGP_VPNVX_HELP_STR
1361 "Display VPN NLRI specific information\n"
1362 "Display information for a route distinguisher\n"
1363 "VPN Route Distinguisher\n"
1364 JSON_STR)
1365
1366 #ifdef KEEP_OLD_VPN_COMMANDS
1367 DEFUN (show_ip_bgp_vpn_rd,
1368 show_ip_bgp_vpn_rd_cmd,
1369 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1370 SHOW_STR
1371 IP_STR
1372 BGP_STR
1373 BGP_AFI_HELP_STR
1374 "Address Family modifier\n"
1375 "Display information for a route distinguisher\n"
1376 "VPN Route Distinguisher\n")
1377 {
1378 int idx_ext_community = argc - 1;
1379 int ret;
1380 struct prefix_rd prd;
1381 afi_t afi;
1382 int idx = 0;
1383
1384 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1385 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1386 if (!ret) {
1387 vty_out(vty, "%% Malformed Route Distinguisher\n");
1388 return CMD_WARNING;
1389 }
1390 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1391 NULL, 0, 0);
1392 }
1393 return CMD_SUCCESS;
1394 }
1395
1396 DEFUN (show_ip_bgp_vpn_all,
1397 show_ip_bgp_vpn_all_cmd,
1398 "show [ip] bgp <vpnv4|vpnv6>",
1399 SHOW_STR
1400 IP_STR
1401 BGP_STR
1402 BGP_VPNVX_HELP_STR)
1403 {
1404 afi_t afi;
1405 int idx = 0;
1406
1407 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1408 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1409 NULL, 0, 0);
1410 return CMD_SUCCESS;
1411 }
1412
1413 DEFUN (show_ip_bgp_vpn_all_tags,
1414 show_ip_bgp_vpn_all_tags_cmd,
1415 "show [ip] bgp <vpnv4|vpnv6> all tags",
1416 SHOW_STR
1417 IP_STR
1418 BGP_STR
1419 BGP_VPNVX_HELP_STR
1420 "Display information about all VPNv4/VPNV6 NLRIs\n"
1421 "Display BGP tags for prefixes\n")
1422 {
1423 afi_t afi;
1424 int idx = 0;
1425
1426 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1427 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1428 NULL, 1, 0);
1429 return CMD_SUCCESS;
1430 }
1431
1432 DEFUN (show_ip_bgp_vpn_rd_tags,
1433 show_ip_bgp_vpn_rd_tags_cmd,
1434 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1435 SHOW_STR
1436 IP_STR
1437 BGP_STR
1438 BGP_VPNVX_HELP_STR
1439 "Display information for a route distinguisher\n"
1440 "VPN Route Distinguisher\n"
1441 "Display BGP tags for prefixes\n")
1442 {
1443 int idx_ext_community = 5;
1444 int ret;
1445 struct prefix_rd prd;
1446 afi_t afi;
1447 int idx = 0;
1448
1449 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1450 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1451 if (!ret) {
1452 vty_out(vty, "%% Malformed Route Distinguisher\n");
1453 return CMD_WARNING;
1454 }
1455 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1456 NULL, 1, 0);
1457 }
1458 return CMD_SUCCESS;
1459 }
1460
1461 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1462 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1463 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1464 SHOW_STR
1465 IP_STR
1466 BGP_STR
1467 BGP_VPNVX_HELP_STR
1468 "Display information about all VPNv4/VPNv6 NLRIs\n"
1469 "Detailed information on TCP and BGP neighbor connections\n"
1470 "Neighbor to display information about\n"
1471 "Display routes learned from neighbor\n"
1472 JSON_STR)
1473 {
1474 int idx_ipv4 = 6;
1475 union sockunion su;
1476 struct peer *peer;
1477 int ret;
1478 u_char uj = use_json(argc, argv);
1479 afi_t afi;
1480 int idx = 0;
1481
1482 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1483 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1484 if (ret < 0) {
1485 if (uj) {
1486 json_object *json_no = NULL;
1487 json_no = json_object_new_object();
1488 json_object_string_add(json_no, "warning",
1489 "Malformed address");
1490 vty_out(vty, "%s\n",
1491 json_object_to_json_string(json_no));
1492 json_object_free(json_no);
1493 } else
1494 vty_out(vty, "Malformed address: %s\n",
1495 argv[idx_ipv4]->arg);
1496 return CMD_WARNING;
1497 }
1498
1499 peer = peer_lookup(NULL, &su);
1500 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1501 if (uj) {
1502 json_object *json_no = NULL;
1503 json_no = json_object_new_object();
1504 json_object_string_add(
1505 json_no, "warning",
1506 "No such neighbor or address family");
1507 vty_out(vty, "%s\n",
1508 json_object_to_json_string(json_no));
1509 json_object_free(json_no);
1510 } else
1511 vty_out(vty,
1512 "%% No such neighbor or address family\n");
1513 return CMD_WARNING;
1514 }
1515
1516 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1517 &su, 0, uj);
1518 }
1519 return CMD_SUCCESS;
1520 }
1521
1522 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1523 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
1524 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1525 SHOW_STR
1526 IP_STR
1527 BGP_STR
1528 BGP_VPNVX_HELP_STR
1529 "Display information for a route distinguisher\n"
1530 "VPN Route Distinguisher\n"
1531 "Detailed information on TCP and BGP neighbor connections\n"
1532 "Neighbor to display information about\n"
1533 "Display routes learned from neighbor\n"
1534 JSON_STR)
1535 {
1536 int idx_ext_community = 5;
1537 int idx_ipv4 = 7;
1538 int ret;
1539 union sockunion su;
1540 struct peer *peer;
1541 struct prefix_rd prd;
1542 u_char uj = use_json(argc, argv);
1543 afi_t afi;
1544 int idx = 0;
1545
1546 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1547 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1548 if (!ret) {
1549 if (uj) {
1550 json_object *json_no = NULL;
1551 json_no = json_object_new_object();
1552 json_object_string_add(
1553 json_no, "warning",
1554 "Malformed Route Distinguisher");
1555 vty_out(vty, "%s\n",
1556 json_object_to_json_string(json_no));
1557 json_object_free(json_no);
1558 } else
1559 vty_out(vty,
1560 "%% Malformed Route Distinguisher\n");
1561 return CMD_WARNING;
1562 }
1563
1564 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1565 if (ret < 0) {
1566 if (uj) {
1567 json_object *json_no = NULL;
1568 json_no = json_object_new_object();
1569 json_object_string_add(json_no, "warning",
1570 "Malformed address");
1571 vty_out(vty, "%s\n",
1572 json_object_to_json_string(json_no));
1573 json_object_free(json_no);
1574 } else
1575 vty_out(vty, "Malformed address: %s\n",
1576 argv[idx_ext_community]->arg);
1577 return CMD_WARNING;
1578 }
1579
1580 peer = peer_lookup(NULL, &su);
1581 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1582 if (uj) {
1583 json_object *json_no = NULL;
1584 json_no = json_object_new_object();
1585 json_object_string_add(
1586 json_no, "warning",
1587 "No such neighbor or address family");
1588 vty_out(vty, "%s\n",
1589 json_object_to_json_string(json_no));
1590 json_object_free(json_no);
1591 } else
1592 vty_out(vty,
1593 "%% No such neighbor or address family\n");
1594 return CMD_WARNING;
1595 }
1596
1597 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
1598 &su, 0, uj);
1599 }
1600 return CMD_SUCCESS;
1601 }
1602
1603 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1604 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1605 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1606 SHOW_STR
1607 IP_STR
1608 BGP_STR
1609 BGP_VPNVX_HELP_STR
1610 "Display information about all VPNv4/VPNv6 NLRIs\n"
1611 "Detailed information on TCP and BGP neighbor connections\n"
1612 "Neighbor to display information about\n"
1613 "Display the routes advertised to a BGP neighbor\n"
1614 JSON_STR)
1615 {
1616 int idx_ipv4 = 6;
1617 int ret;
1618 struct peer *peer;
1619 union sockunion su;
1620 u_char uj = use_json(argc, argv);
1621 afi_t afi;
1622 int idx = 0;
1623
1624 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1625 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1626 if (ret < 0) {
1627 if (uj) {
1628 json_object *json_no = NULL;
1629 json_no = json_object_new_object();
1630 json_object_string_add(json_no, "warning",
1631 "Malformed address");
1632 vty_out(vty, "%s\n",
1633 json_object_to_json_string(json_no));
1634 json_object_free(json_no);
1635 } else
1636 vty_out(vty, "Malformed address: %s\n",
1637 argv[idx_ipv4]->arg);
1638 return CMD_WARNING;
1639 }
1640 peer = peer_lookup(NULL, &su);
1641 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1642 if (uj) {
1643 json_object *json_no = NULL;
1644 json_no = json_object_new_object();
1645 json_object_string_add(
1646 json_no, "warning",
1647 "No such neighbor or address family");
1648 vty_out(vty, "%s\n",
1649 json_object_to_json_string(json_no));
1650 json_object_free(json_no);
1651 } else
1652 vty_out(vty,
1653 "%% No such neighbor or address family\n");
1654 return CMD_WARNING;
1655 }
1656 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
1657 SAFI_MPLS_VPN, uj);
1658 }
1659 return CMD_SUCCESS;
1660 }
1661
1662 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1663 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
1664 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
1665 SHOW_STR
1666 IP_STR
1667 BGP_STR
1668 BGP_VPNVX_HELP_STR
1669 "Display information for a route distinguisher\n"
1670 "VPN Route Distinguisher\n"
1671 "Detailed information on TCP and BGP neighbor connections\n"
1672 "Neighbor to display information about\n"
1673 "Display the routes advertised to a BGP neighbor\n"
1674 JSON_STR)
1675 {
1676 int idx_ext_community = 5;
1677 int idx_ipv4 = 7;
1678 int ret;
1679 struct peer *peer;
1680 struct prefix_rd prd;
1681 union sockunion su;
1682 u_char uj = use_json(argc, argv);
1683 afi_t afi;
1684 int idx = 0;
1685
1686 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1687 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1688 if (ret < 0) {
1689 if (uj) {
1690 json_object *json_no = NULL;
1691 json_no = json_object_new_object();
1692 json_object_string_add(json_no, "warning",
1693 "Malformed address");
1694 vty_out(vty, "%s\n",
1695 json_object_to_json_string(json_no));
1696 json_object_free(json_no);
1697 } else
1698 vty_out(vty, "Malformed address: %s\n",
1699 argv[idx_ext_community]->arg);
1700 return CMD_WARNING;
1701 }
1702 peer = peer_lookup(NULL, &su);
1703 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1704 if (uj) {
1705 json_object *json_no = NULL;
1706 json_no = json_object_new_object();
1707 json_object_string_add(
1708 json_no, "warning",
1709 "No such neighbor or address family");
1710 vty_out(vty, "%s\n",
1711 json_object_to_json_string(json_no));
1712 json_object_free(json_no);
1713 } else
1714 vty_out(vty,
1715 "%% No such neighbor or address family\n");
1716 return CMD_WARNING;
1717 }
1718
1719 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1720 if (!ret) {
1721 if (uj) {
1722 json_object *json_no = NULL;
1723 json_no = json_object_new_object();
1724 json_object_string_add(
1725 json_no, "warning",
1726 "Malformed Route Distinguisher");
1727 vty_out(vty, "%s\n",
1728 json_object_to_json_string(json_no));
1729 json_object_free(json_no);
1730 } else
1731 vty_out(vty,
1732 "%% Malformed Route Distinguisher\n");
1733 return CMD_WARNING;
1734 }
1735
1736 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
1737 SAFI_MPLS_VPN, uj);
1738 }
1739 return CMD_SUCCESS;
1740 }
1741 #endif /* KEEP_OLD_VPN_COMMANDS */
1742
1743 void bgp_mplsvpn_init(void)
1744 {
1745 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
1746 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1747 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1748
1749 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
1750 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
1751
1752 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
1753 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
1754 #ifdef KEEP_OLD_VPN_COMMANDS
1755 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
1756 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1757 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1758 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1759 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1760 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1761 install_element(VIEW_NODE,
1762 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1763 install_element(VIEW_NODE,
1764 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
1765 #endif /* KEEP_OLD_VPN_COMMANDS */
1766 }