-/*
+/* -*- linux-c -*-
* INET 802.1Q VLAN
* Ethernet-type device handling.
*
default:
printk(VLAN_DBG
"%s: unable to resolve type %X addresses.\n",
- dev->name, (int)veth->h_vlan_encapsulated_proto);
+ dev->name, ntohs(veth->h_vlan_encapsulated_proto));
memcpy(veth->h_source, dev->dev_addr, ETH_ALEN);
break;
*
*/
int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type* ptype)
+ struct packet_type* ptype, struct net_device *orig_dev)
{
unsigned char *rawp = NULL;
struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data);
unsigned short vid;
struct net_device_stats *stats;
unsigned short vlan_TCI;
- unsigned short proto;
+ __be16 proto;
/* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
vlan_TCI = ntohs(vhdr->h_vlan_TCI);
stats->rx_packets++;
stats->rx_bytes += skb->len;
- skb_pull(skb, VLAN_HLEN); /* take off the VLAN header (4 bytes currently) */
+ /* Take off the VLAN header (4 bytes currently) */
+ skb_pull_rcsum(skb, VLAN_HLEN);
/* Ok, lets check to make sure the device (dev) we
* came in on is what this VLAN is attached to.
* This allows the VLAN to have a different MAC than the underlying
* device, and still route correctly.
*/
- if (memcmp(eth_hdr(skb)->h_dest, skb->dev->dev_addr, ETH_ALEN) == 0) {
+ if (!compare_ether_addr(eth_hdr(skb)->h_dest, skb->dev->dev_addr)) {
/* It is for our (changed) MAC-address! */
skb->pkt_type = PACKET_HOST;
}
} else {
vhdr->h_vlan_encapsulated_proto = htons(len);
}
+
+ skb->protocol = htons(ETH_P_8021Q);
+ skb->nh.raw = skb->data;
}
/* Before delegating work to the lower layer, enter our MAC-address */
dev->mtu = new_mtu;
- return new_mtu;
+ return 0;
}
int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
return -EINVAL;
}
+
+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;
+}
+
+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;
+}
+
+
int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
{
struct sockaddr *addr = (struct sockaddr *)(addr_struct_p);