summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2012-08-12 14:24:56 +0000
committerclaudio <claudio@openbsd.org>2012-08-12 14:24:56 +0000
commitcaea8f61f9c81189bf1529ac8450ec0d4e90ef21 (patch)
treea433ec96c1063d27f1742a1fa59b75a56afdb368
parentSimplify width calculation (all numbers always sequential) and don't (diff)
downloadwireguard-openbsd-caea8f61f9c81189bf1529ac8450ec0d4e90ef21.tar.xz
wireguard-openbsd-caea8f61f9c81189bf1529ac8450ec0d4e90ef21.zip
By default mask the reserved bits and the ext len bit in the attribute
flags field. Some systems seem to start sending bad flags around which cause session failures in bgpd. Make sure that bgpd ignores the must be zero flags correctly and ensure that they are always reset to zero when sending updates out. Reported and patch tested by Laurent CARON, OK henning@
-rw-r--r--usr.sbin/bgpd/rde.c4
-rw-r--r--usr.sbin/bgpd/rde.h5
-rw-r--r--usr.sbin/bgpd/rde_attr.c8
3 files changed, 11 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index cd1eb5c3c9a..8459ac67739 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.316 2012/05/27 18:52:07 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.317 2012/08/12 14:24:56 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1382,7 +1382,7 @@ rde_update_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix,
} while (0)
#define CHECK_FLAGS(s, t, m) \
- (((s) & ~(ATTR_EXTLEN | (m))) == (t))
+ (((s) & ~(ATTR_DEFMASK | (m))) == (t))
int
rde_attr_parse(u_char *p, u_int16_t len, struct rde_peer *peer,
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 4a11c6afb12..1d489c055b4 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.142 2011/09/21 08:59:01 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.143 2012/08/12 14:24:56 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -118,6 +118,9 @@ enum attrtypes {
#define ATTR_PARTIAL 0x20
#define ATTR_TRANSITIVE 0x40
#define ATTR_OPTIONAL 0x80
+#define ATTR_RESERVED 0x0f
+/* by default mask the reserved bits and the ext len bit */
+#define ATTR_DEFMASK (ATTR_RESERVED | ATTR_EXTLEN)
/* default attribute flags for well known attributes */
#define ATTR_WELL_KNOWN ATTR_TRANSITIVE
diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c
index 5d86e91dc83..d4e1bb39377 100644
--- a/usr.sbin/bgpd/rde_attr.c
+++ b/usr.sbin/bgpd/rde_attr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_attr.c,v 1.90 2012/04/12 17:27:20 claudio Exp $ */
+/* $OpenBSD: rde_attr.c,v 1.91 2012/08/12 14:24:56 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -37,12 +37,12 @@ attr_write(void *p, u_int16_t p_len, u_int8_t flags, u_int8_t type,
u_char *b = p;
u_int16_t tmp, tot_len = 2; /* attribute header (without len) */
+ flags &= ~ATTR_DEFMASK;
if (data_len > 255) {
tot_len += 2 + data_len;
flags |= ATTR_EXTLEN;
} else {
tot_len += 1 + data_len;
- flags &= ~ATTR_EXTLEN;
}
if (tot_len > p_len)
@@ -69,12 +69,12 @@ attr_writebuf(struct ibuf *buf, u_int8_t flags, u_int8_t type, void *data,
{
u_char hdr[4];
+ flags &= ~ATTR_DEFMASK;
if (data_len > 255) {
flags |= ATTR_EXTLEN;
hdr[2] = (data_len >> 8) & 0xff;
hdr[3] = data_len & 0xff;
} else {
- flags &= ~ATTR_EXTLEN;
hdr[2] = data_len & 0xff;
}
@@ -322,6 +322,7 @@ attr_alloc(u_int8_t flags, u_int8_t type, const void *data, u_int16_t len)
fatal("attr_optadd");
rdemem.attr_cnt++;
+ flags &= ~ATTR_DEFMASK; /* normalize mask */
a->flags = flags;
a->hash = hash32_buf(&flags, sizeof(flags), HASHINIT);
a->type = type;
@@ -351,6 +352,7 @@ attr_lookup(u_int8_t flags, u_int8_t type, const void *data, u_int16_t len)
struct attr *a;
u_int32_t hash;
+ flags &= ~ATTR_DEFMASK; /* normalize mask */
hash = hash32_buf(&flags, sizeof(flags), HASHINIT);
hash = hash32_buf(&type, sizeof(type), hash);
hash = hash32_buf(&len, sizeof(len), hash);