aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/vport-internal_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/vport-internal_dev.c')
-rw-r--r--net/openvswitch/vport-internal_dev.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 0531de6c7a4a..84e0a0379186 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -63,16 +63,6 @@ static struct rtnl_link_stats64 *internal_dev_get_stats(struct net_device *netde
63 return stats; 63 return stats;
64} 64}
65 65
66static int internal_dev_mac_addr(struct net_device *dev, void *p)
67{
68 struct sockaddr *addr = p;
69
70 if (!is_valid_ether_addr(addr->sa_data))
71 return -EADDRNOTAVAIL;
72 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
73 return 0;
74}
75
76/* Called with rcu_read_lock_bh. */ 66/* Called with rcu_read_lock_bh. */
77static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) 67static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
78{ 68{
@@ -126,7 +116,7 @@ static const struct net_device_ops internal_dev_netdev_ops = {
126 .ndo_open = internal_dev_open, 116 .ndo_open = internal_dev_open,
127 .ndo_stop = internal_dev_stop, 117 .ndo_stop = internal_dev_stop,
128 .ndo_start_xmit = internal_dev_xmit, 118 .ndo_start_xmit = internal_dev_xmit,
129 .ndo_set_mac_address = internal_dev_mac_addr, 119 .ndo_set_mac_address = eth_mac_addr,
130 .ndo_change_mtu = internal_dev_change_mtu, 120 .ndo_change_mtu = internal_dev_change_mtu,
131 .ndo_get_stats64 = internal_dev_get_stats, 121 .ndo_get_stats64 = internal_dev_get_stats,
132}; 122};
@@ -138,6 +128,7 @@ static void do_setup(struct net_device *netdev)
138 netdev->netdev_ops = &internal_dev_netdev_ops; 128 netdev->netdev_ops = &internal_dev_netdev_ops;
139 129
140 netdev->priv_flags &= ~IFF_TX_SKB_SHARING; 130 netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
131 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
141 netdev->destructor = internal_dev_destructor; 132 netdev->destructor = internal_dev_destructor;
142 SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops); 133 SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops);
143 netdev->tx_queue_len = 0; 134 netdev->tx_queue_len = 0;
@@ -146,7 +137,7 @@ static void do_setup(struct net_device *netdev)
146 NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO; 137 NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO;
147 138
148 netdev->vlan_features = netdev->features; 139 netdev->vlan_features = netdev->features;
149 netdev->features |= NETIF_F_HW_VLAN_TX; 140 netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
150 netdev->hw_features = netdev->features & ~NETIF_F_LLTX; 141 netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
151 eth_hw_addr_random(netdev); 142 eth_hw_addr_random(netdev);
152} 143}
@@ -182,16 +173,19 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
182 if (vport->port_no == OVSP_LOCAL) 173 if (vport->port_no == OVSP_LOCAL)
183 netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL; 174 netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL;
184 175
176 rtnl_lock();
185 err = register_netdevice(netdev_vport->dev); 177 err = register_netdevice(netdev_vport->dev);
186 if (err) 178 if (err)
187 goto error_free_netdev; 179 goto error_free_netdev;
188 180
189 dev_set_promiscuity(netdev_vport->dev, 1); 181 dev_set_promiscuity(netdev_vport->dev, 1);
182 rtnl_unlock();
190 netif_start_queue(netdev_vport->dev); 183 netif_start_queue(netdev_vport->dev);
191 184
192 return vport; 185 return vport;
193 186
194error_free_netdev: 187error_free_netdev:
188 rtnl_unlock();
195 free_netdev(netdev_vport->dev); 189 free_netdev(netdev_vport->dev);
196error_free_vport: 190error_free_vport:
197 ovs_vport_free(vport); 191 ovs_vport_free(vport);
@@ -204,10 +198,13 @@ static void internal_dev_destroy(struct vport *vport)
204 struct netdev_vport *netdev_vport = netdev_vport_priv(vport); 198 struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
205 199
206 netif_stop_queue(netdev_vport->dev); 200 netif_stop_queue(netdev_vport->dev);
201 rtnl_lock();
207 dev_set_promiscuity(netdev_vport->dev, -1); 202 dev_set_promiscuity(netdev_vport->dev, -1);
208 203
209 /* unregister_netdevice() waits for an RCU grace period. */ 204 /* unregister_netdevice() waits for an RCU grace period. */
210 unregister_netdevice(netdev_vport->dev); 205 unregister_netdevice(netdev_vport->dev);
206
207 rtnl_unlock();
211} 208}
212 209
213static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) 210static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
@@ -235,7 +232,6 @@ const struct vport_ops ovs_internal_vport_ops = {
235 .create = internal_dev_create, 232 .create = internal_dev_create,
236 .destroy = internal_dev_destroy, 233 .destroy = internal_dev_destroy,
237 .get_name = ovs_netdev_get_name, 234 .get_name = ovs_netdev_get_name,
238 .get_ifindex = ovs_netdev_get_ifindex,
239 .send = internal_dev_recv, 235 .send = internal_dev_recv,
240}; 236};
241 237