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

Reply via email to