--- v2.4.19pre6/linux/include/linux/inetdevice.h Mon Apr 8 22:06:08 2002 +++ linux/include/linux/inetdevice.h Sat Jun 15 17:23:04 2002 @@ -19,6 +19,7 @@ int tag; int arp_filter; int medium_id; + int rp_filter_mask; void *sysctl; }; @@ -50,6 +51,7 @@ #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) +#define IN_DEV_RPFILTER_MASK(in_dev) ((in_dev)->cnf.rp_filter_mask) #define IN_DEV_RX_REDIRECTS(in_dev) \ ((IN_DEV_FORWARD(in_dev) && \ --- v2.4.19pre6/linux/include/linux/sysctl.h Mon Apr 8 22:06:08 2002 +++ linux/include/linux/sysctl.h Sat Jun 15 22:02:31 2002 @@ -338,6 +338,7 @@ NET_IPV4_CONF_TAG=12, NET_IPV4_CONF_ARPFILTER=13, NET_IPV4_CONF_MEDIUM_ID=14, + NET_IPV4_CONF_RP_FILTER_MASK=15, }; /* /proc/sys/net/ipv6 */ --- v2.4.19pre6/linux/net/ipv4/devinet.c Mon Apr 8 22:06:09 2002 +++ linux/net/ipv4/devinet.c Sat Jun 15 17:26:46 2002 @@ -1032,7 +1032,7 @@ static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[15]; + ctl_table devinet_vars[16]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -1068,6 +1068,9 @@ &proc_dointvec}, {NET_IPV4_CONF_MEDIUM_ID, "medium_id", &ipv4_devconf.medium_id, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_CONF_RP_FILTER_MASK, "rp_filter_mask", + &ipv4_devconf.rp_filter_mask, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay", &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL, --- v2.4.19pre6/linux/net/ipv4/fib_frontend.c Mon Apr 8 22:06:09 2002 +++ linux/net/ipv4/fib_frontend.c Sat Jun 15 19:10:54 2002 @@ -210,6 +210,7 @@ struct rt_key key; struct fib_result res; int no_addr, rpf; + unsigned rpf_mask = 0; int ret; key.dst = src; @@ -225,6 +226,7 @@ if (in_dev) { no_addr = in_dev->ifa_list == NULL; rpf = IN_DEV_RPFILTER(in_dev); + rpf_mask = IN_DEV_RPFILTER_MASK(in_dev); } read_unlock(&inetdev_lock); @@ -246,6 +248,17 @@ ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; fib_res_put(&res); return ret; + } + if (rpf_mask && rpf) { + int omi = 0; + + read_lock(&inetdev_lock); + in_dev = __in_dev_get(FIB_RES_DEV(res)); + if (in_dev) + omi = IN_DEV_MEDIUM_ID(in_dev); + read_unlock(&inetdev_lock); + if (omi >= 1 && omi <= 31 && ((1 << omi) & rpf_mask)) + rpf = 0; } fib_res_put(&res); if (no_addr) --- v2.4.19pre6/linux/Documentation/filesystems/proc.txt Mon Nov 26 23:05:49 2001 +++ linux/Documentation/filesystems/proc.txt Sat Jun 15 18:59:42 2002 @@ -1566,6 +1566,16 @@ (external addresses can still be spoofed), without the need for additional firewall rules. +rp_filter_mask +-------------- + +Integer value representing bitmask of the mediums for which the reverse path +protection is disabled. If the source validation results in reverse path +to interface with medium_id value in the 1..31 range the access is +allowed if the corresponding bit is set in the bitmask. The bitmask value +is considered only when rp_filter is enabled. By default the bitmask is +empty preserving the original rp_filter semantic. + secure_redirects ---------------- --- v2.4.19pre6/linux/Documentation/networking/ip-sysctl.txt Mon Apr 8 22:05:03 2002 +++ linux/Documentation/networking/ip-sysctl.txt Sat Jun 15 19:03:39 2002 @@ -413,6 +413,16 @@ Default value is 0. Note that some distributions enable it in startip scripts. +rp_filter_mask - INTEGER + + Integer value representing bitmask of the mediums for which the + reverse path protection is disabled. If the source validation + results in reverse path to interface with medium_id value in + the 1..31 range the access is allowed if the corresponding bit + is set in the bitmask. The bitmask value is considered only when + rp_filter is enabled. By default the bitmask is empty preserving + the original rp_filter semantic. + Alexey Kuznetsov. kuznet@ms2.inr.ac.ru