On Mon, Feb 09, 2009 at 04:51:12PM +1100, Graeme Lee wrote: > Graeme Lee wrote: >> Graeme Lee wrote: >>> tico wrote: >>>> Graeme Lee wrote: >>>>> tico wrote: >>>>>> Graeme Lee wrote: >>>>>>> <<snip>> >>>>>> >>>>> >> Ok forget bgp configs for a minute. I've been quickly scanning over >> the code, and notable is that the log displays: >> >> Feb 9 13:00:15 gw-nextgen bgpd[17223]: send_rtmsg: action 1, prefix >> 2001:7fb:fe07::/48: Network is unreachable >> >> but shouldn't it be a send_rt6msg call in kroute.c? >>
Yes. The waning message had the wrong function name in it. > On a hunch, I tried a 64bit and a 32 bit machine with 1 prefix each. > The 32bit machine adds routes to the kernel without complaint. The > 64bit machine complained with send_rtmsg.... > Arrg. IPv6 is once again broken by design. For some ridiculous reason struct sockaddr_in6's size is 28 bytes. So IPv6 fucks up alignment on 64 bit archs. All hail link local addressing and all the crappy workarounds needed for it. Please try the attached diff. -- :wq Claudio Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.164 diff -u -p -r1.164 kroute.c --- kroute.c 9 Feb 2009 08:20:11 -0000 1.164 +++ kroute.c 9 Feb 2009 08:49:00 -0000 @@ -2057,12 +2057,14 @@ retry: int send_rt6msg(int fd, int action, struct kroute6 *kroute) { - struct iovec iov[5]; + struct iovec iov[8]; struct rt_msghdr hdr; struct sockaddr_in6 prefix; struct sockaddr_in6 nexthop; struct sockaddr_in6 mask; struct sockaddr_rtlabel label; + char grmbl[sizeof(long) - (sizeof(prefix) & + (sizeof(long) - 1))]; int iovcnt = 0; if (kr_state.fib_sync == 0) @@ -2070,6 +2072,7 @@ send_rt6msg(int fd, int action, struct k /* initialize header */ bzero(&hdr, sizeof(hdr)); + bzero(grmbl, sizeof(grmbl)); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = action; hdr.rtm_tableid = kr_state.rtableid; @@ -2096,6 +2099,11 @@ send_rt6msg(int fd, int action, struct k /* adjust iovec */ iov[iovcnt].iov_base = &prefix; iov[iovcnt++].iov_len = sizeof(prefix); + /* don't we all love IPv6 */ + hdr.rtm_msglen += sizeof(grmbl); + iov[iovcnt].iov_base = &grmbl; + iov[iovcnt++].iov_len = sizeof(grmbl); + if (memcmp(&kroute->nexthop, &in6addr_any, sizeof(struct in6_addr))) { bzero(&nexthop, sizeof(nexthop)); @@ -2110,6 +2118,10 @@ send_rt6msg(int fd, int action, struct k /* adjust iovec */ iov[iovcnt].iov_base = &nexthop; iov[iovcnt++].iov_len = sizeof(nexthop); + /* don't we all love IPv6 */ + hdr.rtm_msglen += sizeof(grmbl); + iov[iovcnt].iov_base = &grmbl; + iov[iovcnt++].iov_len = sizeof(grmbl); } bzero(&mask, sizeof(mask)); @@ -2123,6 +2135,10 @@ send_rt6msg(int fd, int action, struct k /* adjust iovec */ iov[iovcnt].iov_base = &mask; iov[iovcnt++].iov_len = sizeof(mask); + /* don't we all love IPv6 */ + hdr.rtm_msglen += sizeof(grmbl); + iov[iovcnt].iov_base = &grmbl; + iov[iovcnt++].iov_len = sizeof(grmbl); if (kroute->labelid) { bzero(&label, sizeof(label));