On Mon, Feb 9, 2009 at 12:53 AM, Claudio Jeker <cje...@diehard.n-r-g.com> 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.

--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));

Reply via email to