summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
authorEugene Bogomazov <eb@qrator.net>2022-06-17 12:14:46 +0200
committerEugene Bogomazov <eb@qrator.net>2022-06-17 12:14:46 +0200
commitd864dd9eb182eefaa4d08717bd2837f9182956a6 (patch)
treec60b9a1f8d0d4d8a9630d0a218b265cb743e8869 /bgpd/bgp_route.c
parentMerge pull request #11422 from opensourcerouting/feature/autoclose_stale_issu... (diff)
downloadfrr-d864dd9eb182eefaa4d08717bd2837f9182956a6.tar.xz
frr-d864dd9eb182eefaa4d08717bd2837f9182956a6.zip
bgpd: Add RFC9234 implementation
RFC9234 is a way to establish correct connection roles (Customer/ Provider, Peer or with RS) between bgp speakers. This patch: - Add a new configuration/terminal option to set the appropriate local role; - Add a mechanism for checking used roles, implemented by exchanging the corresponding capabilities in OPEN messages; - Add strict mode to force other party to use this feature; - Add basic support for a new transitive optional bgp attribute - OTC (Only to Customer); - Add logic for default setting OTC attribute and filtering routes with this attribute by the edge speakers, if the appropriate conditions are met; - Add two test stands to check role negotiation and route filtering during role usage. Signed-off-by: Eugene Bogomazov <eb@qrator.net>
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f9d01913a..90e3f8805 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1561,6 +1561,43 @@ static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
return false;
}
+static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
+{
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
+ if (peer->local_role == ROLE_PROVIDER ||
+ peer->local_role == ROLE_RS_SERVER)
+ return true;
+ if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
+ return true;
+ return false;
+ }
+ if (peer->local_role == ROLE_CUSTOMER ||
+ peer->local_role == ROLE_PEER ||
+ peer->local_role == ROLE_RS_CLIENT) {
+ attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
+ attr->otc = peer->as;
+ }
+ return false;
+}
+
+static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
+{
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
+ if (peer->local_role == ROLE_CUSTOMER ||
+ peer->local_role == ROLE_RS_CLIENT ||
+ peer->local_role == ROLE_PEER)
+ return true;
+ return false;
+ }
+ if (peer->local_role == ROLE_PROVIDER ||
+ peer->local_role == ROLE_PEER ||
+ peer->local_role == ROLE_RS_SERVER) {
+ attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
+ attr->otc = peer->bgp->as;
+ }
+ return false;
+}
+
static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi,
const char *rmap_name, mpls_label_t *label,
@@ -2165,6 +2202,9 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
}
+ if (bgp_otc_egress(peer, attr))
+ return false;
+
bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
bgp_peer_as_override(bgp, afi, safi, peer, attr);
@@ -3961,6 +4001,12 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
goto filtered;
}
+ if (bgp_otc_filter(peer, &new_attr)) {
+ reason = "failing otc validation";
+ bgp_attr_flush(&new_attr);
+ goto filtered;
+ }
+
/* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
* condition :
* Suppress fib is enabled
@@ -10447,6 +10493,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
vty_out(vty, ", atomic-aggregate");
}
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
+ if (json_paths)
+ json_object_int_add(json_path, "otc", attr->otc);
+ else
+ vty_out(vty, ", otc %u", attr->otc);
+ }
+
if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
|| (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
&& bgp_path_info_mpath_count(path))) {