Пример #1
0
/* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */
int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val)
{
    struct net_device *dev = dev_get_by_name(dev_name);

    if (dev) {
        if (dev->priv_flags & IFF_802_1Q_VLAN) {
            /* verify flag is supported */
            if (flag == 1) {
                if (flag_val) {
                    VLAN_DEV_INFO(dev)->flags |= 1;
                } else {
                    VLAN_DEV_INFO(dev)->flags &= ~1;
                }
                dev_put(dev);
                return 0;
            } else {
                printk(KERN_ERR  "%s: flag %i is not valid.\n",
                       __FUNCTION__, (int)(flag));
                dev_put(dev);
                return -EINVAL;
            }
        } else {
            printk(KERN_ERR
                   "%s: %s is not a vlan device, priv_flags: %hX.\n",
                   __FUNCTION__, dev->name, dev->priv_flags);
            dev_put(dev);
        }
    } else {
        printk(KERN_ERR  "%s: Could not find device: %s\n",
               __FUNCTION__, dev_name);
    }

    return -EINVAL;
}
Пример #2
0
/*
 *	Delete directory entry for VLAN device.
 */
int vlan_proc_rem_dev(struct net_device *vlandev)
{
	if (!vlandev) {
		printk(VLAN_ERR "%s: invalid argument: %p\n",
			__FUNCTION__, vlandev);
		return -EINVAL;
	}

	if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
		printk(VLAN_DBG "%s: invalid argument, device: %s is not a VLAN device, priv_flags: 0x%4hX.\n",
			__FUNCTION__, vlandev->name, vlandev->priv_flags);
		return -EINVAL;
	}

#ifdef VLAN_DEBUG
	printk(VLAN_DBG "%s: dev: %p\n", __FUNCTION__, vlandev);
#endif

	/** NOTE:  This will consume the memory pointed to by dent, it seems. */
	if (VLAN_DEV_INFO(vlandev)->dent) {
		remove_proc_entry(VLAN_DEV_INFO(vlandev)->dent->name, proc_vlan_dir);
		VLAN_DEV_INFO(vlandev)->dent = NULL;
	}

	return 0;
}
Пример #3
0
int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_device_stats *stats = vlan_dev_get_stats(dev);
	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);

	/* Handle non-VLAN frames if they are sent to us, for example by DHCP.
	 *
	 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
	 * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
	 */

	if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
		int orig_headroom = skb_headroom(skb);
		unsigned short veth_TCI;

		/* This is not a VLAN frame...but we can fix that! */
		VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++;

#ifdef VLAN_DEBUG
		printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n",
			__FUNCTION__, htons(veth->h_vlan_proto));
#endif
		/* Construct the second two bytes. This field looks something
		 * like:
		 * usr_priority: 3 bits	 (high bits)
		 * CFI		 1 bit
		 * VLAN ID	 12 bits (low bits)
		 */
		veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
		veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);

		skb = __vlan_put_tag(skb, veth_TCI);
		if (!skb) {
			stats->tx_dropped++;
			return 0;
		}

		if (orig_headroom < VLAN_HLEN) {
			VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
		}
	}

#ifdef VLAN_DEBUG
	printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n",
		__FUNCTION__, skb, skb->dev->name);
	printk(VLAN_DBG "  %2hx.%2hx.%2hx.%2xh.%2hx.%2hx %2hx.%2hx.%2hx.%2hx.%2hx.%2hx %4hx %4hx %4hx\n",
	       veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
	       veth->h_source[0], veth->h_source[1], veth->h_source[2], veth->h_source[3], veth->h_source[4], veth->h_source[5],
	       veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto);
