* Re: [RFT/PATCH] 3c509: use proper suspend/resume API
From: Pekka J Enberg @ 2006-02-15 11:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, netdev
In-Reply-To: <20060215022523.1d21b9c9.akpm@osdl.org>
Hi Andrew,
On Wed, 15 Feb 2006, Andrew Morton wrote:
> Problem is, it doesn't resume correctly either with or without the patch:
> it needs rmmod+modprobe to get it going again. (Which is better than the
> aic7xxx driver, which has a coronary and panics the kernel on post-resume
> reboot).
Hmm. Either I am totally confused or we don't even attempt suspend/resume
for eisa and mca bus devices. Care to try this patch?
Pekka
Index: 2.6/drivers/eisa/eisa-bus.c
===================================================================
--- 2.6.orig/drivers/eisa/eisa-bus.c
+++ 2.6/drivers/eisa/eisa-bus.c
@@ -128,9 +128,31 @@ static int eisa_bus_match (struct device
return 0;
}
+static int eisa_bus_suspend(struct device * dev, pm_message_t state)
+{
+ int ret = 0;
+
+ if (dev->driver && dev->driver->suspend)
+ ret = dev->driver->suspend(dev, state);
+
+ return ret;
+}
+
+static int eisa_bus_resume(struct device * dev)
+{
+ int ret = 0;
+
+ if (dev->driver && dev->driver->resume)
+ ret = dev->driver->resume(dev);
+
+ return ret;
+}
+
struct bus_type eisa_bus_type = {
.name = "eisa",
.match = eisa_bus_match,
+ .suspend = eisa_bus_suspend,
+ .resume = eisa_bus_resume,
};
int eisa_driver_register (struct eisa_driver *edrv)
Index: 2.6/drivers/mca/mca-bus.c
===================================================================
--- 2.6.orig/drivers/mca/mca-bus.c
+++ 2.6/drivers/mca/mca-bus.c
@@ -63,9 +63,32 @@ static int mca_bus_match (struct device
return 0;
}
+static int mca_bus_suspend(struct device * dev, pm_message_t state)
+{
+ int ret = 0;
+
+ if (dev->driver && dev->driver->suspend)
+ ret = dev->driver->suspend(dev, state);
+
+ return ret;
+}
+
+static int mca_bus_resume(struct device * dev)
+{
+ int ret = 0;
+
+ if (dev->driver && dev->driver->resume)
+ ret = dev->driver->resume(dev);
+
+ return ret;
+}
+
+
struct bus_type mca_bus_type = {
.name = "MCA",
.match = mca_bus_match,
+ .suspend = mca_bus_suspend,
+ .resume = mca_bus_resume,
};
EXPORT_SYMBOL (mca_bus_type);
^ permalink raw reply
* Re: [RFT/PATCH] 3c509: use proper suspend/resume API
From: Andrew Morton @ 2006-02-15 11:52 UTC (permalink / raw)
To: Pekka J Enberg; +Cc: linux-kernel, netdev
In-Reply-To: <Pine.LNX.4.58.0602151256580.14223@sbz-30.cs.Helsinki.FI>
Pekka J Enberg <penberg@cs.Helsinki.FI> wrote:
>
> On Wed, 15 Feb 2006, Andrew Morton wrote:
> > I have a 3c509, and I'm not afraid to use it!
> >
> > Problem is, it doesn't resume correctly either with or without the patch:
> > it needs rmmod+modprobe to get it going again. (Which is better than the
> > aic7xxx driver, which has a coronary and panics the kernel on post-resume
> > reboot).
>
> Is there anything in the logs to give us a clue what's going on? I can't
> see anything obvious looking at the code, but then again I don't have
> datasheets for 3c509 either.
>
eeprom reads 0xffff, that's all I noticed.
^ permalink raw reply
* Re: [RFT/PATCH] 3c509: use proper suspend/resume API
From: Russell King @ 2006-02-15 12:40 UTC (permalink / raw)
To: Pekka J Enberg; +Cc: Andrew Morton, linux-kernel, netdev
In-Reply-To: <Pine.LNX.4.58.0602151317110.14223@sbz-30.cs.Helsinki.FI>
On Wed, Feb 15, 2006 at 01:23:19PM +0200, Pekka J Enberg wrote:
> Hmm. Either I am totally confused or we don't even attempt suspend/resume
> for eisa and mca bus devices. Care to try this patch?
Please don't use struct device_driver suspend/resume methods.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply
* Re: [RFT/PATCH] 3c509: use proper suspend/resume API
From: Andrew Morton @ 2006-02-15 12:45 UTC (permalink / raw)
To: Pekka J Enberg; +Cc: linux-kernel, netdev
In-Reply-To: <Pine.LNX.4.58.0602151317110.14223@sbz-30.cs.Helsinki.FI>
Pekka J Enberg <penberg@cs.Helsinki.FI> wrote:
>
> Hi Andrew,
>
> On Wed, 15 Feb 2006, Andrew Morton wrote:
> > Problem is, it doesn't resume correctly either with or without the patch:
> > it needs rmmod+modprobe to get it going again. (Which is better than the
> > aic7xxx driver, which has a coronary and panics the kernel on post-resume
> > reboot).
>
> Hmm. Either I am totally confused or we don't even attempt suspend/resume
> for eisa and mca bus devices. Care to try this patch?
No, el3_suspend() and el3_resume() don't seem to be called. And they're
still not called with this patch applied..
(I got one resume in which the 3c509 still worked. Odd.)
^ permalink raw reply
* [XFRM]: Fix SNAT-related crash in xfrm4_output_finish
From: Patrick McHardy @ 2006-02-15 17:25 UTC (permalink / raw)
To: David S. Miller
Cc: Kernel Netdev Mailing List, Netfilter Development Mailinglist,
Herbert Xu
[-- Attachment #1: Type: text/plain, Size: 81 bytes --]
This patch fixes the crash in xfrm4_output_finish reported by
multiple people.
[-- Attachment #2: 01.diff --]
[-- Type: text/x-patch, Size: 7678 bytes --]
[XFRM]: Fix SNAT-related crash in xfrm4_output_finish
When a packet matching an IPsec policy is SNATed so it doesn't match any
policy anymore it looses its xfrm bundle, which makes xfrm4_output_finish
crash because of a NULL pointer dereference.
This patch directs these packets to the original output path instead. Since
the packets have already passed the POST_ROUTING hook, but need to start at
the beginning of the original output path which includes another
POST_ROUTING invocation, a flag is added to the IPCB to indicate that the
packet was rerouted and doesn't need to pass the POST_ROUTING hook again.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit a31ab06c99e45232b742803677e88363cda2fb85
tree 020e91264409d418d615599a5880df68ca640432
parent ede836cd3164896d741dff1a8d7c1dc0b9b1fdf6
author Patrick McHardy <kaber@trash.net> Wed, 15 Feb 2006 17:30:44 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 15 Feb 2006 17:30:44 +0100
include/linux/netfilter.h | 19 +++++++++++++++----
include/net/ip.h | 1 +
include/net/xfrm.h | 1 -
net/ipv4/ip_gre.c | 3 ++-
net/ipv4/ip_output.c | 16 ++++++++++------
net/ipv4/ipip.c | 3 ++-
net/ipv4/xfrm4_output.c | 13 ++++++++++---
7 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 4cf6088..5deacda 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -184,8 +184,11 @@ static inline int nf_hook_thresh(int pf,
struct sk_buff **pskb,
struct net_device *indev,
struct net_device *outdev,
- int (*okfn)(struct sk_buff *), int thresh)
+ int (*okfn)(struct sk_buff *), int thresh,
+ int cond)
{
+ if (!cond)
+ return 1;
#ifndef CONFIG_NETFILTER_DEBUG
if (list_empty(&nf_hooks[pf][hook]))
return 1;
@@ -197,7 +200,7 @@ static inline int nf_hook(int pf, unsign
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
- return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN);
+ return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN, 1);
}
/* Activate hook; either okfn or kfree_skb called, unless a hook
@@ -224,7 +227,13 @@ static inline int nf_hook(int pf, unsign
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
({int __ret; \
-if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)\
+if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
+ __ret = (okfn)(skb); \
+__ret;})
+
+#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
+({int __ret; \
+if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
__ret = (okfn)(skb); \
__ret;})
@@ -295,11 +304,13 @@ extern struct proc_dir_entry *proc_net_n
#else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
static inline int nf_hook_thresh(int pf, unsigned int hook,
struct sk_buff **pskb,
struct net_device *indev,
struct net_device *outdev,
- int (*okfn)(struct sk_buff *), int thresh)
+ int (*okfn)(struct sk_buff *), int thresh,
+ int cond)
{
return okfn(*pskb);
}
diff --git a/include/net/ip.h b/include/net/ip.h
index 8de0697..fab3d5b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -41,6 +41,7 @@ struct inet_skb_parm
#define IPSKB_XFRM_TUNNEL_SIZE 2
#define IPSKB_XFRM_TRANSFORMED 4
#define IPSKB_FRAG_COMPLETE 8
+#define IPSKB_REROUTED 16
};
struct ipcm_cookie
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index d09ca0e..d6111a2 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -866,7 +866,6 @@ extern int xfrm_state_mtu(struct xfrm_st
extern int xfrm_init_state(struct xfrm_state *x);
extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff *skb);
-extern int xfrm4_output_finish(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index abe2392..9981dcd 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -830,7 +830,8 @@ static int ipgre_tunnel_xmit(struct sk_b
skb->h.raw = skb->nh.raw;
skb->nh.raw = skb_push(skb, gre_hlen);
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
- IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
+ IPSKB_REROUTED);
dst_release(skb->dst);
skb->dst = &rt->u.dst;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3324fbf..57d290d 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -207,8 +207,10 @@ static inline int ip_finish_output(struc
{
#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
/* Policy lookup after SNAT yielded a new policy */
- if (skb->dst->xfrm != NULL)
- return xfrm4_output_finish(skb);
+ if (skb->dst->xfrm != NULL) {
+ IPCB(skb)->flags |= IPSKB_REROUTED;
+ return dst_output(skb);
+ }
#endif
if (skb->len > dst_mtu(skb->dst) &&
!(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
@@ -271,8 +273,9 @@ int ip_mc_output(struct sk_buff *skb)
newskb->dev, ip_dev_loopback_xmit);
}
- return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
- ip_finish_output);
+ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+ ip_finish_output,
+ !(IPCB(skb)->flags & IPSKB_REROUTED));
}
int ip_output(struct sk_buff *skb)
@@ -284,8 +287,9 @@ int ip_output(struct sk_buff *skb)
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
- return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
- ip_finish_output);
+ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+ ip_finish_output,
+ !(IPCB(skb)->flags & IPSKB_REROUTED));
}
int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index e5cbe72..03d1374 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -622,7 +622,8 @@ static int ipip_tunnel_xmit(struct sk_bu
skb->h.raw = skb->nh.raw;
skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
- IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
+ IPSKB_REROUTED);
dst_release(skb->dst);
skb->dst = &rt->u.dst;
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index d4df0dd..32ad229 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -152,10 +152,16 @@ error_nolock:
goto out_exit;
}
-int xfrm4_output_finish(struct sk_buff *skb)
+static int xfrm4_output_finish(struct sk_buff *skb)
{
int err;
+#ifdef CONFIG_NETFILTER
+ if (!skb->dst->xfrm) {
+ IPCB(skb)->flags |= IPSKB_REROUTED;
+ return dst_output(skb);
+ }
+#endif
while (likely((err = xfrm4_output_one(skb)) == 0)) {
nf_reset(skb);
@@ -178,6 +184,7 @@ int xfrm4_output_finish(struct sk_buff *
int xfrm4_output(struct sk_buff *skb)
{
- return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
- xfrm4_output_finish);
+ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
+ xfrm4_output_finish,
+ !(IPCB(skb)->flags & IPSKB_REROUTED));
}
^ permalink raw reply related
* [NETFILTER]: Don't invoke okfn in CONFIG_NETFILTER=n variant of nf_hook()
From: Patrick McHardy @ 2006-02-15 17:25 UTC (permalink / raw)
To: David S. Miller
Cc: Kernel Netdev Mailing List, Netfilter Development Mailinglist,
Herbert Xu
[-- Attachment #1: Type: text/plain, Size: 53 bytes --]
Another fix related to the netfilter IPsec patches.
[-- Attachment #2: 02.diff --]
[-- Type: text/x-patch, Size: 1119 bytes --]
[NETFILTER]: Don't invoke okfn in CONFIG_NETFILTER=n variant of nf_hook()
nf_hook() is supposed to call the netfilter hook and return control of the
packet back to the caller in case it may pass, the okfn is only used for
queueing.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 4611d14cc145cb244634920a7c4b0082f3c08eda
tree 84c175affb78b77e78d908ea8baef43d9dba698a
parent a31ab06c99e45232b742803677e88363cda2fb85
author Patrick McHardy <kaber@trash.net> Wed, 15 Feb 2006 17:39:55 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 15 Feb 2006 17:39:55 +0100
include/linux/netfilter.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 5deacda..aa7bb93 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -318,7 +318,7 @@ static inline int nf_hook(int pf, unsign
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
- return okfn(*pskb);
+ return 1;
}
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
struct flowi;
^ permalink raw reply related
* Re: [RFT/PATCH] 3c509: use proper suspend/resume API
From: Pekka Enberg @ 2006-02-15 17:32 UTC (permalink / raw)
To: Russell King; +Cc: Andrew Morton, linux-kernel, netdev
In-Reply-To: <20060215124020.GA1508@flint.arm.linux.org.uk>
On Wed, Feb 15, 2006 at 01:23:19PM +0200, Pekka J Enberg wrote:
> > Hmm. Either I am totally confused or we don't even attempt suspend/resume
> > for eisa and mca bus devices. Care to try this patch?
On Wed, 2006-02-15 at 12:40 +0000, Russell King wrote:
> Please don't use struct device_driver suspend/resume methods.
So what would be more appropriate? Move suspend/resume/probe and friends
to eisa_driver and mca_driver?
Pekka
^ permalink raw reply
* Re: [PATCH wireless-2.6] bcm43xx-d80211: fix oops when removing the module
From: Michael Buesch @ 2006-02-15 21:34 UTC (permalink / raw)
To: Jiri Benc; +Cc: John W. Linville, NetDev, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
In-Reply-To: <20060215202147.69b82ee2-IhiK2ZEFs2oCVLCxKZUutA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 846 bytes --]
On Wednesday 15 February 2006 20:21, you wrote:
> This patch fixes an oops when bcm43xx-d80211 module is unloaded.
This is already fixed in my tree.
> Signed-off-by: Jiri Benc <jbenc-AlSwsSmVLrQ@public.gmane.org>
>
> --- dscape.testing.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 2006-02-15 20:06:07.000000000 +0100
> +++ dscape.testing/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 2006-02-15 20:07:17.000000000 +0100
> @@ -4785,7 +4785,8 @@ static void __devexit bcm43xx_remove_one
> ieee80211_unregister_hw(net_dev);
> bcm43xx_detach_board(bcm);
> destroy_workqueue(bcm->workqueue);
> - kfree_skb(bcm->cached_beacon);
> + if (bcm->cached_beacon)
> + kfree_skb(bcm->cached_beacon);
> assert(bcm->ucode == NULL);
> ieee80211_free_hw(net_dev);
> kfree(ieee);
>
>
--
Greetings Michael.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 1/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:18 UTC (permalink / raw)
To: netdev, David S. Miller, x25 maintainer, linux-kenel
Cc: Arnd Bergmann, Andre Hendry
Hi
The following patch provides 32 bit userland ioctl support for modular
(x.25 type) socket ioctls in a 64 bit kernel. Since the the
register_ioctl32_conversion() is now obsolete, this patch provides a
mechanism to allow 32 bit user space ioctls to reach the kernel.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/linux/net.h
linux-2.6.16-rc3/include/linux/net.h
--- linux-2.6.16-rc3-vanilla/include/linux/net.h 2006-02-15
10:58:02.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/net.h 2006-02-15 11:02:24.000000000
+1100
@@ -143,6 +143,8 @@ struct proto_ops {
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
+ int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
+ unsigned long arg);
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
@@ -247,6 +249,8 @@ SOCKCALL_UWRAP(name, poll, (struct file
(file, sock, wait)) \
SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \
unsigned long arg), (sock, cmd, arg)) \
+SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int
cmd, \
+ unsigned long arg), (sock, cmd, arg)) \
SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock,
len)) \
SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock,
flags)) \
SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int
optname, \
@@ -271,6 +275,7 @@ static const struct proto_ops name##_ops
.getname = __lock_##name##_getname, \
.poll = __lock_##name##_poll, \
.ioctl = __lock_##name##_ioctl, \
+ .compat_ioctl = __lock_##name##_compat_ioctl, \
.listen = __lock_##name##_listen, \
.shutdown = __lock_##name##_shutdown, \
.setsockopt = __lock_##name##_setsockopt, \
@@ -279,6 +284,7 @@ static const struct proto_ops name##_ops
.recvmsg = __lock_##name##_recvmsg, \
.mmap = __lock_##name##_mmap, \
};
+
#endif
#define MODULE_ALIAS_NETPROTO(proto) \
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/socket.c
linux-2.6.16-rc3/net/socket.c
--- linux-2.6.16-rc3-vanilla/net/socket.c 2006-02-15 10:58:03.000000000
+1100
+++ linux-2.6.16-rc3/net/socket.c 2006-02-15 11:02:24.000000000 +1100
@@ -109,6 +109,10 @@ static unsigned int sock_poll(struct fil
struct poll_table_struct *wait);
static long sock_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+#endif
static int sock_fasync(int fd, struct file *filp, int on);
static ssize_t sock_readv(struct file *file, const struct iovec
*vector,
unsigned long count, loff_t *ppos);
@@ -130,6 +134,9 @@ static struct file_operations socket_fil
.aio_write = sock_aio_write,
.poll = sock_poll,
.unlocked_ioctl = sock_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_sock_ioctl,
+#endif
.mmap = sock_mmap,
.open = sock_no_open, /* special open code to disallow open via /proc
*/
.release = sock_close,
@@ -2089,6 +2096,20 @@ void socket_seq_show(struct seq_file *se
}
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file, unsigned cmd, unsigned
long arg)
+{
+ struct socket *sock;
+ sock = file->private_data;
+
+ int ret = -ENOIOCTLCMD;
+ if(sock->ops->compat_ioctl)
+ ret = sock->ops->compat_ioctl(sock, cmd, arg);
+
+ return ret;
+}
+#endif
+
/* ABI emulation layers need these two */
EXPORT_SYMBOL(move_addr_to_kernel);
EXPORT_SYMBOL(move_addr_to_user);
^ permalink raw reply
* [PATCH 2/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:18 UTC (permalink / raw)
To: netdev, x25 maintainer, linux-kenel, David S. Miller
Cc: Andre Hendry, Arnd Bergmann
This patch is the first step towards migration of the 'handler
functions' for 32-64 bit userspace-kernel conversion, away from the
ioctl32_hash_table. It will be used by the x25 socket layer.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/net/compat.h
linux-2.6.16-rc3/include/net/compat.h
--- linux-2.6.16-rc3-vanilla/include/net/compat.h 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/include/net/compat.h 2006-02-15 11:09:00.000000000
+1100
@@ -23,6 +23,8 @@ struct compat_cmsghdr {
compat_int_t cmsg_type;
};
+extern int compat_sock_get_timestamp(struct sock *, struct timeval
__user *);
+
#else /* defined(CONFIG_COMPAT) */
#define compat_msghdr msghdr /* to avoid compiler warnings */
#endif /* defined(CONFIG_COMPAT) */
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/compat.c
linux-2.6.16-rc3/net/compat.c
--- linux-2.6.16-rc3-vanilla/net/compat.c 2006-02-15 10:58:03.000000000
+1100
+++ linux-2.6.16-rc3/net/compat.c 2006-02-15 11:09:00.000000000 +1100
@@ -503,6 +503,23 @@ static int do_get_sock_timeout(int fd, i
return err;
}
+int compat_sock_get_timestamp(struct sock *sk, struct timeval __user
*userstamp)
+{
+ struct compat_timeval __user *ctv
+ = (struct compat_timeval __user*) userstamp;
+ int err = -ENOENT;
+ if(!sock_flag(sk, SOCK_TIMESTAMP))
+ sock_enable_timestamp(sk);
+ if(sk->sk_stamp.tv_sec == -1)
+ return err;
+ if(sk->sk_stamp.tv_sec == 0)
+ do_gettimeofday(&sk->sk_stamp);
+ if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) |
+ put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+ err = -EFAULT;
+ return err;
+}
+
asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -602,3 +619,5 @@ asmlinkage long compat_sys_socketcall(in
}
return ret;
}
+
+EXPORT_SYMBOL(compat_sock_get_timestamp);
^ permalink raw reply
* [PATCH 3/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:19 UTC (permalink / raw)
To: netdev, David S. Miller, x25 maintainer, linux-kenel
Cc: Arnd Bergmann, Andre Hendry
This patch allows 32 bit x25 module structures to be passed to
a 64 bit kernel via ioctl using the new compat_sock_ioctl registration
mechanism instead of the obsolete 'register_ioctl32_conversion into hash
table' mechanism.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c
linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:12:30.000000000
+1100
@@ -55,6 +55,8 @@
#include <linux/notifier.h>
#include <linux/init.h>
#include <net/x25.h>
+#include <linux/compat.h>
+#include <net/compat.h>
int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
int sysctl_x25_call_request_timeout = X25_DEFAULT_T21;
@@ -69,6 +71,14 @@ static const struct proto_ops x25_proto_
static struct x25_address null_x25_address = {" "};
+#ifdef CONFIG_COMPAT
+struct compat_x25_subscrip_struct {
+ char device[200-sizeof(compat_ulong_t)];
+ compat_ulong_t global_facil_mask;
+ compat_uint_t extended;
+};
+#endif
+
int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
struct x25_address *calling_addr)
{
@@ -1387,6 +1397,115 @@ static struct net_proto_family x25_famil
.owner = THIS_MODULE,
};
+#ifdef CONFIG_COMPAT
+static int compat_x25_subscr_ioctl(unsigned int cmd,
+ struct compat_x25_subscrip_struct __user *x25_subscr32)
+{
+ struct compat_x25_subscrip_struct x25_subscr;
+ struct x25_neigh *nb;
+ struct net_device *dev;
+ int rc = -EINVAL;
+
+ rc = -EFAULT;
+ if(copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
+ goto out;
+
+ rc = -EINVAL;
+ if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
+ goto out;
+
+ if ((nb = x25_get_neigh(dev)) == NULL)
+ goto out_dev_put;
+
+ dev_put(dev);
+
+ if(cmd == SIOCX25GSUBSCRIP) {
+ x25_subscr.extended = nb->extended;
+ x25_subscr.global_facil_mask = nb->global_facil_mask;
+ rc = copy_to_user(x25_subscr32, &x25_subscr,
+ sizeof(*x25_subscr32)) ? -EFAULT : 0;
+ } else {
+ rc = -EINVAL;
+ if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
+ rc = 0;
+ nb->extended = x25_subscr.extended;
+ nb->global_facil_mask = x25_subscr.global_facil_mask;
+ }
+ }
+ x25_neigh_put(nb);
+out:
+ return rc;
+out_dev_put:
+ dev_put(dev);
+ goto out;
+}
+
+static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg)
+{
+ void __user *argp = compat_ptr(arg);
+ struct sock *sk = sock->sk;
+
+ int rc = -ENOIOCTLCMD;
+
+ switch(cmd) {
+ case TIOCOUTQ:
+ case TIOCINQ:
+ rc = x25_ioctl(sock, cmd, (unsigned long)argp);
+ break;
+ case SIOCGSTAMP:
+ rc = -EINVAL;
+ if (sk)
+ rc = compat_sock_get_timestamp(sk,
+ (struct timeval __user*)argp);
+ break;
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ case SIOCGIFDSTADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCGIFNETMASK:
+ case SIOCSIFNETMASK:
+ case SIOCGIFMETRIC:
+ case SIOCSIFMETRIC:
+ rc = -EINVAL;
+ break;
+ case SIOCADDRT:
+ case SIOCDELRT:
+ rc = -EPERM;
+ if(!capable(CAP_NET_ADMIN))
+ break;
+ rc = x25_route_ioctl(cmd, argp);
+ break;
+ case SIOCX25GSUBSCRIP:
+ rc = compat_x25_subscr_ioctl(cmd, argp);
+ break;
+ case SIOCX25SSUBSCRIP:
+ rc = -EPERM;
+ if (!capable(CAP_NET_ADMIN))
+ break;
+ rc = compat_x25_subscr_ioctl(cmd, argp);
+ break;
+ case SIOCX25GFACILITIES:
+ case SIOCX25SFACILITIES:
+ case SIOCX25GCALLUSERDATA:
+ case SIOCX25SCALLUSERDATA:
+ case SIOCX25GCAUSEDIAG:
+ case SIOCX25SCUDMATCHLEN:
+ case SIOCX25CALLACCPTAPPRV:
+ case SIOCX25SENDCALLACCPT:
+ rc = x25_ioctl(sock, cmd, (unsigned long)argp);
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+
+ return rc;
+}
+
+#endif
+
static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.family = AF_X25,
.owner = THIS_MODULE,
@@ -1398,6 +1517,9 @@ static const struct proto_ops SOCKOPS_WR
.getname = x25_getname,
.poll = datagram_poll,
.ioctl = x25_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_x25_ioctl,
+#endif
.listen = x25_listen,
.shutdown = sock_no_shutdown,
.setsockopt = x25_setsockopt,
^ permalink raw reply
* [PATCH 4/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:19 UTC (permalink / raw)
To: netdev, David S. Miller, linux-kenel, x25 maintainer
Cc: Andre Hendry, Arnd Bergmann
This patch allows an x25 server application to run on a 64 bit kernel,
by fixing the following error message from the kernel.
T2 kernel: schedule_timeout:
wrong timeout value ffffffffffffffff from ffffffff88164796
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c
linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15
11:13:50.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:14:06.000000000
+1100
@@ -743,7 +743,7 @@ out:
return rc;
}
-static int x25_wait_for_data(struct sock *sk, int timeout)
+static int x25_wait_for_data(struct sock *sk, long timeout)
{
DECLARE_WAITQUEUE(wait, current);
int rc = 0;
^ permalink raw reply
* [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:22 UTC (permalink / raw)
To: netdev, linux-kenel, x25 maintainer, David S. Miller
Cc: Arnd Bergmann, Andre Hendry
This patch is a re-submit of an earlier patch submitted by Andrew Hendry
that did not make it into the Linux Kernel. Here is some more
information about this patch. Hope this is helpful.
This patch allows use of the optional user facility to insert ITU-T
(http://www.itu.int/ITU-T/) specified DTE facilities in call set-up x25
packets. As this feature is optional; no facilities will be added if the
ioctl is not used, and call setup packet remains the same as before.
If the ioctls provided by the patch are used, then a facility marker
will be added to the x25 packet header so that the called dte address
extension facility can be differentiated from other types of facilities
(as described in the ITU-T X.25 recommendation) that are also allowed in
the x25 packet header.
Facility markers are made up of two octets, and may be present in the
x25 packet headers of call-request, incoming call, call accepted, clear
request, and clear indication packets. The first of the two octets
represents the facility code field and is set to zero by this patch. The
second octet of the marker represents the facility parameter field and
is set to 0x0F because the marker will be inserted before ITU-T type DTE
facilities.
Since according to ITU-T X.25 Recommendation X.25(10/96)- 7.1 "All
networks will support the facility markers with a facility parameter
field set to all ones or to 00001111", therefore this patch should work
with all x.25 networks.
While there are many ITU-T DTE facilities, this patch implements only
the called and calling address extension, with placeholders in the
x25_dte_facilities structure for the rest of the facilities.
Testing
This patch was tested using a cisco xot router connected on its serial
ports to an X.25 network, and on its lan ports to a host running an xotd
daemon.
It is also possible to test this patch using an xotd daemon and an
x25tap patch, where the xotd daemons work back-to-back without actually
using an x.25 network. See www.fyonne.net for details on how to do
this.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/linux/x25.h
linux-2.6.16-rc3/include/linux/x25.h
--- linux-2.6.16-rc3-vanilla/include/linux/x25.h 2006-02-15
10:58:02.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/x25.h 2006-02-15 11:15:32.000000000
+1100
@@ -11,6 +11,8 @@
#ifndef X25_KERNEL_H
#define X25_KERNEL_H
+#include <linux/types.h>
+
#define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0)
#define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1)
#define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2)
@@ -21,6 +23,8 @@
#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
+#define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
+#define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)
/*
* Values for {get,set}sockopt.
@@ -77,6 +81,8 @@ struct x25_subscrip_struct {
#define X25_MASK_PACKET_SIZE 0x04
#define X25_MASK_WINDOW_SIZE 0x08
+#define X25_MASK_CALLING_AE 0x10
+#define X25_MASK_CALLED_AE 0x20
/*
@@ -99,6 +105,26 @@ struct x25_facilities {
};
/*
+* ITU DTE facilities
+* Only the called and calling address
+* extension are currently implemented.
+* The rest are in place to avoid the struct
+* changing size if someone needs them later
+*/
+
+struct x25_dte_facilities {
+ __u16 delay_cumul;
+ __u16 delay_target;
+ __u16 delay_max;
+ __u8 min_throughput;
+ __u8 expedited;
+ __u8 calling_len;
+ __u8 called_len;
+ __u8 calling_ae[20];
+ __u8 called_ae[20];
+};
+
+/*
* Call User Data structure.
*/
struct x25_calluserdata {
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/net/x25.h
linux-2.6.16-rc3/include/net/x25.h
--- linux-2.6.16-rc3-vanilla/include/net/x25.h 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/include/net/x25.h 2006-02-15 11:15:32.000000000
+1100
@@ -101,9 +101,16 @@ enum {
#define X25_FAC_PACKET_SIZE 0x42
#define X25_FAC_WINDOW_SIZE 0x43
-#define X25_MAX_FAC_LEN 20 /* Plenty to spare */
+#define X25_MAX_FAC_LEN 60
#define X25_MAX_CUD_LEN 128
+#define X25_FAC_CALLING_AE 0xCB
+#define X25_FAC_CALLED_AE 0xC9
+
+#define X25_MARKER 0x00
+#define X25_DTE_SERVICES 0x0F
+#define X25_MAX_AE_LEN 32
+
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
@@ -148,6 +155,7 @@ struct x25_sock {
struct timer_list timer;
struct x25_causediag causediag;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
struct x25_calluserdata calluserdata;
unsigned long vc_facil_mask; /* inc_call facilities mask */
};
@@ -180,9 +188,9 @@ extern void x25_establish_link(struct x2
extern void x25_terminate_link(struct x25_neigh *);
/* x25_facilities.c */
-extern int x25_parse_facilities(struct sk_buff *, struct
x25_facilities *, unsigned long *);
-extern int x25_create_facilities(unsigned char *, struct
x25_facilities *, unsigned long);
-extern int x25_negotiate_facilities(struct sk_buff *, struct sock *,
struct x25_facilities *);
+extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities
*, struct x25_dte_facilities *, unsigned long *);
+extern int x25_create_facilities(unsigned char *, struct x25_facilities
*, struct x25_dte_facilities *, unsigned long);
+extern int x25_negotiate_facilities(struct sk_buff *, struct sock *,
struct x25_facilities *, struct x25_dte_facilities *);
extern void x25_limit_facilities(struct x25_facilities *, struct
x25_neigh *);
/* x25_in.c */
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c
linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15
11:15:10.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:15:32.000000000
+1100
@@ -524,6 +524,13 @@ static int x25_create(struct socket *soc
x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
x25->facilities.reverse = X25_DEFAULT_REVERSE;
+ x25->dte_facilities.calling_len = 0;
+ x25->dte_facilities.called_len = 0;
+ memset(x25->dte_facilities.called_ae, '\0',
+ sizeof(x25->dte_facilities.called_ae));
+ memset(x25->dte_facilities.calling_ae, '\0',
+ sizeof(x25->dte_facilities.calling_ae));
+
rc = 0;
out:
return rc;
@@ -560,6 +567,7 @@ static struct sock *x25_make_new(struct
x25->t2 = ox25->t2;
x25->facilities = ox25->facilities;
x25->qbitincl = ox25->qbitincl;
+ x25->dte_facilities = ox25->dte_facilities;
x25->cudmatchlength = ox25->cudmatchlength;
x25->accptapprv = ox25->accptapprv;
@@ -839,6 +847,7 @@ int x25_rx_call_request(struct sk_buff *
struct x25_sock *makex25;
struct x25_address source_addr, dest_addr;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
int len, rc;
/*
@@ -875,7 +884,8 @@ int x25_rx_call_request(struct sk_buff *
/*
* Try to reach a compromise on the requested facilities.
*/
- if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
+ if ((len = x25_negotiate_facilities(skb, sk, &facilities,
+ &dte_facilities)) == -1)
goto out_sock_put;
/*
@@ -906,9 +916,12 @@ int x25_rx_call_request(struct sk_buff *
makex25->source_addr = source_addr;
makex25->neighbour = nb;
makex25->facilities = facilities;
+ makex25->dte_facilities= dte_facilities;
makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
/* ensure no reverse facil on accept */
makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
+ /* ensure no calling address extension on accept */
+ makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
/* Normally all calls are accepted immediatly */
@@ -1315,6 +1328,34 @@ static int x25_ioctl(struct socket *sock
break;
}
+ case SIOCX25GDTEFACILITIES: {
+ rc = copy_to_user(argp, &x25->dte_facilities,
+ sizeof(x25->dte_facilities)) ? -EFAULT : 0;
+ break;
+ }
+
+ case SIOCX25SDTEFACILITIES: {
+ struct x25_dte_facilities dtefacs;
+ rc = -EFAULT;
+ if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
+ break;
+ rc = -EINVAL;
+ if (sk->sk_state != TCP_LISTEN &&
+ sk->sk_state != TCP_CLOSE)
+ break;
+ if (dtefacs.calling_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.calling_ae == NULL)
+ break;
+ if (dtefacs.called_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.called_ae == NULL)
+ break;
+ x25->dte_facilities = dtefacs;
+ rc = 0;
+ break;
+ }
+
case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata;
rc = copy_to_user(argp, &cud,
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_facilities.c
linux-2.6.16-rc3/net/x25/x25_facilities.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_facilities.c 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-15
11:15:32.000000000 +1100
@@ -28,11 +28,12 @@
#include <net/x25.h>
/*
- * Parse a set of facilities into the facilities structure.
Unrecognised
+ * Parse a set of facilities into the facilities structures.
Unrecognised
* facilities are written to the debug log file.
*/
int x25_parse_facilities(struct sk_buff *skb,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
@@ -40,6 +41,16 @@ int x25_parse_facilities(struct sk_buff
*vc_fac_mask = 0;
+ /* The kernel knows which facilities were set on an incoming call
+ * but currently this information is not available to userspace.
+ * Here we give userspace who read incoming call facilities
+ * 0 length to indicate it wasn't set.
+ */
+ dte_facs->calling_len = 0;
+ dte_facs->called_len = 0;
+ memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
+ memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A:
@@ -74,6 +85,10 @@ int x25_parse_facilities(struct sk_buff
facilities->throughput = p[1];
*vc_fac_mask |= X25_MASK_THROUGHPUT;
break;
+
+ case X25_MARKER:
+ break;
+
default:
printk(KERN_DEBUG "X.25: unknown facility "
"%02X, value %02X\n",
@@ -112,9 +127,30 @@ int x25_parse_facilities(struct sk_buff
len -= 4;
break;
case X25_FAC_CLASS_D:
- printk(KERN_DEBUG "X.25: unknown facility %02X, "
- "length %d, values %02X, %02X, %02X, %02X\n",
- p[0], p[1], p[2], p[3], p[4], p[5]);
+ switch (*p) {
+ case X25_FAC_CALLING_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->calling_len = p[2];
+ memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLING_AE;
+ break;
+
+ case X25_FAC_CALLED_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->called_len = p[2];
+ memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLED_AE;
+ break;
+
+ default:
+ printk(KERN_DEBUG "X.25: unknown facility %02X,"
+ "length %d, values %02X, %02X, %02X, %02X\n",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ break;
+ }
+
len -= p[1] + 2;
p += p[1] + 2;
break;
@@ -129,6 +165,7 @@ int x25_parse_facilities(struct sk_buff
*/
int x25_create_facilities(unsigned char *buffer,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
@@ -168,6 +205,34 @@ int x25_create_facilities(unsigned char
*p++ = facilities->winsize_out ? : facilities->winsize_in;
}
+ if ((facil_mask & X25_MASK_CALLING_AE) ||
+ (facil_mask & X25_MASK_CALLED_AE)) {
+ *p++ = X25_MARKER;
+ *p++ = X25_DTE_SERVICES;
+ }
+
+ if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
+ unsigned bytecount = (dte_facs->calling_len % 2) ?
+ dte_facs->calling_len / 2 + 1 :
+ dte_facs->calling_len / 2;
+ *p++ = X25_FAC_CALLING_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->calling_len;
+ memcpy(p, dte_facs->calling_ae, bytecount);
+ p+=bytecount;
+ }
+
+ if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
+ unsigned bytecount = (dte_facs->called_len % 2) ?
+ dte_facs->called_len / 2 + 1 :
+ dte_facs->called_len / 2;
+ *p++ = X25_FAC_CALLED_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->called_len;
+ memcpy(p, dte_facs->called_ae, bytecount);
+ p+=bytecount;
+ }
+
len = p - buffer;
buffer[0] = len - 1;
@@ -180,7 +245,8 @@ int x25_create_facilities(unsigned char
* The only real problem is with reverse charging.
*/
int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
- struct x25_facilities *new)
+ struct x25_facilities *new,
+ struct x25_dte_facilities *dte)
{
struct x25_sock *x25 = x25_sk(sk);
struct x25_facilities *ours = &x25->facilities;
@@ -190,7 +256,7 @@ int x25_negotiate_facilities(struct sk_b
memset(&theirs, 0, sizeof(theirs));
memcpy(new, ours, sizeof(*new));
- len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask);
+ len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
/*
* They want reverse charging, we won't accept it.
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_in.c
linux-2.6.16-rc3/net/x25/x25_in.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_in.c 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_in.c 2006-02-15 11:15:32.000000000
+1100
@@ -106,7 +106,8 @@ static int x25_state1_machine(struct soc
skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
skb_pull(skb,
x25_parse_facilities(skb, &x25->facilities,
- &x25->vc_facil_mask));
+ &x25->dte_facilities,
+ &x25->vc_facil_mask));
/*
* Copy any Call User Data.
*/
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_subr.c
linux-2.6.16-rc3/net/x25/x25_subr.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_subr.c 2006-02-15
10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_subr.c 2006-02-15 11:15:32.000000000
+1100
@@ -191,7 +191,8 @@ void x25_write_internal(struct sock *sk,
memcpy(dptr, addresses, len);
len = x25_create_facilities(facilities,
&x25->facilities,
- x25->neighbour->global_facil_mask);
+ &x25->dte_facilities,
+ x25->neighbour->global_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
dptr = skb_put(skb, x25->calluserdata.cudlength);
@@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk,
*dptr++ = 0x00; /* Address lengths */
len = x25_create_facilities(facilities,
&x25->facilities,
+ &x25->dte_facilities,
x25->vc_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
^ permalink raw reply
* [PATCH 6/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:22 UTC (permalink / raw)
To: David S. Miller, x25 maintainer, netdev, linux-kenel
Cc: Andre Hendry, Arnd Bergmann
Allow patch 5 to use 32-64 bit conversion mechanism
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c
linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15
11:17:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:17:20.000000000
+1100
@@ -1529,6 +1529,8 @@ static int compat_x25_ioctl(struct socke
break;
case SIOCX25GFACILITIES:
case SIOCX25SFACILITIES:
+ case SIOCX25GDTEFACILITIES:
+ case SIOCX25SDTEFACILITIES:
case SIOCX25GCALLUSERDATA:
case SIOCX25SCALLUSERDATA:
case SIOCX25GCAUSEDIAG:
^ permalink raw reply
* Re: [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Arnaldo Carvalho de Melo @ 2006-02-15 22:35 UTC (permalink / raw)
To: spereira
Cc: netdev, linux-kenel, x25 maintainer, David S. Miller,
Arnd Bergmann, Andre Hendry
In-Reply-To: <1140042162.8745.30.camel@spereira05.tusc.com.au>
On 2/15/06, Shaun Pereira <spereira@tusc.com.au> wrote:
> + switch (*p) {
> + case X25_FAC_CALLING_AE:
> + if (p[1] > 33)
> + break;
> + dte_facs->calling_len = p[2];
> + memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
> + *vc_fac_mask |= X25_MASK_CALLING_AE;
> + break;
Can this '33' magic number be replaced with a define or sizeof(something)?
- Arnaldo
^ permalink raw reply
* [PATCH 1/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:35 UTC (permalink / raw)
To: David S. Miller, linux-kenel, netdev
Sorry Dave,
My mail client line wrapped the patch. I will resend the lot
Please ignore the previous set.
The following patch provides 32 bit userland ioctl support for modular (x.25 type)
socket ioctls in a 64 bit kernel. Since the the register_ioctl32_conversion()
is now obsolete, this patch provides a mechanism to allow 32 bit user space
ioctls to reach the kernel.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/linux/net.h linux-2.6.16-rc3/include/linux/net.h
--- linux-2.6.16-rc3-vanilla/include/linux/net.h 2006-02-15 10:58:02.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/net.h 2006-02-15 11:02:24.000000000 +1100
@@ -143,6 +143,8 @@ struct proto_ops {
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
+ int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
+ unsigned long arg);
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
@@ -247,6 +249,8 @@ SOCKCALL_UWRAP(name, poll, (struct file
(file, sock, wait)) \
SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \
unsigned long arg), (sock, cmd, arg)) \
+SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
+ unsigned long arg), (sock, cmd, arg)) \
SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
@@ -271,6 +275,7 @@ static const struct proto_ops name##_ops
.getname = __lock_##name##_getname, \
.poll = __lock_##name##_poll, \
.ioctl = __lock_##name##_ioctl, \
+ .compat_ioctl = __lock_##name##_compat_ioctl, \
.listen = __lock_##name##_listen, \
.shutdown = __lock_##name##_shutdown, \
.setsockopt = __lock_##name##_setsockopt, \
@@ -279,6 +284,7 @@ static const struct proto_ops name##_ops
.recvmsg = __lock_##name##_recvmsg, \
.mmap = __lock_##name##_mmap, \
};
+
#endif
#define MODULE_ALIAS_NETPROTO(proto) \
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/socket.c linux-2.6.16-rc3/net/socket.c
--- linux-2.6.16-rc3-vanilla/net/socket.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/socket.c 2006-02-15 11:02:24.000000000 +1100
@@ -109,6 +109,10 @@ static unsigned int sock_poll(struct fil
struct poll_table_struct *wait);
static long sock_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+#endif
static int sock_fasync(int fd, struct file *filp, int on);
static ssize_t sock_readv(struct file *file, const struct iovec *vector,
unsigned long count, loff_t *ppos);
@@ -130,6 +134,9 @@ static struct file_operations socket_fil
.aio_write = sock_aio_write,
.poll = sock_poll,
.unlocked_ioctl = sock_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_sock_ioctl,
+#endif
.mmap = sock_mmap,
.open = sock_no_open, /* special open code to disallow open via /proc */
.release = sock_close,
@@ -2089,6 +2096,20 @@ void socket_seq_show(struct seq_file *se
}
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+ struct socket *sock;
+ sock = file->private_data;
+
+ int ret = -ENOIOCTLCMD;
+ if(sock->ops->compat_ioctl)
+ ret = sock->ops->compat_ioctl(sock, cmd, arg);
+
+ return ret;
+}
+#endif
+
/* ABI emulation layers need these two */
EXPORT_SYMBOL(move_addr_to_kernel);
EXPORT_SYMBOL(move_addr_to_user);
^ permalink raw reply
* [PATCH 2/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:36 UTC (permalink / raw)
To: David S. Miller, netdev, linux-kenel
32 bit modular socket ioctl emulation for 64 bit kernel
This patch is the first step towards migration of the 'handler functions'
for 32-64 bit userspace-kernel conversion, away from the ioctl32_hash_table.
It will be used by the x25 socket layer.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/net/compat.h linux-2.6.16-rc3/include/net/compat.h
--- linux-2.6.16-rc3-vanilla/include/net/compat.h 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/include/net/compat.h 2006-02-15 11:09:00.000000000 +1100
@@ -23,6 +23,8 @@ struct compat_cmsghdr {
compat_int_t cmsg_type;
};
+extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
+
#else /* defined(CONFIG_COMPAT) */
#define compat_msghdr msghdr /* to avoid compiler warnings */
#endif /* defined(CONFIG_COMPAT) */
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/compat.c linux-2.6.16-rc3/net/compat.c
--- linux-2.6.16-rc3-vanilla/net/compat.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/compat.c 2006-02-15 11:09:00.000000000 +1100
@@ -503,6 +503,23 @@ static int do_get_sock_timeout(int fd, i
return err;
}
+int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
+{
+ struct compat_timeval __user *ctv
+ = (struct compat_timeval __user*) userstamp;
+ int err = -ENOENT;
+ if(!sock_flag(sk, SOCK_TIMESTAMP))
+ sock_enable_timestamp(sk);
+ if(sk->sk_stamp.tv_sec == -1)
+ return err;
+ if(sk->sk_stamp.tv_sec == 0)
+ do_gettimeofday(&sk->sk_stamp);
+ if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) |
+ put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+ err = -EFAULT;
+ return err;
+}
+
asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -602,3 +619,5 @@ asmlinkage long compat_sys_socketcall(in
}
return ret;
}
+
+EXPORT_SYMBOL(compat_sock_get_timestamp);
^ permalink raw reply
* [PATCH 3/6] x25: Allow 32 bit socket ioctl in 64 bit kerne
From: Shaun Pereira @ 2006-02-15 22:38 UTC (permalink / raw)
To: David S. Miller, linux-kenel, netdev
32 bit modular socket ioctl emulation for 64 bit kernel
This patch allows 32 bit x25 module structures to be passed to
a 64 bit kernel via ioctl using the new compat_sock_ioctl registration
mechanism instead of the obsolete 'register_ioctl32_conversion into hash table'
mechanism.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:12:30.000000000 +1100
@@ -55,6 +55,8 @@
#include <linux/notifier.h>
#include <linux/init.h>
#include <net/x25.h>
+#include <linux/compat.h>
+#include <net/compat.h>
int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
int sysctl_x25_call_request_timeout = X25_DEFAULT_T21;
@@ -69,6 +71,14 @@ static const struct proto_ops x25_proto_
static struct x25_address null_x25_address = {" "};
+#ifdef CONFIG_COMPAT
+struct compat_x25_subscrip_struct {
+ char device[200-sizeof(compat_ulong_t)];
+ compat_ulong_t global_facil_mask;
+ compat_uint_t extended;
+};
+#endif
+
int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
struct x25_address *calling_addr)
{
@@ -1387,6 +1397,115 @@ static struct net_proto_family x25_famil
.owner = THIS_MODULE,
};
+#ifdef CONFIG_COMPAT
+static int compat_x25_subscr_ioctl(unsigned int cmd,
+ struct compat_x25_subscrip_struct __user *x25_subscr32)
+{
+ struct compat_x25_subscrip_struct x25_subscr;
+ struct x25_neigh *nb;
+ struct net_device *dev;
+ int rc = -EINVAL;
+
+ rc = -EFAULT;
+ if(copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
+ goto out;
+
+ rc = -EINVAL;
+ if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
+ goto out;
+
+ if ((nb = x25_get_neigh(dev)) == NULL)
+ goto out_dev_put;
+
+ dev_put(dev);
+
+ if(cmd == SIOCX25GSUBSCRIP) {
+ x25_subscr.extended = nb->extended;
+ x25_subscr.global_facil_mask = nb->global_facil_mask;
+ rc = copy_to_user(x25_subscr32, &x25_subscr,
+ sizeof(*x25_subscr32)) ? -EFAULT : 0;
+ } else {
+ rc = -EINVAL;
+ if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
+ rc = 0;
+ nb->extended = x25_subscr.extended;
+ nb->global_facil_mask = x25_subscr.global_facil_mask;
+ }
+ }
+ x25_neigh_put(nb);
+out:
+ return rc;
+out_dev_put:
+ dev_put(dev);
+ goto out;
+}
+
+static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = compat_ptr(arg);
+ struct sock *sk = sock->sk;
+
+ int rc = -ENOIOCTLCMD;
+
+ switch(cmd) {
+ case TIOCOUTQ:
+ case TIOCINQ:
+ rc = x25_ioctl(sock, cmd, (unsigned long)argp);
+ break;
+ case SIOCGSTAMP:
+ rc = -EINVAL;
+ if (sk)
+ rc = compat_sock_get_timestamp(sk,
+ (struct timeval __user*)argp);
+ break;
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ case SIOCGIFDSTADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCGIFNETMASK:
+ case SIOCSIFNETMASK:
+ case SIOCGIFMETRIC:
+ case SIOCSIFMETRIC:
+ rc = -EINVAL;
+ break;
+ case SIOCADDRT:
+ case SIOCDELRT:
+ rc = -EPERM;
+ if(!capable(CAP_NET_ADMIN))
+ break;
+ rc = x25_route_ioctl(cmd, argp);
+ break;
+ case SIOCX25GSUBSCRIP:
+ rc = compat_x25_subscr_ioctl(cmd, argp);
+ break;
+ case SIOCX25SSUBSCRIP:
+ rc = -EPERM;
+ if (!capable(CAP_NET_ADMIN))
+ break;
+ rc = compat_x25_subscr_ioctl(cmd, argp);
+ break;
+ case SIOCX25GFACILITIES:
+ case SIOCX25SFACILITIES:
+ case SIOCX25GCALLUSERDATA:
+ case SIOCX25SCALLUSERDATA:
+ case SIOCX25GCAUSEDIAG:
+ case SIOCX25SCUDMATCHLEN:
+ case SIOCX25CALLACCPTAPPRV:
+ case SIOCX25SENDCALLACCPT:
+ rc = x25_ioctl(sock, cmd, (unsigned long)argp);
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+
+ return rc;
+}
+
+#endif
+
static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.family = AF_X25,
.owner = THIS_MODULE,
@@ -1398,6 +1517,9 @@ static const struct proto_ops SOCKOPS_WR
.getname = x25_getname,
.poll = datagram_poll,
.ioctl = x25_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_x25_ioctl,
+#endif
.listen = x25_listen,
.shutdown = sock_no_shutdown,
.setsockopt = x25_setsockopt,
^ permalink raw reply
* [PATCH 4/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:39 UTC (permalink / raw)
To: linux-kenel, David S. Miller, netdev
32 bit modular socket ioctl emulation for 64 bit kernel
This patch allows an x25 server application to run on a 64 bit kernel, by
fixing the following error message from the kernel.
T2 kernel: schedule_timeout:
wrong timeout value ffffffffffffffff from ffffffff88164796
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15 11:13:50.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:14:06.000000000 +1100
@@ -743,7 +743,7 @@ out:
return rc;
}
-static int x25_wait_for_data(struct sock *sk, int timeout)
+static int x25_wait_for_data(struct sock *sk, long timeout)
{
DECLARE_WAITQUEUE(wait, current);
int rc = 0;
^ permalink raw reply
* [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:41 UTC (permalink / raw)
To: linux-kenel, netdev, David S. Miller
32 bit modular socket ioctl emulation for 64 bit kernel
This patch is a re-submit of an earlier patch submitted by Andrew Hendry
that did not make it into the Linux Kernel. Here is some more information
about this patch.
This patch allows use of the optional user facility to insert ITU-T
(http://www.itu.int/ITU-T/) specified DTE facilities in call set-up x25 packets.
This feature is optional; no facilities will be added if the ioctl is not used,
and call setup packet remains the same as before.
If the ioctls provided by the patch are used, then a facility marker will be
added to the x25 packet header so that the called dte address extension
facility can be differentiated from other types of facilities (as described
in the ITU-T X.25 recommendation) that are also allowed in the x25 packet header.
Facility markers are made up of two octets, and may be present in the x25 packet
headers of call-request, incoming call, call accepted, clear request,
and clear indication packets. The first of the two octets represents the
facility code field and is set to zero by this patch. The second octet of the
marker represents the facility parameter field and is set to 0x0F because the
marker will be inserted before ITU-T type DTE facilities.
Since according to ITU-T X.25 Recommendation X.25(10/96)- 7.1 "All networks
will support the facility markers with a facility parameter field set to
all ones or to 00001111", therefore this patch should work with all x.25
networks.
While there are many ITU-T DTE facilities, this patch implements only the
called and calling address extension, with placeholders in the x25_dte_facilities
structure for the rest of the facilities.
Testing
This patch was tested using a cisco xot router connected on its serial ports
to an X.25 network, and on its lan ports to a host running an xotd daemon.
It is also possible to test this patch using an xotd daemon and an x25tap patch,
where the xotd daemons work back-to-back without actually using an x.25 network.
See www.fyonne.net for details on how to do this.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/linux/x25.h linux-2.6.16-rc3/include/linux/x25.h
--- linux-2.6.16-rc3-vanilla/include/linux/x25.h 2006-02-15 10:58:02.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/x25.h 2006-02-15 11:15:32.000000000 +1100
@@ -11,6 +11,8 @@
#ifndef X25_KERNEL_H
#define X25_KERNEL_H
+#include <linux/types.h>
+
#define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0)
#define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1)
#define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2)
@@ -21,6 +23,8 @@
#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
+#define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
+#define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)
/*
* Values for {get,set}sockopt.
@@ -77,6 +81,8 @@ struct x25_subscrip_struct {
#define X25_MASK_PACKET_SIZE 0x04
#define X25_MASK_WINDOW_SIZE 0x08
+#define X25_MASK_CALLING_AE 0x10
+#define X25_MASK_CALLED_AE 0x20
/*
@@ -99,6 +105,26 @@ struct x25_facilities {
};
/*
+* ITU DTE facilities
+* Only the called and calling address
+* extension are currently implemented.
+* The rest are in place to avoid the struct
+* changing size if someone needs them later
+*/
+
+struct x25_dte_facilities {
+ __u16 delay_cumul;
+ __u16 delay_target;
+ __u16 delay_max;
+ __u8 min_throughput;
+ __u8 expedited;
+ __u8 calling_len;
+ __u8 called_len;
+ __u8 calling_ae[20];
+ __u8 called_ae[20];
+};
+
+/*
* Call User Data structure.
*/
struct x25_calluserdata {
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/net/x25.h linux-2.6.16-rc3/include/net/x25.h
--- linux-2.6.16-rc3-vanilla/include/net/x25.h 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/include/net/x25.h 2006-02-15 11:15:32.000000000 +1100
@@ -101,9 +101,16 @@ enum {
#define X25_FAC_PACKET_SIZE 0x42
#define X25_FAC_WINDOW_SIZE 0x43
-#define X25_MAX_FAC_LEN 20 /* Plenty to spare */
+#define X25_MAX_FAC_LEN 60
#define X25_MAX_CUD_LEN 128
+#define X25_FAC_CALLING_AE 0xCB
+#define X25_FAC_CALLED_AE 0xC9
+
+#define X25_MARKER 0x00
+#define X25_DTE_SERVICES 0x0F
+#define X25_MAX_AE_LEN 32
+
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
@@ -148,6 +155,7 @@ struct x25_sock {
struct timer_list timer;
struct x25_causediag causediag;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
struct x25_calluserdata calluserdata;
unsigned long vc_facil_mask; /* inc_call facilities mask */
};
@@ -180,9 +188,9 @@ extern void x25_establish_link(struct x2
extern void x25_terminate_link(struct x25_neigh *);
/* x25_facilities.c */
-extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *);
-extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long);
-extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *);
+extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long *);
+extern int x25_create_facilities(unsigned char *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long);
+extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *, struct x25_dte_facilities *);
extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);
/* x25_in.c */
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15 11:15:10.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:15:32.000000000 +1100
@@ -524,6 +524,13 @@ static int x25_create(struct socket *soc
x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
x25->facilities.reverse = X25_DEFAULT_REVERSE;
+ x25->dte_facilities.calling_len = 0;
+ x25->dte_facilities.called_len = 0;
+ memset(x25->dte_facilities.called_ae, '\0',
+ sizeof(x25->dte_facilities.called_ae));
+ memset(x25->dte_facilities.calling_ae, '\0',
+ sizeof(x25->dte_facilities.calling_ae));
+
rc = 0;
out:
return rc;
@@ -560,6 +567,7 @@ static struct sock *x25_make_new(struct
x25->t2 = ox25->t2;
x25->facilities = ox25->facilities;
x25->qbitincl = ox25->qbitincl;
+ x25->dte_facilities = ox25->dte_facilities;
x25->cudmatchlength = ox25->cudmatchlength;
x25->accptapprv = ox25->accptapprv;
@@ -839,6 +847,7 @@ int x25_rx_call_request(struct sk_buff *
struct x25_sock *makex25;
struct x25_address source_addr, dest_addr;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
int len, rc;
/*
@@ -875,7 +884,8 @@ int x25_rx_call_request(struct sk_buff *
/*
* Try to reach a compromise on the requested facilities.
*/
- if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
+ if ((len = x25_negotiate_facilities(skb, sk, &facilities,
+ &dte_facilities)) == -1)
goto out_sock_put;
/*
@@ -906,9 +916,12 @@ int x25_rx_call_request(struct sk_buff *
makex25->source_addr = source_addr;
makex25->neighbour = nb;
makex25->facilities = facilities;
+ makex25->dte_facilities= dte_facilities;
makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
/* ensure no reverse facil on accept */
makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
+ /* ensure no calling address extension on accept */
+ makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
/* Normally all calls are accepted immediatly */
@@ -1315,6 +1328,34 @@ static int x25_ioctl(struct socket *sock
break;
}
+ case SIOCX25GDTEFACILITIES: {
+ rc = copy_to_user(argp, &x25->dte_facilities,
+ sizeof(x25->dte_facilities)) ? -EFAULT : 0;
+ break;
+ }
+
+ case SIOCX25SDTEFACILITIES: {
+ struct x25_dte_facilities dtefacs;
+ rc = -EFAULT;
+ if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
+ break;
+ rc = -EINVAL;
+ if (sk->sk_state != TCP_LISTEN &&
+ sk->sk_state != TCP_CLOSE)
+ break;
+ if (dtefacs.calling_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.calling_ae == NULL)
+ break;
+ if (dtefacs.called_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.called_ae == NULL)
+ break;
+ x25->dte_facilities = dtefacs;
+ rc = 0;
+ break;
+ }
+
case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata;
rc = copy_to_user(argp, &cud,
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_facilities.c linux-2.6.16-rc3/net/x25/x25_facilities.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_facilities.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-15 11:15:32.000000000 +1100
@@ -28,11 +28,12 @@
#include <net/x25.h>
/*
- * Parse a set of facilities into the facilities structure. Unrecognised
+ * Parse a set of facilities into the facilities structures. Unrecognised
* facilities are written to the debug log file.
*/
int x25_parse_facilities(struct sk_buff *skb,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
@@ -40,6 +41,16 @@ int x25_parse_facilities(struct sk_buff
*vc_fac_mask = 0;
+ /* The kernel knows which facilities were set on an incoming call
+ * but currently this information is not available to userspace.
+ * Here we give userspace who read incoming call facilities
+ * 0 length to indicate it wasn't set.
+ */
+ dte_facs->calling_len = 0;
+ dte_facs->called_len = 0;
+ memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
+ memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A:
@@ -74,6 +85,10 @@ int x25_parse_facilities(struct sk_buff
facilities->throughput = p[1];
*vc_fac_mask |= X25_MASK_THROUGHPUT;
break;
+
+ case X25_MARKER:
+ break;
+
default:
printk(KERN_DEBUG "X.25: unknown facility "
"%02X, value %02X\n",
@@ -112,9 +127,30 @@ int x25_parse_facilities(struct sk_buff
len -= 4;
break;
case X25_FAC_CLASS_D:
- printk(KERN_DEBUG "X.25: unknown facility %02X, "
- "length %d, values %02X, %02X, %02X, %02X\n",
- p[0], p[1], p[2], p[3], p[4], p[5]);
+ switch (*p) {
+ case X25_FAC_CALLING_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->calling_len = p[2];
+ memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLING_AE;
+ break;
+
+ case X25_FAC_CALLED_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->called_len = p[2];
+ memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLED_AE;
+ break;
+
+ default:
+ printk(KERN_DEBUG "X.25: unknown facility %02X,"
+ "length %d, values %02X, %02X, %02X, %02X\n",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ break;
+ }
+
len -= p[1] + 2;
p += p[1] + 2;
break;
@@ -129,6 +165,7 @@ int x25_parse_facilities(struct sk_buff
*/
int x25_create_facilities(unsigned char *buffer,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
@@ -168,6 +205,34 @@ int x25_create_facilities(unsigned char
*p++ = facilities->winsize_out ? : facilities->winsize_in;
}
+ if ((facil_mask & X25_MASK_CALLING_AE) ||
+ (facil_mask & X25_MASK_CALLED_AE)) {
+ *p++ = X25_MARKER;
+ *p++ = X25_DTE_SERVICES;
+ }
+
+ if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
+ unsigned bytecount = (dte_facs->calling_len % 2) ?
+ dte_facs->calling_len / 2 + 1 :
+ dte_facs->calling_len / 2;
+ *p++ = X25_FAC_CALLING_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->calling_len;
+ memcpy(p, dte_facs->calling_ae, bytecount);
+ p+=bytecount;
+ }
+
+ if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
+ unsigned bytecount = (dte_facs->called_len % 2) ?
+ dte_facs->called_len / 2 + 1 :
+ dte_facs->called_len / 2;
+ *p++ = X25_FAC_CALLED_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->called_len;
+ memcpy(p, dte_facs->called_ae, bytecount);
+ p+=bytecount;
+ }
+
len = p - buffer;
buffer[0] = len - 1;
@@ -180,7 +245,8 @@ int x25_create_facilities(unsigned char
* The only real problem is with reverse charging.
*/
int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
- struct x25_facilities *new)
+ struct x25_facilities *new,
+ struct x25_dte_facilities *dte)
{
struct x25_sock *x25 = x25_sk(sk);
struct x25_facilities *ours = &x25->facilities;
@@ -190,7 +256,7 @@ int x25_negotiate_facilities(struct sk_b
memset(&theirs, 0, sizeof(theirs));
memcpy(new, ours, sizeof(*new));
- len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask);
+ len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
/*
* They want reverse charging, we won't accept it.
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_in.c linux-2.6.16-rc3/net/x25/x25_in.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_in.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_in.c 2006-02-15 11:15:32.000000000 +1100
@@ -106,7 +106,8 @@ static int x25_state1_machine(struct soc
skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
skb_pull(skb,
x25_parse_facilities(skb, &x25->facilities,
- &x25->vc_facil_mask));
+ &x25->dte_facilities,
+ &x25->vc_facil_mask));
/*
* Copy any Call User Data.
*/
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/x25_subr.c linux-2.6.16-rc3/net/x25/x25_subr.c
--- linux-2.6.16-rc3-vanilla/net/x25/x25_subr.c 2006-02-15 10:58:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_subr.c 2006-02-15 11:15:32.000000000 +1100
@@ -191,7 +191,8 @@ void x25_write_internal(struct sock *sk,
memcpy(dptr, addresses, len);
len = x25_create_facilities(facilities,
&x25->facilities,
- x25->neighbour->global_facil_mask);
+ &x25->dte_facilities,
+ x25->neighbour->global_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
dptr = skb_put(skb, x25->calluserdata.cudlength);
@@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk,
*dptr++ = 0x00; /* Address lengths */
len = x25_create_facilities(facilities,
&x25->facilities,
+ &x25->dte_facilities,
x25->vc_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
^ permalink raw reply
* [PATCH 6/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-15 22:43 UTC (permalink / raw)
To: David S. Miller, netdev, linux-kenel
Allow patch 5 to use 32-64 bit conversion mechanism
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/x25/af_x25.c linux-2.6.16-rc3/net/x25/af_x25.c
--- linux-2.6.16-rc3-vanilla/net/x25/af_x25.c 2006-02-15 11:17:03.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-15 11:17:20.000000000 +1100
@@ -1529,6 +1529,8 @@ static int compat_x25_ioctl(struct socke
break;
case SIOCX25GFACILITIES:
case SIOCX25SFACILITIES:
+ case SIOCX25GDTEFACILITIES:
+ case SIOCX25SDTEFACILITIES:
case SIOCX25GCALLUSERDATA:
case SIOCX25SCALLUSERDATA:
case SIOCX25GCAUSEDIAG:
^ permalink raw reply
* Re: [XFRM]: Fix SNAT-related crash in xfrm4_output_finish
From: David S. Miller @ 2006-02-15 23:14 UTC (permalink / raw)
To: kaber; +Cc: netdev, netfilter-devel, herbert
In-Reply-To: <43F3640B.6070809@trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 15 Feb 2006 18:25:31 +0100
> This patch fixes the crash in xfrm4_output_finish reported by
> multiple people.
Looks good, applied.
Thanks Patrick.
^ permalink raw reply
* Re: [NETFILTER]: Don't invoke okfn in CONFIG_NETFILTER=n variant of nf_hook()
From: David S. Miller @ 2006-02-15 23:18 UTC (permalink / raw)
To: kaber; +Cc: netdev, netfilter-devel, herbert
In-Reply-To: <43F36418.1050107@trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 15 Feb 2006 18:25:44 +0100
> Another fix related to the netfilter IPsec patches.
Applied, thanks a lot.
^ permalink raw reply
* Re: [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-16 5:40 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: netdev, linux-kenel, x25 maintainer, David S. Miller,
Arnd Bergmann, Andre Hendry
In-Reply-To: <39e6f6c70602151435r5b965670oab580c75bbaee7ab@mail.gmail.com>
Thanks for that Aranaldo
I have corrected this so as to be compliant with OSI Network services
for DTE facilities and rebuilt and retested the patches
Corrected patches follow.
On Wed, 2006-02-15 at 20:35 -0200, Arnaldo Carvalho de Melo wrote:
> On 2/15/06, Shaun Pereira <spereira@tusc.com.au> wrote:
>
> > + switch (*p) {
> > + case X25_FAC_CALLING_AE:
> > + if (p[1] > 33)
> > + break;
> > + dte_facs->calling_len = p[2];
> > + memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
> > + *vc_fac_mask |= X25_MASK_CALLING_AE;
> > + break;
>
> Can this '33' magic number be replaced with a define or sizeof(something)?
>
> - Arnaldo
^ permalink raw reply
* [PATCH 1/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-16 5:41 UTC (permalink / raw)
To: linux-kenel, netdev, David S. Miller
Includes correction from Arnaldo's suggestions.
32 bit modular socket ioctl emulation for 64 bit kernel
The following patch provides 32 bit userland ioctl support for modular (x.25 type)
socket ioctls in a 64 bit kernel. Since the the register_ioctl32_conversion()
is now obsolete, this patch provides a mechanism to allow 32 bit user space
ioctls to reach the kernel.
Signed-off-by:Shaun Pereira <spereira@tusc.com.au>
Acked-by: Arnd Bergmann <arnd@arndb.de>
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/include/linux/net.h linux-2.6.16-rc3/include/linux/net.h
--- linux-2.6.16-rc3-vanilla/include/linux/net.h 2006-02-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/net.h 2006-02-16 14:57:36.000000000 +1100
@@ -143,6 +143,8 @@ struct proto_ops {
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
+ int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
+ unsigned long arg);
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
@@ -247,6 +249,8 @@ SOCKCALL_UWRAP(name, poll, (struct file
(file, sock, wait)) \
SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \
unsigned long arg), (sock, cmd, arg)) \
+SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
+ unsigned long arg), (sock, cmd, arg)) \
SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
@@ -271,6 +275,7 @@ static const struct proto_ops name##_ops
.getname = __lock_##name##_getname, \
.poll = __lock_##name##_poll, \
.ioctl = __lock_##name##_ioctl, \
+ .compat_ioctl = __lock_##name##_compat_ioctl, \
.listen = __lock_##name##_listen, \
.shutdown = __lock_##name##_shutdown, \
.setsockopt = __lock_##name##_setsockopt, \
@@ -279,6 +284,7 @@ static const struct proto_ops name##_ops
.recvmsg = __lock_##name##_recvmsg, \
.mmap = __lock_##name##_mmap, \
};
+
#endif
#define MODULE_ALIAS_NETPROTO(proto) \
diff -uprN -X dontdiff linux-2.6.16-rc3-vanilla/net/socket.c linux-2.6.16-rc3/net/socket.c
--- linux-2.6.16-rc3-vanilla/net/socket.c 2006-02-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/net/socket.c 2006-02-16 14:57:36.000000000 +1100
@@ -109,6 +109,10 @@ static unsigned int sock_poll(struct fil
struct poll_table_struct *wait);
static long sock_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+#endif
static int sock_fasync(int fd, struct file *filp, int on);
static ssize_t sock_readv(struct file *file, const struct iovec *vector,
unsigned long count, loff_t *ppos);
@@ -130,6 +134,9 @@ static struct file_operations socket_fil
.aio_write = sock_aio_write,
.poll = sock_poll,
.unlocked_ioctl = sock_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_sock_ioctl,
+#endif
.mmap = sock_mmap,
.open = sock_no_open, /* special open code to disallow open via /proc */
.release = sock_close,
@@ -2089,6 +2096,20 @@ void socket_seq_show(struct seq_file *se
}
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+ struct socket *sock;
+ sock = file->private_data;
+
+ int ret = -ENOIOCTLCMD;
+ if(sock->ops->compat_ioctl)
+ ret = sock->ops->compat_ioctl(sock, cmd, arg);
+
+ return ret;
+}
+#endif
+
/* ABI emulation layers need these two */
EXPORT_SYMBOL(move_addr_to_kernel);
EXPORT_SYMBOL(move_addr_to_user);
^ permalink raw reply
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