提交 89da1ecf 编写于 作者: S Samuel Ortiz 提交者: David S. Miller

[IrDA]: Netlink layer.

First IrDA configuration netlink layer implementation.
Currently, we only support the set/get mode commands.
Signed-off-by: NSamuel Ortiz <samuel@sortiz.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 8c644623
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -216,6 +216,33 @@ struct if_irda_req {
#define ifr_dtr ifr_ifru.ifru_line.dtr
#define ifr_rts ifr_ifru.ifru_line.rts
/* IrDA netlink definitions */
#define IRDA_NL_NAME "irda"
#define IRDA_NL_VERSION 1
enum irda_nl_commands {
IRDA_NL_CMD_UNSPEC,
IRDA_NL_CMD_SET_MODE,
IRDA_NL_CMD_GET_MODE,
__IRDA_NL_CMD_AFTER_LAST
};
#define IRDA_NL_CMD_MAX (__IRDA_NL_CMD_AFTER_LAST - 1)
enum nl80211_attrs {
IRDA_NL_ATTR_UNSPEC,
IRDA_NL_ATTR_IFNAME,
IRDA_NL_ATTR_MODE,
__IRDA_NL_ATTR_AFTER_LAST
};
#define IRDA_NL_ATTR_MAX (__IRDA_NL_ATTR_AFTER_LAST - 1)
/* IrDA modes */
#define IRDA_MODE_PRIMARY 0x1
#define IRDA_MODE_SECONDARY 0x2
#endif /* KERNEL_IRDA_H */
......
......@@ -125,6 +125,9 @@ extern void irda_sysctl_unregister(void);
extern int irsock_init(void);
extern void irsock_cleanup(void);
extern int irda_nl_register(void);
extern void irda_nl_unregister(void);
extern int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev);
......
......@@ -208,6 +208,8 @@ struct irlap_cb {
int xbofs_delay; /* Nr of XBOF's used to MTT */
int bofs_count; /* Negotiated extra BOFs */
int next_bofs; /* Negotiated extra BOFs after next frame */
int mode; /* IrLAP mode (primary, secondary or monitor) */
};
/*
......
......@@ -10,6 +10,6 @@ obj-$(CONFIG_IRCOMM) += ircomm/
irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \
irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \
irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \
discovery.o parameters.o irmod.o
discovery.o parameters.o irnetlink.o irmod.o
irda-$(CONFIG_PROC_FS) += irproc.o
irda-$(CONFIG_SYSCTL) += irsysctl.o
......@@ -88,16 +88,23 @@ EXPORT_SYMBOL(irda_notify_init);
*/
static int __init irda_init(void)
{
int ret = 0;
IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
/* Lower layer of the stack */
irlmp_init();
irlap_init();
/* Driver/dongle support */
irda_device_init();
/* Higher layers of the stack */
iriap_init();
irttp_init();
irsock_init();
ret = irsock_init();
if (ret < 0)
goto out_err_1;
/* Add IrDA packet type (Start receiving packets) */
dev_add_pack(&irda_packet_type);
......@@ -107,13 +114,44 @@ static int __init irda_init(void)
irda_proc_register();
#endif
#ifdef CONFIG_SYSCTL
irda_sysctl_register();
ret = irda_sysctl_register();
if (ret < 0)
goto out_err_2;
#endif
/* Driver/dongle support */
irda_device_init();
ret = irda_nl_register();
if (ret < 0)
goto out_err_3;
return 0;
out_err_3:
#ifdef CONFIG_SYSCTL
irda_sysctl_unregister();
#endif
out_err_2:
#ifdef CONFIG_PROC_FS
irda_proc_unregister();
#endif
/* Remove IrDA packet type (stop receiving packets) */
dev_remove_pack(&irda_packet_type);
/* Remove higher layers */
irsock_cleanup();
out_err_1:
irttp_cleanup();
iriap_cleanup();
/* Remove lower layers */
irda_device_cleanup();
irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
/* Remove middle layer */
irlmp_cleanup();
return ret;
}
/*
......@@ -125,6 +163,8 @@ static int __init irda_init(void)
static void __exit irda_cleanup(void)
{
/* Remove External APIs */
irda_nl_unregister();
#ifdef CONFIG_SYSCTL
irda_sysctl_unregister();
#endif
......
/*
* IrDA netlink layer, for stack configuration.
*
* Copyright (c) 2007 Samuel Ortiz <samuel@sortiz>
*
* Partly based on the 802.11 nelink implementation
* (see net/wireless/nl80211.c) which is:
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/socket.h>
#include <linux/irda.h>
#include <net/sock.h>
#include <net/irda/irda.h>
#include <net/irda/irlap.h>
#include <net/genetlink.h>
static struct genl_family irda_nl_family = {
.id = GENL_ID_GENERATE,
.name = IRDA_NL_NAME,
.hdrsize = 0,
.version = IRDA_NL_VERSION,
.maxattr = IRDA_NL_CMD_MAX,
};
static struct net_device * ifname_to_netdev(struct genl_info *info)
{
char * ifname;
if (!info->attrs[IRDA_NL_ATTR_IFNAME])
return NULL;
ifname = nla_data(info->attrs[IRDA_NL_ATTR_IFNAME]);
IRDA_DEBUG(5, "%s(): Looking for %s\n", __FUNCTION__, ifname);
return dev_get_by_name(ifname);
}
static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info)
{
struct net_device * dev;
struct irlap_cb * irlap;
u32 mode;
if (!info->attrs[IRDA_NL_ATTR_MODE])
return -EINVAL;
mode = nla_get_u32(info->attrs[IRDA_NL_ATTR_MODE]);
IRDA_DEBUG(5, "%s(): Switching to mode: %d\n", __FUNCTION__, mode);
dev = ifname_to_netdev(info);
if (!dev)
return -ENODEV;
irlap = (struct irlap_cb *)dev->atalk_ptr;
if (!irlap) {
dev_put(dev);
return -ENODEV;
}
irlap->mode = mode;
dev_put(dev);
return 0;
}
static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
{
struct net_device * dev;
struct irlap_cb * irlap;
struct sk_buff *msg;
void *hdr;
int ret = -ENOBUFS;
dev = ifname_to_netdev(info);
if (!dev)
return -ENODEV;
msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg) {
dev_put(dev);
return -ENOMEM;
}
irlap = (struct irlap_cb *)dev->atalk_ptr;
if (!irlap) {
ret = -ENODEV;
goto err_out;
}
hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
&irda_nl_family, 0, IRDA_NL_CMD_GET_MODE);
if (IS_ERR(hdr)) {
ret = PTR_ERR(hdr);
goto err_out;
}
if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
dev->name));
goto err_out;
if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
goto err_out;
genlmsg_end(msg, hdr);
return genlmsg_unicast(msg, info->snd_pid);
err_out:
nlmsg_free(msg);
dev_put(dev);
return ret;
}
static struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
[IRDA_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING,
.len = IFNAMSIZ-1 },
[IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
};
static struct genl_ops irda_nl_ops[] = {
{
.cmd = IRDA_NL_CMD_SET_MODE,
.doit = irda_nl_set_mode,
.policy = irda_nl_policy,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = IRDA_NL_CMD_GET_MODE,
.doit = irda_nl_get_mode,
.policy = irda_nl_policy,
/* can be retrieved by unprivileged users */
},
};
int irda_nl_register(void)
{
int err, i;
err = genl_register_family(&irda_nl_family);
if (err)
return err;
for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) {
err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]);
if (err)
goto err_out;
}
return 0;
err_out:
genl_unregister_family(&irda_nl_family);
return err;
}
void irda_nl_unregister(void)
{
genl_unregister_family(&irda_nl_family);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部