static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
#define icmp_socket __get_cpu_var(__icmp_socket)
-static __inline__ int icmp_xmit_lock(void)
+static inline int icmp_xmit_lock(void)
{
local_bh_disable();
return 0;
}
-static void icmp_xmit_unlock(void)
+static inline void icmp_xmit_unlock(void)
{
spin_unlock_bh(&icmp_socket->sk->sk_lock.slock);
}
#define XRLIM_BURST_FACTOR 6
int xrlim_allow(struct dst_entry *dst, int timeout)
{
- unsigned long now;
+ unsigned long now, token = dst->rate_tokens;
int rc = 0;
now = jiffies;
- dst->rate_tokens += now - dst->rate_last;
+ token += now - dst->rate_last;
dst->rate_last = now;
- if (dst->rate_tokens > XRLIM_BURST_FACTOR * timeout)
- dst->rate_tokens = XRLIM_BURST_FACTOR * timeout;
- if (dst->rate_tokens >= timeout) {
- dst->rate_tokens -= timeout;
+ if (token > XRLIM_BURST_FACTOR * timeout)
+ token = XRLIM_BURST_FACTOR * timeout;
+ if (token >= timeout) {
+ token -= timeout;
rc = 1;
}
+ dst->rate_tokens = token;
return rc;
}
.tos = RT_TOS(ip_hdr(skb)->tos) } },
.proto = IPPROTO_ICMP };
security_skb_classify_flow(skb, &fl);
- if (ip_route_output_key(&rt, &fl))
+ if (ip_route_output_key(rt->u.dst.dev->nd_net, &rt, &fl))
goto out_unlock;
}
if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type,
struct ipcm_cookie ipc;
__be32 saddr;
u8 tos;
+ struct net *net;
if (!rt)
goto out;
+ net = rt->u.dst.dev->nd_net;
/*
* Find the original header. It is expected to be valid, of course.
struct net_device *dev = NULL;
if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
- dev = dev_get_by_index(&init_net, rt->fl.iif);
+ dev = dev_get_by_index(net, rt->fl.iif);
if (dev) {
saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
struct rtable *rt2;
security_skb_classify_flow(skb_in, &fl);
- if (__ip_route_output_key(&rt, &fl))
+ if (__ip_route_output_key(net, &rt, &fl))
goto out_unlock;
/* No need to clone since we're just using its address. */
if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
goto out_unlock;
- if (inet_addr_type(fl.fl4_src) == RTN_LOCAL)
- err = __ip_route_output_key(&rt2, &fl);
+ if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL)
+ err = __ip_route_output_key(net, &rt2, &fl);
else {
struct flowi fl2 = {};
struct dst_entry *odst;
fl2.fl4_dst = fl.fl4_src;
- if (ip_route_output_key(&rt2, &fl2))
+ if (ip_route_output_key(net, &rt2, &fl2))
goto out_unlock;
/* Ugh! */
int hash, protocol;
struct net_protocol *ipprot;
u32 info = 0;
+ struct net *net;
+
+ net = skb->dst->dev->nd_net;
/*
* Incomplete header ?
"and DF set.\n",
NIPQUAD(iph->daddr));
} else {
- info = ip_rt_frag_needed(iph,
+ info = ip_rt_frag_needed(net, iph,
ntohs(icmph->un.frag.mtu));
if (!info)
goto out;
*/
if (!sysctl_icmp_ignore_bogus_error_responses &&
- inet_addr_type(iph->daddr) == RTN_BROADCAST) {
+ inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
if (net_ratelimit())
printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
"type %u, code %u "
goto error;
}
- __skb_pull(skb, sizeof(*icmph));
+ if (!pskb_pull(skb, sizeof(*icmph)))
+ goto error;
icmph = icmp_hdr(skb);