mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-05 21:48:46 +00:00
bgpd: evpn pip handle svi ip route
By default announct Self Type-2 routes with system IP as nexthop and system MAC as nexthop. An API to check type-2 is self route via checking ipv4/ipv6 address from connected interfaces list. An API to extract RMAC and nexthop for type-2 routes based on advertise-svi-ip knob is enabled. When advertise-pip is enabled/disabled, trigger type-2 route update. For self type-2 routes to use anycast or individual (rmac, nexthop) addresses. Ticket:CM-26190 Reviewed By: Testing Done: Enable 'advertise-svi-ip' knob in bgp default instance. the vrf instance svi ip is advertised with nexthop as default instance router-id and RMAC as system MAC. Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
parent
14e814ea75
commit
0ca1058096
@ -494,6 +494,39 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
@ -1685,6 +1718,9 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
|
||||
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;
|
||||
@ -1828,8 +1864,29 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -2104,7 +2161,8 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
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;
|
||||
@ -2114,6 +2172,19 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
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.
|
||||
*/
|
||||
@ -2301,7 +2372,7 @@ static int bgp_evpn_vni_flood_mode_get(struct bgp *bgp,
|
||||
* 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;
|
||||
|
||||
@ -511,6 +511,16 @@ static inline int is_es_local(struct evpnes *es)
|
||||
return CHECK_FLAG(es->flags, EVPNES_LOCAL) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline bool bgp_evpn_is_svi_macip_enabled(struct bgpevpn *vpn)
|
||||
{
|
||||
struct bgp *bgp_evpn = NULL;
|
||||
|
||||
bgp_evpn = bgp_get_evpn();
|
||||
|
||||
return (bgp_evpn->evpn_info->advertise_svi_macip ||
|
||||
vpn->advertise_svi_macip);
|
||||
}
|
||||
|
||||
extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf,
|
||||
afi_t afi, safi_t safi,
|
||||
bool add);
|
||||
@ -553,4 +563,5 @@ extern struct evpnes *bgp_evpn_es_new(struct bgp *bgp, esi_t *esi,
|
||||
struct ipaddr *originator_ip);
|
||||
extern void bgp_evpn_es_free(struct bgp *bgp, struct evpnes *es);
|
||||
extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni);
|
||||
extern int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn);
|
||||
#endif /* _BGP_EVPN_PRIVATE_H */
|
||||
|
||||
@ -3767,7 +3767,17 @@ DEFPY (bgp_evpn_advertise_pip_ip_mac,
|
||||
}
|
||||
|
||||
if (is_evpn_enabled()) {
|
||||
struct listnode *node = NULL;
|
||||
struct bgpevpn *vpn = NULL;
|
||||
|
||||
update_advertise_vrf_routes(bgp_vrf);
|
||||
|
||||
/* Update (svi) type-2 routes */
|
||||
for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
|
||||
if (!bgp_evpn_is_svi_macip_enabled(vpn))
|
||||
continue;
|
||||
update_routes_for_vni(bgp_evpn, vpn);
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
@ -114,6 +114,10 @@ struct bgp_path_info_extra {
|
||||
mpls_label_t label[BGP_MAX_LABELS];
|
||||
uint32_t num_labels;
|
||||
|
||||
/* af specific flags */
|
||||
uint16_t af_flags;
|
||||
#define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0)
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
union {
|
||||
|
||||
|
||||
@ -490,6 +490,7 @@ enum zapi_iptable_notify_owner {
|
||||
#define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/
|
||||
#define ZEBRA_MACIP_TYPE_ROUTER_FLAG 0x04 /* Router Flag - proxy NA */
|
||||
#define ZEBRA_MACIP_TYPE_OVERRIDE_FLAG 0x08 /* Override Flag */
|
||||
#define ZEBRA_MACIP_TYPE_SVI_IP 0x10 /* SVI MAC-IP */
|
||||
|
||||
enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
|
||||
|
||||
|
||||
@ -2493,6 +2493,8 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
|
||||
/* 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);
|
||||
@ -2813,6 +2815,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
|
||||
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",
|
||||
|
||||
@ -366,6 +366,7 @@ struct zebra_neigh_t_ {
|
||||
#define ZEBRA_NEIGH_DEF_GW 0x08
|
||||
#define ZEBRA_NEIGH_ROUTER_FLAG 0x10
|
||||
#define ZEBRA_NEIGH_DUPLICATE 0x20
|
||||
#define ZEBRA_NEIGH_SVI_IP 0x40
|
||||
|
||||
enum zebra_neigh_state state;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user