#endif

	stats->tx_packets++; /* for statics only */
	stats->tx_bytes += skb->len;

	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
	dev_queue_xmit(skb);

	return 0;
}
Пример #4
0
s32 netmode_br_transparent_rcv_finish(struct sk_buff *skb,
					int (*okfn)(struct sk_buff *))
{
    struct iphdr *iph;
    u32 br_ip;

    netmode_skb_header_revert(skb);
   
    if(skb->protocol == ETH_P_PPP_SES)
    {
        skb_push(skb, skb->data - skb->mac.raw - 14);
        skb_xmit(skb);
        return NF_STOLEN;
    }
    
    if(ETH_P_IP != skb->protocol || 0 != br_get_ip(skb, &br_ip))
    {
		goto BR_CONTINUE;
    }

    if(0 == br_ip)
    {
        if(skb->dev->priv_flags & IFF_802_1Q_VLAN)
        {
            skb = conplat_vlan_skb_recv_put_tag(skb, VLAN_DEV_INFO(skb->dev)->vlan_id);
        }
        
        skb_xmit(skb);
        return NF_STOLEN;
    }

    iph = skb->nh.iph;

    if (likely(iph->saddr != br_ip && iph->daddr != br_ip
        && (u32)WEBAUTH_SERVER_ADDR_U32 != iph->saddr && (u32)WEBAUTH_SERVER_ADDR_U32 != iph->daddr) )
    {
        if ( skb->dev->priv_flags&IFF_802_1Q_VLAN )
        {
            skb = conplat_vlan_skb_recv_put_tag(skb, VLAN_DEV_INFO(skb->dev)->vlan_id);
        }

        skb_xmit(skb);
        return NF_STOLEN;
    }

BR_CONTINUE:
    NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,okfn,-349);

    return NF_STOLEN;
}
Пример #5
0
/* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */
int vlan_dev_set_vlan_flag(const struct net_device *dev,
			   u32 flag, short flag_val)
{
	/* verify flag is supported */
	if (flag == VLAN_FLAG_REORDER_HDR) {
		if (flag_val) {
			VLAN_DEV_INFO(dev)->flags |= VLAN_FLAG_REORDER_HDR;
		} else {
			VLAN_DEV_INFO(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
		}
		return 0;
	}
	printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag);
	return -EINVAL;
}
Пример #6
0
int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
	struct ifreq ifrr;
	int err = -EOPNOTSUPP;

	strncpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
	ifrr.ifr_ifru = ifr->ifr_ifru;

	switch(cmd) {
	case SIOCGMIIPHY:
	case SIOCGMIIREG:
	case SIOCSMIIREG:
		if (real_dev->do_ioctl && netif_device_present(real_dev)) 
			err = real_dev->do_ioctl(real_dev, &ifrr, cmd);
		break;

	case SIOCETHTOOL:
		err = dev_ethtool(&ifrr);
	}

	if (!err) 
		ifr->ifr_ifru = ifrr.ifr_ifru;

	return err;
}
Пример #7
0
int vlan_dev_open(struct net_device *dev)
{
	if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP))
		return -ENETDOWN;

	return 0;
}
Пример #8
0
int vlan_proc_add_dev (struct net_device *vlandev)
{
	struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);

	if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
		printk(KERN_ERR
		       "ERROR:	vlan_proc_add, device -:%s:- is NOT a VLAN\n",
		       vlandev->name);
		return -EINVAL;
	}

	dev_info->dent = create_proc_entry(vlandev->name,
					   S_IFREG|S_IRUSR|S_IWUSR,
					   proc_vlan_dir);
	if (!dev_info->dent)
		return -ENOBUFS;

	dev_info->dent->proc_fops = &vlandev_fops;
	dev_info->dent->data = vlandev;

#ifdef VLAN_DEBUG
	printk(KERN_ERR "vlan_proc_add, device -:%s:- being added.\n",
	       vlandev->name);
#endif
	return 0;
}
int vlan_dev_get_vid(const char *dev_name, unsigned short* result)
{
	struct net_device *dev = dev_get_by_name(dev_name);
	int rv = 0;
	
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			*result = VLAN_DEV_INFO(dev)->vlan_id;
			dev_put(dev);
			rv = 0;
		} else {
			/*printk(KERN_ERR 
			       "%s: %s is not a vlan device, priv_flags: %hX.\n",
			       __FUNCTION__, dev->name, dev->priv_flags);*/
			dev_put(dev);
			rv = -EINVAL;
		}
	} else {
		/* printk(KERN_ERR	 "%s: Could not find device: %s\n", 
		   __FUNCTION__, dev_name);*/
		rv = -ENODEV;
	}

	return rv;
}
Пример #10
0
/* Cleanup all vlan devices
 * Note: devices that have been registered that but not
 * brought up will exist but have no module ref count.
 */
