diff options
author | David S. Miller <davem@davemloft.net> | 2011-06-21 01:29:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-21 01:29:08 -0400 |
commit | 9f6ec8d697c08963d83880ccd35c13c5ace716ea (patch) | |
tree | ad8d93cf6fcdd09b86ade09f5fcbbc66cdb1cca2 /net/core | |
parent | 4aa3a715551c93eda32d79bd52042ce500bd5383 (diff) | |
parent | 56299378726d5f2ba8d3c8cbbd13cb280ba45e4f (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/rtlwifi/pci.c
net/netfilter/ipvs/ip_vs_core.c
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 23 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 23 | ||||
-rw-r--r-- | net/core/net_namespace.c | 28 | ||||
-rw-r--r-- | net/core/netpoll.c | 7 |
4 files changed, 44 insertions, 37 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index b3f52d2f56d7..8efe85070131 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3114,7 +3114,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3114 | 3114 | ||
3115 | skb_reset_network_header(skb); | 3115 | skb_reset_network_header(skb); |
3116 | skb_reset_transport_header(skb); | 3116 | skb_reset_transport_header(skb); |
3117 | skb->mac_len = skb->network_header - skb->mac_header; | 3117 | skb_reset_mac_len(skb); |
3118 | 3118 | ||
3119 | pt_prev = NULL; | 3119 | pt_prev = NULL; |
3120 | 3120 | ||
@@ -6173,6 +6173,11 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
6173 | oldsd->output_queue = NULL; | 6173 | oldsd->output_queue = NULL; |
6174 | oldsd->output_queue_tailp = &oldsd->output_queue; | 6174 | oldsd->output_queue_tailp = &oldsd->output_queue; |
6175 | } | 6175 | } |
6176 | /* Append NAPI poll list from offline CPU. */ | ||
6177 | if (!list_empty(&oldsd->poll_list)) { | ||
6178 | list_splice_init(&oldsd->poll_list, &sd->poll_list); | ||
6179 | raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
6180 | } | ||
6176 | 6181 | ||
6177 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 6182 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
6178 | local_irq_enable(); | 6183 | local_irq_enable(); |
@@ -6259,29 +6264,23 @@ err_name: | |||
6259 | /** | 6264 | /** |
6260 | * netdev_drivername - network driver for the device | 6265 | * netdev_drivername - network driver for the device |
6261 | * @dev: network device | 6266 | * @dev: network device |
6262 | * @buffer: buffer for resulting name | ||
6263 | * @len: size of buffer | ||
6264 | * | 6267 | * |
6265 | * Determine network driver for device. | 6268 | * Determine network driver for device. |
6266 | */ | 6269 | */ |
6267 | char *netdev_drivername(const struct net_device *dev, char *buffer, int len) | 6270 | const char *netdev_drivername(const struct net_device *dev) |
6268 | { | 6271 | { |
6269 | const struct device_driver *driver; | 6272 | const struct device_driver *driver; |
6270 | const struct device *parent; | 6273 | const struct device *parent; |
6271 | 6274 | const char *empty = ""; | |
6272 | if (len <= 0 || !buffer) | ||
6273 | return buffer; | ||
6274 | buffer[0] = 0; | ||
6275 | 6275 | ||
6276 | parent = dev->dev.parent; | 6276 | parent = dev->dev.parent; |
6277 | |||
6278 | if (!parent) | 6277 | if (!parent) |
6279 | return buffer; | 6278 | return empty; |
6280 | 6279 | ||
6281 | driver = parent->driver; | 6280 | driver = parent->driver; |
6282 | if (driver && driver->name) | 6281 | if (driver && driver->name) |
6283 | strlcpy(buffer, driver->name, len); | 6282 | return driver->name; |
6284 | return buffer; | 6283 | return empty; |
6285 | } | 6284 | } |
6286 | 6285 | ||
6287 | static int __netdev_printk(const char *level, const struct net_device *dev, | 6286 | static int __netdev_printk(const char *level, const struct net_device *dev, |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 11b98bc2aa8f..33d2a1fba131 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -1179,9 +1179,14 @@ static void remove_queue_kobjects(struct net_device *net) | |||
1179 | #endif | 1179 | #endif |
1180 | } | 1180 | } |
1181 | 1181 | ||
1182 | static const void *net_current_ns(void) | 1182 | static void *net_grab_current_ns(void) |
1183 | { | 1183 | { |
1184 | return current->nsproxy->net_ns; | 1184 | struct net *ns = current->nsproxy->net_ns; |
1185 | #ifdef CONFIG_NET_NS | ||
1186 | if (ns) | ||
1187 | atomic_inc(&ns->passive); | ||
1188 | #endif | ||
1189 | return ns; | ||
1185 | } | 1190 | } |
1186 | 1191 | ||
1187 | static const void *net_initial_ns(void) | 1192 | static const void *net_initial_ns(void) |
@@ -1196,22 +1201,13 @@ static const void *net_netlink_ns(struct sock *sk) | |||
1196 | 1201 | ||
1197 | struct kobj_ns_type_operations net_ns_type_operations = { | 1202 | struct kobj_ns_type_operations net_ns_type_operations = { |
1198 | .type = KOBJ_NS_TYPE_NET, | 1203 | .type = KOBJ_NS_TYPE_NET, |
1199 | .current_ns = net_current_ns, | 1204 | .grab_current_ns = net_grab_current_ns, |
1200 | .netlink_ns = net_netlink_ns, | 1205 | .netlink_ns = net_netlink_ns, |
1201 | .initial_ns = net_initial_ns, | 1206 | .initial_ns = net_initial_ns, |
1207 | .drop_ns = net_drop_ns, | ||
1202 | }; | 1208 | }; |
1203 | EXPORT_SYMBOL_GPL(net_ns_type_operations); | 1209 | EXPORT_SYMBOL_GPL(net_ns_type_operations); |
1204 | 1210 | ||
1205 | static void net_kobj_ns_exit(struct net *net) | ||
1206 | { | ||
1207 | kobj_ns_exit(KOBJ_NS_TYPE_NET, net); | ||
1208 | } | ||
1209 | |||
1210 | static struct pernet_operations kobj_net_ops = { | ||
1211 | .exit = net_kobj_ns_exit, | ||
1212 | }; | ||
1213 | |||
1214 | |||
1215 | #ifdef CONFIG_HOTPLUG | 1211 | #ifdef CONFIG_HOTPLUG |
1216 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) | 1212 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) |
1217 | { | 1213 | { |
@@ -1339,6 +1335,5 @@ EXPORT_SYMBOL(netdev_class_remove_file); | |||
1339 | int netdev_kobject_init(void) | 1335 | int netdev_kobject_init(void) |
1340 | { | 1336 | { |
1341 | kobj_ns_type_register(&net_ns_type_operations); | 1337 | kobj_ns_type_register(&net_ns_type_operations); |
1342 | register_pernet_subsys(&kobj_net_ops); | ||
1343 | return class_register(&net_class); | 1338 | return class_register(&net_class); |
1344 | } | 1339 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 6c6b86d0da15..ea489db1bc23 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -128,6 +128,7 @@ static __net_init int setup_net(struct net *net) | |||
128 | LIST_HEAD(net_exit_list); | 128 | LIST_HEAD(net_exit_list); |
129 | 129 | ||
130 | atomic_set(&net->count, 1); | 130 | atomic_set(&net->count, 1); |
131 | atomic_set(&net->passive, 1); | ||
131 | 132 | ||
132 | #ifdef NETNS_REFCNT_DEBUG | 133 | #ifdef NETNS_REFCNT_DEBUG |
133 | atomic_set(&net->use_count, 0); | 134 | atomic_set(&net->use_count, 0); |
@@ -210,6 +211,13 @@ static void net_free(struct net *net) | |||
210 | kmem_cache_free(net_cachep, net); | 211 | kmem_cache_free(net_cachep, net); |
211 | } | 212 | } |
212 | 213 | ||
214 | void net_drop_ns(void *p) | ||
215 | { | ||
216 | struct net *ns = p; | ||
217 | if (ns && atomic_dec_and_test(&ns->passive)) | ||
218 | net_free(ns); | ||
219 | } | ||
220 | |||
213 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 221 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) |
214 | { | 222 | { |
215 | struct net *net; | 223 | struct net *net; |
@@ -230,7 +238,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
230 | } | 238 | } |
231 | mutex_unlock(&net_mutex); | 239 | mutex_unlock(&net_mutex); |
232 | if (rv < 0) { | 240 | if (rv < 0) { |
233 | net_free(net); | 241 | net_drop_ns(net); |
234 | return ERR_PTR(rv); | 242 | return ERR_PTR(rv); |
235 | } | 243 | } |
236 | return net; | 244 | return net; |
@@ -286,7 +294,7 @@ static void cleanup_net(struct work_struct *work) | |||
286 | /* Finally it is safe to free my network namespace structure */ | 294 | /* Finally it is safe to free my network namespace structure */ |
287 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 295 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
288 | list_del_init(&net->exit_list); | 296 | list_del_init(&net->exit_list); |
289 | net_free(net); | 297 | net_drop_ns(net); |
290 | } | 298 | } |
291 | } | 299 | } |
292 | static DECLARE_WORK(net_cleanup_work, cleanup_net); | 300 | static DECLARE_WORK(net_cleanup_work, cleanup_net); |
@@ -310,19 +318,17 @@ struct net *get_net_ns_by_fd(int fd) | |||
310 | struct file *file; | 318 | struct file *file; |
311 | struct net *net; | 319 | struct net *net; |
312 | 320 | ||
313 | net = ERR_PTR(-EINVAL); | ||
314 | file = proc_ns_fget(fd); | 321 | file = proc_ns_fget(fd); |
315 | if (!file) | 322 | if (IS_ERR(file)) |
316 | goto out; | 323 | return ERR_CAST(file); |
317 | 324 | ||
318 | ei = PROC_I(file->f_dentry->d_inode); | 325 | ei = PROC_I(file->f_dentry->d_inode); |
319 | if (ei->ns_ops != &netns_operations) | 326 | if (ei->ns_ops == &netns_operations) |
320 | goto out; | 327 | net = get_net(ei->ns); |
328 | else | ||
329 | net = ERR_PTR(-EINVAL); | ||
321 | 330 | ||
322 | net = get_net(ei->ns); | 331 | fput(file); |
323 | out: | ||
324 | if (file) | ||
325 | fput(file); | ||
326 | return net; | 332 | return net; |
327 | } | 333 | } |
328 | 334 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 2d7d6d473781..18d9cbda3a39 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -792,6 +792,13 @@ int netpoll_setup(struct netpoll *np) | |||
792 | return -ENODEV; | 792 | return -ENODEV; |
793 | } | 793 | } |
794 | 794 | ||
795 | if (ndev->master) { | ||
796 | printk(KERN_ERR "%s: %s is a slave device, aborting.\n", | ||
797 | np->name, np->dev_name); | ||
798 | err = -EBUSY; | ||
799 | goto put; | ||
800 | } | ||
801 | |||
795 | if (!netif_running(ndev)) { | 802 | if (!netif_running(ndev)) { |
796 | unsigned long atmost, atleast; | 803 | unsigned long atmost, atleast; |
797 | 804 | ||