On Mon, Feb 09, 2009 at 02:22:08AM -0800, patrick keshishian wrote:
> On Mon, Feb 9, 2009 at 12:53 AM, Claudio Jeker <[email protected]>
> wrote:
> >> 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.
>
> Maybe it is too late for me to be thinking about this ... but could
> you explain the diff below? Unless I'm missing something obvious, it
> looks like it changes behavior for non-64bit archs as well.
>
Hmm. I think your right. I think a different approach would be better.
Will cook up something later today.
> --patrick
>
>
> > 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));
>
--
:wq Claudio