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