Mailing List Archive

[PATCH 28/57] 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 <philippe.guibert@6wind.com>
---
bgpd/bgp_attr.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++----
bgpd/bgp_attr.h | 4 ++--
bgpd/bgp_packet.c | 11 +++++----
3 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c7564ae49fb8..5d333c2edbe2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -41,6 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_ecommunity.h"
#include "table.h"
#include "bgp_encap_types.h"
+#include "bgp_evpn.h"

/* Attribute strings for logging. */
static const struct message attr_str [] =
@@ -2499,10 +2500,68 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi,
return sizep;
}

+static void
+bgp_packet_mpattr_route_type_5 (struct stream *s,
+ struct prefix *p, struct prefix_rd *prd,
+ uint32_t *labels, size_t nlabels, struct attr *attr)
+{
+ int len;
+ char temp[16];
+
+ memset(&temp, 0, 16);
+ if(p->family == AF_INET)
+ len = 8; /* ipv4 */
+ else if (p->family == AF_INET6)
+ len = 32; /* ipv6 */
+ else
+ len = 8; /* XXX */
+ 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);
+ if(attr && attr->extra)
+ stream_putl (s, attr->extra->eth_t_id);
+ else
+ stream_putl (s, 0);
+ stream_putc (s, p->prefixlen);
+ if(p->family == AF_INET)
+ stream_put_ipv4(s, p->u.prefix4.s_addr);
+ else if (p->family == AF_INET6)
+ stream_put(s, &p->u.prefix, 16);
+ if(attr && attr->extra)
+ {
+ //CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
+ if(p->family == AF_INET)
+ {
+ if (attr->extra->use_gw)
+ stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4.s_addr);
+ else
+ stream_put_ipv4(s, attr->extra->mp_nexthop_global_in.s_addr);
+ }
+ else if (p->family == AF_INET6)
+ stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), 16);
+ }
+ else
+ {
+ if(p->family == AF_INET)
+ stream_put_ipv4(s, 0);
+ else if (p->family == AF_INET6)
+ stream_put(s, &temp, 16);
+ }
+ if(labels)
+ stream_put3 (s, labels[0]);
+ else
+ stream_put3 (s, 0);
+ return;
+}
+
void
bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd,
- uint32_t *labels, size_t nlabels)
+ uint32_t *labels, size_t nlabels, struct attr *attr)
{
if (safi == SAFI_MPLS_VPN)
{
@@ -2523,6 +2582,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_INTERNAL_EVPN))
+ {
+ bgp_packet_mpattr_route_type_5(s, p, prd, labels, nlabels, attr);
+ }
else
stream_put_prefix (s, p);
}
@@ -2655,7 +2718,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
{
size_t mpattrlen_pos = 0;
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
- bgp_packet_mpattr_prefix(s, afi, safi, p, prd, labels, nlabels);
+ bgp_packet_mpattr_prefix(s, afi, safi, p, prd, labels, nlabels, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos);
}

@@ -3024,9 +3087,9 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
void
bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, struct prefix_rd *prd,
- uint32_t *labels, size_t nlabels)
+ uint32_t *labels, size_t nlabels, struct attr *attr)
{
- bgp_packet_mpattr_prefix (s, afi, safi, p, prd, labels, nlabels);
+ bgp_packet_mpattr_prefix (s, afi, safi, p, prd, labels, nlabels, attr);
}

void
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 64a7464177df..30fa98a41074 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -234,7 +234,7 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi,
struct attr *attr);
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd,
- uint32_t *labels, size_t nlabels);
+ uint32_t *labels, size_t nlabels, struct attr *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);
@@ -243,7 +243,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,
- uint32_t *labels, size_t nlabels);
+ uint32_t *labels, size_t nlabels, struct attr *attr);
extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt);

#endif /* _QUAGGA_BGP_ATTR_H */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index f568806bf7ff..53e9ac8da8f6 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -49,6 +49,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"

@@ -264,7 +265,7 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
if (stream_empty(snlri))
mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
adv->baa->attr);
- bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, labels, nlabels);
+ bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, labels, nlabels, adv->baa->attr);
}
if (BGP_DEBUG (update, UPDATE_OUT))
{
@@ -422,8 +423,10 @@ bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
mp_start = stream_get_endp (s);
mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
}
-
- bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL, 0);
+ if(adv && adv->baa)
+ bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL, 0, adv->baa->attr);
+ else
+ bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL, 0, NULL);
}

if (BGP_DEBUG (update, UPDATE_OUT))
@@ -593,7 +596,7 @@ bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
stream_putw (s, 0);
mp_start = stream_get_endp (s);
mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
- bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL, 0);
+ bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL, 0, NULL);

/* Set the mp_unreach attr's length */
bgp_packet_mpunreach_end(s, mplen_pos);
--
2.1.4


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev