diff options
author | Thomas Graf <tgraf@suug.ch> | 2015-07-21 04:44:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-21 13:39:07 -0400 |
commit | be4ace6e6b1bc12e18b25fe764917e09a1f96d7b (patch) | |
tree | 6b4ae588041d0245a5f1b2fe47118db445c3886f /net/openvswitch | |
parent | 34ae932a40369be6bd6ea97d66b6686361b4370d (diff) |
openvswitch: Move dev pointer into vport itself
This is the first step in representing all OVS vports as regular
struct net_devices. Move the net_device pointer into the vport
structure itself to get rid of struct vport_netdev.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/datapath.c | 7 | ||||
-rw-r--r-- | net/openvswitch/dp_notify.c | 5 | ||||
-rw-r--r-- | net/openvswitch/vport-internal_dev.c | 37 | ||||
-rw-r--r-- | net/openvswitch/vport-netdev.c | 86 | ||||
-rw-r--r-- | net/openvswitch/vport-netdev.h | 12 | ||||
-rw-r--r-- | net/openvswitch/vport.h | 3 |
6 files changed, 59 insertions, 91 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 02082107c74c..19df28ee5094 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -188,7 +188,7 @@ static int get_dpifindex(const struct datapath *dp) | |||
188 | 188 | ||
189 | local = ovs_vport_rcu(dp, OVSP_LOCAL); | 189 | local = ovs_vport_rcu(dp, OVSP_LOCAL); |
190 | if (local) | 190 | if (local) |
191 | ifindex = netdev_vport_priv(local)->dev->ifindex; | 191 | ifindex = local->dev->ifindex; |
192 | else | 192 | else |
193 | ifindex = 0; | 193 | ifindex = 0; |
194 | 194 | ||
@@ -2219,13 +2219,10 @@ static void __net_exit list_vports_from_net(struct net *net, struct net *dnet, | |||
2219 | struct vport *vport; | 2219 | struct vport *vport; |
2220 | 2220 | ||
2221 | hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) { | 2221 | hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) { |
2222 | struct netdev_vport *netdev_vport; | ||
2223 | |||
2224 | if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL) | 2222 | if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL) |
2225 | continue; | 2223 | continue; |
2226 | 2224 | ||
2227 | netdev_vport = netdev_vport_priv(vport); | 2225 | if (dev_net(vport->dev) == dnet) |
2228 | if (dev_net(netdev_vport->dev) == dnet) | ||
2229 | list_add(&vport->detach_list, head); | 2226 | list_add(&vport->detach_list, head); |
2230 | } | 2227 | } |
2231 | } | 2228 | } |
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c index 2c631fe76be1..a7a80a6b77b0 100644 --- a/net/openvswitch/dp_notify.c +++ b/net/openvswitch/dp_notify.c | |||
@@ -58,13 +58,10 @@ void ovs_dp_notify_wq(struct work_struct *work) | |||
58 | struct hlist_node *n; | 58 | struct hlist_node *n; |
59 | 59 | ||
60 | hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) { | 60 | hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) { |
61 | struct netdev_vport *netdev_vport; | ||
62 | |||
63 | if (vport->ops->type != OVS_VPORT_TYPE_NETDEV) | 61 | if (vport->ops->type != OVS_VPORT_TYPE_NETDEV) |
64 | continue; | 62 | continue; |
65 | 63 | ||
66 | netdev_vport = netdev_vport_priv(vport); | 64 | if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH)) |
67 | if (!(netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH)) | ||
68 | dp_detach_port_notify(vport); | 65 | dp_detach_port_notify(vport); |
69 | } | 66 | } |
70 | } | 67 | } |
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 6a55f7105505..a2c205d9a8d5 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c | |||
@@ -156,49 +156,44 @@ static void do_setup(struct net_device *netdev) | |||
156 | static struct vport *internal_dev_create(const struct vport_parms *parms) | 156 | static struct vport *internal_dev_create(const struct vport_parms *parms) |
157 | { | 157 | { |
158 | struct vport *vport; | 158 | struct vport *vport; |
159 | struct netdev_vport *netdev_vport; | ||
160 | struct internal_dev *internal_dev; | 159 | struct internal_dev *internal_dev; |
161 | int err; | 160 | int err; |
162 | 161 | ||
163 | vport = ovs_vport_alloc(sizeof(struct netdev_vport), | 162 | vport = ovs_vport_alloc(0, &ovs_internal_vport_ops, parms); |
164 | &ovs_internal_vport_ops, parms); | ||
165 | if (IS_ERR(vport)) { | 163 | if (IS_ERR(vport)) { |
166 | err = PTR_ERR(vport); | 164 | err = PTR_ERR(vport); |
167 | goto error; | 165 | goto error; |
168 | } | 166 | } |
169 | 167 | ||
170 | netdev_vport = netdev_vport_priv(vport); | 168 | vport->dev = alloc_netdev(sizeof(struct internal_dev), |
171 | 169 | parms->name, NET_NAME_UNKNOWN, do_setup); | |
172 | netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), | 170 | if (!vport->dev) { |
173 | parms->name, NET_NAME_UNKNOWN, | ||
174 | do_setup); | ||
175 | if (!netdev_vport->dev) { | ||
176 | err = -ENOMEM; | 171 | err = -ENOMEM; |
177 | goto error_free_vport; | 172 | goto error_free_vport; |
178 | } | 173 | } |
179 | 174 | ||
180 | dev_net_set(netdev_vport->dev, ovs_dp_get_net(vport->dp)); | 175 | dev_net_set(vport->dev, ovs_dp_get_net(vport->dp)); |
181 | internal_dev = internal_dev_priv(netdev_vport->dev); | 176 | internal_dev = internal_dev_priv(vport->dev); |
182 | internal_dev->vport = vport; | 177 | internal_dev->vport = vport; |
183 | 178 | ||
184 | /* Restrict bridge port to current netns. */ | 179 | /* Restrict bridge port to current netns. */ |
185 | if (vport->port_no == OVSP_LOCAL) | 180 | if (vport->port_no == OVSP_LOCAL) |
186 | netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL; | 181 | vport->dev->features |= NETIF_F_NETNS_LOCAL; |
187 | 182 | ||
188 | rtnl_lock(); | 183 | rtnl_lock(); |
189 | err = register_netdevice(netdev_vport->dev); | 184 | err = register_netdevice(vport->dev); |
190 | if (err) | 185 | if (err) |
191 | goto error_free_netdev; | 186 | goto error_free_netdev; |
192 | 187 | ||
193 | dev_set_promiscuity(netdev_vport->dev, 1); | 188 | dev_set_promiscuity(vport->dev, 1); |
194 | rtnl_unlock(); | 189 | rtnl_unlock(); |
195 | netif_start_queue(netdev_vport->dev); | 190 | netif_start_queue(vport->dev); |
196 | 191 | ||
197 | return vport; | 192 | return vport; |
198 | 193 | ||
199 | error_free_netdev: | 194 | error_free_netdev: |
200 | rtnl_unlock(); | 195 | rtnl_unlock(); |
201 | free_netdev(netdev_vport->dev); | 196 | free_netdev(vport->dev); |
202 | error_free_vport: | 197 | error_free_vport: |
203 | ovs_vport_free(vport); | 198 | ovs_vport_free(vport); |
204 | error: | 199 | error: |
@@ -207,21 +202,19 @@ error: | |||
207 | 202 | ||
208 | static void internal_dev_destroy(struct vport *vport) | 203 | static void internal_dev_destroy(struct vport *vport) |
209 | { | 204 | { |
210 | struct netdev_vport *netdev_vport = netdev_vport_priv(vport); | 205 | netif_stop_queue(vport->dev); |
211 | |||
212 | netif_stop_queue(netdev_vport->dev); | ||
213 | rtnl_lock(); | 206 | rtnl_lock(); |
214 | dev_set_promiscuity(netdev_vport->dev, -1); | 207 | dev_set_promiscuity(vport->dev, -1); |
215 | 208 | ||
216 | /* unregister_netdevice() waits for an RCU grace period. */ | 209 | /* unregister_netdevice() waits for an RCU grace period. */ |
217 | unregister_netdevice(netdev_vport->dev); | 210 | unregister_netdevice(vport->dev); |
218 | 211 | ||
219 | rtnl_unlock(); | 212 | rtnl_unlock(); |
220 | } | 213 | } |
221 | 214 | ||
222 | static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) | 215 | static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) |
223 | { | 216 | { |
224 | struct net_device *netdev = netdev_vport_priv(vport)->dev; | 217 | struct net_device *netdev = vport->dev; |
225 | int len; | 218 | int len; |
226 | 219 | ||
227 | if (unlikely(!(netdev->flags & IFF_UP))) { | 220 | if (unlikely(!(netdev->flags & IFF_UP))) { |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 33e6d6e2908f..1c9696693f66 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -83,104 +83,97 @@ static struct net_device *get_dpdev(const struct datapath *dp) | |||
83 | 83 | ||
84 | local = ovs_vport_ovsl(dp, OVSP_LOCAL); | 84 | local = ovs_vport_ovsl(dp, OVSP_LOCAL); |
85 | BUG_ON(!local); | 85 | BUG_ON(!local); |
86 | return netdev_vport_priv(local)->dev; | 86 | return local->dev; |
87 | } | 87 | } |
88 | 88 | ||
89 | static struct vport *netdev_create(const struct vport_parms *parms) | 89 | static struct vport *netdev_link(struct vport *vport, const char *name) |
90 | { | 90 | { |
91 | struct vport *vport; | ||
92 | struct netdev_vport *netdev_vport; | ||
93 | int err; | 91 | int err; |
94 | 92 | ||
95 | vport = ovs_vport_alloc(sizeof(struct netdev_vport), | 93 | vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), name); |
96 | &ovs_netdev_vport_ops, parms); | 94 | if (!vport->dev) { |
97 | if (IS_ERR(vport)) { | ||
98 | err = PTR_ERR(vport); | ||
99 | goto error; | ||
100 | } | ||
101 | |||
102 | netdev_vport = netdev_vport_priv(vport); | ||
103 | |||
104 | netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name); | ||
105 | if (!netdev_vport->dev) { | ||
106 | err = -ENODEV; | 95 | err = -ENODEV; |
107 | goto error_free_vport; | 96 | goto error_free_vport; |
108 | } | 97 | } |
109 | 98 | ||
110 | if (netdev_vport->dev->flags & IFF_LOOPBACK || | 99 | if (vport->dev->flags & IFF_LOOPBACK || |
111 | netdev_vport->dev->type != ARPHRD_ETHER || | 100 | vport->dev->type != ARPHRD_ETHER || |
112 | ovs_is_internal_dev(netdev_vport->dev)) { | 101 | ovs_is_internal_dev(vport->dev)) { |
113 | err = -EINVAL; | 102 | err = -EINVAL; |
114 | goto error_put; | 103 | goto error_put; |
115 | } | 104 | } |
116 | 105 | ||
117 | rtnl_lock(); | 106 | rtnl_lock(); |
118 | err = netdev_master_upper_dev_link(netdev_vport->dev, | 107 | err = netdev_master_upper_dev_link(vport->dev, |
119 | get_dpdev(vport->dp)); | 108 | get_dpdev(vport->dp)); |
120 | if (err) | 109 | if (err) |
121 | goto error_unlock; | 110 | goto error_unlock; |
122 | 111 | ||
123 | err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, | 112 | err = netdev_rx_handler_register(vport->dev, netdev_frame_hook, |
124 | vport); | 113 | vport); |
125 | if (err) | 114 | if (err) |
126 | goto error_master_upper_dev_unlink; | 115 | goto error_master_upper_dev_unlink; |
127 | 116 | ||
128 | dev_disable_lro(netdev_vport->dev); | 117 | dev_disable_lro(vport->dev); |
129 | dev_set_promiscuity(netdev_vport->dev, 1); | 118 | dev_set_promiscuity(vport->dev, 1); |
130 | netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; | 119 | vport->dev->priv_flags |= IFF_OVS_DATAPATH; |
131 | rtnl_unlock(); | 120 | rtnl_unlock(); |
132 | 121 | ||
133 | return vport; | 122 | return vport; |
134 | 123 | ||
135 | error_master_upper_dev_unlink: | 124 | error_master_upper_dev_unlink: |
136 | netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp)); | 125 | netdev_upper_dev_unlink(vport->dev, get_dpdev(vport->dp)); |
137 | error_unlock: | 126 | error_unlock: |
138 | rtnl_unlock(); | 127 | rtnl_unlock(); |
139 | error_put: | 128 | error_put: |
140 | dev_put(netdev_vport->dev); | 129 | dev_put(vport->dev); |
141 | error_free_vport: | 130 | error_free_vport: |
142 | ovs_vport_free(vport); | 131 | ovs_vport_free(vport); |
143 | error: | ||
144 | return ERR_PTR(err); | 132 | return ERR_PTR(err); |
145 | } | 133 | } |
146 | 134 | ||
135 | static struct vport *netdev_create(const struct vport_parms *parms) | ||
136 | { | ||
137 | struct vport *vport; | ||
138 | |||
139 | vport = ovs_vport_alloc(0, &ovs_netdev_vport_ops, parms); | ||
140 | if (IS_ERR(vport)) | ||
141 | return vport; | ||
142 | |||
143 | return netdev_link(vport, parms->name); | ||
144 | } | ||
145 | |||
147 | static void free_port_rcu(struct rcu_head *rcu) | 146 | static void free_port_rcu(struct rcu_head *rcu) |
148 | { | 147 | { |
149 | struct netdev_vport *netdev_vport = container_of(rcu, | 148 | struct vport *vport = container_of(rcu, struct vport, rcu); |
150 | struct netdev_vport, rcu); | ||
151 | 149 | ||
152 | dev_put(netdev_vport->dev); | 150 | dev_put(vport->dev); |
153 | ovs_vport_free(vport_from_priv(netdev_vport)); | 151 | ovs_vport_free(vport); |
154 | } | 152 | } |
155 | 153 | ||
156 | void ovs_netdev_detach_dev(struct vport *vport) | 154 | void ovs_netdev_detach_dev(struct vport *vport) |
157 | { | 155 | { |
158 | struct netdev_vport *netdev_vport = netdev_vport_priv(vport); | ||
159 | |||
160 | ASSERT_RTNL(); | 156 | ASSERT_RTNL(); |
161 | netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH; | 157 | vport->dev->priv_flags &= ~IFF_OVS_DATAPATH; |
162 | netdev_rx_handler_unregister(netdev_vport->dev); | 158 | netdev_rx_handler_unregister(vport->dev); |
163 | netdev_upper_dev_unlink(netdev_vport->dev, | 159 | netdev_upper_dev_unlink(vport->dev, |
164 | netdev_master_upper_dev_get(netdev_vport->dev)); | 160 | netdev_master_upper_dev_get(vport->dev)); |
165 | dev_set_promiscuity(netdev_vport->dev, -1); | 161 | dev_set_promiscuity(vport->dev, -1); |
166 | } | 162 | } |
167 | 163 | ||
168 | static void netdev_destroy(struct vport *vport) | 164 | static void netdev_destroy(struct vport *vport) |
169 | { | 165 | { |
170 | struct netdev_vport *netdev_vport = netdev_vport_priv(vport); | ||
171 | |||
172 | rtnl_lock(); | 166 | rtnl_lock(); |
173 | if (netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH) | 167 | if (vport->dev->priv_flags & IFF_OVS_DATAPATH) |
174 | ovs_netdev_detach_dev(vport); | 168 | ovs_netdev_detach_dev(vport); |
175 | rtnl_unlock(); | 169 | rtnl_unlock(); |
176 | 170 | ||
177 | call_rcu(&netdev_vport->rcu, free_port_rcu); | 171 | call_rcu(&vport->rcu, free_port_rcu); |
178 | } | 172 | } |
179 | 173 | ||
180 | const char *ovs_netdev_get_name(const struct vport *vport) | 174 | const char *ovs_netdev_get_name(const struct vport *vport) |
181 | { | 175 | { |
182 | const struct netdev_vport *netdev_vport = netdev_vport_priv(vport); | 176 | return vport->dev->name; |
183 | return netdev_vport->dev->name; | ||
184 | } | 177 | } |
185 | 178 | ||
186 | static unsigned int packet_length(const struct sk_buff *skb) | 179 | static unsigned int packet_length(const struct sk_buff *skb) |
@@ -195,18 +188,17 @@ static unsigned int packet_length(const struct sk_buff *skb) | |||
195 | 188 | ||
196 | static int netdev_send(struct vport *vport, struct sk_buff *skb) | 189 | static int netdev_send(struct vport *vport, struct sk_buff *skb) |
197 | { | 190 | { |
198 | struct netdev_vport *netdev_vport = netdev_vport_priv(vport); | 191 | int mtu = vport->dev->mtu; |
199 | int mtu = netdev_vport->dev->mtu; | ||
200 | int len; | 192 | int len; |
201 | 193 | ||
202 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { | 194 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { |
203 | net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", | 195 | net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", |
204 | netdev_vport->dev->name, | 196 | vport->dev->name, |
205 | packet_length(skb), mtu); | 197 | packet_length(skb), mtu); |
206 | goto drop; | 198 | goto drop; |
207 | } | 199 | } |
208 | 200 | ||
209 | skb->dev = netdev_vport->dev; | 201 | skb->dev = vport->dev; |
210 | len = skb->len; | 202 | len = skb->len; |
211 | dev_queue_xmit(skb); | 203 | dev_queue_xmit(skb); |
212 | 204 | ||
diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h index 6f7038e79c52..1c52aed255c5 100644 --- a/net/openvswitch/vport-netdev.h +++ b/net/openvswitch/vport-netdev.h | |||
@@ -26,18 +26,6 @@ | |||
26 | 26 | ||
27 | struct vport *ovs_netdev_get_vport(struct net_device *dev); | 27 | struct vport *ovs_netdev_get_vport(struct net_device *dev); |
28 | 28 | ||
29 | struct netdev_vport { | ||
30 | struct rcu_head rcu; | ||
31 | |||
32 | struct net_device *dev; | ||
33 | }; | ||
34 | |||
35 | static inline struct netdev_vport * | ||
36 | netdev_vport_priv(const struct vport *vport) | ||
37 | { | ||
38 | return vport_priv(vport); | ||
39 | } | ||
40 | |||
41 | const char *ovs_netdev_get_name(const struct vport *); | 29 | const char *ovs_netdev_get_name(const struct vport *); |
42 | void ovs_netdev_detach_dev(struct vport *); | 30 | void ovs_netdev_detach_dev(struct vport *); |
43 | 31 | ||
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index 75d68248ba69..e05ec68439d1 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h | |||
@@ -107,7 +107,7 @@ struct vport_portids { | |||
107 | * @detach_list: list used for detaching vport in net-exit call. | 107 | * @detach_list: list used for detaching vport in net-exit call. |
108 | */ | 108 | */ |
109 | struct vport { | 109 | struct vport { |
110 | struct rcu_head rcu; | 110 | struct net_device *dev; |
111 | struct datapath *dp; | 111 | struct datapath *dp; |
112 | struct vport_portids __rcu *upcall_portids; | 112 | struct vport_portids __rcu *upcall_portids; |
113 | u16 port_no; | 113 | u16 port_no; |
@@ -120,6 +120,7 @@ struct vport { | |||
120 | 120 | ||
121 | struct vport_err_stats err_stats; | 121 | struct vport_err_stats err_stats; |
122 | struct list_head detach_list; | 122 | struct list_head detach_list; |
123 | struct rcu_head rcu; | ||
123 | }; | 124 | }; |
124 | 125 | ||
125 | /** | 126 | /** |