mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 13:07:24 +00:00
bgpd: Reject routes having AS_SET or AS_CONFED_SET
This is the first step towards eliminating AS_SET and AS_CONFED_SET types and obsolete them in the future. More information: https://datatracker.ietf.org/doc/html/draft-ietf-idr-deprecate-as-set-confed-set-02 Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This commit is contained in:
parent
306c4dab55
commit
fb29348a19
@ -414,6 +414,19 @@ unsigned int aspath_count_hops(const struct aspath *aspath)
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Check if aspath has AS_SET or AS_CONFED_SET */
|
||||
bool aspath_check_as_sets(struct aspath *aspath)
|
||||
{
|
||||
struct assegment *seg = aspath->segments;
|
||||
|
||||
while (seg) {
|
||||
if (seg->type == AS_SET || seg->type == AS_CONFED_SET)
|
||||
return true;
|
||||
seg = seg->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Estimate size aspath /might/ take if encoded into an
|
||||
* ASPATH attribute.
|
||||
*
|
||||
|
@ -120,6 +120,7 @@ extern int aspath_confed_check(struct aspath *);
|
||||
extern int aspath_left_confed_check(struct aspath *);
|
||||
extern unsigned long aspath_count(void);
|
||||
extern unsigned int aspath_count_hops(const struct aspath *);
|
||||
extern bool aspath_check_as_sets(struct aspath *aspath);
|
||||
extern unsigned int aspath_count_confeds(struct aspath *);
|
||||
extern unsigned int aspath_size(struct aspath *);
|
||||
extern as_t aspath_highest(struct aspath *);
|
||||
|
@ -1850,6 +1850,16 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||
if (!bgp_outbound_policy_exists(peer, filter))
|
||||
return 0;
|
||||
|
||||
/* draft-ietf-idr-deprecate-as-set-confed-set
|
||||
* Filter routes having AS_SET or AS_CONFED_SET in the path.
|
||||
* Eventually, This document (if approved) updates RFC 4271
|
||||
* and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
|
||||
* and obsoletes RFC 6472.
|
||||
*/
|
||||
if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
|
||||
if (aspath_check_as_sets(attr->aspath))
|
||||
return 0;
|
||||
|
||||
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||
if (peer->sort == BGP_PEER_IBGP
|
||||
|| peer->sort == BGP_PEER_CONFED) {
|
||||
@ -3143,6 +3153,19 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
|
||||
goto filtered;
|
||||
}
|
||||
|
||||
/* draft-ietf-idr-deprecate-as-set-confed-set
|
||||
* Filter routes having AS_SET or AS_CONFED_SET in the path.
|
||||
* Eventually, This document (if approved) updates RFC 4271
|
||||
* and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
|
||||
* and obsoletes RFC 6472.
|
||||
*/
|
||||
if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
|
||||
if (aspath_check_as_sets(attr->aspath)) {
|
||||
reason =
|
||||
"as-path contains AS_SET or AS_CONFED_SET type;";
|
||||
goto filtered;
|
||||
}
|
||||
|
||||
bgp_attr_dup(&new_attr, attr);
|
||||
|
||||
/* Apply incoming route-map.
|
||||
@ -6363,6 +6386,7 @@ void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
|
||||
/* Aggregate route attribute. */
|
||||
#define AGGREGATE_SUMMARY_ONLY 1
|
||||
#define AGGREGATE_AS_SET 1
|
||||
#define AGGREGATE_AS_UNSET 0
|
||||
|
||||
static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
|
||||
afi_t afi, safi_t safi)
|
||||
@ -6465,6 +6489,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
|
||||
struct prefix p;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_aggregate *aggregate;
|
||||
uint8_t as_set_new = as_set;
|
||||
|
||||
/* Convert string to prefix structure. */
|
||||
ret = str2prefix(prefix_str, &p);
|
||||
@ -6499,7 +6524,27 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
|
||||
/* Make aggregate address structure. */
|
||||
aggregate = bgp_aggregate_new();
|
||||
aggregate->summary_only = summary_only;
|
||||
aggregate->as_set = as_set;
|
||||
|
||||
/* Network operators MUST NOT locally generate any new
|
||||
* announcements containing AS_SET or AS_CONFED_SET. If they have
|
||||
* announced routes with AS_SET or AS_CONFED_SET in them, then they
|
||||
* SHOULD withdraw those routes and re-announce routes for the
|
||||
* aggregate or component prefixes (i.e., the more-specific routes
|
||||
* subsumed by the previously aggregated route) without AS_SET
|
||||
* or AS_CONFED_SET in the updates.
|
||||
*/
|
||||
if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) {
|
||||
if (as_set == AGGREGATE_AS_SET) {
|
||||
as_set_new = AGGREGATE_AS_UNSET;
|
||||
zlog_warn(
|
||||
"%s: Ignoring as-set because `bgp reject-as-sets` is enabled.\n",
|
||||
__func__);
|
||||
vty_out(vty,
|
||||
"Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
aggregate->as_set = as_set_new;
|
||||
aggregate->safi = safi;
|
||||
|
||||
if (rmap) {
|
||||
@ -6534,8 +6579,8 @@ DEFUN (aggregate_address,
|
||||
argv_find(argv, argc, "A.B.C.D/M", &idx);
|
||||
char *prefix = argv[idx]->arg;
|
||||
char *rmap = NULL;
|
||||
int as_set =
|
||||
argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
|
||||
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
|
||||
: AGGREGATE_AS_UNSET;
|
||||
idx = 0;
|
||||
int summary_only = argv_find(argv, argc, "summary-only", &idx)
|
||||
? AGGREGATE_SUMMARY_ONLY
|
||||
@ -6569,8 +6614,8 @@ DEFUN (aggregate_address_mask,
|
||||
char *mask = argv[idx + 1]->arg;
|
||||
bool rmap_found;
|
||||
char *rmap = NULL;
|
||||
int as_set =
|
||||
argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
|
||||
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
|
||||
: AGGREGATE_AS_UNSET;
|
||||
idx = 0;
|
||||
int summary_only = argv_find(argv, argc, "summary-only", &idx)
|
||||
? AGGREGATE_SUMMARY_ONLY
|
||||
@ -6658,8 +6703,8 @@ DEFUN (ipv6_aggregate_address,
|
||||
char *prefix = argv[idx]->arg;
|
||||
char *rmap = NULL;
|
||||
bool rmap_found;
|
||||
int as_set =
|
||||
argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
|
||||
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
|
||||
: AGGREGATE_AS_UNSET;
|
||||
|
||||
idx = 0;
|
||||
int sum_only = argv_find(argv, argc, "summary-only", &idx)
|
||||
|
@ -1921,6 +1921,56 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd,
|
||||
"bgp reject-as-sets",
|
||||
"BGP specific commands\n"
|
||||
"Reject routes with AS_SET or AS_CONFED_SET flag\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||
struct listnode *node, *nnode;
|
||||
struct peer *peer;
|
||||
|
||||
bgp->reject_as_sets = BGP_REJECT_AS_SETS_ENABLED;
|
||||
|
||||
/* Reset existing BGP sessions to reject routes
|
||||
* with aspath containing AS_SET or AS_CONFED_SET.
|
||||
*/
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
|
||||
peer->last_reset = PEER_DOWN_AS_SETS_REJECT;
|
||||
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd,
|
||||
"no bgp reject-as-sets",
|
||||
NO_STR
|
||||
"BGP specific commands\n"
|
||||
"Reject routes with AS_SET or AS_CONFED_SET flag\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||
struct listnode *node, *nnode;
|
||||
struct peer *peer;
|
||||
|
||||
bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED;
|
||||
|
||||
/* Reset existing BGP sessions to reject routes
|
||||
* with aspath containing AS_SET or AS_CONFED_SET.
|
||||
*/
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
|
||||
peer->last_reset = PEER_DOWN_AS_SETS_REJECT;
|
||||
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* "bgp deterministic-med" configuration. */
|
||||
DEFUN (bgp_deterministic_med,
|
||||
@ -13128,6 +13178,10 @@ void bgp_vty_init(void)
|
||||
install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
|
||||
|
||||
/* bgp reject-as-sets */
|
||||
install_element(BGP_NODE, &bgp_reject_as_sets_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_reject_as_sets_cmd);
|
||||
|
||||
/* "bgp deterministic-med" commands */
|
||||
install_element(BGP_NODE, &bgp_deterministic_med_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_deterministic_med_cmd);
|
||||
|
@ -2966,6 +2966,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
||||
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
|
||||
bgp->dynamic_neighbors_count = 0;
|
||||
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED;
|
||||
bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED;
|
||||
#if DFLT_BGP_IMPORT_CHECK
|
||||
bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
|
||||
#endif
|
||||
@ -7588,6 +7589,10 @@ int bgp_config_write(struct vty *vty)
|
||||
== DEFAULT_EBGP_POLICY_ENABLED)
|
||||
vty_out(vty, " bgp ebgp-requires-policy\n");
|
||||
|
||||
/* draft-ietf-idr-deprecate-as-set-confed-set */
|
||||
if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
|
||||
vty_out(vty, " bgp reject-as-sets\n");
|
||||
|
||||
/* BGP default ipv4-unicast. */
|
||||
if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
|
||||
vty_out(vty, " no bgp default ipv4-unicast\n");
|
||||
|
@ -504,6 +504,13 @@ struct bgp {
|
||||
#define DEFAULT_EBGP_POLICY_DISABLED 0
|
||||
#define DEFAULT_EBGP_POLICY_ENABLED 1
|
||||
|
||||
/* draft-ietf-idr-deprecate-as-set-confed-set
|
||||
* Reject aspaths with AS_SET and/or AS_CONFED_SET.
|
||||
*/
|
||||
bool reject_as_sets;
|
||||
#define BGP_REJECT_AS_SETS_DISABLED 0
|
||||
#define BGP_REJECT_AS_SETS_ENABLED 1
|
||||
|
||||
struct bgp_evpn_info *evpn_info;
|
||||
|
||||
/* EVPN - use RFC 8365 to auto-derive RT */
|
||||
@ -1203,6 +1210,7 @@ struct peer {
|
||||
#define PEER_DOWN_NBR_ADDR 28 /* Waiting for peer IPv6 IP Addr */
|
||||
#define PEER_DOWN_VRF_UNINIT 29 /* Associated VRF is not init yet */
|
||||
#define PEER_DOWN_NOAFI_ACTIVATED 30 /* No AFI/SAFI activated for peer */
|
||||
#define PEER_DOWN_AS_SETS_REJECT 31 /* Reject routes with AS_SET */
|
||||
size_t last_reset_cause_size;
|
||||
uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user