proxyarp for shaper device, kernel 2.4.9
Subsystems (3)
PATCH 1/1 proxyarp for shaper device, kernel 2.4.9
I report here a tested and working patch to manage proxy arp on shaper device. Details are on readme.txt file attached.
I had problems using only a patch file, if someone could tell me what is the right command to make a diff file for all kernel source tree.... (I tried with "diff -ur tree.orig tree.modified > diff_file" but also other useless data are reported... :-()
Thank you
Best Regards
Roberto Arcomano
Subject: PATCH to update proxy arp feature on shaper device
Author: Roberto Arcomano, [email protected],
http://www.fatamorgana.com/bertolinux
Date: 9/9/2001
Description: Shaper device is seen by the kernel like a
different device (i.e. shaper0) than the physical one (i.e. eth0) to which is attached:
so kernel always issues an "ARP REPLY" (if proxy arp is active on shaper physical interface): this prevent us from use proxy arp on a shaper device cause, during turning on client machine, we would receive an "IP conflit" message.
Solution: Patch consists in 4 files:
a-) "include/linux/netdevice.h", where we add a new
net feature, NETIF_F_SHAPER which will help us to understand if a device is a shaper one.
b-) "drivers/net/shaper.c", in "shaper_probe" function
we set NETIF_F_SHAPER flag for a new shaper device.
c-) "include/linux/if_shaper.h" where we add the macro
IS_SHAPERDEVICE, used to know if the device is a shaper one (it checks NETIF_F_SHAPER flag in features field, under "netdevice" struct).
d-) "net/ipv4/arp.c" where finally we modify proxy arp;
We use shflag to determine if we are managing a shaper device (with IS_SHAPERDEVICE macro): in this case we check "rt->u.dst.dev->priv->dev" (physical device) instead of
"rt->u.dst.dev" (shaper device)
while if the device is a non shaper one, we check rt->u.dst.dev (anded with !shflag)
TODO: I used "features" field in netdevice struct: maybe it could
be choosen another place where to put the shaper flag.
Tests: I tested new feature using 3 PCs like that:
CLIENT1 ------------- LINUX ------------- CLIENT2
shaper0 ppp0
[eth0]
LINUX host has proxy arp and shaper enabled, with CLIENT1 reachable via shaper0.
With classic proxy arp, when I turn on CLIENT machine I receive an "IP conflit" from OS, while using patched version there are no problems.
Proxy arp still does its work cause, if I give CLIENT2 IP address to CLIENT1 machine, I receive (from CLIENT1 OS) a IP busy message.
Also tests on commercial server have been done with good results.
Kernel version tested is 2.4.9
Final notes: It should be very simple to port patch to older
kernel version (2.0.xx, 2.1.xx, 2.2.xx, 2.3.xx)
drivers/net/shaper.c +1 -0
@@ -670,6 +670,7 @@ dev->addr_len =0 ; dev->tx_queue_len =10 ; dev->flags =0 ; + dev->features |=NETIF_F_SHAPER ;/* * Shaper is ok
include/linux/netdevice.h +1 -0
@@ -345,6 +345,7 @@#define NETIF_F_DYNALLOC 16/* Self-dectructable device. */ #define NETIF_F_HIGHDMA 32/* Can DMA to high memory. */ #define NETIF_F_FRAGLIST 64/* Scatter/gather IO. */ +#define NETIF_F_SHAPER 128/* Shaper device. */ /* Called after device is detached from network. */ void (*uninit)(struct net_device *dev);
include/linux/if_shaper.h +2 -0
@@ -14,6 +14,8 @@#define SHAPER_MAXSLIP 2#define SHAPER_BURST (HZ/50)/* Good for >128K then */ +#define IS_SHAPERDEVICE (dev) ((dev)->features & NETIF_F_SHAPER) +struct shaper {struct sk_buff_head sendq;
net/ipv4/arp.c +9 -3
@@ -111,8 +111,7 @@#include <asm/system.h> #include <asm/uaccess.h> - - +#include <linux/if_shaper.h> /* * Interface to generic neighbour cache.
@@ -767,8 +766,15 @@ } goto out; }else if (IN_DEV_FORWARD (in_dev)) { +char shflag=0 ; +if ( (rt->u.dst.dev) && + (rt->u.dst.dev->priv) && + (((struct shaper *) rt->u.dst.dev->priv)->dev) && + (IS_SHAPERDEVICE (rt->u.dst.dev)) ) + shflag=1 ;if ((rt->rt_flags&RTCF_DNAT ) || - (addr_type ==RTN_UNICAST && rt->u.dst.dev != dev && + (addr_type ==RTN_UNICAST && + ( ((shflag) && ( ((struct shaper *) rt->u.dst.dev->priv)->dev != dev)) || ((!shflag) && (rt->u.dst.dev != dev)) ) && (IN_DEV_PROXY_ARP (in_dev) ||pneigh_lookup (&arp_tbl, &tip, dev,0 )))) { n =neigh_event_ns (&arp_tbl, sha, &sip, dev);if (n)