bgpd: handle AS4 and EOI route distinguishers
Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 3eab76f..bbc739b 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -54,6 +54,7 @@
return l;
}
+/* type == RD_TYPE_AS */
static void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
{
@@ -66,6 +67,20 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 b221c3b..0cb9dec 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -23,6 +23,8 @@
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
+#define RD_TYPE_AS4 2
+#define RD_TYPE_EOI 0xff00
#define RD_ADDRSTRLEN 28