X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fvport-netdev.c;h=d492d19b7d6497f95f804f0d7afa0c6d0034d12c;hb=7f9bd4e8db2b307813c44bce0c5c5e2e69331c25;hp=33fe9a513773e0fcc55983ec3043c06862855b1c;hpb=94903c989826268a7fab3c730cd7d0b35ef423d5;p=openvswitch diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 33fe9a51..d492d19b 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -16,6 +16,7 @@ #include +#include "checksum.h" #include "datapath.h" #include "vport-internal_dev.h" #include "vport-netdev.h" @@ -94,7 +95,7 @@ static struct vport *netdev_create(const struct vport_parms *parms) struct netdev_vport *netdev_vport; int err; - vport = vport_alloc(sizeof(struct netdev_vport), &netdev_vport_ops); + vport = vport_alloc(sizeof(struct netdev_vport), &netdev_vport_ops, parms); if (IS_ERR(vport)) { err = PTR_ERR(vport); goto error; @@ -125,6 +126,15 @@ static struct vport *netdev_create(const struct vport_parms *parms) vport_set_stats(vport, &stats); } + err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, + vport); + if (err) + goto error_put; + + dev_set_promiscuity(netdev_vport->dev, 1); + dev_disable_lro(netdev_vport->dev); + netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; + return vport; error_put: @@ -139,37 +149,15 @@ static int netdev_destroy(struct vport *vport) { struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - dev_put(netdev_vport->dev); - vport_free(vport); - - return 0; -} - -static int netdev_attach(struct vport *vport) -{ - struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - int err; - - err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, - vport); - if (err) - return err; - - dev_set_promiscuity(netdev_vport->dev, 1); - dev_disable_lro(netdev_vport->dev); - netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; - - return 0; -} - -static int netdev_detach(struct vport *vport) -{ - struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH; netdev_rx_handler_unregister(netdev_vport->dev); dev_set_promiscuity(netdev_vport->dev, -1); + synchronize_rcu(); + + dev_put(netdev_vport->dev); + vport_free(vport); + return 0; } @@ -285,17 +273,17 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) /* Returns null if this device is not attached to a datapath. */ struct vport *netdev_get_vport(struct net_device *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) - /* XXX: The bridge code may have registered the data. - * So check that the handler pointer is the datapath's. - * Once the merge is done and IFF_OVS_DATAPATH stops - * being the same value as IFF_BRIDGE_PORT the check can - * simply be netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH. */ - if (rcu_dereference(dev->rx_handler) != netdev_frame_hook) +#ifdef IFF_BRIDGE_PORT +#if IFF_BRIDGE_PORT != IFF_OVS_DATAPATH + if (likely(dev->priv_flags & IFF_OVS_DATAPATH)) +#else + if (likely(rcu_access_pointer(dev->rx_handler) == netdev_frame_hook)) +#endif + return (struct vport *)rcu_dereference_rtnl(dev->rx_handler_data); + else return NULL; - return (struct vport *)rcu_dereference(dev->rx_handler_data); #else - return (struct vport *)rcu_dereference(dev->br_port); + return (struct vport *)rcu_dereference_rtnl(dev->br_port); #endif } @@ -307,8 +295,6 @@ const struct vport_ops netdev_vport_ops = { .exit = netdev_exit, .create = netdev_create, .destroy = netdev_destroy, - .attach = netdev_attach, - .detach = netdev_detach, .set_mtu = netdev_set_mtu, .set_addr = netdev_set_addr, .get_name = netdev_get_name,