The main reason is that AS_SET does not play nice with RPKI ROA.
Introduce a per neighbor and global config option
'reject as-set yes' and 'reject as-set no'
If set to yes received UPDATES with AS_SET segements are rejected.
This is done the same way other ASPATH soft-errors are handled. The UPDATE
is marked invalid and all prefixes are treated as withdraws.
`bgpctl show rib in error` can be used to show prefixes that where denied
and treated as withdraws because of errors.
By default this feature is off.
OK benno@
-.\" $OpenBSD: bgpd.conf.5,v 1.205 2020/05/16 16:58:11 jmc Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.206 2021/01/25 09:15:23 claudio Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 16 2020 $
+.Dd $Mdocdate: January 25 2021 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
The default is
.Ic ignore .
.Pp
+.It Xo
+.Ic reject Ic as-set
+.Pq Ic yes Ns | Ns Ic no
+.Xc
+If set to
+.Ic yes ,
+.Em AS paths
+attributes containing
+.Em AS_SET
+path segements will be rejected and
+all prefixes will be treated as withdraws.
+The default is
+.Ic no .
+.Pp
.It Ic router-id Ar dotted-quad
Set the BGP router ID, which must be non-zero and should be unique
within the AS.
.It Ic passive
Do not attempt to actively open a TCP connection to the neighbor system.
.Pp
+.It Xo
+.Ic reject Ic as-set
+.Pq Ic yes Ns | Ns Ic no
+.Xc
+If set to
+.Ic yes ,
+.Em AS paths
+attributes containing
+.Em AS_SET
+path segements will be rejected and
+all prefixes will be treated as withdraws.
+The default is inherited from the global
+.Ic reject Ic as-set
+setting.
+.Pp
.It Ic remote-as Ar as-number
Set the AS number of the remote system.
.Pp
-/* $OpenBSD: bgpd.h,v 1.410 2021/01/18 12:15:36 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.411 2021/01/25 09:15:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
#define BGPD_FLAG_DECISION_ROUTEAGE 0x0100
#define BGPD_FLAG_DECISION_TRANS_AS 0x0200
#define BGPD_FLAG_DECISION_MED_ALWAYS 0x0400
+#define BGPD_FLAG_NO_AS_SET 0x0800
#define BGPD_LOG_UPDATES 0x0001
#define PEERFLAG_TRANS_AS 0x01
#define PEERFLAG_LOG_UPDATES 0x02
+#define PEERFLAG_NO_AS_SET 0x04
enum network_type {
NETWORK_DEFAULT, /* from network statements */
int aspath_asprint(char **, void *, u_int16_t);
size_t aspath_strlen(void *, u_int16_t);
u_int32_t aspath_extract(const void *, int);
-int aspath_verify(void *, u_int16_t, int);
+int aspath_verify(void *, u_int16_t, int, int);
#define AS_ERR_LEN -1
#define AS_ERR_TYPE -2
#define AS_ERR_BAD -3
-/* $OpenBSD: parse.y,v 1.411 2020/12/29 15:30:34 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.412 2021/01/25 09:15:23 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
else
conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS;
}
+ | REJECT ASSET yesno {
+ if ($3 == 1)
+ conf->flags |= BGPD_FLAG_NO_AS_SET;
+ else
+ conf->flags &= ~BGPD_FLAG_NO_AS_SET;
+ }
| LOG STRING {
if (!strcmp($2, "updates"))
conf->log |= BGPD_LOG_UPDATES;
}
free($2);
}
+ | REJECT ASSET yesno {
+ if ($3 == 1)
+ curpeer->conf.flags |= PEERFLAG_NO_AS_SET;
+ else
+ curpeer->conf.flags &= ~PEERFLAG_NO_AS_SET;
+ }
;
restart : /* nada */ { $$ = 0; }
if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS)
p->conf.flags |= PEERFLAG_TRANS_AS;
+ if (conf->flags & BGPD_FLAG_NO_AS_SET)
+ p->conf.flags |= PEERFLAG_NO_AS_SET;
return (p);
}
-/* $OpenBSD: printconf.c,v 1.144 2020/12/29 15:30:34 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.145 2021/01/25 09:15:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
if (conf->flags & BGPD_FLAG_DECISION_MED_ALWAYS)
printf("rde med compare always\n");
+ if (conf->flags & BGPD_FLAG_NO_AS_SET)
+ printf("reject as-set yes\n");
+
if (conf->log & BGPD_LOG_UPDATES)
printf("log updates\n");
if (p->flags & PEERFLAG_TRANS_AS)
printf("%s\ttransparent-as yes\n", c);
+ if (conf->flags & BGPD_FLAG_NO_AS_SET) {
+ if (!(p->flags & PEERFLAG_NO_AS_SET))
+ printf("%s\treject as-set no\n", c);
+ } else {
+ if (p->flags & PEERFLAG_NO_AS_SET)
+ printf("%s\treject as-set yes\n", c);
+ }
+
if (p->flags & PEERFLAG_LOG_UPDATES)
printf("%s\tlog updates\n", c);
-/* $OpenBSD: rde.c,v 1.513 2021/01/18 12:15:36 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.514 2021/01/25 09:15:24 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
static void rde_softreconfig_sync_reeval(struct rib_entry *, void *);
static void rde_softreconfig_sync_fib(struct rib_entry *, void *);
static void rde_softreconfig_sync_done(void *, u_int8_t);
+static int rde_no_as_set(struct rde_peer *);
int rde_update_queue_pending(void);
void rde_update_queue_runner(void);
void rde_update6_queue_runner(u_int8_t);
case ATTR_ASPATH:
if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0))
goto bad_flags;
- error = aspath_verify(p, attr_len, rde_as4byte(peer));
+ error = aspath_verify(p, attr_len, rde_as4byte(peer),
+ rde_no_as_set(peer));
if (error == AS_ERR_SOFT) {
/*
* soft errors like unexpected segment types are
* marked invalid.
*/
a->flags |= F_ATTR_PARSE_ERR;
- log_peer_warnx(&peer->conf, "bad ASPATH, "
- "path invalidated and prefix withdrawn");
} else if (error != 0) {
rde_update_err(peer, ERR_UPDATE, ERR_UPD_ASPATH,
NULL, 0);
if (npath == NULL)
fatal("aspath_inflate");
}
+ if (error == AS_ERR_SOFT) {
+ char *str;
+
+ aspath_asprint(&str, npath, nlen);
+ log_peer_warnx(&peer->conf, "bad ASPATH %s, "
+ "path invalidated and prefix withdrawn",
+ str ? str : "(bad aspath)");
+ free(str);
+ }
a->flags |= F_ATTR_ASPATH;
a->aspath = aspath_get(npath, nlen);
if (npath != p)
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL))
goto bad_flags;
- if ((error = aspath_verify(p, attr_len, 1)) != 0) {
+ if ((error = aspath_verify(p, attr_len, 1,
+ rde_no_as_set(peer))) != 0) {
/*
* XXX RFC does not specify how to handle errors.
* XXX Instead of dropping the session because of a
return (peer->capa.as4byte);
}
+static int
+rde_no_as_set(struct rde_peer *peer)
+{
+ return (peer->conf.flags & PEERFLAG_NO_AS_SET);
+}
+
/* End-of-RIB marker, RFC 4724 */
static void
rde_peer_recv_eor(struct rde_peer *peer, u_int8_t aid)
-/* $OpenBSD: util.c,v 1.59 2021/01/18 12:15:36 claudio Exp $ */
+/* $OpenBSD: util.c,v 1.60 2021/01/25 09:15:24 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
* Verify that the aspath is correctly encoded.
*/
int
-aspath_verify(void *data, u_int16_t len, int as4byte)
+aspath_verify(void *data, u_int16_t len, int as4byte, int noset)
{
u_int8_t *seg = data;
u_int16_t seg_size, as_size = 2;
*/
if (seg_type == AS_CONFED_SEQUENCE || seg_type == AS_CONFED_SET)
error = AS_ERR_SOFT;
+ /*
+ * If AS_SET filtering (RFC6472) is on, error out on AS_SET
+ * as well.
+ */
+ if (noset && seg_type == AS_SET)
+ error = AS_ERR_SOFT;
if (seg_type != AS_SET && seg_type != AS_SEQUENCE &&
seg_type != AS_CONFED_SEQUENCE && seg_type != AS_CONFED_SET)
return (AS_ERR_TYPE);