Fix minor bug.
Add draft of ac kernel module.
This commit is contained in:
13
src/ac/kmod/Makefile
Normal file
13
src/ac/kmod/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
KVERSION = $(shell uname -r)
|
||||
|
||||
obj-m += smartcapwap.o
|
||||
|
||||
smartcapwap-y := \
|
||||
main.o \
|
||||
netlinkapp.o
|
||||
|
||||
all:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" clean
|
24
src/ac/kmod/main.c
Normal file
24
src/ac/kmod/main.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "netlinkapp.h"
|
||||
|
||||
/* */
|
||||
static int __init smartcapwap_ac_init(void) {
|
||||
int result = 0;
|
||||
|
||||
/* */
|
||||
result = nlsmartcapwap_ac_init();
|
||||
|
||||
return result;
|
||||
}
|
||||
module_init(smartcapwap_ac_init);
|
||||
|
||||
/* */
|
||||
static void __exit smartcapwap_ac_exit(void) {
|
||||
nlsmartcapwap_ac_exit();
|
||||
}
|
||||
module_exit(smartcapwap_ac_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
|
||||
MODULE_DESCRIPTION("SmartCAPWAP AC Data Channel Module");
|
158
src/ac/kmod/netlinkapp.c
Normal file
158
src/ac/kmod/netlinkapp.c
Normal file
@ -0,0 +1,158 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/err.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include "nlsmartcapwap.h"
|
||||
#include "netlinkapp.h"
|
||||
|
||||
/* */
|
||||
struct nlsmartcapwap_ac_device {
|
||||
struct list_head list;
|
||||
|
||||
u32 usermodeid;
|
||||
};
|
||||
|
||||
/* */
|
||||
static u32 nlsmartcapwap_ac_usermodeid = 0;
|
||||
static LIST_HEAD(nlsmartcapwap_ac_dev_list);
|
||||
|
||||
/* Netlink Family */
|
||||
static struct genl_family nlsmartcapwap_ac_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
.name = SMARTCAPWAP_AC_GENL_NAME,
|
||||
.hdrsize = 0,
|
||||
.version = 1,
|
||||
.maxattr = NLSMARTCAPWAP_AC_ATTR_MAX,
|
||||
.netnsok = true,
|
||||
};
|
||||
|
||||
/* */
|
||||
static void nlsmartcapwap_ac_free_device(struct nlsmartcapwap_ac_device* nldev) {
|
||||
/* Free memory */
|
||||
kfree(nldev);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nlsmartcapwap_ac_close(void) {
|
||||
struct nlsmartcapwap_ac_device* nldev;
|
||||
struct nlsmartcapwap_ac_device* tmp;
|
||||
|
||||
list_for_each_entry_safe(nldev, tmp, &nlsmartcapwap_ac_dev_list, list) {
|
||||
list_del(&nldev->list);
|
||||
|
||||
/* Free device */
|
||||
nlsmartcapwap_ac_free_device(nldev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
static int nlsmartcapwap_ac_link(struct sk_buff* skb, struct genl_info* info) {
|
||||
int ret = 0;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
|
||||
u32 portid = info->snd_pid;
|
||||
#else
|
||||
u32 portid = info->snd_portid;
|
||||
#endif
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (!nlsmartcapwap_ac_usermodeid) {
|
||||
nlsmartcapwap_ac_usermodeid = portid;
|
||||
} else if (nlsmartcapwap_ac_usermodeid == portid) {
|
||||
ret = -EALREADY;
|
||||
} else {
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nlsmartcapwap_ac_netlink_notify(struct notifier_block* nb, unsigned long state, void* _notify) {
|
||||
struct netlink_notify* notify = (struct netlink_notify*)_notify;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
|
||||
u32 portid = notify->pid;
|
||||
#else
|
||||
u32 portid = notify->portid;
|
||||
#endif
|
||||
|
||||
/* */
|
||||
if (state == NETLINK_URELEASE) {
|
||||
rtnl_lock();
|
||||
|
||||
if (nlsmartcapwap_ac_usermodeid == portid) {
|
||||
nlsmartcapwap_ac_usermodeid = 0;
|
||||
|
||||
/* Close all devices */
|
||||
nlsmartcapwap_ac_close();
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/* */
|
||||
static const struct nla_policy nlsmartcapwap_ac_policy[NLSMARTCAPWAP_AC_ATTR_MAX + 1] = {
|
||||
[NLSMARTCAPWAP_AC_ATTR_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* Netlink Ops */
|
||||
static struct genl_ops nlsmartcapwap_ac_ops[] = {
|
||||
{
|
||||
.cmd = NLSMARTCAPWAP_AC_CMD_LINK,
|
||||
.doit = nlsmartcapwap_ac_link,
|
||||
.policy = nlsmartcapwap_ac_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
};
|
||||
|
||||
/* Netlink notify */
|
||||
static struct notifier_block nlsmartcapwap_ac_netlink_notifier = {
|
||||
.notifier_call = nlsmartcapwap_ac_netlink_notify,
|
||||
};
|
||||
|
||||
/* */
|
||||
int nlsmartcapwap_ac_init(void) {
|
||||
int ret;
|
||||
|
||||
/* Register netlink family */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
|
||||
ret = genl_register_family_with_ops(&nlsmartcapwap_ac_family, nlsmartcapwap_ac_ops, sizeof(nlsmartcapwap_ac_ops) / sizeof(nlsmartcapwap_ac_ops[0]));
|
||||
#else
|
||||
ret = genl_register_family_with_ops(&nlsmartcapwap_ac_family, nlsmartcapwap_ac_ops);
|
||||
#endif
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Register netlink notifier */
|
||||
ret = netlink_register_notifier(&nlsmartcapwap_ac_netlink_notifier);
|
||||
if (ret) {
|
||||
genl_unregister_family(&nlsmartcapwap_ac_family);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
void nlsmartcapwap_ac_exit(void) {
|
||||
/* */
|
||||
rtnl_lock();
|
||||
nlsmartcapwap_ac_close();
|
||||
rtnl_unlock();
|
||||
|
||||
/* */
|
||||
netlink_unregister_notifier(&nlsmartcapwap_ac_netlink_notifier);
|
||||
genl_unregister_family(&nlsmartcapwap_ac_family);
|
||||
}
|
8
src/ac/kmod/netlinkapp.h
Normal file
8
src/ac/kmod/netlinkapp.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __KMOD_AC_NETLINKAPP_HEADER__
|
||||
#define __KMOD_AC_NETLINKAPP_HEADER__
|
||||
|
||||
/* */
|
||||
int nlsmartcapwap_ac_init(void);
|
||||
void nlsmartcapwap_ac_exit(void);
|
||||
|
||||
#endif /* __KMOD_AC_NETLINKAPP_HEADER__ */
|
29
src/ac/kmod/nlsmartcapwap.h
Normal file
29
src/ac/kmod/nlsmartcapwap.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __AC_NLSMARTCAPWAP_HEADER__
|
||||
#define __AC_NLSMARTCAPWAP_HEADER__
|
||||
|
||||
/* */
|
||||
#define SMARTCAPWAP_AC_GENL_NAME "smartcapwap_ac"
|
||||
|
||||
/* */
|
||||
enum nlsmartcapwap_ac_attrs {
|
||||
NLSMARTCAPWAP_AC_ATTR_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_AC_ATTR_FLAGS,
|
||||
|
||||
/* Last attribute */
|
||||
__NLSMARTCAPWAP_AC_ATTR_AFTER_LAST,
|
||||
NLSMARTCAPWAP_AC_ATTR_MAX = __NLSMARTCAPWAP_AC_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/* */
|
||||
enum nlsmartcapwap_ac_commands {
|
||||
NLSMARTCAPWAP_AC_CMD_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_AC_CMD_LINK,
|
||||
|
||||
/* Last command */
|
||||
__NLSMARTCAPWAP_AC_CMD_AFTER_LAST,
|
||||
NLSMARTCAPWAP_AC_CMD_MAX = __NLSMARTCAPWAP_AC_CMD_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
#endif /* __AC_NLSMARTCAPWAP_HEADER__ */
|
Reference in New Issue
Block a user