예제 #1
0
파일: hsr_slave.c 프로젝트: 020gzh/linux
/* 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;
}
예제 #2
0
파일: slave.c 프로젝트: andy-shev/linux
static int dsa_slave_open(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct net_device *master = p->parent->dst->master_netdev;
	struct dsa_switch *ds = p->parent;
	u8 stp_state = dsa_port_is_bridged(p) ?
			BR_STATE_BLOCKING : BR_STATE_FORWARDING;
	int err;

	if (!(master->flags & IFF_UP))
		return -ENETDOWN;

	if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
		err = dev_uc_add(master, dev->dev_addr);
		if (err < 0)
			goto out;
	}

	if (dev->flags & IFF_ALLMULTI) {
		err = dev_set_allmulti(master, 1);
		if (err < 0)
			goto del_unicast;
	}
	if (dev->flags & IFF_PROMISC) {
		err = dev_set_promiscuity(master, 1);
		if (err < 0)
			goto clear_allmulti;
	}

	if (ds->drv->port_enable) {
		err = ds->drv->port_enable(ds, p->port, p->phy);
		if (err)
			goto clear_promisc;
	}

	if (ds->drv->port_stp_update)
		ds->drv->port_stp_update(ds, p->port, stp_state);

	if (p->phy)
		phy_start(p->phy);

	return 0;

clear_promisc:
	if (dev->flags & IFF_PROMISC)
		dev_set_promiscuity(master, -1);
clear_allmulti:
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(master, -1);
del_unicast:
	if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
		dev_uc_del(master, dev->dev_addr);
out:
	return err;
}
예제 #3
0
파일: br_if.c 프로젝트: nhanh0/hah
int br_add_if(struct net_bridge *br, struct net_device *dev)
{
	struct net_bridge_port *p;

	if (dev->br_port != NULL)
		return -EBUSY;

	if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
		return -EINVAL;

	dev_hold(dev);
	write_lock_bh(&br->lock);
	if ((p = new_nbp(br, dev)) == NULL) {
		write_unlock_bh(&br->lock);
		dev_put(dev);
		return -EXFULL;
	}

	dev_set_promiscuity(dev, 1);

	br_stp_recalculate_bridge_id(br);
	br_fdb_insert(br, p, dev->dev_addr, 1);
	if ((br->dev.flags & IFF_UP) && (dev->flags & IFF_UP))
		br_stp_enable_port(p);
	write_unlock_bh(&br->lock);

	return 0;
}
예제 #4
0
파일: br_if.c 프로젝트: nhanh0/hah
/* called under bridge lock */
static int __br_del_if(struct net_bridge *br, struct net_device *dev)
{
	struct net_bridge_port *p;
	struct net_bridge_port **pptr;

	if ((p = dev->br_port) == NULL)
		return -EINVAL;

	br_stp_disable_port(p);

	dev_set_promiscuity(dev, -1);
	dev->br_port = NULL;

	pptr = &br->port_list;
	while (*pptr != NULL) {
		if (*pptr == p) {
			*pptr = p->next;
			break;
		}

		pptr = &((*pptr)->next);
	}

	br_fdb_delete_by_port(br, p);
	kfree(p);
	dev_put(dev);

	return 0;
}
예제 #5
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);
}
예제 #6
0
파일: hsr_slave.c 프로젝트: 020gzh/linux
void hsr_del_port(struct hsr_port *port)
{
	struct hsr_priv *hsr;
	struct hsr_port *master;

	hsr = port->hsr;
	master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
	list_del_rcu(&port->port_list);

	if (port != master) {
		if (master != NULL) {
			netdev_update_features(master->dev);
			dev_set_mtu(master->dev, hsr_get_max_mtu(hsr));
		}
		netdev_rx_handler_unregister(port->dev);
		dev_set_promiscuity(port->dev, -1);
	}

	/* FIXME?
	 * netdev_upper_dev_unlink(port->dev, port->hsr->dev);
	 */

	synchronize_rcu();

	if (port != master)
		dev_put(port->dev);
}
예제 #7
0
파일: slave.c 프로젝트: andy-shev/linux
static int dsa_slave_close(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct net_device *master = p->parent->dst->master_netdev;
	struct dsa_switch *ds = p->parent;

	if (p->phy)
		phy_stop(p->phy);

	dev_mc_unsync(master, dev);
	dev_uc_unsync(master, dev);
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(master, -1);
	if (dev->flags & IFF_PROMISC)
		dev_set_promiscuity(master, -1);

	if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
		dev_uc_del(master, dev->dev_addr);

	if (ds->drv->port_disable)
		ds->drv->port_disable(ds, p->port, p->phy);

	if (ds->drv->port_stp_update)
		ds->drv->port_stp_update(ds, p->port, BR_STATE_DISABLED);

	return 0;
}
예제 #8
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);
}
예제 #9
0
void ovs_netdev_detach_dev(struct vport *vport)
{
	ASSERT_RTNL();
	vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
	netdev_rx_handler_unregister(vport->dev);
	netdev_upper_dev_unlink(vport->dev,
				netdev_master_upper_dev_get(vport->dev));
	dev_set_promiscuity(vport->dev, -1);
}
static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
{
	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;

	if (change & IFF_ALLMULTI)
		dev_set_allmulti(real_dev, dev->flags & IFF_ALLMULTI ? 1 : -1);
	if (change & IFF_PROMISC)
		dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1);
}
예제 #11
0
static struct vport *internal_dev_create(const struct vport_parms *parms)
{
	struct vport *vport;
	struct internal_dev *internal_dev;
	int err;

