Mailing List Archive

[PATCH 53/57] bgpd: evpn import processing
Enhancement of EVPN bgp information exportation to VRF RIBs.
Currently, only IPv4 unicast VRF RIBs are filled in, according from
EVPN information coming from Prefix route advertisements.
Labels are processed differently according to the VRF layer type.
In addition to this, routermac will not be displayed if VRF layer type
is layer2
In addition to this, a log event is displayed to give information on
MAC/IP and RT5 information.

Signed-off-by: Julien Courtat <julien.courtat@6wind.com>
---
bgpd/bgp_route.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
bgpd/bgp_route.h | 1 +
2 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 191e889634d7..6673749c7dde 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -85,6 +85,17 @@ static struct bgp_info *
info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
struct bgp_node *rn);

+static void
+overlay_index_dup(struct attr *attr, struct overlay_index *src)
+{
+ if(!src)
+ return;
+ if(!attr->extra)
+ bgp_attr_extra_get(attr);
+ memcpy(&(attr->extra->evpn_overlay), src, sizeof(struct overlay_index));
+ return;
+}
+
static struct bgp_node *
bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
struct prefix_rd *prd)
@@ -1583,6 +1594,43 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
}
}

+/* from draft-ietf-bess-evpn-inter-subnet-forwarding-01,
+ * for EVPN, MAC/IP advertisement should be filtered
+ * Label-1 = MPLS Label or VNID corresponding to MAC-VRF
+ * Label-2 = MPLS Label or VNID corresponding to IP-VRF
+ */
+static void bgp_vrf_update_labels (struct bgp_vrf *vrf, struct bgp_node *rn,
+ struct bgp_info *selected, uint32_t *l3label, uint32_t *l2label)
+{
+ if (selected->extra->nlabels)
+ {
+ if (rn->p.family == AF_L2VPN)
+ {
+ if(vrf->ltype == BGP_LAYER_TYPE_3)
+ {
+ /* either select belongs to vrf table => only 1 label
+ * or it is part of global rib => 2 labels
+ */
+ if(rn->table && bgp_node_table (rn) && bgp_node_table (rn)->type == BGP_TABLE_VRF)
+ *l3label = selected->extra->labels[0] >> 4;
+ else
+ *l3label = selected->extra->labels[1] >> 4;
+ *l2label = 0;
+ }
+ else
+ {
+ *l2label = selected->extra->labels[0] >> 4;
+ *l3label = 0;
+ }
+ }
+ else
+ {
+ *l3label = selected->extra->labels[0] >> 4;
+ *l2label = 0;
+ }
+ }
+}
+
/* messages sent to ODL to signify that an entry
* has been selected, or unselected
*/
@@ -1590,6 +1638,9 @@ void
bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
struct bgp_info *selected, uint8_t announce)
{
+ char *esi = NULL, *mac_router = NULL;
+ uint32_t ethtag = 0, l3label = 0, l2label = 0;
+
if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
return;
if (announce == true)
@@ -1611,7 +1662,7 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
}
if (BGP_DEBUG (events, EVENTS))
{
- char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], pfx_str[INET6_BUFSIZ];
+ char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], pfx_str[PREFIX_STRLEN];
char label_str[BUFSIZ] = "<?>", nh_str[BUFSIZ] = "<?>";

prefix_rd2str(&vrf->outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
@@ -1634,6 +1685,55 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
else
zlog_debug ("vrf[%s] %s: prefix withdrawn nh %s label %s",
vrf_rd_str, pfx_str, nh_str, label_str);
+
+ if(CHECK_FLAG (selected->flags, BGP_INFO_ORIGIN_EVPN))
+ {
+ esi = esi2str(&(selected->attr->extra->evpn_overlay.eth_s_id));
+ if (rn->p.family == AF_L2VPN)
+ {
+ ethtag = rn->p.u.prefix_macip.eth_tag_id;
+ }
+ else
+ ethtag = selected->attr->extra->eth_t_id;
+
+ if(selected->extra)
+ bgp_vrf_update_labels (vrf, rn, selected, &l3label, &l2label);
+
+ if(selected->attr && selected->attr->extra && selected->attr->extra->ecommunity)
+ {
+ /* only router mac is filled in for VRF RIB layer 3 */
+ if(vrf->ltype == BGP_LAYER_TYPE_3)
+ {
+ /* import routermac */
+ struct ecommunity_val *routermac = ecommunity_lookup (selected->attr->extra->ecommunity,
+ ECOMMUNITY_ENCODE_EVPN,
+ ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
+ if(routermac)
+ mac_router = ecom_mac2str(routermac->val);
+ else
+ {
+ if(ecommunity_lookup (selected->attr->extra->ecommunity,
+ ECOMMUNITY_ENCODE_EVPN,
+ ECOMMUNITY_EVPN_SUBTYPE_DEF_GW))
+ if ((rn->p).u.prefix_macip.mac_len == 8*ETHER_ADDR_LEN)
+ {
+ mac_router = ecom_mac2str((char *)(&(rn->p).u.prefix_macip.mac));
+ }
+ }
+ }
+ }
+ if(vrf->ltype == BGP_LAYER_TYPE_3)
+ zlog_debug ("vrf[layer3] pfx %s ethtag %u esi %s mac_router %s label l3 %u",
+ pfx_str, ethtag,
+ esi == NULL?"<none>":esi,
+ mac_router == NULL?"<none>":mac_router,
+ l3label);
+ else
+ zlog_debug ("vrf[layer2] pfx %s ethtag %u esi %s label l2 %u",
+ pfx_str, ethtag,
+ esi == NULL?"<none>":esi,
+ l2label);
+ }
}
}

@@ -1650,6 +1750,8 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, safi_t safi, struct bgp_nod
struct prefix_rd *prd;
char pfx_str[INET6_BUFSIZ];

+ if(afi == AFI_INTERNAL_L2VPN)
+ afi = AFI_IP; /* XXX should be set to appropriate AFI : AF_INET or AF_INET6 */
prd = &bgp_node_table (rn)->prd;
if (BGP_DEBUG (events, EVENTS))
{
@@ -1778,6 +1880,10 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, safi_t safi, struct bgp_nod
memcpy (iter->extra->labels, select->extra->labels,
select->extra->nlabels * sizeof(select->extra->labels[0]));
}
+ if (select->attr->extra)
+ overlay_index_dup(iter->attr, &(select->attr->extra->evpn_overlay));
+ if(safi == SAFI_INTERNAL_EVPN)
+ SET_FLAG (iter->flags, BGP_INFO_ORIGIN_EVPN);
SET_FLAG (iter->flags, BGP_INFO_VALID);
bgp_info_add (vrf_rn, iter);
bgp_unlock_node (vrf_rn);
@@ -1830,7 +1936,7 @@ bgp_vrf_process_imports (struct bgp *bgp, afi_t afi, safi_t safi,
int action;
struct bgp_info *ri;

- if (safi != SAFI_MPLS_VPN)
+ if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_INTERNAL_EVPN))
return;

prd = &bgp_node_table (rn)->prd;
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 42fe71e224f6..74b974eb9f1a 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -103,6 +103,7 @@ struct bgp_info
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
#define BGP_INFO_UPDATE_SENT (1 << 13)
#define BGP_INFO_WITHDRAW_SENT (1 << 14)
+#define BGP_INFO_ORIGIN_EVPN (1 << 15)

/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
u_char type;
--
2.1.4


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