On Mon, Aug 06, 2012 at 10:34:22PM +0200, Laurent CARON wrote:
> Hi,
> 
> I'm hit by a rather nasty OpenBGPd 'bug' causing sessions to flap
> (basically go down/up/...).
> 
> One of the prefixes is: 81.169.0.0/17
> 
> Description of bug
> https://puck.nether.net/pipermail/juniper-nsp/2012-July/023774.html
> 
> Is the included fix 
>     (((s & 0xf0) & ~(ATTR_EXTLEN | (m))) == (t))
> instead of just 
>         (((s) & ~(ATTR_EXTLEN | (m))) == (t))
> 
> sufficient ?
> 

I would prefer something like this. Since then we ensure that we do not
forward crap (as in we regard the RFC and send nothing with reserved bits
set). AFAIK there is nothing out there that started to use the reserved
bits so I'm curious how that happend again.

Only compile tested for now.
-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.316
diff -u -p -r1.316 rde.c
--- rde.c       27 May 2012 18:52:07 -0000      1.316
+++ rde.c       6 Aug 2012 20:57:27 -0000
@@ -1382,7 +1382,7 @@ rde_update_withdraw(struct rde_peer *pee
        } 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,
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.142
diff -u -p -r1.142 rde.h
--- rde.h       21 Sep 2011 08:59:01 -0000      1.142
+++ rde.h       6 Aug 2012 21:09:02 -0000
@@ -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
Index: rde_attr.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
retrieving revision 1.90
diff -u -p -r1.90 rde_attr.c
--- rde_attr.c  12 Apr 2012 17:27:20 -0000      1.90
+++ rde_attr.c  6 Aug 2012 21:14:39 -0000
@@ -37,12 +37,12 @@ attr_write(void *p, u_int16_t p_len, u_i
        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
 {
        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
                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 typ
        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);

Reply via email to