diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-07-29 22:26:31 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-07-29 22:26:31 +0000 |
commit | 579a744caec648aafec706212e189e2734ac2101 (patch) | |
tree | 0100ea9cbee93327cc6058cb3212eb6a51e41afb | |
parent | 9cc8316d5183e6f86ed8714b7a5a190d9b26d73b (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.c | 41 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 38 |
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); |