summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorHiroki Shirokura <slank.dev@gmail.com>2021-09-05 04:24:23 +0200
committerHiroki Shirokura <slank.dev@gmail.com>2021-09-07 14:54:39 +0200
commitd79ff732cdcd9583b01d5c22cee05812e7354aa9 (patch)
treef75bac11e8efb3651afe391635c0a03f7f394356 /bgpd
parentzebra: add srv6's no commands (diff)
downloadfrr-d79ff732cdcd9583b01d5c22cee05812e7354aa9.tar.xz
frr-d79ff732cdcd9583b01d5c22cee05812e7354aa9.zip
bgpd: handle srv6 locator notification and update vpn-rib
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_mplsvpn.c37
-rw-r--r--bgpd/bgp_mplsvpn.h4
-rw-r--r--bgpd/bgp_zebra.c84
3 files changed, 123 insertions, 2 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 1af2ab384..b0bab02fb 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -714,6 +714,15 @@ static void setsids(struct bgp_path_info *bpi,
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
*/
@@ -821,7 +830,8 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
else if (new_attr->srv6_vpn)
setsids(bpi, &new_attr->srv6_vpn->sid,
num_sids);
- }
+ } else
+ unsetsids(bpi);
if (nexthop_self_flag)
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(
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)
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
__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);
else if (new_attr->srv6_vpn)
setsids(new, &new_attr->srv6_vpn->sid, num_sids);
- }
+ } else
+ unsetsids(new);
if (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,
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)
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
__func__, (nh_valid ? "" : "not "),
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 38193721b..b0e0f74f7 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -243,6 +243,10 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
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,
bgp_vrf->vpn_policy[afi]
.tovpn_zebra_vrf_sid_last_sent)) {
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 5ef49e510..ac34692fe 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3077,6 +3077,88 @@ static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
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)
{
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->route_notify_owner = bgp_zebra_route_notify_owner;
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 =
bgp_zebra_process_srv6_locator_chunk;
}