lkml.org 
[lkml]   [1997]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectip_alias BUGFIX for pre-2.0.31-9
This patch is a !MUST! for a 2.0.31 (unless we want pretty arp games 
when aliasing is turned on for a netdevice).

This (tested) patch fixes ip_alias ARP storms (notably on big switched
nets) caused by route lookup needed for alias netdevice switching.

ARP and routing problems related to aliasing:
Originally aliasing was doing innecesary arp lookups when trying to
do netdevice selection (after a while arp table was holding almost
every host in the bus).
This problem was fixed around 2.0.2x by restricting aliasing lookups
only to packets for us. This, in turn, broke inter-alias routing.
In 2.0.31pre6+ this changes were undone. Present patch fixes arp
storming by calling route lookups without hh generation.

Changes:
route.c : added struct device * ip_rt_dev(__u32 addr);
ip_alias.c : uses ip_rt_dev() instead of ip_rt_route()
ip_input.c : alias netdevice switching only makes sense if PACKET_HOST
Updated alias.txt
Missing ip_dynaddr.txt included.

Regards!

-- Juanjo
Yo don't need an hologram to know...
Nor you need to sell your brain to anyone.
Yo can feel it. It's Linux.


--- linux/net/ipv4/arp.c.dist Wed Sep 10 13:36:58 1997
+++ linux/net/ipv4/arp.c Tue Sep 16 16:48:30 1997
@@ -1921,6 +1921,7 @@
{
/*
* net_alias_dev_rx32 returns main dev if it fails to found other.
+ * if successful, also incr. alias rx count.
*/
dev = net_alias_dev_rx32(dev, AF_INET, sip, tip);

--- linux/net/ipv4/ip_input.c.dist Wed Sep 10 13:36:59 1997
+++ linux/net/ipv4/ip_input.c Tue Sep 16 16:48:30 1997
@@ -299,10 +299,13 @@
* Try to select closest <src,dst> alias device, if any.
* net_alias_dev_rx32 returns main device if it
* fails to found other.
+ * If successful, also incr. alias rx count.
+ *
+ * Only makes sense for unicasts - Thanks ANK.
*/

#ifdef CONFIG_NET_ALIAS
- if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) {
+ if (skb->pkt_type == PACKET_HOST && iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) {
skb->dev = dev = net_alias_dev_rx32(skb->dev, AF_INET, iph->saddr, iph->daddr);
}
#endif
--- linux/include/net/route.h.dist Wed Sep 10 13:53:23 1997
+++ linux/include/net/route.h Tue Sep 16 16:48:30 1997
@@ -85,6 +85,7 @@
extern void ip_rt_update(int event, struct device *dev);
extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev);
extern struct rtable *ip_rt_slow_route(__u32 daddr, int local, struct device *dev);
+extern struct device *ip_rt_dev(__u32 addr);
extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy);
extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy);
extern int ip_rt_ioctl(unsigned int cmd, void *arg);
--- linux/net/ipv4/ip_alias.c.dist Wed Sep 10 13:36:58 1997
+++ linux/net/ipv4/ip_alias.c Tue Sep 16 16:48:30 1997
@@ -2,12 +2,14 @@
* IP_ALIAS (AF_INET) aliasing module.
*
*
- * Version: @(#)ip_alias.c 0.43 12/20/95
+ * Version: @(#)ip_alias.c 0.50 6/14/97
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
* Fixes:
* JJC : ip_alias_dev_select method.
+ * JJC : use ip_rt_dev instead of ip_rt_route
+ * JJC : new no_sel semantics
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -76,11 +78,13 @@
(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
}

+/*
+ * Called by net_alias module when no local alias address has been hit,
+ * to find out if an alias is a better candidate for handling given addr
+ */
struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
{
__u32 addr;
- struct rtable *rt;
- struct device *dev=NULL;

/*
* Defensive...
@@ -102,13 +106,12 @@
* net_alias module will check if returned device is main_dev's alias
*/

- rt = ip_rt_route(addr, 0, NULL);
- if(rt)
- {
- dev=rt->rt_dev;
- ip_rt_put(rt);
- }
- return dev;
+ /*
+ * Fixed arping caused by incorrectly using ip_rt_route(),
+ * ip_rt_dev() just returns routing device without hh generation.
+ */
+
+ return ip_rt_dev(addr);
}

/*
@@ -149,8 +152,23 @@

#ifdef MODULE

+/*
+ * If no_sel is set, alias association (device selection) with
+ * foreign addresses will be disabled.
+ * You will get:
+ * - faster operation by avoiding completely routing lookups
+ * You will loose:
+ * - inter-alias routing
+ * - proxyarp over aliases
+ */
+
+int no_sel = 0;
+
int init_module(void)
{
+ if (no_sel)
+ ip_alias_type.dev_select = NULL;
+
if (ip_alias_init() != 0)
return -EIO;
return 0;
--- linux/net/ipv4/route.c.dist Wed Sep 10 13:36:59 1997
+++ linux/net/ipv4/route.c Tue Sep 16 16:48:30 1997
@@ -46,6 +46,7 @@
* Andi Kleen : Don't send multicast addresses to
* kerneld.
*
+ * Juan Jose Ciarlante : Added ip_rt_dev
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -1533,6 +1534,20 @@
* refcnt goes to zero, because nobody else will... */
if ( rt && (rt->rt_flags & RTF_NOTCACHED) && (!rt->rt_refcnt) )
rt_free(rt);
+}
+
+/*
+ * Return routing dev for given address.
+ * Called by ip_alias module to avoid using ip_rt_route and
+ * generating hhs.
+ */
+struct device * ip_rt_dev(__u32 addr)
+{
+ struct fib_node *f;
+ f = fib_lookup(addr, NULL);
+ if (f)
+ return f->fib_info->fib_dev;
+ return NULL;
}

struct rtable * ip_rt_route(__u32 daddr, int local, struct device *dev)
--- linux/net/netsyms.c.dist Wed Sep 10 13:37:00 1997
+++ linux/net/netsyms.c Tue Sep 16 16:48:30 1997
@@ -100,6 +100,7 @@

X(init_etherdev),
X(ip_rt_route),
+ X(ip_rt_dev),
X(icmp_send),
X(ip_options_compile),
X(ip_rt_put),
--- linux/include/net/ip_alias.h.dist Tue Dec 26 01:03:01 1995
+++ linux/include/net/ip_alias.h Tue Sep 16 16:48:31 1997
@@ -2,7 +2,7 @@
* IP_ALIAS (AF_INET) aliasing definitions.
*
*
- * Version: @(#)ip_alias.h 0.43 12/20/95
+ * Version: @(#)ip_alias.h 0.50 4/20/97
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
--- linux/Documentation/networking/alias.txt.dist Wed Sep 10 13:36:29 1997
+++ linux/Documentation/networking/alias.txt Tue Sep 16 16:48:31 1997
@@ -6,6 +6,7 @@
(specific IP) support.
From version 0.50, dynamic configuration of max alias per device and
tx/rx stats for aliases added.
+ Also fixed inter-alias routing and arping problems.

Features
--------
@@ -35,9 +36,38 @@
# modprobe ip_alias.o

Also, dynamic loading is supported (kerneld).
- You should have the following line in /etc/conf.modules:
+ You should have the following line in /etc/conf.modules (not needed
+ for newer modutils):
alias net_alias-2 ip_alias

+ Module options
+ --------------
+ From 0.5x ip_alias module supports a new option ("no_sel" symbol).
+ If no_sel is set (default is 0), alias association (device selection) with
+ foreign addresses will be disabled.
+
+ You will get:
+ - Faster operation by avoiding completely routing lookups.
+ Due to the "logical nature" of aliasing, netdevice SELection can only be
+ done based on info from network layer. When packet dst address isn't
+ one of my addresses, I query the routing table to see which netdevice
+ would be selected for packet _source_ address. This option avoids
+ doing so, and you must consider using it if you *only* have same-net
+ aliases (common usage).
+
+ You will loose:
+ - Inter-alias routing
+ - Proxyarp over aliases
+
+ To activate:
+ # insmod ip_alias.o no_sel=1
+ or
+ # modprobe ip_alias.o no_sel=1
+ or
+ add the following line to /etc/conf.modules:
+ options ip_alias no_sel=1
+
+
o Alias creation.
Alias creation is done by 'magic' iface naming: eg. to create a
200.1.1.1 alias for eth0 ...
@@ -81,9 +111,9 @@
device family address
eth0:0 2 200.1.1.1

-o PROCfs dynamic configuration
+o PROCfs dynamic configuration (from v0.50)
You can now change the max aliases per device limit via
- /proc/sys/net/core/net_alias_max entry
+ /proc/sys/net/core/net_alias_max entry (default=256)
# cat /proc/sys/net/core/net_alias_max
256
# echo 1000 > /proc/sys/net/core/net_alias_max
@@ -111,9 +141,9 @@
Fake rx/tx stats are accounted:
- TX
When the packet is ``switched'' from logical alias device to
- physical device, tx counter gets incr.
+ physical device, tx counter gets incremented.
- RX
- When an incoming packet's address equals alias device's addr it
+ When an incoming packet's address equals alias network device's addr it
gets ``switched'' from physical to logical device, rx counter gets
incr.

@@ -122,7 +152,23 @@
will NOT pass down via alias device (so, no tx++ will occur).

Also NOTE that currently ifconfig does not handle the ``:'' of alias devices
- names, a little patch (attached) solves the problem.
+ names, a little patch solves the problem:
+--- ifconfig.c.dist Tue Apr 4 17:58:32 1995
++++ ifconfig.c Fri Oct 25 13:11:23 1996
+@@ -243,7 +243,12 @@
+ bp++;
+ if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
+ {
+- bp=strchr(bp,':');
++ /*
++ * start bp at ifname end to prevent ':' ambiguity
++ * with alias devices (eg. eth0:0)
++ *
++ */
++ bp+=strlen(ifname);
+ bp++;
+ sscanf(bp,"%d %d %d %d %d %d %d %d %d %d %d",
+ &ife->stats.rx_packets,

Relationship with main device
-----------------------------
@@ -138,7 +184,12 @@
Please e-mail me:
Juan Jose Ciarlante <irriga@impsat1.com.ar> or <jjciarla@raiz.uncu.edu.ar>

-
+Acknowledments
+--------------
+Special thanks to Claudia for all her love an patience.
+Also thanks to Antonio Trevi~o <antonio@ecord.gov.ar> great human being
+and un*x guru.
+
; local variables:
; mode: indented-text
; mode: auto-fill
--- linux/Documentation/networking/ip_dynaddr.txt.dist Tue Sep 16 18:15:48 1997
+++ linux/Documentation/networking/ip_dynaddr.txt Tue Sep 16 16:48:31 1997
@@ -0,0 +1,29 @@
+IP dynamic address hack-port v0.03
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This stuff allows diald ONESHOT connections to get established by
+dynamically changing packet source address (and socket's if local procs).
+It is implemented for TCP diald-box connections(1) and IP_MASQuerading(2).
+
+If enabled[*] and forwarding interface has changed:
+ 1) Socket (and packet) source address is rewritten ON RETRANSMISSIONS
+ while in SYN_SENT state (diald-box processes).
+ 2) Out-bounded MASQueraded source address changes ON OUTPUT (when
+ internal host does retransmission) until a packet from outside is
+ received by the tunnel.
+
+This is specially helpful for auto dialup links (diald), where the
+``actual'' outgoing address is unknown at the moment the link is
+going up. So, the *same* (local AND masqueraded) connections requests that
+bring the link up will be able to get established.
+
+[*] At boot, by default no address rewriting is attempted.
+ To enable:
+ # echo 1 > /proc/sys/net/ipv4/ip_dynaddr
+ To enable verbose mode:
+ # echo 2 > /proc/sys/net/ipv4/ip_dynaddr
+ To disable (default)
+ # echo 0 > /proc/sys/net/ipv4/ip_dynaddr
+
+Enjoy!
+
+-- Juanjo <jjciarla@raiz.uncu.edu.ar>
--- linux/CREDITS.dist Wed Sep 10 13:36:27 1997
+++ linux/CREDITS Tue Sep 16 16:48:31 1997
@@ -243,6 +243,7 @@
E: irriga@impsat1.com.ar
D: Network driver alias support
D: IP masq hashing and app modules
+D: IP ip_dynaddr bits
S: Las Cuevas 2385 - Bo Guemes
S: Las Heras, Mendoza CP 5539
S: Argentina
\
 
 \ /
  Last update: 2005-03-22 13:40    [from the cache]
©2003-2011 Jasper Spaans