	vport = ovs_vport_alloc(0, &ovs_internal_vport_ops, parms);
	if (IS_ERR(vport)) {
		err = PTR_ERR(vport);
		goto error;
	}

	vport->dev = alloc_netdev(sizeof(struct internal_dev),
				  parms->name, NET_NAME_USER, do_setup);
	if (!vport->dev) {
		err = -ENOMEM;
		goto error_free_vport;
	}
	vport->dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
	if (!vport->dev->tstats) {
		err = -ENOMEM;
		goto error_free_netdev;
	}

#ifdef HAVE_IFF_PHONY_HEADROOM
	vport->dev->needed_headroom = vport->dp->max_headroom;
#endif
	dev_net_set(vport->dev, ovs_dp_get_net(vport->dp));
	internal_dev = internal_dev_priv(vport->dev);
	internal_dev->vport = vport;

	/* Restrict bridge port to current netns. */
	if (vport->port_no == OVSP_LOCAL)
		vport->dev->features |= NETIF_F_NETNS_LOCAL;

	rtnl_lock();
	err = register_netdevice(vport->dev);
	if (err)
		goto error_unlock;

	dev_set_promiscuity(vport->dev, 1);
	rtnl_unlock();
	netif_start_queue(vport->dev);

	return vport;

error_unlock:
	rtnl_unlock();
	free_percpu(vport->dev->tstats);
error_free_netdev:
	free_netdev(vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}
예제 #12
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);

    return 0;
}
예제 #13
0
static void netdev_destroy(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);

	call_rcu(&netdev_vport->rcu, free_port_rcu);
}
static void internal_dev_destroy(struct vport *vport)
{
	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

	netif_stop_queue(netdev_vport->dev);
	dev_set_promiscuity(netdev_vport->dev, -1);

	/* unregister_netdevice() waits for an RCU grace period. */
	unregister_netdevice(netdev_vport->dev);
}
static void internal_dev_destroy(struct vport *vport)
{
	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

	netif_stop_queue(netdev_vport->dev);
	dev_set_promiscuity(netdev_vport->dev, -1);

	
	unregister_netdevice(netdev_vport->dev);
}
예제 #16
0
파일: slave.c 프로젝트: andy-shev/linux
static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct net_device *master = p->parent->dst->master_netdev;

	if (change & IFF_ALLMULTI)
		dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
	if (change & IFF_PROMISC)
		dev_set_promiscuity(master, dev->flags & IFF_PROMISC ? 1 : -1);
}
예제 #17
0
static void internal_dev_destroy(struct vport *vport)
{
	netif_stop_queue(vport->dev);
	rtnl_lock();
	dev_set_promiscuity(vport->dev, -1);

	/* unregister_netdevice() waits for an RCU grace period. */
	unregister_netdevice(vport->dev);
	free_percpu(vport->dev->tstats);
	rtnl_unlock();
}
예제 #18
0
static void netdev_destroy(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);
	ovs_vport_free(vport);
}
예제 #19
0
파일: vlan_dev.c 프로젝트: avagin/linux
static int vlan_dev_open(struct net_device *dev)
{
	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
	struct net_device *real_dev = vlan->real_dev;
	int err;

	if (!(real_dev->flags & IFF_UP) &&
	    !(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
		return -ENETDOWN;

	if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr) &&
	    !vlan_dev_inherit_address(dev, real_dev)) {
		err = dev_uc_add(real_dev, dev->dev_addr);
		if (err < 0)
			goto out;
	}

	if (dev->flags & IFF_ALLMULTI) {
		err = dev_set_allmulti(real_dev, 1);
		if (err < 0)
			goto del_unicast;
	}
	if (dev->flags & IFF_PROMISC) {
		err = dev_set_promiscuity(real_dev, 1);
		if (err < 0)
			goto clear_allmulti;
	}

	ether_addr_copy(vlan->real_dev_addr, real_dev->dev_addr);

	if (vlan->flags & VLAN_FLAG_GVRP)
		vlan_gvrp_request_join(dev);

	if (vlan->flags & VLAN_FLAG_MVRP)
		vlan_mvrp_request_join(dev);

	if (netif_carrier_ok(real_dev) &&
	    !(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
		netif_carrier_on(dev);
	return 0;

clear_allmulti:
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(real_dev, -1);
del_unicast:
	if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr))
		dev_uc_del(real_dev, dev->dev_addr);
out:
	netif_carrier_off(dev);
	return err;
}
예제 #20
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);
}
예제 #21
0
static struct vport *internal_dev_create(const struct vport_parms *parms)
{
	struct vport *vport;
	struct netdev_vport *netdev_vport;
	struct internal_dev *internal_dev;
	int err;

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

