diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev_mcast.c | 37 | ||||
-rw-r--r-- | net/core/dst.c | 3 | ||||
-rw-r--r-- | net/core/neighbour.c | 7 | ||||
-rw-r--r-- | net/core/netpoll.c | 6 | ||||
-rw-r--r-- | net/core/sock.c | 21 |
5 files changed, 31 insertions, 43 deletions
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index cec582563e0d..f8a3455f4493 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 7deef483c79f..3a01a819ba47 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 d9a02b2cc289..23c0a10c0c37 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 4b7e756181c9..d0c8bf585f06 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -388,9 +388,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); @@ -418,7 +416,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 09cb3a74de7f..bb5236aee643 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; |