summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-03-13 04:18:13 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-03-13 04:18:13 +0000
commitda65acbd1428ad930a228f03948ed11537887836 (patch)
tree125fcc7d819b0e817e01aa0f9803dcf9dd548466 /usr.sbin/bgpd
parentf9270beec5fabc0aff1d89276829eb09bbd79815 (diff)
Correctly encode MP unreach NLRI so that IPv6 prefixes get removed correctly.
One bug was hiding another bug and only foundry based routers where unhappy about these bad updates. Found by Arnoud Vermeer and Elisa Jasinska at ams-ix. OK henning@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/rde_update.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 80b73e2acbe..157dbc57941 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.64 2009/01/13 21:35:16 sthen Exp $ */
+/* $OpenBSD: rde_update.c,v 1.65 2009/03/13 04:18:12 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -917,13 +917,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
return (NULL);
datalen += 3; /* afi + safi */
- if (datalen > 255) {
- attrlen += 2 + datalen;
- flags |= ATTR_EXTLEN;
- } else {
- attrlen += 1 + datalen;
- buf++;
- }
+
/* prepend header, need to do it reverse */
/* safi & afi */
buf[--wpos] = SAFI_UNICAST;
@@ -933,11 +927,15 @@ up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
/* attribute length */
if (datalen > 255) {
+ attrlen += 2 + datalen;
+ flags |= ATTR_EXTLEN;
wpos -= sizeof(u_int16_t);
tmp = htons(datalen);
memcpy(buf + wpos, &tmp, sizeof(u_int16_t));
- } else
+ } else {
+ attrlen += 1 + datalen;
buf[--wpos] = (u_char)datalen;
+ }
/* mp attribute */
buf[--wpos] = (u_char)ATTR_MP_UNREACH_NLRI;
@@ -958,7 +956,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
/* total length includes the two 2-bytes length fields. */
*len = attrlen + 2 * sizeof(u_int16_t);
- return (buf);
+ return (buf + wpos);
}
u_char *