diff options
Diffstat (limited to 'net/ipx')
-rw-r--r-- | net/ipx/.cvsignore | 1 | ||||
-rw-r--r-- | net/ipx/Config.in | 6 | ||||
-rw-r--r-- | net/ipx/Makefile | 8 | ||||
-rw-r--r-- | net/ipx/af_ipx.c | 158 |
4 files changed, 90 insertions, 83 deletions
diff --git a/net/ipx/.cvsignore b/net/ipx/.cvsignore index 4671378ae..857dd22e9 100644 --- a/net/ipx/.cvsignore +++ b/net/ipx/.cvsignore @@ -1 +1,2 @@ .depend +.*.flags diff --git a/net/ipx/Config.in b/net/ipx/Config.in new file mode 100644 index 000000000..d35afbac0 --- /dev/null +++ b/net/ipx/Config.in @@ -0,0 +1,6 @@ +# +# IPX configuration +# + +comment 'IPX options' +bool 'Full internal IPX network' CONFIG_IPX_INTERN diff --git a/net/ipx/Makefile b/net/ipx/Makefile index 0c29dc5d3..b9d337a8a 100644 --- a/net/ipx/Makefile +++ b/net/ipx/Makefile @@ -1,5 +1,5 @@ # -# Makefile for the Linux TCP/IP (INET) layer. +# Makefile for the Linux IPX layer. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here @@ -7,12 +7,14 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +# We only get in/to here if CONFIG_IPX = 'y' or 'm' + O_TARGET := ipx.o -O_OBJS := af_ipx.o M_OBJS := $(O_TARGET) +OX_OBJS += af_ipx.o ifeq ($(CONFIG_SYSCTL),y) -O_OBJS += sysctl_net_ipx.o + O_OBJS += sysctl_net_ipx.o endif include $(TOPDIR)/Rules.make diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 2a46c5270..cf56df492 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -210,11 +210,10 @@ static void ipx_destroy_socket(struct sock *sk) ipx_remove_socket(sk); while((skb=skb_dequeue(&sk->receive_queue))!=NULL) { - kfree_skb(skb,FREE_READ); + kfree_skb(skb); } sk_free(sk); - MOD_DEC_USE_COUNT; } /* The following code is used to support IPX Interfaces (IPXITF). An @@ -378,11 +377,7 @@ static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) if((retval = sock_queue_rcv_skb(sock, skb))<0) { - /* - * skb->sk is NULL here, so FREE_WRITE does not hurt - * the sending socket. - */ - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); } return retval; } @@ -415,14 +410,8 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c if (copy != 0) { skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1 != NULL) - { - skb1->arp = 1; - } - else - { + if (skb1 == NULL) return -ENOMEM; - } } else { @@ -445,10 +434,9 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c if (copy == 0) { /* skb was solely for us, and we did not make a copy, - * so free it. FREE_WRITE does not hurt, because - * skb->sk is NULL here. + * so free it. */ - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); } return 0; } @@ -500,7 +488,7 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c if (sock1 == NULL && sock2 == NULL) { if (!copy) - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); return 0; } @@ -515,8 +503,6 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c if (copy) { skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1) - skb1->arp=1; } else { @@ -533,8 +519,6 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c if (sock1 && sock2) { skb2 = skb_clone(skb1, GFP_ATOMIC); - if (skb2 != NULL) - skb2->arp = 1; } else skb2 = skb1; @@ -561,7 +545,6 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf /* Hopefully, most cases */ if (in_offset >= out_offset) { - skb->arp = 1; return skb; } @@ -572,11 +555,10 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf skb_reserve(skb2,out_offset); skb2->nh.raw= skb2->h.raw=skb_put(skb2,skb->len); - skb2->arp=1; memcpy(skb2->h.raw, skb->h.raw, skb->len); } - kfree_skb(skb, FREE_WRITE); - return skb2; + kfree_skb(skb); + return NULL; } static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) @@ -648,15 +630,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) if (!send_to_wire) { - /* - * We do a FREE_WRITE here because this indicates how - * to treat the socket with which the packet is - * associated. If this packet is associated with a - * socket at all, it must be the originator of the - * packet. Routed packets will have no socket associated - * with them. - */ - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); return 0; } @@ -707,7 +681,6 @@ static int ipxitf_add_local_route(ipx_interface *intrfc) static const char * ipx_frame_name(unsigned short); static const char * ipx_device_name(ipx_interface *); -static int ipxrtr_route_skb(struct sk_buff *); static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) { @@ -720,7 +693,7 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) if (call_in_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) { - kfree_skb(skb, FREE_READ); + kfree_skb(skb); return 0; } @@ -813,20 +786,20 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) */ if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) { - kfree_skb(skb, FREE_READ); + kfree_skb(skb); return 0; } /* We only route point-to-point packets. */ if (skb->pkt_type == PACKET_HOST) { - skb=skb_unshare(skb, GFP_ATOMIC, FREE_READ); + skb=skb_unshare(skb, GFP_ATOMIC); if(skb) return ipxrtr_route_skb(skb); else return 0; } - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } @@ -838,7 +811,7 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } /* we couldn't pawn it off so unload it */ - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } @@ -1025,7 +998,8 @@ static int ipxitf_delete(ipx_interface_definition *idef) return -EPROTONOSUPPORT; dev=dev_get(idef->ipx_device); - if(dev==NULL) return -ENODEV; + if (dev==NULL) + return -ENODEV; intrfc = ipxitf_find_using_phys(dev, dlink_type); if (intrfc != NULL) { @@ -1134,9 +1108,9 @@ static int ipxitf_ioctl_real(unsigned int cmd, void *arg) sipx->sipx_family=AF_IPX; sipx->sipx_network=ipxif->if_netnum; memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node)); - err = copy_to_user(arg,&ifr,sizeof(ifr)); - if (err) - return -EFAULT; + err = -EFAULT; + if (!copy_to_user(arg, &ifr, sizeof(ifr))) + err = 0; return err; } case SIOCAIPXITFCRT: @@ -1360,7 +1334,6 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru return err; skb_reserve(skb,ipx_offset); - skb->arp=1; skb->sk=sk; /* Fill in IPX header */ @@ -1394,7 +1367,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru err = memcpy_fromiovec(skb_put(skb,len),iov,len); if (err) { - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return -EFAULT; } @@ -1409,7 +1382,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) { - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return -EPERM; } @@ -1417,7 +1390,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru rt->ir_router_node : ipx->ipx_dest.node); } -static int ipxrtr_route_skb(struct sk_buff *skb) +int ipxrtr_route_skb(struct sk_buff *skb) { struct ipxhdr *ipx = skb->nh.ipxh; ipx_route *r; @@ -1427,7 +1400,7 @@ static int ipxrtr_route_skb(struct sk_buff *skb) if (r == NULL) { /* no known route */ - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } i = r->ir_intrfc; @@ -1746,8 +1719,11 @@ static int ipx_create(struct socket *sock, int protocol) switch(sock->type) { case SOCK_DGRAM: - sock->ops = &ipx_dgram_ops; - break; + sock->ops = &ipx_dgram_ops; + break; + case SOCK_STREAM: /* Allow higher levels to piggyback */ + case SOCK_SEQPACKET: + printk(KERN_CRIT "IPX: _create-ing non_DGRAM socket\n"); default: sk_free(sk); return(-ESOCKTNOSUPPORT); @@ -1770,6 +1746,9 @@ static int ipx_release(struct socket *sock, struct socket *peer) sk->dead=1; sock->sk=NULL; ipx_destroy_socket(sk); + if ( sock->type == SOCK_DGRAM ) { + MOD_DEC_USE_COUNT; + } return(0); } @@ -1845,7 +1824,9 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) sk->protinfo.af_ipx.node, sk->protinfo.af_ipx.port) != NULL) { - SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port); + SOCK_DEBUG(sk, + "IPX: bind failed because port %X in use.\n", + ntohs((int)addr->sipx_port)); return -EADDRINUSE; } } @@ -1860,7 +1841,9 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) IPX_NODE_LEN); if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) { - SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port); + SOCK_DEBUG(sk, + "IPX: bind failed because port %X in use.\n", + ntohs((int)addr->sipx_port)); return -EADDRINUSE; } } @@ -1871,7 +1854,8 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) an interface routed to IPX with the ipx routing ioctl() */ if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) { - SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port); + SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", + ntohs((int)addr->sipx_port)); return -EADDRINUSE; } @@ -1879,7 +1863,8 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ipxitf_insert_socket(intrfc, sk); sk->zapped=0; - SOCK_DEBUG(sk, "IPX: socket is bound.\n"); + SOCK_DEBUG(sk, "IPX: bound socket 0x%04X.\n", ntohs(addr->sipx_port) ); + return 0; } @@ -1920,8 +1905,10 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, memcpy(sk->protinfo.af_ipx.dest_addr.node, addr->sipx_node,IPX_NODE_LEN); sk->protinfo.af_ipx.type=addr->sipx_type; - sock->state = SS_CONNECTED; - sk->state=TCP_ESTABLISHED; + if(sock->type == SOCK_DGRAM ) { + sock->state = SS_CONNECTED; + sk->state=TCP_ESTABLISHED; + } return 0; } @@ -2052,7 +2039,7 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) /* Too small? */ if(ntohs(ipx->ipx_pktsize)<sizeof(struct ipxhdr)) { - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } @@ -2060,7 +2047,7 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize))!=ipx->ipx_checksum) { - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } } @@ -2077,7 +2064,7 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) if (intrfc == NULL) { /* Not one of ours */ - kfree_skb(skb,FREE_READ); + kfree_skb(skb); return 0; } } @@ -2148,32 +2135,28 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, struct sock *sk=sock->sk; struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name; struct ipxhdr *ipx = NULL; - int copied = 0; - int truesize; struct sk_buff *skb; - int err; + int copied, err; if (sk->zapped) return -ENOTCONN; skb=skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); - if(skb==NULL) - return err; + if (!skb) + goto out; ipx = skb->nh.ipxh; - truesize=ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); - - copied = truesize; + copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); if(copied > size) { copied=size; msg->msg_flags|=MSG_TRUNC; } - err = skb_copy_datagram_iovec(skb,sizeof(struct ipxhdr),msg->msg_iov,copied); - + err = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov, + copied); if (err) - return err; + goto out_free; msg->msg_namelen = sizeof(*sipx); @@ -2185,9 +2168,12 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, sipx->sipx_network=ipx->ipx_source.net; sipx->sipx_type = ipx->ipx_type; } - skb_free_datagram(sk, skb); + err = copied; - return(copied); +out_free: + skb_free_datagram(sk, skb); +out: + return err; } /* @@ -2242,11 +2228,12 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) { if(sk->stamp.tv_sec==0) return -ENOENT; - ret = copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval)); - if (ret) - ret = -EFAULT; + ret = -EFAULT; + if (!copy_to_user((void *)arg, &sk->stamp, + sizeof(struct timeval))) + ret = 0; } - return 0; + return ret; } case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: @@ -2372,6 +2359,19 @@ ipx_proto_init(struct net_proto *pro) printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); } +/* Higher layers need this info to prep tx pkts */ +int ipx_if_offset(unsigned long ipx_net_number) +{ + ipx_route *rt = NULL; + + rt = ipxrtr_lookup(ipx_net_number); + return ( rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH ); +} + +/* Export symbols for higher layers */ +EXPORT_SYMBOL(ipxrtr_route_skb); +EXPORT_SYMBOL(ipx_if_offset); + #ifdef MODULE /* Note on MOD_{INC,DEC}_USE_COUNT: * @@ -2426,8 +2426,6 @@ __initfunc(static void ipx_proto_finito(void)) return; } -EXPORT_NO_SYMBOLS; - int init_module(void) { ipx_proto_init(NULL); |