summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorLou Berger <lberger@labn.net>2016-01-12 13:41:55 -0500
committerPaul Jakma <paul.jakma@hpe.com>2016-02-26 14:11:42 +0000
commit9da04bca0e994ec92b9242159bf27d89c6743354 (patch)
tree3c38048088082749e2ba7f03f15bdbff19234f0c /bgpd
parenta03bd16eedc5077e98716509b8918ed365227e02 (diff)
downloadquagga-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.c25
-rw-r--r--bgpd/bgp_mplsvpn.c23
-rw-r--r--bgpd/bgp_mplsvpn.h2
-rw-r--r--bgpd/bgp_open.c15
-rw-r--r--bgpd/bgp_packet.c32
-rw-r--r--bgpd/bgp_vty.c6
-rw-r--r--bgpd/bgpd.c11
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;
}