diff -urN v2.5.67/linux/Documentation/filesystems/proc.txt linux/Documentation/filesystems/proc.txt --- v2.5.67/linux/Documentation/filesystems/proc.txt Tue Mar 18 23:09:46 2003 +++ linux/Documentation/filesystems/proc.txt Sat Apr 12 17:17:18 2003 @@ -1436,6 +1436,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 ---------------- @@ -1452,6 +1464,16 @@ -------------- Determines whether to send ICMP redirects to other hosts. + +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. Routing settings ---------------- diff -urN v2.5.67/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt --- v2.5.67/linux/Documentation/networking/ip-sysctl.txt Tue Feb 25 01:56:45 2003 +++ linux/Documentation/networking/ip-sysctl.txt Sat Apr 12 17:17:18 2003 @@ -385,6 +385,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. @@ -484,6 +495,15 @@ tag - INTEGER Allows you to write a number, which can be used as required. Default value is 0. + + +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. (1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact diff -urN v2.5.67/linux/include/linux/inetdevice.h linux/include/linux/inetdevice.h --- v2.5.67/linux/include/linux/inetdevice.h Mon Nov 11 23:43:52 2002 +++ linux/include/linux/inetdevice.h Sat Apr 12 17:17:18 2003 @@ -21,6 +21,8 @@ int medium_id; int no_xfrm; int no_policy; + int hidden; + int forward_shared; void *sysctl; }; @@ -47,6 +49,7 @@ #define IN_DEV_LOG_MARTIANS(in_dev) (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians) #define IN_DEV_PROXY_ARP(in_dev) (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp) +#define IN_DEV_HIDDEN(in_dev) ((in_dev)->cnf.hidden && ipv4_devconf.hidden) #define IN_DEV_SHARED_MEDIA(in_dev) (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media) #define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects) #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) @@ -60,6 +63,8 @@ (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects))) #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 { diff -urN v2.5.67/linux/include/linux/sysctl.h linux/include/linux/sysctl.h --- v2.5.67/linux/include/linux/sysctl.h Tue Feb 25 01:56:55 2003 +++ linux/include/linux/sysctl.h Sat Apr 12 17:17:18 2003 @@ -355,6 +355,8 @@ NET_IPV4_CONF_MEDIUM_ID=14, NET_IPV4_CONF_NOXFRM=15, NET_IPV4_CONF_NOPOLICY=16, + NET_IPV4_CONF_HIDDEN=17, + NET_IPV4_CONF_FORWARD_SHARED=18, }; /* /proc/sys/net/ipv6 */ diff -urN v2.5.67/linux/include/net/ip_fib.h linux/include/net/ip_fib.h --- v2.5.67/linux/include/net/ip_fib.h Tue Nov 19 00:13:38 2002 +++ linux/include/net/ip_fib.h Sat Apr 12 17:17:18 2003 @@ -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 flowi *flp, struct fib_result *res); /* Exported by fib_semantics.c */ diff -urN v2.5.67/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.5.67/linux/net/ipv4/arp.c Wed Apr 9 01:18:31 2003 +++ linux/net/ipv4/arp.c Sat Apr 12 17:17:18 2003 @@ -67,6 +67,8 @@ * now it is in net/core/neighbour.c. * Krzysztof Halasa: Added Frame Relay ARP support. * Arnaldo C. Melo : convert /proc/net/arp to seq_file + * Julian Anastasov: "hidden" flag: hide the + * interface and don't reply for it */ #include @@ -320,12 +322,23 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) { u32 saddr; + int from_skb; + struct in_device *in_dev2 = NULL; + struct net_device *dev2 = NULL; u8 *dst_ha = NULL; struct net_device *dev = neigh->dev; u32 target = *(u32*)neigh->primary_key; int probes = atomic_read(&neigh->probes); - if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL) + from_skb = (skb && + (dev2 = ip_dev_find(skb->nh.iph->saddr)) != NULL && + (in_dev2 = in_dev_get(dev2)) != NULL && + !IN_DEV_HIDDEN(in_dev2)); + if (dev2) { + if (in_dev2) in_dev_put(in_dev2); + dev_put(dev2); + } + if (from_skb) saddr = skb->nh.iph->saddr; else saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); @@ -731,9 +744,22 @@ /* Special case: IPv4 duplicate address detection packet (RFC2131) */ if (sip == 0) { - if (arp->ar_op == htons(ARPOP_REQUEST) && - inet_addr_type(tip) == RTN_LOCAL) + int reply; + struct net_device *dev2 = NULL; + struct in_device *in_dev2 = NULL; + + reply = + (arp->ar_op == htons(ARPOP_REQUEST) && + (dev2 = ip_dev_find(tip)) != NULL && + (dev2 == dev || + ((in_dev2 = in_dev_get(dev2)) != NULL && + !IN_DEV_HIDDEN(in_dev2)))); + if (dev2) { + if (in_dev2) in_dev_put(in_dev2); + dev_put(dev2); + if (reply) arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr); + } goto out; } @@ -747,6 +773,21 @@ n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { int dont_send = 0; + if (ipv4_devconf.hidden && + skb->pkt_type != PACKET_HOST) { + struct net_device *dev2 = NULL; + struct in_device *in_dev2 = NULL; + + dont_send |= + ((dev2 = ip_dev_find(tip)) != NULL && + dev2 != dev && + (in_dev2=in_dev_get(dev2)) != NULL && + IN_DEV_HIDDEN(in_dev2)); + if (dev2) { + if (in_dev2) in_dev_put(in_dev2); + dev_put(dev2); + } + } if (IN_DEV_ARPFILTER(in_dev)) dont_send |= arp_filter(sip,tip,dev); if (!dont_send) diff -urN v2.5.67/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c --- v2.5.67/linux/net/ipv4/devinet.c Wed Apr 9 01:21:26 2003 +++ linux/net/ipv4/devinet.c Sat Apr 12 17:20:09 2003 @@ -790,7 +790,8 @@ read_lock(&in_dev->lock); for_primary_ifa(in_dev) { - if (ifa->ifa_scope != RT_SCOPE_LINK && + if (!IN_DEV_HIDDEN(in_dev) && + ifa->ifa_scope != RT_SCOPE_LINK && ifa->ifa_scope <= scope) { read_unlock(&in_dev->lock); addr = ifa->ifa_local; @@ -1123,7 +1124,7 @@ static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[17]; + ctl_table devinet_vars[19]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -1235,9 +1236,25 @@ .proc_handler = &proc_dointvec, }, { + .ctl_name = NET_IPV4_CONF_HIDDEN, + .procname = "hidden", + .data = &ipv4_devconf.hidden, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = NET_IPV4_CONF_ARPFILTER, .procname = "arp_filter", .data = &ipv4_devconf.arp_filter, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_FORWARD_SHARED, + .procname = "forward_shared", + .data = &ipv4_devconf.forward_shared, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec, diff -urN v2.5.67/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c --- v2.5.67/linux/net/ipv4/fib_frontend.c Thu Oct 17 03:43:21 2002 +++ linux/net/ipv4/fib_frontend.c Sat Apr 12 17:17:18 2003 @@ -158,7 +158,8 @@ */ 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 flowi fl = { .nl_u = { .ip4_u = @@ -169,6 +170,7 @@ struct fib_result res; int no_addr, rpf; int ret; + int fwdsh = 0; no_addr = rpf = 0; read_lock(&inetdev_lock); @@ -176,6 +178,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); @@ -184,7 +187,12 @@ if (fib_lookup(&fl, &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); @@ -204,6 +212,8 @@ if (rpf) goto e_inval; fl.oif = dev->ifindex; + if (fwdsh) + fl.iif = loopback_dev.ifindex; ret = 0; if (fib_lookup(&fl, &res) == 0) { diff -urN v2.5.67/linux/net/ipv4/route.c linux/net/ipv4/route.c --- v2.5.67/linux/net/ipv4/route.c Wed Apr 9 01:18:31 2003 +++ linux/net/ipv4/route.c Sat Apr 12 17:17:18 2003 @@ -1357,7 +1357,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); @@ -1522,7 +1522,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) @@ -1549,7 +1549,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; @@ -1637,7 +1637,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)