diff options
-rw-r--r-- | bgpd/bgp_attr.c | 17 | ||||
-rw-r--r-- | bgpd/bgp_attr.h | 4 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 19 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_open.c | 15 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 37 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 6 | ||||
-rw-r--r-- | bgpd/bgpd.c | 8 |
8 files changed, 92 insertions, 16 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 844bc0fd9..ad8c7641e 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1601,10 +1601,27 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args, break; #ifdef HAVE_IPV6 case BGP_ATTR_NHLEN_IPV6_GLOBAL: + case BGP_ATTR_NHLEN_VPNV6_GLOBAL: + if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) + { + stream_getl (s); /* RD high */ + stream_getl (s); /* RD low */ + } stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN); break; case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: + case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL: + if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) + { + stream_getl (s); /* RD high */ + stream_getl (s); /* RD low */ + } stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN); + if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) + { + stream_getl (s); /* RD high */ + stream_getl (s); /* RD low */ + } stream_get (&attre->mp_nexthop_local, s, IPV6_MAX_BYTELEN); if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local)) { diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index d71cb6805..da9bfec49 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -49,9 +49,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA /* Valid lengths for mp_nexthop_len */ #define BGP_ATTR_NHLEN_IPV4 IPV4_MAX_BYTELEN -#define BGP_ATTR_NHLEN_VPNV4 12 +#define BGP_ATTR_NHLEN_VPNV4 8+IPV4_MAX_BYTELEN #define BGP_ATTR_NHLEN_IPV6_GLOBAL IPV6_MAX_BYTELEN #define BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL (IPV6_MAX_BYTELEN * 2) +#define BGP_ATTR_NHLEN_VPNV6_GLOBAL 8+IPV6_MAX_BYTELEN +#define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2) /* Additional/uncommon BGP attributes. * lazily allocated as and when a struct attr diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 206d23f94..9f27c9add 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -93,13 +93,13 @@ decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip) } int -bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr, - struct bgp_nlri *packet) +bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, + struct bgp_nlri *packet) { u_char *pnt; u_char *lim; struct prefix p; - int psize; + int psize = 0; int prefixlen; u_int16_t type; struct rd_as rd_as; @@ -219,10 +219,10 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr, psize - VPN_PREFIXLEN_MIN_BYTES); if (attr) - bgp_update (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN, + bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0); else - bgp_withdraw (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN, + bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt); } /* Packet length consistency check. */ @@ -572,6 +572,7 @@ static int bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, int tags, u_char use_json) { + afi_t afi = AFI_IP; struct bgp *bgp; struct bgp_table *table; struct bgp_node *rn; @@ -616,7 +617,13 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty json_object_string_add(json_ocode, "incomplete", "?"); } - for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn)) + if ((afi != AFI_IP) && (afi != AFI_IP6)) + { + vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE); + return CMD_WARNING; + } + + for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn)) { if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) continue; diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 0cb9decac..4e9b317b7 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -43,7 +43,7 @@ struct rd_ip }; extern void bgp_mplsvpn_init (void); -extern int bgp_nlri_parse_vpnv4 (struct peer *, struct attr *, struct bgp_nlri *); +extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *); extern u_int32_t decode_label (u_char *); extern int str2prefix_rd (const char *, struct prefix_rd *); extern int str2tag (const char *, u_char *); diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 1444a5837..8be906d39 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -1124,7 +1124,8 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability) && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST] && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST] - && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) + && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST] + && ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]) { zlog_err ("%s [Error] Configured AFI/SAFIs do not " "overlap with received MP capabilities", @@ -1316,6 +1317,18 @@ bgp_open_capability (struct stream *s, struct peer *peer) stream_putc (s, 0); stream_putc (s, SAFI_MULTICAST); } + /* IPv6 VPN. */ + if (peer->afc[AFI_IP6][SAFI_MPLS_VPN]) + { + peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1; + stream_putc (s, BGP_OPEN_OPT_CAP); + stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); + stream_putc (s, CAPABILITY_CODE_MP); + stream_putc (s, CAPABILITY_CODE_MP_LEN); + stream_putw (s, AFI_IP6); + stream_putc (s, 0); + stream_putc (s, SAFI_MPLS_LABELED_VPN); + } #endif /* HAVE_IPV6 */ /* Route refresh. */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9d931da10..02f5e82d4 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1528,12 +1528,12 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) if (peer->afc_nego[AFI_IP][SAFI_MULTICAST]) { if (mp_update.length - && mp_update.afi == AFI_IP + && mp_update.afi == AFI_IP && mp_update.safi == SAFI_MULTICAST) bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); if (mp_withdraw.length - && mp_withdraw.afi == AFI_IP + && mp_withdraw.afi == AFI_IP && mp_withdraw.safi == SAFI_MULTICAST) bgp_nlri_parse (peer, NULL, &mp_withdraw); @@ -1631,12 +1631,12 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) if (mp_update.length && mp_update.afi == AFI_IP && mp_update.safi == SAFI_MPLS_LABELED_VPN) - bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update); + bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update); if (mp_withdraw.length && mp_withdraw.afi == AFI_IP && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN) - bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw); + bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw); if (! withdraw_len && mp_withdraw.afi == AFI_IP @@ -1656,6 +1656,35 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) zlog_debug ("rcvd End-of-RIB for VPNv4 Unicast from %s", peer->host); } } + if (peer->afc[AFI_IP6][SAFI_MPLS_VPN]) + { + if (mp_update.length + && mp_update.afi == AFI_IP6 + && mp_update.safi == SAFI_MPLS_LABELED_VPN) + bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update); + + if (mp_withdraw.length + && mp_withdraw.afi == AFI_IP6 + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN) + bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw); + + if (! withdraw_len + && mp_withdraw.afi == AFI_IP6 + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN + && mp_withdraw.length == 0) + { + /* End-of-RIB received */ + if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN], + PEER_STATUS_EOR_RECEIVED)) + { + SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN], PEER_STATUS_EOR_RECEIVED); + bgp_update_explicit_eors(peer); + } + + if (bgp_debug_neighbor_events(peer)) + zlog_debug ("rcvd End-of-RIB for VPNv6 Unicast from %s", peer->host); + } + } /* Everything is done. We unintern temporary structures which interned in bgp_attr_parse(). */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5041e64ee..5fc0b7512 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10460,11 +10460,13 @@ afi_safi_print (afi_t afi, safi_t safi) else if (afi == AFI_IP && safi == SAFI_MULTICAST) return "IPv4 Multicast"; else if (afi == AFI_IP && safi == SAFI_MPLS_VPN) - return "VPNv4 Unicast"; + return "VPN-IPv4 Unicast"; else if (afi == AFI_IP6 && safi == SAFI_UNICAST) return "IPv6 Unicast"; else if (afi == AFI_IP6 && safi == SAFI_MULTICAST) return "IPv6 Multicast"; + else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN) + return "VPN-IPv6 Unicast"; else return "Unknown"; } @@ -11248,6 +11250,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js || p->afc_recv[AFI_IP6][SAFI_UNICAST] || p->afc_adv[AFI_IP6][SAFI_MULTICAST] || p->afc_recv[AFI_IP6][SAFI_MULTICAST] + || p->afc_adv[AFI_IP6][SAFI_MPLS_VPN] + || p->afc_recv[AFI_IP6][SAFI_MPLS_VPN] #endif /* HAVE_IPV6 */ || p->afc_adv[AFI_IP][SAFI_MPLS_VPN] || p->afc_recv[AFI_IP][SAFI_MPLS_VPN]) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index fca6e5bb1..8c2c61f4c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1545,6 +1545,8 @@ peer_as_change (struct peer *peer, as_t as, int as_specified) PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST], PEER_FLAG_REFLECTOR_CLIENT); + UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN], + PEER_FLAG_REFLECTOR_CLIENT); } /* local-as reset */ @@ -3461,7 +3463,8 @@ peer_active (struct peer *peer) || peer->afc[AFI_IP][SAFI_MULTICAST] || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP6][SAFI_UNICAST] - || peer->afc[AFI_IP6][SAFI_MULTICAST]) + || peer->afc[AFI_IP6][SAFI_MULTICAST] + || peer->afc[AFI_IP6][SAFI_MPLS_VPN]) return 1; return 0; } @@ -3474,7 +3477,8 @@ peer_active_nego (struct peer *peer) || peer->afc_nego[AFI_IP][SAFI_MULTICAST] || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] || peer->afc_nego[AFI_IP6][SAFI_UNICAST] - || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) + || peer->afc_nego[AFI_IP6][SAFI_MULTICAST] + || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]) return 1; return 0; } |