aboutsummaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev_mcast.c37
-rw-r--r--net/core/dst.c3
-rw-r--r--net/core/neighbour.c7
-rw-r--r--net/core/netpoll.c6
-rw-r--r--net/core/sock.c21
5 files changed, 31 insertions, 43 deletions
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index cec582563e0..f8a3455f449 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -156,39 +156,14 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from)
EXPORT_SYMBOL(dev_mc_unsync);
#ifdef CONFIG_PROC_FS
-static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(dev_base_lock)
-{
- struct net *net = seq_file_net(seq);
- struct net_device *dev;
- loff_t off = 0;
-
- read_lock(&dev_base_lock);
- for_each_netdev(net, dev) {
- if (off++ == *pos)
- return dev;
- }
- return NULL;
-}
-
-static void *dev_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- ++*pos;
- return next_net_device((struct net_device *)v);
-}
-
-static void dev_mc_seq_stop(struct seq_file *seq, void *v)
- __releases(dev_base_lock)
-{
- read_unlock(&dev_base_lock);
-}
-
-
static int dev_mc_seq_show(struct seq_file *seq, void *v)
{
struct dev_addr_list *m;
struct net_device *dev = v;
+ if (v == SEQ_START_TOKEN)
+ return 0;
+
netif_tx_lock_bh(dev);
for (m = dev->mc_list; m; m = m->next) {
int i;
@@ -206,9 +181,9 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
}
static const struct seq_operations dev_mc_seq_ops = {
- .start = dev_mc_seq_start,
- .next = dev_mc_seq_next,
- .stop = dev_mc_seq_stop,
+ .start = dev_seq_start,
+ .next = dev_seq_next,
+ .stop = dev_seq_stop,
.show = dev_mc_seq_show,
};
diff --git a/net/core/dst.c b/net/core/dst.c
index 7deef483c79..3a01a819ba4 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -295,9 +295,6 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
struct net_device *dev = ptr;
struct dst_entry *dst, *last = NULL;
- if (dev->nd_net != &init_net)
- return NOTIFY_DONE;
-
switch (event) {
case NETDEV_UNREGISTER:
case NETDEV_DOWN:
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d9a02b2cc28..23c0a10c0c3 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1284,9 +1284,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
struct neigh_parms *p;
for (p = &tbl->parms; p; p = p->next) {
- if (p->net != net)
- continue;
- if ((p->dev && p->dev->ifindex == ifindex) ||
+ if ((p->dev && p->dev->ifindex == ifindex && p->net == net) ||
(!p->dev && !ifindex))
return p;
}
@@ -2741,7 +2739,8 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id;
- t->sysctl_header = register_sysctl_paths(neigh_path, t->neigh_vars);
+ t->sysctl_header =
+ register_net_sysctl_table(p->net, neigh_path, t->neigh_vars);
if (!t->sysctl_header)
goto free_procname;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index c635de52526..b04d643fc3c 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -390,9 +390,7 @@ static void arp_reply(struct sk_buff *skb)
if (skb->dev->flags & IFF_NOARP)
return;
- if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
- (2 * skb->dev->addr_len) +
- (2 * sizeof(u32)))))
+ if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
return;
skb_reset_network_header(skb);
@@ -420,7 +418,7 @@ static void arp_reply(struct sk_buff *skb)
ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
return;
- size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
+ size = arp_hdr_len(skb->dev);
send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
LL_RESERVED_SPACE(np->dev));
diff --git a/net/core/sock.c b/net/core/sock.c
index 09cb3a74de7..bb5236aee64 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -981,12 +981,31 @@ void sk_free(struct sock *sk)
if (atomic_read(&sk->sk_omem_alloc))
printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n",
- __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
+ __func__, atomic_read(&sk->sk_omem_alloc));
put_net(sk->sk_net);
sk_prot_free(sk->sk_prot_creator, sk);
}
+/*
+ * Last sock_put should drop referrence to sk->sk_net. It has already
+ * been dropped in sk_change_net. Taking referrence to stopping namespace
+ * is not an option.
+ * Take referrence to a socket to remove it from hash _alive_ and after that
+ * destroy it in the context of init_net.
+ */
+void sk_release_kernel(struct sock *sk)
+{
+ if (sk == NULL || sk->sk_socket == NULL)
+ return;
+
+ sock_hold(sk);
+ sock_release(sk->sk_socket);
+ sk->sk_net = get_net(&init_net);
+ sock_put(sk);
+}
+EXPORT_SYMBOL(sk_release_kernel);
+
struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
{
struct sock *newsk;