	netdev_vport = netdev_vport_priv(vport);

	netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev),
					 parms->name, NET_NAME_UNKNOWN,
					 do_setup);
	if (!netdev_vport->dev) {
		err = -ENOMEM;
		goto error_free_vport;
	}

	dev_net_set(netdev_vport->dev, ovs_dp_get_net(vport->dp));
	internal_dev = internal_dev_priv(netdev_vport->dev);
	internal_dev->vport = vport;

	/* Restrict bridge port to current netns. */
	if (vport->port_no == OVSP_LOCAL)
		netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL;

	rtnl_lock();
	err = register_netdevice(netdev_vport->dev);
	if (err)
		goto error_free_netdev;

	dev_set_promiscuity(netdev_vport->dev, 1);
	rtnl_unlock();
	netif_start_queue(netdev_vport->dev);

	return vport;

error_free_netdev:
	rtnl_unlock();
	free_netdev(netdev_vport->dev);
error_free_vport:
	ovs_vport_free(vport);
error:
	return ERR_PTR(err);
}
예제 #22
0
/* teach the switch the mac of a disabled slave
 * on the primary for fault tolerance
 *
 * Caller must hold bond->ptrlock for write or bond lock for write
 */
static void
rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
{
	if (!bond->current_slave) {
		return;
	}
	if (!bond->alb_info.primary_is_promisc) {
		bond->alb_info.primary_is_promisc = 1;
		dev_set_promiscuity(bond->current_slave->dev, 1);
	}
	bond->alb_info.rlb_promisc_timeout_counter = 0;

	alb_send_learning_packets(bond->current_slave, addr);
}
예제 #23
0
static void netdev_destroy(struct vport *vport)
{
    struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

    netdev_exit();
    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);
}
예제 #24
0
파일: vlan_dev.c 프로젝트: cilynx/dd-wrt
int vlan_dev_stop(struct net_device *dev)
{
	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;

	dev_mc_unsync(real_dev, dev);
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(real_dev, -1);
	if (dev->flags & IFF_PROMISC)
		dev_set_promiscuity(real_dev, -1);

	if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
		dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len);

	return 0;
}
예제 #25
0
/**
 * bond_alb_assign_current_slave - assign new current_slave
 * @bond: our bonding struct
 * @new_slave: new slave to assign
 *
 * Set the bond->current_slave to @new_slave and handle
 * mac address swapping and promiscuity changes as needed.
 *
 * Caller must hold bond ptrlock for write (or bond lock for write)
 */
