2 * This file created by LabN Consulting, L.L.C.
4 * This file is based on bgp_mplsvpn.c which is Copyright (C) 2000
5 * Kunihiro Ishiguro <kunihiro@zebra.org>
7 * This file is part of GNU Zebra.
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "bgpd/bgpd.h"
34 #include "bgpd/bgp_table.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_attr.h"
37 #include "bgpd/bgp_ecommunity.h"
38 #include "bgpd/bgp_lcommunity.h"
39 #include "bgpd/bgp_mplsvpn.h"
40 #include "bgpd/bgp_vty.h"
41 #include "bgpd/bgp_encap.h"
44 #include "bgpd/rfapi/rfapi_backend.h"
48 ecom2prd(struct ecommunity
*ecom
, struct prefix_rd
*prd
)
52 memset(prd
, 0, sizeof(struct prefix_rd
));
53 prd
->family
= AF_UNSPEC
;
59 for (i
= 0; i
< (ecom
->size
* ECOMMUNITY_SIZE
); i
+= ECOMMUNITY_SIZE
) {
73 prd
->val
[1] = ep
[0] & 0x03;
74 memcpy(prd
->val
+ 2, ep
+ 2, 6);
85 struct bgp_nlri
*packet
)
89 afi_t afi
= packet
->afi
;
96 struct ecommunity
*pEcom
= NULL
;
97 u_int16_t rdtype
= 0xffff;
100 /* Check peer status. */
101 if (peer
->status
!= Established
)
105 if (attr
&& attr
->extra
&& attr
->extra
->ecommunity
)
106 pEcom
= attr
->extra
->ecommunity
;
108 ecom2prd(pEcom
, &prd
);
109 memset(&rd_as
, 0, sizeof(rd_as
));
110 memset(&rd_ip
, 0, sizeof(rd_ip
));
114 rdtype
= (prd
.val
[0] << 8) | prd
.val
[1];
116 /* Decode RD value. */
117 if (rdtype
== RD_TYPE_AS
)
118 decode_rd_as (prd
.val
+ 2, &rd_as
);
119 else if (rdtype
== RD_TYPE_IP
)
120 decode_rd_ip (prd
.val
+ 2, &rd_ip
);
121 else if (rdtype
== RD_TYPE_AS4
)
122 decode_rd_as4 (prd
.val
+ 2, &rd_as
);
125 zlog_err ("Invalid RD type %d", rdtype
);
131 * NB: this code was based on the MPLS VPN code, which supported RDs.
132 * For the moment we are retaining the underlying RIB structure that
133 * keeps a per-RD radix tree, but since the RDs are not carried over
134 * the wire, we set the RD internally to 0.
136 prd
.family
= AF_UNSPEC
;
138 memset(prd
.val
, 0, sizeof(prd
.val
));
141 lim
= pnt
+ packet
->length
;
143 for (; pnt
< lim
; pnt
+= psize
)
145 /* Clear prefix structure. */
146 memset (&p
, 0, sizeof (struct prefix
));
148 /* Fetch prefix length. */
150 p
.family
= afi2family(afi
);
152 /* bad afi, shouldn't happen */
153 zlog_warn("%s: bad afi %d, dropping incoming route", __func__
, afi
);
156 psize
= PSIZE (prefixlen
);
158 p
.prefixlen
= prefixlen
;
159 memcpy (&p
.u
.prefix
, pnt
, psize
);
161 if (pnt
+ psize
> lim
)
165 if (rdtype
== RD_TYPE_AS
)
166 zlog_info ("rd-as %u:%u prefix %s/%d", rd_as
.as
, rd_as
.val
,
167 inet_ntop (p
.family
, &p
.u
.prefix
, buf
, BUFSIZ
),
169 else if (rdtype
== RD_TYPE_IP
)
170 zlog_info ("rd-ip %s:%u prefix %s/%d", inet_ntoa (rd_ip
.ip
),
172 inet_ntop (p
.family
, &p
.u
.prefix
, buf
, BUFSIZ
),
174 else if (rdtype
== RD_TYPE_AS4
)
175 zlog_info ("rd-as4 %u:%u prefix %s/%d", rd_as
.as
, rd_as
.val
,
176 inet_ntop (p
.family
, &p
.u
.prefix
, buf
, BUFSIZ
),
179 zlog_info ("rd unknown, default to 0:0 prefix %s/%d",
180 inet_ntop (p
.family
, &p
.u
.prefix
, buf
, BUFSIZ
),
184 bgp_update (peer
, &p
, 0, attr
, afi
, SAFI_ENCAP
,
185 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, NULL
, 0, NULL
);
187 bgp_withdraw (peer
, &p
, 0, attr
, afi
, SAFI_ENCAP
,
188 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, NULL
, NULL
);
192 /* Packet length consistency check. */
200 /* TBD: these routes should probably all be host routes */
202 /* For testing purpose, static route of ENCAP. */
203 DEFUN (encap_network
,
205 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
206 "Specify a network to announce via BGP\n"
208 "Specify Route Distinguisher\n"
209 "ENCAP Route Distinguisher\n"
216 return bgp_static_set_safi (SAFI_ENCAP
, vty
, argv
[idx_ipv4
]->arg
, argv
[idx_rd
]->arg
, argv
[idx_word
]->arg
,
217 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
220 /* For testing purpose, static route of ENCAP. */
221 DEFUN (no_encap_network
,
222 no_encap_network_cmd
,
223 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
225 "Specify a network to announce via BGP\n"
227 "Specify Route Distinguisher\n"
228 "ENCAP Route Distinguisher\n"
235 return bgp_static_unset_safi (SAFI_ENCAP
, vty
, argv
[idx_ipv4
]->arg
, argv
[idx_rd
]->arg
, argv
[idx_word
]->arg
,
236 0, NULL
, NULL
, NULL
);
240 show_adj_route_encap (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
)
243 struct bgp_table
*table
;
249 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
251 bgp
= bgp_get_default ();
254 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
258 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][SAFI_ENCAP
]); rn
;
259 rn
= bgp_route_next (rn
))
261 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
264 if ((table
= rn
->info
) != NULL
)
268 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
269 if ((attr
= rm
->info
) != NULL
)
273 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
274 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
275 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
277 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
278 VTY_NEWLINE
, VTY_NEWLINE
);
279 vty_out (vty
, v4_header
, VTY_NEWLINE
);
292 vty_out (vty
, "Route Distinguisher: ");
294 /* Decode RD type. */
295 type
= decode_rd_type (pnt
);
300 decode_rd_as (pnt
+ 2, &rd_as
);
301 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
305 decode_rd_ip (pnt
+ 2, &rd_ip
);
306 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
310 vty_out (vty
, "unknown RD type");
314 vty_out (vty
, "%s", VTY_NEWLINE
);
317 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_ENCAP
, 0, NULL
);
328 struct prefix_rd
*prd
,
329 enum bgp_show_type type
,
334 struct bgp_table
*table
;
340 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
341 char v4_header_tag
[] = " Network Next Hop In tag/Out tag%s";
343 unsigned long output_count
= 0;
344 unsigned long total_count
= 0;
346 bgp
= bgp_get_default ();
349 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
353 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
)) {
354 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
358 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_ENCAP
]); rn
; rn
= bgp_route_next (rn
))
360 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
363 if ((table
= rn
->info
) != NULL
)
367 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
368 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
371 if (type
== bgp_show_type_neighbor
)
373 union sockunion
*su
= output_arg
;
375 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
381 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
384 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
385 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
386 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
388 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
389 VTY_NEWLINE
, VTY_NEWLINE
);
390 vty_out (vty
, v4_header
, VTY_NEWLINE
);
404 /* Decode RD type. */
405 type
= decode_rd_type (pnt
);
407 vty_out (vty
, "Route Distinguisher: ");
412 decode_rd_as (pnt
+ 2, &rd_as
);
413 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
417 decode_rd_ip (pnt
+ 2, &rd_ip
);
418 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
422 vty_out (vty
, "Unknown RD type");
426 vty_out (vty
, "%s", VTY_NEWLINE
);
430 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_ENCAP
, NULL
);
432 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_ENCAP
, NULL
);
438 if (output_count
== 0)
440 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
443 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
444 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
449 DEFUN (show_bgp_ipv4_encap_rd
,
450 show_bgp_ipv4_encap_rd_cmd
,
451 "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn",
456 "Display ENCAP NLRI specific information\n"
457 "Display information for a route distinguisher\n"
458 "ENCAP Route Distinguisher\n")
462 struct prefix_rd prd
;
464 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
467 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
470 return bgp_show_encap (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0);
473 DEFUN (show_bgp_ipv6_encap_rd
,
474 show_bgp_ipv6_encap_rd_cmd
,
475 "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn",
480 "Display ENCAP NLRI specific information\n"
481 "Display information for a route distinguisher\n"
482 "ENCAP Route Distinguisher\n"
483 "Display BGP tags for prefixes\n")
487 struct prefix_rd prd
;
489 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
492 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
495 return bgp_show_encap (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 0);
498 DEFUN (show_bgp_ipv4_encap_tags
,
499 show_bgp_ipv4_encap_tags_cmd
,
500 "show [ip] bgp ipv4 encap tags",
505 "Display ENCAP NLRI specific information\n"
506 "Display BGP tags for prefixes\n")
508 return bgp_show_encap (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 1);
511 DEFUN (show_bgp_ipv6_encap_tags
,
512 show_bgp_ipv6_encap_tags_cmd
,
513 "show [ip] bgp ipv6 encap tags",
518 "Display ENCAP NLRI specific information\n"
519 "Display BGP tags for prefixes\n")
521 return bgp_show_encap (vty
, AFI_IP6
, NULL
, bgp_show_type_normal
, NULL
, 1);
524 DEFUN (show_bgp_ipv4_encap_rd_tags
,
525 show_bgp_ipv4_encap_rd_tags_cmd
,
526 "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags",
531 "Display ENCAP NLRI specific information\n"
532 "Display information for a route distinguisher\n"
533 "ENCAP Route Distinguisher\n"
534 "Display BGP tags for prefixes\n")
538 struct prefix_rd prd
;
540 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
543 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
546 return bgp_show_encap (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 1);
549 DEFUN (show_bgp_ipv6_encap_rd_tags
,
550 show_bgp_ipv6_encap_rd_tags_cmd
,
551 "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags",
556 "Display ENCAP NLRI specific information\n"
557 "Display information for a route distinguisher\n"
558 "ENCAP Route Distinguisher\n"
559 "Display BGP tags for prefixes\n")
563 struct prefix_rd prd
;
565 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
568 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
571 return bgp_show_encap (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 1);
574 DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes
,
575 show_bgp_ipv4_encap_rd_neighbor_routes_cmd
,
576 "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes",
581 "Display ENCAP NLRI specific information\n"
582 "Display information for a route distinguisher\n"
583 "ENCAP Route Distinguisher\n"
584 "Detailed information on TCP and BGP neighbor connections\n"
585 "Neighbor to display information about\n"
586 "Neighbor to display information about\n"
587 "Display routes learned from neighbor\n")
594 struct prefix_rd prd
;
596 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
599 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
603 if (str2sockunion(argv
[idx_peer
]->arg
, &su
))
605 vty_out (vty
, "Malformed address: %s%s", argv
[idx_peer
]->arg
, VTY_NEWLINE
);
609 peer
= peer_lookup (NULL
, &su
);
610 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_ENCAP
])
612 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
616 return bgp_show_encap (vty
, AFI_IP
, &prd
, bgp_show_type_neighbor
, &su
, 0);
619 DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes
,
620 show_bgp_ipv6_encap_rd_neighbor_routes_cmd
,
621 "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes",
626 "Display ENCAP NLRI specific information\n"
627 "Display information for a route distinguisher\n"
628 "ENCAP Route Distinguisher\n"
629 "Detailed information on TCP and BGP neighbor connections\n"
630 "Neighbor to display information about\n"
631 "Neighbor to display information about\n"
632 "Display routes learned from neighbor\n")
639 struct prefix_rd prd
;
641 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
644 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
648 if (str2sockunion(argv
[idx_peer
]->arg
, &su
))
650 vty_out (vty
, "Malformed address: %s%s", argv
[idx_peer
]->arg
, VTY_NEWLINE
);
654 peer
= peer_lookup (NULL
, &su
);
655 if (! peer
|| ! peer
->afc
[AFI_IP6
][SAFI_ENCAP
])
657 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
661 return bgp_show_encap (vty
, AFI_IP6
, &prd
, bgp_show_type_neighbor
, &su
, 0);
664 DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes
,
665 show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd
,
666 "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes",
671 "Display ENCAP NLRI specific information\n"
672 "Display information for a route distinguisher\n"
673 "ENCAP Route Distinguisher\n"
674 "Detailed information on TCP and BGP neighbor connections\n"
675 "Neighbor to display information about\n"
676 "Neighbor to display information about\n"
677 "Display the routes advertised to a BGP neighbor\n")
683 struct prefix_rd prd
;
686 ret
= str2sockunion (argv
[idx_peer
]->arg
, &su
);
689 vty_out (vty
, "%% Malformed address: %s%s", argv
[idx_peer
]->arg
, VTY_NEWLINE
);
692 peer
= peer_lookup (NULL
, &su
);
693 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_ENCAP
])
695 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
699 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
702 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
706 return show_adj_route_encap (vty
, peer
, &prd
);
709 DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes
,
710 show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd
,
711 "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes",
716 "Display ENCAP NLRI specific information\n"
717 "Display information for a route distinguisher\n"
718 "ENCAP Route Distinguisher\n"
719 "Detailed information on TCP and BGP neighbor connections\n"
720 "Neighbor to display information about\n"
721 "Neighbor to display information about\n"
722 "Display the routes advertised to a BGP neighbor\n")
728 struct prefix_rd prd
;
731 ret
= str2sockunion (argv
[idx_peer
]->arg
, &su
);
734 vty_out (vty
, "%% Malformed address: %s%s", argv
[idx_peer
]->arg
, VTY_NEWLINE
);
737 peer
= peer_lookup (NULL
, &su
);
738 if (! peer
|| ! peer
->afc
[AFI_IP6
][SAFI_ENCAP
])
740 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
744 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
747 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
751 return show_adj_route_encap (vty
, peer
, &prd
);
755 bgp_encap_init (void)
757 install_element (BGP_ENCAP_NODE
, &encap_network_cmd
);
758 install_element (BGP_ENCAP_NODE
, &no_encap_network_cmd
);
760 install_element (VIEW_NODE
, &show_bgp_ipv4_encap_rd_cmd
);
761 install_element (VIEW_NODE
, &show_bgp_ipv4_encap_tags_cmd
);
762 install_element (VIEW_NODE
, &show_bgp_ipv4_encap_rd_tags_cmd
);
763 install_element (VIEW_NODE
, &show_bgp_ipv4_encap_rd_neighbor_routes_cmd
);
764 install_element (VIEW_NODE
, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd
);
766 install_element (VIEW_NODE
, &show_bgp_ipv6_encap_rd_cmd
);
767 install_element (VIEW_NODE
, &show_bgp_ipv6_encap_tags_cmd
);
768 install_element (VIEW_NODE
, &show_bgp_ipv6_encap_rd_tags_cmd
);
769 install_element (VIEW_NODE
, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd
);
770 install_element (VIEW_NODE
, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd
);