* [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
* [PATCH 2/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-16 5:42 UTC (permalink / raw)
To: linux-x25, netdev, David S. Miller
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-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/include/net/compat.h 2006-02-16 14:58:58.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-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/net/compat.c 2006-02-16 14:58:58.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-16 5:43 UTC (permalink / raw)
To: linux-kenel, netdev, David S. Miller
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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:18:39.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-16 5:44 UTC (permalink / raw)
To: linux-kenel, netdev, David S. Miller
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-16 15:28:58.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:29:04.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-16 5:46 UTC (permalink / raw)
To: linux-kenel, netdev, David S. Miller
removed magic number 33 as suggested by Arnaldo
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-16 15:26:19.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/x25.h 2006-02-16 15:31:50.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-16 15:26:19.000000000 +1100
+++ linux-2.6.16-rc3/include/net/x25.h 2006-02-16 15:31:50.000000000 +1100
@@ -101,9 +101,17 @@ 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 40 /* Max num of semi-octets in AE - OSI Nw */
+#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */
+
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
@@ -148,6 +156,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 +189,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-16 15:30:17.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:31:50.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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-16 15:31:50.000000000 +1100
@@ -28,18 +28,29 @@
#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,
- unsigned long *vc_fac_mask)
+ struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
+ unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
unsigned int len = *p++;
*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] > X25_MAX_DTE_FACIL_LEN)
+ 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] > X25_MAX_DTE_FACIL_LEN)
+ 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;
@@ -128,8 +164,9 @@ int x25_parse_facilities(struct sk_buff
* Create a set of facilities.
*/
int x25_create_facilities(unsigned char *buffer,
- struct x25_facilities *facilities,
- unsigned long facil_mask)
+ struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
+ unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
int len;
@@ -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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_in.c 2006-02-16 15:31:50.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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_subr.c 2006-02-16 15:31:50.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-16 5:48 UTC (permalink / raw)
To: linux-kenel, David S. Miller, netdev
32 - 64 converstion for patch 5
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-16 15:33:48.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:34:05.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 wireless-2.6] bcm43xx-d80211: fix oops when removing the module
From: Michael Buesch @ 2006-02-16 9:54 UTC (permalink / raw)
To: Jiri Benc; +Cc: NetDev, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
In-Reply-To: <20060216103543.5a96f0a0-IhiK2ZEFs2oCVLCxKZUutA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 704 bytes --]
On Thursday 16 February 2006 10:35, you wrote:
> On Wed, 15 Feb 2006 22:34:35 +0100, Michael Buesch wrote:
> > 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.
>
> Is the tree available somewhere? I'm testing some patches for the d80211
> stack and it will help me if I can pull the latest bcm43xx version to my
> local repository.
sure.
git://bu3sch.de/wireless-2.6
branches dscape-all and softmac-all. The other branches are unused and
the result of the initial linville clone. ;) I should probably clean
it up a little bit, but I did not care, yet.
--
Greetings Michael.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Ingo Oeser @ 2006-02-16 14:18 UTC (permalink / raw)
To: spereira; +Cc: linux-kenel, netdev, David S. Miller
In-Reply-To: <1140068774.4941.26.camel@spereira05.tusc.com.au>
Shaun Pereira wrote:
> removed magic number 33 as suggested by Arnaldo
But are you sure, you use the right substitute for it?
> 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-16 15:26:19.000000000 +1100
> +++ linux-2.6.16-rc3/include/net/x25.h 2006-02-16 15:31:50.000000000 +1100
> @@ -101,9 +101,17 @@ 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 40 /* Max num of semi-octets in AE - OSI Nw */
> +#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */
Are you sure that you don't mean 0x21 (== 33) here?
> 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-16 15:26:25.000000000 +1100
> +++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-16 15:31:50.000000000 +1100
> @@ -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] > X25_MAX_DTE_FACIL_LEN)
Because the magic number 33 was here before ...
> + 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] > X25_MAX_DTE_FACIL_LEN)
...and here
> + 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;
Regards
Ingo Oeser
^ permalink raw reply
* [PATCH 5/6] scsi tgt: scsi target netlink interface
From: Mike Christie @ 2006-02-16 19:53 UTC (permalink / raw)
To: netdev, linux-scsi
This patch implments a netlink interface for the scsi tgt framework.
I was not sure if code using the netlink interface had to get reviewed
by the netdev guys. I am ccing them on this patch and providing
a basic review of why/how we want to use netlink.
I did not think the netdev people wanted to see the scsi and
block layer code, so I am just sending the netlink interface part
of this patchset to netdev. I can resend the other parts if
needed.
The scsi tgt framework, adds support for scsi target mode
cards. So instead of using the scsi card in your box as a initiator/host
you can use it as a target/server.
The reason for the netlink use is becuase the target normally
receives a interrupt indicating that a command or event is
ready to be processed. The scsi card's driver will then call
a scsi lib function which eventually calls scsi_tgt_uspace_send (in
this patch below) to tell userspace to begin to process the request
(userspace contains the state model). Later userspace will call back
into the kernel by sending a netlink msg, and instruct the scsi driver
what to do next. When the scsi driver is done executing the
operation, it will send a netlink message back to userspace
to indicate the success or failure of the operation (using
scsi_tgt_uspace_send_status in the patch below).
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
new file mode 100644
index 0000000..38b35da
--- /dev/null
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -0,0 +1,214 @@
+/*
+ * SCSI target kernel/user interface functions
+ *
+ * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/netlink.h>
+#include <net/tcp.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tgt.h>
+#include <scsi/scsi_tgt_if.h>
+
+#include "scsi_tgt_priv.h"
+
+static int tgtd_pid;
+static struct sock *nl_sk;
+
+static int send_event_res(uint16_t type, struct tgt_event *p,
+ void *data, int dlen, gfp_t flags, pid_t pid)
+{
+ struct tgt_event *ev;
+ struct nlmsghdr *nlh;
+ struct sk_buff *skb;
+ uint32_t len;
+
+ len = NLMSG_SPACE(sizeof(*ev) + dlen);
+ skb = alloc_skb(len, flags);
+ if (!skb)
+ return -ENOMEM;
+
+ nlh = __nlmsg_put(skb, pid, 0, type, len - sizeof(*nlh), 0);
+
+ ev = NLMSG_DATA(nlh);
+ memcpy(ev, p, sizeof(*ev));
+ if (dlen)
+ memcpy(ev->data, data, dlen);
+
+ return netlink_unicast(nl_sk, skb, pid, 0);
+}
+
+int scsi_tgt_uspace_send(struct scsi_cmnd *cmd, struct scsi_lun *lun, gfp_t gfp_mask)
+{
+ struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct tgt_event *ev;
+ struct tgt_cmd *tcmd;
+ int err, len;
+
+ len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct tgt_cmd));
+ /*
+ * TODO: add MAX_COMMAND_SIZE to ev and add mempool
+ */
+ skb = alloc_skb(NLMSG_SPACE(len), gfp_mask);
+ if (!skb)
+ return -ENOMEM;
+
+ nlh = __nlmsg_put(skb, tgtd_pid, 0, TGT_KEVENT_CMD_REQ,
+ len - sizeof(*nlh), 0);
+
+ ev = NLMSG_DATA(nlh);
+ ev->k.cmd_req.host_no = shost->host_no;
+ ev->k.cmd_req.cid = cmd->request->tag;
+ ev->k.cmd_req.data_len = cmd->request_bufflen;
+
+ dprintk("%d %u %u\n", ev->k.cmd_req.host_no, ev->k.cmd_req.cid,
+ ev->k.cmd_req.data_len);
+
+ /* FIXME: we need scsi core to do that. */
+ memcpy(cmd->cmnd, cmd->data_cmnd, MAX_COMMAND_SIZE);
+
+ tcmd = (struct tgt_cmd *) ev->data;
+ memcpy(tcmd->scb, cmd->cmnd, sizeof(tcmd->scb));
+ memcpy(tcmd->lun, lun, sizeof(struct scsi_lun));
+
+ err = netlink_unicast(nl_sk, skb, tgtd_pid, 0);
+ if (err < 0)
+ printk(KERN_ERR "scsi_tgt_uspace_send: could not send skb %d\n",
+ err);
+ return err;
+}
+
+int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+ struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
+ struct tgt_event ev;
+ char dummy[sizeof(struct tgt_cmd)];
+
+ memset(&ev, 0, sizeof(ev));
+ ev.k.cmd_done.host_no = shost->host_no;
+ ev.k.cmd_done.cid = cmd->request->tag;
+ ev.k.cmd_done.result = cmd->result;
+
+ return send_event_res(TGT_KEVENT_CMD_DONE, &ev, dummy, sizeof(dummy),
+ gfp_mask, tgtd_pid);
+}
+
+static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ struct tgt_event *ev = NLMSG_DATA(nlh);
+ int err = 0;
+
+ dprintk("%d %d %d\n", nlh->nlmsg_type,
+ nlh->nlmsg_pid, current->pid);
+
+ switch (nlh->nlmsg_type) {
+ case TGT_UEVENT_TGTD_BIND:
+ tgtd_pid = NETLINK_CREDS(skb)->pid;
+ break;
+ case TGT_UEVENT_CMD_RES:
+ /* TODO: handle multiple cmds in one event */
+ err = scsi_tgt_kspace_exec(ev->u.cmd_res.host_no,
+ ev->u.cmd_res.cid,
+ ev->u.cmd_res.result,
+ ev->u.cmd_res.len,
+ ev->u.cmd_res.offset,
+ ev->u.cmd_res.uaddr,
+ ev->u.cmd_res.rw,
+ ev->u.cmd_res.try_map);
+ break;
+ default:
+ eprintk("unknown type %d\n", nlh->nlmsg_type);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int event_recv_skb(struct sk_buff *skb)
+{
+ int err;
+ uint32_t rlen;
+ struct nlmsghdr *nlh;
+
+ while (skb->len >= NLMSG_SPACE(0)) {
+ nlh = (struct nlmsghdr *) skb->data;
+ if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
+ return 0;
+ rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+ if (rlen > skb->len)
+ rlen = skb->len;
+ err = event_recv_msg(skb, nlh);
+
+ dprintk("%d %d\n", nlh->nlmsg_type, err);
+ /*
+ * TODO for passthru commands the lower level should
+ * probably handle the result or we should modify this
+ */
+ if (nlh->nlmsg_type != TGT_UEVENT_CMD_RES) {
+ struct tgt_event ev;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.k.event_res.err = err;
+ send_event_res(TGT_KEVENT_RESPONSE, &ev, NULL, 0,
+ GFP_KERNEL | __GFP_NOFAIL,
+ nlh->nlmsg_pid);
+ }
+ skb_pull(skb, rlen);
+ }
+ return 0;
+}
+
+static void event_recv(struct sock *sk, int length)
+{
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
+ if (NETLINK_CREDS(skb)->uid) {
+ skb_pull(skb, skb->len);
+ kfree_skb(skb);
+ continue;
+ }
+
+ if (event_recv_skb(skb) && skb->len)
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ else
+ kfree_skb(skb);
+ }
+}
+
+void __exit scsi_tgt_if_exit(void)
+{
+ sock_release(nl_sk->sk_socket);
+}
+
+int __init scsi_tgt_if_init(void)
+{
+ nl_sk = netlink_kernel_create(NETLINK_TGT, 1, event_recv,
+ THIS_MODULE);
+ if (!nl_sk)
+ return -ENOMEM;
+
+ return 0;
+}
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 6a2ccf7..580fb42 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -21,6 +21,7 @@
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
#define NETLINK_GENERIC 16
+#define NETLINK_TGT 17 /* SCSI target */
#define MAX_LINKS 32
diff --git a/include/scsi/scsi_tgt_if.h b/include/scsi/scsi_tgt_if.h
new file mode 100644
index 0000000..da3a808
--- /dev/null
+++ b/include/scsi/scsi_tgt_if.h
@@ -0,0 +1,88 @@
+/*
+ * SCSI target kernel/user interface
+ *
+ * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef __SCSI_TARGET_IF_H
+#define __SCSI_TARGET_IF_H
+
+enum tgt_event_type {
+ /* user -> kernel */
+ TGT_UEVENT_TGTD_BIND,
+ TGT_UEVENT_TARGET_SETUP,
+ TGT_UEVENT_CMD_RES,
+
+ /* kernel -> user */
+ TGT_KEVENT_RESPONSE,
+ TGT_KEVENT_CMD_REQ,
+ TGT_KEVENT_CMD_DONE,
+};
+
+struct tgt_event {
+ /* user-> kernel */
+ union {
+ struct {
+ int pk_fd;
+ } tgtd_bind;
+ struct {
+ int host_no;
+ uint32_t cid;
+ uint32_t len;
+ int result;
+ uint64_t uaddr;
+ uint64_t offset;
+ uint8_t rw;
+ uint8_t try_map;
+ } cmd_res;
+ } u;
+
+ /* kernel -> user */
+ union {
+ struct {
+ int err;
+ } event_res;
+ struct {
+ int host_no;
+ uint32_t cid;
+ uint32_t data_len;
+ uint64_t dev_id;
+ } cmd_req;
+ struct {
+ int host_no;
+ uint32_t cid;
+ int result;
+ } cmd_done;
+ } k;
+
+ /*
+ * I think a pointer is a unsigned long but this struct
+ * gets passed around from the kernel to userspace and
+ * back again so to handle some ppc64 setups where userspace is
+ * 32 bits but the kernel is 64 we do this odd thing
+ */
+ uint64_t data[0];
+} __attribute__ ((aligned (sizeof(uint64_t))));
+
+struct tgt_cmd {
+ uint8_t scb[16];
+ uint8_t lun[8];
+ int tags;
+} __attribute__ ((aligned (sizeof(uint64_t))));
+
+#endif
^ permalink raw reply related
* Re: KERNEL: assertion (!sk->sk_forward_alloc) failed
From: Jan-Frode Myklebust @ 2006-02-16 21:02 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
In-Reply-To: <43EB98B0.4@kernelpanic.ru>
On 2006-02-09, Boris B. Zhmurov <bb@kernelpanic.ru> wrote:
>
>> Is it possible for you to download 2.6.16-rc2 or similar and see if it
>> goes away?
>
> It'll be better, if I get only patch fixs that problem, not all 2.6.16-rc2.
I just got this same warning on a system running 2.6.14.5. It's been
up for 50 days, quite heavily loaded, and I've seen this only once.
Should i be conserned ? Could someone tell me what it means ?
# uname -a
Linux mail 2.6.14.5 #1 SMP Tue Dec 27 14:39:55 CET 2005 i686 i686 i386 GNU/Linux
# dmesg|grep KERNEL
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/core/stream.c (279)
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/ipv4/af_inet.c (148)
# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: on
# ethtool -k eth1
Offload parameters for eth1:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: on
-jf
^ permalink raw reply
* Re: [PATCH 5/6] x25: Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-16 22:51 UTC (permalink / raw)
To: Ingo Oeser; +Cc: linux-kenel, netdev, David S. Miller
In-Reply-To: <200602161518.25157.netdev@axxeo.de>
Thank for reviewing the patch Ingo.
There was a mistake the first time round, lucky for me Arnaldo's comment
about the magic number helped me spot it. When ITU-T DTE facilities are
added to the X.25 header packet the length field has to contain n + 1
bytes where n is the number of bytes needed to hold the calling(or
called address) extension.
The kernel used to check that the maximum number of bytes/allowed-length
is 33. However as I understand the X.25 recommendation for
ITU-T specified DTE facilities to support OSI network services, the
value of n can be a maximum of 20 bytes. This makes the allowable
length 21. By co-incidence 0x21 turned out to be 33 bytes. But I meant
21 bytes. The other decimal value of 40 is the maximum number of semi-
octets in the calling address extension. (Therefore 20 octets + 1 in the
length field).
Now I just have to correct my other mistake .. all these patches have
the same subject...
Regards
Shaun
On Thu, 2006-02-16 at 15:18 +0100, Ingo Oeser wrote:
> Shaun Pereira wrote:
> > removed magic number 33 as suggested by Arnaldo
>
> But are you sure, you use the right substitute for it?
>
> > 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-16 15:26:19.000000000 +1100
> > +++ linux-2.6.16-rc3/include/net/x25.h 2006-02-16 15:31:50.000000000 +1100
> > @@ -101,9 +101,17 @@ 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 40 /* Max num of semi-octets in AE - OSI Nw */
> > +#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */
>
> Are you sure that you don't mean 0x21 (== 33) here?
>
> > 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-16 15:26:25.000000000 +1100
> > +++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-16 15:31:50.000000000 +1100
> > @@ -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] > X25_MAX_DTE_FACIL_LEN)
>
> Because the magic number 33 was here before ...
>
> > + 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] > X25_MAX_DTE_FACIL_LEN)
>
> ...and here
>
> > + 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;
>
> Regards
>
> Ingo Oeser
^ permalink raw reply
* [PATCH 1/6]net:Allow 32 bit socket ioctl in 64 bit kernel
From: Shaun Pereira @ 2006-02-17 5:00 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, linux-kenel, netdev; +Cc: Andre Hendry
From: spereira@tusc.com.au
Since the register_ioctl32_conversion() patch in the kernel
is now obsolete, provide another method 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
* [PATCH 2/6]net:socket timestamp 32 bit handler for 64 bit kernel
From: Shaun Pereira @ 2006-02-17 5:01 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, linux-kenel, netdev; +Cc: Andre Hendry
From: spereira@tusc.com.au
Get socket timestamp handler function that does not
use the ioctl32_hash_table.
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-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/include/net/compat.h 2006-02-16 14:58:58.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-16 14:57:01.000000000 +1100
+++ linux-2.6.16-rc3/net/compat.c 2006-02-16 14:58:58.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:ioctl conversion 32 bit user to 64 bit kernel
From: Shaun Pereira @ 2006-02-17 5:01 UTC (permalink / raw)
To: linux-kenel, netdev, Andrew Morton, David S. Miller; +Cc: Andre Hendry
From: spereira@tusc.com.au
To allow 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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:18:39.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:Fix kernel error message 64 bit kernel
From: Shaun Pereira @ 2006-02-17 5:02 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, netdev, linux-kenel; +Cc: Andre Hendry
From: spereira@tusc.com.au
Fixes the following error from 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-16 15:28:58.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:29:04.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 ITU-T DTE facilities for x25
From: Shaun Pereira @ 2006-02-17 5:02 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, netdev, linux-kenel, Andre Hendry
From: spereira@tusc.com.au
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>
Acked-by:Andrew Hendry <ahendry@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-16 15:26:19.000000000 +1100
+++ linux-2.6.16-rc3/include/linux/x25.h 2006-02-16 15:31:50.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-16 15:26:19.000000000 +1100
+++ linux-2.6.16-rc3/include/net/x25.h 2006-02-16 15:31:50.000000000 +1100
@@ -101,9 +101,17 @@ 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 40 /* Max num of semi-octets in AE - OSI Nw */
+#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */
+
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
@@ -148,6 +156,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 +189,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-16 15:30:17.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:31:50.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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_facilities.c 2006-02-16 15:31:50.000000000 +1100
@@ -28,18 +28,29 @@
#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,
- unsigned long *vc_fac_mask)
+ struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
+ unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
unsigned int len = *p++;
*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] > X25_MAX_DTE_FACIL_LEN)
+ 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] > X25_MAX_DTE_FACIL_LEN)
+ 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;
@@ -128,8 +164,9 @@ int x25_parse_facilities(struct sk_buff
* Create a set of facilities.
*/
int x25_create_facilities(unsigned char *buffer,
- struct x25_facilities *facilities,
- unsigned long facil_mask)
+ struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
+ unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
int len;
@@ -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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_in.c 2006-02-16 15:31:50.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-16 15:26:25.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/x25_subr.c 2006-02-16 15:31:50.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:dte facilities 32 64 ioctl conversion
From: Shaun Pereira @ 2006-02-17 5:02 UTC (permalink / raw)
To: David S. Miller, linux-kenel, netdev, Andrew Morton; +Cc: Andre Hendry
From: spereira@tusc.com.au
Allows dte facility patch to use 32 64 bit ioctl
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-16 15:33:48.000000000 +1100
+++ linux-2.6.16-rc3/net/x25/af_x25.c 2006-02-16 15:34:05.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
* (usagi-users 03606) [PATCH] [NET]: NETFILTER: remove duplicated operation and fix order in skb_clone().
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-02-17 12:51 UTC (permalink / raw)
To: davem; +Cc: netdev, usagi-users, olivier.matz, yoshfuji
In-Reply-To: <43F5A7B2.90803@6wind.com>
Hello.
In article <43F5A7B2.90803@6wind.com> (at Fri, 17 Feb 2006 11:38:42 +0100), Olivier MATZ <olivier.matz@6wind.com> says:
> in skb_clone(), the following code is done twice :
>
> #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
> C(nfct_reasm);
> nf_conntrack_get_reasm(skb->nfct_reasm);
> #endif
David, please apply the fillowing patch.
Thank you.
---
[NET]: NETFILTER: remove duplicated lines and fix order in skb_clone().
Some of netfilter-related members are initalized / copied twice in
skb_clone(). Remove one. Pointed out by Olivier MATZ <olivier.matz@6wind.com>.
And this patch also fixes order of copying / clearing members.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6766f11..2144952 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -411,6 +411,9 @@ struct sk_buff *skb_clone(struct sk_buff
C(pkt_type);
C(ip_summed);
C(priority);
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+ C(ipvs_property);
+#endif
C(protocol);
n->destructor = NULL;
#ifdef CONFIG_NETFILTER
@@ -422,13 +425,6 @@ struct sk_buff *skb_clone(struct sk_buff
C(nfct_reasm);
nf_conntrack_get_reasm(skb->nfct_reasm);
#endif
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
- C(ipvs_property);
-#endif
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- C(nfct_reasm);
- nf_conntrack_get_reasm(skb->nfct_reasm);
-#endif
#ifdef CONFIG_BRIDGE_NETFILTER
C(nf_bridge);
nf_bridge_get(skb->nf_bridge);
--
YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply related
* ANNOUNCE: new DHCP client for linux 2.6.x
From: Stefan Rompf @ 2006-02-17 14:37 UTC (permalink / raw)
To: netdev, linux-kernel
dhcpclient
A DHCP client for linux 2.6, using modern kernel features, (c) 2006
Stefan Rompf.
Motivation
Using a notebook, I'm often traveling between different networks.
After replugging, I always needed to issue a ifdown/ifup sequence
because the DHCP client did not realize the temporary disconnection.
This is an unneeded limitation because since 2.6, the kernel notifies
userspace of these disconnection/reconnection events. Actually is was
me who implemented this feature.
Beginning with 2.6.17, the linux kernel will allow userspace to
influence this signalling, so that for example a wpa supplicant can
tell the dhcpclient that an association has finished and the client
should try to get an IP address.
Of course, you need software that support this feature. Unfortunately,
most existing DHCP clients implemented their statemachine using
siglongjmp() or one huge function, so there was no easy way extending
them. So I wrote a new one.
Features
* RFC2131 compatible DHCP client, tested with ISC dhcpd directly and
via a Cisco IOS relay agent, Cisco IOS DHCP server and dnsmasq.
* uses netlink for interface configuration
* does act on link state messages
* calls a script on every state change to allow updating resolv.conf
etc
* small, compiles with [1]uclibc
Status
Currently, this is alpha software. It shouldn't be used in production
environment, but I'm looking forward for people who like to test it in
different environments and for (reasonable ;-) feature suggestions!
Support
The webpage is at [2]http://www.flamewarmaster.de/software/dhcpclient/
There is a mailing list available on
[3]http://www.flamewarmaster.de/mailman/listinfo/dhcpclient/
References
1. http://www.uclibc.org/
2. http://www.flamewarmaster.de/software/dhcpclient/
3. http://www.flamewarmaster.de/mailman/listinfo/dhcpclient/
^ permalink raw reply
* [PATCH 1/2] pcnet32: Introduce basic AT 2700/01 FTX support
From: Seewer Philippe @ 2006-02-17 16:14 UTC (permalink / raw)
To: tsbogend; +Cc: linux-kernel, netdev
This patch extends Don Fry's last patch for AT 2700/01 FX to set the
speed/fdx options for the FTX variants of these cards as well.
Additionally the option override has been moved from pcnet32_open to
pcnet32_probe1 because it's only necessary to override the options once.
Tested and works.
Patch applies to 2.6.16-rc3
Signed-off-by: Philippe Seewer <philippe.seewer@bfh.ch>
---
drivers/net/pcnet32.c | 39 ++++++++++++++++++++++++++-------------
include/linux/pci_ids.h | 2 ++
2 files changed, 28 insertions(+), 13 deletions(-)
diff -uprN -X linux-2.6.16-rc3-vanilla/Documentation/dontdiff linux-2.6.16-rc3-vanilla/drivers/net/pcnet32.c linux-2.6.16-rc3/drivers/net/pcnet32.c
--- linux-2.6.16-rc3-vanilla/drivers/net/pcnet32.c 2006-02-13 01:27:25.000000000 +0100
+++ linux-2.6.16-rc3/drivers/net/pcnet32.c 2006-02-17 15:49:41.000000000 +0100
@@ -22,8 +22,8 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
-#define DRV_VERSION "1.31c"
-#define DRV_RELDATE "01.Nov.2005"
+#define DRV_VERSION "1.31d"
+#define DRV_RELDATE "17.Feb.2006"
#define PFX DRV_NAME ": "
static const char *version =
@@ -265,6 +265,8 @@ static int homepna[MAX_UNITS];
* v1.31c 01 Nov 2005 Don Fry Allied Telesyn 2700/2701 FX are 100Mbit only.
* Force 100Mbit FD if Auto (ASEL) is selected.
* See Bugzilla 2669 and 4551.
+ * v1.31d 17 Nov 2006 Philippe Seewer Extended AT 2700/01 FX support
+ * to support FTX variants as well.
*/
@@ -1404,6 +1406,28 @@ pcnet32_probe1(unsigned long ioaddr, int
if (lp->mii)
lp->mii_if.phy_id = ((lp->a.read_bcr (ioaddr, 33)) >> 5) & 0x1f;
+ /*
+ * Override options:
+ * Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not
+ * negotiate. The same goes for AT 2701 FTX on fiber and
+ * autoneg on 2700FTX seems generally broken.
+ */
+ if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+ ((lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
+ lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX ||
+ lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FTX)
+ ||
+ (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FTX &&
+ lp->mii_if.phy_id == 1)
+ )) {
+ if (lp->options & PCNET32_PORT_ASEL) {
+ lp->options = PCNET32_PORT_MII | PCNET32_PORT_FD | PCNET32_PORT_100;
+ if (pcnet32_debug & NETIF_MSG_PROBE)
+ printk(" Setting 100Mb-Full Duplex.\n");
+ }
+ }
+
+
init_timer (&lp->watchdog_timer);
lp->watchdog_timer.data = (unsigned long) dev;
lp->watchdog_timer.function = (void *) &pcnet32_watchdog;
@@ -1614,17 +1638,6 @@ pcnet32_open(struct net_device *dev)
val |= 0x10;
lp->a.write_csr (ioaddr, 124, val);
- /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
- if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
- (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
- lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
- if (lp->options & PCNET32_PORT_ASEL) {
- lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
- if (netif_msg_link(lp))
- printk(KERN_DEBUG "%s: Setting 100Mb-Full Duplex.\n",
- dev->name);
- }
- }
{
/*
* 24 Jun 2004 according AMD, in order to change the PHY,
diff -uprN -X linux-2.6.16-rc3-vanilla/Documentation/dontdiff linux-2.6.16-rc3-vanilla/include/linux/pci_ids.h linux-2.6.16-rc3/include/linux/pci_ids.h
--- linux-2.6.16-rc3-vanilla/include/linux/pci_ids.h 2006-02-13 01:27:25.000000000 +0100
+++ linux-2.6.16-rc3/include/linux/pci_ids.h 2006-02-17 15:51:37.000000000 +0100
@@ -1538,7 +1538,9 @@
/* Allied Telesyn */
#define PCI_VENDOR_ID_AT 0x1259
#define PCI_SUBDEVICE_ID_AT_2700FX 0x2701
+#define PCI_SUBDEVICE_ID_AT_2700FTX 0x2702
#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703
+#define PCI_SUBDEVICE_ID_AT_2701FTX 0x2704
#define PCI_VENDOR_ID_ESS 0x125d
#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
^ permalink raw reply
* [PATCH 2/2] pcnet32: PHY selection support
From: Seewer Philippe @ 2006-02-17 16:14 UTC (permalink / raw)
To: tsbogend; +Cc: linux-kernel, netdev
Most AMD pcnet chips support up to 32 external PHYs. This patch
introduces basic PHY selection/switching support, by adding two
new module parameters:
-maxphy: how many PHYs the card supports
-usephy: which phy to use instead of eeprom default
Maxphy is necessary in order to check the range of usephy and may
be overriden inside the module.
If only maxphy is present I've implemented an algorithm which checks
the link state on all PHYs and uses the one that has a link.
I tested this extensively on our 2700/01 FTX cards and works. I have
added a maxphy override for those cards to the driver as well.
The only drawback here is that I wasn't able to figure out how to
dynamically switch the PHY, so the whole switching process is done in
pcnet32_probe1 instead of open or when the link state changes. This
means that once the driver is loaded the PHY which was connected must
be used and no change is possible without physically resetting
(power off/on) the card.
Patch applies to 2.6.16-rc3 and depends on patch nr. 1 to completely
support AT 2700/01 FTX cards.
Signed-off-by: Philippe Seewer <philippe.seewer@bfh.ch>
---
pcnet32.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 105 insertions(+), 2 deletions(-)
diff -uprN -X linux-2.6.16-rc3-vanilla/Documentation/dontdiff linux-2.6.16-rc3-vanilla/drivers/net/pcnet32.c linux-2.6.16-rc3/drivers/net/pcnet32.c
--- linux-2.6.16-rc3-vanilla/drivers/net/pcnet32.c 2006-02-17 16:38:44.000000000 +0100
+++ linux-2.6.16-rc3/drivers/net/pcnet32.c 2006-02-17 16:40:47.000000000 +0100
@@ -22,7 +22,7 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
-#define DRV_VERSION "1.31d"
+#define DRV_VERSION "1.32"
#define DRV_RELDATE "17.Feb.2006"
#define PFX DRV_NAME ": "
@@ -140,6 +140,10 @@ static int options[MAX_UNITS];
static int full_duplex[MAX_UNITS];
static int homepna[MAX_UNITS];
+/* Options to switch PHY */
+static int maxphy[MAX_UNITS];
+static int usephy[MAX_UNITS];
+
/*
* Theory of Operation
*
@@ -267,6 +271,8 @@ static int homepna[MAX_UNITS];
* See Bugzilla 2669 and 4551.
* v1.31d 17 Nov 2006 Philippe Seewer Extended AT 2700/01 FX support
* to support FTX variants as well.
+ * v1.32 17 Nov 2006 Philippe Seewer Basic PHY switching support on
+ * module load.
*/
@@ -386,6 +392,8 @@ struct pcnet32_private {
struct timer_list watchdog_timer;
struct timer_list blink_timer;
u32 msg_enable; /* debug message level */
+ int maxphy; /* max PHYs supported by chip */
+ int usephy; /* which PHY to use */
};
static void pcnet32_probe_vlbus(void);
@@ -417,6 +425,7 @@ static void pcnet32_get_regs(struct net_
static void pcnet32_purge_tx_ring(struct net_device *dev);
static int pcnet32_alloc_ring(struct net_device *dev, char *name);
static void pcnet32_free_ring(struct net_device *dev);
+static void pcnet32_switch_phy(struct net_device *dev, int phy);
enum pci_flags_bit {
@@ -1336,6 +1345,20 @@ pcnet32_probe1(unsigned long ioaddr, int
lp->mii_if.mdio_read = mdio_read;
lp->mii_if.mdio_write = mdio_write;
+ lp->maxphy = 1;
+ if ((cards_found >= MAX_UNITS) || (maxphy[cards_found]))
+ lp->maxphy = maxphy[cards_found];
+
+ lp->usephy = 0;
+ if ((cards_found >= MAX_UNITS) || (usephy[cards_found]))
+ lp->usephy = usephy[cards_found];
+
+ if (lp->usephy > lp->maxphy) {
+ printk(KERN_ERR PFX " usephy paramater out of range! ignoring!\n");
+ lp->usephy = 0;
+ }
+
+
if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
((cards_found>=MAX_UNITS) || full_duplex[cards_found]))
lp->options |= PCNET32_PORT_FD;
@@ -1358,6 +1381,15 @@ pcnet32_probe1(unsigned long ioaddr, int
&& dev->dev_addr[2] == 0x75)
lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
+ /*
+ * Test for specific cards to set maxphy count
+ */
+ if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+ (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FTX ||
+ lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FTX)) {
+ lp->maxphy = 2;
+ }
+
lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
@@ -1403,9 +1435,38 @@ pcnet32_probe1(unsigned long ioaddr, int
}
/* Set the mii phy_id so that we can query the link state */
- if (lp->mii)
+ if (lp->mii) {
lp->mii_if.phy_id = ((lp->a.read_bcr (ioaddr, 33)) >> 5) & 0x1f;
+ /* Multi PHY? */
+ if (lp->maxphy > 1) {
+ /* Autoswitch? */
+ if (lp->usephy == 0) {
+ /* backup */
+ lp->usephy = lp->mii_if.phy_id;
+
+ /* give preference to eeprom default if no link */
+ media = lp->mii_if.phy_id;
+
+ /* check link */
+ for (i = 1; i <= lp->maxphy; i++) {
+ lp->mii_if.phy_id = i;
+ if (mii_check_media(&lp->mii_if, 0, 1)) {
+ media = i;
+ /* give preference to eeprom default if link found */
+ if (i == lp->usephy)
+ break;
+ }
+ }
+
+ lp->mii_if.phy_id = media;
+ } else {
+ lp->mii_if.phy_id = lp->usephy;
+ }
+ pcnet32_switch_phy(dev, lp->mii_if.phy_id);
+ }
+ }
+
/*
* Override options:
* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not
@@ -1573,6 +1634,32 @@ static void pcnet32_free_ring(struct net
}
}
+static void pcnet32_switch_phy(struct net_device *dev, int phy)
+{
+ struct pcnet32_private *lp = dev->priv;
+ unsigned long ioaddr = dev->base_addr;
+ int i;
+
+ /* Isolate all unused phy's */
+ for (i = 1; i < 3; i++) {
+ if (i != phy)
+ mdio_write(dev, 1, MII_BMCR, BMCR_ISOLATE);
+ }
+
+ /* Make sure used phy is not isolated */
+ mdio_write(dev, phy, MII_BMCR,
+ mdio_read(dev, phy, MII_BMCR) & ~BMCR_ISOLATE);
+
+ /* Rearead mii regs */
+ for (i = 0; i < 5; i++) {
+ mdio_read(dev, phy, i);
+ mdio_read(dev, phy, i);
+ }
+
+ /* Store PHY */
+ lp->a.write_bcr(ioaddr, 33, ((phy & 0x1f) << 5) | MII_BMCR);
+}
+
static int
pcnet32_open(struct net_device *dev)
@@ -1654,6 +1741,16 @@ pcnet32_open(struct net_device *dev)
if (lp->options & PCNET32_PORT_100)
val |= 0x08;
lp->a.write_bcr (ioaddr, 32, val);
+ /*
+ * AT 2700 FTX seems broken somehow, when disabling the
+ * DANAS the mii registers for the fiber poort need to be
+ * set.
+ */
+ if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+ lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FTX &&
+ lp->mii_if.phy_id == 1) {
+ mdio_write(dev, lp->mii_if.phy_id, MII_BMCR, 0x2100);
+ }
} else {
if (lp->options & PCNET32_PORT_ASEL) {
lp->a.write_bcr(ioaddr, 32,
@@ -2505,6 +2602,12 @@ MODULE_PARM_DESC(full_duplex, DRV_NAME "
module_param_array(homepna, int, NULL, 0);
MODULE_PARM_DESC(homepna, DRV_NAME " mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet");
+/* Module parameters for PHY selection support */
+module_param_array(maxphy, int, NULL, 0);
+MODULE_PARM_DESC(maxphy, DRV_NAME " max PHYs the card supports");
+module_param_array(usephy, int, NULL, 0);
+MODULE_PARM_DESC(usephy, DRV_NAME " use specified PHY port instead of default");
+
MODULE_AUTHOR("Thomas Bogendoerfer");
MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards");
MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH 1/2] pcnet32: Introduce basic AT 2700/01 FTX support
From: Don Fry @ 2006-02-17 18:21 UTC (permalink / raw)
To: Seewer Philippe; +Cc: tsbogend, linux-kernel, netdev
In-Reply-To: <43F5F66F.6040608@bfh.ch>
Philippe,
On a purely mechanical note, the patches do not apply cleanly because
of whitespace changes. Possibly your mailer changed tabs to spaces,
which causes the patch not to apply, and also causes your patch to have
different spacing than the rest of the file. The driver does not
conform to the 8-space indentation guideline/rule, but it is consistent
in 4-space indentation.
I am looking over this change and the following one, to try and
understand what and why you made your changes.
The change made by Thomas Bogendoerfer and modified by myself is much
more flexible than your changes, in that they are not specific just to
the Allied Telesyn boards with multiple Phys. They also allow dynamic
changing of cabling without requiring the driver to be removed/installed
or the card power cycled. I also see little value in the module
parameters, when it can be determined dynamically. Also, maxphy might be
thought to the the maximum number of phys, rather than the maximum phy
number supported. If static selection of the phy to use is passed in as
a module parameter, why also include a maxphy?
As I review your patches I will follow up to the mailing list.
On Fri, Feb 17, 2006 at 05:14:39PM +0100, Seewer Philippe wrote:
>
> This patch extends Don Fry's last patch for AT 2700/01 FX to set the
> speed/fdx options for the FTX variants of these cards as well.
>
> Additionally the option override has been moved from pcnet32_open to
> pcnet32_probe1 because it's only necessary to override the options once.
>
> Tested and works.
>
> Patch applies to 2.6.16-rc3
>
Don Fry
brazilnut@us.ibm.com
^ permalink raw reply
* Re: [PATCH 2/2] pcnet32: PHY selection support
From: Adam Kropelin @ 2006-02-17 18:49 UTC (permalink / raw)
To: philippe.seewer; +Cc: linux-kernel, netdev, tsbogend
In-Reply-To: <43F5F672.9080904@bfh.ch>
Seewer Philippe wrote:
> Most AMD pcnet chips support up to 32 external PHYs. This patch
> introduces basic PHY selection/switching support, by adding two
> new module parameters:
> -maxphy: how many PHYs the card supports
> -usephy: which phy to use instead of eeprom default
>
> Maxphy is necessary in order to check the range of usephy and may
> be overriden inside the module.
It seems a bit pointless for the range check of a user-supplied value to
be driven by another user-supplied value.
> If only maxphy is present I've implemented an algorithm which checks
> the link state on all PHYs and uses the one that has a link.
Knowing how many PHYs to scan is potentially useful, but how about
determining that at runtime? Missing PHYs should be detectable with a
timeout or similar. Too risky?
--Adam
^ permalink raw reply
* Re: [PATCH 2/2] pcnet32: PHY selection support
From: Seewer Philippe @ 2006-02-17 19:56 UTC (permalink / raw)
To: Adam Kropelin; +Cc: linux-kernel, netdev, tsbogend
In-Reply-To: <20060217134938.B24429@mail.kroptech.com>
Adam Kropelin wrote:
> Seewer Philippe wrote:
>
>>Most AMD pcnet chips support up to 32 external PHYs. This patch
>>introduces basic PHY selection/switching support, by adding two
>>new module parameters:
>>-maxphy: how many PHYs the card supports
>>-usephy: which phy to use instead of eeprom default
>>
>>Maxphy is necessary in order to check the range of usephy and may
>>be overriden inside the module.
>
>
> It seems a bit pointless for the range check of a user-supplied value to
> be driven by another user-supplied value.
I just want to make sure and there's the possibility of supplying only maxphy
and let the autoswitch algorithm decide...
>
>
>>If only maxphy is present I've implemented an algorithm which checks
>>the link state on all PHYs and uses the one that has a link.
>
>
> Knowing how many PHYs to scan is potentially useful, but how about
> determining that at runtime? Missing PHYs should be detectable with a
> timeout or similar. Too risky?
Actually its possible to query them with mii and all non-present phy's
should "return" 0xffff. I wanted my changes to have no impact on pcnet
cards with only one phy, thats why.
>
> --Adam
>
^ permalink raw reply
* Re: [PATCH 1/2] pcnet32: Introduce basic AT 2700/01 FTX support
From: Seewer Philippe @ 2006-02-17 20:12 UTC (permalink / raw)
To: Don Fry; +Cc: tsbogend, linux-kernel, netdev
In-Reply-To: <20060217182104.GA19257@us.ibm.com>
Don Fry wrote:
> Philippe,
>
> On a purely mechanical note, the patches do not apply cleanly because
> of whitespace changes. Possibly your mailer changed tabs to spaces,
> which causes the patch not to apply, and also causes your patch to have
> different spacing than the rest of the file. The driver does not
> conform to the 8-space indentation guideline/rule, but it is consistent
> in 4-space indentation.
uhhh.... did i forget to run Lindent..? Or was it that i just
selected-middle clicked them into thunderbird?
what's the recommended procedure oh how to append patches to
mails? (Documentation just says included not attached...)
>
> I am looking over this change and the following one, to try and
> understand what and why you made your changes.
>
> The change made by Thomas Bogendoerfer and modified by myself is much
> more flexible than your changes, in that they are not specific just to
> the Allied Telesyn boards with multiple Phys.
I'm not sure what you are talking about. I didn't see any PHY switching
code in the driver... And the specs specifically say that when more than
one PHY is connected control should revert to software.
> They also allow dynamic
> changing of cabling without requiring the driver to be removed/installed
> or the card power cycled. I also see little value in the module
> parameters, when it can be determined dynamically. Also, maxphy might be
> thought to the the maximum number of phys, rather than the maximum phy
> number supported. If static selection of the phy to use is passed in as
> a module parameter, why also include a maxphy?
maxphy is supposed to be how many PHYs are actually connected to the chip.
I didn't want to introduce a generic PHY scanner (which is possible)
because that would have haa impact on all cards not only cards that actually
have more than one phy.
I really tried to put this into pcnet32_open. But i just didn't work...
>
> As I review your patches I will follow up to the mailing list.
>
> On Fri, Feb 17, 2006 at 05:14:39PM +0100, Seewer Philippe wrote:
>
>>This patch extends Don Fry's last patch for AT 2700/01 FX to set the
>>speed/fdx options for the FTX variants of these cards as well.
>>
>>Additionally the option override has been moved from pcnet32_open to
>>pcnet32_probe1 because it's only necessary to override the options once.
>>
>>Tested and works.
>>
>>Patch applies to 2.6.16-rc3
>>
>
> Don Fry
> brazilnut@us.ibm.com
^ 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