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);
}
static int netif_drop_packets_enable(netif_info *pt_netif)
{
	int ret = 0;
	ret = netdev_rx_handler_register(pt_netif->ndev, drop_packet,
					 pt_netif);
	if (ret) {
		DBG_PRINT("Error %d calling netdev_rx_handler_register\n", ret);
		goto out;
	}

#ifdef CONFIG_NETPOLL

	DBG_PRINT("==CONFIG_NETPOLL");

	/* no effection for net_device on which netpoll have already been set up */
	pt_netif->ndev->priv_flags |= IFF_DISABLE_NETPOLL;
	smp_wmb();
	if (rcu_dereference(pt_netif->ndev->npinfo))
	{
		/* netpoll already set up on this dev, rollback previous operations and return fail */
		netif_drop_packets_disable(pt_netif);
		ret = -EBUSY;
		goto out;

	}

	
#endif
	DBG_PRINT("==");

out:
	return ret;

}
Exemple #3
0
static int rmnet_register_real_device(struct net_device *real_dev)
{
	struct rmnet_port *port;
	int rc;

	ASSERT_RTNL();

	if (rmnet_is_real_dev_registered(real_dev))
		return 0;

	port = kzalloc(sizeof(*port), GFP_ATOMIC);
	if (!port)
		return -ENOMEM;

	port->dev = real_dev;
	rc = netdev_rx_handler_register(real_dev, rmnet_rx_handler, port);
	if (rc) {
		kfree(port);
		return -EBUSY;
	}

	/* hold on to real dev for MAP data */
	dev_hold(real_dev);

	netdev_dbg(real_dev, "registered with rmnet\n");
	return 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();
#ifdef HAVE_RHEL_OVS_HOOK
	rcu_assign_pointer(netdev_vport->dev->ax25_ptr, vport);
	atomic_inc(&nr_bridges);
	rcu_assign_pointer(openvswitch_handle_frame_hook, netdev_frame_hook);
#else
	err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
					 vport);
	if (err)
		goto error_unlock;
#endif

	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();

	return vport;

#ifndef HAVE_RHEL_OVS_HOOK
error_unlock:
#endif
	rtnl_unlock();
error_put:
	dev_put(netdev_vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}
Exemple #5
0
/* Setup device to be added to the HSR bridge. */
static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port)
{
	int res;

	dev_hold(dev);
	res = dev_set_promiscuity(dev, 1);
	if (res)
		goto fail_promiscuity;

	/* FIXME:
	 * What does net device "adjacency" mean? Should we do
	 * res = netdev_master_upper_dev_link(port->dev, port->hsr->dev); ?
	 */

	res = netdev_rx_handler_register(dev, hsr_handle_frame, port);
	if (res)
		goto fail_rx_handler;
	dev_disable_lro(dev);

	return 0;

fail_rx_handler:
	dev_set_promiscuity(dev, -1);
fail_promiscuity:
	dev_put(dev);

	return res;
}
Exemple #6
0
static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
{
	int ret;

	/* register the packet handler for slave ports */
	ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev);
	if (ret) {
		netdev_err(port_dev,
			   "Device %s failed to register rx_handler\n",
			   port_dev->name);
		goto out_fail;
	}

	ret = netdev_master_upper_dev_link(port_dev, dev, NULL, NULL);
	if (ret < 0)
		goto out_unregister;

	port_dev->priv_flags |= IFF_L3MDEV_SLAVE;
	cycle_netdev(port_dev);

	return 0;

out_unregister:
	netdev_rx_handler_unregister(port_dev);
out_fail:
	return ret;
}
Exemple #7
0
/*
 * 重要!通过相应的参数进行网络设备的注册
 * 何时调用?
*/
static struct vport *netdev_create(const struct vport_parms *parms)
{
	struct vport *vport;
	struct netdev_vport *netdev_vport;  // 看vport_netdev.h中的定义
	int err;
	//根据具体的ovs_netdev_vport_ops和参数构造一个vport
	// 第一个参数代表私有数据的大小,这里正是要放struct netdev_vport
	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;
	}
	/* 重要!就是设置net_device两个字段  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
	*/
	err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, vport);
	if (err)
		goto error_put;

	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;

	return vport;

error_put:
	dev_put(netdev_vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}
Exemple #8
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;
}
Exemple #9
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);
}
Exemple #10
0
/* Ask the Linux RX subsystem to intercept (or stop intercepting)
 * the packets incoming from the interface attached to 'na'.
 */
int
netmap_catch_rx(struct netmap_adapter *na, int intercept)
{
#ifndef NETMAP_LINUX_HAVE_RX_REGISTER
    return 0;
#else /* HAVE_RX_REGISTER */
    struct ifnet *ifp = na->ifp;

    if (intercept) {
        return -netdev_rx_handler_register(na->ifp,
                &linux_generic_rx_handler, na);
    } else {
        netdev_rx_handler_unregister(ifp);
        return 0;
    }
#endif /* HAVE_RX_REGISTER */
}
Exemple #11
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(&init_net, 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;
	}

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

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

	return vport;

