blob: ac90f3c546ea6b97f98e2d57ead94150f64d062d [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;
87 u_int32_t label;
88 u_int16_t type;
89 struct rd_as rd_as;
90 struct rd_ip rd_ip;
91 struct prefix_rd prd;
92 u_char *tagpnt;
93
94 /* Check peer status. */
95 if (peer->status != Established)
96 return 0;
97
98 /* Make prefix_rd */
99 prd.family = AF_UNSPEC;
100 prd.prefixlen = 64;
101
102 pnt = packet->nlri;
103 lim = pnt + packet->length;
104
105 for (; pnt < lim; pnt += psize)
106 {
107 /* Clear prefix structure. */
108 memset (&p, 0, sizeof (struct prefix));
109
110 /* Fetch prefix length. */
111 prefixlen = *pnt++;
112 p.family = AF_INET;
113 psize = PSIZE (prefixlen);
114
115 if (prefixlen < 88)
116 {
117 zlog_err ("prefix length is less than 88: %d", prefixlen);
118 return -1;
119 }
120
121 label = decode_label (pnt);
122
123 /* Copyr label to prefix. */
124 tagpnt = pnt;;
125
126 /* Copy routing distinguisher to rd. */
127 memcpy (&prd.val, pnt + 3, 8);
128
129 /* Decode RD type. */
130 type = decode_rd_type (pnt + 3);
131
132 /* Decode RD value. */
133 if (type == RD_TYPE_AS)
134 decode_rd_as (pnt + 5, &rd_as);
135 else if (type == RD_TYPE_IP)
136 decode_rd_ip (pnt + 5, &rd_ip);
137 else
138 {
139 zlog_err ("Invalid RD type %d", type);
140 return -1;
141 }
142
143 p.prefixlen = prefixlen - 88;
144 memcpy (&p.u.prefix, pnt + 11, psize - 11);
145
146#if 0
147 if (type == RD_TYPE_AS)
148 zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
149 inet_ntoa (p.u.prefix4), p.prefixlen);
150 else if (type == RD_TYPE_IP)
151 zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
152 rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
153#endif /* 0 */
154
155 if (pnt + psize > lim)
156 return -1;
157
158 if (attr)
159 bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
paul94f2b392005-06-28 12:44:16 +0000160 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000161 else
162 bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
163 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
164 }
165
166 /* Packet length consistency check. */
167 if (pnt != lim)
168 return -1;
169
170 return 0;
171}
172
173int
paulfd79ac92004-10-13 05:06:08 +0000174str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000175{
176 int ret;
paul5228ad22004-06-04 17:58:18 +0000177 char *p;
178 char *p2;
paul718e3742002-12-13 20:15:29 +0000179 struct stream *s;
paul5228ad22004-06-04 17:58:18 +0000180 char *half;
paul718e3742002-12-13 20:15:29 +0000181 struct in_addr addr;
182
183 s = stream_new (8);
184
185 prd->family = AF_UNSPEC;
186 prd->prefixlen = 64;
187
188 p = strchr (str, ':');
189 if (! p)
190 return 0;
191
192 if (! all_digit (p + 1))
193 return 0;
194
195 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
196 memcpy (half, str, (p - str));
197 half[p - str] = '\0';
198
199 p2 = strchr (str, '.');
200
201 if (! p2)
202 {
203 if (! all_digit (half))
204 {
205 XFREE (MTYPE_TMP, half);
206 return 0;
207 }
208 stream_putw (s, RD_TYPE_AS);
209 stream_putw (s, atoi (half));
210 stream_putl (s, atol (p + 1));
211 }
212 else
213 {
214 ret = inet_aton (half, &addr);
215 if (! ret)
216 {
217 XFREE (MTYPE_TMP, half);
218 return 0;
219 }
220 stream_putw (s, RD_TYPE_IP);
221 stream_put_in_addr (s, &addr);
222 stream_putw (s, atol (p + 1));
223 }
224 memcpy (prd->val, s->data, 8);
225
226 return 1;
227}
228
229int
paulfd79ac92004-10-13 05:06:08 +0000230str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000231{
paulfd79ac92004-10-13 05:06:08 +0000232 unsigned long l;
233 char *endptr;
234 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000235
paulfd79ac92004-10-13 05:06:08 +0000236 l = strtoul (str, &endptr, 10);
237
238 if (*endptr == '\0' || l == ULONG_MAX || l > UINT32_MAX)
239 return 0;
paul718e3742002-12-13 20:15:29 +0000240
paulfd79ac92004-10-13 05:06:08 +0000241 t = (u_int32_t) l;
242
243 tag[0] = (u_char)(t >> 12);
244 tag[1] = (u_char)(t >> 4);
245 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000246
247 return 1;
248}
249
250char *
251prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
252{
253 u_char *pnt;
254 u_int16_t type;
255 struct rd_as rd_as;
256 struct rd_ip rd_ip;
257
258 if (size < RD_ADDRSTRLEN)
259 return NULL;
260
261 pnt = prd->val;
262
263 type = decode_rd_type (pnt);
264
265 if (type == RD_TYPE_AS)
266 {
267 decode_rd_as (pnt + 2, &rd_as);
268 snprintf (buf, size, "%d:%d", rd_as.as, rd_as.val);
269 return buf;
270 }
271 else if (type == RD_TYPE_IP)
272 {
273 decode_rd_ip (pnt + 2, &rd_ip);
274 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
275 return buf;
276 }
277
278 return NULL;
279}
280
281/* For testing purpose, static route of MPLS-VPN. */
282DEFUN (vpnv4_network,
283 vpnv4_network_cmd,
284 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
285 "Specify a network to announce via BGP\n"
286 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
287 "Specify Route Distinguisher\n"
288 "VPN Route Distinguisher\n"
289 "BGP tag\n"
290 "tag value\n")
291{
292 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
293}
294
295/* For testing purpose, static route of MPLS-VPN. */
296DEFUN (no_vpnv4_network,
297 no_vpnv4_network_cmd,
298 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
299 NO_STR
300 "Specify a network to announce via BGP\n"
301 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
302 "Specify Route Distinguisher\n"
303 "VPN Route Distinguisher\n"
304 "BGP tag\n"
305 "tag value\n")
306{
307 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
308}
309
paul94f2b392005-06-28 12:44:16 +0000310static int
paul718e3742002-12-13 20:15:29 +0000311show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
312{
313 struct bgp *bgp;
314 struct bgp_table *table;
315 struct bgp_node *rn;
316 struct bgp_node *rm;
317 struct attr *attr;
318 int rd_header;
319 int header = 1;
320 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
321
322 bgp = bgp_get_default ();
323 if (bgp == NULL)
324 {
325 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
326 return CMD_WARNING;
327 }
328
329 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
330 rn = bgp_route_next (rn))
331 {
332 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
333 continue;
334
335 if ((table = rn->info) != NULL)
336 {
337 rd_header = 1;
338
339 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
340 if ((attr = rm->info) != NULL)
341 {
342 if (header)
343 {
344 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
345 inet_ntoa (bgp->router_id), VTY_NEWLINE);
346 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
347 VTY_NEWLINE);
348 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
349 VTY_NEWLINE, VTY_NEWLINE);
350 vty_out (vty, v4_header, VTY_NEWLINE);
351 header = 0;
352 }
353
354 if (rd_header)
355 {
356 u_int16_t type;
357 struct rd_as rd_as;
358 struct rd_ip rd_ip;
359 u_char *pnt;
360
361 pnt = rn->p.u.val;
362
363 /* Decode RD type. */
364 type = decode_rd_type (pnt);
365 /* Decode RD value. */
366 if (type == RD_TYPE_AS)
367 decode_rd_as (pnt + 2, &rd_as);
368 else if (type == RD_TYPE_IP)
369 decode_rd_ip (pnt + 2, &rd_ip);
370
371 vty_out (vty, "Route Distinguisher: ");
372
373 if (type == RD_TYPE_AS)
374 vty_out (vty, "%d:%d", rd_as.as, rd_as.val);
375 else if (type == RD_TYPE_IP)
376 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
377
378 vty_out (vty, "%s", VTY_NEWLINE);
379 rd_header = 0;
380 }
381 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
382 }
383 }
384 }
385 return CMD_SUCCESS;
386}
387
388enum bgp_show_type
389{
390 bgp_show_type_normal,
391 bgp_show_type_regexp,
392 bgp_show_type_prefix_list,
393 bgp_show_type_filter_list,
394 bgp_show_type_neighbor,
395 bgp_show_type_cidr_only,
396 bgp_show_type_prefix_longer,
397 bgp_show_type_community_all,
398 bgp_show_type_community,
399 bgp_show_type_community_exact,
400 bgp_show_type_community_list,
401 bgp_show_type_community_list_exact
402};
403
paul94f2b392005-06-28 12:44:16 +0000404static int
paul718e3742002-12-13 20:15:29 +0000405bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
406 void *output_arg, int tags)
407{
408 struct bgp *bgp;
409 struct bgp_table *table;
410 struct bgp_node *rn;
411 struct bgp_node *rm;
412 struct bgp_info *ri;
413 int rd_header;
414 int header = 1;
415 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
416 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
417
418 bgp = bgp_get_default ();
419 if (bgp == NULL)
420 {
421 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
422 return CMD_WARNING;
423 }
424
425 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
426 {
427 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
428 continue;
429
430 if ((table = rn->info) != NULL)
431 {
432 rd_header = 1;
433
434 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
435 for (ri = rm->info; ri; ri = ri->next)
436 {
437 if (type == bgp_show_type_neighbor)
438 {
439 union sockunion *su = output_arg;
440
441 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
442 continue;
443 }
444 if (header)
445 {
446 if (tags)
447 vty_out (vty, v4_header_tag, VTY_NEWLINE);
448 else
449 {
450 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
451 inet_ntoa (bgp->router_id), VTY_NEWLINE);
452 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
453 VTY_NEWLINE);
454 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
455 VTY_NEWLINE, VTY_NEWLINE);
456 vty_out (vty, v4_header, VTY_NEWLINE);
457 }
458 header = 0;
459 }
460
461 if (rd_header)
462 {
463 u_int16_t type;
464 struct rd_as rd_as;
465 struct rd_ip rd_ip;
466 u_char *pnt;
467
468 pnt = rn->p.u.val;
469
470 /* Decode RD type. */
471 type = decode_rd_type (pnt);
472 /* Decode RD value. */
473 if (type == RD_TYPE_AS)
474 decode_rd_as (pnt + 2, &rd_as);
475 else if (type == RD_TYPE_IP)
476 decode_rd_ip (pnt + 2, &rd_ip);
477
478 vty_out (vty, "Route Distinguisher: ");
479
480 if (type == RD_TYPE_AS)
481 vty_out (vty, "%d:%d", rd_as.as, rd_as.val);
482 else if (type == RD_TYPE_IP)
483 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
484
485 vty_out (vty, "%s", VTY_NEWLINE);
486 rd_header = 0;
487 }
488 if (tags)
489 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
490 else
491 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
492 }
493 }
494 }
495 return CMD_SUCCESS;
496}
497
498DEFUN (show_ip_bgp_vpnv4_all,
499 show_ip_bgp_vpnv4_all_cmd,
500 "show ip bgp vpnv4 all",
501 SHOW_STR
502 IP_STR
503 BGP_STR
504 "Display VPNv4 NLRI specific information\n"
505 "Display information about all VPNv4 NLRIs\n")
506{
507 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
508}
509
510DEFUN (show_ip_bgp_vpnv4_rd,
511 show_ip_bgp_vpnv4_rd_cmd,
512 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
513 SHOW_STR
514 IP_STR
515 BGP_STR
516 "Display VPNv4 NLRI specific information\n"
517 "Display information for a route distinguisher\n"
518 "VPN Route Distinguisher\n")
519{
520 int ret;
521 struct prefix_rd prd;
522
523 ret = str2prefix_rd (argv[0], &prd);
524 if (! ret)
525 {
526 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
527 return CMD_WARNING;
528 }
529 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
530}
531
532DEFUN (show_ip_bgp_vpnv4_all_tags,
533 show_ip_bgp_vpnv4_all_tags_cmd,
534 "show ip bgp vpnv4 all tags",
535 SHOW_STR
536 IP_STR
537 BGP_STR
538 "Display VPNv4 NLRI specific information\n"
539 "Display information about all VPNv4 NLRIs\n"
540 "Display BGP tags for prefixes\n")
541{
542 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
543}
544
545DEFUN (show_ip_bgp_vpnv4_rd_tags,
546 show_ip_bgp_vpnv4_rd_tags_cmd,
547 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
548 SHOW_STR
549 IP_STR
550 BGP_STR
551 "Display VPNv4 NLRI specific information\n"
552 "Display information for a route distinguisher\n"
553 "VPN Route Distinguisher\n"
554 "Display BGP tags for prefixes\n")
555{
556 int ret;
557 struct prefix_rd prd;
558
559 ret = str2prefix_rd (argv[0], &prd);
560 if (! ret)
561 {
562 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
563 return CMD_WARNING;
564 }
565 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
566}
567
568DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
569 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
570 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
571 SHOW_STR
572 IP_STR
573 BGP_STR
574 "Display VPNv4 NLRI specific information\n"
575 "Display information about all VPNv4 NLRIs\n"
576 "Detailed information on TCP and BGP neighbor connections\n"
577 "Neighbor to display information about\n"
578 "Display routes learned from neighbor\n")
579{
580 union sockunion *su;
581 struct peer *peer;
582
583 su = sockunion_str2su (argv[0]);
584 if (su == NULL)
585 {
586 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
587 return CMD_WARNING;
588 }
589
590 peer = peer_lookup (NULL, su);
591 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
592 {
593 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
594 return CMD_WARNING;
595 }
596
597 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0);
598}
599
600DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
601 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
602 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
603 SHOW_STR
604 IP_STR
605 BGP_STR
606 "Display VPNv4 NLRI specific information\n"
607 "Display information for a route distinguisher\n"
608 "VPN Route Distinguisher\n"
609 "Detailed information on TCP and BGP neighbor connections\n"
610 "Neighbor to display information about\n"
611 "Display routes learned from neighbor\n")
612{
613 int ret;
614 union sockunion *su;
615 struct peer *peer;
616 struct prefix_rd prd;
617
618 ret = str2prefix_rd (argv[0], &prd);
619 if (! ret)
620 {
621 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
622 return CMD_WARNING;
623 }
624
625 su = sockunion_str2su (argv[1]);
626 if (su == NULL)
627 {
628 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
629 return CMD_WARNING;
630 }
631
632 peer = peer_lookup (NULL, su);
633 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
634 {
635 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
636 return CMD_WARNING;
637 }
638
639 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0);
640}
641
642DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
643 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
644 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
645 SHOW_STR
646 IP_STR
647 BGP_STR
648 "Display VPNv4 NLRI specific information\n"
649 "Display information about all VPNv4 NLRIs\n"
650 "Detailed information on TCP and BGP neighbor connections\n"
651 "Neighbor to display information about\n"
652 "Display the routes advertised to a BGP neighbor\n")
653{
654 int ret;
655 struct peer *peer;
656 union sockunion su;
657
658 ret = str2sockunion (argv[0], &su);
659 if (ret < 0)
660 {
661 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
662 return CMD_WARNING;
663 }
664 peer = peer_lookup (NULL, &su);
665 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
666 {
667 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
668 return CMD_WARNING;
669 }
670
671 return show_adj_route_vpn (vty, peer, NULL);
672}
673
674DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
675 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
676 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
677 SHOW_STR
678 IP_STR
679 BGP_STR
680 "Display VPNv4 NLRI specific information\n"
681 "Display information for a route distinguisher\n"
682 "VPN Route Distinguisher\n"
683 "Detailed information on TCP and BGP neighbor connections\n"
684 "Neighbor to display information about\n"
685 "Display the routes advertised to a BGP neighbor\n")
686{
687 int ret;
688 struct peer *peer;
689 struct prefix_rd prd;
690 union sockunion su;
691
692 ret = str2sockunion (argv[1], &su);
693 if (ret < 0)
694 {
695 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
696 return CMD_WARNING;
697 }
698 peer = peer_lookup (NULL, &su);
699 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
700 {
701 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
702 return CMD_WARNING;
703 }
704
705 ret = str2prefix_rd (argv[0], &prd);
706 if (! ret)
707 {
708 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
709 return CMD_WARNING;
710 }
711
712 return show_adj_route_vpn (vty, peer, &prd);
713}
714
715void
paul94f2b392005-06-28 12:44:16 +0000716bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000717{
718 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
719 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
720
721
722 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
723 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
724 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
725 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
726 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
727 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
728 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
729 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
730
731 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
732 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
733 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
734 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
735 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
736 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
737 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
738 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
739}