From a03bd16eedc5077e98716509b8918ed365227e02 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Tue, 12 Jan 2016 13:41:54 -0500 Subject: bgpd: handle AS4 and EOI route distinguishers Signed-off-by: Lou Berger Signed-off-by: David Lamparter --- bgpd/bgp_mplsvpn.c | 80 ++++++++++++++++++++++++++++++++++++++++-------------- bgpd/bgp_mplsvpn.h | 2 ++ 2 files changed, 61 insertions(+), 21 deletions(-) (limited to 'bgpd') 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 -- cgit v1.2.3