blob: a72d5edeb125156820a62721fbba4c631ba232c1 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* MPLS-VPN
2 Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "prefix.h"
25#include "log.h"
26#include "memory.h"
27#include "stream.h"
28
29#include "bgpd/bgpd.h"
30#include "bgpd/bgp_table.h"
31#include "bgpd/bgp_route.h"
32#include "bgpd/bgp_attr.h"
33#include "bgpd/bgp_mplsvpn.h"
34
paul94f2b392005-06-28 12:44:16 +000035static u_int16_t
paul718e3742002-12-13 20:15:29 +000036decode_rd_type (u_char *pnt)
37{
38 u_int16_t v;
39
40 v = ((u_int16_t) *pnt++ << 8);
41 v |= (u_int16_t) *pnt;
42 return v;
43}
44
45u_int32_t
46decode_label (u_char *pnt)
47{
48 u_int32_t l;
49
50 l = ((u_int32_t) *pnt++ << 12);
51 l |= (u_int32_t) *pnt++ << 4;
52 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
53 return l;
54}
55
paul94f2b392005-06-28 12:44:16 +000056static void
paul718e3742002-12-13 20:15:29 +000057decode_rd_as (u_char *pnt, struct rd_as *rd_as)
58{
59 rd_as->as = (u_int16_t) *pnt++ << 8;
60 rd_as->as |= (u_int16_t) *pnt++;
61
62 rd_as->val = ((u_int32_t) *pnt++ << 24);
63 rd_as->val |= ((u_int32_t) *pnt++ << 16);
64 rd_as->val |= ((u_int32_t) *pnt++ << 8);
65 rd_as->val |= (u_int32_t) *pnt;
66}
67
paul94f2b392005-06-28 12:44:16 +000068static void
paul718e3742002-12-13 20:15:29 +000069decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
70{
71 memcpy (&rd_ip->ip, pnt, 4);
72 pnt += 4;
73
74 rd_ip->val = ((u_int16_t) *pnt++ << 8);
75 rd_ip->val |= (u_int16_t) *pnt;
76}
77
paul718e3742002-12-13 20:15:29 +000078int
79bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
80 struct bgp_nlri *packet)
81{
82 u_char *pnt;
83 u_char *lim;
84 struct prefix p;
85 int psize;
86 int prefixlen;
paul718e3742002-12-13 20:15:29 +000087 u_int16_t type;
88 struct rd_as rd_as;
89 struct rd_ip rd_ip;
90 struct prefix_rd prd;
91 u_char *tagpnt;
92
93 /* Check peer status. */
94 if (peer->status != Established)
95 return 0;
96
97 /* Make prefix_rd */
98 prd.family = AF_UNSPEC;
99 prd.prefixlen = 64;
100
101 pnt = packet->nlri;
102 lim = pnt + packet->length;
103
104 for (; pnt < lim; pnt += psize)
105 {
106 /* Clear prefix structure. */
107 memset (&p, 0, sizeof (struct prefix));
108
109 /* Fetch prefix length. */
110 prefixlen = *pnt++;
111 p.family = AF_INET;
112 psize = PSIZE (prefixlen);
113
114 if (prefixlen < 88)
115 {
116 zlog_err ("prefix length is less than 88: %d", prefixlen);
117 return -1;
118 }
paul718e3742002-12-13 20:15:29 +0000119
120 /* Copyr label to prefix. */
121 tagpnt = pnt;;
122
123 /* Copy routing distinguisher to rd. */
124 memcpy (&prd.val, pnt + 3, 8);
125
126 /* Decode RD type. */
127 type = decode_rd_type (pnt + 3);
128
129 /* Decode RD value. */
130 if (type == RD_TYPE_AS)
131 decode_rd_as (pnt + 5, &rd_as);
132 else if (type == RD_TYPE_IP)
133 decode_rd_ip (pnt + 5, &rd_ip);
134 else
135 {
136 zlog_err ("Invalid RD type %d", type);
137 return -1;
138 }
139
140 p.prefixlen = prefixlen - 88;
141 memcpy (&p.u.prefix, pnt + 11, psize - 11);
142
143#if 0
144 if (type == RD_TYPE_AS)
145 zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
146 inet_ntoa (p.u.prefix4), p.prefixlen);
147 else if (type == RD_TYPE_IP)
148 zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
149 rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
150#endif /* 0 */
151
152 if (pnt + psize > lim)
153 return -1;
154
155 if (attr)
156 bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
paul94f2b392005-06-28 12:44:16 +0000157 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000158 else
159 bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
160 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
161 }
162
163 /* Packet length consistency check. */
164 if (pnt != lim)
165 return -1;
166
167 return 0;
168}
169
170int
paulfd79ac92004-10-13 05:06:08 +0000171str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000172{
Lou Berger056f3762013-04-10 12:30:04 -0700173 int ret; /* ret of called functions */
174 int lret; /* local ret, of this func */
paul5228ad22004-06-04 17:58:18 +0000175 char *p;
176 char *p2;
Lou Berger056f3762013-04-10 12:30:04 -0700177 struct stream *s = NULL;
178 char *half = NULL;
paul718e3742002-12-13 20:15:29 +0000179 struct in_addr addr;
180
181 s = stream_new (8);
182
183 prd->family = AF_UNSPEC;
184 prd->prefixlen = 64;
185
Lou Berger056f3762013-04-10 12:30:04 -0700186 lret = 0;
paul718e3742002-12-13 20:15:29 +0000187 p = strchr (str, ':');
188 if (! p)
Lou Berger056f3762013-04-10 12:30:04 -0700189 goto out;
paul718e3742002-12-13 20:15:29 +0000190
191 if (! all_digit (p + 1))
Lou Berger056f3762013-04-10 12:30:04 -0700192 goto out;
paul718e3742002-12-13 20:15:29 +0000193
194 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
195 memcpy (half, str, (p - str));
196 half[p - str] = '\0';
197
198 p2 = strchr (str, '.');
199
200 if (! p2)
201 {
202 if (! all_digit (half))
Lou Berger056f3762013-04-10 12:30:04 -0700203 goto out;
204
paul718e3742002-12-13 20:15:29 +0000205 stream_putw (s, RD_TYPE_AS);
206 stream_putw (s, atoi (half));
207 stream_putl (s, atol (p + 1));
208 }
209 else
210 {
211 ret = inet_aton (half, &addr);
212 if (! ret)
Lou Berger056f3762013-04-10 12:30:04 -0700213 goto out;
214
paul718e3742002-12-13 20:15:29 +0000215 stream_putw (s, RD_TYPE_IP);
216 stream_put_in_addr (s, &addr);
217 stream_putw (s, atol (p + 1));
218 }
219 memcpy (prd->val, s->data, 8);
Lou Berger056f3762013-04-10 12:30:04 -0700220 lret = 1;
paul718e3742002-12-13 20:15:29 +0000221
Lou Berger056f3762013-04-10 12:30:04 -0700222out:
223 if (s)
224 stream_free (s);
225 if (half)
226 XFREE(MTYPE_TMP, half);
227 return lret;
paul718e3742002-12-13 20:15:29 +0000228}
229
230int
paulfd79ac92004-10-13 05:06:08 +0000231str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000232{
paulfd79ac92004-10-13 05:06:08 +0000233 unsigned long l;
234 char *endptr;
235 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000236
Ulrich Weber664711c2011-12-21 02:24:11 +0400237 if (*str == '-')
238 return 0;
paulfd79ac92004-10-13 05:06:08 +0000239
Ulrich Weber664711c2011-12-21 02:24:11 +0400240 errno = 0;
241 l = strtoul (str, &endptr, 10);
242
243 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000244 return 0;
paul718e3742002-12-13 20:15:29 +0000245
paulfd79ac92004-10-13 05:06:08 +0000246 t = (u_int32_t) l;
247
248 tag[0] = (u_char)(t >> 12);
249 tag[1] = (u_char)(t >> 4);
250 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000251
252 return 1;
253}
254
255char *
256prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
257{
258 u_char *pnt;
259 u_int16_t type;
260 struct rd_as rd_as;
261 struct rd_ip rd_ip;
262
263 if (size < RD_ADDRSTRLEN)
264 return NULL;
265
266 pnt = prd->val;
267
268 type = decode_rd_type (pnt);
269
270 if (type == RD_TYPE_AS)
271 {
272 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400273 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000274 return buf;
275 }
276 else if (type == RD_TYPE_IP)
277 {
278 decode_rd_ip (pnt + 2, &rd_ip);
279 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
280 return buf;
281 }
282
283 return NULL;
284}
285
286/* For testing purpose, static route of MPLS-VPN. */
287DEFUN (vpnv4_network,
288 vpnv4_network_cmd,
289 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
290 "Specify a network to announce via BGP\n"
291 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
292 "Specify Route Distinguisher\n"
293 "VPN Route Distinguisher\n"
294 "BGP tag\n"
295 "tag value\n")
296{
297 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
298}
299
300/* For testing purpose, static route of MPLS-VPN. */
301DEFUN (no_vpnv4_network,
302 no_vpnv4_network_cmd,
303 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
304 NO_STR
305 "Specify a network to announce via BGP\n"
306 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
307 "Specify Route Distinguisher\n"
308 "VPN Route Distinguisher\n"
309 "BGP tag\n"
310 "tag value\n")
311{
312 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
313}
314
paul94f2b392005-06-28 12:44:16 +0000315static int
paul718e3742002-12-13 20:15:29 +0000316show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
317{
318 struct bgp *bgp;
319 struct bgp_table *table;
320 struct bgp_node *rn;
321 struct bgp_node *rm;
322 struct attr *attr;
323 int rd_header;
324 int header = 1;
325 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
326
327 bgp = bgp_get_default ();
328 if (bgp == NULL)
329 {
330 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
331 return CMD_WARNING;
332 }
333
334 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
335 rn = bgp_route_next (rn))
336 {
337 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
338 continue;
339
340 if ((table = rn->info) != NULL)
341 {
342 rd_header = 1;
343
344 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
345 if ((attr = rm->info) != NULL)
346 {
347 if (header)
348 {
349 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
350 inet_ntoa (bgp->router_id), VTY_NEWLINE);
351 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
352 VTY_NEWLINE);
353 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
354 VTY_NEWLINE, VTY_NEWLINE);
355 vty_out (vty, v4_header, VTY_NEWLINE);
356 header = 0;
357 }
358
359 if (rd_header)
360 {
361 u_int16_t type;
362 struct rd_as rd_as;
363 struct rd_ip rd_ip;
364 u_char *pnt;
365
366 pnt = rn->p.u.val;
367
368 /* Decode RD type. */
369 type = decode_rd_type (pnt);
370 /* Decode RD value. */
371 if (type == RD_TYPE_AS)
372 decode_rd_as (pnt + 2, &rd_as);
373 else if (type == RD_TYPE_IP)
374 decode_rd_ip (pnt + 2, &rd_ip);
375
376 vty_out (vty, "Route Distinguisher: ");
377
378 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400379 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000380 else if (type == RD_TYPE_IP)
381 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
382
383 vty_out (vty, "%s", VTY_NEWLINE);
384 rd_header = 0;
385 }
386 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
387 }
388 }
389 }
390 return CMD_SUCCESS;
391}
392
393enum bgp_show_type
394{
395 bgp_show_type_normal,
396 bgp_show_type_regexp,
397 bgp_show_type_prefix_list,
398 bgp_show_type_filter_list,
399 bgp_show_type_neighbor,
400 bgp_show_type_cidr_only,
401 bgp_show_type_prefix_longer,
402 bgp_show_type_community_all,
403 bgp_show_type_community,
404 bgp_show_type_community_exact,
405 bgp_show_type_community_list,
406 bgp_show_type_community_list_exact
407};
408
paul94f2b392005-06-28 12:44:16 +0000409static int
paul718e3742002-12-13 20:15:29 +0000410bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
411 void *output_arg, int tags)
412{
413 struct bgp *bgp;
414 struct bgp_table *table;
415 struct bgp_node *rn;
416 struct bgp_node *rm;
417 struct bgp_info *ri;
418 int rd_header;
419 int header = 1;
420 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
421 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
422
423 bgp = bgp_get_default ();
424 if (bgp == NULL)
425 {
426 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
427 return CMD_WARNING;
428 }
429
430 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
431 {
432 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
433 continue;
434
435 if ((table = rn->info) != NULL)
436 {
437 rd_header = 1;
438
439 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
440 for (ri = rm->info; ri; ri = ri->next)
441 {
442 if (type == bgp_show_type_neighbor)
443 {
444 union sockunion *su = output_arg;
445
446 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
447 continue;
448 }
449 if (header)
450 {
451 if (tags)
452 vty_out (vty, v4_header_tag, VTY_NEWLINE);
453 else
454 {
455 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
456 inet_ntoa (bgp->router_id), VTY_NEWLINE);
457 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
458 VTY_NEWLINE);
459 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
460 VTY_NEWLINE, VTY_NEWLINE);
461 vty_out (vty, v4_header, VTY_NEWLINE);
462 }
463 header = 0;
464 }
465
466 if (rd_header)
467 {
468 u_int16_t type;
469 struct rd_as rd_as;
470 struct rd_ip rd_ip;
471 u_char *pnt;
472
473 pnt = rn->p.u.val;
474
475 /* Decode RD type. */
476 type = decode_rd_type (pnt);
477 /* Decode RD value. */
478 if (type == RD_TYPE_AS)
479 decode_rd_as (pnt + 2, &rd_as);
480 else if (type == RD_TYPE_IP)
481 decode_rd_ip (pnt + 2, &rd_ip);
482
483 vty_out (vty, "Route Distinguisher: ");
484
485 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400486 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000487 else if (type == RD_TYPE_IP)
488 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
489
490 vty_out (vty, "%s", VTY_NEWLINE);
491 rd_header = 0;
492 }
493 if (tags)
494 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
495 else
496 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
497 }
498 }
499 }
500 return CMD_SUCCESS;
501}
502
503DEFUN (show_ip_bgp_vpnv4_all,
504 show_ip_bgp_vpnv4_all_cmd,
505 "show ip bgp vpnv4 all",
506 SHOW_STR
507 IP_STR
508 BGP_STR
509 "Display VPNv4 NLRI specific information\n"
510 "Display information about all VPNv4 NLRIs\n")
511{
512 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
513}
514
515DEFUN (show_ip_bgp_vpnv4_rd,
516 show_ip_bgp_vpnv4_rd_cmd,
517 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
518 SHOW_STR
519 IP_STR
520 BGP_STR
521 "Display VPNv4 NLRI specific information\n"
522 "Display information for a route distinguisher\n"
523 "VPN Route Distinguisher\n")
524{
525 int ret;
526 struct prefix_rd prd;
527
528 ret = str2prefix_rd (argv[0], &prd);
529 if (! ret)
530 {
531 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
532 return CMD_WARNING;
533 }
534 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
535}
536
537DEFUN (show_ip_bgp_vpnv4_all_tags,
538 show_ip_bgp_vpnv4_all_tags_cmd,
539 "show ip bgp vpnv4 all tags",
540 SHOW_STR
541 IP_STR
542 BGP_STR
543 "Display VPNv4 NLRI specific information\n"
544 "Display information about all VPNv4 NLRIs\n"
545 "Display BGP tags for prefixes\n")
546{
547 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
548}
549
550DEFUN (show_ip_bgp_vpnv4_rd_tags,
551 show_ip_bgp_vpnv4_rd_tags_cmd,
552 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
553 SHOW_STR
554 IP_STR
555 BGP_STR
556 "Display VPNv4 NLRI specific information\n"
557 "Display information for a route distinguisher\n"
558 "VPN Route Distinguisher\n"
559 "Display BGP tags for prefixes\n")
560{
561 int ret;
562 struct prefix_rd prd;
563
564 ret = str2prefix_rd (argv[0], &prd);
565 if (! ret)
566 {
567 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
568 return CMD_WARNING;
569 }
570 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
571}
572
573DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
574 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
575 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
576 SHOW_STR
577 IP_STR
578 BGP_STR
579 "Display VPNv4 NLRI specific information\n"
580 "Display information about all VPNv4 NLRIs\n"
581 "Detailed information on TCP and BGP neighbor connections\n"
582 "Neighbor to display information about\n"
583 "Display routes learned from neighbor\n")
584{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200585 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000586 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200587 int ret;
588
589 ret = str2sockunion (argv[0], &su);
590 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000591 {
592 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200593 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000594 }
595
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200596 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000597 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
598 {
599 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
600 return CMD_WARNING;
601 }
602
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200603 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000604}
605
606DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
607 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
608 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
609 SHOW_STR
610 IP_STR
611 BGP_STR
612 "Display VPNv4 NLRI specific information\n"
613 "Display information for a route distinguisher\n"
614 "VPN Route Distinguisher\n"
615 "Detailed information on TCP and BGP neighbor connections\n"
616 "Neighbor to display information about\n"
617 "Display routes learned from neighbor\n")
618{
619 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200620 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000621 struct peer *peer;
622 struct prefix_rd prd;
623
624 ret = str2prefix_rd (argv[0], &prd);
625 if (! ret)
626 {
627 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
628 return CMD_WARNING;
629 }
630
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200631 ret = str2sockunion (argv[1], &su);
632 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000633 {
634 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200635 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000636 }
637
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200638 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000639 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
640 {
641 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
642 return CMD_WARNING;
643 }
644
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200645 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000646}
647
648DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
649 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
650 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
651 SHOW_STR
652 IP_STR
653 BGP_STR
654 "Display VPNv4 NLRI specific information\n"
655 "Display information about all VPNv4 NLRIs\n"
656 "Detailed information on TCP and BGP neighbor connections\n"
657 "Neighbor to display information about\n"
658 "Display the routes advertised to a BGP neighbor\n")
659{
660 int ret;
661 struct peer *peer;
662 union sockunion su;
663
664 ret = str2sockunion (argv[0], &su);
665 if (ret < 0)
666 {
667 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
668 return CMD_WARNING;
669 }
670 peer = peer_lookup (NULL, &su);
671 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
672 {
673 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
674 return CMD_WARNING;
675 }
676
677 return show_adj_route_vpn (vty, peer, NULL);
678}
679
680DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
681 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
682 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
683 SHOW_STR
684 IP_STR
685 BGP_STR
686 "Display VPNv4 NLRI specific information\n"
687 "Display information for a route distinguisher\n"
688 "VPN Route Distinguisher\n"
689 "Detailed information on TCP and BGP neighbor connections\n"
690 "Neighbor to display information about\n"
691 "Display the routes advertised to a BGP neighbor\n")
692{
693 int ret;
694 struct peer *peer;
695 struct prefix_rd prd;
696 union sockunion su;
697
698 ret = str2sockunion (argv[1], &su);
699 if (ret < 0)
700 {
701 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
702 return CMD_WARNING;
703 }
704 peer = peer_lookup (NULL, &su);
705 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
706 {
707 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
708 return CMD_WARNING;
709 }
710
711 ret = str2prefix_rd (argv[0], &prd);
712 if (! ret)
713 {
714 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
715 return CMD_WARNING;
716 }
717
718 return show_adj_route_vpn (vty, peer, &prd);
719}
720
721void
paul94f2b392005-06-28 12:44:16 +0000722bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000723{
724 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
725 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
726
727
728 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
729 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
730 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
731 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
732 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
733 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
734 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
735 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
736
737 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
738 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
739 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
740 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
741 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
742 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
743 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
744 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
745}