static void __exit vlan_cleanup_devices(void)
{
	struct net_device *dev, *nxt;

	rtnl_lock();
	for (dev = dev_base; dev; dev = nxt) {
		nxt = dev->next;
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
					    VLAN_DEV_INFO(dev)->vlan_id);

			unregister_netdevice(dev);
		}
	}
	rtnl_unlock();
}
Пример #11
0
static int vlandev_seq_show(struct seq_file *seq, void *offset)
{
	struct net_device *vlandev = (struct net_device *) seq->private;
	const struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
	struct net_device_stats *stats;
	static const char fmt[] = "%30s %12lu\n";
	static const char fmt_bytes[] = "%30s %20llu\n";
	static const char fmt_pkt[] = "%30s %16llu\n";
	int i;

	if (!(vlandev->priv_flags & IFF_802_1Q_VLAN))
		return 0;

	seq_printf(seq, "%s  VID: %d	 REORDER_HDR: %i  dev->priv_flags: %hx\n",
		       vlandev->name, dev_info->vlan_id,
		       (int)(dev_info->flags & 1), vlandev->priv_flags);


	stats = vlan_dev_get_stats(vlandev);

	seq_printf(seq, fmt_pkt, "total frames received", stats->rx_packets);
	seq_printf(seq, fmt_bytes, "total bytes received", stats->rx_bytes);
	seq_printf(seq, fmt, "Broadcast/Multicast Rcvd", stats->multicast);
	seq_puts(seq, "\n");
	seq_printf(seq, fmt_pkt, "total frames transmitted", stats->tx_packets);
	seq_printf(seq, fmt_bytes, "total bytes transmitted", stats->tx_bytes);
	seq_printf(seq, fmt, "total headroom inc",
		   dev_info->cnt_inc_headroom_on_tx);
	seq_printf(seq, fmt, "total encap on xmit",
		   dev_info->cnt_encap_on_xmit);
	seq_printf(seq, "Device: %s", dev_info->real_dev->name);
	/* now show all PRIORITY mappings relating to this VLAN */
	seq_printf(seq,
		       "\nINGRESS priority mappings: 0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
		       dev_info->ingress_priority_map[0],
		       dev_info->ingress_priority_map[1],
		       dev_info->ingress_priority_map[2],
		       dev_info->ingress_priority_map[3],
		       dev_info->ingress_priority_map[4],
		       dev_info->ingress_priority_map[5],
		       dev_info->ingress_priority_map[6],
		       dev_info->ingress_priority_map[7]);

	seq_printf(seq, "EGRESSS priority Mappings: ");
	for (i = 0; i < 16; i++) {
		const struct vlan_priority_tci_mapping *mp
			= dev_info->egress_priority_map[i];
		while (mp) {
			seq_printf(seq, "%u:%hu ",
				   mp->priority, ((mp->vlan_qos >> 13) & 0x7));
			mp = mp->next;
		}
	}
	seq_puts(seq, "\n");

	return 0;
}
Пример #12
0
int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_device_stats *stats = vlan_dev_get_stats(dev);
	struct vlan_skb_tx_cookie *cookie;

	stats->tx_packets++;
	stats->tx_bytes += skb->len;

	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
	cookie = VLAN_TX_SKB_CB(skb);
	cookie->magic = VLAN_TX_COOKIE_MAGIC;
	cookie->vlan_tag = (VLAN_DEV_INFO(dev)->vlan_id |
			    vlan_dev_get_egress_qos_mask(dev, skb));

	dev_queue_xmit(skb);

	return 0;
}
Пример #13
0
void vlan_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);
}
Пример #14
0
int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
{
	/* TODO: gotta make sure the underlying layer can handle it,
	 * maybe an IFF_VLAN_CAPABLE flag for devices?
	 */
	if (VLAN_DEV_INFO(dev)->real_dev->mtu < new_mtu)
		return -ERANGE;

	dev->mtu = new_mtu;

	return 0;
}
Пример #15
0
static void vlan_flush_mc_list(struct net_device *dev)
{
	struct dev_mc_list *dmi = dev->mc_list;

	while (dmi) {
		printk(KERN_DEBUG "%s: del %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address from vlan interface\n",
		       dev->name,
		       dmi->dmi_addr[0],
		       dmi->dmi_addr[1],
		       dmi->dmi_addr[2],
		       dmi->dmi_addr[3],
		       dmi->dmi_addr[4],
		       dmi->dmi_addr[5]);
		dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
		dmi = dev->mc_list;
	}

	/* dev->mc_list is NULL by the time we get here. */
	vlan_destroy_mc_list(VLAN_DEV_INFO(dev)->old_mc_list);
	VLAN_DEV_INFO(dev)->old_mc_list = NULL;
}
Пример #16
0
void vlan_dev_set_ingress_priority(const struct net_device *dev,
				   u32 skb_prio, short vlan_prio)
{
	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);

	if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
		vlan->nr_ingress_mappings--;
	else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio)
		vlan->nr_ingress_mappings++;

	vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
}
Пример #17
0
void vlan_dev_destruct(struct net_device *dev)
{
	if (dev) {
		vlan_flush_mc_list(dev);
		if (dev->priv) {
			if (VLAN_DEV_INFO(dev)->dent)
				BUG();

			kfree(dev->priv);
			dev->priv = NULL;
		}
	}
}
Пример #18
0
static int unregister_vlan_device(const char *vlan_IF_name)
{
	struct net_device *dev = NULL;
	int ret;


	dev = dev_get_by_name(vlan_IF_name);
	ret = -EINVAL;
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			rtnl_lock();

			ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
						  VLAN_DEV_INFO(dev)->vlan_id);

			dev_put(dev);
			unregister_netdevice(dev);

			rtnl_unlock();

			if (ret == 1)
				ret = 0;
		} else {
			printk(VLAN_ERR 
			       "%s: ERROR:	Tried to remove a non-vlan device "
			       "with VLAN code, name: %s  priv_flags: %hX\n",
			       __FUNCTION__, dev->name, dev->priv_flags);
			dev_put(dev);
			ret = -EPERM;
		}
	} else {
#ifdef VLAN_DEBUG
		printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
#endif
		ret = -EINVAL;
	}

	return ret;
}
Пример #19
0
int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
{
	struct net_device *dev = dev_get_by_name(dev_name);
	struct vlan_priority_tci_mapping *mp = NULL;
	struct vlan_priority_tci_mapping *np;
   
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			/* See if a priority mapping exists.. */
			mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
			while (mp) {
				if (mp->priority == skb_prio) {
					mp->vlan_qos = ((vlan_prio << 13) & 0xE000);
					dev_put(dev);
					return 0;
				}
				mp = mp->next;
			}

			/* Create a new mapping then. */
			mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
			np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
			if (np) {
				np->next = mp;
				np->priority = skb_prio;
				np->vlan_qos = ((vlan_prio << 13) & 0xE000);
				VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
				dev_put(dev);
				return 0;
			} else {
				dev_put(dev);
				return -ENOBUFS;
			}
		}
		dev_put(dev);
	}
	return -EINVAL;
}
Пример #20
0
static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
{
	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
		skb = skb_share_check(skb, GFP_ATOMIC);
		if (skb) {
			/* Lifted from Gleb's VLAN code... */
			memmove(skb->data - ETH_HLEN,
				skb->data - VLAN_ETH_HLEN, 12);
			skb->mac.raw += VLAN_HLEN;
		}
	}

	return skb;
}
Пример #21
0
int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_device_stats *stats = vlan_dev_get_stats(dev);
	unsigned short veth_TCI;

	/* Construct the second two bytes. This field looks something
	 * like:
	 * usr_priority: 3 bits	 (high bits)
	 * CFI		 1 bit
	 * VLAN ID	 12 bits (low bits)
	 */
	veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
	veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
	skb = __vlan_hwaccel_put_tag(skb, veth_TCI);

	stats->tx_packets++;
	stats->tx_bytes += skb->len;

	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
	dev_queue_xmit(skb);

	return 0;
}
Пример #22
0
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;
}
Пример #23
0
int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
{
	struct net_device *dev = dev_get_by_name(dev_name);

	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			/* see if a priority mapping exists.. */
			VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
			dev_put(dev);
			return 0;
		}

		dev_put(dev);
	}
	return -EINVAL;
}
Пример #24
0
static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev,
							  struct sk_buff* skb)
{
	struct vlan_priority_tci_mapping *mp =
		VLAN_DEV_INFO(dev)->egress_priority_map[(skb->priority & 0xF)];

