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