From 8abb719409c9060a7c0676f76e9182c1e0b8ca46 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 19 Mar 2000 01:28:40 +0000 Subject: Merge with 2.3.99-pre1. --- net/appletalk/ddp.c | 7 ++- net/atm/Makefile | 2 +- net/ax25/af_ax25.c | 145 +++++++++++++++++++++++++++++++++++------------- net/econet/af_econet.c | 50 +++++++++-------- net/packet/af_packet.c | 4 +- net/sched/sch_ingress.c | 1 - net/x25/af_x25.c | 6 +- net/x25/x25_link.c | 9 ++- 8 files changed, 154 insertions(+), 70 deletions(-) (limited to 'net') 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 @@ -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, * Fred N. van Kempen, @@ -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 @@ -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: -- cgit v1.2.3