summaryrefslogtreecommitdiff
path: root/drivers/ipoe/ipoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ipoe/ipoe.c')
-rw-r--r--drivers/ipoe/ipoe.c410
1 files changed, 1 insertions, 409 deletions
diff --git a/drivers/ipoe/ipoe.c b/drivers/ipoe/ipoe.c
index 3fc266e6..d7de5e62 100644
--- a/drivers/ipoe/ipoe.c
+++ b/drivers/ipoe/ipoe.c
@@ -103,22 +103,6 @@ struct ipoe_entry_u {
unsigned long tstamp;
};
-struct vlan_dev {
- unsigned int magic;
- int ifindex;
- struct rcu_head rcu_head;
- struct list_head entry;
-
- spinlock_t lock;
- unsigned long vid[4096/8/sizeof(long)];
-};
-
-struct vlan_notify {
- struct list_head entry;
- int ifindex;
- int vid;
-};
-
static struct list_head ipoe_list[HASH_BITS + 1];
static struct list_head ipoe_list1_u[HASH_BITS + 1];
static struct list_head ipoe_excl_list[HASH_BITS + 1];
@@ -130,11 +114,6 @@ static LIST_HEAD(ipoe_interfaces);
static struct work_struct ipoe_queue_work;
static struct sk_buff_head ipoe_queue;
-static LIST_HEAD(vlan_devices);
-static LIST_HEAD(vlan_notifies);
-static DEFINE_SPINLOCK(vlan_lock);
-static struct work_struct vlan_notify_work;
-
static void ipoe_start_queue_work(unsigned long);
static DEFINE_TIMER(ipoe_timer_u, ipoe_start_queue_work, 0, 0);
@@ -194,10 +173,6 @@ static void ipoe_kfree_rcu(struct rcu_head *head)
}
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
-#define vlan_tx_tag_present(skb) skb_vlan_tag_present(skb)
-#endif
-
static int ipoe_check_network(__be32 addr)
{
struct ipoe_network *n;
@@ -937,143 +912,6 @@ static unsigned int ipt_out_hook(const struct nf_hook_ops *ops, struct sk_buff *
return NF_ACCEPT;
}
-static int vlan_pt_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *prev, struct net_device *orig_dev)
-{
- struct vlan_dev *d;
- struct vlan_notify *n;
- int vid;
-
- if (!dev->ml_priv)
- goto out;
-
- if (!vlan_tx_tag_present(skb))
- goto out;
-
- rcu_read_lock();
-
- d = rcu_dereference(dev->ml_priv);
- if (!d || d->magic != IPOE_MAGIC2 || d->ifindex != dev->ifindex) {
- rcu_read_unlock();
- goto out;
- }
-
- vid = skb->vlan_tci & VLAN_VID_MASK;
- //pr_info("vid %i\n", vid);
-
- if (d->vid[vid / (8*sizeof(long))] & (1lu << (vid % (8*sizeof(long)))))
- vid = -1;
- else {
- spin_lock(&d->lock);
- d->vid[vid / (8*sizeof(long))] |= 1lu << (vid % (8*sizeof(long)));
- spin_unlock(&d->lock);
- }
- rcu_read_unlock();
-
- if (vid == -1)
- goto out;
-
- //pr_info("queue %i %i\n", dev->ifindex, vid);
-
- n = kmalloc(sizeof(*n), GFP_ATOMIC);
- if (!n)
- goto out;
-
- n->ifindex = dev->ifindex;
- n->vid = vid;
-
- spin_lock(&vlan_lock);
- list_add_tail(&n->entry, &vlan_notifies);
- spin_unlock(&vlan_lock);
-
- schedule_work(&vlan_notify_work);
-
-out:
- kfree_skb(skb);
- return 0;
-}
-
-static void vlan_do_notify(struct work_struct *w)
-{
- struct vlan_notify *n;
- struct sk_buff *report_skb = NULL;
- 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);
- 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);
-
- if (!n)
- break;
-
- if (!report_skb) {
- report_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
- header = genlmsg_put(report_skb, 0, ipoe_nl_mcg.id, &ipoe_nl_family, 0, IPOE_VLAN_NOTIFY);
-#else
- header = genlmsg_put(report_skb, 0, ipoe_nl_family.mcgrp_offset, &ipoe_nl_family, 0, IPOE_VLAN_NOTIFY);
-#endif
- }
-
- //pr_info("notify %i vlan %i\n", id, n->vid);
-
- ns = nla_nest_start(report_skb, id++);
- if (!ns)
- goto nl_err;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
- if (nla_put_u32(report_skb, IPOE_ATTR_IFINDEX, n->ifindex))
-#else
- if (nla_put_u32(report_skb, IPOE_ATTR_IFINDEX, n->ifindex))
-#endif
- goto nl_err;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
- if (nla_put_u32(report_skb, IPOE_ATTR_ADDR, n->vid))
-#else
- if (nla_put_u32(report_skb, IPOE_ATTR_ADDR, n->vid))
-#endif
- goto nl_err;
-
- if (nla_nest_end(report_skb, ns) >= IPOE_NLMSG_SIZE) {
- genlmsg_end(report_skb, header);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
- genlmsg_multicast(report_skb, 0, ipoe_nl_mcg.id, GFP_KERNEL);
-#else
- genlmsg_multicast(&ipoe_nl_family, report_skb, 0, 0, GFP_KERNEL);
-#endif
- report_skb = NULL;
- id = 1;
- }
-
- kfree(n);
- continue;
-
-nl_err:
- nlmsg_free(report_skb);
- report_skb = NULL;
- }
-
- if (report_skb) {
- genlmsg_end(report_skb, header);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
- genlmsg_multicast(report_skb, 0, ipoe_nl_mcg.id, GFP_KERNEL);
-#else
- genlmsg_multicast(&ipoe_nl_family, report_skb, 0, 0, GFP_KERNEL);
-#endif
- }
-}
-
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
static struct rtnl_link_stats64 *ipoe_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
@@ -1806,195 +1644,6 @@ static int ipoe_nl_cmd_del_interface(struct sk_buff *skb, struct genl_info *info
return 0;
}
-static int ipoe_nl_cmd_add_vlan_mon(struct sk_buff *skb, struct genl_info *info)
-{
- struct vlan_dev *d;
- struct net_device *dev;
- int ifindex, i;
-
- if (!info->attrs[IPOE_ATTR_IFINDEX])
- return -EINVAL;
-
- ifindex = nla_get_u32(info->attrs[IPOE_ATTR_IFINDEX]);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- rtnl_lock();
- dev = __dev_get_by_index(&init_net, ifindex);
- rtnl_unlock();
-#else
- dev = dev_get_by_index(&init_net, ifindex);
-#endif
-
- if (!dev)
- return -ENODEV;
-
- down(&ipoe_wlock);
- if (dev->ml_priv) {
- up(&ipoe_wlock);
- dev_put(dev);
- return -EBUSY;
- }
-
- d = kzalloc(sizeof(*d), GFP_KERNEL);
- if (!d) {
- up(&ipoe_wlock);
- dev_put(dev);
- return -ENOMEM;
- }
-
- d->magic = IPOE_MAGIC2;
- d->ifindex = ifindex;
- spin_lock_init(&d->lock);
-
- if (info->attrs[IPOE_ATTR_VLAN_MASK]) {
- memcpy(d->vid, nla_data(info->attrs[IPOE_ATTR_VLAN_MASK]), min((int)nla_len(info->attrs[IPOE_ATTR_VLAN_MASK]), (int)sizeof(d->vid)));
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- if (dev->features & NETIF_F_HW_VLAN_FILTER) {
- rtnl_lock();
- for (i = 1; i < 4096; i++) {
- if (!(d->vid[i / (8*sizeof(long))] & (1lu << (i % (8*sizeof(long))))))
- dev->netdev_ops->ndo_vlan_rx_add_vid(dev, i);
- }
- rtnl_unlock();
- }
-#else
- if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
- rtnl_lock();
- for (i = 1; i < 4096; i++) {
- if (!(d->vid[i / (8*sizeof(long))] & (1lu << (i % (8*sizeof(long))))))
- dev->netdev_ops->ndo_vlan_rx_add_vid(dev, htons(ETH_P_8021Q), i);
- }
- rtnl_unlock();
- }
-#endif
- }
-
- rcu_assign_pointer(dev->ml_priv, d);
-
- list_add_tail_rcu(&d->entry, &vlan_devices);
- up(&ipoe_wlock);
-
- dev_put(dev);
-
- return 0;
-}
-
-static int ipoe_nl_cmd_add_vlan_mon_vid(struct sk_buff *skb, struct genl_info *info)
-{
- struct vlan_dev *d;
- int ifindex, vid;
- struct net_device *dev;
- unsigned long flags;
-
- if (!info->attrs[IPOE_ATTR_IFINDEX] || !info->attrs[IPOE_ATTR_ADDR])
- return -EINVAL;
-
- ifindex = nla_get_u32(info->attrs[IPOE_ATTR_IFINDEX]);
- vid = nla_get_u32(info->attrs[IPOE_ATTR_ADDR]);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- rtnl_lock();
- dev = __dev_get_by_index(&init_net, ifindex);
- rtnl_unlock();
-#else
- dev = dev_get_by_index(&init_net, ifindex);
-#endif
-
- if (!dev)
- return -ENODEV;
-
- down(&ipoe_wlock);
-
- if (!dev->ml_priv) {
- up(&ipoe_wlock);
- dev_put(dev);
- return -EINVAL;
- }
-
- d = dev->ml_priv;
-
- spin_lock_irqsave(&d->lock, flags);
- d->vid[vid / (8*sizeof(long))] &= ~(1lu << (vid % (8*sizeof(long))));
- spin_unlock_irqrestore(&d->lock, flags);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- if (dev->features & NETIF_F_HW_VLAN_FILTER) {
- rtnl_lock();
- dev->netdev_ops->ndo_vlan_rx_add_vid(dev, vid);
- rtnl_unlock();
- }
-#else
- if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
- rtnl_lock();
- dev->netdev_ops->ndo_vlan_rx_add_vid(dev, htons(ETH_P_8021Q), vid);
- rtnl_unlock();
- }
-#endif
-
- up(&ipoe_wlock);
-
- dev_put(dev);
-
- return 0;
-}
-
-static int ipoe_nl_cmd_del_vlan_mon(struct sk_buff *skb, struct genl_info *info)
-{
- struct vlan_dev *d;
- struct vlan_notify *vn;
- int ifindex;
- unsigned long flags;
- struct list_head *pos, *n;
- struct net_device *dev;
-
- if (info->attrs[IPOE_ATTR_IFINDEX])
- ifindex = nla_get_u32(info->attrs[IPOE_ATTR_IFINDEX]);
- else
- ifindex = -1;
-
- down(&ipoe_wlock);
- list_for_each_entry(d, &vlan_devices, entry) {
- if (ifindex == -1 || d->ifindex == ifindex) {
- //pr_info("del net %08x/%08x\n", n->addr, n->mask);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- rtnl_lock();
- dev = __dev_get_by_index(&init_net, d->ifindex);
- rtnl_unlock();
-#else
- dev = dev_get_by_index(&init_net, d->ifindex);
-#endif
-
- if (dev) {
- if (dev->ml_priv == d)
- rcu_assign_pointer(dev->ml_priv, NULL);
- dev_put(dev);
- }
-
- list_del_rcu(&d->entry);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
- kfree_rcu(d, rcu_head);
-#else
- call_rcu(&d->rcu_head, ipoe_kfree_rcu);
-#endif
- }
- }
- up(&ipoe_wlock);
-
- spin_lock_irqsave(&vlan_lock, flags);
- list_for_each_safe(pos, n, &vlan_notifies) {
- vn = list_entry(pos, typeof(*vn), entry);
- if (ifindex == -1 || vn->ifindex == ifindex) {
- list_del(&vn->entry);
- kfree(vn);
- }
- }
- spin_unlock_irqrestore(&vlan_lock, flags);
-
- return 0;
-}
-
-
-
static struct nla_policy ipoe_nl_policy[IPOE_ATTR_MAX + 1] = {
[IPOE_ATTR_NONE] = { .type = NLA_UNSPEC, },
[IPOE_ATTR_ADDR] = { .type = NLA_U32, },
@@ -2003,7 +1652,6 @@ static struct nla_policy ipoe_nl_policy[IPOE_ATTR_MAX + 1] = {
[IPOE_ATTR_HWADDR] = { .type = NLA_U64 },
[IPOE_ATTR_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
[IPOE_ATTR_MASK] = { .type = NLA_U32, },
- [IPOE_ATTR_VLAN_MASK] = { .type = NLA_BINARY, .len = 4096/8 },
};
static struct genl_ops ipoe_nl_ops[] = {
@@ -2061,24 +1709,6 @@ static struct genl_ops ipoe_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
},
{
- .cmd = IPOE_CMD_ADD_VLAN_MON,
- .doit = ipoe_nl_cmd_add_vlan_mon,
- .policy = ipoe_nl_policy,
- .flags = GENL_ADMIN_PERM,
- },
- {
- .cmd = IPOE_CMD_ADD_VLAN_MON_VID,
- .doit = ipoe_nl_cmd_add_vlan_mon_vid,
- .policy = ipoe_nl_policy,
- .flags = GENL_ADMIN_PERM,
- },
- {
- .cmd = IPOE_CMD_DEL_VLAN_MON,
- .doit = ipoe_nl_cmd_del_vlan_mon,
- .policy = ipoe_nl_policy,
- .flags = GENL_ADMIN_PERM,
- },
- {
.cmd = IPOE_CMD_ADD_EXCLUDE,
.doit = ipoe_nl_cmd_add_exclude,
.policy = ipoe_nl_policy,
@@ -2134,11 +1764,6 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
},
};
-static struct packet_type vlan_pt __read_mostly = {
- .type = __constant_htons(ETH_P_ALL),
- .func = vlan_pt_recv,
-};
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
static const struct net_device_ops ipoe_netdev_ops = {
.ndo_start_xmit = ipoe_xmit,
@@ -2159,7 +1784,7 @@ static int __init ipoe_init(void)
{
int err, i;
- printk("IPoE session driver v1.9.0\n");
+ printk("IPoE session driver v1.10-rc1\n");
/*err = register_pernet_device(&ipoe_net_ops);
if (err < 0)
@@ -2173,8 +1798,6 @@ static int __init ipoe_init(void)
skb_queue_head_init(&ipoe_queue);
INIT_WORK(&ipoe_queue_work, ipoe_process_queue);
- INIT_WORK(&vlan_notify_work, vlan_do_notify);
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
err = genl_register_family(&ipoe_nl_family);
if (err < 0) {
@@ -2218,8 +1841,6 @@ static int __init ipoe_init(void)
goto out_unreg;
}
- dev_add_pack(&vlan_pt);
-
return 0;
out_unreg:
@@ -2233,12 +1854,8 @@ static void __exit ipoe_fini(void)
struct ipoe_network *n;
struct ipoe_entry_u *e;
struct ipoe_session *ses;
- struct vlan_dev *d;
- struct vlan_notify *vn;
- struct net_device *dev;
int i;
- dev_remove_pack(&vlan_pt);
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
@@ -2281,31 +1898,6 @@ static void __exit ipoe_fini(void)
kfree(e);
}
- while (!list_empty(&vlan_devices)) {
- d = list_first_entry(&vlan_devices, typeof(*d), entry);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- rtnl_lock();
- dev = __dev_get_by_index(&init_net, d->ifindex);
- rtnl_unlock();
-#else
- dev = dev_get_by_index(&init_net, d->ifindex);
-#endif
- if (dev)
- rcu_assign_pointer(dev->ml_priv, NULL);
- list_del(&d->entry);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
- kfree_rcu(d, rcu_head);
-#else
- call_rcu(&d->rcu_head, ipoe_kfree_rcu);
-#endif
- }
-
- while (!list_empty(&vlan_notifies)) {
- vn = list_first_entry(&vlan_notifies, typeof(*vn), entry);
- list_del(&vn->entry);
- kfree(vn);
- }
-
clean_excl_list();
synchronize_rcu();