mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-17 19:05:44 +00:00
bgpd: handle srv6 locator notification and update vpn-rib
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
parent
0a735cd523
commit
d79ff732cd
@ -714,6 +714,15 @@ static void setsids(struct bgp_path_info *bpi,
|
|||||||
extra->num_sids = num_sids;
|
extra->num_sids = num_sids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unsetsids(struct bgp_path_info *bpi)
|
||||||
|
{
|
||||||
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
|
extra = bgp_path_info_extra_get(bpi);
|
||||||
|
extra->num_sids = 0;
|
||||||
|
memset(extra->sid, 0, sizeof(extra->sid));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns pointer to new bgp_path_info upon success
|
* returns pointer to new bgp_path_info upon success
|
||||||
*/
|
*/
|
||||||
@ -821,7 +830,8 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
else if (new_attr->srv6_vpn)
|
else if (new_attr->srv6_vpn)
|
||||||
setsids(bpi, &new_attr->srv6_vpn->sid,
|
setsids(bpi, &new_attr->srv6_vpn->sid,
|
||||||
num_sids);
|
num_sids);
|
||||||
}
|
} else
|
||||||
|
unsetsids(bpi);
|
||||||
|
|
||||||
if (nexthop_self_flag)
|
if (nexthop_self_flag)
|
||||||
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
|
||||||
@ -847,6 +857,17 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
nh_valid = bgp_find_or_add_nexthop(
|
nh_valid = bgp_find_or_add_nexthop(
|
||||||
bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p);
|
bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you are using SRv6 VPN instead of MPLS, it need to check
|
||||||
|
* the SID allocation. If the sid is not allocated, the rib
|
||||||
|
* will be invalid.
|
||||||
|
*/
|
||||||
|
if (bgp->srv6_enabled
|
||||||
|
&& (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
|
||||||
|
bgp_path_info_unset_flag(bn, bpi, BGP_PATH_VALID);
|
||||||
|
nh_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
__func__, (nh_valid ? "" : "not "),
|
__func__, (nh_valid ? "" : "not "),
|
||||||
@ -893,7 +914,8 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
|
setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
|
||||||
else if (new_attr->srv6_vpn)
|
else if (new_attr->srv6_vpn)
|
||||||
setsids(new, &new_attr->srv6_vpn->sid, num_sids);
|
setsids(new, &new_attr->srv6_vpn->sid, num_sids);
|
||||||
}
|
} else
|
||||||
|
unsetsids(new);
|
||||||
|
|
||||||
if (num_labels)
|
if (num_labels)
|
||||||
setlabels(new, label, num_labels);
|
setlabels(new, label, num_labels);
|
||||||
@ -933,6 +955,17 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
|
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
|
||||||
new, NULL, 0, p);
|
new, NULL, 0, p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you are using SRv6 VPN instead of MPLS, it need to check
|
||||||
|
* the SID allocation. If the sid is not allocated, the rib
|
||||||
|
* will be invalid.
|
||||||
|
*/
|
||||||
|
if (bgp->srv6_enabled
|
||||||
|
&& (!new->attr->srv6_l3vpn && !new->attr->srv6_vpn)) {
|
||||||
|
bgp_path_info_unset_flag(bn, new, BGP_PATH_VALID);
|
||||||
|
nh_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
__func__, (nh_valid ? "" : "not "),
|
__func__, (nh_valid ? "" : "not "),
|
||||||
|
@ -243,6 +243,10 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
|
|||||||
if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
|
if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
|
||||||
ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
|
ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
|
||||||
|
|
||||||
|
if (!bgp_vrf->vpn_policy[afi].tovpn_sid
|
||||||
|
&& bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent)
|
||||||
|
vpn_leak_zebra_vrf_sid_withdraw(bgp_vrf, afi);
|
||||||
|
|
||||||
if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
|
if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
|
||||||
bgp_vrf->vpn_policy[afi]
|
bgp_vrf->vpn_policy[afi]
|
||||||
.tovpn_zebra_vrf_sid_last_sent)) {
|
.tovpn_zebra_vrf_sid_last_sent)) {
|
||||||
|
@ -3077,6 +3077,88 @@ static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
|
|||||||
vpn_leak_postchange_all();
|
vpn_leak_postchange_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS)
|
||||||
|
{
|
||||||
|
struct srv6_locator loc = {};
|
||||||
|
struct bgp *bgp = bgp_get_default();
|
||||||
|
const char *loc_name = bgp->srv6_locator_name;
|
||||||
|
|
||||||
|
if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!bgp || !bgp->srv6_enabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bgp_zebra_srv6_manager_get_locator_chunk(loc_name) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
|
||||||
|
{
|
||||||
|
struct srv6_locator loc = {};
|
||||||
|
struct bgp *bgp = bgp_get_default();
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct prefix_ipv6 *chunk;
|
||||||
|
struct bgp_srv6_function *func;
|
||||||
|
struct bgp *bgp_vrf;
|
||||||
|
struct in6_addr *tovpn_sid;
|
||||||
|
struct prefix_ipv6 tmp_prefi;
|
||||||
|
|
||||||
|
if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// refresh chunks
|
||||||
|
for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
|
||||||
|
if (prefix_match((struct prefix *)&loc.prefix,
|
||||||
|
(struct prefix *)chunk))
|
||||||
|
listnode_delete(bgp->srv6_locator_chunks, chunk);
|
||||||
|
|
||||||
|
// refresh functions
|
||||||
|
for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) {
|
||||||
|
tmp_prefi.family = AF_INET6;
|
||||||
|
tmp_prefi.prefixlen = 128;
|
||||||
|
tmp_prefi.prefix = func->sid;
|
||||||
|
if (prefix_match((struct prefix *)&loc.prefix,
|
||||||
|
(struct prefix *)&tmp_prefi))
|
||||||
|
listnode_delete(bgp->srv6_functions, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh tovpn_sid
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
|
||||||
|
if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// refresh vpnv4 tovpn_sid
|
||||||
|
tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid;
|
||||||
|
if (tovpn_sid) {
|
||||||
|
tmp_prefi.family = AF_INET6;
|
||||||
|
tmp_prefi.prefixlen = 128;
|
||||||
|
tmp_prefi.prefix = *tovpn_sid;
|
||||||
|
if (prefix_match((struct prefix *)&loc.prefix,
|
||||||
|
(struct prefix *)&tmp_prefi))
|
||||||
|
XFREE(MTYPE_BGP_SRV6_SID,
|
||||||
|
bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh vpnv6 tovpn_sid
|
||||||
|
tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid;
|
||||||
|
if (tovpn_sid) {
|
||||||
|
tmp_prefi.family = AF_INET6;
|
||||||
|
tmp_prefi.prefixlen = 128;
|
||||||
|
tmp_prefi.prefix = *tovpn_sid;
|
||||||
|
if (prefix_match((struct prefix *)&loc.prefix,
|
||||||
|
(struct prefix *)&tmp_prefi))
|
||||||
|
XFREE(MTYPE_BGP_SRV6_SID,
|
||||||
|
bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vpn_leak_postchange_all();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
|
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
|
||||||
{
|
{
|
||||||
zclient_num_connects = 0;
|
zclient_num_connects = 0;
|
||||||
@ -3119,6 +3201,8 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
|
|||||||
zclient->iptable_notify_owner = iptable_notify_owner;
|
zclient->iptable_notify_owner = iptable_notify_owner;
|
||||||
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
|
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
|
||||||
zclient->instance = instance;
|
zclient->instance = instance;
|
||||||
|
zclient->srv6_locator_add = bgp_zebra_process_srv6_locator_add;
|
||||||
|
zclient->srv6_locator_delete = bgp_zebra_process_srv6_locator_delete;
|
||||||
zclient->process_srv6_locator_chunk =
|
zclient->process_srv6_locator_chunk =
|
||||||
bgp_zebra_process_srv6_locator_chunk;
|
bgp_zebra_process_srv6_locator_chunk;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user