ipv4 05/05: add sysctl to accept packets with local source addresses

commit 8ec1e0ebe26087bfc5c0394ada5feb5758014fc8
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Dec 3 12:16:35 2009 +0100

    ipv4: add sysctl to accept packets with local source addresses

    Change fib_validate_source() to accept packets with a local source address when
    the "accept_local" sysctl is set for the incoming inet device. Combined with the
    previous patches, this allows to communicate between multiple local interfaces
    over the wire.

    Signed-off-by: Patrick McHardy <kaber@trash.net>

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Patrick McHardy 2009-12-03 01:25:58 +00:00 committed by David S. Miller
parent 5adef18091
commit 8153a10c08
6 changed files with 17 additions and 4 deletions

View file

@ -731,6 +731,12 @@ accept_source_route - BOOLEAN
default TRUE (router) default TRUE (router)
FALSE (host) FALSE (host)
accept_local - BOOLEAN
Accept packets with local source addresses. In combination with
suitable routing, this can be used to direct packets between two
local interfaces over the wire and have them accepted properly.
default FALSE
rp_filter - INTEGER rp_filter - INTEGER
0 - No source validation. 0 - No source validation.
1 - Strict mode as defined in RFC3704 Strict Reverse Path 1 - Strict mode as defined in RFC3704 Strict Reverse Path

View file

@ -83,6 +83,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
#define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER) #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER)
#define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
ACCEPT_SOURCE_ROUTE) ACCEPT_SOURCE_ROUTE)
#define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
#define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY) #define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
#define IN_DEV_LOG_MARTIANS(in_dev) IN_DEV_ORCONF((in_dev), LOG_MARTIANS) #define IN_DEV_LOG_MARTIANS(in_dev) IN_DEV_ORCONF((in_dev), LOG_MARTIANS)

View file

@ -490,6 +490,7 @@ enum
NET_IPV4_CONF_PROMOTE_SECONDARIES=20, NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
NET_IPV4_CONF_ARP_ACCEPT=21, NET_IPV4_CONF_ARP_ACCEPT=21,
NET_IPV4_CONF_ARP_NOTIFY=22, NET_IPV4_CONF_ARP_NOTIFY=22,
NET_IPV4_CONF_ACCEPT_LOCAL=23,
__NET_IPV4_CONF_MAX __NET_IPV4_CONF_MAX
}; };

View file

@ -220,6 +220,7 @@ static const struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
{ NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" }, { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" },
{ NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" }, { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" },
{ NET_IPV4_CONF_ARP_NOTIFY, "arp_notify" }, { NET_IPV4_CONF_ARP_NOTIFY, "arp_notify" },
{ NET_IPV4_CONF_ACCEPT_LOCAL, "accept_local" },
{} {}
}; };

View file

@ -1468,6 +1468,7 @@ static struct devinet_sysctl_table {
DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"), DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
"accept_source_route"), "accept_source_route"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),

View file

@ -241,16 +241,17 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
.iif = oif }; .iif = oif };
struct fib_result res; struct fib_result res;
int no_addr, rpf; int no_addr, rpf, accept_local;
int ret; int ret;
struct net *net; struct net *net;
no_addr = rpf = 0; no_addr = rpf = accept_local = 0;
rcu_read_lock(); rcu_read_lock();
in_dev = __in_dev_get_rcu(dev); in_dev = __in_dev_get_rcu(dev);
if (in_dev) { if (in_dev) {
no_addr = in_dev->ifa_list == NULL; no_addr = in_dev->ifa_list == NULL;
rpf = IN_DEV_RPFILTER(in_dev); rpf = IN_DEV_RPFILTER(in_dev);
accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
} }
rcu_read_unlock(); rcu_read_unlock();
@ -260,8 +261,10 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
net = dev_net(dev); net = dev_net(dev);
if (fib_lookup(net, &fl, &res)) if (fib_lookup(net, &fl, &res))
goto last_resort; goto last_resort;
if (res.type != RTN_UNICAST) if (res.type != RTN_UNICAST) {
goto e_inval_res; if (res.type != RTN_LOCAL || !accept_local)
goto e_inval_res;
}
*spec_dst = FIB_RES_PREFSRC(res); *spec_dst = FIB_RES_PREFSRC(res);
fib_combine_itag(itag, &res); fib_combine_itag(itag, &res);
#ifdef CONFIG_IP_ROUTE_MULTIPATH #ifdef CONFIG_IP_ROUTE_MULTIPATH