Current-Users archive

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

Re: [5.0_RC3] pppd: Couldn't add proxy arp entry: Invalid argument

On Apr 2, 2009, at 7:52 , Greg Troxel wrote:

route monitor on my system (NetBSD/i386 5.0ish) shows the LLINFO flag on
arp entries generated automatically.

RTM_ADD: Add Route: len 148, pid 0, seq 0, errno 0, flags: <UP,HOST,DONE,LLINFO,CLONED>
locks:  inits:
sockaddrs: <DST,GATEWAY,IFP,IFA>
[ip addr]  ex0:[mac addr] [my-hostname-on-that interface]


arp -s [on-link-ip-addr] 1:2:3:4:5:6

RTM_ADD: Add Route: len 112, pid 14709, seq 2, errno 0, flags: <HOST,DONE,STATIC>
locks:  inits: <expire>
sockaddrs: <DST,GATEWAY>

and the entry has flags UHLS.

Using the 'pub' argument to arp, I see instead

RTM_ADD: Add Route: len 120, pid 18698, seq 2, errno 0, flags: <DONE,STATIC,PROTO2>
locks:  inits: <expire>

I would run 'route -n monitor' and see what the add request looks like
as it prints it.   I see that RTF_ANNOUNCE is RTF_PROTO2.

Except for the length and seq, this is the same when doing an arp -s 0.d.88.6f.2d.37

got message of size 154 on Thu Apr  2 11:46:57 2009
RTM_ADD: Add Route: len 154, pid 16031, seq 1, errno 22, flags: <HOST,STATIC,PROTO2>
locks:  inits: <expire>
sockaddrs: <DST,GATEWAY> 0.d.88.6f.2d.37

I compared the actual data written by arp and by pppd to the routing socket. The differences:

1. pppd's request has the interface name in the sockaddr_dl structure, arp does not
2. arp's  sdl_len is padded by 6 bytes, pppd's is not
3. arp's rtm_msglen is padded by 4 byes, pppd's is not

Changing pppd's arpmsg packet accordingly makes the proxy arp request in pppd work!

The diff below illustrates the changes:

--- sys-bsd.c   25 Oct 2008 22:12:20 -0000      1.58
+++ sys-bsd.c   2 Apr 2009 17:25:32 -0000
@@ -1598,6 +1598,13 @@
        return 0;

+    /* remove the intrafce name from the sdl struct */
+ memcpy((char *)&arpmsg.hwa.sdl_data, (char *)&arpmsg.hwa.sdl_data +arpmsg.hwa.sdl_nlen, arpmsg.hwa.sdl_alen);
+    arpmsg.hwa.sdl_len-=arpmsg.hwa.sdl_nlen;
+    arpmsg.hwa.sdl_nlen=0;
+    /* pad the packet */
+    arpmsg.hwa.sdl_len+=6;
     if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
        error("Couldn't add proxy arp entry: socket: %m");
        return 0;
@@ -1615,7 +1622,7 @@
     arpmsg.dst.sin_other = SIN_PROXY;

     arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
-       + arpmsg.hwa.sdl_len;
+       + arpmsg.hwa.sdl_len + 4;
     if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
        error("Couldn't add proxy arp entry: %m");

I don't understand why the padding is needed, maybe i386 vs. amd64?

I am wondering if pppd is using a pre-4.4 method that doesn't work any
more.  There could also be an architecture-dependent bug that no one
else has hit yet - ppp with proxy arp is becoming not so common.

The next thing is to go through the kernel code and see if you can
figure out how this is supposed to be interpreted, and to add printfs at
the various EINVAL return points.  (or run kgdb).
See sys/net/rtsock.c and sys/net/route.c:rtrequest1

I think you want RTSOCK_DEBUG. There is also RT_DPRINTF that you could figure out how to turn on (seems permanently off, but obviously intended
to do most of what you need).

I am afraid I am not skilled enough to dive into the kernel.

Home | Main Index | Thread Index | Old Index