summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-07-29 22:26:31 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-07-29 22:26:31 +0000
commit579a744caec648aafec706212e189e2734ac2101 (patch)
tree0100ea9cbee93327cc6058cb3212eb6a51e41afb
parent9cc8316d5183e6f86ed8714b7a5a190d9b26d73b (diff)
Debugging session at WTH. Fix many bugs in the IPv6 support -- some copy paste
and some more obscure ones. With this is it possible to run IPv6 sessions between two bgpd. OK if it does not break IPv4 hummpa barman Henning
-rw-r--r--usr.sbin/bgpd/rde.c41
-rw-r--r--usr.sbin/bgpd/rde_update.c38
2 files changed, 41 insertions, 38 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 1152cbf79c3..5647fa86ae5 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.167 2005/07/29 12:38:40 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.168 2005/07/29 22:26:30 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -249,6 +249,7 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
}
rde_update_queue_runner();
+ rde_update6_queue_runner();
}
rde_shutdown();
@@ -1858,7 +1859,7 @@ rde_update6_queue_runner(void)
len = sizeof(queue_buf) - MSGSIZE_HEADER;
b = up_dump_mp_unreach(queue_buf, &len, peer);
- if (b == NULL || len <= 4)
+ if (b == NULL)
/*
* No packet to send. The 4 bytes are the
* needed withdraw and path attribute length.
@@ -1881,7 +1882,7 @@ rde_update6_queue_runner(void)
len = sizeof(queue_buf) - MSGSIZE_HEADER;
b = up_dump_mp_reach(queue_buf, &len, peer);
- if (b == NULL || len <= 4)
+ if (b == NULL)
/*
* No packet to send. The 4 bytes are the
* needed withdraw and path attribute length.
@@ -2050,15 +2051,13 @@ peer_localaddrs(struct rde_peer *peer, struct bgpd_addr *laddr)
if (ifa->ifa_addr->sa_family ==
match->ifa_addr->sa_family)
ifa = match;
- else {
- if (IN6_IS_ADDR_LINKLOCAL(
- &((struct sockaddr_in6 *)ifa->
- ifa_addr)->sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(
- &((struct sockaddr_in6 *)ifa->
- ifa_addr)->sin6_addr))
- continue;
- }
+ else if (IN6_IS_ADDR_LINKLOCAL(
+ &((struct sockaddr_in6 *)ifa->
+ ifa_addr)->sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL(
+ &((struct sockaddr_in6 *)ifa->
+ ifa_addr)->sin6_addr))
+ continue;
peer->local_v6_addr.af = AF_INET6;
memcpy(&peer->local_v6_addr.v6,
&((struct sockaddr_in6 *)ifa->ifa_addr)->
@@ -2152,26 +2151,20 @@ peer_dump(u_int32_t id, u_int16_t afi, u_int8_t safi)
if (safi == SAFI_ALL || safi == SAFI_UNICAST ||
safi == SAFI_BOTH) {
if (peer->conf.announce_type ==
- ANNOUNCE_DEFAULT_ROUTE) {
+ ANNOUNCE_DEFAULT_ROUTE)
up_generate_default(peer, AF_INET);
- return;
- }
- pt_dump(up_dump_upcall, peer, AF_INET);
- return;
+ else
+ pt_dump(up_dump_upcall, peer, AF_INET);
}
if (afi == AFI_ALL || afi == AFI_IPv6)
if (safi == SAFI_ALL || safi == SAFI_UNICAST ||
safi == SAFI_BOTH) {
if (peer->conf.announce_type ==
- ANNOUNCE_DEFAULT_ROUTE) {
+ ANNOUNCE_DEFAULT_ROUTE)
up_generate_default(peer, AF_INET6);
- return;
- }
- pt_dump(up_dump_upcall, peer, AF_INET6);
- return;
+ else
+ pt_dump(up_dump_upcall, peer, AF_INET6);
}
-
- log_peer_warnx(&peer->conf, "unsupported AFI, SAFI combination");
}
/*
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 70fc1f6112c..505121db7a0 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.37 2005/07/29 12:38:40 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.38 2005/07/29 22:26:30 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -965,25 +965,29 @@ up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
buf++;
}
/* prepend header */
+ /* no IPv4 withdraws */
wpos = 0;
- bzero(buf, 2);
- wpos += 2;
+ bzero(buf, sizeof(u_int16_t));
+ wpos += sizeof(u_int16_t);
+ /* attribute length */
tmp = htons(attrlen);
- memcpy(buf + wpos, &tmp, sizeof(tmp));
- wpos += 2;
+ memcpy(buf + wpos, &tmp, sizeof(u_int16_t));
+ wpos += sizeof(u_int16_t);
+ /* mp attribute */
buf[wpos++] = flags;
buf[wpos++] = (u_char)ATTR_MP_UNREACH_NLRI;
if (datalen > 255) {
tmp = htons(datalen);
- memcpy(buf + wpos, &tmp, sizeof(tmp));
- wpos += 2;
+ memcpy(buf + wpos, &tmp, sizeof(u_int16_t));
+ wpos += sizeof(u_int16_t);
} else
buf[wpos++] = (u_char)datalen;
- *len = datalen + wpos;
+ /* total length includes the two 2-bytes length fields. */
+ *len = attrlen + 2 * sizeof(u_int16_t);
return (buf);
}
@@ -1000,12 +1004,12 @@ up_dump_mp_reach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
* It is possible that a queued path attribute has no nlri prefix.
* Ignore and remove those path attributes.
*/
- while ((upa = TAILQ_FIRST(&peer->updates)) != NULL)
+ while ((upa = TAILQ_FIRST(&peer->updates6)) != NULL)
if (TAILQ_EMPTY(&upa->prefix_h)) {
if (RB_REMOVE(uptree_attr, &peer->up_attrs,
upa) == NULL)
log_warnx("dequeuing update failed.");
- TAILQ_REMOVE(&peer->updates, upa, attr_l);
+ TAILQ_REMOVE(&peer->updates6, upa, attr_l);
free(upa->attr);
free(upa->mpattr);
free(upa);
@@ -1013,19 +1017,25 @@ up_dump_mp_reach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
} else
break;
+ if (upa == NULL)
+ return (NULL);
+
/*
- * reserve space for withdraw len, attr len, the attributes, the
- * mp attribute and the atributte header
+ * reserve space for attr len, the attributes, the
+ * mp attribute and the attribute header
*/
wpos = 2 + 2 + upa->attr_len + 4 + upa->mpattr_len;
if (*len < wpos)
return (NULL);
datalen = up_dump_prefix(buf + wpos, *len - wpos,
- &peer->withdraws6, peer);
+ &upa->prefix_h, peer);
if (datalen == 0)
return (NULL);
+ if (upa->mpattr_len == 0 || upa->mpattr == NULL)
+ fatalx("mulitprotocol update without MP attrs");
+
datalen += upa->mpattr_len;
wpos -= upa->mpattr_len;
memcpy(buf + wpos, upa->mpattr, upa->mpattr_len);
@@ -1063,7 +1073,7 @@ up_dump_mp_reach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
if (TAILQ_EMPTY(&upa->prefix_h)) {
if (RB_REMOVE(uptree_attr, &peer->up_attrs, upa) == NULL)
log_warnx("dequeuing update failed.");
- TAILQ_REMOVE(&peer->updates, upa, attr_l);
+ TAILQ_REMOVE(&peer->updates6, upa, attr_l);
free(upa->attr);
free(upa->mpattr);
free(upa);