Port-xen archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: static ARP entry bug?



On Wed, Aug 12, 2009 at 06:21:54PM +0200, Manuel Bouyer wrote:
> On Wed, Aug 12, 2009 at 08:59:18AM -0400, Greg Troxel wrote:
> > 
> > You are right - I am having the same problem.
> > 
> > So I think something is wrong with if_xennet.
> 
> What's wrong is the name is too long :)
> 
> The problem is in if_arp.c:
>         case RTM_RESOLVE:
>               if (gate->sa_family != AF_LINK ||
>                   gate->sa_len < sockaddr_dl_measure(namelen, addrlen)) {
> 
> gate->sa_family is correct, but gate->sa_len is shorter by one.
> 'struct sockaddr_dl' has by default 12 bytes for address+ifname, which leaves
> 6 bytes for the interface name, which is one too short for xennet0.
> One obvious workaround would be to bump sockaddr_dl->sdl_data to 16 I guess.
> But it's only a workaround. My guess is that arp_setgate() should
> handle this case and allocate a larger struct sockaddr_dl when needed,
> but I don't know what the side effect of doing a rt_setgate() in
> the !RTF_CLONING could be.

I tried the quick&dirty patch attached. Now arp -s doens't return an error,
but the kenrel complains on arp -a:
arpresolve: unresolved and rt_expire == 0
and the entry doesn't appear as permanent (it appears as "unresolved"
before trying to ping the address and as a standart arp entry after).
So more work is needed.

-- 
Manuel Bouyer, LIP6, Universite Paris VI.           
Manuel.Bouyer%lip6.fr@localhost
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: if_arp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/if_arp.c,v
retrieving revision 1.143
diff -u -p -u -r1.143 if_arp.c
--- if_arp.c    24 Oct 2008 17:07:33 -0000      1.143
+++ if_arp.c    12 Aug 2009 16:28:14 -0000
@@ -428,7 +428,8 @@ arp_setgate(struct rtentry *rt, struct s
        if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
            satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
                rt->rt_flags |= RTF_CLONING;
-       if (rt->rt_flags & RTF_CLONING) {
+       if ((rt->rt_flags & RTF_CLONING) ||
+           gate->sa_len < sockaddr_dl_measure(namelen, addrlen)) {
                union {
                        struct sockaddr sa;
                        struct sockaddr_storage ss;
@@ -517,7 +518,9 @@ arp_rtrequest(int req, struct rtentry *r
                gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
                break;
        case RTM_ADD:
+               printf("gate %p sa_len %d ", gate, gate->sa_len);
                gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
+               printf("now %p sa_len %d\n", gate, gate->sa_len);
                if (rt->rt_flags & RTF_CLONING) {
                        /*
                         * Give this route an expiration time, even though
@@ -568,7 +571,7 @@ arp_rtrequest(int req, struct rtentry *r
        case RTM_RESOLVE:
                if (gate->sa_family != AF_LINK ||
                    gate->sa_len < sockaddr_dl_measure(namelen, addrlen)) {
-                       log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
+                       log(LOG_DEBUG, "arp_rtrequest: bad gateway value %d %d 
%d %d %d\n",  gate->sa_family, gate->sa_len, sockaddr_dl_measure(namelen, 
addrlen), namelen, addrlen);
                        break;
                }
                satosdl(gate)->sdl_type = ifp->if_type;


Home | Main Index | Thread Index | Old Index