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 /usr.sbin | |
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
Diffstat (limited to 'usr.sbin')
-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); |