	while (mp) {
		if (mp->priority == skb->priority) {
			return mp->vlan_qos; /* This should already be shifted to mask
					      * correctly with the VLAN's TCI
					      */
		}
		mp = mp->next;
	}
	return 0;
}
Пример #25
0
int vlan_dev_get_vid(const char *dev_name, unsigned short* result)
{
	struct net_device *dev = dev_get_by_name(dev_name);
	int rv = 0;
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			*result = VLAN_DEV_INFO(dev)->vlan_id;
			rv = 0;
		} else {
			rv = -EINVAL;
		}
		dev_put(dev);
	} else {
		rv = -ENODEV;
	}
	return rv;
}
Пример #26
0
int vlan_dev_get_realdev_name(const char *dev_name, char* result)
{
	struct net_device *dev = dev_get_by_name(dev_name);
	int rv = 0;
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
			rv = 0;
		} else {
			rv = -EINVAL;
		}
		dev_put(dev);
	} else {
		rv = -ENODEV;
	}
	return rv;
}
Пример #27
0
static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
{
	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
		if (skb_shared(skb) || skb_cloned(skb)) {
			struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
			kfree_skb(skb);
			skb = nskb;
		}
		if (skb) {
			/* Lifted from Gleb's VLAN code... */
			memmove(skb->data - ETH_HLEN,
				skb->data - VLAN_ETH_HLEN, 12);
			skb->mac_header += VLAN_HLEN;
		}
	}

	return skb;
}
Пример #28
0
static int vlan_dev_init(struct net_device *dev)
{
	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;

	/* IFF_BROADCAST|IFF_MULTICAST; ??? */
	dev->flags  = real_dev->flags & ~IFF_UP;
	dev->iflink = real_dev->ifindex;
	dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
					  (1<<__LINK_STATE_DORMANT))) |
		      (1<<__LINK_STATE_PRESENT);

	/* TODO: maybe just assign it to be ETHERNET? */
	dev->type = real_dev->type;