error_put:
	dev_put(netdev_vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}
/**
 * rmnet_associate_network_device() - Associate network device
 * @dev:      Device to register with RmNet data
 *
 * Typically used on physical network devices. Registers RX handler and private
 * metadata structures.
 *
 * Return:
 *      - RMNET_CONFIG_OK if successful
 *      - RMNET_CONFIG_NO_SUCH_DEVICE dev is null
 *      - RMNET_CONFIG_INVALID_REQUEST if the device to be associated is a vnd
 *      - RMNET_CONFIG_DEVICE_IN_USE if dev rx_handler is already filled
 *      - RMNET_CONFIG_DEVICE_IN_USE if netdev_rx_handler_register() fails
 */
int rmnet_associate_network_device(struct net_device *dev)
{
	struct rmnet_phys_ep_conf_s *config;
	int rc;
	ASSERT_RTNL();

	LOGL("(%s);\n", dev->name);

	if (!dev)
		return RMNET_CONFIG_NO_SUCH_DEVICE;

	if (_rmnet_is_physical_endpoint_associated(dev)) {
		LOGM("%s is already regestered", dev->name);
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	if (rmnet_vnd_is_vnd(dev)) {
		LOGM("%s is a vnd", dev->name);
		return RMNET_CONFIG_INVALID_REQUEST;
	}

	config = (struct rmnet_phys_ep_conf_s *)
		 kmalloc(sizeof(struct rmnet_phys_ep_conf_s), GFP_ATOMIC);

	if (!config)
		return RMNET_CONFIG_NOMEM;

	memset(config, 0, sizeof(struct rmnet_phys_ep_conf_s));
	config->dev = dev;
	spin_lock_init(&config->agg_lock);

	rc = netdev_rx_handler_register(dev, rmnet_rx_handler, config);

	if (rc) {
		LOGM("netdev_rx_handler_register returns %d", rc);
		kfree(config);
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	/* Explicitly hold a reference to the device */
	dev_hold(dev);
	trace_rmnet_associate(dev);
	return RMNET_CONFIG_OK;
}
Exemple #13
0
int __init init( void ) {
   int err = 0;
   struct priv *priv;
   char ifstr[ 40 ];
   sprintf( ifstr, "%s%s", ifname, "%d" );
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
   child = alloc_netdev( sizeof( struct priv ), ifstr, setup );
#else
   child = alloc_netdev( sizeof( struct priv ), ifstr, NET_NAME_UNKNOWN, setup );
#endif
   if( child == NULL ) {
      ERR( "%s: allocate error", THIS_MODULE->name ); return -ENOMEM;
   }
   priv = netdev_priv( child );
   priv->parent = __dev_get_by_name( &init_net, link ); // parent interface  
   if( !priv->parent ) {
      ERR( "%s: no such net: %s", THIS_MODULE->name, link );
      err = -ENODEV; goto err;
   }
   if( priv->parent->type != ARPHRD_ETHER && priv->parent->type != ARPHRD_LOOPBACK ) {
      ERR( "%s: illegal net type", THIS_MODULE->name );
      err = -EINVAL; goto err;
   }
   /* also, and clone its IP, MAC and other information */
   memcpy( child->dev_addr, priv->parent->dev_addr, ETH_ALEN );
   memcpy( child->broadcast, priv->parent->broadcast, ETH_ALEN );
   if( ( err = dev_alloc_name( child, child->name ) ) ) {
      ERR( "%s: allocate name, error %i", THIS_MODULE->name, err );
      err = -EIO; goto err;
   }
   register_netdev( child );
   rtnl_lock();
   netdev_rx_handler_register( priv->parent, &handle_frame, NULL );
   rtnl_unlock();
   LOG( "module %s loaded", THIS_MODULE->name );
   LOG( "%s: create link %s", THIS_MODULE->name, child->name );
   LOG( "%s: registered rx handler for %s", THIS_MODULE->name, priv->parent->name );
   return 0;
err:
   free_netdev( child );
   return err;
}
Exemple #14
0
static int macvtap_newlink(struct net *src_net, struct net_device *dev,
			   struct nlattr *tb[], struct nlattr *data[],
			   struct netlink_ext_ack *extack)
{
	struct macvtap_dev *vlantap = netdev_priv(dev);
	int err;

	INIT_LIST_HEAD(&vlantap->tap.queue_list);

	/* Since macvlan supports all offloads by default, make
	 * tap support all offloads also.
	 */
	vlantap->tap.tap_features = TUN_OFFLOADS;

	/* Register callbacks for rx/tx drops accounting and updating
	 * net_device features
	 */
	vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped;
	vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped;
	vlantap->tap.update_features  = macvtap_update_features;

	err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap);
	if (err)
		return err;

	/* Don't put anything that may fail after macvlan_common_newlink
	 * because we can't undo what it does.
	 */
	err = macvlan_common_newlink(src_net, dev, tb, data);
	if (err) {
		netdev_rx_handler_unregister(dev);
		return err;
	}

	vlantap->tap.dev = vlantap->vlan.dev;

	return 0;
}
Exemple #15
0
static int __init rh_init(void)
{
	int rc = 0, err;
	int i;

	pr_info("rxhook (v%s) is loaded\n", RXHOOK_VERSION);

	rh = kmalloc(sizeof(struct rh_dev), GFP_KERNEL);
	if (rh == 0) {
		pr_info("fail to kmalloc: *rh_dev\n");
		rc = -1;
		goto out;
	}

	rh->dev = dev_get_by_name(&init_net, ifname);
	if (!rh->dev) {
		pr_err("Could not find %s\n", ifname);
		rc = -1;
		goto out;
	}

	rh->cpu = smp_processor_id();
	pr_info("cpuid: %d\n", rh->cpu);

	// register
	rtnl_lock();
	err = netdev_rx_handler_register(rh->dev, rh_handle_frame, rh);
	rtnl_unlock();
	if (err) {
		pr_err("%s failed to register rx_handler\n", ifname);
	}

	for(i = 0; i < 10; i++)
		pps[i] = 0;

out:
	return rc;
}
Exemple #16
0
static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
{
	struct slave *slave = kzalloc(sizeof(*slave), GFP_KERNEL);
	struct net_vrf *vrf = netdev_priv(dev);
	struct slave_queue *queue = &vrf->queue;
	int ret = -ENOMEM;

	if (!slave)
		goto out_fail;

	slave->dev = port_dev;

	/* register the packet handler for slave ports */
	ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev);
	if (ret) {
		netdev_err(port_dev,
			   "Device %s failed to register rx_handler\n",
			   port_dev->name);
		goto out_fail;
	}

	ret = netdev_master_upper_dev_link(port_dev, dev);
	if (ret < 0)
		goto out_unregister;

	port_dev->priv_flags |= IFF_L3MDEV_SLAVE;
	__vrf_insert_slave(queue, slave);
	cycle_netdev(port_dev);

	return 0;

out_unregister:
	netdev_rx_handler_unregister(port_dev);
out_fail:
	kfree(slave);
	return ret;
}
/**
 * rmnet_associate_network_device() - Associate network device
 * @dev:      Device to register with RmNet data
 *
 * Typically used on physical network devices. Registers RX handler and private
 * metadata structures.
 *
 * Return:
 *      - RMNET_CONFIG_OK if successful
 *      - RMNET_CONFIG_NO_SUCH_DEVICE dev is null
 *      - RMNET_CONFIG_DEVICE_IN_USE if dev rx_handler is already filled
 *      - RMNET_CONFIG_DEVICE_IN_USE if netdev_rx_handler_register() fails
 */
