Line data Source code
1 : /* MPLS-VPN
2 : Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 :
4 : This file is part of GNU Zebra.
5 :
6 : GNU Zebra is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU General Public License as published by the
8 : Free Software Foundation; either version 2, or (at your option) any
9 : later version.
10 :
11 : GNU Zebra is distributed in the hope that it will be useful, but
12 : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GNU Zebra; see the file COPYING. If not, write to the Free
18 : Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 : 02111-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 :
35 : static u_int16_t
36 0 : decode_rd_type (u_char *pnt)
37 : {
38 : u_int16_t v;
39 :
40 0 : v = ((u_int16_t) *pnt++ << 8);
41 0 : v |= (u_int16_t) *pnt;
42 0 : return v;
43 : }
44 :
45 : u_int32_t
46 0 : decode_label (u_char *pnt)
47 : {
48 : u_int32_t l;
49 :
50 0 : l = ((u_int32_t) *pnt++ << 12);
51 0 : l |= (u_int32_t) *pnt++ << 4;
52 0 : l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
53 0 : return l;
54 : }
55 :
56 : static void
57 0 : decode_rd_as (u_char *pnt, struct rd_as *rd_as)
58 : {
59 0 : rd_as->as = (u_int16_t) *pnt++ << 8;
60 0 : rd_as->as |= (u_int16_t) *pnt++;
61 :
62 0 : rd_as->val = ((u_int32_t) *pnt++ << 24);
63 0 : rd_as->val |= ((u_int32_t) *pnt++ << 16);
64 0 : rd_as->val |= ((u_int32_t) *pnt++ << 8);
65 0 : rd_as->val |= (u_int32_t) *pnt;
66 0 : }
67 :
68 : static void
69 0 : decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
70 : {
71 0 : memcpy (&rd_ip->ip, pnt, 4);
72 0 : pnt += 4;
73 :
74 0 : rd_ip->val = ((u_int16_t) *pnt++ << 8);
75 0 : rd_ip->val |= (u_int16_t) *pnt;
76 0 : }
77 :
78 : int
79 0 : bgp_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 0 : if (peer->status != Established)
96 0 : return 0;
97 :
98 : /* Make prefix_rd */
99 0 : prd.family = AF_UNSPEC;
100 0 : prd.prefixlen = 64;
101 :
102 0 : pnt = packet->nlri;
103 0 : lim = pnt + packet->length;
104 :
105 0 : for (; pnt < lim; pnt += psize)
106 : {
107 : /* Clear prefix structure. */
108 0 : memset (&p, 0, sizeof (struct prefix));
109 :
110 : /* Fetch prefix length. */
111 0 : prefixlen = *pnt++;
112 0 : p.family = AF_INET;
113 0 : psize = PSIZE (prefixlen);
114 :
115 0 : if (prefixlen < 88)
116 : {
117 0 : zlog_err ("prefix length is less than 88: %d", prefixlen);
118 0 : return -1;
119 : }
120 :
121 0 : label = decode_label (pnt);
122 :
123 : /* Copyr label to prefix. */
124 0 : tagpnt = pnt;;
125 :
126 : /* Copy routing distinguisher to rd. */
127 0 : memcpy (&prd.val, pnt + 3, 8);
128 :
129 : /* Decode RD type. */
130 0 : type = decode_rd_type (pnt + 3);
131 :
132 : /* Decode RD value. */
133 0 : if (type == RD_TYPE_AS)
134 0 : decode_rd_as (pnt + 5, &rd_as);
135 0 : else if (type == RD_TYPE_IP)
136 0 : decode_rd_ip (pnt + 5, &rd_ip);
137 : else
138 : {
139 0 : zlog_err ("Invalid RD type %d", type);
140 0 : return -1;
141 : }
142 :
143 0 : p.prefixlen = prefixlen - 88;
144 0 : 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 0 : if (pnt + psize > lim)
156 0 : return -1;
157 :
158 0 : if (attr)
159 0 : bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
160 : ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
161 : else
162 0 : 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 0 : if (pnt != lim)
168 0 : return -1;
169 :
170 0 : return 0;
171 : }
172 :
173 : int
174 0 : str2prefix_rd (const char *str, struct prefix_rd *prd)
175 : {
176 : int ret;
177 : char *p;
178 : char *p2;
179 : struct stream *s;
180 : char *half;
181 : struct in_addr addr;
182 :
183 0 : s = stream_new (8);
184 :
185 0 : prd->family = AF_UNSPEC;
186 0 : prd->prefixlen = 64;
187 :
188 0 : p = strchr (str, ':');
189 0 : if (! p)
190 0 : return 0;
191 :
192 0 : if (! all_digit (p + 1))
193 0 : return 0;
194 :
195 0 : half = XMALLOC (MTYPE_TMP, (p - str) + 1);
196 0 : memcpy (half, str, (p - str));
197 0 : half[p - str] = '\0';
198 :
199 0 : p2 = strchr (str, '.');
200 :
201 0 : if (! p2)
202 : {
203 0 : if (! all_digit (half))
204 : {
205 0 : XFREE (MTYPE_TMP, half);
206 0 : return 0;
207 : }
208 0 : stream_putw (s, RD_TYPE_AS);
209 0 : stream_putw (s, atoi (half));
210 0 : stream_putl (s, atol (p + 1));
211 : }
212 : else
213 : {
214 0 : ret = inet_aton (half, &addr);
215 0 : if (! ret)
216 : {
217 0 : XFREE (MTYPE_TMP, half);
218 0 : return 0;
219 : }
220 0 : stream_putw (s, RD_TYPE_IP);
221 0 : stream_put_in_addr (s, &addr);
222 0 : stream_putw (s, atol (p + 1));
223 : }
224 0 : memcpy (prd->val, s->data, 8);
225 :
226 0 : return 1;
227 : }
228 :
229 : int
230 0 : str2tag (const char *str, u_char *tag)
231 : {
232 : unsigned long l;
233 : char *endptr;
234 : u_int32_t t;
235 :
236 0 : if (*str == '-')
237 0 : return 0;
238 :
239 0 : errno = 0;
240 0 : l = strtoul (str, &endptr, 10);
241 :
242 0 : if (*endptr != '\0' || errno || l > UINT32_MAX)
243 0 : return 0;
244 :
245 0 : t = (u_int32_t) l;
246 :
247 0 : tag[0] = (u_char)(t >> 12);
248 0 : tag[1] = (u_char)(t >> 4);
249 0 : tag[2] = (u_char)(t << 4);
250 :
251 0 : return 1;
252 : }
253 :
254 : char *
255 0 : prefix_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 0 : if (size < RD_ADDRSTRLEN)
263 0 : return NULL;
264 :
265 0 : pnt = prd->val;
266 :
267 0 : type = decode_rd_type (pnt);
268 :
269 0 : if (type == RD_TYPE_AS)
270 : {
271 0 : decode_rd_as (pnt + 2, &rd_as);
272 0 : snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
273 0 : return buf;
274 : }
275 0 : else if (type == RD_TYPE_IP)
276 : {
277 0 : decode_rd_ip (pnt + 2, &rd_ip);
278 0 : snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
279 0 : return buf;
280 : }
281 :
282 0 : return NULL;
283 : }
284 :
285 : /* For testing purpose, static route of MPLS-VPN. */
286 0 : DEFUN (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 0 : return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
297 : }
298 :
299 : /* For testing purpose, static route of MPLS-VPN. */
300 0 : DEFUN (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 0 : return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
312 : }
313 :
314 : static int
315 0 : show_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 0 : int header = 1;
324 0 : char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
325 :
326 0 : bgp = bgp_get_default ();
327 0 : if (bgp == NULL)
328 : {
329 0 : vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
330 0 : return CMD_WARNING;
331 : }
332 :
333 0 : for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
334 0 : rn = bgp_route_next (rn))
335 : {
336 0 : if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
337 0 : continue;
338 :
339 0 : if ((table = rn->info) != NULL)
340 : {
341 0 : rd_header = 1;
342 :
343 0 : for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
344 0 : if ((attr = rm->info) != NULL)
345 : {
346 0 : if (header)
347 : {
348 0 : vty_out (vty, "BGP table version is 0, local router ID is %s%s",
349 0 : inet_ntoa (bgp->router_id), VTY_NEWLINE);
350 0 : vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
351 0 : VTY_NEWLINE);
352 0 : vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
353 0 : VTY_NEWLINE, VTY_NEWLINE);
354 0 : vty_out (vty, v4_header, VTY_NEWLINE);
355 0 : header = 0;
356 : }
357 :
358 0 : 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 0 : pnt = rn->p.u.val;
366 :
367 : /* Decode RD type. */
368 0 : type = decode_rd_type (pnt);
369 : /* Decode RD value. */
370 0 : if (type == RD_TYPE_AS)
371 0 : decode_rd_as (pnt + 2, &rd_as);
372 0 : else if (type == RD_TYPE_IP)
373 0 : decode_rd_ip (pnt + 2, &rd_ip);
374 :
375 0 : vty_out (vty, "Route Distinguisher: ");
376 :
377 0 : if (type == RD_TYPE_AS)
378 0 : vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
379 0 : else if (type == RD_TYPE_IP)
380 0 : vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
381 :
382 0 : vty_out (vty, "%s", VTY_NEWLINE);
383 0 : rd_header = 0;
384 : }
385 0 : route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
386 : }
387 : }
388 : }
389 0 : return CMD_SUCCESS;
390 : }
391 :
392 : enum 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 :
408 : static int
409 0 : bgp_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 0 : int header = 1;
419 0 : char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
420 0 : char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
421 :
422 0 : bgp = bgp_get_default ();
423 0 : if (bgp == NULL)
424 : {
425 0 : vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
426 0 : return CMD_WARNING;
427 : }
428 :
429 0 : for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
430 : {
431 0 : if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
432 0 : continue;
433 :
434 0 : if ((table = rn->info) != NULL)
435 : {
436 0 : rd_header = 1;
437 :
438 0 : for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
439 0 : for (ri = rm->info; ri; ri = ri->next)
440 : {
441 0 : if (type == bgp_show_type_neighbor)
442 : {
443 0 : union sockunion *su = output_arg;
444 :
445 0 : if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
446 0 : continue;
447 : }
448 0 : if (header)
449 : {
450 0 : if (tags)
451 0 : vty_out (vty, v4_header_tag, VTY_NEWLINE);
452 : else
453 : {
454 0 : vty_out (vty, "BGP table version is 0, local router ID is %s%s",
455 0 : inet_ntoa (bgp->router_id), VTY_NEWLINE);
456 0 : vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
457 0 : VTY_NEWLINE);
458 0 : vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
459 0 : VTY_NEWLINE, VTY_NEWLINE);
460 0 : vty_out (vty, v4_header, VTY_NEWLINE);
461 : }
462 0 : header = 0;
463 : }
464 :
465 0 : 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 0 : pnt = rn->p.u.val;
473 :
474 : /* Decode RD type. */
475 0 : type = decode_rd_type (pnt);
476 : /* Decode RD value. */
477 0 : if (type == RD_TYPE_AS)
478 0 : decode_rd_as (pnt + 2, &rd_as);
479 0 : else if (type == RD_TYPE_IP)
480 0 : decode_rd_ip (pnt + 2, &rd_ip);
481 :
482 0 : vty_out (vty, "Route Distinguisher: ");
483 :
484 0 : if (type == RD_TYPE_AS)
485 0 : vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
486 0 : else if (type == RD_TYPE_IP)
487 0 : vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
488 :
489 0 : vty_out (vty, "%s", VTY_NEWLINE);
490 0 : rd_header = 0;
491 : }
492 0 : if (tags)
493 0 : route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
494 : else
495 0 : route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
496 : }
497 : }
498 : }
499 0 : return CMD_SUCCESS;
500 : }
501 :
502 0 : DEFUN (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 0 : return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
512 : }
513 :
514 0 : DEFUN (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 0 : ret = str2prefix_rd (argv[0], &prd);
528 0 : if (! ret)
529 : {
530 0 : vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
531 0 : return CMD_WARNING;
532 : }
533 0 : return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
534 : }
535 :
536 0 : DEFUN (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 0 : return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
547 : }
548 :
549 0 : DEFUN (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 0 : ret = str2prefix_rd (argv[0], &prd);
564 0 : if (! ret)
565 : {
566 0 : vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
567 0 : return CMD_WARNING;
568 : }
569 0 : return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
570 : }
571 :
572 0 : DEFUN (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 : {
584 : union sockunion su;
585 : struct peer *peer;
586 : int ret;
587 :
588 0 : ret = str2sockunion (argv[0], &su);
589 0 : if (ret < 0)
590 : {
591 0 : vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
592 0 : return CMD_WARNING;
593 : }
594 :
595 0 : peer = peer_lookup (NULL, &su);
596 0 : if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
597 : {
598 0 : vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
599 0 : return CMD_WARNING;
600 : }
601 :
602 0 : return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
603 : }
604 :
605 0 : DEFUN (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;
619 : union sockunion su;
620 : struct peer *peer;
621 : struct prefix_rd prd;
622 :
623 0 : ret = str2prefix_rd (argv[0], &prd);
624 0 : if (! ret)
625 : {
626 0 : vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
627 0 : return CMD_WARNING;
628 : }
629 :
630 0 : ret = str2sockunion (argv[1], &su);
631 0 : if (ret < 0)
632 : {
633 0 : vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
634 0 : return CMD_WARNING;
635 : }
636 :
637 0 : peer = peer_lookup (NULL, &su);
638 0 : if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
639 : {
640 0 : vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
641 0 : return CMD_WARNING;
642 : }
643 :
644 0 : return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
645 : }
646 :
647 0 : DEFUN (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 0 : ret = str2sockunion (argv[0], &su);
664 0 : if (ret < 0)
665 : {
666 0 : vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
667 0 : return CMD_WARNING;
668 : }
669 0 : peer = peer_lookup (NULL, &su);
670 0 : if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
671 : {
672 0 : vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
673 0 : return CMD_WARNING;
674 : }
675 :
676 0 : return show_adj_route_vpn (vty, peer, NULL);
677 : }
678 :
679 0 : DEFUN (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 0 : ret = str2sockunion (argv[1], &su);
698 0 : if (ret < 0)
699 : {
700 0 : vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
701 0 : return CMD_WARNING;
702 : }
703 0 : peer = peer_lookup (NULL, &su);
704 0 : if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
705 : {
706 0 : vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
707 0 : return CMD_WARNING;
708 : }
709 :
710 0 : ret = str2prefix_rd (argv[0], &prd);
711 0 : if (! ret)
712 : {
713 0 : vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
714 0 : return CMD_WARNING;
715 : }
716 :
717 0 : return show_adj_route_vpn (vty, peer, &prd);
718 : }
719 :
720 : void
721 0 : bgp_mplsvpn_init (void)
722 : {
723 0 : install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
724 0 : install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
725 :
726 :
727 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
728 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
729 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
730 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
731 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
732 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
733 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
734 0 : install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
735 :
736 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
737 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
738 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
739 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
740 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
741 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
742 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
743 0 : install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
744 0 : }
|