diff options
Diffstat (limited to 'net/openvswitch/vport-netdev.c')
| -rw-r--r-- | net/openvswitch/vport-netdev.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 5982f3f62835..09d93c13cfd6 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/llc.h> | 25 | #include <linux/llc.h> |
| 26 | #include <linux/rtnetlink.h> | 26 | #include <linux/rtnetlink.h> |
| 27 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
| 28 | #include <linux/openvswitch.h> | ||
| 28 | 29 | ||
| 29 | #include <net/llc.h> | 30 | #include <net/llc.h> |
| 30 | 31 | ||
| @@ -74,6 +75,15 @@ static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb) | |||
| 74 | return RX_HANDLER_CONSUMED; | 75 | return RX_HANDLER_CONSUMED; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 78 | static struct net_device *get_dpdev(struct datapath *dp) | ||
| 79 | { | ||
| 80 | struct vport *local; | ||
| 81 | |||
| 82 | local = ovs_vport_ovsl(dp, OVSP_LOCAL); | ||
| 83 | BUG_ON(!local); | ||
| 84 | return netdev_vport_priv(local)->dev; | ||
| 85 | } | ||
| 86 | |||
| 77 | static struct vport *netdev_create(const struct vport_parms *parms) | 87 | static struct vport *netdev_create(const struct vport_parms *parms) |
| 78 | { | 88 | { |
| 79 | struct vport *vport; | 89 | struct vport *vport; |
| @@ -103,10 +113,15 @@ static struct vport *netdev_create(const struct vport_parms *parms) | |||
| 103 | } | 113 | } |
| 104 | 114 | ||
| 105 | rtnl_lock(); | 115 | rtnl_lock(); |
| 116 | err = netdev_master_upper_dev_link(netdev_vport->dev, | ||
| 117 | get_dpdev(vport->dp)); | ||
| 118 | if (err) | ||
| 119 | goto error_unlock; | ||
| 120 | |||
| 106 | err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, | 121 | err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, |
| 107 | vport); | 122 | vport); |
| 108 | if (err) | 123 | if (err) |
| 109 | goto error_unlock; | 124 | goto error_master_upper_dev_unlink; |
| 110 | 125 | ||
| 111 | dev_set_promiscuity(netdev_vport->dev, 1); | 126 | dev_set_promiscuity(netdev_vport->dev, 1); |
| 112 | netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; | 127 | netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; |
| @@ -114,6 +129,8 @@ static struct vport *netdev_create(const struct vport_parms *parms) | |||
| 114 | 129 | ||
| 115 | return vport; | 130 | return vport; |
| 116 | 131 | ||
| 132 | error_master_upper_dev_unlink: | ||
| 133 | netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp)); | ||
| 117 | error_unlock: | 134 | error_unlock: |
| 118 | rtnl_unlock(); | 135 | rtnl_unlock(); |
| 119 | error_put: | 136 | error_put: |
| @@ -140,6 +157,7 @@ static void netdev_destroy(struct vport *vport) | |||
| 140 | rtnl_lock(); | 157 | rtnl_lock(); |
| 141 | netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH; | 158 | netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH; |
| 142 | netdev_rx_handler_unregister(netdev_vport->dev); | 159 | netdev_rx_handler_unregister(netdev_vport->dev); |
| 160 | netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp)); | ||
| 143 | dev_set_promiscuity(netdev_vport->dev, -1); | 161 | dev_set_promiscuity(netdev_vport->dev, -1); |
| 144 | rtnl_unlock(); | 162 | rtnl_unlock(); |
| 145 | 163 | ||
