diff -Naur linux-ssi/Documentation/filesystems/proc.txt linux-ssi-new/Documentation/filesystems/proc.txt --- linux-ssi/Documentation/filesystems/proc.txt 2004-06-15 14:37:43.000000000 -0700 +++ linux-ssi-new/Documentation/filesystems/proc.txt 2004-07-01 13:48:11.000000000 -0700 @@ -1556,6 +1556,18 @@ (external addresses can still be spoofed), without the need for additional firewall rules. +forward_shared +-------------- + +Integer value determines if a source validation should allow forwarding +of packets with local source address. 1 means yes, 0 means no. By default +the flag is disabled and such packets are not forwarded. + +If you enable this flag on internal network, the router will forward +packets from internal hosts with shared IP addresses no matter how +the rp_filter is set. This flag is activated only if it is enabled +both in specific device section and in "all" section. + secure_redirects ---------------- @@ -1576,6 +1588,16 @@ hidden ------ +Hide addresses attached to this device from other devices. +Such addresses will never be selected by source address autoselection +mechanism, host does not answer broadcast ARP requests for them, +does not announce them as source address of ARP requests, but they +are still reachable via IP. This flag is activated only if it is +enabled both in specific device section and in "all" section. + +hidden +------ + Hide addresses attached to this device from another devices. Such addresses will never be selected by source address autoselection mechanism, host does not answer broadcast ARP requests for them, diff -Naur linux-ssi/Documentation/networking/ip-sysctl.txt linux-ssi-new/Documentation/networking/ip-sysctl.txt --- linux-ssi/Documentation/networking/ip-sysctl.txt 2004-06-15 14:37:43.000000000 -0700 +++ linux-ssi-new/Documentation/networking/ip-sysctl.txt 2004-07-01 13:48:11.000000000 -0700 @@ -377,6 +377,17 @@ forwarding - BOOLEAN Enable IP forwarding on this interface. +forward_shared - BOOLEAN + Integer value determines if a source validation should allow + forwarding of packets with local source address. 1 means yes, + 0 means no. By default the flag is disabled and such packets + are not forwarded. + + If you enable this flag on internal network, the router will forward + packets from internal hosts with shared IP addresses no matter how + the rp_filter is set. This flag is activated only if it is + enabled both in specific device section and in "all" section. + mc_forwarding - BOOLEAN Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE and a multicast routing daemon is required. @@ -469,6 +480,14 @@ particular interfaces. Only for more complex setups like load- balancing, does this behaviour cause problems. +hidden - BOOLEAN + Hide addresses attached to this device from other devices. + Such addresses will never be selected by source address autoselection + mechanism, host does not answer broadcast ARP requests for them, + does not announce them as source address of ARP requests, but they + are still reachable via IP. This flag is activated only if it is + enabled both in specific device section and in "all" section. + arp_filter for the interface will be enabled if at least one of conf/{all,interface}/arp_filter is set to TRUE, it will be disabled otherwise diff -Naur linux-ssi/include/linux/inetdevice.h linux-ssi-new/include/linux/inetdevice.h --- linux-ssi/include/linux/inetdevice.h 2004-06-15 14:37:43.000000000 -0700 +++ linux-ssi-new/include/linux/inetdevice.h 2004-07-01 13:49:50.000000000 -0700 @@ -20,6 +20,7 @@ int hidden; int arp_filter; int medium_id; + int forward_shared; void *sysctl; }; @@ -61,6 +62,8 @@ #define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter) +#define IN_DEV_FORWARD_SHARED(in_dev) ((in_dev)->cnf.forward_shared && ipv4_devconf.forward_shared) + struct in_ifaddr { struct in_ifaddr *ifa_next; diff -Naur linux-ssi/include/linux/sysctl.h linux-ssi-new/include/linux/sysctl.h --- linux-ssi/include/linux/sysctl.h 2004-06-29 14:34:36.000000000 -0700 +++ linux-ssi-new/include/linux/sysctl.h 2004-07-01 13:50:15.000000000 -0700 @@ -348,6 +348,7 @@ NET_IPV4_CONF_ARPFILTER=13, NET_IPV4_CONF_MEDIUM_ID=14, NET_IPV4_CONF_HIDDEN=15, + NET_IPV4_CONF_FORWARD_SHARED=16, }; /* /proc/sys/net/ipv6 */ diff -Naur linux-ssi/include/net/ip_fib.h linux-ssi-new/include/net/ip_fib.h --- linux-ssi/include/net/ip_fib.h 2004-06-29 14:34:38.000000000 -0700 +++ linux-ssi-new/include/net/ip_fib.h 2004-07-01 13:48:11.000000000 -0700 @@ -203,7 +203,7 @@ extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, - struct net_device *dev, u32 *spec_dst, u32 *itag); + struct net_device *dev, u32 *spec_dst, u32 *itag, int our); extern void fib_select_multipath(const struct rt_key *key, struct fib_result *res); /* Exported by fib_semantics.c */ diff -Naur linux-ssi/net/ipv4/devinet.c linux-ssi-new/net/ipv4/devinet.c --- linux-ssi/net/ipv4/devinet.c 2004-06-15 14:37:43.000000000 -0700 +++ linux-ssi-new/net/ipv4/devinet.c 2004-07-01 15:57:50.000000000 -0700 @@ -1057,7 +1057,7 @@ static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[16]; + ctl_table devinet_vars[17]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -1108,6 +1108,9 @@ &proc_dointvec}, {NET_IPV4_CONF_ARPFILTER, "arp_filter", &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_CONF_FORWARD_SHARED, "forward_shared", + &ipv4_devconf.forward_shared, sizeof(int), 0644, NULL, &proc_dointvec}, {0}}, diff -Naur linux-ssi/net/ipv4/fib_frontend.c linux-ssi-new/net/ipv4/fib_frontend.c --- linux-ssi/net/ipv4/fib_frontend.c 2004-07-01 18:47:51.000000000 -0700 +++ linux-ssi-new/net/ipv4/fib_frontend.c 2004-07-01 18:54:45.000000000 -0700 @@ -204,13 +204,15 @@ */ int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, - struct net_device *dev, u32 *spec_dst, u32 *itag) + struct net_device *dev, u32 *spec_dst, u32 *itag, + int our) { struct in_device *in_dev; struct rt_key key; struct fib_result res; int no_addr, rpf; int ret; + int fwdsh = 0; key.dst = src; key.src = dst; @@ -225,6 +227,7 @@ if (in_dev) { no_addr = in_dev->ifa_list == NULL; rpf = IN_DEV_RPFILTER(in_dev); + fwdsh = IN_DEV_FORWARD_SHARED(in_dev); } read_unlock(&inetdev_lock); @@ -233,8 +236,15 @@ if (fib_lookup(&key, &res)) goto last_resort; - if (res.type != RTN_UNICAST) + if (fwdsh) { + fwdsh = (res.type == RTN_LOCAL && !our); + if (fwdsh){ + rpf = 0; + } + } + if (res.type != RTN_UNICAST && !fwdsh){ goto e_inval_res; + } *spec_dst = FIB_RES_PREFSRC(res); fib_combine_itag(itag, &res); #ifdef CONFIG_IP_ROUTE_MULTIPATH @@ -252,7 +262,10 @@ goto last_resort; if (rpf) goto e_inval; + key.oif = dev->ifindex; + if (fwdsh) + key.iif = loopback_dev.ifindex; ret = 0; if (fib_lookup(&key, &res) == 0) { diff -Naur linux-ssi/net/ipv4/route.c linux-ssi-new/net/ipv4/route.c --- linux-ssi/net/ipv4/route.c 2004-07-01 18:36:33.000000000 -0700 +++ linux-ssi-new/net/ipv4/route.c 2004-07-01 18:36:33.000000000 -0700 @@ -1267,7 +1267,7 @@ goto e_inval; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else if (fib_validate_source(saddr, 0, tos, 0, - dev, &spec_dst, &itag) < 0) + dev, &spec_dst, &itag, our) < 0) goto e_inval; rth = dst_alloc(&ipv4_dst_ops); @@ -1432,7 +1432,7 @@ int result; result = fib_validate_source(saddr, daddr, tos, loopback_dev.ifindex, - dev, &spec_dst, &itag); + dev, &spec_dst, &itag, 1); if (result < 0) goto martian_source; if (result) @@ -1460,7 +1460,7 @@ } err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev, - &spec_dst, &itag); + &spec_dst, &itag,0); if (err < 0) goto martian_source; if (err) @@ -1543,7 +1543,7 @@ spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); else { err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, - &itag); + &itag, 1); if (err < 0) goto martian_source; if (err)