summaryrefslogtreecommitdiff
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c91
1 files changed, 79 insertions, 12 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index b2db54ef79..30e3c6f31d 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -999,6 +999,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
/* Make Zebra API structure. */
memset(&api, 0, sizeof(api));
+ memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP;
api.safi = safi;
@@ -1015,6 +1016,13 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
if (info->sub_type == BGP_ROUTE_AGGREGATE)
zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
+ /* If it is an EVPN route mark as such.
+ * Currently presence of rmac in attr denotes
+ * this is an EVPN type-2 route
+ */
+ if (!is_zero_mac(&(info->attr->rmac)))
+ SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
+
if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED
|| info->sub_type == BGP_ROUTE_AGGREGATE) {
SET_FLAG(api.flags, ZEBRA_FLAG_IBGP);
@@ -1072,7 +1080,14 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
api_nh = &api.nexthops[valid_nh_count];
api_nh->gate.ipv4 = *nexthop;
- api_nh->type = NEXTHOP_TYPE_IPV4;
+
+ /* EVPN type-2 routes are
+ programmed as onlink on l3-vni SVI
+ */
+ if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))
+ api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else
+ api_nh->type = NEXTHOP_TYPE_IPV4;
} else {
ifindex_t ifindex;
struct in6_addr *nexthop;
@@ -1126,8 +1141,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
}
- if (mpinfo->extra
- && bgp_is_valid_label(&mpinfo->extra->label)) {
+ if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)
+ && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
has_valid_label = 1;
label = label_pton(&mpinfo->extra->label);
@@ -1137,7 +1152,9 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
valid_nh_count++;
}
- if (has_valid_label)
+ /* if this is a evpn route we don't have to include the label */
+ if (has_valid_label &&
+ !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)))
SET_FLAG(api.message, ZAPI_MESSAGE_LABEL);
if (info->sub_type != BGP_ROUTE_AGGREGATE)
@@ -1179,7 +1196,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
sizeof(nh_buf));
label_buf[0] = '\0';
- if (has_valid_label)
+ if (has_valid_label &&
+ !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))
sprintf(label_buf, "label %u",
api_nh->labels[0]);
zlog_debug(" nhop [%d]: %s %s", i + 1, nh_buf,
@@ -1233,11 +1251,19 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi)
return;
memset(&api, 0, sizeof(api));
+ memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = peer->bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP;
api.safi = safi;
api.prefix = *p;
+ /* If it is an EVPN route mark as such.
+ * Currently presence of rmac in attr denotes
+ * this is an EVPN type-2 route
+ */
+ if (!is_zero_mac(&(info->attr->rmac)))
+ SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
+
if (peer->sort == BGP_PEER_IBGP) {
SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL);
SET_FLAG(api.flags, ZEBRA_FLAG_IBGP);
@@ -1551,7 +1577,7 @@ void bgp_zebra_instance_register(struct bgp *bgp)
/* For default instance, register to learn about VNIs, if appropriate.
*/
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
- && bgp->advertise_all_vni)
+ && is_evpn_enabled())
bgp_zebra_advertise_all_vni(bgp, 1);
}
@@ -1570,7 +1596,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp)
/* For default instance, unregister learning about VNIs, if appropriate.
*/
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
- && bgp->advertise_all_vni)
+ && is_evpn_enabled())
bgp_zebra_advertise_all_vni(bgp, 0);
/* Deregister for router-id, interfaces, redistributed routes. */
@@ -1676,6 +1702,39 @@ static void bgp_zebra_connected(struct zclient *zclient)
*/
}
+static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ char buf[ETHER_ADDR_STRLEN];
+ vni_t l3vni = 0;
+ struct ethaddr rmac;
+ struct in_addr originator_ip;
+ struct stream *s;
+
+ memset(&rmac, 0, sizeof(struct ethaddr));
+ memset(&originator_ip, 0, sizeof(struct in_addr));
+ s = zclient->ibuf;
+ l3vni = stream_getl(s);
+ if (cmd == ZEBRA_L3VNI_ADD) {
+ stream_get(&rmac, s, sizeof(struct ethaddr));
+ originator_ip.s_addr = stream_get_ipv4(s);
+ }
+
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s",
+ (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del",
+ vrf_id_to_name(vrf_id),
+ l3vni,
+ prefix_mac2str(&rmac, buf, sizeof(buf)));
+
+ if (cmd == ZEBRA_L3VNI_ADD)
+ bgp_evpn_local_l3vni_add(l3vni, vrf_id, &rmac, originator_ip);
+ else
+ bgp_evpn_local_l3vni_del(l3vni, vrf_id);
+
+ return 0;
+}
+
static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
@@ -1683,23 +1742,29 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
vni_t vni;
struct bgp *bgp;
struct in_addr vtep_ip;
+ vrf_id_t tenant_vrf_id = VRF_DEFAULT;
s = zclient->ibuf;
vni = stream_getl(s);
- if (command == ZEBRA_VNI_ADD)
+ if (command == ZEBRA_VNI_ADD) {
vtep_ip.s_addr = stream_get_ipv4(s);
+ stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t));
+ }
+
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp)
return 0;
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("Rx VNI %s VRF %u VNI %u",
- (command == ZEBRA_VNI_ADD) ? "add" : "del", vrf_id,
- vni);
+ zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s",
+ (command == ZEBRA_VNI_ADD) ? "add" : "del",
+ vrf_id_to_name(vrf_id),
+ vni, vrf_id_to_name(tenant_vrf_id));
if (command == ZEBRA_VNI_ADD)
return bgp_evpn_local_vni_add(
- bgp, vni, vtep_ip.s_addr ? vtep_ip : bgp->router_id);
+ bgp, vni, vtep_ip.s_addr ? vtep_ip : bgp->router_id,
+ tenant_vrf_id);
else
return bgp_evpn_local_vni_del(bgp, vni);
}
@@ -1783,6 +1848,8 @@ void bgp_zebra_init(struct thread_master *master)
zclient->local_vni_del = bgp_zebra_process_local_vni;
zclient->local_macip_add = bgp_zebra_process_local_macip;
zclient->local_macip_del = bgp_zebra_process_local_macip;
+ zclient->local_l3vni_add = bgp_zebra_process_local_l3vni;
+ zclient->local_l3vni_del = bgp_zebra_process_local_l3vni;
}
void bgp_zebra_destroy(void)