* Re: netfilter 02/02: xt_connlimit: fix regression caused by zero family value
From: Patrick McHardy @ 2009-11-06 14:49 UTC (permalink / raw)
To: Jan Engelhardt
Cc: David S. Miller, Netfilter Development Mailinglist,
Linux Netdev List
In-Reply-To: <alpine.LSU.2.00.0911051943130.25147@obet.zrqbmnf.qr>
Jan Engelhardt wrote:
> On Thursday 2009-11-05 19:23, Patrick McHardy wrote:
>> netfilter: xt_connlimit: fix regression caused by zero family value
>>
>> Commit v2.6.28-rc1~7172~1092~2 was slightly incomplete; not all
>> instances of par->match->family were changed to par->family.
>>
>> Netfilter bugzilla #610.
>
> Hold it.
> git would never output ~7172~1092~2 because ~8266 would be much simpler.
>
> I originally wrote "Commit v2.6.28-rc1~717^2~109^2~2", but one of your
> programs seems to eat commit messages or more.
Indeed, my email client displays ^2 as ², which cut and paste transforms
to 2 :)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next] Phonet: use rwlock for sockets list
From: Rémi Denis-Courmont @ 2009-11-06 14:29 UTC (permalink / raw)
To: ext Eric Dumazet; +Cc: netdev@vger.kernel.org
In-Reply-To: <4AF42C07.4050008@gmail.com>
On Friday 06 November 2009 16:00:39 ext Eric Dumazet, you wrote:
> Rémi Denis-Courmont a écrit :
> > It seems better than a spinlock, assuming that sockets are
> > created/destroyed more seldom than they receive packets. And then
> > sk_for_each_rcu does not exist. I am sure there is a good reason for
> > that, though I wouldn't know. I guess I should try to use RCU hlist_nulls
> > then?
>
> spin_lock()/spin_unlock() is faster than read_lock()/read_unlock(), unless
> there is contention. (two atomic ops instead of one)
>
> So, unless you have a particular performance problem, it's actually
> better to use a spinlock.
>
> If you do have performance problem, a RCU conversion is better than rwlock.
> I can do RCU conversion if you ask me...
The most obvious current bottleneck is the sockets linked-list more so than
the locking scheme (RCU vs spinlock vs rwlock). I'll fix that soonish
regardless of the locking.
Then there is the devices lists. I did not want to clutter all net_device's
with a Phonet-specific pointer, since most devices aren't Phonet-capable. So
we have a linked-list for per-device data. There, I guess RCU would make
sense, but it did not seem trivial a change at all.
That said, there are no real "problems" yet - I was just trying to improve
things. N900 ships with the 2.6.30 Phonet stack, and it works fine :) The 3G
access network is typically the biggest bottleneck anyway...
So if you say R/W locks suck, screw this patch.
Thanks!
--
Rémi Denis-Courmont
Nokia Devices R&D, Maemo Software, Helsinki
^ permalink raw reply
* Re: [PATCH 1/2] udp: cleanup __udp4_lib_mcast_deliver
From: Lucian Adrian Grijincu @ 2009-11-06 14:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, opurdila
In-Reply-To: <20091106.004215.114490979.davem@davemloft.net>
În data de Vin 06 Noi 2009 10:42:15 David Miller a scris:
> Getting rid of the useless return value is fine, but the
> new do{}while() loop et al. is less readable to me.
It's not new.
I just moved it:
previously:
if(cond) {
do {}
while()
} else {return}
now:
if (!cond)
return;
do {}
while {}
Also this moves a consume_skb() from a path protected by spin locks.
As far as I understand it, the spin locks protect the hslot, and freeing the
skb does not walk/change or interact with the hslot in any way.
--
Lucian
^ permalink raw reply
* Re: [PATCH net-next] Phonet: use rwlock for sockets list
From: Eric Dumazet @ 2009-11-06 14:00 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev, Rémi Denis-Courmont
In-Reply-To: <65081524fbfeb975c842ebc79a8fb038@chewa.net>
Rémi Denis-Courmont a écrit :
> It seems better than a spinlock, assuming that sockets are
> created/destroyed more seldom than they receive packets. And then
> sk_for_each_rcu does not exist. I am sure there is a good reason for that,
> though I wouldn't know. I guess I should try to use RCU hlist_nulls then?
>
spin_lock()/spin_unlock() is faster than read_lock()/read_unlock(), unless
there is contention. (two atomic ops instead of one)
So, unless you have a particular performance problem, it's actually
better to use a spinlock.
If you do have performance problem, a RCU conversion is better than rwlock.
I can do RCU conversion if you ask me...
^ permalink raw reply
* [PATCH, WTF] atm: move all compat_ioctl handling to atm/ioctl.c
From: Arnd Bergmann @ 2009-11-06 14:00 UTC (permalink / raw)
To: David Woodhouse; +Cc: David Miller, LKML, netdev, Eric Dumazet
For some interesting historic reasons that are not at all clear to me,
we seem to have two implementations of the ATM ioctl compatibility
layer in the kernel, and we use a combination of the two.
For ioctl numbers that have the same identifier on 32 and 64 bit systems,
we go directly through the compat_ioctl socket operation, for those that
differ, we do a conversion in fs/compat_ioctl.c.
This patch moves both variants into the vcc_compat_ioctl() function, while
preserving the current behaviour. It also kills off the COMPATIBLE_IOCTL
definitions that we never use here.
Doing it this way is clearly not a good solution, but I hope it is a
step into the right direction, so that someone is able to clean up this
mess for real.
Found while trying to untangle the compat socket ioctl mess
in fs/compat_ioctl.c.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
fs/compat_ioctl.c | 205 -----------------------------------------------------
net/atm/ioctl.c | 172 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 171 insertions(+), 206 deletions(-)
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index f91fd51..8b78b5f 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1212,170 +1212,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a
return err;
}
-struct atmif_sioc32 {
- compat_int_t number;
- compat_int_t length;
- compat_caddr_t arg;
-};
-
-struct atm_iobuf32 {
- compat_int_t length;
- compat_caddr_t buffer;
-};
-
-#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
-#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
-#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
-#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
-#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
-#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
-#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
-#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
-#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
-#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
-#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
-#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
-#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
-#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
-#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
-#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
-#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} atm_ioctl_map[] = {
- { ATM_GETLINKRATE32, ATM_GETLINKRATE },
- { ATM_GETNAMES32, ATM_GETNAMES },
- { ATM_GETTYPE32, ATM_GETTYPE },
- { ATM_GETESI32, ATM_GETESI },
- { ATM_GETADDR32, ATM_GETADDR },
- { ATM_RSTADDR32, ATM_RSTADDR },
- { ATM_ADDADDR32, ATM_ADDADDR },
- { ATM_DELADDR32, ATM_DELADDR },
- { ATM_GETCIRANGE32, ATM_GETCIRANGE },
- { ATM_SETCIRANGE32, ATM_SETCIRANGE },
- { ATM_SETESI32, ATM_SETESI },
- { ATM_SETESIF32, ATM_SETESIF },
- { ATM_GETSTAT32, ATM_GETSTAT },
- { ATM_GETSTATZ32, ATM_GETSTATZ },
- { ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP },
- { ATM_QUERYLOOP32, ATM_QUERYLOOP }
-};
-
-#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
-
-static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atm_iobuf __user *iobuf;
- struct atm_iobuf32 __user *iobuf32;
- u32 data;
- void __user *datap;
- int len, err;
-
- iobuf = compat_alloc_user_space(sizeof(*iobuf));
- iobuf32 = compat_ptr(arg);
-
- if (get_user(len, &iobuf32->length) ||
- get_user(data, &iobuf32->buffer))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(len, &iobuf->length) ||
- put_user(datap, &iobuf->buffer))
- return -EFAULT;
-
- err = sys_ioctl(fd, cmd, (unsigned long)iobuf);
-
- if (!err) {
- if (copy_in_user(&iobuf32->length, &iobuf->length,
- sizeof(int)))
- err = -EFAULT;
- }
-
- return err;
-}
-
-static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atmif_sioc __user *sioc;
- struct atmif_sioc32 __user *sioc32;
- u32 data;
- void __user *datap;
- int err;
-
- sioc = compat_alloc_user_space(sizeof(*sioc));
- sioc32 = compat_ptr(arg);
-
- if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
- get_user(data, &sioc32->arg))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(datap, &sioc->arg))
- return -EFAULT;
-
- err = sys_ioctl(fd, cmd, (unsigned long) sioc);
-
- if (!err) {
- if (copy_in_user(&sioc32->length, &sioc->length,
- sizeof(int)))
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
-{
- int i;
- unsigned int cmd = 0;
-
- switch (cmd32) {
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atmif_sioc(fd, cmd32, arg);
- }
-
- for (i = 0; i < NR_ATM_IOCTL; i++) {
- if (cmd32 == atm_ioctl_map[i].cmd32) {
- cmd = atm_ioctl_map[i].cmd;
- break;
- }
- }
- if (i == NR_ATM_IOCTL)
- return -EINVAL;
-
- switch (cmd) {
- case ATM_GETNAMES:
- return do_atm_iobuf(fd, cmd, arg);
-
- case ATM_GETLINKRATE:
- case ATM_GETTYPE:
- case ATM_GETESI:
- case ATM_GETADDR:
- case ATM_RSTADDR:
- case ATM_ADDADDR:
- case ATM_DELADDR:
- case ATM_GETCIRANGE:
- case ATM_SETCIRANGE:
- case ATM_SETESI:
- case ATM_SETESIF:
- case ATM_GETSTAT:
- case ATM_GETSTATZ:
- case ATM_GETLOOP:
- case ATM_SETLOOP:
- case ATM_QUERYLOOP:
- return do_atmif_sioc(fd, cmd, arg);
- }
-
- return -EINVAL;
-}
-
static __used int
ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
{
@@ -2311,22 +2147,6 @@ COMPATIBLE_IOCTL(RAW_SETBIND)
COMPATIBLE_IOCTL(RAW_GETBIND)
/* SMB ioctls which do not need any translations */
COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* Little a */
-COMPATIBLE_IOCTL(ATMSIGD_CTRL)
-COMPATIBLE_IOCTL(ATMARPD_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_MCAST)
-COMPATIBLE_IOCTL(ATMLEC_DATA)
-COMPATIBLE_IOCTL(ATM_SETSC)
-COMPATIBLE_IOCTL(SIOCSIFATMTCP)
-COMPATIBLE_IOCTL(SIOCMKCLIP)
-COMPATIBLE_IOCTL(ATMARP_MKIP)
-COMPATIBLE_IOCTL(ATMARP_SETENTRY)
-COMPATIBLE_IOCTL(ATMARP_ENCAP)
-COMPATIBLE_IOCTL(ATMTCP_CREATE)
-COMPATIBLE_IOCTL(ATMTCP_REMOVE)
-COMPATIBLE_IOCTL(ATMMPC_CTRL)
-COMPATIBLE_IOCTL(ATMMPC_DATA)
/* Watchdog */
COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
@@ -2613,31 +2433,6 @@ HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
/* One SMB ioctl needs translations. */
#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
-HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
/* block stuff */
#ifdef CONFIG_BLOCK
/* loop */
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4da8892..163547d 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -191,8 +191,178 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
#ifdef CONFIG_COMPAT
+struct atmif_sioc32 {
+ compat_int_t number;
+ compat_int_t length;
+ compat_caddr_t arg;
+};
+
+struct atm_iobuf32 {
+ compat_int_t length;
+ compat_caddr_t buffer;
+};
+
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
+#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
+#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
+#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
+#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
+#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
+#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
+#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
+#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
+#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
+#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
+#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
+#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
+#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
+#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
+#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
+
+static struct {
+ unsigned int cmd32;
+ unsigned int cmd;
+} atm_ioctl_map[] = {
+ { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+ { ATM_GETNAMES32, ATM_GETNAMES },
+ { ATM_GETTYPE32, ATM_GETTYPE },
+ { ATM_GETESI32, ATM_GETESI },
+ { ATM_GETADDR32, ATM_GETADDR },
+ { ATM_RSTADDR32, ATM_RSTADDR },
+ { ATM_ADDADDR32, ATM_ADDADDR },
+ { ATM_DELADDR32, ATM_DELADDR },
+ { ATM_GETCIRANGE32, ATM_GETCIRANGE },
+ { ATM_SETCIRANGE32, ATM_SETCIRANGE },
+ { ATM_SETESI32, ATM_SETESI },
+ { ATM_SETESIF32, ATM_SETESIF },
+ { ATM_GETSTAT32, ATM_GETSTAT },
+ { ATM_GETSTATZ32, ATM_GETSTATZ },
+ { ATM_GETLOOP32, ATM_GETLOOP },
+ { ATM_SETLOOP32, ATM_SETLOOP },
+ { ATM_QUERYLOOP32, ATM_QUERYLOOP }
+};
+
+#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
+
+static int do_atm_iobuf(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ struct atm_iobuf __user *iobuf;
+ struct atm_iobuf32 __user *iobuf32;
+ u32 data;
+ void __user *datap;
+ int len, err;
+
+ iobuf = compat_alloc_user_space(sizeof(*iobuf));
+ iobuf32 = compat_ptr(arg);
+
+ if (get_user(len, &iobuf32->length) ||
+ get_user(data, &iobuf32->buffer))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(len, &iobuf->length) ||
+ put_user(datap, &iobuf->buffer))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long)iobuf, 0);
+
+ if (!err) {
+ if (copy_in_user(&iobuf32->length, &iobuf->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+
+ return err;
+}
+
+static int do_atmif_sioc(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ struct atmif_sioc __user *sioc;
+ struct atmif_sioc32 __user *sioc32;
+ u32 data;
+ void __user *datap;
+ int err;
+
+ sioc = compat_alloc_user_space(sizeof(*sioc));
+ sioc32 = compat_ptr(arg);
+
+ if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
+ get_user(data, &sioc32->arg))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(datap, &sioc->arg))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long) sioc, 0);
+
+ if (!err) {
+ if (copy_in_user(&sioc32->length, &sioc->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int do_atm_ioctl(struct socket *sock, unsigned int cmd32, unsigned long arg)
+{
+ int i;
+ unsigned int cmd = 0;
+
+ switch (cmd32) {
+ case SONET_GETSTAT:
+ case SONET_GETSTATZ:
+ case SONET_GETDIAG:
+ case SONET_SETDIAG:
+ case SONET_CLRDIAG:
+ case SONET_SETFRAMING:
+ case SONET_GETFRAMING:
+ case SONET_GETFRSENSE:
+ return do_atmif_sioc(sock, cmd32, arg);
+ }
+
+ for (i = 0; i < NR_ATM_IOCTL; i++) {
+ if (cmd32 == atm_ioctl_map[i].cmd32) {
+ cmd = atm_ioctl_map[i].cmd;
+ break;
+ }
+ }
+ if (i == NR_ATM_IOCTL)
+ return -EINVAL;
+
+ switch (cmd) {
+ case ATM_GETNAMES:
+ return do_atm_iobuf(sock, cmd, arg);
+
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+ case ATM_GETADDR:
+ case ATM_RSTADDR:
+ case ATM_ADDADDR:
+ case ATM_DELADDR:
+ case ATM_GETCIRANGE:
+ case ATM_SETCIRANGE:
+ case ATM_SETESI:
+ case ATM_SETESIF:
+ case ATM_GETSTAT:
+ case ATM_GETSTATZ:
+ case ATM_GETLOOP:
+ case ATM_SETLOOP:
+ case ATM_QUERYLOOP:
+ return do_atmif_sioc(sock, cmd, arg);
+ }
+
+ return -EINVAL;
+}
+
int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
- return do_vcc_ioctl(sock, cmd, arg, 1);
+ int ret;
+
+ ret = do_vcc_ioctl(sock, cmd, arg, 1);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+
+ return do_atm_ioctl(sock, cmd, arg);
}
#endif
^ permalink raw reply related
* Re: [PATCH net-next] Phonet: use rwlock for sockets list
From: Rémi Denis-Courmont @ 2009-11-06 13:54 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, Rémi Denis-Courmont
In-Reply-To: <4AF42834.7010707@gmail.com>
On Fri, 06 Nov 2009 14:44:20 +0100, Eric Dumazet <eric.dumazet@gmail.com>
wrote:
> Rémi Denis-Courmont a écrit :
>> From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
>>
>> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
>> ---
>> net/phonet/socket.c | 24 ++++++++++++------------
>> 1 files changed, 12 insertions(+), 12 deletions(-)
>
> Hmm... rwlocks are bad...
They're in many places throughout the non-IP families...
> Would you care to explain why you introduce a rwlock ?
It seems better than a spinlock, assuming that sockets are
created/destroyed more seldom than they receive packets. And then
sk_for_each_rcu does not exist. I am sure there is a good reason for that,
though I wouldn't know. I guess I should try to use RCU hlist_nulls then?
--
Rémi Denis-Courmont
^ permalink raw reply
* Re: [PATCH net-next] Phonet: use rwlock for sockets list
From: Eric Dumazet @ 2009-11-06 13:44 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev, Rémi Denis-Courmont
In-Reply-To: <1257514891-18917-1-git-send-email-remi@remlab.net>
Rémi Denis-Courmont a écrit :
> From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> ---
> net/phonet/socket.c | 24 ++++++++++++------------
> 1 files changed, 12 insertions(+), 12 deletions(-)
Hmm... rwlocks are bad...
Would you care to explain why you introduce a rwlock ?
Thanks
^ permalink raw reply
* [PATCH net-next] Phonet: use rwlock for sockets list
From: Rémi Denis-Courmont @ 2009-11-06 13:41 UTC (permalink / raw)
To: netdev; +Cc: Rémi Denis-Courmont
From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
net/phonet/socket.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 0412beb..ecb5f20 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -47,10 +47,10 @@ static int pn_socket_release(struct socket *sock)
static struct {
struct hlist_head hlist;
- spinlock_t lock;
+ rwlock_t lock;
} pnsocks = {
.hlist = HLIST_HEAD_INIT,
- .lock = __SPIN_LOCK_UNLOCKED(pnsocks.lock),
+ .lock = __RW_LOCK_UNLOCKED(pnsocks.lock),
};
/*
@@ -65,7 +65,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
u16 obj = pn_sockaddr_get_object(spn);
u8 res = spn->spn_resource;
- spin_lock_bh(&pnsocks.lock);
+ read_lock_bh(&pnsocks.lock);
sk_for_each(sknode, node, &pnsocks.hlist) {
struct pn_sock *pn = pn_sk(sknode);
@@ -91,7 +91,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
break;
}
- spin_unlock_bh(&pnsocks.lock);
+ read_unlock_bh(&pnsocks.lock);
return rval;
}
@@ -102,7 +102,7 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
struct hlist_node *node;
struct sock *sknode;
- spin_lock(&pnsocks.lock);
+ read_lock(&pnsocks.lock);
sk_for_each(sknode, node, &pnsocks.hlist) {
struct sk_buff *clone;
@@ -117,22 +117,22 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
sk_receive_skb(sknode, clone, 0);
}
}
- spin_unlock(&pnsocks.lock);
+ read_unlock(&pnsocks.lock);
}
void pn_sock_hash(struct sock *sk)
{
- spin_lock_bh(&pnsocks.lock);
+ write_lock_bh(&pnsocks.lock);
sk_add_node(sk, &pnsocks.hlist);
- spin_unlock_bh(&pnsocks.lock);
+ write_unlock_bh(&pnsocks.lock);
}
EXPORT_SYMBOL(pn_sock_hash);
void pn_sock_unhash(struct sock *sk)
{
- spin_lock_bh(&pnsocks.lock);
+ write_lock_bh(&pnsocks.lock);
sk_del_node_init(sk);
- spin_unlock_bh(&pnsocks.lock);
+ write_unlock_bh(&pnsocks.lock);
}
EXPORT_SYMBOL(pn_sock_unhash);
@@ -466,7 +466,7 @@ static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(pnsocks.lock)
{
- spin_lock_bh(&pnsocks.lock);
+ read_lock_bh(&pnsocks.lock);
return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
}
@@ -485,7 +485,7 @@ static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void pn_sock_seq_stop(struct seq_file *seq, void *v)
__releases(pnsocks.lock)
{
- spin_unlock_bh(&pnsocks.lock);
+ read_unlock_bh(&pnsocks.lock);
}
static int pn_sock_seq_show(struct seq_file *seq, void *v)
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH 2.6.33/1 00/12] WiMAX patches for 2.6.33 (batch #1)
From: David Miller @ 2009-11-06 13:23 UTC (permalink / raw)
To: inaky; +Cc: netdev, wimax
In-Reply-To: <1257445051.3263.12.camel@localhost.localdomain>
From: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Date: Thu, 05 Nov 2009 10:17:31 -0800
> So this pull should be against:
>
> REPO git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git
> BRANCH linux-2.6.33.y
This looks a lot better, pulled and pushed back out to net-next-2.6
Thanks.
^ permalink raw reply
* [PATCH 17/17] ieee802154: add support for creation/removal of logic interfaces
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add support for two more NL802154 commands: ADD_IFACE and DEL_IFACE,
thus allowing creation and removal of logic WPAN interfaces on the top
of wpan-phy.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/linux/nl802154.h | 2 +
include/net/wpan-phy.h | 4 +
net/ieee802154/nl-phy.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 162 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index 275fd94..33d9f51 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -118,6 +118,8 @@ enum {
IEEE802154_LIST_IFACE,
IEEE802154_LIST_PHY,
+ IEEE802154_ADD_IFACE,
+ IEEE802154_DEL_IFACE,
__IEEE802154_CMD_MAX,
};
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index a65e985..8592623 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -41,6 +41,10 @@ struct wpan_phy {
struct device dev;
int idx;
+ struct net_device *(*add_iface)(struct wpan_phy *phy,
+ const char *name);
+ void (*del_iface)(struct wpan_phy *phy, struct net_device *dev);
+
char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index b7af722..199a2d9 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -26,6 +26,9 @@
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/wpan-phy.h>
+#include <net/af_ieee802154.h>
+#include <net/ieee802154_netdev.h>
+#include <net/rtnetlink.h> /* for rtnl_{un,}lock */
#include <linux/nl802154.h>
#include "ieee802154.h"
@@ -164,9 +167,162 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
return skb->len;
}
+static int ieee802154_add_iface(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ const char *devname;
+ int rc = -ENOBUFS;
+ struct net_device *dev;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+
+ if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
+ devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]);
+ if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1]
+ != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+ } else {
+ devname = "wpan%d";
+ }
+
+ if (strlen(devname) >= IFNAMSIZ)
+ return -ENAMETOOLONG;
+
+ phy = wpan_phy_find(name);
+ if (!phy)
+ return -ENODEV;
+
+ msg = ieee802154_nl_new_reply(info, 0, IEEE802154_ADD_IFACE);
+ if (!msg)
+ goto out_dev;
+
+ if (!phy->add_iface) {
+ rc = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ dev = phy->add_iface(phy, devname);
+ if (IS_ERR(dev)) {
+ rc = PTR_ERR(dev);
+ goto nla_put_failure;
+ }
+
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+
+ dev_put(dev);
+
+ wpan_phy_put(phy);
+
+ return ieee802154_nl_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ return rc;
+}
+
+static int ieee802154_del_iface(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ int rc;
+ struct net_device *dev;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_DEV_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0')
+ return -EINVAL; /* name should be null-terminated */
+
+ dev = dev_get_by_name(genl_info_net(info), name);
+ if (!dev)
+ return -ENODEV;
+
+ phy = ieee802154_mlme_ops(dev)->get_phy(dev);
+ BUG_ON(!phy);
+
+ rc = -EINVAL;
+ /* phy name is optional, but should be checked if it's given */
+ if (info->attrs[IEEE802154_ATTR_PHY_NAME]) {
+ struct wpan_phy *phy2;
+
+ const char *pname =
+ nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (pname[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1]
+ != '\0')
+ /* name should be null-terminated */
+ goto out_dev;
+
+ phy2 = wpan_phy_find(pname);
+ if (!phy2)
+ goto out_dev;
+
+ if (phy != phy2) {
+ wpan_phy_put(phy2);
+ goto out_dev;
+ }
+ }
+
+ rc = -ENOBUFS;
+
+ msg = ieee802154_nl_new_reply(info, 0, IEEE802154_DEL_IFACE);
+ if (!msg)
+ goto out_dev;
+
+ if (!phy->del_iface) {
+ rc = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ rtnl_lock();
+ phy->del_iface(phy, dev);
+
+ /* We don't have device anymore */
+ dev_put(dev);
+ dev = NULL;
+
+ rtnl_unlock();
+
+
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, name);
+
+ wpan_phy_put(phy);
+
+ return ieee802154_nl_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ if (dev)
+ dev_put(dev);
+
+ return rc;
+}
+
static struct genl_ops ieee802154_phy_ops[] = {
IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
ieee802154_dump_phy),
+ IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
+ IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
};
/*
--
1.6.5
^ permalink raw reply related
* [PATCH 16/17] ieee802154: add PHY_NAME to LIST_IFACE command results
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/nl-mac.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index e8816bf..135c167 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -33,6 +33,7 @@
#include <net/nl802154.h>
#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
+#include <net/wpan-phy.h>
#include "ieee802154.h"
@@ -251,6 +252,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
u32 seq, int flags, struct net_device *dev)
{
void *hdr;
+ struct wpan_phy *phy;
pr_debug("%s\n", __func__);
@@ -259,7 +261,11 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
if (!hdr)
goto out;
+ phy = ieee802154_mlme_ops(dev)->get_phy(dev);
+ BUG_ON(!phy);
+
NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
@@ -268,9 +274,11 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
ieee802154_mlme_ops(dev)->get_short_addr(dev));
NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
ieee802154_mlme_ops(dev)->get_pan_id(dev));
+ wpan_phy_put(phy);
return genlmsg_end(msg, hdr);
nla_put_failure:
+ wpan_phy_put(phy);
genlmsg_cancel(msg, hdr);
out:
return -EMSGSIZE;
--
1.6.5
^ permalink raw reply related
* [PATCH 15/17] ieee802154: add two nl802154 helpers
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add two nl802154 helpers: one for starting a reply message, one for sending.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/ieee802154.h | 5 +++++
net/ieee802154/netlink.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 0790eb0..aadec42 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -38,8 +38,13 @@ void __exit ieee802154_nl_exit(void);
.dumpit = _dump, \
}
+struct genl_info;
+
struct sk_buff *ieee802154_nl_create(int flags, u8 req);
int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group);
+struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
+ int flags, u8 req);
+int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
extern struct genl_family nl802154_family;
int nl802154_mac_register(void);
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 8a22173..33137b9 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -75,6 +75,39 @@ out:
return -ENOBUFS;
}
+struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
+ int flags, u8 req)
+{
+ void *hdr;
+ struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+
+ if (!msg)
+ return NULL;
+
+ hdr = genlmsg_put_reply(msg, info,
+ &nl802154_family, flags, req);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return NULL;
+ }
+
+ return msg;
+}
+
+int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
+{
+ /* XXX: nlh is right at the start of msg */
+ void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
+
+ if (genlmsg_end(msg, hdr) < 0)
+ goto out;
+
+ return genlmsg_reply(msg, info);
+out:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
int __init ieee802154_nl_init(void)
{
int rc;
--
1.6.5
^ permalink raw reply related
* [PATCH 14/17] fakehard: mlme_ops->get_phy implementation
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 38 ++++++++++++++++++++++++++++++++------
1 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 70a9f9c..f877f13 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -32,9 +32,29 @@
#include <net/nl802154.h>
#include <net/wpan-phy.h>
-static struct wpan_phy *net_to_phy(struct net_device *dev)
+struct fakehard_priv {
+ struct wpan_phy *phy;
+};
+
+static struct wpan_phy *fake_to_phy(const struct net_device *dev)
+{
+ struct fakehard_priv *priv = netdev_priv(dev);
+ return priv->phy;
+}
+
+/**
+ * fake_get_phy - Return a phy corresponding to this device.
+ * @dev: The network device for which to return the wan-phy object
+ *
+ * This function returns a wpan-phy object corresponding to the passed
+ * network device. Reference counter for wpan-phy object is incremented,
+ * so when the wpan-phy isn't necessary, you should drop the reference
+ * via @wpan_phy_put() call.
+ */
+static struct wpan_phy *fake_get_phy(const struct net_device *dev)
{
- return container_of(dev->dev.parent, struct wpan_phy, dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
+ return to_phy(get_device(&phy->dev));
}
/**
@@ -121,7 +141,7 @@ static u8 fake_get_bsn(const struct net_device *dev)
static int fake_assoc_req(struct net_device *dev,
struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
mutex_lock(&phy->pib_lock);
phy->current_channel = channel;
@@ -196,7 +216,7 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
u8 coord_realign)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
mutex_lock(&phy->pib_lock);
phy->current_channel = channel;
@@ -239,6 +259,8 @@ static struct ieee802154_mlme_ops fake_mlme = {
.start_req = fake_start_req,
.scan_req = fake_scan_req,
+ .get_phy = fake_get_phy,
+
.get_pan_id = fake_get_pan_id,
.get_short_addr = fake_get_short_addr,
.get_dsn = fake_get_dsn,
@@ -313,7 +335,7 @@ static const struct net_device_ops fake_ops = {
static void ieee802154_fake_destruct(struct net_device *dev)
{
- struct wpan_phy *phy = net_to_phy(dev);
+ struct wpan_phy *phy = fake_to_phy(dev);
wpan_phy_unregister(phy);
free_netdev(dev);
@@ -338,13 +360,14 @@ static void ieee802154_fake_setup(struct net_device *dev)
static int __devinit ieee802154fake_probe(struct platform_device *pdev)
{
struct net_device *dev;
+ struct fakehard_priv *priv;
struct wpan_phy *phy = wpan_phy_alloc(0);
int err;
if (!phy)
return -ENOMEM;
- dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+ dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup);
if (!dev) {
wpan_phy_free(phy);
return -ENOMEM;
@@ -370,6 +393,9 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->netdev_ops = &fake_ops;
dev->ml_priv = &fake_mlme;
+ priv = netdev_priv(dev);
+ priv->phy = phy;
+
/*
* If the name is a format string the caller wants us to do a
* name allocation.
--
1.6.5
^ permalink raw reply related
* [PATCH 13/17] ieee802154: add an mlme_ops call to retrieve PHY object
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
ops->get_phy should increment reference to wpan-phy. As we return
the external structure, we should do refcounting correctly.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/net/ieee802154_netdev.h | 6 ++++++
include/net/wpan-phy.h | 2 ++
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index d23fb5a..5743055 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -74,8 +74,12 @@ static inline int mac_cb_type(struct sk_buff *skb)
#define IEEE802154_MAC_SCAN_PASSIVE 2
#define IEEE802154_MAC_SCAN_ORPHAN 3
+struct wpan_phy;
/*
* This should be located at net_device->ml_priv
+ *
+ * get_phy should increment the reference counting on returned phy.
+ * Use wpan_wpy_put to put that reference.
*/
struct ieee802154_mlme_ops {
int (*assoc_req)(struct net_device *dev,
@@ -94,6 +98,8 @@ struct ieee802154_mlme_ops {
int (*scan_req)(struct net_device *dev,
u8 type, u32 channels, u8 page, u8 duration);
+ struct wpan_phy *(*get_phy)(const struct net_device *dev);
+
/*
* FIXME: these should become the part of PIB/MIB interface.
* However we still don't have IB interface of any kind
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index f63537c..a65e985 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -44,6 +44,8 @@ struct wpan_phy {
char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
+#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
+
struct wpan_phy *wpan_phy_alloc(size_t priv_size);
static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
{
--
1.6.5
^ permalink raw reply related
* [PATCH 12/17] fakehard: claim all 2.4 Ghz channels as supported
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Make fakehard device claim all 2.4 Ghz channels from 802.15.4-2006,
802.15.4a-2007 as supported by the hw.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index ccf83eb..70a9f9c 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -356,7 +356,15 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- phy->channels_supported[0] = (1 << 27) - 1;
+ /*
+ * For now we'd like to emulate 2.4 GHz-only device,
+ * both O-QPSK and CSS
+ */
+ /* 2.4 GHz O-QPSK 802.15.4-2003 */
+ phy->channels_supported[0] |= 0x7FFF800;
+ /* 2.4 GHz CSS 802.15.4a-2007 */
+ phy->channels_supported[3] |= 0x3fff;
+
phy->transmit_power = 0xbf;
dev->netdev_ops = &fake_ops;
--
1.6.5
^ permalink raw reply related
* [PATCH 11/17] fakehard: no need to export net_to_phy, make it static
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 77fbb51..ccf83eb 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -32,7 +32,7 @@
#include <net/nl802154.h>
#include <net/wpan-phy.h>
-struct wpan_phy *net_to_phy(struct net_device *dev)
+static struct wpan_phy *net_to_phy(struct net_device *dev)
{
return container_of(dev->dev.parent, struct wpan_phy, dev);
}
--
1.6.5
^ permalink raw reply related
* [PATCH 10/17] ieee802154: add LIST_PHY command support
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add nl802154 command to get information about PHY's present in
the system.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/linux/nl802154.h | 4 +
net/ieee802154/Makefile | 2 +-
net/ieee802154/netlink.c | 4 +
net/ieee802154/nl-phy.c | 188 ++++++++++++++++++++++++++++++++++++++++++++
net/ieee802154/nl_policy.c | 2 +
5 files changed, 199 insertions(+), 1 deletions(-)
create mode 100644 net/ieee802154/nl-phy.c
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index b7d9435..275fd94 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -65,6 +65,9 @@ enum {
IEEE802154_ATTR_SEC,
IEEE802154_ATTR_PAGE,
+ IEEE802154_ATTR_CHANNEL_PAGE_LIST,
+
+ IEEE802154_ATTR_PHY_NAME,
__IEEE802154_ATTR_MAX,
};
@@ -114,6 +117,7 @@ enum {
IEEE802154_RX_ENABLE_CONF, /* Not supported yet */
IEEE802154_LIST_IFACE,
+ IEEE802154_LIST_PHY,
__IEEE802154_CMD_MAX,
};
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 69af9f6..ce2d335 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
-ieee802154-y := netlink.o nl-mac.o nl_policy.o wpan-class.o
+ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 5b738ec..8a22173 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -87,6 +87,10 @@ int __init ieee802154_nl_init(void)
if (rc)
goto fail;
+ rc = nl802154_phy_register();
+ if (rc)
+ goto fail;
+
return 0;
fail:
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
new file mode 100644
index 0000000..b7af722
--- /dev/null
+++ b/net/ieee802154/nl-phy.c
@@ -0,0 +1,188 @@
+/*
+ * Netlink inteface for IEEE 802.15.4 stack
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ */
+
+#include <linux/kernel.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <net/wpan-phy.h>
+#include <linux/nl802154.h>
+
+#include "ieee802154.h"
+
+static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
+ u32 seq, int flags, struct wpan_phy *phy)
+{
+ void *hdr;
+ int i, pages = 0;
+ uint32_t *buf = kzalloc(32 * sizeof(uint32_t), GFP_KERNEL);
+
+ pr_debug("%s\n", __func__);
+
+ if (!buf)
+ goto out;
+
+ hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
+ IEEE802154_LIST_PHY);
+ if (!hdr)
+ goto out;
+
+ mutex_lock(&phy->pib_lock);
+ NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
+
+ NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, phy->current_page);
+ NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel);
+ for (i = 0; i < 32; i++) {
+ if (phy->channels_supported[i])
+ buf[pages++] = phy->channels_supported[i] | (i << 27);
+ }
+ if (pages)
+ NLA_PUT(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST,
+ pages * sizeof(uint32_t), buf);
+
+ mutex_unlock(&phy->pib_lock);
+ return genlmsg_end(msg, hdr);
+
+nla_put_failure:
+ mutex_unlock(&phy->pib_lock);
+ genlmsg_cancel(msg, hdr);
+out:
+ kfree(buf);
+ return -EMSGSIZE;
+}
+
+static int ieee802154_list_phy(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ /* Request for interface name, index, type, IEEE address,
+ PAN Id, short address */
+ struct sk_buff *msg;
+ struct wpan_phy *phy;
+ const char *name;
+ int rc = -ENOBUFS;
+
+ pr_debug("%s\n", __func__);
+
+ if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
+ if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
+ return -EINVAL; /* phy name should be null-terminated */
+
+
+ phy = wpan_phy_find(name);
+ if (!phy)
+ return -ENODEV;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ goto out_dev;
+
+ rc = ieee802154_nl_fill_phy(msg, info->snd_pid, info->snd_seq,
+ 0, phy);
+ if (rc < 0)
+ goto out_free;
+
+ wpan_phy_put(phy);
+
+ return genlmsg_reply(msg, info);
+out_free:
+ nlmsg_free(msg);
+out_dev:
+ wpan_phy_put(phy);
+ return rc;
+
+}
+
+struct dump_phy_data {
+ struct sk_buff *skb;
+ struct netlink_callback *cb;
+ int idx, s_idx;
+};
+
+static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
+{
+ int rc;
+ struct dump_phy_data *data = _data;
+
+ pr_debug("%s\n", __func__);
+
+ if (data->idx++ < data->s_idx)
+ return 0;
+
+ rc = ieee802154_nl_fill_phy(data->skb,
+ NETLINK_CB(data->cb->skb).pid,
+ data->cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ phy);
+
+ if (rc < 0) {
+ data->idx--;
+ return rc;
+ }
+
+ return 0;
+}
+
+static int ieee802154_dump_phy(struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ struct dump_phy_data data = {
+ .cb = cb,
+ .skb = skb,
+ .s_idx = cb->args[0],
+ .idx = 0,
+ };
+
+ pr_debug("%s\n", __func__);
+
+ wpan_phy_for_each(ieee802154_dump_phy_iter, &data);
+
+ cb->args[0] = data.idx;
+
+ return skb->len;
+}
+
+static struct genl_ops ieee802154_phy_ops[] = {
+ IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
+ ieee802154_dump_phy),
+};
+
+/*
+ * No need to unregister as family unregistration will do it.
+ */
+int nl802154_phy_register(void)
+{
+ int i;
+ int rc;
+
+ for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
+ rc = genl_register_ops(&nl802154_family,
+ &ieee802154_phy_ops[i]);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 2363ebe..6adda4d 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -27,6 +27,7 @@
const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
[IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
[IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
+ [IEEE802154_ATTR_PHY_NAME] = { .type = NLA_STRING, },
[IEEE802154_ATTR_STATUS] = { .type = NLA_U8, },
[IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
@@ -50,5 +51,6 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
[IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, },
[IEEE802154_ATTR_DURATION] = { .type = NLA_U8, },
[IEEE802154_ATTR_ED_LIST] = { .len = 27 },
+ [IEEE802154_ATTR_CHANNEL_PAGE_LIST] = { .len = 32 * 4, },
};
--
1.6.5
^ permalink raw reply related
* [PATCH 09/17] ieee802154: split away MAC commands implementation
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Move all mac-related stuff to separate file so that ieee802154/netlink.c
contains only generic code.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/Makefile | 2 +-
net/ieee802154/ieee802154.h | 48 +++
net/ieee802154/netlink.c | 605 +-------------------------------
net/ieee802154/{netlink.c => nl-mac.c} | 117 ++-----
4 files changed, 81 insertions(+), 691 deletions(-)
create mode 100644 net/ieee802154/ieee802154.h
copy net/ieee802154/{netlink.c => nl-mac.c} (86%)
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 42b1f0d..69af9f6 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
-ieee802154-y := netlink.o nl_policy.o wpan-class.o
+ieee802154-y := netlink.o nl-mac.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
new file mode 100644
index 0000000..0790eb0
--- /dev/null
+++ b/net/ieee802154/ieee802154.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#ifndef IEEE_802154_LOCAL_H
+#define IEEE_802154_LOCAL_H
+
+int __init ieee802154_nl_init(void);
+void __exit ieee802154_nl_exit(void);
+
+#define IEEE802154_OP(_cmd, _func) \
+ { \
+ .cmd = _cmd, \
+ .policy = ieee802154_policy, \
+ .doit = _func, \
+ .dumpit = NULL, \
+ .flags = GENL_ADMIN_PERM, \
+ }
+
+#define IEEE802154_DUMP(_cmd, _func, _dump) \
+ { \
+ .cmd = _cmd, \
+ .policy = ieee802154_policy, \
+ .doit = _func, \
+ .dumpit = _dump, \
+ }
+
+struct sk_buff *ieee802154_nl_create(int flags, u8 req);
+int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group);
+
+extern struct genl_family nl802154_family;
+int nl802154_mac_register(void);
+int nl802154_phy_register(void);
+
+#endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 0fadd6b..5b738ec 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -23,21 +23,15 @@
*/
#include <linux/kernel.h>
-#include <linux/if_arp.h>
-#include <linux/netdevice.h>
-#include <net/netlink.h>
#include <net/genetlink.h>
-#include <net/sock.h>
#include <linux/nl802154.h>
-#include <net/af_ieee802154.h>
-#include <net/nl802154.h>
-#include <net/ieee802154.h>
-#include <net/ieee802154_netdev.h>
+
+#include "ieee802154.h"
static unsigned int ieee802154_seq_num;
static DEFINE_SPINLOCK(ieee802154_seq_lock);
-static struct genl_family ieee802154_coordinator_family = {
+struct genl_family nl802154_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = IEEE802154_NL_NAME,
@@ -45,16 +39,8 @@ static struct genl_family ieee802154_coordinator_family = {
.maxattr = IEEE802154_ATTR_MAX,
};
-static struct genl_multicast_group ieee802154_coord_mcgrp = {
- .name = IEEE802154_MCAST_COORD_NAME,
-};
-
-static struct genl_multicast_group ieee802154_beacon_mcgrp = {
- .name = IEEE802154_MCAST_BEACON_NAME,
-};
-
/* Requests to userspace */
-static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
+struct sk_buff *ieee802154_nl_create(int flags, u8 req)
{
void *hdr;
struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
@@ -65,7 +51,7 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
spin_lock_irqsave(&ieee802154_seq_lock, f);
hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
- &ieee802154_coordinator_family, flags, req);
+ &nl802154_family, flags, req);
spin_unlock_irqrestore(&ieee802154_seq_lock, f);
if (!hdr) {
nlmsg_free(msg);
@@ -75,7 +61,7 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
return msg;
}
-static int ieee802154_nl_finish(struct sk_buff *msg)
+int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group)
{
/* XXX: nlh is right at the start of msg */
void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
@@ -83,602 +69,33 @@ static int ieee802154_nl_finish(struct sk_buff *msg)
if (genlmsg_end(msg, hdr) < 0)
goto out;
- return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
- GFP_ATOMIC);
+ return genlmsg_multicast(msg, 0, group, GFP_ATOMIC);
out:
nlmsg_free(msg);
return -ENOBUFS;
}
-int ieee802154_nl_assoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 cap)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- if (addr->addr_type != IEEE802154_ADDR_LONG) {
- pr_err("%s: received non-long source address!\n", __func__);
- return -EINVAL;
- }
-
- msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_assoc_indic);
-
-int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
- u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_assoc_confirm);
-
-int ieee802154_nl_disassoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 reason)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- if (addr->addr_type == IEEE802154_ADDR_LONG)
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
- else
- NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
- addr->short_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_disassoc_indic);
-
-int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm);
-
-int ieee802154_nl_beacon_indic(struct net_device *dev,
- u16 panid, u16 coord_addr)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
-
-int ieee802154_nl_scan_confirm(struct net_device *dev,
- u8 status, u8 scan_type, u32 unscanned, u8 page,
- u8 *edl/* , struct list_head *pan_desc_list */)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
- NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
- NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page);
-
- if (edl)
- NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_scan_confirm);
-
-int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
-{
- struct sk_buff *msg;
-
- pr_debug("%s\n", __func__);
-
- msg = ieee802154_nl_create(0, IEEE802154_START_CONF);
- if (!msg)
- return -ENOBUFS;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
- return ieee802154_nl_finish(msg);
-
-nla_put_failure:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-EXPORT_SYMBOL(ieee802154_nl_start_confirm);
-
-static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
- u32 seq, int flags, struct net_device *dev)
-{
- void *hdr;
-
- pr_debug("%s\n", __func__);
-
- hdr = genlmsg_put(msg, 0, seq, &ieee802154_coordinator_family, flags,
- IEEE802154_LIST_IFACE);
- if (!hdr)
- goto out;
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
-
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR,
- ieee802154_mlme_ops(dev)->get_short_addr(dev));
- NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
- ieee802154_mlme_ops(dev)->get_pan_id(dev));
- return genlmsg_end(msg, hdr);
-
-nla_put_failure:
- genlmsg_cancel(msg, hdr);
-out:
- return -EMSGSIZE;
-}
-
-/* Requests from userspace */
-static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
-{
- struct net_device *dev;
-
- if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
- char name[IFNAMSIZ + 1];
- nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
- sizeof(name));
- dev = dev_get_by_name(&init_net, name);
- } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX])
- dev = dev_get_by_index(&init_net,
- nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
- else
- return NULL;
-
- if (!dev)
- return NULL;
-
- if (dev->type != ARPHRD_IEEE802154) {
- dev_put(dev);
- return NULL;
- }
-
- return dev;
-}
-
-static int ieee802154_associate_req(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- u8 page;
- int ret = -EINVAL;
-
- if (!info->attrs[IEEE802154_ATTR_CHANNEL] ||
- !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
- (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] &&
- !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) ||
- !info->attrs[IEEE802154_ATTR_CAPABILITY])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) {
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr,
- info->attrs[IEEE802154_ATTR_COORD_HW_ADDR],
- IEEE802154_ADDR_LEN);
- } else {
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
- }
- addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
- ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr,
- nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]),
- page,
- nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY]));
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_associate_resp(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- int ret = -EINVAL;
-
- if (!info->attrs[IEEE802154_ATTR_STATUS] ||
- !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] ||
- !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
- IEEE802154_ADDR_LEN);
- addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
-
-
- ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr,
- nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]),
- nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS]));
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_disassociate_req(struct sk_buff *skb,
- struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
- int ret = -EINVAL;
-
- if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] &&
- !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
- !info->attrs[IEEE802154_ATTR_REASON])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) {
- addr.addr_type = IEEE802154_ADDR_LONG;
- nla_memcpy(addr.hwaddr,
- info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
- IEEE802154_ADDR_LEN);
- } else {
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]);
- }
- addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
-
- ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr,
- nla_get_u8(info->attrs[IEEE802154_ATTR_REASON]));
-
- dev_put(dev);
- return ret;
-}
-
-/*
- * PANid, channel, beacon_order = 15, superframe_order = 15,
- * PAN_coordinator, battery_life_extension = 0,
- * coord_realignment = 0, security_enable = 0
-*/
-static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
-{
- struct net_device *dev;
- struct ieee802154_addr addr;
-
- u8 channel, bcn_ord, sf_ord;
- u8 page;
- int pan_coord, blx, coord_realign;
- int ret;
-
- if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
- !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] ||
- !info->attrs[IEEE802154_ATTR_CHANNEL] ||
- !info->attrs[IEEE802154_ATTR_BCN_ORD] ||
- !info->attrs[IEEE802154_ATTR_SF_ORD] ||
- !info->attrs[IEEE802154_ATTR_PAN_COORD] ||
- !info->attrs[IEEE802154_ATTR_BAT_EXT] ||
- !info->attrs[IEEE802154_ATTR_COORD_REALIGN]
- )
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- addr.addr_type = IEEE802154_ADDR_SHORT;
- addr.short_addr = nla_get_u16(
- info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
- addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
-
- channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]);
- bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]);
- sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]);
- pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]);
- blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]);
- coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
-
- if (addr.short_addr == IEEE802154_ADDR_BROADCAST) {
- ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS);
- dev_put(dev);
- return -EINVAL;
- }
-
- ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page,
- bcn_ord, sf_ord, pan_coord, blx, coord_realign);
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
-{
- struct net_device *dev;
- int ret;
- u8 type;
- u32 channels;
- u8 duration;
- u8 page;
-
- if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] ||
- !info->attrs[IEEE802154_ATTR_CHANNELS] ||
- !info->attrs[IEEE802154_ATTR_DURATION])
- return -EINVAL;
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]);
- channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]);
- duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]);
-
- if (info->attrs[IEEE802154_ATTR_PAGE])
- page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
- else
- page = 0;
-
-
- ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page,
- duration);
-
- dev_put(dev);
- return ret;
-}
-
-static int ieee802154_list_iface(struct sk_buff *skb,
- struct genl_info *info)
-{
- /* Request for interface name, index, type, IEEE address,
- PAN Id, short address */
- struct sk_buff *msg;
- struct net_device *dev = NULL;
- int rc = -ENOBUFS;
-
- pr_debug("%s\n", __func__);
-
- dev = ieee802154_nl_get_dev(info);
- if (!dev)
- return -ENODEV;
-
- msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
- if (!msg)
- goto out_dev;
-
- rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq,
- 0, dev);
- if (rc < 0)
- goto out_free;
-
- dev_put(dev);
-
- return genlmsg_unicast(&init_net, msg, info->snd_pid);
-out_free:
- nlmsg_free(msg);
-out_dev:
- dev_put(dev);
- return rc;
-
-}
-
-static int ieee802154_dump_iface(struct sk_buff *skb,
- struct netlink_callback *cb)
-{
- struct net *net = sock_net(skb->sk);
- struct net_device *dev;
- int idx;
- int s_idx = cb->args[0];
-
- pr_debug("%s\n", __func__);
-
- idx = 0;
- for_each_netdev(net, dev) {
- if (idx < s_idx || (dev->type != ARPHRD_IEEE802154))
- goto cont;
-
- if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
- break;
-cont:
- idx++;
- }
- cb->args[0] = idx;
-
- return skb->len;
-}
-
-#define IEEE802154_OP(_cmd, _func) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = NULL, \
- .flags = GENL_ADMIN_PERM, \
- }
-
-#define IEEE802154_DUMP(_cmd, _func, _dump) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = _dump, \
- }
-
-static struct genl_ops ieee802154_coordinator_ops[] = {
- IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
- IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
- IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
- IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
- IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
- IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
- ieee802154_dump_iface),
-};
-
int __init ieee802154_nl_init(void)
{
int rc;
- int i;
- rc = genl_register_family(&ieee802154_coordinator_family);
+ rc = genl_register_family(&nl802154_family);
if (rc)
goto fail;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
- &ieee802154_coord_mcgrp);
+ rc = nl802154_mac_register();
if (rc)
goto fail;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
- &ieee802154_beacon_mcgrp);
- if (rc)
- goto fail;
-
-
- for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
- rc = genl_register_ops(&ieee802154_coordinator_family,
- &ieee802154_coordinator_ops[i]);
- if (rc)
- goto fail;
- }
-
return 0;
fail:
- genl_unregister_family(&ieee802154_coordinator_family);
+ genl_unregister_family(&nl802154_family);
return rc;
}
void __exit ieee802154_nl_exit(void)
{
- genl_unregister_family(&ieee802154_coordinator_family);
+ genl_unregister_family(&nl802154_family);
}
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/nl-mac.c
similarity index 86%
copy from net/ieee802154/netlink.c
copy to net/ieee802154/nl-mac.c
index 0fadd6b..e8816bf 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/nl-mac.c
@@ -34,16 +34,7 @@
#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
-static unsigned int ieee802154_seq_num;
-static DEFINE_SPINLOCK(ieee802154_seq_lock);
-
-static struct genl_family ieee802154_coordinator_family = {
- .id = GENL_ID_GENERATE,
- .hdrsize = 0,
- .name = IEEE802154_NL_NAME,
- .version = 1,
- .maxattr = IEEE802154_ATTR_MAX,
-};
+#include "ieee802154.h"
static struct genl_multicast_group ieee802154_coord_mcgrp = {
.name = IEEE802154_MCAST_COORD_NAME,
@@ -53,43 +44,6 @@ static struct genl_multicast_group ieee802154_beacon_mcgrp = {
.name = IEEE802154_MCAST_BEACON_NAME,
};
-/* Requests to userspace */
-static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
-{
- void *hdr;
- struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
- unsigned long f;
-
- if (!msg)
- return NULL;
-
- spin_lock_irqsave(&ieee802154_seq_lock, f);
- hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
- &ieee802154_coordinator_family, flags, req);
- spin_unlock_irqrestore(&ieee802154_seq_lock, f);
- if (!hdr) {
- nlmsg_free(msg);
- return NULL;
- }
-
- return msg;
-}
-
-static int ieee802154_nl_finish(struct sk_buff *msg)
-{
- /* XXX: nlh is right at the start of msg */
- void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
-
- if (genlmsg_end(msg, hdr) < 0)
- goto out;
-
- return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
- GFP_ATOMIC);
-out:
- nlmsg_free(msg);
- return -ENOBUFS;
-}
-
int ieee802154_nl_assoc_indic(struct net_device *dev,
struct ieee802154_addr *addr, u8 cap)
{
@@ -116,7 +70,7 @@ int ieee802154_nl_assoc_indic(struct net_device *dev,
NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -143,7 +97,7 @@ int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -176,7 +130,7 @@ int ieee802154_nl_disassoc_indic(struct net_device *dev,
NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -201,7 +155,7 @@ int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -227,7 +181,7 @@ int ieee802154_nl_beacon_indic(struct net_device *dev,
NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -260,7 +214,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev,
if (edl)
NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -285,7 +239,7 @@ int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- return ieee802154_nl_finish(msg);
+ return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
nlmsg_free(msg);
@@ -300,7 +254,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
pr_debug("%s\n", __func__);
- hdr = genlmsg_put(msg, 0, seq, &ieee802154_coordinator_family, flags,
+ hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
IEEE802154_LIST_IFACE);
if (!hdr)
goto out;
@@ -581,7 +535,7 @@ static int ieee802154_list_iface(struct sk_buff *skb,
dev_put(dev);
- return genlmsg_unicast(&init_net, msg, info->snd_pid);
+ return genlmsg_reply(msg, info);
out_free:
nlmsg_free(msg);
out_dev:
@@ -616,23 +570,6 @@ cont:
return skb->len;
}
-#define IEEE802154_OP(_cmd, _func) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = NULL, \
- .flags = GENL_ADMIN_PERM, \
- }
-
-#define IEEE802154_DUMP(_cmd, _func, _dump) \
- { \
- .cmd = _cmd, \
- .policy = ieee802154_policy, \
- .doit = _func, \
- .dumpit = _dump, \
- }
-
static struct genl_ops ieee802154_coordinator_ops[] = {
IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
@@ -643,42 +580,30 @@ static struct genl_ops ieee802154_coordinator_ops[] = {
ieee802154_dump_iface),
};
-int __init ieee802154_nl_init(void)
+/*
+ * No need to unregister as family unregistration will do it.
+ */
+int nl802154_mac_register(void)
{
- int rc;
int i;
+ int rc;
- rc = genl_register_family(&ieee802154_coordinator_family);
- if (rc)
- goto fail;
-
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
+ rc = genl_register_mc_group(&nl802154_family,
&ieee802154_coord_mcgrp);
if (rc)
- goto fail;
+ return rc;
- rc = genl_register_mc_group(&ieee802154_coordinator_family,
+ rc = genl_register_mc_group(&nl802154_family,
&ieee802154_beacon_mcgrp);
if (rc)
- goto fail;
-
+ return rc;
for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
- rc = genl_register_ops(&ieee802154_coordinator_family,
+ rc = genl_register_ops(&nl802154_family,
&ieee802154_coordinator_ops[i]);
if (rc)
- goto fail;
+ return rc;
}
return 0;
-
-fail:
- genl_unregister_family(&ieee802154_coordinator_family);
- return rc;
}
-
-void __exit ieee802154_nl_exit(void)
-{
- genl_unregister_family(&ieee802154_coordinator_family);
-}
-
--
1.6.5
^ permalink raw reply related
* [PATCH 08/17] ieee802154: merge nl802154 and wpan-class in single module
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
There is no real need to have ieee802154 interfaces separate
into several small modules, as neither of them has it's own use.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/Makefile | 4 ++--
net/ieee802154/netlink.c | 9 ++-------
net/ieee802154/wpan-class.c | 23 ++++++++++++++++++++---
3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 4068a9f..42b1f0d 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,5 +1,5 @@
-obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o wpan-class.o
-nl802154-y := netlink.o nl_policy.o
+obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
+ieee802154-y := netlink.o nl_policy.o wpan-class.o
af_802154-y := af_ieee802154.o raw.o dgram.o
ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index ca767bd..0fadd6b 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -643,7 +643,7 @@ static struct genl_ops ieee802154_coordinator_ops[] = {
ieee802154_dump_iface),
};
-static int __init ieee802154_nl_init(void)
+int __init ieee802154_nl_init(void)
{
int rc;
int i;
@@ -676,14 +676,9 @@ fail:
genl_unregister_family(&ieee802154_coordinator_family);
return rc;
}
-module_init(ieee802154_nl_init);
-static void __exit ieee802154_nl_exit(void)
+void __exit ieee802154_nl_exit(void)
{
genl_unregister_family(&ieee802154_coordinator_family);
}
-module_exit(ieee802154_nl_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("ieee 802.15.4 configuration interface");
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index cd42e88..38bac70 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -22,6 +22,8 @@
#include <net/wpan-phy.h>
+#include "ieee802154.h"
+
#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
static ssize_t name ## _show(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -188,16 +190,31 @@ EXPORT_SYMBOL(wpan_phy_free);
static int __init wpan_phy_class_init(void)
{
- return class_register(&wpan_phy_class);
+ int rc;
+ rc = class_register(&wpan_phy_class);
+ if (rc)
+ goto err;
+
+ rc = ieee802154_nl_init();
+ if (rc)
+ goto err_nl;
+
+ return 0;
+err_nl:
+ class_unregister(&wpan_phy_class);
+err:
+ return rc;
}
-subsys_initcall(wpan_phy_class_init);
+module_init(wpan_phy_class_init);
static void __exit wpan_phy_class_exit(void)
{
+ ieee802154_nl_exit();
class_unregister(&wpan_phy_class);
}
module_exit(wpan_phy_class_exit);
-MODULE_DESCRIPTION("IEEE 802.15.4 device class");
MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov");
--
1.6.5
^ permalink raw reply related
* [PATCH 07/17] ieee802154: constify struct net_device in some operations
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Some of ieee802154 operations really shouldn't change passed net_device.
Constify passed argument.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 8 ++++----
include/net/ieee802154_netdev.h | 10 +++++-----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 4ea93cc..77fbb51 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -43,7 +43,7 @@ struct wpan_phy *net_to_phy(struct net_device *dev)
*
* Return the ID of the PAN from the PIB.
*/
-static u16 fake_get_pan_id(struct net_device *dev)
+static u16 fake_get_pan_id(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -58,7 +58,7 @@ static u16 fake_get_pan_id(struct net_device *dev)
* device. If the device has not yet had a short address assigned
* then this should return 0xFFFF to indicate a lack of association.
*/
-static u16 fake_get_short_addr(struct net_device *dev)
+static u16 fake_get_short_addr(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -78,7 +78,7 @@ static u16 fake_get_short_addr(struct net_device *dev)
* Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
* document.
*/
-static u8 fake_get_dsn(struct net_device *dev)
+static u8 fake_get_dsn(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -98,7 +98,7 @@ static u8 fake_get_dsn(struct net_device *dev)
* Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
* document.
*/
-static u8 fake_get_bsn(struct net_device *dev)
+static u8 fake_get_bsn(const struct net_device *dev)
{
BUG_ON(dev->type != ARPHRD_IEEE802154);
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 5dc6a61..d23fb5a 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -98,14 +98,14 @@ struct ieee802154_mlme_ops {
* FIXME: these should become the part of PIB/MIB interface.
* However we still don't have IB interface of any kind
*/
- u16 (*get_pan_id)(struct net_device *dev);
- u16 (*get_short_addr)(struct net_device *dev);
- u8 (*get_dsn)(struct net_device *dev);
- u8 (*get_bsn)(struct net_device *dev);
+ u16 (*get_pan_id)(const struct net_device *dev);
+ u16 (*get_short_addr)(const struct net_device *dev);
+ u8 (*get_dsn)(const struct net_device *dev);
+ u8 (*get_bsn)(const struct net_device *dev);
};
static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
- struct net_device *dev)
+ const struct net_device *dev)
{
return dev->ml_priv;
}
--
1.6.5
^ permalink raw reply related
* [PATCH 06/17] wpan-phy: follow usual patter of devices registration
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Follow the usual pattern of devices registration by adding new function
(wpan_phy_set_dev) that sets child->parent relationship and removing
parent argument from wpan_phy_register call.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 3 ++-
include/net/wpan-phy.h | 6 +++++-
net/ieee802154/wpan-class.c | 4 +---
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index f6f2afe..4ea93cc 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -372,11 +372,12 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
goto out;
}
+ wpan_phy_set_dev(phy, &pdev->dev);
SET_NETDEV_DEV(dev, &phy->dev);
platform_set_drvdata(pdev, dev);
- err = wpan_phy_register(&pdev->dev, phy);
+ err = wpan_phy_register(phy);
if (err)
goto out;
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 7b7fc58..f63537c 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -45,7 +45,11 @@ struct wpan_phy {
};
struct wpan_phy *wpan_phy_alloc(size_t priv_size);
-int wpan_phy_register(struct device *parent, struct wpan_phy *phy);
+static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
+{
+ phy->dev.parent = dev;
+}
+int wpan_phy_register(struct wpan_phy *phy);
void wpan_phy_unregister(struct wpan_phy *phy);
void wpan_phy_free(struct wpan_phy *phy);
/* Same semantics as for class_for_each_device */
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 0c51f85..cd42e88 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -168,10 +168,8 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
}
EXPORT_SYMBOL(wpan_phy_alloc);
-int wpan_phy_register(struct device *parent, struct wpan_phy *phy)
+int wpan_phy_register(struct wpan_phy *phy)
{
- phy->dev.parent = parent;
-
return device_add(&phy->dev);
}
EXPORT_SYMBOL(wpan_phy_register);
--
1.6.5
^ permalink raw reply related
* [PATCH 05/17] wpan-phy: allow specifying a per-page channel mask
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
IEEE 802.15.4-2006 defines channel pages that hold channels (max 32 pages,
27 channels per page). Allow the driver to specify supported channels
on pages, other than the first one.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/ieee802154/fakehard.c | 2 +-
include/net/wpan-phy.h | 2 +-
net/ieee802154/wpan-class.c | 20 +++++++++++++++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 96a2959..f6f2afe 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -356,7 +356,7 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- phy->channels_supported = (1 << 27) - 1;
+ phy->channels_supported[0] = (1 << 27) - 1;
phy->transmit_power = 0xbf;
dev->netdev_ops = &fake_ops;
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 3367dd9..7b7fc58 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -34,7 +34,7 @@ struct wpan_phy {
*/
u8 current_channel;
u8 current_page;
- u32 channels_supported;
+ u32 channels_supported[32];
u8 transmit_power;
u8 cca_mode;
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 68ccde6..0c51f85 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -40,12 +40,30 @@ static ssize_t name ## _show(struct device *dev, \
MASTER_SHOW(current_channel, "%d");
MASTER_SHOW(current_page, "%d");
-MASTER_SHOW(channels_supported, "%#x");
MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",
((signed char) (phy->transmit_power << 2)) >> 2,
(phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );
MASTER_SHOW(cca_mode, "%d");
+static ssize_t channels_supported_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ int ret;
+ int i, len = 0;
+
+ mutex_lock(&phy->pib_lock);
+ for (i = 0; i < 32; i++) {
+ ret = snprintf(buf + len, PAGE_SIZE - len,
+ "%#09x\n", phy->channels_supported[i]);
+ if (ret < 0)
+ break;
+ len += ret;
+ }
+ mutex_unlock(&phy->pib_lock);
+ return len;
+}
+
static struct device_attribute pmib_attrs[] = {
__ATTR_RO(current_channel),
__ATTR_RO(current_page),
--
1.6.5
^ permalink raw reply related
* [PATCH 04/17] wpan-phy: use snprintf to limit the amount of chars written
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Use snprintf to limit the amount of chars put in the buffer for attr -> show.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/wpan-class.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index a10ae5b..68ccde6 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -30,7 +30,7 @@ static ssize_t name ## _show(struct device *dev, \
int ret; \
\
mutex_lock(&phy->pib_lock); \
- ret = sprintf(buf, format_string "\n", args); \
+ ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
mutex_unlock(&phy->pib_lock); \
return ret; \
}
--
1.6.5
^ permalink raw reply related
* [PATCH 03/17] wpan-phy: init channel/page fields
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Set page to zero (for compatibility w/ devices supporting only first page).
Also init channel by default to -1 to disallow transfers for non-initialised
devices.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
net/ieee802154/wpan-class.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 0cec138..a10ae5b 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -143,6 +143,9 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
phy->dev.class = &wpan_phy_class;
+ phy->current_channel = -1; /* not initialised */
+ phy->current_page = 0; /* for compatibility */
+
return phy;
}
EXPORT_SYMBOL(wpan_phy_alloc);
--
1.6.5
^ permalink raw reply related
* [PATCH 02/17] wpan-phy: add wpan-phy iteration functions
From: Dmitry Eremin-Solenikov @ 2009-11-06 12:39 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Sergey Lapin
In-Reply-To: <1257511181-19403-1-git-send-email-dbaryshkov@gmail.com>
Add API to iterate over the wpan-phy instances.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
include/net/wpan-phy.h | 2 ++
net/ieee802154/wpan-class.c | 25 +++++++++++++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
index 5e803a0..3367dd9 100644
--- a/include/net/wpan-phy.h
+++ b/include/net/wpan-phy.h
@@ -48,6 +48,8 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size);
int wpan_phy_register(struct device *parent, struct wpan_phy *phy);
void wpan_phy_unregister(struct wpan_phy *phy);
void wpan_phy_free(struct wpan_phy *phy);
+/* Same semantics as for class_for_each_device */
+int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data);
static inline void *wpan_phy_priv(struct wpan_phy *phy)
{
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index f306604..0cec138 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -91,6 +91,31 @@ struct wpan_phy *wpan_phy_find(const char *str)
}
EXPORT_SYMBOL(wpan_phy_find);
+struct wpan_phy_iter_data {
+ int (*fn)(struct wpan_phy *phy, void *data);
+ void *data;
+};
+
+static int wpan_phy_iter(struct device *dev, void *_data)
+{
+ struct wpan_phy_iter_data *wpid = _data;
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ return wpid->fn(phy, wpid->data);
+}
+
+int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
+ void *data)
+{
+ struct wpan_phy_iter_data wpid = {
+ .fn = fn,
+ .data = data,
+ };
+
+ return class_for_each_device(&wpan_phy_class, NULL,
+ &wpid, wpan_phy_iter);
+}
+EXPORT_SYMBOL(wpan_phy_for_each);
+
static int wpan_phy_idx_valid(int idx)
{
return idx >= 0;
--
1.6.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox