blob: 8a1ed70e2aa300fa219218035fdf710e63be6708 [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{
173 int ret;
paul5228ad22004-06-04 17:58:18 +0000174 char *p;
175 char *p2;
paul718e3742002-12-13 20:15:29 +0000176 struct stream *s;
paul5228ad22004-06-04 17:58:18 +0000177 char *half;
paul718e3742002-12-13 20:15:29 +0000178 struct in_addr addr;
179
180 s = stream_new (8);
181
182 prd->family = AF_UNSPEC;
183 prd->prefixlen = 64;
184
185 p = strchr (str, ':');
186 if (! p)
187 return 0;
188
189 if (! all_digit (p + 1))
190 return 0;
191
192 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
193 memcpy (half, str, (p - str));
194 half[p - str] = '\0';
195
196 p2 = strchr (str, '.');
197
198 if (! p2)
199 {
200 if (! all_digit (half))
201 {
202 XFREE (MTYPE_TMP, half);
203 return 0;
204 }
205 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)
213 {
214 XFREE (MTYPE_TMP, half);
215 return 0;
216 }
217 stream_putw (s, RD_TYPE_IP);
218 stream_put_in_addr (s, &addr);
219 stream_putw (s, atol (p + 1));
220 }
221 memcpy (prd->val, s->data, 8);
222
Donald Sharp79969962015-08-19 21:27:24 -0400223 XFREE(MTYPE_TMP, half);
paul718e3742002-12-13 20:15:29 +0000224 return 1;
225}
226
227int
paulfd79ac92004-10-13 05:06:08 +0000228str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000229{
paulfd79ac92004-10-13 05:06:08 +0000230 unsigned long l;
231 char *endptr;
232 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000233
Ulrich Weber664711c2011-12-21 02:24:11 +0400234 if (*str == '-')
235 return 0;
paulfd79ac92004-10-13 05:06:08 +0000236
Ulrich Weber664711c2011-12-21 02:24:11 +0400237 errno = 0;
238 l = strtoul (str, &endptr, 10);
239
240 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000241 return 0;
paul718e3742002-12-13 20:15:29 +0000242
paulfd79ac92004-10-13 05:06:08 +0000243 t = (u_int32_t) l;
244
245 tag[0] = (u_char)(t >> 12);
246 tag[1] = (u_char)(t >> 4);
247 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000248
249 return 1;
250}
251
252char *
253prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
254{
255 u_char *pnt;
256 u_int16_t type;
257 struct rd_as rd_as;
258 struct rd_ip rd_ip;
259
260 if (size < RD_ADDRSTRLEN)
261 return NULL;
262
263 pnt = prd->val;
264
265 type = decode_rd_type (pnt);
266
267 if (type == RD_TYPE_AS)
268 {
269 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400270 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000271 return buf;
272 }
273 else if (type == RD_TYPE_IP)
274 {
275 decode_rd_ip (pnt + 2, &rd_ip);
276 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
277 return buf;
278 }
279
280 return NULL;
281}
282
283/* For testing purpose, static route of MPLS-VPN. */
284DEFUN (vpnv4_network,
285 vpnv4_network_cmd,
286 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
287 "Specify a network to announce via BGP\n"
288 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
289 "Specify Route Distinguisher\n"
290 "VPN Route Distinguisher\n"
291 "BGP tag\n"
292 "tag value\n")
293{
294 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
295}
296
297/* For testing purpose, static route of MPLS-VPN. */
298DEFUN (no_vpnv4_network,
299 no_vpnv4_network_cmd,
300 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
301 NO_STR
302 "Specify a network to announce via BGP\n"
303 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
304 "Specify Route Distinguisher\n"
305 "VPN Route Distinguisher\n"
306 "BGP tag\n"
307 "tag value\n")
308{
309 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
310}
311
paul94f2b392005-06-28 12:44:16 +0000312static int
paul718e3742002-12-13 20:15:29 +0000313show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
314{
315 struct bgp *bgp;
316 struct bgp_table *table;
317 struct bgp_node *rn;
318 struct bgp_node *rm;
319 struct attr *attr;
320 int rd_header;
321 int header = 1;
322 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
323
324 bgp = bgp_get_default ();
325 if (bgp == NULL)
326 {
327 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
328 return CMD_WARNING;
329 }
330
331 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
332 rn = bgp_route_next (rn))
333 {
334 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
335 continue;
336
337 if ((table = rn->info) != NULL)
338 {
339 rd_header = 1;
340
341 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
342 if ((attr = rm->info) != NULL)
343 {
344 if (header)
345 {
346 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
347 inet_ntoa (bgp->router_id), VTY_NEWLINE);
348 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
349 VTY_NEWLINE);
350 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
351 VTY_NEWLINE, VTY_NEWLINE);
352 vty_out (vty, v4_header, VTY_NEWLINE);
353 header = 0;
354 }
355
356 if (rd_header)
357 {
358 u_int16_t type;
359 struct rd_as rd_as;
360 struct rd_ip rd_ip;
361 u_char *pnt;
362
363 pnt = rn->p.u.val;
364
365 /* Decode RD type. */
366 type = decode_rd_type (pnt);
367 /* Decode RD value. */
368 if (type == RD_TYPE_AS)
369 decode_rd_as (pnt + 2, &rd_as);
370 else if (type == RD_TYPE_IP)
371 decode_rd_ip (pnt + 2, &rd_ip);
372
373 vty_out (vty, "Route Distinguisher: ");
374
375 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400376 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000377 else if (type == RD_TYPE_IP)
378 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
379
380 vty_out (vty, "%s", VTY_NEWLINE);
381 rd_header = 0;
382 }
383 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
384 }
385 }
386 }
387 return CMD_SUCCESS;
388}
389
390enum bgp_show_type
391{
392 bgp_show_type_normal,
393 bgp_show_type_regexp,
394 bgp_show_type_prefix_list,
395 bgp_show_type_filter_list,
396 bgp_show_type_neighbor,
397 bgp_show_type_cidr_only,
398 bgp_show_type_prefix_longer,
399 bgp_show_type_community_all,
400 bgp_show_type_community,
401 bgp_show_type_community_exact,
402 bgp_show_type_community_list,
403 bgp_show_type_community_list_exact
404};
405
paul94f2b392005-06-28 12:44:16 +0000406static int
paul718e3742002-12-13 20:15:29 +0000407bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
408 void *output_arg, int tags)
409{
410 struct bgp *bgp;
411 struct bgp_table *table;
412 struct bgp_node *rn;
413 struct bgp_node *rm;
414 struct bgp_info *ri;
415 int rd_header;
416 int header = 1;
417 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
418 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
419
420 bgp = bgp_get_default ();
421 if (bgp == NULL)
422 {
423 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
424 return CMD_WARNING;
425 }
426
427 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
428 {
429 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
430 continue;
431
432 if ((table = rn->info) != NULL)
433 {
434 rd_header = 1;
435
436 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
437 for (ri = rm->info; ri; ri = ri->next)
438 {
439 if (type == bgp_show_type_neighbor)
440 {
441 union sockunion *su = output_arg;
442
443 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
444 continue;
445 }
446 if (header)
447 {
448 if (tags)
449 vty_out (vty, v4_header_tag, VTY_NEWLINE);
450 else
451 {
452 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
453 inet_ntoa (bgp->router_id), VTY_NEWLINE);
454 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
455 VTY_NEWLINE);
456 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
457 VTY_NEWLINE, VTY_NEWLINE);
458 vty_out (vty, v4_header, VTY_NEWLINE);
459 }
460 header = 0;
461 }
462
463 if (rd_header)
464 {
465 u_int16_t type;
466 struct rd_as rd_as;
467 struct rd_ip rd_ip;
468 u_char *pnt;
469
470 pnt = rn->p.u.val;
471
472 /* Decode RD type. */
473 type = decode_rd_type (pnt);
474 /* Decode RD value. */
475 if (type == RD_TYPE_AS)
476 decode_rd_as (pnt + 2, &rd_as);
477 else if (type == RD_TYPE_IP)
478 decode_rd_ip (pnt + 2, &rd_ip);
479
480 vty_out (vty, "Route Distinguisher: ");
481
482 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400483 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000484 else if (type == RD_TYPE_IP)
485 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
486
487 vty_out (vty, "%s", VTY_NEWLINE);
488 rd_header = 0;
489 }
490 if (tags)
491 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
492 else
493 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
494 }
495 }
496 }
497 return CMD_SUCCESS;
498}
499
500DEFUN (show_ip_bgp_vpnv4_all,
501 show_ip_bgp_vpnv4_all_cmd,
502 "show ip bgp vpnv4 all",
503 SHOW_STR
504 IP_STR
505 BGP_STR
506 "Display VPNv4 NLRI specific information\n"
507 "Display information about all VPNv4 NLRIs\n")
508{
509 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
510}
511
512DEFUN (show_ip_bgp_vpnv4_rd,
513 show_ip_bgp_vpnv4_rd_cmd,
514 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
515 SHOW_STR
516 IP_STR
517 BGP_STR
518 "Display VPNv4 NLRI specific information\n"
519 "Display information for a route distinguisher\n"
520 "VPN Route Distinguisher\n")
521{
522 int ret;
523 struct prefix_rd prd;
524
525 ret = str2prefix_rd (argv[0], &prd);
526 if (! ret)
527 {
528 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
529 return CMD_WARNING;
530 }
531 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
532}
533
534DEFUN (show_ip_bgp_vpnv4_all_tags,
535 show_ip_bgp_vpnv4_all_tags_cmd,
536 "show ip bgp vpnv4 all tags",
537 SHOW_STR
538 IP_STR
539 BGP_STR
540 "Display VPNv4 NLRI specific information\n"
541 "Display information about all VPNv4 NLRIs\n"
542 "Display BGP tags for prefixes\n")
543{
544 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
545}
546
547DEFUN (show_ip_bgp_vpnv4_rd_tags,
548 show_ip_bgp_vpnv4_rd_tags_cmd,
549 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
550 SHOW_STR
551 IP_STR
552 BGP_STR
553 "Display VPNv4 NLRI specific information\n"
554 "Display information for a route distinguisher\n"
555 "VPN Route Distinguisher\n"
556 "Display BGP tags for prefixes\n")
557{
558 int ret;
559 struct prefix_rd prd;
560
561 ret = str2prefix_rd (argv[0], &prd);
562 if (! ret)
563 {
564 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
565 return CMD_WARNING;
566 }
567 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
568}
569
570DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
571 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
572 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
573 SHOW_STR
574 IP_STR
575 BGP_STR
576 "Display VPNv4 NLRI specific information\n"
577 "Display information about all VPNv4 NLRIs\n"
578 "Detailed information on TCP and BGP neighbor connections\n"
579 "Neighbor to display information about\n"
580 "Display routes learned from neighbor\n")
581{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200582 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000583 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200584 int ret;
585
586 ret = str2sockunion (argv[0], &su);
587 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000588 {
589 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200590 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000591 }
592
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200593 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000594 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
595 {
596 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
597 return CMD_WARNING;
598 }
599
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200600 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000601}
602
603DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
604 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
605 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
606 SHOW_STR
607 IP_STR
608 BGP_STR
609 "Display VPNv4 NLRI specific information\n"
610 "Display information for a route distinguisher\n"
611 "VPN Route Distinguisher\n"
612 "Detailed information on TCP and BGP neighbor connections\n"
613 "Neighbor to display information about\n"
614 "Display routes learned from neighbor\n")
615{
616 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200617 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000618 struct peer *peer;
619 struct prefix_rd prd;
620
621 ret = str2prefix_rd (argv[0], &prd);
622 if (! ret)
623 {
624 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
625 return CMD_WARNING;
626 }
627
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200628 ret = str2sockunion (argv[1], &su);
629 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000630 {
631 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200632 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000633 }
634
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200635 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000636 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
637 {
638 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
639 return CMD_WARNING;
640 }
641
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200642 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000643}
644
645DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
646 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
647 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
648 SHOW_STR
649 IP_STR
650 BGP_STR
651 "Display VPNv4 NLRI specific information\n"
652 "Display information about all VPNv4 NLRIs\n"
653 "Detailed information on TCP and BGP neighbor connections\n"
654 "Neighbor to display information about\n"
655 "Display the routes advertised to a BGP neighbor\n")
656{
657 int ret;
658 struct peer *peer;
659 union sockunion su;
660
661 ret = str2sockunion (argv[0], &su);
662 if (ret < 0)
663 {
664 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
665 return CMD_WARNING;
666 }
667 peer = peer_lookup (NULL, &su);
668 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
669 {
670 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
671 return CMD_WARNING;
672 }
673
674 return show_adj_route_vpn (vty, peer, NULL);
675}
676
677DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
678 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
679 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
680 SHOW_STR
681 IP_STR
682 BGP_STR
683 "Display VPNv4 NLRI specific information\n"
684 "Display information for a route distinguisher\n"
685 "VPN Route Distinguisher\n"
686 "Detailed information on TCP and BGP neighbor connections\n"
687 "Neighbor to display information about\n"
688 "Display the routes advertised to a BGP neighbor\n")
689{
690 int ret;
691 struct peer *peer;
692 struct prefix_rd prd;
693 union sockunion su;
694
695 ret = str2sockunion (argv[1], &su);
696 if (ret < 0)
697 {
698 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
699 return CMD_WARNING;
700 }
701 peer = peer_lookup (NULL, &su);
702 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
703 {
704 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
705 return CMD_WARNING;
706 }
707
708 ret = str2prefix_rd (argv[0], &prd);
709 if (! ret)
710 {
711 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
712 return CMD_WARNING;
713 }
714
715 return show_adj_route_vpn (vty, peer, &prd);
716}
717
718void
paul94f2b392005-06-28 12:44:16 +0000719bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000720{
721 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
722 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
723
724
725 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
726 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
727 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
728 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
729 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
730 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
731 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
732 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
733
734 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
735 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
736 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
737 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
738 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
739 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
740 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
741 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
742}