summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-19 01:28:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-19 01:28:40 +0000
commit8abb719409c9060a7c0676f76e9182c1e0b8ca46 (patch)
treeb88cc5a6cd513a04a512b7e6215c873c90a1c5dd /net
parentf01bd7aeafd95a08aafc9e3636bb26974df69d82 (diff)
Merge with 2.3.99-pre1.
Diffstat (limited to 'net')
-rw-r--r--net/appletalk/ddp.c7
-rw-r--r--net/atm/Makefile2
-rw-r--r--net/ax25/af_ax25.c145
-rw-r--r--net/econet/af_econet.c50
-rw-r--r--net/packet/af_packet.c4
-rw-r--r--net/sched/sch_ingress.c1
-rw-r--r--net/x25/af_x25.c6
-rw-r--r--net/x25/x25_link.c9
8 files changed, 154 insertions, 70 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 80fc635f2..9a1b18270 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1378,11 +1378,12 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (n < 0)
return n;
- } else
+ } else {
sk->protinfo.af_at.src_port = addr->sat_port;
- if (atalk_find_or_insert_socket(sk, addr) != NULL)
- return -EADDRINUSE;
+ if (atalk_find_or_insert_socket(sk, addr) != NULL)
+ return -EADDRINUSE;
+ }
sk->zapped = 0;
diff --git a/net/atm/Makefile b/net/atm/Makefile
index 999fe1203..1c525f601 100644
--- a/net/atm/Makefile
+++ b/net/atm/Makefile
@@ -58,4 +58,4 @@ endif
include $(TOPDIR)/Rules.make
mpoa.o: mpc.o mpoa_caches.o mpoa_proc.o
- ld -r -o mpoa.o mpc.o mpoa_caches.o mpoa_proc.o
+ $(LD) -r -o mpoa.o mpc.o mpoa_caches.o mpoa_proc.o
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index a676660dc..949c2b3e9 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -96,6 +96,10 @@
* AX.25 038 Matthias(DG2FEF) Small fixes to the syscall interface to make kernel
* independent of AX25_MAX_DIGIS used by applications.
* Tomi(OH2BNS) Fixed ax25_getname().
+ * Joerg(DL1BKE) Starting to phase out the support for full_sockaddr_ax25
+ * with only 6 digipeaters and sockaddr_ax25 in ax25_bind(),
+ * ax25_connect() and ax25_sendmsg()
+ * Joerg(DL1BKE) Added support for SO_BINDTODEVICE
*/
#include <linux/config.h>
@@ -624,6 +628,8 @@ ax25_cb *ax25_create_cb(void)
static int ax25_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
{
struct sock *sk = sock->sk;
+ struct net_device *dev;
+ char devname[IFNAMSIZ];
int opt;
if (level != SOL_AX25)
@@ -702,6 +708,22 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, char *op
sk->protinfo.ax25->paclen = opt;
return 0;
+ case SO_BINDTODEVICE:
+ if (optlen > IFNAMSIZ) optlen=IFNAMSIZ;
+ if (copy_from_user(devname, optval, optlen))
+ return -EFAULT;
+
+ dev = dev_get_by_name(devname);
+ if (dev == NULL) return -ENODEV;
+
+ if (sk->type == SOCK_SEQPACKET &&
+ (sock->state != SS_UNCONNECTED || sk->state == TCP_LISTEN))
+ return -EADDRNOTAVAIL;
+
+ sk->protinfo.ax25->ax25_dev = ax25_dev_ax25dev(dev);
+ ax25_fillin_cb(sk->protinfo.ax25, sk->protinfo.ax25->ax25_dev);
+ return 0;
+
default:
return -ENOPROTOOPT;
}
@@ -710,15 +732,24 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, char *op
static int ax25_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
{
struct sock *sk = sock->sk;
+ struct ax25_dev *ax25_dev;
+ char devname[IFNAMSIZ];
+ void *valptr;
int val = 0;
- int len;
+ int maxlen, length;
if (level != SOL_AX25)
return -ENOPROTOOPT;
- if (get_user(len, optlen))
+ if (get_user(maxlen, optlen))
+ return -EFAULT;
+
+ if (maxlen < 1)
return -EFAULT;
+ valptr = (void *) &val;
+ length = min(maxlen, sizeof(int));
+
switch (optname) {
case AX25_WINDOW:
val = sk->protinfo.ax25->window;
@@ -763,17 +794,30 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, char *op
case AX25_PACLEN:
val = sk->protinfo.ax25->paclen;
break;
+
+ case SO_BINDTODEVICE:
+ ax25_dev = sk->protinfo.ax25->ax25_dev;
+
+ if (ax25_dev != NULL && ax25_dev->dev != NULL) {
+ strncpy(devname, ax25_dev->dev->name, IFNAMSIZ);
+ length = min(strlen(ax25_dev->dev->name)+1, maxlen);
+ devname[length-1] = '\0';
+ } else {
+ *devname = '\0';
+ length = 1;
+ }
+
+ valptr = (void *) devname;
+ break;
default:
return -ENOPROTOOPT;
}
- len = min(len, sizeof(int));
-
- if (put_user(len, optlen))
+ if (put_user(length, optlen))
return -EFAULT;
- if (copy_to_user(optval, &val, len))
+ if (copy_to_user(optval, valptr, length))
return -EFAULT;
return 0;
@@ -997,9 +1041,9 @@ static int ax25_release(struct socket *sock)
/*
* We support a funny extension here so you can (as root) give any callsign
- * digipeated via a local address as source. This is a hack until we add
- * BSD 4.4 ADDIFADDR type support. It is however small and trivially backward
- * compatible 8)
+ * digipeated via a local address as source. This hack is obsolete now
+ * that we've implemented support for SO_BINDTODEVICE. It is however small
+ * and trivially backward compatible.
*/
static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
@@ -1011,11 +1055,16 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (sk->zapped == 0)
return -EINVAL;
- if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25))
- return -EINVAL;
+ if (addr_len != sizeof(struct sockaddr_ax25) &&
+ addr_len != sizeof(struct full_sockaddr_ax25)) {
+ /* support for old structure may go away some time */
+ if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
+ (addr_len > sizeof(struct full_sockaddr_ax25)))
+ return -EINVAL;
- if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25)))
- return -EINVAL;
+ printk(KERN_WARNING "ax25_bind(): %s uses old (6 digipeater) socket structure.\n",
+ current->comm);
+ }
if (addr->fsa_ax25.sax25_family != AF_AX25)
return -EINVAL;
@@ -1029,34 +1078,28 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
else
sk->protinfo.ax25->source_addr = *call;
- SOCK_DEBUG(sk, "AX25: source address set to %s\n", ax2asc(&sk->protinfo.ax25->source_addr));
+ /*
+ * User already set interface with SO_BINDTODEVICE
+ */
+
+ if (sk->protinfo.ax25->ax25_dev != NULL)
+ goto done;
if (addr_len > sizeof(struct sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
- if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) == 0) {
- ax25_dev = NULL;
- SOCK_DEBUG(sk, "AX25: bound to any device\n");
- } else {
- if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_digipeater[0])) == NULL) {
- SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
- return -EADDRNOTAVAIL;
- }
- SOCK_DEBUG(sk, "AX25: bound to device %s\n", ax25_dev->dev->name);
- }
- } else {
- if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_ax25.sax25_call)) == NULL) {
- SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
+ if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) != 0 &&
+ (ax25_dev = ax25_addr_ax25dev(&addr->fsa_digipeater[0])) == NULL)
+ return -EADDRNOTAVAIL;
+ } else {
+ if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_ax25.sax25_call)) == NULL)
return -EADDRNOTAVAIL;
- }
- SOCK_DEBUG(sk, "AX25: bound to device %s\n", ax25_dev->dev->name);
}
if (ax25_dev != NULL)
ax25_fillin_cb(sk->protinfo.ax25, ax25_dev);
+done:
ax25_insert_socket(sk->protinfo.ax25);
-
sk->zapped = 0;
- SOCK_DEBUG(sk, "AX25: socket is bound\n");
return 0;
}
@@ -1095,8 +1138,21 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
/*
* some sanity checks. code further down depends on this
*/
- if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25))
- return -EINVAL;
+
+ if (addr_len == sizeof(struct sockaddr_ax25)) {
+ /* support for this will go away in early 2.5.x */
+ printk(KERN_WARNING "ax25_connect(): %s uses obsolete socket structure\n",
+ current->comm);
+ }
+ else if (addr_len != sizeof(struct full_sockaddr_ax25)) {
+ /* support for old structure may go away some time */
+ if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
+ (addr_len > sizeof(struct full_sockaddr_ax25)))
+ return -EINVAL;
+
+ printk(KERN_WARNING "ax25_connect(): %s uses old (6 digipeater) socket structure.\n",
+ current->comm);
+ }
if (fsa->fsa_ax25.sax25_family != AF_AX25)
return -EINVAL;
@@ -1105,7 +1161,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
kfree(sk->protinfo.ax25->digipeat);
sk->protinfo.ax25->digipeat = NULL;
}
-
+
/*
* Handle digi-peaters to be used.
*/
@@ -1138,6 +1194,9 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
* been filled in, error if it hasn't.
*/
if (sk->zapped) {
+ /* check if we can remove this feature. It is broken. */
+ printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@poboxes.com\n",
+ current->comm);
if ((err = ax25_rt_autobind(sk->protinfo.ax25, &fsa->fsa_ax25.sax25_call)) < 0)
return err;
ax25_fillin_cb(sk->protinfo.ax25, sk->protinfo.ax25->ax25_dev);
@@ -1330,10 +1389,20 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
if (usax != NULL) {
if (usax->sax25_family != AF_AX25)
return -EINVAL;
- if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25))
- return -EINVAL;
- if (addr_len < (usax->sax25_ndigis * AX25_ADDR_LEN + sizeof(struct sockaddr_ax25)))
- return -EINVAL;
+
+ if (addr_len == sizeof(struct sockaddr_ax25)) {
+ printk(KERN_WARNING "ax25_sendmsg(): %s uses obsolete socket structure\n",
+ current->comm);
+ }
+ else if (addr_len != sizeof(struct full_sockaddr_ax25)) {
+ /* support for old structure may go away some time */
+ if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
+ (addr_len > sizeof(struct full_sockaddr_ax25)))
+ return -EINVAL;
+
+ printk(KERN_WARNING "ax25_sendmsg(): %s uses old (6 digipeater) socket structure.\n",
+ current->comm);
+ }
if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
int ct = 0;
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 091155076..a22098207 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -51,12 +51,13 @@ static struct sock *econet_sklist;
how you count) it makes sense to use a simple lookup table. */
static struct net_device *net2dev_map[256];
+#define EC_PORT_IP 0xd2
+
#ifdef CONFIG_ECONET_AUNUDP
static spinlock_t aun_queue_lock;
static struct socket *udpsock;
#define AUN_PORT 0x8000
-#define EC_PORT_IP 0xd2
struct aunhdr
{
@@ -750,6 +751,28 @@ struct sock *ec_listening_socket(unsigned char port, unsigned char
return NULL;
}
+/*
+ * Queue a received packet for a socket.
+ */
+
+static int ec_queue_packet(struct sock *sk, struct sk_buff *skb,
+ unsigned char stn, unsigned char net,
+ unsigned char cb, unsigned char port)
+{
+ struct ec_cb *eb = (struct ec_cb *)&skb->cb;
+ struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec;
+
+ memset(sec, 0, sizeof(struct sockaddr_ec));
+ sec->sec_family = AF_ECONET;
+ sec->type = ECTYPE_PACKET_RECEIVED;
+ sec->port = port;
+ sec->cb = cb;
+ sec->addr.net = net;
+ sec->addr.station = stn;
+
+ return sock_queue_rcv_skb(sk, skb);
+}
+
#ifdef CONFIG_ECONET_AUNUDP
/*
@@ -792,27 +815,6 @@ static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb)
set_fs(oldfs);
}
-/*
- * Queue a received packet for a socket.
- */
-
-static int ec_queue_packet(struct sock *sk, struct sk_buff *skb,
- unsigned char stn, unsigned char net,
- unsigned char cb, unsigned char port)
-{
- struct ec_cb *eb = (struct ec_cb *)&skb->cb;
- struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec;
-
- memset(sec, 0, sizeof(struct sockaddr_ec));
- sec->sec_family = AF_ECONET;
- sec->type = ECTYPE_PACKET_RECEIVED;
- sec->port = port;
- sec->cb = cb;
- sec->addr.net = net;
- sec->addr.station = stn;
-
- return sock_queue_rcv_skb(sk, skb);
-}
/*
* Handle incoming AUN packets. Work out if anybody wants them,
@@ -1029,7 +1031,7 @@ release:
* Receive an Econet frame from a device.
*/
-static int econet_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
struct ec_framehdr *hdr = (struct ec_framehdr *)skb->data;
struct sock *sk;
@@ -1132,9 +1134,9 @@ void __exit econet_proto_exit(void)
int __init econet_proto_init(struct net_proto *pro)
{
extern void econet_sysctl_register(void);
- spin_lock_init(&aun_queue_lock);
sock_register(&econet_family_ops);
#ifdef CONFIG_ECONET_AUNUDP
+ spin_lock_init(&aun_queue_lock);
aun_udp_initialise();
#endif
#ifdef CONFIG_ECONET_NATIVE
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 3a9d20e9c..799ec9476 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -5,7 +5,7 @@
*
* PACKET - implements raw packet sockets.
*
- * Version: $Id: af_packet.c,v 1.32 2000/02/21 16:25:55 davem Exp $
+ * Version: $Id: af_packet.c,v 1.33 2000/03/13 22:11:50 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1439,6 +1439,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg
case SIOCGIFBR:
case SIOCSIFBR:
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+#ifdef CONFIG_INET
#ifdef CONFIG_KMOD
if (br_ioctl_hook == NULL)
request_module("bridge");
@@ -1446,6 +1447,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg
if (br_ioctl_hook != NULL)
return br_ioctl_hook(arg);
#endif
+#endif
return -ENOPKG;
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 64a915d7e..ddc738fcc 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -229,7 +229,6 @@ static struct nf_hook_ops ing_ops =
{
{ NULL, NULL},
ing_hook,
- NULL,
PF_INET,
NF_IP_PRE_ROUTING,
1
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 82b39c1b5..e042ce1d8 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -16,6 +16,7 @@
* X.25 001 Jonathan Naylor Started coding.
* X.25 002 Jonathan Naylor Centralised disconnect handling.
* New timer architecture.
+ * 2000-11-03 Henner Eisen MSG_EOR handling more POSIX compliant.
*/
#include <linux/config.h>
@@ -851,7 +852,7 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
return -EINVAL;
- /* we currently don't support segments at the user interface */
+ /* we currently don't support segmented records at the user interface */
if (!(msg->msg_flags & MSG_EOR))
return -EINVAL;
@@ -1034,6 +1035,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
msg->msg_flags |= MSG_TRUNC;
}
+ /* Currently, each datagram always contains a complete record */
+ msg->msg_flags |= MSG_EOR;
+
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (sx25 != NULL) {
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index be9f7edd3..d33dc63c3 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -73,18 +73,25 @@ static void x25_stop_t20timer(struct x25_neigh *neigh)
del_timer(&neigh->t20timer);
}
+static int x25_t20timer_pending(struct x25_neigh *neigh)
+{
+ return timer_pending(&neigh->t20timer);
+}
+
/*
* This handles all restart and diagnostic frames.
*/
void x25_link_control(struct sk_buff *skb, struct x25_neigh *neigh, unsigned short frametype)
{
struct sk_buff *skbn;
+ int confirm;
switch (frametype) {
case X25_RESTART_REQUEST:
+ confirm = !x25_t20timer_pending(neigh);
x25_stop_t20timer(neigh);
neigh->state = X25_LINK_STATE_3;
- x25_transmit_restart_confirmation(neigh);
+ if (confirm) x25_transmit_restart_confirmation(neigh);
break;
case X25_RESTART_CONFIRMATION: