]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #583 from chiragshah6/pim_dev_3_0
[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
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 #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 char *
385 prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
386 {
387 u_char *pnt;
388 u_int16_t type;
389 struct rd_as rd_as;
390 struct rd_ip rd_ip;
391
392 if (size < RD_ADDRSTRLEN)
393 return NULL;
394
395 pnt = prd->val;
396
397 type = decode_rd_type (pnt);
398
399 if (type == RD_TYPE_AS)
400 {
401 decode_rd_as (pnt + 2, &rd_as);
402 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
403 return buf;
404 }
405 else if (type == RD_TYPE_AS4)
406 {
407 decode_rd_as4 (pnt + 2, &rd_as);
408 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
409 return buf;
410 }
411 else if (type == RD_TYPE_IP)
412 {
413 decode_rd_ip (pnt + 2, &rd_ip);
414 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
415 return buf;
416 }
417 #if ENABLE_BGP_VNC
418 else if (type == RD_TYPE_VNC_ETH)
419 {
420 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
421 *(pnt+1), /* LHI */
422 *(pnt+2), /* MAC[0] */
423 *(pnt+3),
424 *(pnt+4),
425 *(pnt+5),
426 *(pnt+6),
427 *(pnt+7));
428
429 return buf;
430 }
431 #endif
432 return NULL;
433 }
434
435 /* For testing purpose, static route of MPLS-VPN. */
436 DEFUN (vpnv4_network,
437 vpnv4_network_cmd,
438 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
439 "Specify a network to announce via BGP\n"
440 "IPv4 prefix\n"
441 "Specify Route Distinguisher\n"
442 "VPN Route Distinguisher\n"
443 "VPN NLRI label (tag)\n"
444 "VPN NLRI label (tag)\n"
445 "Label value\n")
446 {
447 int idx_ipv4_prefixlen = 1;
448 int idx_ext_community = 3;
449 int idx_label = 5;
450 return bgp_static_set_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg,
451 argv[idx_label]->arg, NULL, 0, NULL, NULL, NULL, NULL);
452 }
453
454 DEFUN (vpnv4_network_route_map,
455 vpnv4_network_route_map_cmd,
456 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) route-map WORD",
457 "Specify a network to announce via BGP\n"
458 "IPv4 prefix\n"
459 "Specify Route Distinguisher\n"
460 "VPN Route Distinguisher\n"
461 "VPN NLRI label (tag)\n"
462 "VPN NLRI label (tag)\n"
463 "Label value\n"
464 "route map\n"
465 "route map name\n")
466 {
467 int idx_ipv4_prefixlen = 1;
468 int idx_ext_community = 3;
469 int idx_label = 5;
470 int idx_word_2 = 7;
471 return bgp_static_set_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_label]->arg,
472 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
473 }
474
475 /* For testing purpose, static route of MPLS-VPN. */
476 DEFUN (no_vpnv4_network,
477 no_vpnv4_network_cmd,
478 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
479 NO_STR
480 "Specify a network to announce via BGP\n"
481 "IPv4 prefix\n"
482 "Specify Route Distinguisher\n"
483 "VPN Route Distinguisher\n"
484 "VPN NLRI label (tag)\n"
485 "VPN NLRI label (tag)\n"
486 "Label value\n")
487 {
488 int idx_ipv4_prefixlen = 2;
489 int idx_ext_community = 4;
490 int idx_label = 6;
491 return bgp_static_unset_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
492 argv[idx_ext_community]->arg, argv[idx_label]->arg,
493 0, NULL, NULL, NULL);
494 }
495
496 DEFUN (vpnv6_network,
497 vpnv6_network_cmd,
498 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) [route-map WORD]",
499 "Specify a network to announce via BGP\n"
500 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
501 "Specify Route Distinguisher\n"
502 "VPN Route Distinguisher\n"
503 "VPN NLRI label (tag)\n"
504 "VPN NLRI label (tag)\n"
505 "Label value\n"
506 "route map\n"
507 "route map name\n")
508 {
509 int idx_ipv6_prefix = 1;
510 int idx_ext_community = 3;
511 int idx_label = 5;
512 int idx_word_2 = 7;
513 if (argc == 8)
514 return bgp_static_set_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_label]->arg, argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
515 else
516 return bgp_static_set_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0, NULL, NULL, NULL, NULL);
517 }
518
519 /* For testing purpose, static route of MPLS-VPN. */
520 DEFUN (no_vpnv6_network,
521 no_vpnv6_network_cmd,
522 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
523 NO_STR
524 "Specify a network to announce via BGP\n"
525 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
526 "Specify Route Distinguisher\n"
527 "VPN Route Distinguisher\n"
528 "VPN NLRI label (tag)\n"
529 "VPN NLRI label (tag)\n"
530 "Label value\n")
531 {
532 int idx_ipv6_prefix = 2;
533 int idx_ext_community = 4;
534 int idx_label = 6;
535 return bgp_static_unset_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_label]->arg, 0, NULL, NULL, NULL);
536 }
537
538 int
539 bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
540 enum bgp_show_type type, void *output_arg, int tags, u_char use_json)
541 {
542 struct bgp *bgp;
543 struct bgp_table *table;
544 struct bgp_node *rn;
545 struct bgp_node *rm;
546 struct bgp_info *ri;
547 int rd_header;
548 int header = 1;
549 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
550 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
551 unsigned long output_count = 0;
552 unsigned long total_count = 0;
553 json_object *json = NULL;
554 json_object *json_mroute = NULL;
555 json_object *json_nroute = NULL;
556 json_object *json_array = NULL;
557 json_object *json_scode = NULL;
558 json_object *json_ocode = NULL;
559
560 bgp = bgp_get_default ();
561 if (bgp == NULL)
562 {
563 if (!use_json)
564 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
565 return CMD_WARNING;
566 }
567
568 if (use_json)
569 {
570 json_scode = json_object_new_object();
571 json_ocode = json_object_new_object();
572 json = json_object_new_object();
573 json_mroute = json_object_new_object();
574 json_nroute = json_object_new_object();
575
576 json_object_string_add(json_scode, "suppressed", "s");
577 json_object_string_add(json_scode, "damped", "d");
578 json_object_string_add(json_scode, "history", "h");
579 json_object_string_add(json_scode, "valid", "*");
580 json_object_string_add(json_scode, "best", ">");
581 json_object_string_add(json_scode, "internal", "i");
582
583 json_object_string_add(json_ocode, "igp", "i");
584 json_object_string_add(json_ocode, "egp", "e");
585 json_object_string_add(json_ocode, "incomplete", "?");
586 }
587
588 if ((afi != AFI_IP) && (afi != AFI_IP6))
589 {
590 vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
591 return CMD_WARNING;
592 }
593
594 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
595 {
596 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
597 continue;
598
599 if ((table = rn->info) != NULL)
600 {
601 rd_header = 1;
602
603 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
604 {
605 total_count++;
606 if (use_json)
607 json_array = json_object_new_array();
608 else
609 json_array = NULL;
610
611 for (ri = rm->info; ri; ri = ri->next)
612 {
613 if (type == bgp_show_type_neighbor)
614 {
615 union sockunion *su = output_arg;
616
617 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
618 continue;
619 }
620 if (header)
621 {
622 if (use_json)
623 {
624 if (!tags)
625 {
626 json_object_int_add(json, "bgpTableVersion", 0);
627 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
628 json_object_object_add(json, "bgpStatusCodes", json_scode);
629 json_object_object_add(json, "bgpOriginCodes", json_ocode);
630 }
631 }
632 else
633 {
634 if (tags)
635 vty_out (vty, v4_header_tag, VTY_NEWLINE);
636 else
637 {
638 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
639 inet_ntoa (bgp->router_id), VTY_NEWLINE);
640 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
641 VTY_NEWLINE);
642 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
643 VTY_NEWLINE, VTY_NEWLINE);
644 vty_out (vty, v4_header, VTY_NEWLINE);
645 }
646 }
647 header = 0;
648 }
649
650 if (rd_header)
651 {
652 u_int16_t type;
653 struct rd_as rd_as;
654 struct rd_ip rd_ip = {0};
655 #if ENABLE_BGP_VNC
656 struct rd_vnc_eth rd_vnc_eth = {0};
657 #endif
658 u_char *pnt;
659
660 pnt = rn->p.u.val;
661
662 /* Decode RD type. */
663 type = decode_rd_type (pnt);
664 /* Decode RD value. */
665 if (type == RD_TYPE_AS)
666 decode_rd_as (pnt + 2, &rd_as);
667 else if (type == RD_TYPE_AS4)
668 decode_rd_as4 (pnt + 2, &rd_as);
669 else if (type == RD_TYPE_IP)
670 decode_rd_ip (pnt + 2, &rd_ip);
671 #if ENABLE_BGP_VNC
672 else if (type == RD_TYPE_VNC_ETH)
673 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
674 #endif
675
676 if (use_json)
677 {
678 char buffer[BUFSIZ];
679 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
680 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
681 else if (type == RD_TYPE_IP)
682 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
683 json_object_string_add(json_nroute, "routeDistinguisher", buffer);
684 }
685 else
686 {
687 vty_out (vty, "Route Distinguisher: ");
688
689 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
690 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
691 else if (type == RD_TYPE_IP)
692 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
693 #if ENABLE_BGP_VNC
694 else if (type == RD_TYPE_VNC_ETH)
695 vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
696 rd_vnc_eth.local_nve_id,
697 rd_vnc_eth.macaddr.octet[0],
698 rd_vnc_eth.macaddr.octet[1],
699 rd_vnc_eth.macaddr.octet[2],
700 rd_vnc_eth.macaddr.octet[3],
701 rd_vnc_eth.macaddr.octet[4],
702 rd_vnc_eth.macaddr.octet[5]);
703 #endif
704 vty_out (vty, "%s", VTY_NEWLINE);
705 }
706 rd_header = 0;
707 }
708 if (tags)
709 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
710 else
711 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
712 output_count++;
713 }
714
715 if (use_json)
716 {
717 struct prefix *p;
718 char buf_a[BUFSIZ];
719 char buf_b[BUFSIZ];
720 p = &rm->p;
721 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
722 json_object_object_add(json_mroute, buf_a, json_array);
723 }
724 }
725
726 if (use_json)
727 {
728 struct prefix *p;
729 char buf_a[BUFSIZ];
730 char buf_b[BUFSIZ];
731 p = &rn->p;
732 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
733 json_object_object_add(json_nroute, buf_a, json_mroute);
734 }
735 }
736 }
737
738 if (use_json)
739 {
740 json_object_object_add(json, "routes", json_nroute);
741 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
742 json_object_free(json);
743 }
744 else
745 {
746 if (output_count == 0)
747 vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
748 else
749 vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
750 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
751 }
752
753 return CMD_SUCCESS;
754 }
755
756 DEFUN (show_bgp_ip_vpn_all_rd,
757 show_bgp_ip_vpn_all_rd_cmd,
758 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
759 SHOW_STR
760 IP_STR
761 BGP_STR
762 BGP_VPNVX_HELP_STR
763 "Display VPN NLRI specific information\n"
764 "Display information for a route distinguisher\n"
765 "VPN Route Distinguisher\n"
766 JSON_STR)
767 {
768 int idx_rd = 5;
769 int ret;
770 struct prefix_rd prd;
771 afi_t afi;
772 int idx = 0;
773
774 if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
775 {
776 if (argc >= 7 && argv[idx_rd]->arg)
777 {
778 ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
779 if (! ret)
780 {
781 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
782 return CMD_WARNING;
783 }
784 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
785 }
786 else
787 {
788 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
789 }
790 }
791 return CMD_SUCCESS;
792 }
793
794 DEFUN (show_ip_bgp_vpn_rd,
795 show_ip_bgp_vpn_rd_cmd,
796 "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
797 SHOW_STR
798 IP_STR
799 BGP_STR
800 BGP_AFI_HELP_STR
801 "Address Family modifier\n"
802 "Display information for a route distinguisher\n"
803 "VPN Route Distinguisher\n")
804 {
805 int idx_ext_community = argc-1;
806 int ret;
807 struct prefix_rd prd;
808 afi_t afi;
809 int idx = 0;
810
811 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
812 {
813 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
814 if (! ret)
815 {
816 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
817 return CMD_WARNING;
818 }
819 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, 0);
820 }
821 return CMD_SUCCESS;
822 }
823
824 #ifdef KEEP_OLD_VPN_COMMANDS
825 DEFUN (show_ip_bgp_vpn_all,
826 show_ip_bgp_vpn_all_cmd,
827 "show [ip] bgp <vpnv4|vpnv6>",
828 SHOW_STR
829 IP_STR
830 BGP_STR
831 BGP_VPNVX_HELP_STR)
832 {
833 afi_t afi;
834 int idx = 0;
835
836 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
837 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, 0);
838 return CMD_SUCCESS;
839 }
840
841 DEFUN (show_ip_bgp_vpn_all_tags,
842 show_ip_bgp_vpn_all_tags_cmd,
843 "show [ip] bgp <vpnv4|vpnv6> all tags",
844 SHOW_STR
845 IP_STR
846 BGP_STR
847 BGP_VPNVX_HELP_STR
848 "Display information about all VPNv4/VPNV6 NLRIs\n"
849 "Display BGP tags for prefixes\n")
850 {
851 afi_t afi;
852 int idx = 0;
853
854 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
855 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 1, 0);
856 return CMD_SUCCESS;
857 }
858
859 DEFUN (show_ip_bgp_vpn_rd_tags,
860 show_ip_bgp_vpn_rd_tags_cmd,
861 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
862 SHOW_STR
863 IP_STR
864 BGP_STR
865 BGP_VPNVX_HELP_STR
866 "Display information for a route distinguisher\n"
867 "VPN Route Distinguisher\n"
868 "Display BGP tags for prefixes\n")
869 {
870 int idx_ext_community = 5;
871 int ret;
872 struct prefix_rd prd;
873 afi_t afi;
874 int idx = 0;
875
876 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
877 {
878 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
879 if (! ret)
880 {
881 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
882 return CMD_WARNING;
883 }
884 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 1, 0);
885 }
886 return CMD_SUCCESS;
887 }
888
889 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
890 show_ip_bgp_vpn_all_neighbor_routes_cmd,
891 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
892 SHOW_STR
893 IP_STR
894 BGP_STR
895 BGP_VPNVX_HELP_STR
896 "Display information about all VPNv4/VPNv6 NLRIs\n"
897 "Detailed information on TCP and BGP neighbor connections\n"
898 "Neighbor to display information about\n"
899 "Display routes learned from neighbor\n"
900 JSON_STR)
901 {
902 int idx_ipv4 = 6;
903 union sockunion su;
904 struct peer *peer;
905 int ret;
906 u_char uj = use_json(argc, argv);
907 afi_t afi;
908 int idx = 0;
909
910 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
911 {
912 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
913 if (ret < 0)
914 {
915 if (uj)
916 {
917 json_object *json_no = NULL;
918 json_no = json_object_new_object();
919 json_object_string_add(json_no, "warning", "Malformed address");
920 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
921 json_object_free(json_no);
922 }
923 else
924 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
925 return CMD_WARNING;
926 }
927
928 peer = peer_lookup (NULL, &su);
929 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
930 {
931 if (uj)
932 {
933 json_object *json_no = NULL;
934 json_no = json_object_new_object();
935 json_object_string_add(json_no, "warning", "No such neighbor or address family");
936 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
937 json_object_free(json_no);
938 }
939 else
940 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
941 return CMD_WARNING;
942 }
943
944 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
945 }
946 return CMD_SUCCESS;
947 }
948
949 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
950 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
951 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
952 SHOW_STR
953 IP_STR
954 BGP_STR
955 BGP_VPNVX_HELP_STR
956 "Display information for a route distinguisher\n"
957 "VPN Route Distinguisher\n"
958 "Detailed information on TCP and BGP neighbor connections\n"
959 "Neighbor to display information about\n"
960 "Display routes learned from neighbor\n"
961 JSON_STR)
962 {
963 int idx_ext_community = 5;
964 int idx_ipv4 = 7;
965 int ret;
966 union sockunion su;
967 struct peer *peer;
968 struct prefix_rd prd;
969 u_char uj = use_json(argc, argv);
970 afi_t afi;
971 int idx = 0;
972
973 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
974 {
975 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
976 if (! ret)
977 {
978 if (uj)
979 {
980 json_object *json_no = NULL;
981 json_no = json_object_new_object();
982 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
983 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
984 json_object_free(json_no);
985 }
986 else
987 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
988 return CMD_WARNING;
989 }
990
991 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
992 if (ret < 0)
993 {
994 if (uj)
995 {
996 json_object *json_no = NULL;
997 json_no = json_object_new_object();
998 json_object_string_add(json_no, "warning", "Malformed address");
999 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1000 json_object_free(json_no);
1001 }
1002 else
1003 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1004 return CMD_WARNING;
1005 }
1006
1007 peer = peer_lookup (NULL, &su);
1008 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1009 {
1010 if (uj)
1011 {
1012 json_object *json_no = NULL;
1013 json_no = json_object_new_object();
1014 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1015 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1016 json_object_free(json_no);
1017 }
1018 else
1019 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1020 return CMD_WARNING;
1021 }
1022
1023 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
1024 }
1025 return CMD_SUCCESS;
1026 }
1027
1028 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1029 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1030 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1031 SHOW_STR
1032 IP_STR
1033 BGP_STR
1034 BGP_VPNVX_HELP_STR
1035 "Display information about all VPNv4/VPNv6 NLRIs\n"
1036 "Detailed information on TCP and BGP neighbor connections\n"
1037 "Neighbor to display information about\n"
1038 "Display the routes advertised to a BGP neighbor\n"
1039 JSON_STR)
1040 {
1041 int idx_ipv4 = 6;
1042 int ret;
1043 struct peer *peer;
1044 union sockunion su;
1045 u_char uj = use_json(argc, argv);
1046 afi_t afi;
1047 int idx = 0;
1048
1049 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1050 {
1051 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1052 if (ret < 0)
1053 {
1054 if (uj)
1055 {
1056 json_object *json_no = NULL;
1057 json_no = json_object_new_object();
1058 json_object_string_add(json_no, "warning", "Malformed address");
1059 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1060 json_object_free(json_no);
1061 }
1062 else
1063 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1064 return CMD_WARNING;
1065 }
1066 peer = peer_lookup (NULL, &su);
1067 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1068 {
1069 if (uj)
1070 {
1071 json_object *json_no = NULL;
1072 json_no = json_object_new_object();
1073 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1074 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1075 json_object_free(json_no);
1076 }
1077 else
1078 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1079 return CMD_WARNING;
1080 }
1081 return show_adj_route_vpn (vty, peer, NULL, AFI_IP, SAFI_MPLS_VPN, uj);
1082 }
1083 return CMD_SUCCESS;
1084 }
1085
1086 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1087 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
1088 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1089 SHOW_STR
1090 IP_STR
1091 BGP_STR
1092 BGP_VPNVX_HELP_STR
1093 "Display information for a route distinguisher\n"
1094 "VPN Route Distinguisher\n"
1095 "Detailed information on TCP and BGP neighbor connections\n"
1096 "Neighbor to display information about\n"
1097 "Display the routes advertised to a BGP neighbor\n"
1098 JSON_STR)
1099 {
1100 int idx_ext_community = 5;
1101 int idx_ipv4 = 7;
1102 int ret;
1103 struct peer *peer;
1104 struct prefix_rd prd;
1105 union sockunion su;
1106 u_char uj = use_json(argc, argv);
1107 afi_t afi;
1108 int idx = 0;
1109
1110 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1111 {
1112 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1113 if (ret < 0)
1114 {
1115 if (uj)
1116 {
1117 json_object *json_no = NULL;
1118 json_no = json_object_new_object();
1119 json_object_string_add(json_no, "warning", "Malformed address");
1120 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1121 json_object_free(json_no);
1122 }
1123 else
1124 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1125 return CMD_WARNING;
1126 }
1127 peer = peer_lookup (NULL, &su);
1128 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1129 {
1130 if (uj)
1131 {
1132 json_object *json_no = NULL;
1133 json_no = json_object_new_object();
1134 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1135 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1136 json_object_free(json_no);
1137 }
1138 else
1139 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1140 return CMD_WARNING;
1141 }
1142
1143 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1144 if (! ret)
1145 {
1146 if (uj)
1147 {
1148 json_object *json_no = NULL;
1149 json_no = json_object_new_object();
1150 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1151 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1152 json_object_free(json_no);
1153 }
1154 else
1155 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1156 return CMD_WARNING;
1157 }
1158
1159 return show_adj_route_vpn (vty, peer, &prd, AFI_IP, SAFI_MPLS_VPN, uj);
1160 }
1161 return CMD_SUCCESS;
1162 }
1163 #endif /* KEEP_OLD_VPN_COMMANDS */
1164
1165 void
1166 bgp_mplsvpn_init (void)
1167 {
1168 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
1169 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1170 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1171
1172 install_element (BGP_VPNV6_NODE, &vpnv6_network_cmd);
1173 install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
1174
1175 install_element (VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
1176 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
1177 #ifdef KEEP_OLD_VPN_COMMANDS
1178 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1179 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1180 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1181 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1182 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1183 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1184 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
1185 #endif /* KEEP_OLD_VPN_COMMANDS */
1186 }