]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
*: make consistent & update GPLv2 file headers
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
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 #include "queue.h"
29 #include "filter.h"
30
31 #include "lib/json.h"
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_table.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_mplsvpn.h"
37 #include "bgpd/bgp_packet.h"
38 #include "bgpd/bgp_vty.h"
39 #include "bgpd/bgp_vpn.h"
40
41 #if ENABLE_BGP_VNC
42 #include "bgpd/rfapi/rfapi_backend.h"
43 #endif
44
45 extern int
46 argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi)
47 {
48 int ret = 0;
49 if (argv_find (argv, argc, "vpnv4", index))
50 {
51 ret = 1;
52 if (afi)
53 *afi = AFI_IP;
54 }
55 else if (argv_find (argv, argc, "vpnv6", index))
56 {
57 ret = 1;
58 if (afi)
59 *afi = AFI_IP6;
60 }
61 return ret;
62 }
63
64 u_int16_t
65 decode_rd_type (u_char *pnt)
66 {
67 u_int16_t v;
68
69 v = ((u_int16_t) *pnt++ << 8);
70 #if ENABLE_BGP_VNC
71 /*
72 * VNC L2 stores LHI in lower byte, so omit it
73 */
74 if (v != RD_TYPE_VNC_ETH)
75 v |= (u_int16_t) *pnt;
76 #else /* duplicate code for clarity */
77 v |= (u_int16_t) *pnt;
78 #endif
79
80 return v;
81 }
82
83 void
84 encode_rd_type (u_int16_t v, u_char *pnt)
85 {
86 *((u_int16_t *)pnt) = htons(v);
87 }
88
89 u_int32_t
90 decode_label (u_char *pnt)
91 {
92 u_int32_t l;
93
94 l = ((u_int32_t) *pnt++ << 12);
95 l |= (u_int32_t) *pnt++ << 4;
96 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
97 return l;
98 }
99
100 void
101 encode_label(u_int32_t label,
102 u_char *pnt)
103 {
104 if (pnt == NULL)
105 return;
106 *pnt++ = (label>>12) & 0xff;
107 *pnt++ = (label>>4) & 0xff;
108 *pnt++ = ((label<<4)+1) & 0xff; /* S=1 */
109 }
110
111 /* type == RD_TYPE_AS */
112 void
113 decode_rd_as (u_char *pnt, struct rd_as *rd_as)
114 {
115 rd_as->as = (u_int16_t) *pnt++ << 8;
116 rd_as->as |= (u_int16_t) *pnt++;
117
118 rd_as->val = ((u_int32_t) *pnt++ << 24);
119 rd_as->val |= ((u_int32_t) *pnt++ << 16);
120 rd_as->val |= ((u_int32_t) *pnt++ << 8);
121 rd_as->val |= (u_int32_t) *pnt;
122 }
123
124 /* type == RD_TYPE_AS4 */
125 void
126 decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
127 {
128 rd_as->as = (u_int32_t) *pnt++ << 24;
129 rd_as->as |= (u_int32_t) *pnt++ << 16;
130 rd_as->as |= (u_int32_t) *pnt++ << 8;
131 rd_as->as |= (u_int32_t) *pnt++;
132
133 rd_as->val = ((u_int16_t) *pnt++ << 8);
134 rd_as->val |= (u_int16_t) *pnt;
135 }
136
137 /* type == RD_TYPE_IP */
138 void
139 decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
140 {
141 memcpy (&rd_ip->ip, pnt, 4);
142 pnt += 4;
143
144 rd_ip->val = ((u_int16_t) *pnt++ << 8);
145 rd_ip->val |= (u_int16_t) *pnt;
146 }
147
148 #if ENABLE_BGP_VNC
149 /* type == RD_TYPE_VNC_ETH */
150 void
151 decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
152 {
153 rd_vnc_eth->type = RD_TYPE_VNC_ETH;
154 rd_vnc_eth->local_nve_id = pnt[1];
155 memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
156 }
157 #endif
158
159 int
160 bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
161 struct bgp_nlri *packet)
162 {
163 u_char *pnt;
164 u_char *lim;
165 struct prefix p;
166 int psize = 0;
167 int prefixlen;
168 u_int16_t type;
169 struct rd_as rd_as;
170 struct rd_ip rd_ip;
171 struct prefix_rd prd;
172 u_char *tagpnt;
173 afi_t afi;
174 safi_t safi;
175 int addpath_encoded;
176 u_int32_t addpath_id;
177
178 /* Check peer status. */
179 if (peer->status != Established)
180 return 0;
181
182 /* Make prefix_rd */
183 prd.family = AF_UNSPEC;
184 prd.prefixlen = 64;
185
186 pnt = packet->nlri;
187 lim = pnt + packet->length;
188 afi = packet->afi;
189 safi = packet->safi;
190 addpath_id = 0;
191
192 addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
193 CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
194
195 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
196 for (; pnt < lim; pnt += psize)
197 {
198 /* Clear prefix structure. */
199 memset (&p, 0, sizeof (struct prefix));
200
201 if (addpath_encoded)
202 {
203
204 /* When packet overflow occurs return immediately. */
205 if (pnt + BGP_ADDPATH_ID_LEN > lim)
206 return -1;
207
208 addpath_id = ntohl(*((uint32_t*) pnt));
209 pnt += BGP_ADDPATH_ID_LEN;
210 }
211
212 /* Fetch prefix length. */
213 prefixlen = *pnt++;
214 p.family = afi2family (packet->afi);
215 psize = PSIZE (prefixlen);
216
217 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
218 {
219 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
220 peer->host, prefixlen);
221 return -1;
222 }
223
224 /* sanity check against packet data */
225 if ((pnt + psize) > lim)
226 {
227 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
228 peer->host,
229 prefixlen, (uint)(lim-pnt));
230 return -1;
231 }
232
233 /* sanity check against storage for the IP address portion */
234 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
235 {
236 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
237 peer->host,
238 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
239 return -1;
240 }
241
242 /* Sanity check against max bitlen of the address family */
243 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
244 {
245 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
246 peer->host,
247 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
248 p.family, prefix_blen (&p));
249 return -1;
250 }
251
252 /* Copyr label to prefix. */
253 tagpnt = pnt;
254
255 /* Copy routing distinguisher to rd. */
256 memcpy (&prd.val, pnt + 3, 8);
257
258 /* Decode RD type. */
259 type = decode_rd_type (pnt + 3);
260
261 switch (type)
262 {
263 case RD_TYPE_AS:
264 decode_rd_as (pnt + 5, &rd_as);
265 break;
266
267 case RD_TYPE_AS4:
268 decode_rd_as4 (pnt + 5, &rd_as);
269 break;
270
271 case RD_TYPE_IP:
272 decode_rd_ip (pnt + 5, &rd_ip);
273 break;
274
275 #if ENABLE_BGP_VNC
276 case RD_TYPE_VNC_ETH:
277 break;
278 #endif
279
280 default:
281 zlog_err ("Unknown RD type %d", type);
282 break; /* just report */
283 }
284
285 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;/* exclude label & RD */
286 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
287 psize - VPN_PREFIXLEN_MIN_BYTES);
288
289 if (attr)
290 {
291 bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
292 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0, NULL);
293 }
294 else
295 {
296 bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
297 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, NULL);
298 }
299 }
300 /* Packet length consistency check. */
301 if (pnt != lim)
302 {
303 zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
304 peer->host, lim - pnt);
305 return -1;
306 }
307
308 return 0;
309 #undef VPN_PREFIXLEN_MIN_BYTES
310 }
311
312 int
313 str2prefix_rd (const char *str, struct prefix_rd *prd)
314 {
315 int ret; /* ret of called functions */
316 int lret; /* local ret, of this func */
317 char *p;
318 char *p2;
319 struct stream *s = NULL;
320 char *half = NULL;
321 struct in_addr addr;
322
323 s = stream_new (8);
324
325 prd->family = AF_UNSPEC;
326 prd->prefixlen = 64;
327
328 lret = 0;
329 p = strchr (str, ':');
330 if (! p)
331 goto out;
332
333 if (! all_digit (p + 1))
334 goto out;
335
336 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
337 memcpy (half, str, (p - str));
338 half[p - str] = '\0';
339
340 p2 = strchr (str, '.');
341
342 if (! p2)
343 {
344 unsigned long as_val;
345
346 if (! all_digit (half))
347 goto out;
348
349 as_val = atol(half);
350 if (as_val > 0xffff)
351 {
352 stream_putw (s, RD_TYPE_AS4);
353 stream_putl (s, as_val);
354 stream_putw (s, atol (p + 1));
355 }
356 else
357 {
358 stream_putw (s, RD_TYPE_AS);
359 stream_putw (s, as_val);
360 stream_putl (s, atol (p + 1));
361 }
362 }
363 else
364 {
365 ret = inet_aton (half, &addr);
366 if (! ret)
367 goto out;
368
369 stream_putw (s, RD_TYPE_IP);
370 stream_put_in_addr (s, &addr);
371 stream_putw (s, atol (p + 1));
372 }
373 memcpy (prd->val, s->data, 8);
374 lret = 1;
375
376 out:
377 if (s)
378 stream_free (s);
379 if (half)
380 XFREE(MTYPE_TMP, half);
381 return lret;
382 }
383
384 int
385 str2tag (const char *str, u_char *tag)
386 {
387 unsigned long l;
388 char *endptr;
389 u_int32_t t;
390
391 if (*str == '-')
392 return 0;
393
394 errno = 0;
395 l = strtoul (str, &endptr, 10);
396
397 if (*endptr != '\0' || errno || l > UINT32_MAX)
398 return 0;
399
400 t = (u_int32_t) l;
401
402 tag[0] = (u_char)(t >> 12);
403 tag[1] = (u_char)(t >> 4);
404 tag[2] = (u_char)(t << 4);
405
406 return 1;
407 }
408
409 char *
410 prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
411 {
412 u_char *pnt;
413 u_int16_t type;
414 struct rd_as rd_as;
415 struct rd_ip rd_ip;
416
417 if (size < RD_ADDRSTRLEN)
418 return NULL;
419
420 pnt = prd->val;
421
422 type = decode_rd_type (pnt);
423
424 if (type == RD_TYPE_AS)
425 {
426 decode_rd_as (pnt + 2, &rd_as);
427 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
428 return buf;
429 }
430 else if (type == RD_TYPE_AS4)
431 {
432 decode_rd_as4 (pnt + 2, &rd_as);
433 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
434 return buf;
435 }
436 else if (type == RD_TYPE_IP)
437 {
438 decode_rd_ip (pnt + 2, &rd_ip);
439 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
440 return buf;
441 }
442 #if ENABLE_BGP_VNC
443 else if (type == RD_TYPE_VNC_ETH)
444 {
445 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
446 *(pnt+1), /* LHI */
447 *(pnt+2), /* MAC[0] */
448 *(pnt+3),
449 *(pnt+4),
450 *(pnt+5),
451 *(pnt+6),
452 *(pnt+7));
453
454 return buf;
455 }
456 #endif
457 return NULL;
458 }
459
460 /* For testing purpose, static route of MPLS-VPN. */
461 DEFUN (vpnv4_network,
462 vpnv4_network_cmd,
463 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
464 "Specify a network to announce via BGP\n"
465 "IPv4 prefix\n"
466 "Specify Route Distinguisher\n"
467 "VPN Route Distinguisher\n"
468 "BGP tag\n"
469 "tag value\n")
470 {
471 int idx_ipv4_prefixlen = 1;
472 int idx_ext_community = 3;
473 int idx_word = 5;
474 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg,
475 argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);
476 }
477
478 DEFUN (vpnv4_network_route_map,
479 vpnv4_network_route_map_cmd,
480 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
481 "Specify a network to announce via BGP\n"
482 "IPv4 prefix\n"
483 "Specify Route Distinguisher\n"
484 "VPN Route Distinguisher\n"
485 "BGP tag\n"
486 "tag value\n"
487 "route map\n"
488 "route map name\n")
489 {
490 int idx_ipv4_prefixlen = 1;
491 int idx_ext_community = 3;
492 int idx_word = 5;
493 int idx_word_2 = 7;
494 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg,
495 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
496 }
497
498 /* For testing purpose, static route of MPLS-VPN. */
499 DEFUN (no_vpnv4_network,
500 no_vpnv4_network_cmd,
501 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
502 NO_STR
503 "Specify a network to announce via BGP\n"
504 "IPv4 prefix\n"
505 "Specify Route Distinguisher\n"
506 "VPN Route Distinguisher\n"
507 "BGP tag\n"
508 "tag value\n")
509 {
510 int idx_ipv4_prefixlen = 2;
511 int idx_ext_community = 4;
512 int idx_word = 6;
513 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
514 argv[idx_ext_community]->arg, argv[idx_word]->arg,
515 0, NULL, NULL, NULL);
516 }
517
518 DEFUN (vpnv6_network,
519 vpnv6_network_cmd,
520 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
521 "Specify a network to announce via BGP\n"
522 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
523 "Specify Route Distinguisher\n"
524 "VPN Route Distinguisher\n"
525 "BGP tag\n"
526 "tag value\n"
527 "route map\n"
528 "route map name\n")
529 {
530 int idx_ipv6_prefix = 1;
531 int idx_ext_community = 3;
532 int idx_word = 5;
533 int idx_word_2 = 7;
534 if (argc == 8)
535 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
536 else
537 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);
538 }
539
540 /* For testing purpose, static route of MPLS-VPN. */
541 DEFUN (no_vpnv6_network,
542 no_vpnv6_network_cmd,
543 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD",
544 NO_STR
545 "Specify a network to announce via BGP\n"
546 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
547 "Specify Route Distinguisher\n"
548 "VPN Route Distinguisher\n"
549 "BGP tag\n"
550 "tag value\n")
551 {
552 int idx_ipv6_prefix = 2;
553 int idx_ext_community = 4;
554 int idx_word = 6;
555 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, 0, NULL, NULL, NULL);
556 }
557
558 int
559 bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
560 enum bgp_show_type type, void *output_arg, int tags, u_char use_json)
561 {
562 struct bgp *bgp;
563 struct bgp_table *table;
564 struct bgp_node *rn;
565 struct bgp_node *rm;
566 struct bgp_info *ri;
567 int rd_header;
568 int header = 1;
569 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
570 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
571 unsigned long output_count = 0;
572 unsigned long total_count = 0;
573 json_object *json = NULL;
574 json_object *json_mroute = NULL;
575 json_object *json_nroute = NULL;
576 json_object *json_array = NULL;
577 json_object *json_scode = NULL;
578 json_object *json_ocode = NULL;
579
580 bgp = bgp_get_default ();
581 if (bgp == NULL)
582 {
583 if (!use_json)
584 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
585 return CMD_WARNING;
586 }
587
588 if (use_json)
589 {
590 json_scode = json_object_new_object();
591 json_ocode = json_object_new_object();
592 json = json_object_new_object();
593 json_mroute = json_object_new_object();
594 json_nroute = json_object_new_object();
595
596 json_object_string_add(json_scode, "suppressed", "s");
597 json_object_string_add(json_scode, "damped", "d");
598 json_object_string_add(json_scode, "history", "h");
599 json_object_string_add(json_scode, "valid", "*");
600 json_object_string_add(json_scode, "best", ">");
601 json_object_string_add(json_scode, "internal", "i");
602
603 json_object_string_add(json_ocode, "igp", "i");
604 json_object_string_add(json_ocode, "egp", "e");
605 json_object_string_add(json_ocode, "incomplete", "?");
606 }
607
608 if ((afi != AFI_IP) && (afi != AFI_IP6))
609 {
610 vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
611 return CMD_WARNING;
612 }
613
614 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
615 {
616 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
617 continue;
618
619 if ((table = rn->info) != NULL)
620 {
621 rd_header = 1;
622
623 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
624 {
625 total_count++;
626 if (use_json)
627 json_array = json_object_new_array();
628 else
629 json_array = NULL;
630
631 for (ri = rm->info; ri; ri = ri->next)
632 {
633 if (type == bgp_show_type_neighbor)
634 {
635 union sockunion *su = output_arg;
636
637 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
638 continue;
639 }
640 if (header)
641 {
642 if (use_json)
643 {
644 if (!tags)
645 {
646 json_object_int_add(json, "bgpTableVersion", 0);
647 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
648 json_object_object_add(json, "bgpStatusCodes", json_scode);
649 json_object_object_add(json, "bgpOriginCodes", json_ocode);
650 }
651 }
652 else
653 {
654 if (tags)
655 vty_out (vty, v4_header_tag, VTY_NEWLINE);
656 else
657 {
658 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
659 inet_ntoa (bgp->router_id), VTY_NEWLINE);
660 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
661 VTY_NEWLINE);
662 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
663 VTY_NEWLINE, VTY_NEWLINE);
664 vty_out (vty, v4_header, VTY_NEWLINE);
665 }
666 }
667 header = 0;
668 }
669
670 if (rd_header)
671 {
672 u_int16_t type;
673 struct rd_as rd_as;
674 struct rd_ip rd_ip = {0};
675 #if ENABLE_BGP_VNC
676 struct rd_vnc_eth rd_vnc_eth = {0};
677 #endif
678 u_char *pnt;
679
680 pnt = rn->p.u.val;
681
682 /* Decode RD type. */
683 type = decode_rd_type (pnt);
684 /* Decode RD value. */
685 if (type == RD_TYPE_AS)
686 decode_rd_as (pnt + 2, &rd_as);
687 else if (type == RD_TYPE_AS4)
688 decode_rd_as4 (pnt + 2, &rd_as);
689 else if (type == RD_TYPE_IP)
690 decode_rd_ip (pnt + 2, &rd_ip);
691 #if ENABLE_BGP_VNC
692 else if (type == RD_TYPE_VNC_ETH)
693 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
694 #endif
695
696 if (use_json)
697 {
698 char buffer[BUFSIZ];
699 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
700 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
701 else if (type == RD_TYPE_IP)
702 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
703 json_object_string_add(json_nroute, "routeDistinguisher", buffer);
704 }
705 else
706 {
707 vty_out (vty, "Route Distinguisher: ");
708
709 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
710 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
711 else if (type == RD_TYPE_IP)
712 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
713 #if ENABLE_BGP_VNC
714 else if (type == RD_TYPE_VNC_ETH)
715 vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
716 rd_vnc_eth.local_nve_id,
717 rd_vnc_eth.macaddr.octet[0],
718 rd_vnc_eth.macaddr.octet[1],
719 rd_vnc_eth.macaddr.octet[2],
720 rd_vnc_eth.macaddr.octet[3],
721 rd_vnc_eth.macaddr.octet[4],
722 rd_vnc_eth.macaddr.octet[5]);
723 #endif
724 vty_out (vty, "%s", VTY_NEWLINE);
725 }
726 rd_header = 0;
727 }
728 if (tags)
729 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
730 else
731 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
732 output_count++;
733 }
734
735 if (use_json)
736 {
737 struct prefix *p;
738 char buf_a[BUFSIZ];
739 char buf_b[BUFSIZ];
740 p = &rm->p;
741 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
742 json_object_object_add(json_mroute, buf_a, json_array);
743 }
744 }
745
746 if (use_json)
747 {
748 struct prefix *p;
749 char buf_a[BUFSIZ];
750 char buf_b[BUFSIZ];
751 p = &rn->p;
752 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
753 json_object_object_add(json_nroute, buf_a, json_mroute);
754 }
755 }
756 }
757
758 if (use_json)
759 {
760 json_object_object_add(json, "routes", json_nroute);
761 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
762 json_object_free(json);
763 }
764 else
765 {
766 if (output_count == 0)
767 vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
768 else
769 vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
770 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
771 }
772
773 return CMD_SUCCESS;
774 }
775
776 DEFUN (show_bgp_ip_vpn_all_rd,
777 show_bgp_ip_vpn_all_rd_cmd,
778 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
779 SHOW_STR
780 IP_STR
781 BGP_STR
782 BGP_VPNVX_HELP_STR
783 "Display VPN NLRI specific information\n"
784 "Display information for a route distinguisher\n"
785 "VPN Route Distinguisher\n"
786 JSON_STR)
787 {
788 int idx_rd = 5;
789 int ret;
790 struct prefix_rd prd;
791 afi_t afi;
792 int idx = 0;
793
794 if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
795 {
796 if (argc >= 7 && argv[idx_rd]->arg)
797 {
798 ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
799 if (! ret)
800 {
801 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
802 return CMD_WARNING;
803 }
804 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
805 }
806 else
807 {
808 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
809 }
810 }
811 return CMD_SUCCESS;
812 }
813
814 DEFUN (show_ip_bgp_vpn_rd,
815 show_ip_bgp_vpn_rd_cmd,
816 "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
817 SHOW_STR
818 IP_STR
819 BGP_STR
820 BGP_AFI_HELP_STR
821 "Address Family modifier\n"
822 "Display information for a route distinguisher\n"
823 "VPN Route Distinguisher\n")
824 {
825 int idx_ext_community = argc-1;
826 int ret;
827 struct prefix_rd prd;
828 afi_t afi;
829 int idx = 0;
830
831 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
832 {
833 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
834 if (! ret)
835 {
836 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
837 return CMD_WARNING;
838 }
839 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, 0);
840 }
841 return CMD_SUCCESS;
842 }
843
844 #ifdef KEEP_OLD_VPN_COMMANDS
845 DEFUN (show_ip_bgp_vpn_all,
846 show_ip_bgp_vpn_all_cmd,
847 "show [ip] bgp <vpnv4|vpnv6>",
848 SHOW_STR
849 IP_STR
850 BGP_STR
851 BGP_VPNVX_HELP_STR)
852 {
853 afi_t afi;
854 int idx = 0;
855
856 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
857 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, 0);
858 return CMD_SUCCESS;
859 }
860
861 DEFUN (show_ip_bgp_vpn_all_tags,
862 show_ip_bgp_vpn_all_tags_cmd,
863 "show [ip] bgp <vpnv4|vpnv6> all tags",
864 SHOW_STR
865 IP_STR
866 BGP_STR
867 BGP_VPNVX_HELP_STR
868 "Display information about all VPNv4/VPNV6 NLRIs\n"
869 "Display BGP tags for prefixes\n")
870 {
871 afi_t afi;
872 int idx = 0;
873
874 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
875 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 1, 0);
876 return CMD_SUCCESS;
877 }
878
879 DEFUN (show_ip_bgp_vpn_rd_tags,
880 show_ip_bgp_vpn_rd_tags_cmd,
881 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
882 SHOW_STR
883 IP_STR
884 BGP_STR
885 BGP_VPNVX_HELP_STR
886 "Display information for a route distinguisher\n"
887 "VPN Route Distinguisher\n"
888 "Display BGP tags for prefixes\n")
889 {
890 int idx_ext_community = 5;
891 int ret;
892 struct prefix_rd prd;
893 afi_t afi;
894 int idx = 0;
895
896 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
897 {
898 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
899 if (! ret)
900 {
901 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
902 return CMD_WARNING;
903 }
904 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 1, 0);
905 }
906 return CMD_SUCCESS;
907 }
908
909 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
910 show_ip_bgp_vpn_all_neighbor_routes_cmd,
911 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
912 SHOW_STR
913 IP_STR
914 BGP_STR
915 BGP_VPNVX_HELP_STR
916 "Display information about all VPNv4/VPNv6 NLRIs\n"
917 "Detailed information on TCP and BGP neighbor connections\n"
918 "Neighbor to display information about\n"
919 "Display routes learned from neighbor\n"
920 JSON_STR)
921 {
922 int idx_ipv4 = 6;
923 union sockunion su;
924 struct peer *peer;
925 int ret;
926 u_char uj = use_json(argc, argv);
927 afi_t afi;
928 int idx = 0;
929
930 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
931 {
932 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
933 if (ret < 0)
934 {
935 if (uj)
936 {
937 json_object *json_no = NULL;
938 json_no = json_object_new_object();
939 json_object_string_add(json_no, "warning", "Malformed address");
940 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
941 json_object_free(json_no);
942 }
943 else
944 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
945 return CMD_WARNING;
946 }
947
948 peer = peer_lookup (NULL, &su);
949 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
950 {
951 if (uj)
952 {
953 json_object *json_no = NULL;
954 json_no = json_object_new_object();
955 json_object_string_add(json_no, "warning", "No such neighbor or address family");
956 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
957 json_object_free(json_no);
958 }
959 else
960 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
961 return CMD_WARNING;
962 }
963
964 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
965 }
966 return CMD_SUCCESS;
967 }
968
969 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
970 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
971 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
972 SHOW_STR
973 IP_STR
974 BGP_STR
975 BGP_VPNVX_HELP_STR
976 "Display information for a route distinguisher\n"
977 "VPN Route Distinguisher\n"
978 "Detailed information on TCP and BGP neighbor connections\n"
979 "Neighbor to display information about\n"
980 "Display routes learned from neighbor\n"
981 JSON_STR)
982 {
983 int idx_ext_community = 5;
984 int idx_ipv4 = 7;
985 int ret;
986 union sockunion su;
987 struct peer *peer;
988 struct prefix_rd prd;
989 u_char uj = use_json(argc, argv);
990 afi_t afi;
991 int idx = 0;
992
993 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
994 {
995 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
996 if (! ret)
997 {
998 if (uj)
999 {
1000 json_object *json_no = NULL;
1001 json_no = json_object_new_object();
1002 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1003 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1004 json_object_free(json_no);
1005 }
1006 else
1007 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1008 return CMD_WARNING;
1009 }
1010
1011 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1012 if (ret < 0)
1013 {
1014 if (uj)
1015 {
1016 json_object *json_no = NULL;
1017 json_no = json_object_new_object();
1018 json_object_string_add(json_no, "warning", "Malformed address");
1019 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1020 json_object_free(json_no);
1021 }
1022 else
1023 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1024 return CMD_WARNING;
1025 }
1026
1027 peer = peer_lookup (NULL, &su);
1028 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1029 {
1030 if (uj)
1031 {
1032 json_object *json_no = NULL;
1033 json_no = json_object_new_object();
1034 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1035 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1036 json_object_free(json_no);
1037 }
1038 else
1039 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1040 return CMD_WARNING;
1041 }
1042
1043 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
1044 }
1045 return CMD_SUCCESS;
1046 }
1047
1048 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1049 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1050 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1051 SHOW_STR
1052 IP_STR
1053 BGP_STR
1054 BGP_VPNVX_HELP_STR
1055 "Display information about all VPNv4/VPNv6 NLRIs\n"
1056 "Detailed information on TCP and BGP neighbor connections\n"
1057 "Neighbor to display information about\n"
1058 "Display the routes advertised to a BGP neighbor\n"
1059 JSON_STR)
1060 {
1061 int idx_ipv4 = 6;
1062 int ret;
1063 struct peer *peer;
1064 union sockunion su;
1065 u_char uj = use_json(argc, argv);
1066 afi_t afi;
1067 int idx = 0;
1068
1069 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1070 {
1071 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1072 if (ret < 0)
1073 {
1074 if (uj)
1075 {
1076 json_object *json_no = NULL;
1077 json_no = json_object_new_object();
1078 json_object_string_add(json_no, "warning", "Malformed address");
1079 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1080 json_object_free(json_no);
1081 }
1082 else
1083 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1084 return CMD_WARNING;
1085 }
1086 peer = peer_lookup (NULL, &su);
1087 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1088 {
1089 if (uj)
1090 {
1091 json_object *json_no = NULL;
1092 json_no = json_object_new_object();
1093 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1094 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1095 json_object_free(json_no);
1096 }
1097 else
1098 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1099 return CMD_WARNING;
1100 }
1101 return show_adj_route_vpn (vty, peer, NULL, AFI_IP, SAFI_MPLS_VPN, uj);
1102 }
1103 return CMD_SUCCESS;
1104 }
1105
1106 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1107 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
1108 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1109 SHOW_STR
1110 IP_STR
1111 BGP_STR
1112 BGP_VPNVX_HELP_STR
1113 "Display information for a route distinguisher\n"
1114 "VPN Route Distinguisher\n"
1115 "Detailed information on TCP and BGP neighbor connections\n"
1116 "Neighbor to display information about\n"
1117 "Display the routes advertised to a BGP neighbor\n"
1118 JSON_STR)
1119 {
1120 int idx_ext_community = 5;
1121 int idx_ipv4 = 7;
1122 int ret;
1123 struct peer *peer;
1124 struct prefix_rd prd;
1125 union sockunion su;
1126 u_char uj = use_json(argc, argv);
1127 afi_t afi;
1128 int idx = 0;
1129
1130 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1131 {
1132 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1133 if (ret < 0)
1134 {
1135 if (uj)
1136 {
1137 json_object *json_no = NULL;
1138 json_no = json_object_new_object();
1139 json_object_string_add(json_no, "warning", "Malformed address");
1140 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1141 json_object_free(json_no);
1142 }
1143 else
1144 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1145 return CMD_WARNING;
1146 }
1147 peer = peer_lookup (NULL, &su);
1148 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1149 {
1150 if (uj)
1151 {
1152 json_object *json_no = NULL;
1153 json_no = json_object_new_object();
1154 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1155 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1156 json_object_free(json_no);
1157 }
1158 else
1159 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1160 return CMD_WARNING;
1161 }
1162
1163 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1164 if (! ret)
1165 {
1166 if (uj)
1167 {
1168 json_object *json_no = NULL;
1169 json_no = json_object_new_object();
1170 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1171 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1172 json_object_free(json_no);
1173 }
1174 else
1175 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1176 return CMD_WARNING;
1177 }
1178
1179 return show_adj_route_vpn (vty, peer, &prd, AFI_IP, SAFI_MPLS_VPN, uj);
1180 }
1181 return CMD_SUCCESS;
1182 }
1183 #endif /* KEEP_OLD_VPN_COMMANDS */
1184
1185 void
1186 bgp_mplsvpn_init (void)
1187 {
1188 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
1189 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1190 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1191
1192 install_element (BGP_VPNV6_NODE, &vpnv6_network_cmd);
1193 install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
1194
1195 install_element (VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
1196 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
1197 #ifdef KEEP_OLD_VPN_COMMANDS
1198 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1199 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1200 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1201 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1202 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1203 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1204 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
1205 #endif /* KEEP_OLD_VPN_COMMANDS */
1206 }