]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Added json formating support to show-...-neighbors-... bgp commands.
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
CommitLineData
718e3744 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"
3f9c7369 28#include "queue.h"
718e3744 29
856ca177 30#include "lib/json.h"
718e3744 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
94f2b392 37static u_int16_t
718e3744 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
94f2b392 58static void
718e3744 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
94f2b392 70static void
718e3744 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
718e3744 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;
718e3744 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;
a82478b9
DS
94 afi_t afi;
95 safi_t safi;
96 u_char addpath_encoded;
97 u_int32_t addpath_id;
718e3744 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;
a82478b9
DS
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));
718e3744 115
116 for (; pnt < lim; pnt += psize)
117 {
118 /* Clear prefix structure. */
119 memset (&p, 0, sizeof (struct prefix));
120
a82478b9
DS
121 if (addpath_encoded)
122 {
cd808e74
DS
123
124 /* When packet overflow occurs return immediately. */
125 if (pnt + BGP_ADDPATH_ID_LEN > lim)
126 return -1;
127
a82478b9
DS
128 addpath_id = ntohl(*((uint32_t*) pnt));
129 pnt += BGP_ADDPATH_ID_LEN;
130 }
131
718e3744 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
718e3744 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)
a82478b9 179 bgp_update (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
94f2b392 180 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
718e3744 181 else
a82478b9 182 bgp_withdraw (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
718e3744 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
fd79ac91 194str2prefix_rd (const char *str, struct prefix_rd *prd)
718e3744 195{
196 int ret;
5228ad27 197 char *p;
198 char *p2;
718e3744 199 struct stream *s;
5228ad27 200 char *half;
718e3744 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
fd79ac91 250str2tag (const char *str, u_char *tag)
718e3744 251{
fd79ac91 252 unsigned long l;
253 char *endptr;
254 u_int32_t t;
718e3744 255
664711c1
UW
256 if (*str == '-')
257 return 0;
fd79ac91 258
664711c1
UW
259 errno = 0;
260 l = strtoul (str, &endptr, 10);
261
262 if (*endptr != '\0' || errno || l > UINT32_MAX)
fd79ac91 263 return 0;
718e3744 264
fd79ac91 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);
718e3744 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);
aea339f7 292 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
718e3744 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
94f2b392 334static int
856ca177 335show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json)
718e3744 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";
856ca177
MS
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;
718e3744 350
351 bgp = bgp_get_default ();
352 if (bgp == NULL)
353 {
856ca177
MS
354 if (!use_json)
355 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
718e3744 356 return CMD_WARNING;
357 }
358
856ca177
MS
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
718e3744 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 {
856ca177
MS
386 if (use_json)
387 json_array = json_object_new_array();
388 else
389 json_array = NULL;
390
718e3744 391 rd_header = 1;
392
393 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
856ca177
MS
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 }
718e3744 470 }
471 }
856ca177
MS
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 }
718e3744 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
94f2b392 497static int
718e3744 498bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
856ca177 499 void *output_arg, int tags, u_char use_json)
718e3744 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";
856ca177
MS
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;
718e3744 516
517 bgp = bgp_get_default ();
518 if (bgp == NULL)
519 {
856ca177
MS
520 if (!use_json)
521 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
718e3744 522 return CMD_WARNING;
523 }
856ca177
MS
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))
718e3744 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))
856ca177
MS
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 }
718e3744 664 }
665 }
856ca177
MS
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 }
718e3744 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{
856ca177 685 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0, 0);
718e3744 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 }
856ca177 707 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0, 0);
718e3744 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{
856ca177 720 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1, 0);
718e3744 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 }
856ca177 743 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1, 0);
718e3744 744}
745
746DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
747 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
856ca177 748 "show ip bgp vpnv4 all neighbors A.B.C.D routes {json}",
718e3744 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"
856ca177
MS
756 "Display routes learned from neighbor\n"
757 "JavaScript Object Notation\n")
718e3744 758{
c63b83fe 759 union sockunion su;
718e3744 760 struct peer *peer;
c63b83fe 761 int ret;
856ca177 762 u_char use_json = (argv[1] != NULL);
c63b83fe
JBD
763
764 ret = str2sockunion (argv[0], &su);
765 if (ret < 0)
718e3744 766 {
856ca177
MS
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);
c63b83fe 777 return CMD_WARNING;
718e3744 778 }
779
c63b83fe 780 peer = peer_lookup (NULL, &su);
718e3744 781 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
782 {
856ca177
MS
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);
718e3744 793 return CMD_WARNING;
794 }
795
856ca177 796 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0, use_json);
718e3744 797}
798
799DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
800 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
856ca177 801 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes {json}",
718e3744 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"
856ca177
MS
810 "Display routes learned from neighbor\n"
811 "JavaScript Object Notation\n")
718e3744 812{
813 int ret;
c63b83fe 814 union sockunion su;
718e3744 815 struct peer *peer;
816 struct prefix_rd prd;
856ca177 817 u_char use_json = (argv[2] != NULL);
718e3744 818
819 ret = str2prefix_rd (argv[0], &prd);
820 if (! ret)
821 {
856ca177
MS
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);
718e3744 832 return CMD_WARNING;
833 }
834
c63b83fe
JBD
835 ret = str2sockunion (argv[1], &su);
836 if (ret < 0)
718e3744 837 {
856ca177
MS
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);
c63b83fe 848 return CMD_WARNING;
718e3744 849 }
850
c63b83fe 851 peer = peer_lookup (NULL, &su);
718e3744 852 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
853 {
856ca177
MS
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);
718e3744 864 return CMD_WARNING;
865 }
866
856ca177 867 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0, use_json);
718e3744 868}
869
870DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
871 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
856ca177 872 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes {json}",
718e3744 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"
856ca177
MS
880 "Display the routes advertised to a BGP neighbor\n"
881 "JavaScript Object Notation\n")
718e3744 882{
883 int ret;
884 struct peer *peer;
885 union sockunion su;
856ca177 886 u_char use_json = (argv[1] != NULL);
718e3744 887
888 ret = str2sockunion (argv[0], &su);
889 if (ret < 0)
890 {
856ca177
MS
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);
718e3744 901 return CMD_WARNING;
902 }
903 peer = peer_lookup (NULL, &su);
904 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
905 {
856ca177
MS
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);
718e3744 916 return CMD_WARNING;
917 }
918
856ca177 919 return show_adj_route_vpn (vty, peer, NULL, use_json);
718e3744 920}
921
922DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
923 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
856ca177 924 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes {json}",
718e3744 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"
856ca177
MS
933 "Display the routes advertised to a BGP neighbor\n"
934 "JavaScript Object Notation\n")
718e3744 935{
936 int ret;
937 struct peer *peer;
938 struct prefix_rd prd;
939 union sockunion su;
856ca177 940 u_char use_json = (argv[2] != NULL);
718e3744 941
942 ret = str2sockunion (argv[1], &su);
943 if (ret < 0)
944 {
856ca177
MS
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);
718e3744 955 return CMD_WARNING;
956 }
957 peer = peer_lookup (NULL, &su);
958 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
959 {
856ca177
MS
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);
718e3744 970 return CMD_WARNING;
971 }
972
973 ret = str2prefix_rd (argv[0], &prd);
974 if (! ret)
975 {
856ca177
MS
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);
718e3744 986 return CMD_WARNING;
987 }
988
856ca177 989 return show_adj_route_vpn (vty, peer, &prd, use_json);
718e3744 990}
991
992void
94f2b392 993bgp_mplsvpn_init (void)
718e3744 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}