]> git.proxmox.com Git - mirror_frr.git/blame_incremental - bgpd/bgp_mplsvpn.c
Added json formating support to show-...-neighbors-... bgp commands.
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
... / ...
CommitLineData
1/* MPLS-VPN
2 Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
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
30#include "lib/json.h"
31#include "bgpd/bgpd.h"
32#include "bgpd/bgp_table.h"
33#include "bgpd/bgp_route.h"
34#include "bgpd/bgp_attr.h"
35#include "bgpd/bgp_mplsvpn.h"
36
37static u_int16_t
38decode_rd_type (u_char *pnt)
39{
40 u_int16_t v;
41
42 v = ((u_int16_t) *pnt++ << 8);
43 v |= (u_int16_t) *pnt;
44 return v;
45}
46
47u_int32_t
48decode_label (u_char *pnt)
49{
50 u_int32_t l;
51
52 l = ((u_int32_t) *pnt++ << 12);
53 l |= (u_int32_t) *pnt++ << 4;
54 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
55 return l;
56}
57
58static void
59decode_rd_as (u_char *pnt, struct rd_as *rd_as)
60{
61 rd_as->as = (u_int16_t) *pnt++ << 8;
62 rd_as->as |= (u_int16_t) *pnt++;
63
64 rd_as->val = ((u_int32_t) *pnt++ << 24);
65 rd_as->val |= ((u_int32_t) *pnt++ << 16);
66 rd_as->val |= ((u_int32_t) *pnt++ << 8);
67 rd_as->val |= (u_int32_t) *pnt;
68}
69
70static void
71decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
72{
73 memcpy (&rd_ip->ip, pnt, 4);
74 pnt += 4;
75
76 rd_ip->val = ((u_int16_t) *pnt++ << 8);
77 rd_ip->val |= (u_int16_t) *pnt;
78}
79
80int
81bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
82 struct bgp_nlri *packet)
83{
84 u_char *pnt;
85 u_char *lim;
86 struct prefix p;
87 int psize;
88 int prefixlen;
89 u_int16_t type;
90 struct rd_as rd_as;
91 struct rd_ip rd_ip;
92 struct prefix_rd prd;
93 u_char *tagpnt;
94 afi_t afi;
95 safi_t safi;
96 u_char addpath_encoded;
97 u_int32_t addpath_id;
98
99 /* Check peer status. */
100 if (peer->status != Established)
101 return 0;
102
103 /* Make prefix_rd */
104 prd.family = AF_UNSPEC;
105 prd.prefixlen = 64;
106
107 pnt = packet->nlri;
108 lim = pnt + packet->length;
109 afi = packet->afi;
110 safi = packet->safi;
111 addpath_id = 0;
112
113 addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
114 CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
115
116 for (; pnt < lim; pnt += psize)
117 {
118 /* Clear prefix structure. */
119 memset (&p, 0, sizeof (struct prefix));
120
121 if (addpath_encoded)
122 {
123
124 /* When packet overflow occurs return immediately. */
125 if (pnt + BGP_ADDPATH_ID_LEN > lim)
126 return -1;
127
128 addpath_id = ntohl(*((uint32_t*) pnt));
129 pnt += BGP_ADDPATH_ID_LEN;
130 }
131
132 /* Fetch prefix length. */
133 prefixlen = *pnt++;
134 p.family = AF_INET;
135 psize = PSIZE (prefixlen);
136
137 if (prefixlen < 88)
138 {
139 zlog_err ("prefix length is less than 88: %d", prefixlen);
140 return -1;
141 }
142
143 /* Copyr label to prefix. */
144 tagpnt = pnt;;
145
146 /* Copy routing distinguisher to rd. */
147 memcpy (&prd.val, pnt + 3, 8);
148
149 /* Decode RD type. */
150 type = decode_rd_type (pnt + 3);
151
152 /* Decode RD value. */
153 if (type == RD_TYPE_AS)
154 decode_rd_as (pnt + 5, &rd_as);
155 else if (type == RD_TYPE_IP)
156 decode_rd_ip (pnt + 5, &rd_ip);
157 else
158 {
159 zlog_err ("Invalid RD type %d", type);
160 return -1;
161 }
162
163 p.prefixlen = prefixlen - 88;
164 memcpy (&p.u.prefix, pnt + 11, psize - 11);
165
166#if 0
167 if (type == RD_TYPE_AS)
168 zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
169 inet_ntoa (p.u.prefix4), p.prefixlen);
170 else if (type == RD_TYPE_IP)
171 zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
172 rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
173#endif /* 0 */
174
175 if (pnt + psize > lim)
176 return -1;
177
178 if (attr)
179 bgp_update (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
180 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
181 else
182 bgp_withdraw (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
183 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
184 }
185
186 /* Packet length consistency check. */
187 if (pnt != lim)
188 return -1;
189
190 return 0;
191}
192
193int
194str2prefix_rd (const char *str, struct prefix_rd *prd)
195{
196 int ret;
197 char *p;
198 char *p2;
199 struct stream *s;
200 char *half;
201 struct in_addr addr;
202
203 s = stream_new (8);
204
205 prd->family = AF_UNSPEC;
206 prd->prefixlen = 64;
207
208 p = strchr (str, ':');
209 if (! p)
210 return 0;
211
212 if (! all_digit (p + 1))
213 return 0;
214
215 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
216 memcpy (half, str, (p - str));
217 half[p - str] = '\0';
218
219 p2 = strchr (str, '.');
220
221 if (! p2)
222 {
223 if (! all_digit (half))
224 {
225 XFREE (MTYPE_TMP, half);
226 return 0;
227 }
228 stream_putw (s, RD_TYPE_AS);
229 stream_putw (s, atoi (half));
230 stream_putl (s, atol (p + 1));
231 }
232 else
233 {
234 ret = inet_aton (half, &addr);
235 if (! ret)
236 {
237 XFREE (MTYPE_TMP, half);
238 return 0;
239 }
240 stream_putw (s, RD_TYPE_IP);
241 stream_put_in_addr (s, &addr);
242 stream_putw (s, atol (p + 1));
243 }
244 memcpy (prd->val, s->data, 8);
245
246 return 1;
247}
248
249int
250str2tag (const char *str, u_char *tag)
251{
252 unsigned long l;
253 char *endptr;
254 u_int32_t t;
255
256 if (*str == '-')
257 return 0;
258
259 errno = 0;
260 l = strtoul (str, &endptr, 10);
261
262 if (*endptr != '\0' || errno || l > UINT32_MAX)
263 return 0;
264
265 t = (u_int32_t) l;
266
267 tag[0] = (u_char)(t >> 12);
268 tag[1] = (u_char)(t >> 4);
269 tag[2] = (u_char)(t << 4);
270
271 return 1;
272}
273
274char *
275prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
276{
277 u_char *pnt;
278 u_int16_t type;
279 struct rd_as rd_as;
280 struct rd_ip rd_ip;
281
282 if (size < RD_ADDRSTRLEN)
283 return NULL;
284
285 pnt = prd->val;
286
287 type = decode_rd_type (pnt);
288
289 if (type == RD_TYPE_AS)
290 {
291 decode_rd_as (pnt + 2, &rd_as);
292 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
293 return buf;
294 }
295 else if (type == RD_TYPE_IP)
296 {
297 decode_rd_ip (pnt + 2, &rd_ip);
298 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
299 return buf;
300 }
301
302 return NULL;
303}
304
305/* For testing purpose, static route of MPLS-VPN. */
306DEFUN (vpnv4_network,
307 vpnv4_network_cmd,
308 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
309 "Specify a network to announce via BGP\n"
310 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
311 "Specify Route Distinguisher\n"
312 "VPN Route Distinguisher\n"
313 "BGP tag\n"
314 "tag value\n")
315{
316 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
317}
318
319/* For testing purpose, static route of MPLS-VPN. */
320DEFUN (no_vpnv4_network,
321 no_vpnv4_network_cmd,
322 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
323 NO_STR
324 "Specify a network to announce via BGP\n"
325 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
326 "Specify Route Distinguisher\n"
327 "VPN Route Distinguisher\n"
328 "BGP tag\n"
329 "tag value\n")
330{
331 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
332}
333
334static int
335show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json)
336{
337 struct bgp *bgp;
338 struct bgp_table *table;
339 struct bgp_node *rn;
340 struct bgp_node *rm;
341 struct attr *attr;
342 int rd_header;
343 int header = 1;
344 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
345 json_object *json = NULL;
346 json_object *json_scode = NULL;
347 json_object *json_ocode = NULL;
348 json_object *json_routes = NULL;
349 json_object *json_array = NULL;
350
351 bgp = bgp_get_default ();
352 if (bgp == NULL)
353 {
354 if (!use_json)
355 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
356 return CMD_WARNING;
357 }
358
359 if (use_json)
360 {
361 json_scode = json_object_new_object();
362 json_ocode = json_object_new_object();
363 json_routes = json_object_new_object();
364 json = json_object_new_object();
365
366 json_object_string_add(json_scode, "suppressed", "s");
367 json_object_string_add(json_scode, "damped", "d");
368 json_object_string_add(json_scode, "history", "h");
369 json_object_string_add(json_scode, "valid", "*");
370 json_object_string_add(json_scode, "best", ">");
371 json_object_string_add(json_scode, "internal", "i");
372
373 json_object_string_add(json_ocode, "igp", "i");
374 json_object_string_add(json_ocode, "egp", "e");
375 json_object_string_add(json_ocode, "incomplete", "?");
376 }
377
378 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
379 rn = bgp_route_next (rn))
380 {
381 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
382 continue;
383
384 if ((table = rn->info) != NULL)
385 {
386 if (use_json)
387 json_array = json_object_new_array();
388 else
389 json_array = NULL;
390
391 rd_header = 1;
392
393 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
394 {
395 if ((attr = rm->info) != NULL)
396 {
397 if (header)
398 {
399 if (use_json)
400 {
401 json_object_int_add(json, "bgpTableVersion", 0);
402 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
403 json_object_object_add(json, "bgpStatusCodes", json_scode);
404 json_object_object_add(json, "bgpOriginCodes", json_ocode);
405 }
406 else
407 {
408 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
409 inet_ntoa (bgp->router_id), VTY_NEWLINE);
410 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
411 VTY_NEWLINE);
412 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
413 VTY_NEWLINE, VTY_NEWLINE);
414 vty_out (vty, v4_header, VTY_NEWLINE);
415 }
416 header = 0;
417 }
418
419 if (rd_header)
420 {
421 u_int16_t type;
422 struct rd_as rd_as;
423 struct rd_ip rd_ip;
424 u_char *pnt;
425
426 pnt = rn->p.u.val;
427
428 /* Decode RD type. */
429 type = decode_rd_type (pnt);
430 /* Decode RD value. */
431 if (type == RD_TYPE_AS)
432 decode_rd_as (pnt + 2, &rd_as);
433 else if (type == RD_TYPE_IP)
434 decode_rd_ip (pnt + 2, &rd_ip);
435
436 if (use_json)
437 {
438 char buffer[BUFSIZ];
439 if (type == RD_TYPE_AS)
440 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
441 else if (type == RD_TYPE_IP)
442 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
443 json_object_string_add(json_routes, "routeDistinguisher", buffer);
444 }
445 else
446 {
447 vty_out (vty, "Route Distinguisher: ");
448
449 if (type == RD_TYPE_AS)
450 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
451 else if (type == RD_TYPE_IP)
452 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
453
454 vty_out (vty, "%s", VTY_NEWLINE);
455 }
456 rd_header = 0;
457 }
458 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array);
459 }
460 }
461 if (use_json)
462 {
463 struct prefix *p;
464 char buf_a[BUFSIZ];
465 char buf_b[BUFSIZ];
466 p = &rm->p;
467 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
468 json_object_object_add(json_routes, buf_a, json_array);
469 }
470 }
471 }
472 if (use_json)
473 {
474 json_object_object_add(json, "routes", json_routes);
475 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
476 json_object_free(json);
477 }
478 return CMD_SUCCESS;
479}
480
481enum bgp_show_type
482{
483 bgp_show_type_normal,
484 bgp_show_type_regexp,
485 bgp_show_type_prefix_list,
486 bgp_show_type_filter_list,
487 bgp_show_type_neighbor,
488 bgp_show_type_cidr_only,
489 bgp_show_type_prefix_longer,
490 bgp_show_type_community_all,
491 bgp_show_type_community,
492 bgp_show_type_community_exact,
493 bgp_show_type_community_list,
494 bgp_show_type_community_list_exact
495};
496
497static int
498bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
499 void *output_arg, int tags, u_char use_json)
500{
501 struct bgp *bgp;
502 struct bgp_table *table;
503 struct bgp_node *rn;
504 struct bgp_node *rm;
505 struct bgp_info *ri;
506 int rd_header;
507 int header = 1;
508 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
509 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
510 json_object *json = NULL;
511 json_object *json_mroute = NULL;
512 json_object *json_nroute = NULL;
513 json_object *json_array = NULL;
514 json_object *json_scode = NULL;
515 json_object *json_ocode = NULL;
516
517 bgp = bgp_get_default ();
518 if (bgp == NULL)
519 {
520 if (!use_json)
521 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
522 return CMD_WARNING;
523 }
524
525 if (use_json)
526 {
527 json_scode = json_object_new_object();
528 json_ocode = json_object_new_object();
529 json = json_object_new_object();
530 json_mroute = json_object_new_object();
531 json_nroute = json_object_new_object();
532
533 json_object_string_add(json_scode, "suppressed", "s");
534 json_object_string_add(json_scode, "damped", "d");
535 json_object_string_add(json_scode, "history", "h");
536 json_object_string_add(json_scode, "valid", "*");
537 json_object_string_add(json_scode, "best", ">");
538 json_object_string_add(json_scode, "internal", "i");
539
540 json_object_string_add(json_ocode, "igp", "i");
541 json_object_string_add(json_ocode, "egp", "e");
542 json_object_string_add(json_ocode, "incomplete", "?");
543 }
544
545 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
546 {
547 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
548 continue;
549
550 if ((table = rn->info) != NULL)
551 {
552 rd_header = 1;
553
554 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
555 {
556 if (use_json)
557 json_array = json_object_new_array();
558 else
559 json_array = NULL;
560
561 for (ri = rm->info; ri; ri = ri->next)
562 {
563 if (type == bgp_show_type_neighbor)
564 {
565 union sockunion *su = output_arg;
566
567 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
568 continue;
569 }
570 if (header)
571 {
572 if (use_json)
573 {
574 if (!tags)
575 {
576 json_object_int_add(json, "bgpTableVersion", 0);
577 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
578 json_object_object_add(json, "bgpStatusCodes", json_scode);
579 json_object_object_add(json, "bgpOriginCodes", json_ocode);
580 }
581 }
582 else
583 {
584 if (tags)
585 vty_out (vty, v4_header_tag, VTY_NEWLINE);
586 else
587 {
588 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
589 inet_ntoa (bgp->router_id), VTY_NEWLINE);
590 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
591 VTY_NEWLINE);
592 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
593 VTY_NEWLINE, VTY_NEWLINE);
594 vty_out (vty, v4_header, VTY_NEWLINE);
595 }
596 }
597 header = 0;
598 }
599
600 if (rd_header)
601 {
602 u_int16_t type;
603 struct rd_as rd_as;
604 struct rd_ip rd_ip;
605 u_char *pnt;
606
607 pnt = rn->p.u.val;
608
609 /* Decode RD type. */
610 type = decode_rd_type (pnt);
611 /* Decode RD value. */
612 if (type == RD_TYPE_AS)
613 decode_rd_as (pnt + 2, &rd_as);
614 else if (type == RD_TYPE_IP)
615 decode_rd_ip (pnt + 2, &rd_ip);
616
617 if (use_json)
618 {
619 char buffer[BUFSIZ];
620 if (type == RD_TYPE_AS)
621 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
622 else if (type == RD_TYPE_IP)
623 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
624 json_object_string_add(json_nroute, "routeDistinguisher", buffer);
625 }
626 else
627 {
628 vty_out (vty, "Route Distinguisher: ");
629
630 if (type == RD_TYPE_AS)
631 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
632 else if (type == RD_TYPE_IP)
633 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
634 vty_out (vty, "%s", VTY_NEWLINE);
635 }
636 rd_header = 0;
637 }
638 if (tags)
639 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
640 else
641 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
642 }
643
644 if (use_json)
645 {
646 struct prefix *p;
647 char buf_a[BUFSIZ];
648 char buf_b[BUFSIZ];
649 p = &rm->p;
650 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
651 json_object_object_add(json_mroute, buf_a, json_array);
652 }
653 }
654
655 if (use_json)
656 {
657 struct prefix *p;
658 char buf_a[BUFSIZ];
659 char buf_b[BUFSIZ];
660 p = &rn->p;
661 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
662 json_object_object_add(json_nroute, buf_a, json_mroute);
663 }
664 }
665 }
666
667 if (use_json)
668 {
669 json_object_object_add(json, "routes", json_nroute);
670 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
671 json_object_free(json);
672 }
673 return CMD_SUCCESS;
674}
675
676DEFUN (show_ip_bgp_vpnv4_all,
677 show_ip_bgp_vpnv4_all_cmd,
678 "show ip bgp vpnv4 all",
679 SHOW_STR
680 IP_STR
681 BGP_STR
682 "Display VPNv4 NLRI specific information\n"
683 "Display information about all VPNv4 NLRIs\n")
684{
685 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0, 0);
686}
687
688DEFUN (show_ip_bgp_vpnv4_rd,
689 show_ip_bgp_vpnv4_rd_cmd,
690 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
691 SHOW_STR
692 IP_STR
693 BGP_STR
694 "Display VPNv4 NLRI specific information\n"
695 "Display information for a route distinguisher\n"
696 "VPN Route Distinguisher\n")
697{
698 int ret;
699 struct prefix_rd prd;
700
701 ret = str2prefix_rd (argv[0], &prd);
702 if (! ret)
703 {
704 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
705 return CMD_WARNING;
706 }
707 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0, 0);
708}
709
710DEFUN (show_ip_bgp_vpnv4_all_tags,
711 show_ip_bgp_vpnv4_all_tags_cmd,
712 "show ip bgp vpnv4 all tags",
713 SHOW_STR
714 IP_STR
715 BGP_STR
716 "Display VPNv4 NLRI specific information\n"
717 "Display information about all VPNv4 NLRIs\n"
718 "Display BGP tags for prefixes\n")
719{
720 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1, 0);
721}
722
723DEFUN (show_ip_bgp_vpnv4_rd_tags,
724 show_ip_bgp_vpnv4_rd_tags_cmd,
725 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
726 SHOW_STR
727 IP_STR
728 BGP_STR
729 "Display VPNv4 NLRI specific information\n"
730 "Display information for a route distinguisher\n"
731 "VPN Route Distinguisher\n"
732 "Display BGP tags for prefixes\n")
733{
734 int ret;
735 struct prefix_rd prd;
736
737 ret = str2prefix_rd (argv[0], &prd);
738 if (! ret)
739 {
740 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
741 return CMD_WARNING;
742 }
743 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1, 0);
744}
745
746DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
747 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
748 "show ip bgp vpnv4 all neighbors A.B.C.D routes {json}",
749 SHOW_STR
750 IP_STR
751 BGP_STR
752 "Display VPNv4 NLRI specific information\n"
753 "Display information about all VPNv4 NLRIs\n"
754 "Detailed information on TCP and BGP neighbor connections\n"
755 "Neighbor to display information about\n"
756 "Display routes learned from neighbor\n"
757 "JavaScript Object Notation\n")
758{
759 union sockunion su;
760 struct peer *peer;
761 int ret;
762 u_char use_json = (argv[1] != NULL);
763
764 ret = str2sockunion (argv[0], &su);
765 if (ret < 0)
766 {
767 if (use_json)
768 {
769 json_object *json_no = NULL;
770 json_no = json_object_new_object();
771 json_object_string_add(json_no, "warning", "Malformed address");
772 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
773 json_object_free(json_no);
774 }
775 else
776 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
777 return CMD_WARNING;
778 }
779
780 peer = peer_lookup (NULL, &su);
781 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
782 {
783 if (use_json)
784 {
785 json_object *json_no = NULL;
786 json_no = json_object_new_object();
787 json_object_string_add(json_no, "warning", "No such neighbor or address family");
788 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
789 json_object_free(json_no);
790 }
791 else
792 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
793 return CMD_WARNING;
794 }
795
796 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0, use_json);
797}
798
799DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
800 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
801 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes {json}",
802 SHOW_STR
803 IP_STR
804 BGP_STR
805 "Display VPNv4 NLRI specific information\n"
806 "Display information for a route distinguisher\n"
807 "VPN Route Distinguisher\n"
808 "Detailed information on TCP and BGP neighbor connections\n"
809 "Neighbor to display information about\n"
810 "Display routes learned from neighbor\n"
811 "JavaScript Object Notation\n")
812{
813 int ret;
814 union sockunion su;
815 struct peer *peer;
816 struct prefix_rd prd;
817 u_char use_json = (argv[2] != NULL);
818
819 ret = str2prefix_rd (argv[0], &prd);
820 if (! ret)
821 {
822 if (use_json)
823 {
824 json_object *json_no = NULL;
825 json_no = json_object_new_object();
826 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
827 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
828 json_object_free(json_no);
829 }
830 else
831 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
832 return CMD_WARNING;
833 }
834
835 ret = str2sockunion (argv[1], &su);
836 if (ret < 0)
837 {
838 if (use_json)
839 {
840 json_object *json_no = NULL;
841 json_no = json_object_new_object();
842 json_object_string_add(json_no, "warning", "Malformed address");
843 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
844 json_object_free(json_no);
845 }
846 else
847 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
848 return CMD_WARNING;
849 }
850
851 peer = peer_lookup (NULL, &su);
852 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
853 {
854 if (use_json)
855 {
856 json_object *json_no = NULL;
857 json_no = json_object_new_object();
858 json_object_string_add(json_no, "warning", "No such neighbor or address family");
859 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
860 json_object_free(json_no);
861 }
862 else
863 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
864 return CMD_WARNING;
865 }
866
867 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0, use_json);
868}
869
870DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
871 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
872 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes {json}",
873 SHOW_STR
874 IP_STR
875 BGP_STR
876 "Display VPNv4 NLRI specific information\n"
877 "Display information about all VPNv4 NLRIs\n"
878 "Detailed information on TCP and BGP neighbor connections\n"
879 "Neighbor to display information about\n"
880 "Display the routes advertised to a BGP neighbor\n"
881 "JavaScript Object Notation\n")
882{
883 int ret;
884 struct peer *peer;
885 union sockunion su;
886 u_char use_json = (argv[1] != NULL);
887
888 ret = str2sockunion (argv[0], &su);
889 if (ret < 0)
890 {
891 if (use_json)
892 {
893 json_object *json_no = NULL;
894 json_no = json_object_new_object();
895 json_object_string_add(json_no, "warning", "Malformed address");
896 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
897 json_object_free(json_no);
898 }
899 else
900 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
901 return CMD_WARNING;
902 }
903 peer = peer_lookup (NULL, &su);
904 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
905 {
906 if (use_json)
907 {
908 json_object *json_no = NULL;
909 json_no = json_object_new_object();
910 json_object_string_add(json_no, "warning", "No such neighbor or address family");
911 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
912 json_object_free(json_no);
913 }
914 else
915 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
916 return CMD_WARNING;
917 }
918
919 return show_adj_route_vpn (vty, peer, NULL, use_json);
920}
921
922DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
923 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
924 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes {json}",
925 SHOW_STR
926 IP_STR
927 BGP_STR
928 "Display VPNv4 NLRI specific information\n"
929 "Display information for a route distinguisher\n"
930 "VPN Route Distinguisher\n"
931 "Detailed information on TCP and BGP neighbor connections\n"
932 "Neighbor to display information about\n"
933 "Display the routes advertised to a BGP neighbor\n"
934 "JavaScript Object Notation\n")
935{
936 int ret;
937 struct peer *peer;
938 struct prefix_rd prd;
939 union sockunion su;
940 u_char use_json = (argv[2] != NULL);
941
942 ret = str2sockunion (argv[1], &su);
943 if (ret < 0)
944 {
945 if (use_json)
946 {
947 json_object *json_no = NULL;
948 json_no = json_object_new_object();
949 json_object_string_add(json_no, "warning", "Malformed address");
950 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
951 json_object_free(json_no);
952 }
953 else
954 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
955 return CMD_WARNING;
956 }
957 peer = peer_lookup (NULL, &su);
958 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
959 {
960 if (use_json)
961 {
962 json_object *json_no = NULL;
963 json_no = json_object_new_object();
964 json_object_string_add(json_no, "warning", "No such neighbor or address family");
965 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
966 json_object_free(json_no);
967 }
968 else
969 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
970 return CMD_WARNING;
971 }
972
973 ret = str2prefix_rd (argv[0], &prd);
974 if (! ret)
975 {
976 if (use_json)
977 {
978 json_object *json_no = NULL;
979 json_no = json_object_new_object();
980 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
981 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
982 json_object_free(json_no);
983 }
984 else
985 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
986 return CMD_WARNING;
987 }
988
989 return show_adj_route_vpn (vty, peer, &prd, use_json);
990}
991
992void
993bgp_mplsvpn_init (void)
994{
995 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
996 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
997
998
999 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
1000 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
1001 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
1002 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
1003 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
1004 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
1005 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
1006 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
1007
1008 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
1009 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
1010 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
1011 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
1012 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
1013 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
1014 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
1015 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
1016}