diff options
author | Lou Berger <lberger@labn.net> | 2016-01-12 13:41:55 -0500 |
---|---|---|
committer | Paul Jakma <paul.jakma@hpe.com> | 2016-02-26 14:11:42 +0000 |
commit | 9da04bca0e994ec92b9242159bf27d89c6743354 (patch) | |
tree | 3c38048088082749e2ba7f03f15bdbff19234f0c /bgpd | |
parent | a03bd16eedc5077e98716509b8918ed365227e02 (diff) | |
download | quagga-9da04bca0e994ec92b9242159bf27d89c6743354.tar.bz2 quagga-9da04bca0e994ec92b9242159bf27d89c6743354.tar.xz |
bgpd: wire up VPNv6 protocol processing
There wasn't much missing for VPNv6 to begin with; just a few bits of
de- & encoding and a few lists to be updated.
Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
[Editorial note: Signed-off-by may imply an authorship claim, but need not]
Edited-by: Paul Jakma <paul.jakma@hpe.com> / <paul@jakma.org>
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_attr.c | 25 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 23 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_open.c | 15 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 32 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 6 | ||||
-rw-r--r-- | bgpd/bgpd.c | 11 |
7 files changed, 96 insertions, 18 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index ce8f8a08..ecf1c314 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1535,11 +1535,36 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args, stream_get (&attre->mp_nexthop_global_in, s, 4); break; #ifdef HAVE_IPV6 + case 24: + { + u_int32_t rd_high __attribute__((unused)); + u_int32_t rd_low __attribute__((unused)); + + rd_high = stream_getl (s); + rd_low = stream_getl (s); + } + /* fall through */ case 16: stream_get (&attre->mp_nexthop_global, s, 16); break; case 32: + case 48: + if (attre->mp_nexthop_len == 48) { + u_int32_t rd_high __attribute__((unused)); + u_int32_t rd_low __attribute__((unused)); + + rd_high = stream_getl (s); + rd_low = stream_getl (s); + } stream_get (&attre->mp_nexthop_global, s, 16); + + if (attre->mp_nexthop_len == 48) { + u_int32_t rd_high __attribute__((unused)); + u_int32_t rd_low __attribute__((unused)); + + rd_high = stream_getl (s); + rd_low = stream_getl (s); + } stream_get (&attre->mp_nexthop_local, s, 16); if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local)) { diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index bbc739bb..78a71e70 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -92,13 +92,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; @@ -191,11 +191,11 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr, psize - VPN_PREFIXLEN_MIN_BYTES); if (attr) - bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0); + bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0); else - bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt); + bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt); } /* Packet length consistency check. */ if (pnt != lim) @@ -480,6 +480,7 @@ static int bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, int tags) { + afi_t afi = AFI_IP; struct bgp *bgp; struct bgp_table *table; struct bgp_node *rn; @@ -497,7 +498,13 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty return CMD_WARNING; } - 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 0cb9deca..4e9b317b 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 7a5f5ce0..302e4ce5 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -842,7 +842,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]) { plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not " "overlap with received MP capabilities", @@ -1012,6 +1013,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 ec60069d..16e1435a 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1797,12 +1797,12 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) if (peer->afc[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); @@ -1886,12 +1886,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 @@ -1905,6 +1905,30 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) 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 (BGP_DEBUG (update, UPDATE_IN)) + zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 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 efbd8dbb..6f3af9ea 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7303,11 +7303,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"; } @@ -7650,6 +7652,8 @@ bgp_show_peer (struct vty *vty, struct peer *p) || 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 2325f07c..c3c0dba3 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -978,6 +978,8 @@ peer_as_change (struct peer *peer, as_t as) 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 */ @@ -1394,7 +1396,8 @@ peer_group_active (struct peer *peer) || peer->af_group[AFI_IP][SAFI_MULTICAST] || peer->af_group[AFI_IP][SAFI_MPLS_VPN] || peer->af_group[AFI_IP6][SAFI_UNICAST] - || peer->af_group[AFI_IP6][SAFI_MULTICAST]) + || peer->af_group[AFI_IP6][SAFI_MULTICAST] + || peer->af_group[AFI_IP6][SAFI_MPLS_VPN]) return 1; return 0; } @@ -2335,7 +2338,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; } @@ -2348,7 +2352,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; } |