diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2016-03-17 22:24:19 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-03-17 22:24:26 +0300 |
commit | cc9e2a49061b2a77a51e27ed23c8040626a2083b (patch) | |
tree | a906d60e21d789d9d7a88825ada70be0622ecca4 /drivers | |
parent | ea7f988b40c03a21571143be30200f77450f3ba4 (diff) | |
download | accel-ppp-cc9e2a49061b2a77a51e27ed23c8040626a2083b.tar.gz accel-ppp-cc9e2a49061b2a77a51e27ed23c8040626a2083b.zip |
vlan_mon,ipoe,pppoe: implemented detection of vlan existance
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/vlan_mon/vlan_mon.c | 34 | ||||
-rw-r--r-- | drivers/vlan_mon/vlan_mon.h | 1 |
2 files changed, 25 insertions, 10 deletions
diff --git a/drivers/vlan_mon/vlan_mon.c b/drivers/vlan_mon/vlan_mon.c index 2037495a..f88dda3d 100644 --- a/drivers/vlan_mon/vlan_mon.c +++ b/drivers/vlan_mon/vlan_mon.c @@ -53,6 +53,7 @@ struct vlan_dev { struct vlan_notify { struct list_head entry; int ifindex; + int vlan_ifindex; int vid; int proto; }; @@ -85,6 +86,7 @@ static int vlan_pt_recv(struct sk_buff *skb, struct net_device *dev, struct pack struct vlan_dev *d; struct vlan_notify *n; int vid; + int vlan_ifindex = 0; int proto; if (!dev->ml_priv) @@ -120,6 +122,19 @@ static int vlan_pt_recv(struct sk_buff *skb, struct net_device *dev, struct pack d->vid[proto][vid / (8*sizeof(long))] |= 1lu << (vid % (8*sizeof(long))); spin_unlock(&d->lock); } + + if (vid > 0) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) + struct net_device *vd = __vlan_find_dev_deep(dev, vid); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0) + struct net_device *vd = __vlan_find_dev_deep(dev, skb->vlan_proto, vid); +#else + struct net_device *vd = __vlan_find_dev_deep_rcu(dev, skb->vlan_proto, vid); +#endif + if (vd) + vlan_ifindex = vd->ifindex; + } + rcu_read_unlock(); if (vid == -1) @@ -132,6 +147,7 @@ static int vlan_pt_recv(struct sk_buff *skb, struct net_device *dev, struct pack goto out; n->ifindex = dev->ifindex; + n->vlan_ifindex = vlan_ifindex; n->vid = vid; n->proto = ntohs(skb->protocol); @@ -153,19 +169,18 @@ static void vlan_do_notify(struct work_struct *w) void *header = NULL; struct nlattr *ns; int id = 1; - unsigned long flags; //pr_info("vlan_do_notify\n"); while (1) { - spin_lock_irqsave(&vlan_lock, flags); + spin_lock_bh(&vlan_lock); if (list_empty(&vlan_notifies)) n = NULL; else { n = list_first_entry(&vlan_notifies, typeof(*n), entry); list_del(&n->entry); } - spin_unlock_irqrestore(&vlan_lock, flags); + spin_unlock_bh(&vlan_lock); if (!n) break; @@ -188,6 +203,9 @@ static void vlan_do_notify(struct work_struct *w) if (nla_put_u32(report_skb, VLAN_MON_ATTR_IFINDEX, n->ifindex)) goto nl_err; + if (n->vlan_ifindex && nla_put_u32(report_skb, VLAN_MON_ATTR_VLAN_IFINDEX, n->vlan_ifindex)) + goto nl_err; + if (nla_put_u16(report_skb, VLAN_MON_ATTR_VID, n->vid)) goto nl_err; @@ -350,7 +368,6 @@ static int vlan_mon_nl_cmd_add_vlan_mon_vid(struct sk_buff *skb, struct genl_inf struct vlan_dev *d; int ifindex, vid, proto; struct net_device *dev; - unsigned long flags; if (!info->attrs[VLAN_MON_ATTR_IFINDEX] || !info->attrs[VLAN_MON_ATTR_VID] || !info->attrs[VLAN_MON_ATTR_PROTO]) return -EINVAL; @@ -359,8 +376,6 @@ static int vlan_mon_nl_cmd_add_vlan_mon_vid(struct sk_buff *skb, struct genl_inf vid = nla_get_u16(info->attrs[VLAN_MON_ATTR_VID]); proto = nla_get_u16(info->attrs[VLAN_MON_ATTR_PROTO]); - proto = nla_get_u16(info->attrs[VLAN_MON_ATTR_PROTO]); - proto = vlan_mon_proto(proto); if (proto < 0) return proto; @@ -380,9 +395,9 @@ static int vlan_mon_nl_cmd_add_vlan_mon_vid(struct sk_buff *skb, struct genl_inf d = dev->ml_priv; - spin_lock_irqsave(&d->lock, flags); + spin_lock_bh(&d->lock); d->vid[proto][vid / (8*sizeof(long))] &= ~(1lu << (vid % (8*sizeof(long)))); - spin_unlock_irqrestore(&d->lock, flags); + spin_unlock_bh(&d->lock); #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) if (dev->features & NETIF_F_HW_VLAN_FILTER) { rtnl_lock(); @@ -536,8 +551,7 @@ static int __init vlan_mon_init(void) int i; #endif - - printk("vlan-mon driver v1.10-rc1\n"); + printk("vlan-mon driver v1.11\n"); INIT_WORK(&vlan_notify_work, vlan_do_notify); diff --git a/drivers/vlan_mon/vlan_mon.h b/drivers/vlan_mon/vlan_mon.h index e65f65ee..ff5c8523 100644 --- a/drivers/vlan_mon/vlan_mon.h +++ b/drivers/vlan_mon/vlan_mon.h @@ -20,6 +20,7 @@ enum { VLAN_MON_ATTR_PROTO, /* u32 */ VLAN_MON_ATTR_IFINDEX, /* u32 */ VLAN_MON_ATTR_VID, /* u32 */ + VLAN_MON_ATTR_VLAN_IFINDEX, /* u32 */ __VLAN_MON_ATTR_MAX, }; |