summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorLou Berger <lberger@labn.net>2016-01-12 13:41:54 -0500
committerPaul Jakma <paul.jakma@hpe.com>2016-02-26 14:11:42 +0000
commita03bd16eedc5077e98716509b8918ed365227e02 (patch)
treece2cdce1e28a98318bd4605e7f70c43267cc5eb7 /bgpd
parenta76d9ca3584c1751a592457c167c1e146648ceb6 (diff)
downloadquagga-a03bd16eedc5077e98716509b8918ed365227e02.tar.bz2
quagga-a03bd16eedc5077e98716509b8918ed365227e02.tar.xz
bgpd: handle AS4 and EOI route distinguishers
Signed-off-by: Lou Berger <lberger@labn.net> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_mplsvpn.c80
-rw-r--r--bgpd/bgp_mplsvpn.h2
2 files changed, 61 insertions, 21 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 3eab76fc..bbc739bb 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -54,6 +54,7 @@ decode_label (u_char *pnt)
return l;
}
+/* type == RD_TYPE_AS */
static void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
{
@@ -66,6 +67,20 @@ decode_rd_as (u_char *pnt, struct rd_as *rd_as)
rd_as->val |= (u_int32_t) *pnt;
}
+/* type == RD_TYPE_AS4 */
+static void
+decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
+{
+ rd_as->as = (u_int32_t) *pnt++ << 24;
+ rd_as->as |= (u_int32_t) *pnt++ << 16;
+ rd_as->as |= (u_int32_t) *pnt++ << 8;
+ rd_as->as |= (u_int32_t) *pnt++;
+
+ rd_as->val = ((u_int16_t) *pnt++ << 8);
+ rd_as->val |= (u_int16_t) *pnt;
+}
+
+/* type == RD_TYPE_IP */
static void
decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
{
@@ -149,30 +164,32 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
/* Decode RD type. */
type = decode_rd_type (pnt + 3);
- /* Decode RD value. */
- if (type == RD_TYPE_AS)
- decode_rd_as (pnt + 5, &rd_as);
- else if (type == RD_TYPE_IP)
- decode_rd_ip (pnt + 5, &rd_ip);
- else
- {
- zlog_err ("Invalid RD type %d", type);
- return -1;
- }
+ switch (type)
+ {
+ case RD_TYPE_AS:
+ decode_rd_as (pnt + 5, &rd_as);
+ break;
+
+ case RD_TYPE_AS4:
+ decode_rd_as4 (pnt + 5, &rd_as);
+ break;
+
+ case RD_TYPE_IP:
+ decode_rd_ip (pnt + 5, &rd_ip);
+ break;
+
+ case RD_TYPE_EOI:
+ break;
+
+ default:
+ zlog_err ("Invalid RD type %d", type);
+ return -1;
+ }
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
psize - VPN_PREFIXLEN_MIN_BYTES);
-#if 0
- if (type == RD_TYPE_AS)
- zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
- inet_ntoa (p.u.prefix4), p.prefixlen);
- else if (type == RD_TYPE_IP)
- zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
- rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
-#endif /* 0 */
-
if (attr)
bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
@@ -294,12 +311,25 @@ prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
return buf;
}
+ else if (type == RD_TYPE_AS4)
+ {
+ decode_rd_as4 (pnt + 2, &rd_as);
+ snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
+ return buf;
+ }
else if (type == RD_TYPE_IP)
{
decode_rd_ip (pnt + 2, &rd_ip);
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
return buf;
}
+ else if (type == RD_TYPE_EOI)
+ {
+ snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
+ pnt[1], /* LHI */
+ pnt[2], pnt[3], pnt[4], pnt[5], pnt[6], pnt[7]); /* MAC */
+ return buf;
+ }
return NULL;
}
@@ -406,6 +436,8 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
@@ -413,6 +445,8 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
if (type == RD_TYPE_AS)
vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
@@ -513,15 +547,19 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
vty_out (vty, "Route Distinguisher: ");
if (type == RD_TYPE_AS)
- vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
- vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+ vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
vty_out (vty, "%s", VTY_NEWLINE);
rd_header = 0;
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index b221c3bd..0cb9deca 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -23,6 +23,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
+#define RD_TYPE_AS4 2
+#define RD_TYPE_EOI 0xff00
#define RD_ADDRSTRLEN 28