Re: arp, kernel 2.2.15 and 2.3.99-pre6

From: Andrey Savochkin (saw@saw.sw.com.sg)
Date: Sat May 06 2000 - 23:26:58 EST


Hello,

On Sat, May 06, 2000 at 08:50:38AM +0300, Julian Anastasov wrote:
> On Sat, 6 May 2000, Andrey Savochkin wrote:
> > What autoselection are you speaking about?
>
> Sorry. This is the source address autoselection.

OK. The next question: which source address?
Source for ARP requests for forwarding packets?
Source for locally originated IP packets sent from unbound socket and going
through routes without pref_src? Or whatever else source?
Please keep in mind that inet_select_addr()
controls both of the source selections mentioned above.

> 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?

Sorry, I don't see the point of any modifications for inet_select_addr.
IN_DEV_HIDDEN is an absolute alien here!

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

Fine.

> > 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.

I was speaking about ARP request in the opposite direction (from packet
receiver to sender under normal circumstances). That's why I think an option
to control the 2 variants of the behavior (skb source with fallback to
{inet,fib}_select_addr, or just {inet,fib}_select_addr).

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

Great.

> 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.

IP addresses have only minimal relations with devices, if have any.
Addresses are the matter of IP routing, devices are the matter of packet
transmission/reception. Certainly, checking the device flags in address
lookup routine (fib_local_source) is a strange thing.
Any sane kernel should work if there are several independent IP networks are
configured on the same media as well if there is only one network.

Andi's patch essentially do the following: it introduce a per-device flag
whether to apply some route-based rules to check whether to reply to the ARP
request. This concept is ok. Moreover, it's the only acceptable concept in
this area I've heard. Do you have any objections against the proposed
implementation of the route-based check (arp_filter routine itself)? That's
the only place where different solutions may exist.

[snip]
> ... 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?
[snip]
> 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);
> }

It's very wrong, because you're starting to toss with
per-device settings in the place where we hopefully reduced the question to
the routing table examination.

So, is it true that Andi's patch together with something like the
patch below allows you to solve your problems?

--- net/ipv4/arp.c.orig Sun May 7 11:55:03 2000
+++ net/ipv4/arp.c Sun May 7 11:55:03 2000
@@ -330,13 +330,16 @@
         u32 saddr;
         u8 *dst_ha = NULL;
         struct net_device *dev = neigh->dev;
+ struct in_device *in_dev = in_dev_get(dev);
         u32 target = *(u32*)neigh->primary_key;
         int probes = atomic_read(&neigh->probes);
 
- if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
+ if (skb && (in_dev == NULL || !IN_DEV_DEFAULT_ARP_SRC(in_dev)) &&
+ inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
                 saddr = skb->nh.iph->saddr;
         else
                 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
+ in_dev_put(in_dev);
 
         if ((probes -= neigh->parms->ucast_probes) < 0) {
                 if (!(neigh->nud_state&NUD_VALID))

inet_select_addr() may be replaced by fib_select_address() here for more
flexibility. But no device flag checks inside! :-)

Best regards
                                        Andrey V.
                                        Savochkin

-
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:20 EST