Subject: Re: FW: IFF_NOARP, RTM_RESOLVE ...
To: Sundstrom, Per <Per.Sundstrom@compaq.com>
From: Ignatios Souvatzis <ignatios@cs.uni-bonn.de>
List: tech-net
Date: 05/05/2000 12:55:56
Thought I answered your message from home, but I can't find my message...

> We have a need for a daemon based arp resolver in a firewall-like
> application where we need to have full control over the arp resolution.

Assuming you really need this (you can often get away with using the bpf
interface, like rarpd and proxyarpd do),

> Suggested solution:
> 
>   Move the generation of RTM_RESOLVE for interface routes to
>   if_arp.c

You have to be careful... if_arp isn't the only module involved (it is only
used for IPv4). IPv6 is handling the same task by "neighbour discovery", 
Appletalk does Apple-ARP (aarp) etc.

So, if you move the message generation to a different place, out of route.c,
you have to adapt more places than just arp. Something like a function hook
would be needed.

Actually, there _is_ a function hook (ifa->ifa_rtrequest, where ifa is 
struct ifaddr *) used for this purpose.

This function hook is per-interface address record, so the per-protocol
seperation is already handled for you.

For IPv4 ifaddr of ARPing interfaces, this is set to arp_rtrequest.
You could do two things:

- either enhance arp_rtrequest to test the ARP bit and branch
- or swap yourcode_rtrequest and arp_rtrequest, when the ARP bit is set or
  unset.

yourcode_rtrequest would then, on RTM_RESOLVE requests, use the functions
in net/rtsock.c to compose the message going out of routing sockets, and on
RTM_ADD, handle the sending out of the la_hold packet like in_arpinput() does.

if I read the code right, the aprequest() functions (called by w.g.
ether_output) will already have managed holding the last sent packet for you.
You might need a hook in there.

hm... Let me look again.


- ether_output (and arc_output, token_output) call arpresolve() for outputting
packets.
- arpresolve checks to see if a rt is present, and uses its rt_llinfo 
  if there, else does an arplookup() and uses its la->rt for the rt.

- if the rt is complete, the packet is sent out, else (rt incomplete) the
  packet is stored in la->la_hold (possibly freeing a former packet waiting
  for the same destination).

- the code below handles resending of an arp request.

as for arplookup(): it calls rtalloc1(), which does the requesting of
RTM_RESOLVE, calling rtrequest(), which in turn calls eventually the
ifa->ifa_rtrequest which is arp_rtreuqest. So yes, at that place, you can
hook in and  holding the packet is handled for you.

Your arp_rtrequest replacement or addition will need to handle the sending out,
like in_arpinput does normally.

At least, thats what I deduced from browsing the code.

When your code is ready, show us the diffs.

Regards,
	Ignatios

-- 
 * Progress (n.): The process through which Usenet has evolved from
   smart people in front of dumb terminals to dumb people in front of
   smart terminals.  -- obs@burnout.demon.co.uk (obscurity)