int rmnet_associate_network_device(struct net_device *dev)
{
	struct rmnet_phys_ep_conf_s *config;
	int rc;
	ASSERT_RTNL();

	LOGL("%s(%s);", __func__, dev->name);

	if (!dev)
		return RMNET_CONFIG_NO_SUCH_DEVICE;

	if (_rmnet_is_physical_endpoint_associated(dev)) {
		LOGM("%s(): %s is already regestered\n", __func__, dev->name);
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	config = (struct rmnet_phys_ep_conf_s *)
		 kmalloc(sizeof(struct rmnet_phys_ep_conf_s), GFP_ATOMIC);

	if (!config)
		return RMNET_CONFIG_NOMEM;

	memset(config, 0, sizeof(struct rmnet_phys_ep_conf_s));
	config->dev = dev;
	spin_lock_init(&config->agg_lock);

	rc = netdev_rx_handler_register(dev, rmnet_rx_handler, config);

	if (rc) {
		LOGM("%s(): netdev_rx_handler_register returns %d\n",
		     __func__, rc);
		kfree(config);
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	return RMNET_CONFIG_OK;
}
Exemple #18
0
/*
 * register an rx handler which will bypass all vrouter processing. Helpful
 * at the time of vrouter soft reset. For kernels that does not support rx
 * handler tap, the logic is handled in linux_rx_handler, albeit in an
 * inefficient way (but works :)
 */
void
vhost_tap_phys(struct net_device *vdev, struct net_device *pdev)
{
    struct vhost_priv *vp;

    if (!vdev || !pdev)
        return;

    vp = netdev_priv(vdev);
    /*
     * with vhost_attach_phys, it is possible that everything was OK except
     * that the physical went out and came back. if that is the case, do not
     * tap here
     */
    if (vp->vp_vifp)
        goto exit_tap_phys;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
    /*
     * it can so happen (unlikely) that vhost is deleted from vrouter
     * before the physical, in which case we will have to unregister
     * the rx handler in physical and install the vhost_rx_handler
     */
    if (rcu_dereference(pdev->rx_handler) == linux_rx_handler)
        netdev_rx_handler_unregister(pdev);

    if (!rcu_dereference(pdev->rx_handler))
        netdev_rx_handler_register(pdev, vhost_rx_handler, (void *)vdev);

#else
    vr_set_vif_ptr(pdev, &vr_reset_interface);
#endif

exit_tap_phys:
    return;
}
Exemple #19
0
struct netpoll_wrapper *netpoll_wrapper_create(const char *pDeviceName, int localPort, const char *pOptionalLocalIp)
{
	struct net_device *pDevice;
	struct netpoll_wrapper *pResult;
	int localIp;
	int err;

	if (!pDeviceName || !localPort)
	{
		printk(KERN_ERR "kgdboe: cannot create a netpoll wrapper without a device name\n");
		return NULL;
	}

	pDevice = dev_get_by_name(&init_net, pDeviceName);
	if (!pDevice)
	{
		printk(KERN_ERR "kgdboe: Cannot find network device by name: %s\n", pDeviceName);
		return NULL;
	}


	if (pOptionalLocalIp)
	{
		localIp = in_aton(pOptionalLocalIp);
		if (!localIp)
		{
			printk(KERN_ERR "kgdboe: Invalid local IP: %s\n", pOptionalLocalIp);
			return NULL;
		}
	}
	else
	{
		if (!pDevice->ip_ptr)
		{
			printk(KERN_ERR "kgdboe: %s does not have an in_device associated. Cannot get default IP address.\n", pDeviceName);
			return NULL;
		}
		if (!pDevice->ip_ptr->ifa_list)
		{
			printk(KERN_ERR "kgdboe: %s does not have a in_ifaddr struct associated. Cannot get default IP address.\n", pDeviceName);
			return NULL;
		}

		localIp = pDevice->ip_ptr->ifa_list->ifa_local;
	}

	pResult = (struct netpoll_wrapper *)kmalloc(sizeof(struct netpoll_wrapper), GFP_KERNEL);
	if (!pResult)
	{
		printk(KERN_ERR "kgdboe: cannot allocate memory for netpoll wrapper\n");
		return NULL;
	}

	memset(pResult, 0, sizeof(*pResult));

#ifdef NETPOLL_POLL_DEV_USABLE
	pResult->netpoll_poll_dev = (void(*)(struct net_device *))kallsyms_lookup_name("netpoll_poll_dev");
	if (!pResult->netpoll_poll_dev)
	{
		printk(KERN_ERR "kgdboe: Cannot find netpoll_poll_dev(). Aborting.\n");
		netpoll_wrapper_free(pResult);
		return NULL;
	}
#else
	pResult->zap_completion_queue = (void(*)(void))kallsyms_lookup_name("zap_completion_queue");
	if (!pResult->zap_completion_queue)
	{
		printk(KERN_ERR "kgdboe: Cannot find zap_completion_queue(). Aborting.\n");
		netpoll_wrapper_free(pResult);
		return NULL;
	}
#endif

	rtnl_lock();
	err = netdev_rx_handler_register(pDevice, netpoll_wrapper_rx_handler, pResult);
	rtnl_unlock();
	if (err < 0)
	{
		printk(KERN_ERR "kgdboe: Failed to register rx handler for %s, code %d\n", pDeviceName, err);
		netpoll_wrapper_free(pResult);
		return NULL;
	}

	register_tracepoint_wrapper(netif_receive_skb, hook_receive_skb, pResult);
	pResult->tracepoint_registered = true;

	pResult->pDeviceWithHandler = pDevice;

	strncpy(pResult->netpoll_obj.dev_name, pDeviceName, sizeof(pResult->netpoll_obj.dev_name));
	pResult->netpoll_obj.name = "kgdboe";
	pResult->netpoll_obj.local_port = localPort;
	memset(pResult->netpoll_obj.remote_mac, 0xFF, sizeof(pResult->netpoll_obj.remote_mac));

	err = netpoll_setup(&pResult->netpoll_obj);
	if (err < 0)
	{
		printk(KERN_ERR "kgdboe: Failed to setup netpoll for %s, code %d\n", pDeviceName, err);
		netpoll_wrapper_free(pResult);
		return NULL;
	}

	pResult->netpoll_initialized = true;

	return pResult;
}
Exemple #20
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);
}