diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/arp.c | 3 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 5 | ||||
-rw-r--r-- | net/ipv4/route.c | 30 |
3 files changed, 27 insertions, 11 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index cda37be02f8d..2e560f0c757d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -790,7 +790,8 @@ static int arp_process(struct sk_buff *skb) | |||
790 | * Check for bad requests for 127.x.x.x and requests for multicast | 790 | * Check for bad requests for 127.x.x.x and requests for multicast |
791 | * addresses. If this is one such, delete it. | 791 | * addresses. If this is one such, delete it. |
792 | */ | 792 | */ |
793 | if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip)) | 793 | if (ipv4_is_multicast(tip) || |
794 | (!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip))) | ||
794 | goto out; | 795 | goto out; |
795 | 796 | ||
796 | /* | 797 | /* |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 10e15a144e95..44bf82e3aef7 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1500,7 +1500,8 @@ static int devinet_conf_proc(ctl_table *ctl, int write, | |||
1500 | 1500 | ||
1501 | if (cnf == net->ipv4.devconf_dflt) | 1501 | if (cnf == net->ipv4.devconf_dflt) |
1502 | devinet_copy_dflt_conf(net, i); | 1502 | devinet_copy_dflt_conf(net, i); |
1503 | if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1) | 1503 | if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 || |
1504 | i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) | ||
1504 | if ((new_value == 0) && (old_value != 0)) | 1505 | if ((new_value == 0) && (old_value != 0)) |
1505 | rt_cache_flush(net, 0); | 1506 | rt_cache_flush(net, 0); |
1506 | } | 1507 | } |
@@ -1617,6 +1618,8 @@ static struct devinet_sysctl_table { | |||
1617 | "force_igmp_version"), | 1618 | "force_igmp_version"), |
1618 | DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, | 1619 | DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, |
1619 | "promote_secondaries"), | 1620 | "promote_secondaries"), |
1621 | DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET, | ||
1622 | "route_localnet"), | ||
1620 | }, | 1623 | }, |
1621 | }; | 1624 | }; |
1622 | 1625 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 842510d50453..655506af47ca 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1960,9 +1960,13 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1960 | return -EINVAL; | 1960 | return -EINVAL; |
1961 | 1961 | ||
1962 | if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || | 1962 | if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || |
1963 | ipv4_is_loopback(saddr) || skb->protocol != htons(ETH_P_IP)) | 1963 | skb->protocol != htons(ETH_P_IP)) |
1964 | goto e_inval; | 1964 | goto e_inval; |
1965 | 1965 | ||
1966 | if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) | ||
1967 | if (ipv4_is_loopback(saddr)) | ||
1968 | goto e_inval; | ||
1969 | |||
1966 | if (ipv4_is_zeronet(saddr)) { | 1970 | if (ipv4_is_zeronet(saddr)) { |
1967 | if (!ipv4_is_local_multicast(daddr)) | 1971 | if (!ipv4_is_local_multicast(daddr)) |
1968 | goto e_inval; | 1972 | goto e_inval; |
@@ -2203,8 +2207,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2203 | by fib_lookup. | 2207 | by fib_lookup. |
2204 | */ | 2208 | */ |
2205 | 2209 | ||
2206 | if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || | 2210 | if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr)) |
2207 | ipv4_is_loopback(saddr)) | ||
2208 | goto martian_source; | 2211 | goto martian_source; |
2209 | 2212 | ||
2210 | if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0)) | 2213 | if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0)) |
@@ -2216,9 +2219,17 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2216 | if (ipv4_is_zeronet(saddr)) | 2219 | if (ipv4_is_zeronet(saddr)) |
2217 | goto martian_source; | 2220 | goto martian_source; |
2218 | 2221 | ||
2219 | if (ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr)) | 2222 | if (ipv4_is_zeronet(daddr)) |
2220 | goto martian_destination; | 2223 | goto martian_destination; |
2221 | 2224 | ||
2225 | if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) { | ||
2226 | if (ipv4_is_loopback(daddr)) | ||
2227 | goto martian_destination; | ||
2228 | |||
2229 | if (ipv4_is_loopback(saddr)) | ||
2230 | goto martian_source; | ||
2231 | } | ||
2232 | |||
2222 | /* | 2233 | /* |
2223 | * Now we are ready to route packet. | 2234 | * Now we are ready to route packet. |
2224 | */ | 2235 | */ |
@@ -2457,9 +2468,14 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2457 | u16 type = res->type; | 2468 | u16 type = res->type; |
2458 | struct rtable *rth; | 2469 | struct rtable *rth; |
2459 | 2470 | ||
2460 | if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK)) | 2471 | in_dev = __in_dev_get_rcu(dev_out); |
2472 | if (!in_dev) | ||
2461 | return ERR_PTR(-EINVAL); | 2473 | return ERR_PTR(-EINVAL); |
2462 | 2474 | ||
2475 | if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) | ||
2476 | if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK)) | ||
2477 | return ERR_PTR(-EINVAL); | ||
2478 | |||
2463 | if (ipv4_is_lbcast(fl4->daddr)) | 2479 | if (ipv4_is_lbcast(fl4->daddr)) |
2464 | type = RTN_BROADCAST; | 2480 | type = RTN_BROADCAST; |
2465 | else if (ipv4_is_multicast(fl4->daddr)) | 2481 | else if (ipv4_is_multicast(fl4->daddr)) |
@@ -2470,10 +2486,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2470 | if (dev_out->flags & IFF_LOOPBACK) | 2486 | if (dev_out->flags & IFF_LOOPBACK) |
2471 | flags |= RTCF_LOCAL; | 2487 | flags |= RTCF_LOCAL; |
2472 | 2488 | ||
2473 | in_dev = __in_dev_get_rcu(dev_out); | ||
2474 | if (!in_dev) | ||
2475 | return ERR_PTR(-EINVAL); | ||
2476 | |||
2477 | if (type == RTN_BROADCAST) { | 2489 | if (type == RTN_BROADCAST) { |
2478 | flags |= RTCF_BROADCAST | RTCF_LOCAL; | 2490 | flags |= RTCF_BROADCAST | RTCF_LOCAL; |
2479 | fi = NULL; | 2491 | fi = NULL; |