From b18825ebc779cd85f9acc40293bb448a09af4cd2 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 5 Sep 2016 14:19:40 +0200 Subject: [PATCH] bgpd: evpn NLRI route type 5 forging This patch introduces the ability to make route type 5 message when EVPN is enabled. Picked up paramters are collected from the bgp extra attribute structure and are the ESI, the ethernet tag information. In addition to this, nexthop attribute is collected too. Signed-off-by: Philippe Guibert --- bgpd/bgp_attr.c | 27 +++++++++------------ bgpd/bgp_attr.h | 5 ++-- bgpd/bgp_evpn.c | 51 ++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_evpn.h | 4 ++++ bgpd/bgp_packet.c | 1 + bgpd/bgp_updgrp_packet.c | 9 +++---- 6 files changed, 75 insertions(+), 22 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index cc2e23ec04..70d8ffbcc7 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -50,6 +50,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # include "bgp_encap_types.h" # include "bgp_vnc_types.h" #endif +#include "bgp_encap_types.h" +#include "bgp_evpn.h" /* Attribute strings for logging. */ static const struct message attr_str [] = @@ -2858,7 +2860,7 @@ void bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi, struct prefix *p, struct prefix_rd *prd, u_char *tag, int addpath_encode, - u_int32_t addpath_tx_id) + u_int32_t addpath_tx_id, struct attr *attr) { if (safi == SAFI_MPLS_VPN) { @@ -2870,6 +2872,10 @@ bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi, stream_put (s, prd->val, 8); stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); } + else if ((safi == SAFI_EVPN)) + { + bgp_packet_mpattr_route_type_5(s, p, prd, tag, attr); + } else stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id); } @@ -3023,7 +3029,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, AFI_MAX), /* get from NH */ vecarr, attr); bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag, - addpath_encode, addpath_tx_id); + addpath_encode, addpath_tx_id, attr); bgp_packet_mpattr_end(s, mpattrlen_pos); } @@ -3431,21 +3437,10 @@ void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, afi_t afi, safi_t safi, struct prefix_rd *prd, u_char *tag, int addpath_encode, - u_int32_t addpath_tx_id) + u_int32_t addpath_tx_id, struct attr *attr) { - if (safi == SAFI_MPLS_VPN) - { - /* addpath TX ID */ - if (addpath_encode) - stream_putl(s, addpath_tx_id); - - stream_putc (s, p->prefixlen + 88); - stream_put (s, tag, 3); - stream_put (s, prd->val, 8); - stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); - } - else - stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id); + return bgp_packet_mpattr_prefix (s, afi, safi, p, prd, + tag, addpath_encode, addpath_tx_id, attr); } void diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 3ccf65029c..bd9d7daf4d 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -294,7 +294,8 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi, extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, struct prefix *p, struct prefix_rd *prd, u_char *tag, int addpath_encode, - u_int32_t addpath_tx_id); + u_int32_t addpath_tx_id, + struct attr *); extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, struct prefix *p); extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep); @@ -303,7 +304,7 @@ extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi); extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, afi_t afi, safi_t safi, struct prefix_rd *prd, - u_char *tag, int, u_int32_t); + u_char *tag, int, u_int32_t, struct attr *); extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt); static inline int diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fd785b9a64..a9db7d2360 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -187,3 +187,54 @@ bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr, return 0; } + +void +bgp_packet_mpattr_route_type_5 (struct stream *s, + struct prefix *p, struct prefix_rd *prd, + u_char *label, struct attr *attr) +{ + int len; + char temp[16]; + struct evpn_addr *p_evpn_p; + + memset(&temp, 0, 16); + if(p->family != AF_ETHERNET) + return; + p_evpn_p = &(p->u.prefix_evpn); + if (p_evpn_p->flags & IP_PREFIX_V4) + len = 8; /* ipv4 */ + else + len = 32; /* ipv6 */ + stream_putc (s, EVPN_IP_PREFIX); + stream_putc (s, 8 /* RD */ + 10 /* ESI */ + 4 /* EthTag */ + 1 + len + 3 /* label */); + stream_put (s, prd->val, 8); + if(attr && attr->extra) + stream_put (s, &(attr->extra->evpn_overlay.eth_s_id), 10); + else + stream_put (s, &temp, 10); + stream_putl (s, p_evpn_p->eth_tag); + stream_putc (s, p_evpn_p->ip_prefix_length); + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr); + else + stream_put(s, &p_evpn_p->ip.v6_addr, 16); + if(attr && attr->extra) + { + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4.s_addr); + else + stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), 16); + } + else + { + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, 0); + else + stream_put(s, &temp, 16); + } + if(label) + stream_put (s, label, 3); + else + stream_put3 (s, 0); + return; +} diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index a493962350..d23509304b 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -24,6 +24,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA extern int bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr, struct bgp_nlri *packet, int withdraw); +extern void +bgp_packet_mpattr_route_type_5 (struct stream *s, + struct prefix *p, struct prefix_rd *prd, + u_char *label, struct attr *attr); /* EVPN route types as per RFC7432 and * as per draft-ietf-bess-evpn-prefix-advertisement-02 */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9a8722a749..0dbf41a4a1 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -51,6 +51,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_evpn.h" #include "bgpd/bgp_encap.h" +#include "bgpd/bgp_evpn.h" #include "bgpd/bgp_advertise.h" #include "bgpd/bgp_vty.h" #include "bgpd/bgp_updgrp.h" diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index ca1bd1e0e6..02979602bf 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -766,8 +766,9 @@ subgroup_update_packet (struct update_subgroup *subgrp) (peer_cap_enhe(peer) ? AFI_IP6 : AFI_MAX), /* get from NH */ &vecarr, adv->baa->attr); - bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag, - addpath_encode, addpath_tx_id); + + bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, + tag, addpath_encode, addpath_tx_id, adv->baa->attr); } num_pfx++; @@ -922,7 +923,7 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp) } bgp_packet_mpunreach_prefix (s, &rn->p, afi, safi, prd, NULL, - addpath_encode, addpath_tx_id); + addpath_encode, addpath_tx_id, NULL); } num_pfx++; @@ -1126,7 +1127,7 @@ subgroup_default_withdraw_packet (struct update_subgroup *subgrp) mplen_pos = bgp_packet_mpunreach_start (s, afi, safi); bgp_packet_mpunreach_prefix (s, &p, afi, safi, NULL, NULL, addpath_encode, - BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); + BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL); /* Set the mp_unreach attr's length */ bgp_packet_mpunreach_end (s, mplen_pos); -- 2.39.5