Re: arp, kernel 2.2.15 and 2.3.99-pre6

From: Julian Anastasov (uli@linux.tu-varna.acad.bg)
Date: Sat May 06 2000 - 00:50:38 EST


        Hello,

On Sat, 6 May 2000, Andrey Savochkin wrote:

> Hello Julian,
>
> On Fri, May 05, 2000 at 02:41:14PM +0300, Julian Anastasov wrote:
> > > > 2. the real servers must not broadcast ARP requests with
> > > > saddr=VIP because only the Director must announce VIP. For
> > > > this the real servers must announce another IP as source
> > > > address for the ARP request. I.e. requests such as "who-has
> > > > ROUTER tell VIP" are allowed for the Director only. The
> > > > real hosts must announce another visible (and uniq) IP
> > > > address to the router or the reply will not be received.
> > > > This can't be handled using a filter. This is a logic.
> > >
> > > You may easily implement it without any kernel modifications.
> > > Check how ARP engine selects source address. In the current kernels it picks
> > > up the address from the same network without "secondary" flag.
> >
> > LVS doesn't use autoselection. The change in the
>
> What autoselection are you speaking about?

        Sorry. This is the source address autoselection.
The check in inet_select_addr for IN_DEV_HIDDEN. By the way
I'm still not sure why this check is in the loop. It can be
moved before the for(), for example:

        if (IN_DEV_HIDDEN(in_dev))
                continue;
        for_primary_ifa(in_dev) {
                if (ifa->ifa_scope <= scope &&
                    ifa->ifa_scope != RT_SCOPE_LINK)
                        return ifa->ifa_local;
        } endfor_ifa(in_dev);

        Alexey, is there a reason the check to be in the
in_dev loop?

>
> > autoselection is included only to cover the "hidden"
> > functionality. The VIP is local address (we can talk IP) but
> > it is not advertised. I think, the feature is very clear.
> > Look in arp_solicit. We can set per-device flag if the src
> > IP address in the header can be announced. This is the
> > trick which is not present in the arpfilter functionality
> > (Andi, I see, the hidden functionality is not replaced from
> > arpfilter) nor in fib_local_source (route.generic). I.e. the
> > feature to hide some local IP addresses by not including
> > them in the ARP requests, addresses which are shared in the
> > LAN. This feature covers such shared IP addresses. It can't
> > be tuned at routing level, at least this will be more
> > difficult: to disable some local addresses to be announced
> > in the ARP requests.
>
> I do not understand you well.
> Are you speaking about the problem that you send packets with VIP source but
> want to use different IP address in the ARP request headers?

        Exactly. I want specific local addresses not to be
announced as source of the ARP request. They are shared
addresses and it is assumed that only one host on the LAN
will treat them normally. In my example only the Director
can use it. In the webs this VIP is configured on hidden
device. By this way the real servers can receive locally
packets with daddr=VIP but they use non-shared addresses for
their broadcast ARP requests. This is same as the
transparent proxy support. We can talk IP using non-local
IP address but we use other local address in the ARP
requests (from inet_select_addr).
 
> Well, with route.generic patch you _are able_ to solve the problem by
> introducing a policy route for packets with src=GW and dst=VIP and
> dev=your_dev as a non-local route. But it's not elegant. I agree that we
> should try to find a more clear way to do it.

        Yep.
 
> [snip]
> > > BTW, I fix the plain-and-dumb ARP source selection in my patch.
> > > ftp://ftp.sw.com.sg/pub/Linux/people/saw/kernel/v2.3/route.generic
> > > (look at arp.c changes).
> >
> > I see. May be the fib_local_source call will be
> > replaced with arp_local_src? May be we have problem here? We
> > need a way to skip some local addresses and not to announce
> > them as source of the ARP request: the shared local
> > addresses.
>
> Are you suggesting to stop to use skb source for ARP requests and use only
> inet_select_addr() or fib_select_addr() or dedicated "ARP request" addresses?

        Yes, we fallback to {inet,fib}_select_addr in such
case.
 
> In general case it increases the ARP traffic on the link, but it's perfectly
> ok for me if this behavior may be turned on and off.

        The ARP request is sent in any case. We only
restrict some local addresses not to be used as source of
the broadcast request, i.e. the saddr is changed only.
 
> Does Andi's filters plus this change of arp_solicit() policy solve all the
> problems for you network configurations?

        Yes. This is possible. But my understanding is that
we can have two variants to control the interfaces:

1. Change the flag for the interface where the ARP requests
come from (arpfilter) and don't reply for IP addresses not
on this interface.

2. Change the flag for the interface for which you don't
reply its IP addresses (hidden) through the other ARP
devices.

        I think, the two variants only can increase the
flexibility. But if arpfilter is going to replace the hidden
functionality I think arpfilter must include change in
arp_solicit. There must be restriction to announce only
addresses from this device as source for the ARP requests.
Currently, only "hidden" feature has such check.

        If this change in arp_solicit exists we can live
without "hidden" feature. The change in arp_solicit may
include a fib_lookup call. For the arpfilter this is easier
than for the hidden feature. But may be it is possible. Is
it possible fib_local_source to be replaced in arp_solicit
with call to a similar function which uses fib_lookup but
restricts the local address to be from the output device?

        Please, correct me:
        
int fib_local_arp_source(u32 saddr, u32 daddr, u8 tos, struct net_device *dev)
{
        struct rt_key key;
        struct fib_result res;
        struct in_device *in_dev;

        memset(&key, 0, sizeof(key));
        key.src = daddr;
        key.dst = saddr;
        key.tos = tos;
        key.iif = dev->ifindex;
        in_dev = in_dev_get(dev);
        if (IN_DEV_ARPFILTER(in_dev))
                key.oif = dev->ifindex;
        in_dev_put(in_dev);
        ret = -EINVAL;
        if (fib_lookup(&key, &res) == 0) {
                if (res.type == RTN_LOCAL) {
                        in_dev = in_dev_get(FIB_RES_DEV(res));
                        if (!in_dev) goto out;
                        if (!IN_DEV_HIDDEN(in_dev))
                                ret = 0;
                        in_dev_put(in_dev);
                }
                out:
                fib_res_put(&res);
        }
        return ret;
}

        Is this code correct? Something near this code :)
May be I incorrectly build the request. May be arpfilter + hidden
can coexist?

        BTW fib_local_source returns 0 when fib_lookup
fails. Is this correct?

Regards

--
Julian Anastasov <uli@linux.tu-varna.acad.bg>

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun May 07 2000 - 21:00:19 EST