blob: e922665139273c3e743d8bb87bb2f913d29e0f0d [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"
Donald Sharp04907292016-01-07 10:03:01 -050028#include "filter.h"
paul718e3742002-12-13 20:15:29 +000029
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_table.h"
32#include "bgpd/bgp_route.h"
33#include "bgpd/bgp_attr.h"
34#include "bgpd/bgp_mplsvpn.h"
35
paul94f2b392005-06-28 12:44:16 +000036static u_int16_t
paul718e3742002-12-13 20:15:29 +000037decode_rd_type (u_char *pnt)
38{
39 u_int16_t v;
40
41 v = ((u_int16_t) *pnt++ << 8);
42 v |= (u_int16_t) *pnt;
43 return v;
44}
45
46u_int32_t
47decode_label (u_char *pnt)
48{
49 u_int32_t l;
50
51 l = ((u_int32_t) *pnt++ << 12);
52 l |= (u_int32_t) *pnt++ << 4;
53 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
54 return l;
55}
56
Lou Bergera03bd162016-01-12 13:41:54 -050057/* type == RD_TYPE_AS */
paul94f2b392005-06-28 12:44:16 +000058static void
paul718e3742002-12-13 20:15:29 +000059decode_rd_as (u_char *pnt, struct rd_as *rd_as)
60{
61 rd_as->as = (u_int16_t) *pnt++ << 8;
62 rd_as->as |= (u_int16_t) *pnt++;
63
64 rd_as->val = ((u_int32_t) *pnt++ << 24);
65 rd_as->val |= ((u_int32_t) *pnt++ << 16);
66 rd_as->val |= ((u_int32_t) *pnt++ << 8);
67 rd_as->val |= (u_int32_t) *pnt;
68}
69
Lou Bergera03bd162016-01-12 13:41:54 -050070/* type == RD_TYPE_AS4 */
71static void
72decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
73{
74 rd_as->as = (u_int32_t) *pnt++ << 24;
75 rd_as->as |= (u_int32_t) *pnt++ << 16;
76 rd_as->as |= (u_int32_t) *pnt++ << 8;
77 rd_as->as |= (u_int32_t) *pnt++;
78
79 rd_as->val = ((u_int16_t) *pnt++ << 8);
80 rd_as->val |= (u_int16_t) *pnt;
81}
82
83/* type == RD_TYPE_IP */
paul94f2b392005-06-28 12:44:16 +000084static void
paul718e3742002-12-13 20:15:29 +000085decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
86{
87 memcpy (&rd_ip->ip, pnt, 4);
88 pnt += 4;
89
90 rd_ip->val = ((u_int16_t) *pnt++ << 8);
91 rd_ip->val |= (u_int16_t) *pnt;
92}
93
paul718e3742002-12-13 20:15:29 +000094int
Lou Berger9da04bc2016-01-12 13:41:55 -050095bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
96 struct bgp_nlri *packet)
paul718e3742002-12-13 20:15:29 +000097{
98 u_char *pnt;
99 u_char *lim;
100 struct prefix p;
Lou Berger9da04bc2016-01-12 13:41:55 -0500101 int psize = 0;
paul718e3742002-12-13 20:15:29 +0000102 int prefixlen;
paul718e3742002-12-13 20:15:29 +0000103 u_int16_t type;
104 struct rd_as rd_as;
105 struct rd_ip rd_ip;
106 struct prefix_rd prd;
107 u_char *tagpnt;
108
109 /* Check peer status. */
110 if (peer->status != Established)
111 return 0;
112
113 /* Make prefix_rd */
114 prd.family = AF_UNSPEC;
115 prd.prefixlen = 64;
116
117 pnt = packet->nlri;
118 lim = pnt + packet->length;
119
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000120#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
paul718e3742002-12-13 20:15:29 +0000121 for (; pnt < lim; pnt += psize)
122 {
123 /* Clear prefix structure. */
124 memset (&p, 0, sizeof (struct prefix));
125
126 /* Fetch prefix length. */
127 prefixlen = *pnt++;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000128 p.family = afi2family (packet->afi);
paul718e3742002-12-13 20:15:29 +0000129 psize = PSIZE (prefixlen);
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000130
131 /* sanity check against packet data */
132 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8 || (pnt + psize) > lim)
133 {
134 zlog_err ("prefix length (%d) is less than 88"
135 " or larger than received (%u)",
136 prefixlen, (uint)(lim-pnt));
137 return -1;
138 }
139
140 /* sanity check against storage for the IP address portion */
141 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
142 {
143 zlog_err ("prefix length (%d) exceeds prefix storage (%zu)",
144 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
145 return -1;
146 }
147
148 /* Sanity check against max bitlen of the address family */
149 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
150 {
151 zlog_err ("prefix length (%d) exceeds family (%u) max byte length (%u)",
152 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
153 p.family, prefix_blen (&p));
154 return -1;
155
156 }
157
paul718e3742002-12-13 20:15:29 +0000158 /* Copyr label to prefix. */
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000159 tagpnt = pnt;
paul718e3742002-12-13 20:15:29 +0000160
161 /* Copy routing distinguisher to rd. */
162 memcpy (&prd.val, pnt + 3, 8);
163
164 /* Decode RD type. */
165 type = decode_rd_type (pnt + 3);
166
Lou Bergera03bd162016-01-12 13:41:54 -0500167 switch (type)
168 {
169 case RD_TYPE_AS:
170 decode_rd_as (pnt + 5, &rd_as);
171 break;
172
173 case RD_TYPE_AS4:
174 decode_rd_as4 (pnt + 5, &rd_as);
175 break;
176
177 case RD_TYPE_IP:
178 decode_rd_ip (pnt + 5, &rd_ip);
179 break;
180
Lou Berger050defe2016-01-12 13:41:59 -0500181 default:
182 zlog_err ("Unknown RD type %d", type);
183 break; /* just report */
184 }
paul718e3742002-12-13 20:15:29 +0000185
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000186 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
187 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
188 psize - VPN_PREFIXLEN_MIN_BYTES);
paul718e3742002-12-13 20:15:29 +0000189
paul718e3742002-12-13 20:15:29 +0000190 if (attr)
Lou Berger9da04bc2016-01-12 13:41:55 -0500191 bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
192 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000193 else
Lou Berger9da04bc2016-01-12 13:41:55 -0500194 bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
195 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
paul718e3742002-12-13 20:15:29 +0000196 }
paul718e3742002-12-13 20:15:29 +0000197 /* Packet length consistency check. */
198 if (pnt != lim)
199 return -1;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000200
paul718e3742002-12-13 20:15:29 +0000201 return 0;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000202#undef VPN_PREFIXLEN_MIN_BYTES
paul718e3742002-12-13 20:15:29 +0000203}
204
205int
paulfd79ac92004-10-13 05:06:08 +0000206str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000207{
Lou Berger056f3762013-04-10 12:30:04 -0700208 int ret; /* ret of called functions */
209 int lret; /* local ret, of this func */
paul5228ad22004-06-04 17:58:18 +0000210 char *p;
211 char *p2;
Lou Berger056f3762013-04-10 12:30:04 -0700212 struct stream *s = NULL;
213 char *half = NULL;
paul718e3742002-12-13 20:15:29 +0000214 struct in_addr addr;
215
216 s = stream_new (8);
217
218 prd->family = AF_UNSPEC;
219 prd->prefixlen = 64;
220
Lou Berger056f3762013-04-10 12:30:04 -0700221 lret = 0;
paul718e3742002-12-13 20:15:29 +0000222 p = strchr (str, ':');
223 if (! p)
Lou Berger056f3762013-04-10 12:30:04 -0700224 goto out;
paul718e3742002-12-13 20:15:29 +0000225
226 if (! all_digit (p + 1))
Lou Berger056f3762013-04-10 12:30:04 -0700227 goto out;
paul718e3742002-12-13 20:15:29 +0000228
229 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
230 memcpy (half, str, (p - str));
231 half[p - str] = '\0';
232
233 p2 = strchr (str, '.');
234
235 if (! p2)
236 {
237 if (! all_digit (half))
Lou Berger056f3762013-04-10 12:30:04 -0700238 goto out;
239
paul718e3742002-12-13 20:15:29 +0000240 stream_putw (s, RD_TYPE_AS);
241 stream_putw (s, atoi (half));
242 stream_putl (s, atol (p + 1));
243 }
244 else
245 {
246 ret = inet_aton (half, &addr);
247 if (! ret)
Lou Berger056f3762013-04-10 12:30:04 -0700248 goto out;
249
paul718e3742002-12-13 20:15:29 +0000250 stream_putw (s, RD_TYPE_IP);
251 stream_put_in_addr (s, &addr);
252 stream_putw (s, atol (p + 1));
253 }
254 memcpy (prd->val, s->data, 8);
Lou Berger056f3762013-04-10 12:30:04 -0700255 lret = 1;
paul718e3742002-12-13 20:15:29 +0000256
Lou Berger056f3762013-04-10 12:30:04 -0700257out:
258 if (s)
259 stream_free (s);
260 if (half)
261 XFREE(MTYPE_TMP, half);
262 return lret;
paul718e3742002-12-13 20:15:29 +0000263}
264
265int
paulfd79ac92004-10-13 05:06:08 +0000266str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000267{
paulfd79ac92004-10-13 05:06:08 +0000268 unsigned long l;
269 char *endptr;
270 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000271
Ulrich Weber664711c2011-12-21 02:24:11 +0400272 if (*str == '-')
273 return 0;
paulfd79ac92004-10-13 05:06:08 +0000274
Ulrich Weber664711c2011-12-21 02:24:11 +0400275 errno = 0;
276 l = strtoul (str, &endptr, 10);
277
278 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000279 return 0;
paul718e3742002-12-13 20:15:29 +0000280
paulfd79ac92004-10-13 05:06:08 +0000281 t = (u_int32_t) l;
282
283 tag[0] = (u_char)(t >> 12);
284 tag[1] = (u_char)(t >> 4);
285 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000286
287 return 1;
288}
289
290char *
291prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
292{
293 u_char *pnt;
294 u_int16_t type;
295 struct rd_as rd_as;
296 struct rd_ip rd_ip;
297
298 if (size < RD_ADDRSTRLEN)
299 return NULL;
300
301 pnt = prd->val;
302
303 type = decode_rd_type (pnt);
304
305 if (type == RD_TYPE_AS)
306 {
307 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400308 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000309 return buf;
310 }
Lou Bergera03bd162016-01-12 13:41:54 -0500311 else if (type == RD_TYPE_AS4)
312 {
313 decode_rd_as4 (pnt + 2, &rd_as);
314 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
315 return buf;
316 }
paul718e3742002-12-13 20:15:29 +0000317 else if (type == RD_TYPE_IP)
318 {
319 decode_rd_ip (pnt + 2, &rd_ip);
320 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
321 return buf;
322 }
paul718e3742002-12-13 20:15:29 +0000323 return NULL;
324}
325
326/* For testing purpose, static route of MPLS-VPN. */
327DEFUN (vpnv4_network,
328 vpnv4_network_cmd,
329 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
330 "Specify a network to announce via BGP\n"
331 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
332 "Specify Route Distinguisher\n"
333 "VPN Route Distinguisher\n"
334 "BGP tag\n"
335 "tag value\n")
336{
Lou Bergera76d9ca2016-01-12 13:41:53 -0500337 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
338}
339
340DEFUN (vpnv4_network_route_map,
341 vpnv4_network_route_map_cmd,
342 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
343 "Specify a network to announce via BGP\n"
344 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
345 "Specify Route Distinguisher\n"
346 "VPN Route Distinguisher\n"
347 "BGP tag\n"
348 "tag value\n"
349 "route map\n"
350 "route map name\n")
351{
352 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000353}
354
355/* For testing purpose, static route of MPLS-VPN. */
356DEFUN (no_vpnv4_network,
357 no_vpnv4_network_cmd,
358 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
359 NO_STR
360 "Specify a network to announce via BGP\n"
361 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
362 "Specify Route Distinguisher\n"
363 "VPN Route Distinguisher\n"
364 "BGP tag\n"
365 "tag value\n")
366{
Lou Bergera76d9ca2016-01-12 13:41:53 -0500367 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
paul718e3742002-12-13 20:15:29 +0000368}
369
paul94f2b392005-06-28 12:44:16 +0000370static int
paul718e3742002-12-13 20:15:29 +0000371show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
372{
373 struct bgp *bgp;
374 struct bgp_table *table;
375 struct bgp_node *rn;
376 struct bgp_node *rm;
377 struct attr *attr;
378 int rd_header;
379 int header = 1;
380 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
381
382 bgp = bgp_get_default ();
383 if (bgp == NULL)
384 {
385 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
386 return CMD_WARNING;
387 }
388
389 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
390 rn = bgp_route_next (rn))
391 {
392 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
393 continue;
394
395 if ((table = rn->info) != NULL)
396 {
397 rd_header = 1;
398
399 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
400 if ((attr = rm->info) != NULL)
401 {
402 if (header)
403 {
404 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
405 inet_ntoa (bgp->router_id), VTY_NEWLINE);
406 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
407 VTY_NEWLINE);
408 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
409 VTY_NEWLINE, VTY_NEWLINE);
410 vty_out (vty, v4_header, VTY_NEWLINE);
411 header = 0;
412 }
413
414 if (rd_header)
415 {
416 u_int16_t type;
417 struct rd_as rd_as;
418 struct rd_ip rd_ip;
419 u_char *pnt;
420
421 pnt = rn->p.u.val;
422
423 /* Decode RD type. */
424 type = decode_rd_type (pnt);
425 /* Decode RD value. */
426 if (type == RD_TYPE_AS)
427 decode_rd_as (pnt + 2, &rd_as);
Lou Bergera03bd162016-01-12 13:41:54 -0500428 else if (type == RD_TYPE_AS4)
429 decode_rd_as4 (pnt + 2, &rd_as);
paul718e3742002-12-13 20:15:29 +0000430 else if (type == RD_TYPE_IP)
431 decode_rd_ip (pnt + 2, &rd_ip);
432
433 vty_out (vty, "Route Distinguisher: ");
434
435 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400436 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
Lou Bergera03bd162016-01-12 13:41:54 -0500437 else if (type == RD_TYPE_AS4)
438 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000439 else if (type == RD_TYPE_IP)
440 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
441
442 vty_out (vty, "%s", VTY_NEWLINE);
443 rd_header = 0;
444 }
445 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
446 }
447 }
448 }
449 return CMD_SUCCESS;
450}
451
452enum bgp_show_type
453{
454 bgp_show_type_normal,
455 bgp_show_type_regexp,
456 bgp_show_type_prefix_list,
457 bgp_show_type_filter_list,
458 bgp_show_type_neighbor,
459 bgp_show_type_cidr_only,
460 bgp_show_type_prefix_longer,
461 bgp_show_type_community_all,
462 bgp_show_type_community,
463 bgp_show_type_community_exact,
464 bgp_show_type_community_list,
465 bgp_show_type_community_list_exact
466};
467
paul94f2b392005-06-28 12:44:16 +0000468static int
paul718e3742002-12-13 20:15:29 +0000469bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
470 void *output_arg, int tags)
471{
Lou Berger9da04bc2016-01-12 13:41:55 -0500472 afi_t afi = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000473 struct bgp *bgp;
474 struct bgp_table *table;
475 struct bgp_node *rn;
476 struct bgp_node *rm;
477 struct bgp_info *ri;
478 int rd_header;
479 int header = 1;
480 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
481 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
482
483 bgp = bgp_get_default ();
484 if (bgp == NULL)
485 {
486 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
487 return CMD_WARNING;
488 }
489
Lou Berger9da04bc2016-01-12 13:41:55 -0500490 if ((afi != AFI_IP) && (afi != AFI_IP6))
491 {
492 vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
493 return CMD_WARNING;
494 }
495
496 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
paul718e3742002-12-13 20:15:29 +0000497 {
498 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
499 continue;
500
501 if ((table = rn->info) != NULL)
502 {
503 rd_header = 1;
504
505 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
506 for (ri = rm->info; ri; ri = ri->next)
507 {
508 if (type == bgp_show_type_neighbor)
509 {
510 union sockunion *su = output_arg;
511
512 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
513 continue;
514 }
515 if (header)
516 {
517 if (tags)
518 vty_out (vty, v4_header_tag, VTY_NEWLINE);
519 else
520 {
521 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
522 inet_ntoa (bgp->router_id), VTY_NEWLINE);
523 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
524 VTY_NEWLINE);
525 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
526 VTY_NEWLINE, VTY_NEWLINE);
527 vty_out (vty, v4_header, VTY_NEWLINE);
528 }
529 header = 0;
530 }
531
532 if (rd_header)
533 {
534 u_int16_t type;
535 struct rd_as rd_as;
536 struct rd_ip rd_ip;
537 u_char *pnt;
538
539 pnt = rn->p.u.val;
540
541 /* Decode RD type. */
542 type = decode_rd_type (pnt);
543 /* Decode RD value. */
544 if (type == RD_TYPE_AS)
545 decode_rd_as (pnt + 2, &rd_as);
Lou Bergera03bd162016-01-12 13:41:54 -0500546 else if (type == RD_TYPE_AS4)
547 decode_rd_as4 (pnt + 2, &rd_as);
paul718e3742002-12-13 20:15:29 +0000548 else if (type == RD_TYPE_IP)
549 decode_rd_ip (pnt + 2, &rd_ip);
550
551 vty_out (vty, "Route Distinguisher: ");
552
553 if (type == RD_TYPE_AS)
Lou Bergera03bd162016-01-12 13:41:54 -0500554 vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
555 else if (type == RD_TYPE_AS4)
556 vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000557 else if (type == RD_TYPE_IP)
Lou Bergera03bd162016-01-12 13:41:54 -0500558 vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
paul718e3742002-12-13 20:15:29 +0000559
560 vty_out (vty, "%s", VTY_NEWLINE);
561 rd_header = 0;
562 }
563 if (tags)
564 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
565 else
566 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
567 }
568 }
569 }
570 return CMD_SUCCESS;
571}
572
573DEFUN (show_ip_bgp_vpnv4_all,
574 show_ip_bgp_vpnv4_all_cmd,
575 "show ip bgp vpnv4 all",
576 SHOW_STR
577 IP_STR
578 BGP_STR
579 "Display VPNv4 NLRI specific information\n"
580 "Display information about all VPNv4 NLRIs\n")
581{
582 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
583}
584
585DEFUN (show_ip_bgp_vpnv4_rd,
586 show_ip_bgp_vpnv4_rd_cmd,
587 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
588 SHOW_STR
589 IP_STR
590 BGP_STR
591 "Display VPNv4 NLRI specific information\n"
592 "Display information for a route distinguisher\n"
593 "VPN Route Distinguisher\n")
594{
595 int ret;
596 struct prefix_rd prd;
597
598 ret = str2prefix_rd (argv[0], &prd);
599 if (! ret)
600 {
601 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
602 return CMD_WARNING;
603 }
604 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
605}
606
607DEFUN (show_ip_bgp_vpnv4_all_tags,
608 show_ip_bgp_vpnv4_all_tags_cmd,
609 "show ip bgp vpnv4 all tags",
610 SHOW_STR
611 IP_STR
612 BGP_STR
613 "Display VPNv4 NLRI specific information\n"
614 "Display information about all VPNv4 NLRIs\n"
615 "Display BGP tags for prefixes\n")
616{
617 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
618}
619
620DEFUN (show_ip_bgp_vpnv4_rd_tags,
621 show_ip_bgp_vpnv4_rd_tags_cmd,
622 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
623 SHOW_STR
624 IP_STR
625 BGP_STR
626 "Display VPNv4 NLRI specific information\n"
627 "Display information for a route distinguisher\n"
628 "VPN Route Distinguisher\n"
629 "Display BGP tags for prefixes\n")
630{
631 int ret;
632 struct prefix_rd prd;
633
634 ret = str2prefix_rd (argv[0], &prd);
635 if (! ret)
636 {
637 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
638 return CMD_WARNING;
639 }
640 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
641}
642
643DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
644 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
645 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
646 SHOW_STR
647 IP_STR
648 BGP_STR
649 "Display VPNv4 NLRI specific information\n"
650 "Display information about all VPNv4 NLRIs\n"
651 "Detailed information on TCP and BGP neighbor connections\n"
652 "Neighbor to display information about\n"
653 "Display routes learned from neighbor\n")
654{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200655 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000656 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200657 int ret;
658
659 ret = str2sockunion (argv[0], &su);
660 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000661 {
662 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200663 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000664 }
665
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200666 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000667 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
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200673 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000674}
675
676DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
677 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
678 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D 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 routes learned from neighbor\n")
688{
689 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200690 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000691 struct peer *peer;
692 struct prefix_rd prd;
693
694 ret = str2prefix_rd (argv[0], &prd);
695 if (! ret)
696 {
697 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
698 return CMD_WARNING;
699 }
700
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200701 ret = str2sockunion (argv[1], &su);
702 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000703 {
704 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200705 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000706 }
707
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200708 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000709 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
710 {
711 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
712 return CMD_WARNING;
713 }
714
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200715 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000716}
717
718DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
719 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
720 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
721 SHOW_STR
722 IP_STR
723 BGP_STR
724 "Display VPNv4 NLRI specific information\n"
725 "Display information about all VPNv4 NLRIs\n"
726 "Detailed information on TCP and BGP neighbor connections\n"
727 "Neighbor to display information about\n"
728 "Display the routes advertised to a BGP neighbor\n")
729{
730 int ret;
731 struct peer *peer;
732 union sockunion su;
733
734 ret = str2sockunion (argv[0], &su);
735 if (ret < 0)
736 {
737 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
738 return CMD_WARNING;
739 }
740 peer = peer_lookup (NULL, &su);
741 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
742 {
743 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
744 return CMD_WARNING;
745 }
746
747 return show_adj_route_vpn (vty, peer, NULL);
748}
749
750DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
751 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
752 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
753 SHOW_STR
754 IP_STR
755 BGP_STR
756 "Display VPNv4 NLRI specific information\n"
757 "Display information for a route distinguisher\n"
758 "VPN Route Distinguisher\n"
759 "Detailed information on TCP and BGP neighbor connections\n"
760 "Neighbor to display information about\n"
761 "Display the routes advertised to a BGP neighbor\n")
762{
763 int ret;
764 struct peer *peer;
765 struct prefix_rd prd;
766 union sockunion su;
767
768 ret = str2sockunion (argv[1], &su);
769 if (ret < 0)
770 {
771 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
772 return CMD_WARNING;
773 }
774 peer = peer_lookup (NULL, &su);
775 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
776 {
777 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
778 return CMD_WARNING;
779 }
780
781 ret = str2prefix_rd (argv[0], &prd);
782 if (! ret)
783 {
784 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
785 return CMD_WARNING;
786 }
787
788 return show_adj_route_vpn (vty, peer, &prd);
789}
790
791void
paul94f2b392005-06-28 12:44:16 +0000792bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000793{
794 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
Lou Bergera76d9ca2016-01-12 13:41:53 -0500795 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
paul718e3742002-12-13 20:15:29 +0000796 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
797
798
799 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
800 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
801 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
802 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
803 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
804 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
805 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
806 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
807
808 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
809 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
810 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
811 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
812 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
813 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
814 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
815 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
816}