#if defined (CONFIG_RAETH_TSO)
#if defined(CONFIG_RALINK_MT7620)
	if( (*(volatile u32 *)(0xB000000C) & 0xf) >= 0x5) {
		dev->features = real_dev->features;
	}
#else
	/* make pseudo interface has same capacity like real interface */
	dev->features = real_dev->features;
#endif
#endif
	memcpy(dev->broadcast, real_dev->broadcast, real_dev->addr_len);
	memcpy(dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
	dev->addr_len = real_dev->addr_len;

	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
		dev->hard_header     = real_dev->hard_header;
		dev->hard_header_len = real_dev->hard_header_len;
		dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
		dev->rebuild_header  = real_dev->rebuild_header;
	} else {
		dev->hard_header     = vlan_dev_hard_header;
		dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
		dev->hard_start_xmit = vlan_dev_hard_start_xmit;
		dev->rebuild_header  = vlan_dev_rebuild_header;
	}
	dev->hard_header_parse = real_dev->hard_header_parse;

	lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
	return 0;
}
Пример #29
0
struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
			     struct net_device *dev)
{
	struct l2t_entry *e;
	struct l2t_data *d = L2DATA(cdev);
	u32 addr = *(u32 *) neigh->primary_key;
	int ifidx = neigh->dev->ifindex;
	int hash = arp_hash(addr, ifidx, d);
	struct port_info *p = netdev_priv(dev);
	int smt_idx = p->port_id;

	write_lock_bh(&d->lock);
	for (e = d->l2tab[hash].first; e; e = e->next)
		if (e->addr == addr && e->ifindex == ifidx &&
		    e->smt_idx == smt_idx) {
			l2t_hold(d, e);
			if (atomic_read(&e->refcnt) == 1)
				reuse_entry(e, neigh);
			goto done;
		}

	/* Need to allocate a new entry */
	e = alloc_l2e(d);
	if (e) {
		spin_lock(&e->lock);	/* avoid race with t3_l2t_free */
		e->next = d->l2tab[hash].first;
		d->l2tab[hash].first = e;
		e->state = L2T_STATE_RESOLVING;
		e->addr = addr;
		e->ifindex = ifidx;
		e->smt_idx = smt_idx;
		atomic_set(&e->refcnt, 1);
		neigh_replace(e, neigh);
		if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
			e->vlan = VLAN_DEV_INFO(neigh->dev)->vlan_id;
		else
			e->vlan = VLAN_NONE;
		spin_unlock(&e->lock);
	}
done:
	write_unlock_bh(&d->lock);
	return e;
}
Пример #30
0
static int vlan_seq_show(struct seq_file *seq, void *v)
{
	if (v == SEQ_START_TOKEN) {
		const char *nmtype = NULL;

		seq_puts(seq, "VLAN Dev name	 | VLAN ID\n");

		if (vlan_name_type < ARRAY_SIZE(vlan_name_type_str))
		    nmtype =  vlan_name_type_str[vlan_name_type];

		seq_printf(seq, "Name-Type: %s\n", 
			   nmtype ? nmtype :  "UNKNOWN" );
	} else {
		const struct net_device *vlandev = v;
		const struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);

		seq_printf(seq, "%-15s| %d  | %s\n",  vlandev->name,  
			   dev_info->vlan_id,    dev_info->real_dev->name);
	}
	return 0;
}