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