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