--- v2.2.19/linux/include/linux/inetdevice.h~ Wed Dec 13 11:19:12 2000 +++ linux/include/linux/inetdevice.h Sun Jul 1 14:06:02 2001 @@ -18,6 +18,7 @@ int mc_forwarding; int hidden; int arp_filter; + int forward_shared; void *sysctl; }; @@ -55,6 +56,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 { --- v2.2.19/linux/include/linux/sysctl.h~ Tue Jul 3 00:01:05 2001 +++ linux/include/linux/sysctl.h Sun Jul 1 14:48:48 2001 @@ -274,7 +274,8 @@ NET_IPV4_CONF_BOOTP_RELAY=10, NET_IPV4_CONF_LOG_MARTIANS=11, NET_IPV4_CONF_HIDDEN=12, - NET_IPV4_CONF_ARPFILTER=13 + NET_IPV4_CONF_ARPFILTER=13, + NET_IPV4_CONF_FORWARD_SHARED=14, }; /* /proc/sys/net/ipv6 */ --- v2.2.19/linux/net/ipv4/devinet.c~ Wed Dec 13 11:19:12 2000 +++ linux/net/ipv4/devinet.c Sun Jul 1 14:08:42 2001 @@ -925,7 +925,7 @@ static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[14]; + ctl_table devinet_vars[15]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -970,6 +970,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}}, --- v2.2.19/linux/include/net/ip_fib.h~ Sat Oct 21 12:10:47 2000 +++ linux/include/net/ip_fib.h Sun Jul 1 15:16:03 2001 @@ -200,7 +200,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 device *dev, u32 *spec_dst, u32 *itag); + struct 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 */ --- v2.2.19/linux/net/ipv4/fib_frontend.c~ Sat Oct 21 12:10:47 2000 +++ linux/net/ipv4/fib_frontend.c Sun Jul 1 14:16:19 2001 @@ -189,11 +189,12 @@ */ int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, - struct device *dev, u32 *spec_dst, u32 *itag) + struct device *dev, u32 *spec_dst, u32 *itag, int our) { struct in_device *in_dev = dev->ip_ptr; struct rt_key key; struct fib_result res; + int fwdsh = 0; key.dst = src; key.src = dst; @@ -206,7 +207,9 @@ return -EINVAL; if (fib_lookup(&key, &res)) goto last_resort; - if (res.type != RTN_UNICAST) + if (IN_DEV_FORWARD_SHARED(in_dev)) + fwdsh = (res.type == RTN_LOCAL && !our); + if (res.type != RTN_UNICAST && !fwdsh) return -EINVAL; *spec_dst = FIB_RES_PREFSRC(res); if (itag) @@ -220,9 +223,11 @@ if (in_dev->ifa_list == NULL) goto last_resort; - if (IN_DEV_RPFILTER(in_dev)) + if (IN_DEV_RPFILTER(in_dev) && !fwdsh) return -EINVAL; key.oif = dev->ifindex; + if (fwdsh) + key.iif = loopback_dev.ifindex; if (fib_lookup(&key, &res) == 0 && res.type == RTN_UNICAST) { *spec_dst = FIB_RES_PREFSRC(res); return FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; @@ -230,7 +235,7 @@ return 0; last_resort: - if (IN_DEV_RPFILTER(in_dev)) + if (IN_DEV_RPFILTER(in_dev) && !fwdsh) return -EINVAL; *spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); *itag = 0; --- v2.2.19/linux/net/ipv4/route.c~ Tue Jul 3 00:01:05 2001 +++ linux/net/ipv4/route.c Sun Jul 1 14:48:49 2001 @@ -1037,7 +1037,7 @@ if (!LOCAL_MCAST(daddr)) return -EINVAL; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); - } else if (fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag) < 0) + } else if (fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag, our) < 0) return -EINVAL; rth = dst_alloc(sizeof(struct rtable), &ipv4_dst_ops); @@ -1181,7 +1181,7 @@ if (res.type == RTN_LOCAL) { 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) @@ -1206,7 +1206,7 @@ return -EINVAL; } - err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev, &spec_dst, &itag); + err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev, &spec_dst, &itag, 0); if (err < 0) goto martian_source; @@ -1279,7 +1279,7 @@ if (ZERONET(saddr)) { spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else { - err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag); + err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag, 1); if (err < 0) goto martian_source; if (err) --- v2.2.19/linux/Documentation/proc.txt~ Sat Oct 21 12:12:42 2000 +++ linux/Documentation/proc.txt Sun Jul 1 14:27:55 2001 @@ -1182,6 +1182,16 @@ against your internal networks (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 Accept ICMP redirect messages only for gateways, listed in default gateway list. Enabled by default. --- v2.2.19/linux/Documentation/networking/ip-sysctl.txt~ Sat Oct 21 12:11:52 2000 +++ linux/Documentation/networking/ip-sysctl.txt Sun Jul 1 14:41:33 2001 @@ -149,6 +149,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.