void
bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave)
{
	struct slave *swap_slave = bond->current_slave;

	if (bond->current_slave == new_slave) {
		return;
	}

	if (bond->current_slave && bond->alb_info.primary_is_promisc) {
		dev_set_promiscuity(bond->current_slave->dev, -1);
		bond->alb_info.primary_is_promisc = 0;
		bond->alb_info.rlb_promisc_timeout_counter = 0;
	}

	bond->current_slave = new_slave;

	if (!new_slave || (bond->slave_cnt == 0)) {
		return;
	}

	/* set the new current_slave to the bonds mac address
	 * i.e. swap mac addresses of old current_slave and new current_slave
	 */
	if (!swap_slave) {
		/* find slave that is holding the bond's mac address */
		swap_slave = bond_get_first_slave(bond);
		while (swap_slave) {
			if (!memcmp(swap_slave->dev->dev_addr,
				bond->device->dev_addr, ETH_ALEN)) {
				break;
			}
			swap_slave = bond_get_next_slave(bond, swap_slave);
		}
	}

	/* current_slave must be set before calling alb_swap_mac_addr */
	if (swap_slave) {
		/* swap mac address */
		alb_swap_mac_addr(bond, swap_slave, new_slave);
	} else {
		/* set the new_slave to the bond mac address */
		alb_set_mac_addr(new_slave, bond->device->dev_addr,
				 bond->alb_info.rlb_enabled);
		/* fasten bond mac on new current slave */
		alb_send_learning_packets(new_slave, bond->device->dev_addr);
	}
}
예제 #26
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;
}
예제 #27
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);
}
예제 #28
0
static int dsa_slave_close(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct net_device *master = p->parent->dst->master_netdev;

	dev_mc_unsync(master, dev);
	dev_uc_unsync(master, dev);
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(master, -1);
	if (dev->flags & IFF_PROMISC)
		dev_set_promiscuity(master, -1);

	if (compare_ether_addr(dev->dev_addr, master->dev_addr))
		dev_uc_del(master, dev->dev_addr);

	return 0;
}
예제 #29
0
int nta_register_zc(struct net_device *netdev,
                    int	(*hard_start_xmit) (struct m_buf *mbuf,
                            struct net_device *dev))
{
    int i;
    struct zc_control *zc = &zc_sniffer[0];
    for(i=0; i< ZC_MAX_NETDEVS; i++) {
        //printk("zc->netdev[%d] %p\n", i, zc->netdev[i]);
        if(!zc->netdev[i] && netdev) {
            zc->netdev[i] = netdev;
            zc->hard_start_xmit = hard_start_xmit;
            dev_set_promiscuity(zc->netdev[i], 1);
            return i;
        }
    }
    return -1;
}
static int vlan_dev_open(struct net_device *dev)
{
	struct vlan_dev_info *vlan = vlan_dev_info(dev);
	struct net_device *real_dev = vlan->real_dev;
	int err;

	if (!(real_dev->flags & IFF_UP) &&
	    !(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
		return -ENETDOWN;

	if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
		err = dev_uc_add(real_dev, dev->dev_addr);
		if (err < 0)
			goto out;
	}

	if (dev->flags & IFF_ALLMULTI) {
		err = dev_set_allmulti(real_dev, 1);
		if (err < 0)
			goto del_unicast;
	}
	if (dev->flags & IFF_PROMISC) {
		err = dev_set_promiscuity(real_dev, 1);
		if (err < 0)
			goto clear_allmulti;
	}

	memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN);

	if (vlan->flags & VLAN_FLAG_GVRP)
		vlan_gvrp_request_join(dev);

	netif_carrier_on(dev);
	return 0;

clear_allmulti:
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(real_dev, -1);
del_unicast:
	if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
		dev_uc_del(real_dev, dev->dev_addr);
out:
	netif_carrier_off(dev);
	return err;
}