}
}
+static void bgp_evpn_get_rmac_nexthop(struct bgpevpn *vpn,
+ struct prefix_evpn *p,
+ struct attr *attr, uint8_t flags)
+{
+ struct bgp *bgp_vrf = vpn->bgp_vrf;
+
+ memset(&attr->rmac, 0, sizeof(struct ethaddr));
+ if (!bgp_vrf)
+ return;
+
+ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+ /* Copy sys (pip) RMAC and PIP IP as nexthop
+ * in case of route is self MAC-IP,
+ * advertise-pip and advertise-svi-ip features
+ * are enabled.
+ * Otherwise, for all host MAC-IP route's
+ * copy anycast RMAC
+ */
+ if (CHECK_FLAG(flags, BGP_EVPN_MACIP_TYPE_SVI_IP)
+ && bgp_evpn_is_svi_macip_enabled(vpn)) {
+ /* copy sys rmac */
+ memcpy(&attr->rmac, &bgp_vrf->evpn_info->pip_rmac,
+ ETH_ALEN);
+ if (bgp_vrf->evpn_info->advertise_pip &&
+ bgp_vrf->evpn_info->is_anycast_mac) {
+ attr->nexthop = bgp_vrf->evpn_info->pip_ip;
+ attr->mp_nexthop_global_in =
+ bgp_vrf->evpn_info->pip_ip;
+ }
+ } else
+ memcpy(&attr->rmac, &bgp_vrf->rmac, ETH_ALEN);
+ }
+}
/*
* Create RT extended community automatically from passed information:
* of the form AS:VNI.
memcpy(&tmp_pi->extra->label, label, sizeof(label));
tmp_pi->extra->num_labels = num_labels;
+ /* Mark route as self type-2 route */
+ if (flags && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP))
+ tmp_pi->extra->af_flags = BGP_EVPN_MACIP_TYPE_SVI_IP;
bgp_path_info_add(rn, tmp_pi);
} else {
tmp_pi = local_pi;
}
/* router mac is only needed for type-2 routes here. */
- if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
- bgpevpn_get_rmac(vpn, &attr.rmac);
+ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+ uint8_t af_flags = 0;
+
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP))
+ SET_FLAG(af_flags, BGP_EVPN_MACIP_TYPE_SVI_IP);
+
+ bgp_evpn_get_rmac_nexthop(vpn, p, &attr, af_flags);
+
+ if (bgp_debug_zebra(NULL)) {
+ char buf[ETHER_ADDR_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("VRF %s vni %u type-2 route evp %s RMAC %s nexthop %s",
+ vpn->bgp_vrf ?
+ vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ",
+ vpn->vni,
+ prefix2str(p, buf1, sizeof(buf1)),
+ prefix_mac2str(&attr.rmac, buf,
+ sizeof(buf)),
+ inet_ntoa(attr.mp_nexthop_global_in));
+ }
+ }
+
vni2label(vpn->vni, &(attr.label));
/* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
attr.nexthop = vpn->originator_ip;
attr.mp_nexthop_global_in = vpn->originator_ip;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- bgpevpn_get_rmac(vpn, &attr.rmac);
+ bgp_evpn_get_rmac_nexthop(vpn, evp, &attr,
+ tmp_pi->extra->af_flags);
if (evpn_route_is_sticky(bgp, rn))
attr.sticky = 1;
attr.router_flag = 1;
}
+ if (bgp_debug_zebra(NULL)) {
+ char buf[ETHER_ADDR_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("VRF %s vni %u evp %s RMAC %s nexthop %s",
+ vpn->bgp_vrf ?
+ vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ",
+ vpn->vni,
+ prefix2str(evp, buf1, sizeof(buf1)),
+ prefix_mac2str(&attr.rmac, buf, sizeof(buf)),
+ inet_ntoa(attr.mp_nexthop_global_in));
+ }
+
/* Add L3 VNI RTs and RMAC for non IPv6 link-local if
* using L3 VNI for type-2 routes also.
*/
* situations need the route in the per-VNI table as well as the global
* table to be updated (as attributes change).
*/
-static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
+int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
{
int ret;
struct prefix_evpn p;
/* Set router flag (R-bit) based on local neigh entry add */
if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+ if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_SVI_IP))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP);
return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
seq, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_ADD);
n->flags, n->loc_seq);
} else if (advertise_svi_macip_enabled(zvni)) {
+ SET_FLAG(n->flags, ZEBRA_NEIGH_SVI_IP);
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"SVI %s(%u) L2-VNI %u, sending SVI MAC %s IP %s add to BGP with flags 0x%x",