Esempio n. 1
0
static struct vport *netdev_create(const struct vport_parms *parms)
{
    struct vport *vport;
    struct netdev_vport *netdev_vport;
    int err;

    vport = ovs_vport_alloc(sizeof(struct netdev_vport),
                            &ovs_netdev_vport_ops, parms);
    if (IS_ERR(vport)) {
        err = PTR_ERR(vport);
        goto error;
    }

    netdev_vport = netdev_vport_priv(vport);

    netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
    if (!netdev_vport->dev) {
        err = -ENODEV;
        goto error_free_vport;
    }

    if (netdev_vport->dev->flags & IFF_LOOPBACK ||
            netdev_vport->dev->type != ARPHRD_ETHER ||
            ovs_is_internal_dev(netdev_vport->dev)) {
        err = -EINVAL;
        goto error_put;
    }

    rtnl_lock();
    err = netdev_master_upper_dev_link(netdev_vport->dev,
                                       get_dpdev(vport->dp));
    if (err)
        goto error_unlock;

    err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
                                     vport);
    if (err)
        goto error_master_upper_dev_unlink;

    dev_set_promiscuity(netdev_vport->dev, 1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    dev_disable_lro(netdev_vport->dev);
#endif
    netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
    rtnl_unlock();

    netdev_init();
    return vport;

error_master_upper_dev_unlink:
    netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
error_unlock:
    rtnl_unlock();
error_put:
    dev_put(netdev_vport->dev);
error_free_vport:
    ovs_vport_free(vport);
error:
    return ERR_PTR(err);
}
Esempio n. 2
0
struct vport *ovs_netdev_link(struct vport *vport, const char *name)
{
	int err;

	vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), name);
	if (!vport->dev) {
		err = -ENODEV;
		goto error_free_vport;
	}

	if (vport->dev->flags & IFF_LOOPBACK ||
	    (vport->dev->type != ARPHRD_ETHER &&
	     vport->dev->type != ARPHRD_NONE) ||
	    ovs_is_internal_dev(vport->dev)) {
		err = -EINVAL;
		goto error_put;
	}

	rtnl_lock();
	err = netdev_master_upper_dev_link(vport->dev,
					   get_dpdev(vport->dp),
					   NULL, NULL, NULL);
	if (err)
		goto error_unlock;

	err = netdev_rx_handler_register(vport->dev, netdev_frame_hook,
					 vport);
	if (err)
		goto error_master_upper_dev_unlink;

	dev_disable_lro(vport->dev);
	dev_set_promiscuity(vport->dev, 1);
	vport->dev->priv_flags |= IFF_OVS_DATAPATH;
	rtnl_unlock();

	return vport;

error_master_upper_dev_unlink:
	netdev_upper_dev_unlink(vport->dev, get_dpdev(vport->dp));
error_unlock:
	rtnl_unlock();
error_put:
	dev_put(vport->dev);
error_free_vport:
	ovs_vport_free(vport);
	return ERR_PTR(err);
}
static void netdev_destroy(struct vport *vport)
{
	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

	rtnl_lock();
	netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
	netdev_rx_handler_unregister(netdev_vport->dev);
	netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
	dev_set_promiscuity(netdev_vport->dev, -1);
	rtnl_unlock();

	call_rcu(&netdev_vport->rcu, free_port_rcu);
}
Esempio n. 4
0
static struct vport *netdev_create(const struct vport_parms *parms)
{
	struct vport *vport;
	struct netdev_vport *netdev_vport;
	int err;

	vport = ovs_vport_alloc(sizeof(struct netdev_vport),
				&ovs_netdev_vport_ops, parms);
	if (IS_ERR(vport)) {
		err = PTR_ERR(vport);
		goto error;
	}

	netdev_vport = netdev_vport_priv(vport);

    //TODO:这里直接获取, 原因
	netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
	if (!netdev_vport->dev) {
		err = -ENODEV;
		goto error_free_vport;
	}

	if (netdev_vport->dev->flags & IFF_LOOPBACK ||
	    netdev_vport->dev->type != ARPHRD_ETHER ||
	    ovs_is_internal_dev(netdev_vport->dev)) {
		err = -EINVAL;
		goto error_put;
	}

	rtnl_lock();
    /**
     * netdev_master_upper_dev_link - Add a master link to the upper device
     * @dev: device
     * @upper_dev: new upper device
     *
     * Adds a link to device which is upper to this one. In this case, only
     * one master upper device can be linked, although other non-master devices
     * might be linked as well. The caller must hold the RTNL lock.
     * On a failure a negative errno code is returned. On success the reference
     * counts are adjusted and the function returns zero.
     */

	err = netdev_master_upper_dev_link(netdev_vport->dev,
					   get_dpdev(vport->dp));
	if (err)
		goto error_unlock;

    /**
    *      netdev_rx_handler_register - register receive handler
    *      @dev: device to register a handler for
    *      @rx_handler: receive handler to register
    *      @rx_handler_data: data pointer that is used by rx handler
    *
    *      Register a receive handler for a device. This handler will then be
    *      called from __netif_receive_skb. A negative errno code is returned
    *      on a failure.
    *
    *      The caller must hold the rtnl_mutex.
    *
    *      For a general description of rx_handler, see enum rx_handler_result.
    */
	err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
					 vport);
	if (err)
		goto error_master_upper_dev_unlink;

	dev_set_promiscuity(netdev_vport->dev, 1);
	netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
	rtnl_unlock();

	return vport;

error_master_upper_dev_unlink:
	netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
error_unlock:
	rtnl_unlock();
error_put:
	dev_put(netdev_vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}