diff options
Diffstat (limited to 'net/openvswitch/vport-netdev.c')
-rw-r--r-- | net/openvswitch/vport-netdev.c | 86 |
1 files changed, 39 insertions, 47 deletions
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 | ||