]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #1664 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 "lib/json.h"
31
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_table.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_label.h"
37 #include "bgpd/bgp_mplsvpn.h"
38 #include "bgpd/bgp_packet.h"
39 #include "bgpd/bgp_vty.h"
40 #include "bgpd/bgp_vpn.h"
41
42 #if ENABLE_BGP_VNC
43 #include "bgpd/rfapi/rfapi_backend.h"
44 #endif
45
46 extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
47 int *index, afi_t *afi)
48 {
49 int ret = 0;
50 if (argv_find(argv, argc, "vpnv4", index)) {
51 ret = 1;
52 if (afi)
53 *afi = AFI_IP;
54 } else if (argv_find(argv, argc, "vpnv6", index)) {
55 ret = 1;
56 if (afi)
57 *afi = AFI_IP6;
58 }
59 return ret;
60 }
61
62 u_int32_t decode_label(mpls_label_t *label_pnt)
63 {
64 u_int32_t l;
65 u_char *pnt = (u_char *)label_pnt;
66
67 l = ((u_int32_t)*pnt++ << 12);
68 l |= (u_int32_t)*pnt++ << 4;
69 l |= (u_int32_t)((*pnt & 0xf0) >> 4);
70 return l;
71 }
72
73 void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
74 {
75 u_char *pnt = (u_char *)label_pnt;
76 if (pnt == NULL)
77 return;
78 *pnt++ = (label >> 12) & 0xff;
79 *pnt++ = (label >> 4) & 0xff;
80 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
81 }
82
83 int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
84 struct bgp_nlri *packet)
85 {
86 u_char *pnt;
87 u_char *lim;
88 struct prefix p;
89 int psize = 0;
90 int prefixlen;
91 u_int16_t type;
92 struct rd_as rd_as;
93 struct rd_ip rd_ip;
94 struct prefix_rd prd;
95 mpls_label_t label;
96 afi_t afi;
97 safi_t safi;
98 int addpath_encoded;
99 u_int32_t addpath_id;
100
101 /* Check peer status. */
102 if (peer->status != Established)
103 return 0;
104
105 /* Make prefix_rd */
106 prd.family = AF_UNSPEC;
107 prd.prefixlen = 64;
108
109 pnt = packet->nlri;
110 lim = pnt + packet->length;
111 afi = packet->afi;
112 safi = packet->safi;
113 addpath_id = 0;
114
115 addpath_encoded =
116 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
117 && CHECK_FLAG(peer->af_cap[afi][safi],
118 PEER_CAP_ADDPATH_AF_TX_RCV));
119
120 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
121 for (; pnt < lim; pnt += psize) {
122 /* Clear prefix structure. */
123 memset(&p, 0, sizeof(struct prefix));
124
125 if (addpath_encoded) {
126
127 /* When packet overflow occurs return immediately. */
128 if (pnt + BGP_ADDPATH_ID_LEN > lim)
129 return -1;
130
131 addpath_id = ntohl(*((uint32_t *)pnt));
132 pnt += BGP_ADDPATH_ID_LEN;
133 }
134
135 /* Fetch prefix length. */
136 prefixlen = *pnt++;
137 p.family = afi2family(packet->afi);
138 psize = PSIZE(prefixlen);
139
140 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
141 zlog_err(
142 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
143 peer->host, prefixlen);
144 return -1;
145 }
146
147 /* sanity check against packet data */
148 if ((pnt + psize) > lim) {
149 zlog_err(
150 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
151 peer->host, prefixlen, (uint)(lim - pnt));
152 return -1;
153 }
154
155 /* sanity check against storage for the IP address portion */
156 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
157 zlog_err(
158 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
159 peer->host,
160 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
161 sizeof(p.u));
162 return -1;
163 }
164
165 /* Sanity check against max bitlen of the address family */
166 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
167 zlog_err(
168 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
169 peer->host,
170 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
171 p.family, prefix_blen(&p));
172 return -1;
173 }
174
175 /* Copy label to prefix. */
176 memcpy(&label, pnt, BGP_LABEL_BYTES);
177 bgp_set_valid_label(&label);
178
179 /* Copy routing distinguisher to rd. */
180 memcpy(&prd.val, pnt + BGP_LABEL_BYTES, 8);
181
182 /* Decode RD type. */
183 type = decode_rd_type(pnt + BGP_LABEL_BYTES);
184
185 switch (type) {
186 case RD_TYPE_AS:
187 decode_rd_as(pnt + 5, &rd_as);
188 break;
189
190 case RD_TYPE_AS4:
191 decode_rd_as4(pnt + 5, &rd_as);
192 break;
193
194 case RD_TYPE_IP:
195 decode_rd_ip(pnt + 5, &rd_ip);
196 break;
197
198 #if ENABLE_BGP_VNC
199 case RD_TYPE_VNC_ETH:
200 break;
201 #endif
202
203 default:
204 zlog_err("Unknown RD type %d", type);
205 break; /* just report */
206 }
207
208 p.prefixlen =
209 prefixlen
210 - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
211 memcpy(&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
212 psize - VPN_PREFIXLEN_MIN_BYTES);
213
214 if (attr) {
215 bgp_update(peer, &p, addpath_id, attr, packet->afi,
216 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
217 BGP_ROUTE_NORMAL, &prd, &label, 0, NULL);
218 } else {
219 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
220 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
221 BGP_ROUTE_NORMAL, &prd, &label, NULL);
222 }
223 }
224 /* Packet length consistency check. */
225 if (pnt != lim) {
226 zlog_err(
227 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
228 peer->host, lim - pnt);
229 return -1;
230 }
231
232 return 0;
233 #undef VPN_PREFIXLEN_MIN_BYTES
234 }
235
236 /* For testing purpose, static route of MPLS-VPN. */
237 DEFUN (vpnv4_network,
238 vpnv4_network_cmd,
239 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
240 "Specify a network to announce via BGP\n"
241 "IPv4 prefix\n"
242 "Specify Route Distinguisher\n"
243 "VPN Route Distinguisher\n"
244 "VPN NLRI label (tag)\n"
245 "VPN NLRI label (tag)\n"
246 "Label value\n")
247 {
248 int idx_ipv4_prefixlen = 1;
249 int idx_ext_community = 3;
250 int idx_label = 5;
251 return bgp_static_set_safi(
252 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
253 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
254 NULL, NULL, NULL, NULL);
255 }
256
257 DEFUN (vpnv4_network_route_map,
258 vpnv4_network_route_map_cmd,
259 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
260 "Specify a network to announce via BGP\n"
261 "IPv4 prefix\n"
262 "Specify Route Distinguisher\n"
263 "VPN Route Distinguisher\n"
264 "VPN NLRI label (tag)\n"
265 "VPN NLRI label (tag)\n"
266 "Label value\n"
267 "route map\n"
268 "route map name\n")
269 {
270 int idx_ipv4_prefixlen = 1;
271 int idx_ext_community = 3;
272 int idx_label = 5;
273 int idx_word_2 = 7;
274 return bgp_static_set_safi(
275 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
276 argv[idx_ext_community]->arg, argv[idx_label]->arg,
277 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
278 }
279
280 /* For testing purpose, static route of MPLS-VPN. */
281 DEFUN (no_vpnv4_network,
282 no_vpnv4_network_cmd,
283 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
284 NO_STR
285 "Specify a network to announce via BGP\n"
286 "IPv4 prefix\n"
287 "Specify Route Distinguisher\n"
288 "VPN Route Distinguisher\n"
289 "VPN NLRI label (tag)\n"
290 "VPN NLRI label (tag)\n"
291 "Label value\n")
292 {
293 int idx_ipv4_prefixlen = 2;
294 int idx_ext_community = 4;
295 int idx_label = 6;
296 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
297 argv[idx_ipv4_prefixlen]->arg,
298 argv[idx_ext_community]->arg,
299 argv[idx_label]->arg, 0, NULL, NULL, NULL);
300 }
301
302 DEFUN (vpnv6_network,
303 vpnv6_network_cmd,
304 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
305 "Specify a network to announce via BGP\n"
306 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
307 "Specify Route Distinguisher\n"
308 "VPN Route Distinguisher\n"
309 "VPN NLRI label (tag)\n"
310 "VPN NLRI label (tag)\n"
311 "Label value\n"
312 "route map\n"
313 "route map name\n")
314 {
315 int idx_ipv6_prefix = 1;
316 int idx_ext_community = 3;
317 int idx_label = 5;
318 int idx_word_2 = 7;
319 if (argc == 8)
320 return bgp_static_set_safi(
321 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
322 argv[idx_ext_community]->arg, argv[idx_label]->arg,
323 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
324 else
325 return bgp_static_set_safi(
326 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
327 argv[idx_ext_community]->arg, argv[idx_label]->arg,
328 NULL, 0, NULL, NULL, NULL, NULL);
329 }
330
331 /* For testing purpose, static route of MPLS-VPN. */
332 DEFUN (no_vpnv6_network,
333 no_vpnv6_network_cmd,
334 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
335 NO_STR
336 "Specify a network to announce via BGP\n"
337 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
338 "Specify Route Distinguisher\n"
339 "VPN Route Distinguisher\n"
340 "VPN NLRI label (tag)\n"
341 "VPN NLRI label (tag)\n"
342 "Label value\n")
343 {
344 int idx_ipv6_prefix = 2;
345 int idx_ext_community = 4;
346 int idx_label = 6;
347 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
348 argv[idx_ipv6_prefix]->arg,
349 argv[idx_ext_community]->arg,
350 argv[idx_label]->arg, 0, NULL, NULL, NULL);
351 }
352
353 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
354 enum bgp_show_type type, void *output_arg, int tags,
355 u_char use_json)
356 {
357 struct bgp *bgp;
358 struct bgp_table *table;
359
360 bgp = bgp_get_default();
361 if (bgp == NULL) {
362 if (!use_json)
363 vty_out(vty, "No BGP process is configured\n");
364 else
365 vty_out(vty, "{}\n");
366 return CMD_WARNING;
367 }
368 table = bgp->rib[afi][SAFI_MPLS_VPN];
369 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN,
370 table, prd, type, output_arg, use_json);
371 }
372
373 DEFUN (show_bgp_ip_vpn_all_rd,
374 show_bgp_ip_vpn_all_rd_cmd,
375 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
376 SHOW_STR
377 BGP_STR
378 BGP_VPNVX_HELP_STR
379 "Display VPN NLRI specific information\n"
380 "Display VPN NLRI specific information\n"
381 "Display information for a route distinguisher\n"
382 "VPN Route Distinguisher\n"
383 JSON_STR)
384 {
385 int ret;
386 struct prefix_rd prd;
387 afi_t afi;
388 int idx = 0;
389
390 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
391 if (argv_find(argv, argc, "rd", &idx)) {
392 ret = str2prefix_rd(argv[idx+1]->arg, &prd);
393 if (!ret) {
394 vty_out(vty,
395 "%% Malformed Route Distinguisher\n");
396 return CMD_WARNING;
397 }
398 return bgp_show_mpls_vpn(vty, afi, &prd,
399 bgp_show_type_normal, NULL, 0,
400 use_json(argc, argv));
401 } else {
402 return bgp_show_mpls_vpn(vty, afi, NULL,
403 bgp_show_type_normal, NULL, 0,
404 use_json(argc, argv));
405 }
406 }
407 return CMD_SUCCESS;
408 }
409
410 ALIAS(show_bgp_ip_vpn_all_rd,
411 show_bgp_ip_vpn_rd_cmd,
412 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
413 SHOW_STR
414 BGP_STR
415 BGP_VPNVX_HELP_STR
416 "Display VPN NLRI specific information\n"
417 "Display information for a route distinguisher\n"
418 "VPN Route Distinguisher\n"
419 JSON_STR)
420
421 #ifdef KEEP_OLD_VPN_COMMANDS
422 DEFUN (show_ip_bgp_vpn_rd,
423 show_ip_bgp_vpn_rd_cmd,
424 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
425 SHOW_STR
426 IP_STR
427 BGP_STR
428 BGP_AFI_HELP_STR
429 "Address Family modifier\n"
430 "Display information for a route distinguisher\n"
431 "VPN Route Distinguisher\n")
432 {
433 int idx_ext_community = argc - 1;
434 int ret;
435 struct prefix_rd prd;
436 afi_t afi;
437 int idx = 0;
438
439 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
440 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
441 if (!ret) {
442 vty_out(vty, "%% Malformed Route Distinguisher\n");
443 return CMD_WARNING;
444 }
445 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
446 NULL, 0, 0);
447 }
448 return CMD_SUCCESS;
449 }
450
451 DEFUN (show_ip_bgp_vpn_all,
452 show_ip_bgp_vpn_all_cmd,
453 "show [ip] bgp <vpnv4|vpnv6>",
454 SHOW_STR
455 IP_STR
456 BGP_STR
457 BGP_VPNVX_HELP_STR)
458 {
459 afi_t afi;
460 int idx = 0;
461
462 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
463 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
464 NULL, 0, 0);
465 return CMD_SUCCESS;
466 }
467
468 DEFUN (show_ip_bgp_vpn_all_tags,
469 show_ip_bgp_vpn_all_tags_cmd,
470 "show [ip] bgp <vpnv4|vpnv6> all tags",
471 SHOW_STR
472 IP_STR
473 BGP_STR
474 BGP_VPNVX_HELP_STR
475 "Display information about all VPNv4/VPNV6 NLRIs\n"
476 "Display BGP tags for prefixes\n")
477 {
478 afi_t afi;
479 int idx = 0;
480
481 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
482 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
483 NULL, 1, 0);
484 return CMD_SUCCESS;
485 }
486
487 DEFUN (show_ip_bgp_vpn_rd_tags,
488 show_ip_bgp_vpn_rd_tags_cmd,
489 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
490 SHOW_STR
491 IP_STR
492 BGP_STR
493 BGP_VPNVX_HELP_STR
494 "Display information for a route distinguisher\n"
495 "VPN Route Distinguisher\n"
496 "Display BGP tags for prefixes\n")
497 {
498 int idx_ext_community = 5;
499 int ret;
500 struct prefix_rd prd;
501 afi_t afi;
502 int idx = 0;
503
504 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
505 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
506 if (!ret) {
507 vty_out(vty, "%% Malformed Route Distinguisher\n");
508 return CMD_WARNING;
509 }
510 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
511 NULL, 1, 0);
512 }
513 return CMD_SUCCESS;
514 }
515
516 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
517 show_ip_bgp_vpn_all_neighbor_routes_cmd,
518 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
519 SHOW_STR
520 IP_STR
521 BGP_STR
522 BGP_VPNVX_HELP_STR
523 "Display information about all VPNv4/VPNv6 NLRIs\n"
524 "Detailed information on TCP and BGP neighbor connections\n"
525 "Neighbor to display information about\n"
526 "Display routes learned from neighbor\n"
527 JSON_STR)
528 {
529 int idx_ipv4 = 6;
530 union sockunion su;
531 struct peer *peer;
532 int ret;
533 u_char uj = use_json(argc, argv);
534 afi_t afi;
535 int idx = 0;
536
537 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
538 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
539 if (ret < 0) {
540 if (uj) {
541 json_object *json_no = NULL;
542 json_no = json_object_new_object();
543 json_object_string_add(json_no, "warning",
544 "Malformed address");
545 vty_out(vty, "%s\n",
546 json_object_to_json_string(json_no));
547 json_object_free(json_no);
548 } else
549 vty_out(vty, "Malformed address: %s\n",
550 argv[idx_ipv4]->arg);
551 return CMD_WARNING;
552 }
553
554 peer = peer_lookup(NULL, &su);
555 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
556 if (uj) {
557 json_object *json_no = NULL;
558 json_no = json_object_new_object();
559 json_object_string_add(
560 json_no, "warning",
561 "No such neighbor or address family");
562 vty_out(vty, "%s\n",
563 json_object_to_json_string(json_no));
564 json_object_free(json_no);
565 } else
566 vty_out(vty,
567 "%% No such neighbor or address family\n");
568 return CMD_WARNING;
569 }
570
571 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
572 &su, 0, uj);
573 }
574 return CMD_SUCCESS;
575 }
576
577 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
578 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
579 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
580 SHOW_STR
581 IP_STR
582 BGP_STR
583 BGP_VPNVX_HELP_STR
584 "Display information for a route distinguisher\n"
585 "VPN Route Distinguisher\n"
586 "Detailed information on TCP and BGP neighbor connections\n"
587 "Neighbor to display information about\n"
588 "Display routes learned from neighbor\n"
589 JSON_STR)
590 {
591 int idx_ext_community = 5;
592 int idx_ipv4 = 7;
593 int ret;
594 union sockunion su;
595 struct peer *peer;
596 struct prefix_rd prd;
597 u_char uj = use_json(argc, argv);
598 afi_t afi;
599 int idx = 0;
600
601 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
602 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
603 if (!ret) {
604 if (uj) {
605 json_object *json_no = NULL;
606 json_no = json_object_new_object();
607 json_object_string_add(
608 json_no, "warning",
609 "Malformed Route Distinguisher");
610 vty_out(vty, "%s\n",
611 json_object_to_json_string(json_no));
612 json_object_free(json_no);
613 } else
614 vty_out(vty,
615 "%% Malformed Route Distinguisher\n");
616 return CMD_WARNING;
617 }
618
619 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
620 if (ret < 0) {
621 if (uj) {
622 json_object *json_no = NULL;
623 json_no = json_object_new_object();
624 json_object_string_add(json_no, "warning",
625 "Malformed address");
626 vty_out(vty, "%s\n",
627 json_object_to_json_string(json_no));
628 json_object_free(json_no);
629 } else
630 vty_out(vty, "Malformed address: %s\n",
631 argv[idx_ext_community]->arg);
632 return CMD_WARNING;
633 }
634
635 peer = peer_lookup(NULL, &su);
636 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
637 if (uj) {
638 json_object *json_no = NULL;
639 json_no = json_object_new_object();
640 json_object_string_add(
641 json_no, "warning",
642 "No such neighbor or address family");
643 vty_out(vty, "%s\n",
644 json_object_to_json_string(json_no));
645 json_object_free(json_no);
646 } else
647 vty_out(vty,
648 "%% No such neighbor or address family\n");
649 return CMD_WARNING;
650 }
651
652 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
653 &su, 0, uj);
654 }
655 return CMD_SUCCESS;
656 }
657
658 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
659 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
660 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
661 SHOW_STR
662 IP_STR
663 BGP_STR
664 BGP_VPNVX_HELP_STR
665 "Display information about all VPNv4/VPNv6 NLRIs\n"
666 "Detailed information on TCP and BGP neighbor connections\n"
667 "Neighbor to display information about\n"
668 "Display the routes advertised to a BGP neighbor\n"
669 JSON_STR)
670 {
671 int idx_ipv4 = 6;
672 int ret;
673 struct peer *peer;
674 union sockunion su;
675 u_char uj = use_json(argc, argv);
676 afi_t afi;
677 int idx = 0;
678
679 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
680 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
681 if (ret < 0) {
682 if (uj) {
683 json_object *json_no = NULL;
684 json_no = json_object_new_object();
685 json_object_string_add(json_no, "warning",
686 "Malformed address");
687 vty_out(vty, "%s\n",
688 json_object_to_json_string(json_no));
689 json_object_free(json_no);
690 } else
691 vty_out(vty, "Malformed address: %s\n",
692 argv[idx_ipv4]->arg);
693 return CMD_WARNING;
694 }
695 peer = peer_lookup(NULL, &su);
696 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
697 if (uj) {
698 json_object *json_no = NULL;
699 json_no = json_object_new_object();
700 json_object_string_add(
701 json_no, "warning",
702 "No such neighbor or address family");
703 vty_out(vty, "%s\n",
704 json_object_to_json_string(json_no));
705 json_object_free(json_no);
706 } else
707 vty_out(vty,
708 "%% No such neighbor or address family\n");
709 return CMD_WARNING;
710 }
711 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
712 SAFI_MPLS_VPN, uj);
713 }
714 return CMD_SUCCESS;
715 }
716
717 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
718 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
719 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
720 SHOW_STR
721 IP_STR
722 BGP_STR
723 BGP_VPNVX_HELP_STR
724 "Display information for a route distinguisher\n"
725 "VPN Route Distinguisher\n"
726 "Detailed information on TCP and BGP neighbor connections\n"
727 "Neighbor to display information about\n"
728 "Display the routes advertised to a BGP neighbor\n"
729 JSON_STR)
730 {
731 int idx_ext_community = 5;
732 int idx_ipv4 = 7;
733 int ret;
734 struct peer *peer;
735 struct prefix_rd prd;
736 union sockunion su;
737 u_char uj = use_json(argc, argv);
738 afi_t afi;
739 int idx = 0;
740
741 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
742 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
743 if (ret < 0) {
744 if (uj) {
745 json_object *json_no = NULL;
746 json_no = json_object_new_object();
747 json_object_string_add(json_no, "warning",
748 "Malformed address");
749 vty_out(vty, "%s\n",
750 json_object_to_json_string(json_no));
751 json_object_free(json_no);
752 } else
753 vty_out(vty, "Malformed address: %s\n",
754 argv[idx_ext_community]->arg);
755 return CMD_WARNING;
756 }
757 peer = peer_lookup(NULL, &su);
758 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
759 if (uj) {
760 json_object *json_no = NULL;
761 json_no = json_object_new_object();
762 json_object_string_add(
763 json_no, "warning",
764 "No such neighbor or address family");
765 vty_out(vty, "%s\n",
766 json_object_to_json_string(json_no));
767 json_object_free(json_no);
768 } else
769 vty_out(vty,
770 "%% No such neighbor or address family\n");
771 return CMD_WARNING;
772 }
773
774 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
775 if (!ret) {
776 if (uj) {
777 json_object *json_no = NULL;
778 json_no = json_object_new_object();
779 json_object_string_add(
780 json_no, "warning",
781 "Malformed Route Distinguisher");
782 vty_out(vty, "%s\n",
783 json_object_to_json_string(json_no));
784 json_object_free(json_no);
785 } else
786 vty_out(vty,
787 "%% Malformed Route Distinguisher\n");
788 return CMD_WARNING;
789 }
790
791 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
792 SAFI_MPLS_VPN, uj);
793 }
794 return CMD_SUCCESS;
795 }
796 #endif /* KEEP_OLD_VPN_COMMANDS */
797
798 void bgp_mplsvpn_init(void)
799 {
800 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
801 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
802 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
803
804 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
805 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
806
807 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
808 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
809 #ifdef KEEP_OLD_VPN_COMMANDS
810 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
811 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
812 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
813 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
814 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
815 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
816 install_element(VIEW_NODE,
817 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
818 install_element(VIEW_NODE,
819 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
820 #endif /* KEEP_OLD_VPN_COMMANDS */
821 }