blob: 3d2dadef6f1fb2f7bd898b77c97d06b06ea83ff1 [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 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100119
120 /* XXX: Not doing anything with the label */
121 decode_label (pnt);
paul718e3742002-12-13 20:15:29 +0000122
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
Ulrich Weber664711c2011-12-21 02:24:11 +0400236 if (*str == '-')
237 return 0;
paulfd79ac92004-10-13 05:06:08 +0000238
Ulrich Weber664711c2011-12-21 02:24:11 +0400239 errno = 0;
240 l = strtoul (str, &endptr, 10);
241
242 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000243 return 0;
paul718e3742002-12-13 20:15:29 +0000244
paulfd79ac92004-10-13 05:06:08 +0000245 t = (u_int32_t) l;
246
247 tag[0] = (u_char)(t >> 12);
248 tag[1] = (u_char)(t >> 4);
249 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000250
251 return 1;
252}
253
254char *
255prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
256{
257 u_char *pnt;
258 u_int16_t type;
259 struct rd_as rd_as;
260 struct rd_ip rd_ip;
261
262 if (size < RD_ADDRSTRLEN)
263 return NULL;
264
265 pnt = prd->val;
266
267 type = decode_rd_type (pnt);
268
269 if (type == RD_TYPE_AS)
270 {
271 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400272 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000273 return buf;
274 }
275 else if (type == RD_TYPE_IP)
276 {
277 decode_rd_ip (pnt + 2, &rd_ip);
278 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
279 return buf;
280 }
281
282 return NULL;
283}
284
285/* For testing purpose, static route of MPLS-VPN. */
286DEFUN (vpnv4_network,
287 vpnv4_network_cmd,
288 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
289 "Specify a network to announce via BGP\n"
290 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
291 "Specify Route Distinguisher\n"
292 "VPN Route Distinguisher\n"
293 "BGP tag\n"
294 "tag value\n")
295{
296 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
297}
298
299/* For testing purpose, static route of MPLS-VPN. */
300DEFUN (no_vpnv4_network,
301 no_vpnv4_network_cmd,
302 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
303 NO_STR
304 "Specify a network to announce via BGP\n"
305 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
306 "Specify Route Distinguisher\n"
307 "VPN Route Distinguisher\n"
308 "BGP tag\n"
309 "tag value\n")
310{
311 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
312}
313
paul94f2b392005-06-28 12:44:16 +0000314static int
paul718e3742002-12-13 20:15:29 +0000315show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
316{
317 struct bgp *bgp;
318 struct bgp_table *table;
319 struct bgp_node *rn;
320 struct bgp_node *rm;
321 struct attr *attr;
322 int rd_header;
323 int header = 1;
324 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
325
326 bgp = bgp_get_default ();
327 if (bgp == NULL)
328 {
329 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
330 return CMD_WARNING;
331 }
332
333 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
334 rn = bgp_route_next (rn))
335 {
336 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
337 continue;
338
339 if ((table = rn->info) != NULL)
340 {
341 rd_header = 1;
342
343 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
344 if ((attr = rm->info) != NULL)
345 {
346 if (header)
347 {
348 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
349 inet_ntoa (bgp->router_id), VTY_NEWLINE);
350 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
351 VTY_NEWLINE);
352 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
353 VTY_NEWLINE, VTY_NEWLINE);
354 vty_out (vty, v4_header, VTY_NEWLINE);
355 header = 0;
356 }
357
358 if (rd_header)
359 {
360 u_int16_t type;
361 struct rd_as rd_as;
362 struct rd_ip rd_ip;
363 u_char *pnt;
364
365 pnt = rn->p.u.val;
366
367 /* Decode RD type. */
368 type = decode_rd_type (pnt);
369 /* Decode RD value. */
370 if (type == RD_TYPE_AS)
371 decode_rd_as (pnt + 2, &rd_as);
372 else if (type == RD_TYPE_IP)
373 decode_rd_ip (pnt + 2, &rd_ip);
374
375 vty_out (vty, "Route Distinguisher: ");
376
377 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400378 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000379 else if (type == RD_TYPE_IP)
380 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
381
382 vty_out (vty, "%s", VTY_NEWLINE);
383 rd_header = 0;
384 }
385 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
386 }
387 }
388 }
389 return CMD_SUCCESS;
390}
391
392enum bgp_show_type
393{
394 bgp_show_type_normal,
395 bgp_show_type_regexp,
396 bgp_show_type_prefix_list,
397 bgp_show_type_filter_list,
398 bgp_show_type_neighbor,
399 bgp_show_type_cidr_only,
400 bgp_show_type_prefix_longer,
401 bgp_show_type_community_all,
402 bgp_show_type_community,
403 bgp_show_type_community_exact,
404 bgp_show_type_community_list,
405 bgp_show_type_community_list_exact
406};
407
paul94f2b392005-06-28 12:44:16 +0000408static int
paul718e3742002-12-13 20:15:29 +0000409bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
410 void *output_arg, int tags)
411{
412 struct bgp *bgp;
413 struct bgp_table *table;
414 struct bgp_node *rn;
415 struct bgp_node *rm;
416 struct bgp_info *ri;
417 int rd_header;
418 int header = 1;
419 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
420 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
421
422 bgp = bgp_get_default ();
423 if (bgp == NULL)
424 {
425 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
426 return CMD_WARNING;
427 }
428
429 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
430 {
431 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
432 continue;
433
434 if ((table = rn->info) != NULL)
435 {
436 rd_header = 1;
437
438 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
439 for (ri = rm->info; ri; ri = ri->next)
440 {
441 if (type == bgp_show_type_neighbor)
442 {
443 union sockunion *su = output_arg;
444
445 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
446 continue;
447 }
448 if (header)
449 {
450 if (tags)
451 vty_out (vty, v4_header_tag, VTY_NEWLINE);
452 else
453 {
454 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
455 inet_ntoa (bgp->router_id), VTY_NEWLINE);
456 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
457 VTY_NEWLINE);
458 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
459 VTY_NEWLINE, VTY_NEWLINE);
460 vty_out (vty, v4_header, VTY_NEWLINE);
461 }
462 header = 0;
463 }
464
465 if (rd_header)
466 {
467 u_int16_t type;
468 struct rd_as rd_as;
469 struct rd_ip rd_ip;
470 u_char *pnt;
471
472 pnt = rn->p.u.val;
473
474 /* Decode RD type. */
475 type = decode_rd_type (pnt);
476 /* Decode RD value. */
477 if (type == RD_TYPE_AS)
478 decode_rd_as (pnt + 2, &rd_as);
479 else if (type == RD_TYPE_IP)
480 decode_rd_ip (pnt + 2, &rd_ip);
481
482 vty_out (vty, "Route Distinguisher: ");
483
484 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400485 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000486 else if (type == RD_TYPE_IP)
487 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
488
489 vty_out (vty, "%s", VTY_NEWLINE);
490 rd_header = 0;
491 }
492 if (tags)
493 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
494 else
495 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
496 }
497 }
498 }
499 return CMD_SUCCESS;
500}
501
502DEFUN (show_ip_bgp_vpnv4_all,
503 show_ip_bgp_vpnv4_all_cmd,
504 "show ip bgp vpnv4 all",
505 SHOW_STR
506 IP_STR
507 BGP_STR
508 "Display VPNv4 NLRI specific information\n"
509 "Display information about all VPNv4 NLRIs\n")
510{
511 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
512}
513
514DEFUN (show_ip_bgp_vpnv4_rd,
515 show_ip_bgp_vpnv4_rd_cmd,
516 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
517 SHOW_STR
518 IP_STR
519 BGP_STR
520 "Display VPNv4 NLRI specific information\n"
521 "Display information for a route distinguisher\n"
522 "VPN Route Distinguisher\n")
523{
524 int ret;
525 struct prefix_rd prd;
526
527 ret = str2prefix_rd (argv[0], &prd);
528 if (! ret)
529 {
530 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
531 return CMD_WARNING;
532 }
533 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
534}
535
536DEFUN (show_ip_bgp_vpnv4_all_tags,
537 show_ip_bgp_vpnv4_all_tags_cmd,
538 "show ip bgp vpnv4 all tags",
539 SHOW_STR
540 IP_STR
541 BGP_STR
542 "Display VPNv4 NLRI specific information\n"
543 "Display information about all VPNv4 NLRIs\n"
544 "Display BGP tags for prefixes\n")
545{
546 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
547}
548
549DEFUN (show_ip_bgp_vpnv4_rd_tags,
550 show_ip_bgp_vpnv4_rd_tags_cmd,
551 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
552 SHOW_STR
553 IP_STR
554 BGP_STR
555 "Display VPNv4 NLRI specific information\n"
556 "Display information for a route distinguisher\n"
557 "VPN Route Distinguisher\n"
558 "Display BGP tags for prefixes\n")
559{
560 int ret;
561 struct prefix_rd prd;
562
563 ret = str2prefix_rd (argv[0], &prd);
564 if (! ret)
565 {
566 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
567 return CMD_WARNING;
568 }
569 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
570}
571
572DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
573 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
574 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
575 SHOW_STR
576 IP_STR
577 BGP_STR
578 "Display VPNv4 NLRI specific information\n"
579 "Display information about all VPNv4 NLRIs\n"
580 "Detailed information on TCP and BGP neighbor connections\n"
581 "Neighbor to display information about\n"
582 "Display routes learned from neighbor\n")
583{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200584 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000585 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200586 int ret;
587
588 ret = str2sockunion (argv[0], &su);
589 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000590 {
591 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200592 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000593 }
594
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200595 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000596 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
597 {
598 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
599 return CMD_WARNING;
600 }
601
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200602 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000603}
604
605DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
606 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
607 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
608 SHOW_STR
609 IP_STR
610 BGP_STR
611 "Display VPNv4 NLRI specific information\n"
612 "Display information for a route distinguisher\n"
613 "VPN Route Distinguisher\n"
614 "Detailed information on TCP and BGP neighbor connections\n"
615 "Neighbor to display information about\n"
616 "Display routes learned from neighbor\n")
617{
618 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200619 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000620 struct peer *peer;
621 struct prefix_rd prd;
622
623 ret = str2prefix_rd (argv[0], &prd);
624 if (! ret)
625 {
626 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
627 return CMD_WARNING;
628 }
629
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200630 ret = str2sockunion (argv[1], &su);
631 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000632 {
633 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200634 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000635 }
636
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200637 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000638 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
639 {
640 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
641 return CMD_WARNING;
642 }
643
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200644 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000645}
646
647DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
648 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
649 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
650 SHOW_STR
651 IP_STR
652 BGP_STR
653 "Display VPNv4 NLRI specific information\n"
654 "Display information about all VPNv4 NLRIs\n"
655 "Detailed information on TCP and BGP neighbor connections\n"
656 "Neighbor to display information about\n"
657 "Display the routes advertised to a BGP neighbor\n")
658{
659 int ret;
660 struct peer *peer;
661 union sockunion su;
662
663 ret = str2sockunion (argv[0], &su);
664 if (ret < 0)
665 {
666 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
667 return CMD_WARNING;
668 }
669 peer = peer_lookup (NULL, &su);
670 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
671 {
672 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
673 return CMD_WARNING;
674 }
675
676 return show_adj_route_vpn (vty, peer, NULL);
677}
678
679DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
680 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
681 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
682 SHOW_STR
683 IP_STR
684 BGP_STR
685 "Display VPNv4 NLRI specific information\n"
686 "Display information for a route distinguisher\n"
687 "VPN Route Distinguisher\n"
688 "Detailed information on TCP and BGP neighbor connections\n"
689 "Neighbor to display information about\n"
690 "Display the routes advertised to a BGP neighbor\n")
691{
692 int ret;
693 struct peer *peer;
694 struct prefix_rd prd;
695 union sockunion su;
696
697 ret = str2sockunion (argv[1], &su);
698 if (ret < 0)
699 {
700 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
701 return CMD_WARNING;
702 }
703 peer = peer_lookup (NULL, &su);
704 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
705 {
706 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
707 return CMD_WARNING;
708 }
709
710 ret = str2prefix_rd (argv[0], &prd);
711 if (! ret)
712 {
713 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
714 return CMD_WARNING;
715 }
716
717 return show_adj_route_vpn (vty, peer, &prd);
718}
719
720void
paul94f2b392005-06-28 12:44:16 +0000721bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000722{
723 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
724 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
725
726
727 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
728 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
729 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
730 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
731 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
732 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
733 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
734 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
735
736 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
737 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
738 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
739 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
740 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
741 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
742 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
743 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
744}