aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-09-17 14:56:21 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:10 -0400
commit881d966b48b035ab3f3aeaae0f3d3f9b584f45b2 (patch)
treec579d59a4107cbbe9e2b85939bc0d496b815c887 /include
parentb4b510290b056b86611757ce1175a230f1080f53 (diff)
[NET]: Make the device list and device lookups per namespace.
This patch makes most of the generic device layer network namespace safe. This patch makes dev_base_head a network namespace variable, and then it picks up a few associated variables. The functions: dev_getbyhwaddr dev_getfirsthwbytype dev_get_by_flags dev_get_by_name __dev_get_by_name dev_get_by_index __dev_get_by_index dev_ioctl dev_ethtool dev_load wireless_process_ioctl were modified to take a network namespace argument, and deal with it. vlan_ioctl_set and brioctl_set were modified so their hooks will receive a network namespace argument. So basically anthing in the core of the network stack that was affected to by the change of dev_base was modified to handle multiple network namespaces. The rest of the network stack was simply modified to explicitly use &init_net the initial network namespace. This can be fixed when those components of the network stack are modified to handle multiple network namespaces. For now the ifindex generator is left global. Fundametally ifindex numbers are per namespace, or else we will have corner case problems with migration when we get that far. At the same time there are assumptions in the network stack that the ifindex of a network device won't change. Making the ifindex number global seems a good compromise until the network stack can cope with ifindex changes when you change namespaces, and the like. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/if_bridge.h2
-rw-r--r--include/linux/if_vlan.h2
-rw-r--r--include/linux/netdevice.h66
-rw-r--r--include/net/net_namespace.h4
-rw-r--r--include/net/pkt_cls.h3
-rw-r--r--include/net/rtnetlink.h2
-rw-r--r--include/net/wext.h15
7 files changed, 55 insertions, 39 deletions
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 4ff211d98769..99e3a1a00099 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -104,7 +104,7 @@ struct __fdb_entry
104 104
105#include <linux/netdevice.h> 105#include <linux/netdevice.h>
106 106
107extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *)); 107extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
108extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p, 108extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
109 struct sk_buff *skb); 109 struct sk_buff *skb);
110extern int (*br_should_route_hook)(struct sk_buff **pskb); 110extern int (*br_should_route_hook)(struct sk_buff **pskb);
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index f8443fdb124a..976d4b1067d1 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -62,7 +62,7 @@ struct vlan_hdr {
62#define VLAN_VID_MASK 0xfff 62#define VLAN_VID_MASK 0xfff
63 63
64/* found in socket.c */ 64/* found in socket.c */
65extern void vlan_ioctl_set(int (*hook)(void __user *)); 65extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
66 66
67#define VLAN_NAME "vlan" 67#define VLAN_NAME "vlan"
68 68
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index dc3c15b726bc..7353b3e1f4fc 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -741,44 +741,48 @@ struct packet_type {
741#include <linux/notifier.h> 741#include <linux/notifier.h>
742 742
743extern struct net_device loopback_dev; /* The loopback */ 743extern struct net_device loopback_dev; /* The loopback */
744extern struct list_head dev_base_head; /* All devices */
745extern rwlock_t dev_base_lock; /* Device list lock */ 744extern rwlock_t dev_base_lock; /* Device list lock */
746 745
747#define for_each_netdev(d) \
748 list_for_each_entry(d, &dev_base_head, dev_list)
749#define for_each_netdev_safe(d, n) \
750 list_for_each_entry_safe(d, n, &dev_base_head, dev_list)
751#define for_each_netdev_continue(d) \
752 list_for_each_entry_continue(d, &dev_base_head, dev_list)
753#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
754
755static inline struct net_device *next_net_device(struct net_device *dev)
756{
757 struct list_head *lh;
758 746
759 lh = dev->dev_list.next; 747#define for_each_netdev(net, d) \
760 return lh == &dev_base_head ? NULL : net_device_entry(lh); 748 list_for_each_entry(d, &(net)->dev_base_head, dev_list)
761} 749#define for_each_netdev_safe(net, d, n) \
750 list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
751#define for_each_netdev_continue(net, d) \
752 list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list)
753#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
762 754
763static inline struct net_device *first_net_device(void) 755#define next_net_device(d) \
764{ 756({ \
765 return list_empty(&dev_base_head) ? NULL : 757 struct net_device *dev = d; \
766 net_device_entry(dev_base_head.next); 758 struct list_head *lh; \
767} 759 struct net *net; \
760 \
761 net = dev->nd_net; \
762 lh = dev->dev_list.next; \
763 lh == &net->dev_base_head ? NULL : net_device_entry(lh); \
764})
765
766#define first_net_device(N) \
767({ \
768 struct net *NET = (N); \
769 list_empty(&NET->dev_base_head) ? NULL : \
770 net_device_entry(NET->dev_base_head.next); \
771})
768 772
769extern int netdev_boot_setup_check(struct net_device *dev); 773extern int netdev_boot_setup_check(struct net_device *dev);
770extern unsigned long netdev_boot_base(const char *prefix, int unit); 774extern unsigned long netdev_boot_base(const char *prefix, int unit);
771extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); 775extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
772extern struct net_device *dev_getfirstbyhwtype(unsigned short type); 776extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
773extern struct net_device *__dev_getfirstbyhwtype(unsigned short type); 777extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
774extern void dev_add_pack(struct packet_type *pt); 778extern void dev_add_pack(struct packet_type *pt);
775extern void dev_remove_pack(struct packet_type *pt); 779extern void dev_remove_pack(struct packet_type *pt);
776extern void __dev_remove_pack(struct packet_type *pt); 780extern void __dev_remove_pack(struct packet_type *pt);
777 781
778extern struct net_device *dev_get_by_flags(unsigned short flags, 782extern struct net_device *dev_get_by_flags(struct net *net, unsigned short flags,
779 unsigned short mask); 783 unsigned short mask);
780extern struct net_device *dev_get_by_name(const char *name); 784extern struct net_device *dev_get_by_name(struct net *net, const char *name);
781extern struct net_device *__dev_get_by_name(const char *name); 785extern struct net_device *__dev_get_by_name(struct net *net, const char *name);
782extern int dev_alloc_name(struct net_device *dev, const char *name); 786extern int dev_alloc_name(struct net_device *dev, const char *name);
783extern int dev_open(struct net_device *dev); 787extern int dev_open(struct net_device *dev);
784extern int dev_close(struct net_device *dev); 788extern int dev_close(struct net_device *dev);
@@ -790,8 +794,8 @@ extern void synchronize_net(void);
790extern int register_netdevice_notifier(struct notifier_block *nb); 794extern int register_netdevice_notifier(struct notifier_block *nb);
791extern int unregister_netdevice_notifier(struct notifier_block *nb); 795extern int unregister_netdevice_notifier(struct notifier_block *nb);
792extern int call_netdevice_notifiers(unsigned long val, void *v); 796extern int call_netdevice_notifiers(unsigned long val, void *v);
793extern struct net_device *dev_get_by_index(int ifindex); 797extern struct net_device *dev_get_by_index(struct net *net, int ifindex);
794extern struct net_device *__dev_get_by_index(int ifindex); 798extern struct net_device *__dev_get_by_index(struct net *net, int ifindex);
795extern int dev_restart(struct net_device *dev); 799extern int dev_restart(struct net_device *dev);
796#ifdef CONFIG_NETPOLL_TRAP 800#ifdef CONFIG_NETPOLL_TRAP
797extern int netpoll_trap(void); 801extern int netpoll_trap(void);
@@ -1007,8 +1011,8 @@ extern int netif_rx_ni(struct sk_buff *skb);
1007#define HAVE_NETIF_RECEIVE_SKB 1 1011#define HAVE_NETIF_RECEIVE_SKB 1
1008extern int netif_receive_skb(struct sk_buff *skb); 1012extern int netif_receive_skb(struct sk_buff *skb);
1009extern int dev_valid_name(const char *name); 1013extern int dev_valid_name(const char *name);
1010extern int dev_ioctl(unsigned int cmd, void __user *); 1014extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
1011extern int dev_ethtool(struct ifreq *); 1015extern int dev_ethtool(struct net *net, struct ifreq *);
1012extern unsigned dev_get_flags(const struct net_device *); 1016extern unsigned dev_get_flags(const struct net_device *);
1013extern int dev_change_flags(struct net_device *, unsigned); 1017extern int dev_change_flags(struct net_device *, unsigned);
1014extern int dev_change_name(struct net_device *, char *); 1018extern int dev_change_name(struct net_device *, char *);
@@ -1327,7 +1331,7 @@ extern void dev_set_allmulti(struct net_device *dev, int inc);
1327extern void netdev_state_change(struct net_device *dev); 1331extern void netdev_state_change(struct net_device *dev);
1328extern void netdev_features_change(struct net_device *dev); 1332extern void netdev_features_change(struct net_device *dev);
1329/* Load a device via the kmod */ 1333/* Load a device via the kmod */
1330extern void dev_load(const char *name); 1334extern void dev_load(struct net *net, const char *name);
1331extern void dev_mcast_init(void); 1335extern void dev_mcast_init(void);
1332extern int netdev_max_backlog; 1336extern int netdev_max_backlog;
1333extern int weight_p; 1337extern int weight_p;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 547247681345..fac42db7f6d0 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -22,6 +22,10 @@ struct net {
22 struct proc_dir_entry *proc_net; 22 struct proc_dir_entry *proc_net;
23 struct proc_dir_entry *proc_net_stat; 23 struct proc_dir_entry *proc_net_stat;
24 struct proc_dir_entry *proc_net_root; 24 struct proc_dir_entry *proc_net_root;
25
26 struct list_head dev_base_head;
27 struct hlist_head *dev_name_head;
28 struct hlist_head *dev_index_head;
25}; 29};
26 30
27extern struct net init_net; 31extern struct net init_net;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 7968b1d66369..f285de69c615 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -2,6 +2,7 @@
2#define __NET_PKT_CLS_H 2#define __NET_PKT_CLS_H
3 3
4#include <linux/pkt_cls.h> 4#include <linux/pkt_cls.h>
5#include <net/net_namespace.h>
5#include <net/sch_generic.h> 6#include <net/sch_generic.h>
6#include <net/act_api.h> 7#include <net/act_api.h>
7 8
@@ -351,7 +352,7 @@ tcf_match_indev(struct sk_buff *skb, char *indev)
351 if (indev[0]) { 352 if (indev[0]) {
352 if (!skb->iif) 353 if (!skb->iif)
353 return 0; 354 return 0;
354 dev = __dev_get_by_index(skb->iif); 355 dev = __dev_get_by_index(&init_net, skb->iif);
355 if (!dev || strcmp(indev, dev->name)) 356 if (!dev || strcmp(indev, dev->name))
356 return 0; 357 return 0;
357 } 358 }
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 8218288ab7ee..793863e09c69 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -78,7 +78,7 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops);
78extern int rtnl_link_register(struct rtnl_link_ops *ops); 78extern int rtnl_link_register(struct rtnl_link_ops *ops);
79extern void rtnl_link_unregister(struct rtnl_link_ops *ops); 79extern void rtnl_link_unregister(struct rtnl_link_ops *ops);
80 80
81extern struct net_device *rtnl_create_link(char *ifname, 81extern struct net_device *rtnl_create_link(struct net *net, char *ifname,
82 const struct rtnl_link_ops *ops, struct nlattr *tb[]); 82 const struct rtnl_link_ops *ops, struct nlattr *tb[]);
83extern const struct nla_policy ifla_policy[IFLA_MAX+1]; 83extern const struct nla_policy ifla_policy[IFLA_MAX+1];
84 84
diff --git a/include/net/wext.h b/include/net/wext.h
index c02b8decf3af..80b31d826b7a 100644
--- a/include/net/wext.h
+++ b/include/net/wext.h
@@ -5,16 +5,23 @@
5 * wireless extensions interface to the core code 5 * wireless extensions interface to the core code
6 */ 6 */
7 7
8struct net;
9
8#ifdef CONFIG_WIRELESS_EXT 10#ifdef CONFIG_WIRELESS_EXT
9extern int wext_proc_init(void); 11extern int wext_proc_init(struct net *net);
10extern int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, 12extern void wext_proc_exit(struct net *net);
13extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
11 void __user *arg); 14 void __user *arg);
12#else 15#else
13static inline int wext_proc_init(void) 16static inline int wext_proc_init(struct net *net)
14{ 17{
15 return 0; 18 return 0;
16} 19}
17static inline int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, 20static inline void wext_proc_exit(struct net *net)
21{
22 return;
23}
24static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
18 void __user *arg) 25 void __user *arg)
19{ 26{
20 return -EINVAL; 27 return -EINVAL;