Skip to content

Commit

Permalink
Merge pull request #5305 from ton31337/feature/draft-ietf-idr-depreca…
Browse files Browse the repository at this point in the history
…te-as-set-confed-set

bgpd: Reject incoming and outgoing UPDATES for AS_SET and AS_CONFED_SET
  • Loading branch information
donaldsharp authored Dec 4, 2019
2 parents e25ca45 + 7ea16cb commit 2d3c8c2
Show file tree
Hide file tree
Showing 15 changed files with 358 additions and 7 deletions.
13 changes: 13 additions & 0 deletions bgpd/bgp_aspath.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,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.
*
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_aspath.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
59 changes: 52 additions & 7 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,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) {
Expand Down Expand Up @@ -3155,6 +3165,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.
Expand Down Expand Up @@ -6392,6 +6415,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)
Expand Down Expand Up @@ -6494,6 +6518,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);
Expand Down Expand Up @@ -6528,7 +6553,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) {
Expand Down Expand Up @@ -6563,8 +6608,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
Expand Down Expand Up @@ -6598,8 +6643,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
Expand Down Expand Up @@ -6687,8 +6732,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)
Expand Down
54 changes: 54 additions & 0 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -13136,6 +13186,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);
Expand Down
5 changes: 5 additions & 0 deletions bgpd/bgpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2990,6 +2990,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
Expand Down Expand Up @@ -7618,6 +7619,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");
Expand Down
8 changes: 8 additions & 0 deletions bgpd/bgpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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];

Expand Down
8 changes: 8 additions & 0 deletions doc/user/bgp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,14 @@ Require policy on EBGP

This command requires incoming and outgoing filters to be applied for eBGP sessions. Without the incoming filter, no routes will be accepted. Without the outgoing filter, no routes will be announced.

Reject routes with AS_SET or AS_CONFED_SET types
-------------------------------

.. index:: [no] bgp reject-as-sets
.. clicmd:: [no] bgp reject-as-sets

This command enables rejection of incoming and outgoing routes having AS_SET or AS_CONFED_SET type.

.. _bgp-route-flap-dampening:

Route Flap Dampening
Expand Down
Empty file.
8 changes: 8 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r1/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
! exit1
router bgp 65001
neighbor 192.168.255.1 remote-as 65002
address-family ipv4 unicast
redistribute connected
exit-address-family
!
!
9 changes: 9 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r1/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
! exit1
interface lo
ip address 172.16.255.254/32
!
interface r1-eth0
ip address 192.168.255.2/30
!
ip forwarding
!
10 changes: 10 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r2/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
! spine
router bgp 65002
bgp reject-as-sets
neighbor 192.168.255.2 remote-as 65001
neighbor 192.168.254.2 remote-as 65003
address-family ipv4 unicast
aggregate-address 172.16.0.0/16 as-set summary-only
exit-address-family
!
!
9 changes: 9 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r2/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
! spine
interface r2-eth0
ip address 192.168.255.1/30
!
interface r2-eth1
ip address 192.168.254.1/30
!
ip forwarding
!
9 changes: 9 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r3/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
! exit2
router bgp 65003
neighbor 192.168.254.1 remote-as 65002
address-family ipv4 unicast
neighbor 192.168.254.1 allowas-in
redistribute connected
exit-address-family
!
!
9 changes: 9 additions & 0 deletions tests/topotests/bgp_reject_as_sets/r3/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
! exit2
interface lo
ip address 172.16.254.254/32
!
interface r3-eth0
ip address 192.168.254.2/30
!
ip forwarding
!
Loading

0 comments on commit 2d3c8c2

Please sign in to comment.