diff --git a/include/linux/ipx.h b/include/linux/ipx.h index 8b9d6bb127ae0f470f39cbdc621fb58947738b12..a6fa090601078847767ba0134f18517f8144ec22 100644 --- a/include/linux/ipx.h +++ b/include/linux/ipx.h @@ -24,15 +24,13 @@ struct sockaddr_ipx #define IPX_DLTITF 0 #define IPX_CRTITF 1 -typedef struct ipx_route_definition -{ +struct ipx_route_definition { __u32 ipx_network; __u32 ipx_router_network; unsigned char ipx_router_node[IPX_NODE_LEN]; -} ipx_route_definition; +}; -typedef struct ipx_interface_definition -{ +struct ipx_interface_definition { __u32 ipx_network; unsigned char ipx_device[16]; unsigned char ipx_dlink_type; @@ -47,13 +45,12 @@ typedef struct ipx_interface_definition #define IPX_PRIMARY 1 #define IPX_INTERNAL 2 unsigned char ipx_node[IPX_NODE_LEN]; -} ipx_interface_definition; +}; -typedef struct ipx_config_data -{ +struct ipx_config_data { unsigned char ipxcfg_auto_select_primary; unsigned char ipxcfg_auto_create_interfaces; -} ipx_config_data; +}; /* * OLD Route Definition for backward compatibility. @@ -77,13 +74,4 @@ struct ipx_route_def #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1) #define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2) #define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3) - -#ifdef __KERNEL__ -#include <linux/skbuff.h> - -extern int ipxrtr_route_skb(struct sk_buff *); -extern int ipx_if_offset(unsigned long ipx_net_number); -extern void ipx_remove_socket(struct sock *sk); -#endif /* def __KERNEL__ */ - #endif /* def _IPX_H_ */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 1e7feee38df6a67b5d39b9b425d09b70bdd7846a..a812681251633b52ad7f6dd6dc17b8ce339c435b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -182,7 +182,6 @@ struct sk_buff { struct icmphdr *icmph; struct igmphdr *igmph; struct iphdr *ipiph; - struct spxhdr *spxh; unsigned char *raw; } h; @@ -190,7 +189,6 @@ struct sk_buff { struct iphdr *iph; struct ipv6hdr *ipv6h; struct arphdr *arph; - struct ipxhdr *ipxh; unsigned char *raw; } nh; diff --git a/include/net/ipx.h b/include/net/ipx.h index 3e013f3f4804f3d2d29f340aa6a89b3f237e06e9..1f59db84c1a1823c0ee929044d8ee1013cfe94c0 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -14,12 +14,11 @@ #include <net/datalink.h> #include <linux/ipx.h> -typedef struct -{ +struct ipx_address { __u32 net; __u8 node[IPX_NODE_LEN]; __u16 sock; -} ipx_address; +}; #define ipx_broadcast_node "\377\377\377\377\377\377" #define ipx_this_node "\0\0\0\0\0\0" @@ -39,11 +38,16 @@ struct ipxhdr #define IPX_TYPE_SPX 0x05 /* SPX protocol */ #define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */ #define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */ - ipx_address ipx_dest __attribute__ ((packed)); - ipx_address ipx_source __attribute__ ((packed)); + struct ipx_address ipx_dest __attribute__ ((packed)); + struct ipx_address ipx_source __attribute__ ((packed)); }; -typedef struct ipx_interface { +static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb) +{ + return (struct ipxhdr *)skb->h.raw; +} + +struct ipx_interface { /* IPX address */ __u32 if_netnum; unsigned char if_node[IPX_NODE_LEN]; @@ -65,16 +69,16 @@ typedef struct ipx_interface { unsigned char if_primary; struct ipx_interface *if_next; -} ipx_interface; +}; -typedef struct ipx_route { +struct ipx_route { __u32 ir_net; - ipx_interface *ir_intrfc; + struct ipx_interface *ir_intrfc; unsigned char ir_routed; unsigned char ir_router_node[IPX_NODE_LEN]; - struct ipx_route *ir_next; + struct ipx_route *ir_next; atomic_t refcnt; -} ipx_route; +}; #ifdef __KERNEL__ struct ipx_cb { @@ -88,8 +92,8 @@ struct ipx_cb { }; struct ipx_opt { - ipx_address dest_addr; - ipx_interface *intrfc; + struct ipx_address dest_addr; + struct ipx_interface *intrfc; unsigned short port; #ifdef CONFIG_IPX_INTERN unsigned char node[IPX_NODE_LEN]; @@ -106,7 +110,4 @@ struct ipx_opt { #define IPX_MIN_EPHEMERAL_SOCKET 0x4000 #define IPX_MAX_EPHEMERAL_SOCKET 0x7fff -extern int ipx_register_spx(struct proto_ops **, struct net_proto_family *); -extern int ipx_unregister_spx(void); - #endif /* def _NET_INET_IPX_H_ */ diff --git a/include/net/spx.h b/include/net/spx.h deleted file mode 100644 index 951953d0a8e27e802b44485a8a91cbcf43e7a9bd..0000000000000000000000000000000000000000 --- a/include/net/spx.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __NET_SPX_H -#define __NET_SPX_H - -#include <net/ipx.h> - -struct spxhdr -{ __u8 cctl; - __u8 dtype; -#define SPX_DTYPE_ECONN 0xFE /* Finished */ -#define SPX_DTYPE_ECACK 0xFF /* Ok */ - __u16 sconn; /* Connection ID */ - __u16 dconn; /* Connection ID */ - __u16 sequence; - __u16 ackseq; - __u16 allocseq; -}; - -struct ipxspxhdr -{ struct ipxhdr ipx; - struct spxhdr spx; -}; - -#define SPX_SYS_PKT_LEN (sizeof(struct ipxspxhdr)) - -#ifdef __KERNEL__ -struct spx_opt -{ int state; - int sndbuf; - int retries; /* Number of WD retries */ - int retransmits; /* Number of retransmits */ - int max_retries; - int wd_interval; - void *owner; - __u16 dest_connid; /* Net order */ - __u16 source_connid; /* Net order */ - __u16 sequence; /* Host order - our current pkt # */ - __u16 alloc; /* Host order - max seq we can rcv now */ - __u16 rmt_ack; /* Host order - last pkt ACKd by remote */ - __u16 rmt_seq; - __u16 acknowledge; - __u16 rmt_alloc; /* Host order - max seq remote can handle now */ - ipx_address dest_addr; - ipx_address source_addr; - struct timer_list watchdog; /* Idle watch */ - struct timer_list retransmit; /* Retransmit timer */ - struct sk_buff_head rcv_queue; - struct sk_buff_head transmit_queue; - struct sk_buff_head retransmit_queue; -}; - -#define spx_sk(__sk) ((struct spx_opt *)(((struct sock *)(__sk)) + 1)) - -/* Packet connectino control defines */ -#define CCTL_SPXII_XHD 0x01 /* SPX2 extended header */ -#define CCTL_SPX_UNKNOWN 0x02 /* Unknown (unused ??) */ -#define CCTL_SPXII_NEG 0x04 /* Negotiate size */ -#define CCTL_SPXII 0x08 /* Set for SPX2 */ -#define CCTL_EOM 0x10 /* End of message marker */ -#define CCTL_URG 0x20 /* Urgent marker in SPP (not used in SPX?) */ -#define CCTL_ACK 0x40 /* Send me an ACK */ -#define CCTL_CTL 0x80 /* Control message */ -#define CCTL_SYS CCTL_CTL /* Spec uses CCTL_SYS */ - -/* Connection state defines */ -#define SPX_CLOSED 7 -#define SPX_CONNECTING 8 -#define SPX_CONNECTED 9 - -/* Packet transmit types - Internal */ -#define DATA 0 /* Data */ -#define ACK 1 /* Data ACK */ -#define WDACK 2 /* WD ACK */ -#define CONACK 3 /* Connection Request ACK */ -#define CONREQ 4 /* Connection Request */ -#define WDREQ 5 /* WD Request */ -#define DISCON 6 /* Informed Disconnect */ -#define DISACK 7 /* Informed Disconnect ACK */ -#define RETRAN 8 /* Int. Retransmit of packet */ -#define TQUEUE 9 /* Int. Transmit of a queued packet */ - -/* - * These are good canidates for IOcontrol calls - */ - -/* Watchdog defines */ -#define VERIFY_TIMEOUT 3 * HZ -#define ABORT_TIMEOUT 30 * HZ - -/* Packet retransmit defines */ -#define RETRY_COUNT 10 -#define RETRY_TIME 1 * HZ -#define MAX_RETRY_DELAY 5 * HZ - -#endif /* __KERNEL__ */ -#endif /* def __NET_SPX_H */ diff --git a/net/ipx/Config.help b/net/ipx/Config.help index 0fd66cbf57efce7a8ce4914b7f94cdb34d8a9f9d..49ab84e0c74c548db52d46c8f2f7dcffeb78784e 100644 --- a/net/ipx/Config.help +++ b/net/ipx/Config.help @@ -23,25 +23,3 @@ CONFIG_IPX_INTERN If you don't know what you are doing, say N. -CONFIG_SPX - * Orphaned entry retained 20 April 2001 by Petr Vandrovec * - * If you read this note from the configurator, please contact * - * the Configure.help maintainers. * - The Sequenced Packet eXchange protocol is a transport layer protocol - built on top of IPX. It is used in Novell NetWare systems for - client-server applications and is similar to TCP (which runs on top - of IP). - - Note that Novell NetWare file sharing does not use SPX; it uses a - protocol called NCP, for which separate Linux support is available - ("NCP file system support" below for the client side, and the user - space programs lwared or mars_nwe for the server side). - - Say Y here if you have use for SPX; read the IPX-HOWTO at - <http://www.linuxdoc.org/docs.html#howto> for details. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called af_spx.o. If you want to compile it as a - module, say M here and read <file:Documentation/modules.txt>. - diff --git a/net/ipx/Config.in b/net/ipx/Config.in index 0c798e495b4bf011ca4158201064a293b2c664aa..c16672edd4feea4578b75e60b350d7ed7707896f 100644 --- a/net/ipx/Config.in +++ b/net/ipx/Config.in @@ -3,6 +3,3 @@ # bool ' IPX: Full internal IPX network' CONFIG_IPX_INTERN -#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -# dep_tristate ' IPX: SPX networking (EXPERIMENTAL)' CONFIG_SPX $CONFIG_IPX -#fi diff --git a/net/ipx/Makefile b/net/ipx/Makefile index a7683693c1e8c5544b85a574633efdcbb0de948b..5bf1385eabd98fdb9d5bb0e156c26ad53f1f9954 100644 --- a/net/ipx/Makefile +++ b/net/ipx/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_IPX) += ipx.o ipx-y := af_ipx.o ipx-$(CONFIG_SYSCTL) += sysctl_net_ipx.o -ipx-$(CONFIG_SPX) += af_spx.o ipx-objs := $(ipx-y) include $(TOPDIR)/Rules.make diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 2577ad82185caf92e77359139343be36b80d5994..1e13d83d0fd925df510a6550481412e3f1ac26dd 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -76,6 +76,7 @@ * Revision 048: Use sk->protinfo to store the pointer to IPX private * area, remove af_ipx from sk->protinfo and move ipx_opt * to include/net/ipx.h, use IPX_SK like DecNET, etc + * Revision 049: SPX support dropped, see comment in ipx_create * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -144,17 +145,14 @@ static struct datalink_proto *pSNAP_datalink; static struct proto_ops ipx_dgram_ops; -static struct net_proto_family *spx_family_ops; -static DECLARE_RWSEM(spx_family_ops_lock); - -static ipx_route *ipx_routes; +static struct ipx_route *ipx_routes; static rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED; -static ipx_interface *ipx_interfaces; +static struct ipx_interface *ipx_interfaces; static spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED; -static ipx_interface *ipx_primary_net; -static ipx_interface *ipx_internal_net; +static struct ipx_interface *ipx_primary_net; +static struct ipx_interface *ipx_internal_net; #undef IPX_REFCNT_DEBUG #ifdef IPX_REFCNT_DEBUG @@ -180,9 +178,9 @@ static void ipxcfg_set_auto_select(char val) ipx_primary_net = ipx_interfaces; } -static int ipxcfg_get_config_data(ipx_config_data *arg) +static int ipxcfg_get_config_data(struct ipx_config_data *arg) { - ipx_config_data vals; + struct ipx_config_data vals; vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; @@ -192,22 +190,22 @@ static int ipxcfg_get_config_data(ipx_config_data *arg) /* Handlers for the socket list. */ -static inline void ipxitf_hold(ipx_interface *intrfc) +static __inline__ void ipxitf_hold(struct ipx_interface *intrfc) { atomic_inc(&intrfc->refcnt); } -static void ipxitf_down(ipx_interface *intrfc); +static void ipxitf_down(struct ipx_interface *intrfc); -static inline void ipxitf_put(ipx_interface *intrfc) +static __inline__ void ipxitf_put(struct ipx_interface *intrfc) { if (atomic_dec_and_test(&intrfc->refcnt)) ipxitf_down(intrfc); } -static void __ipxitf_down(ipx_interface *intrfc); +static void __ipxitf_down(struct ipx_interface *intrfc); -static inline void __ipxitf_put(ipx_interface *intrfc) +static __inline__ void __ipxitf_put(struct ipx_interface *intrfc) { if (atomic_dec_and_test(&intrfc->refcnt)) __ipxitf_down(intrfc); @@ -218,11 +216,11 @@ static inline void __ipxitf_put(ipx_interface *intrfc) * use this facility. */ -void ipx_remove_socket(struct sock *sk) +static void ipx_remove_socket(struct sock *sk) { struct sock *s; /* Determine interface with which socket is associated */ - ipx_interface *intrfc = ipx_sk(sk)->intrfc; + struct ipx_interface *intrfc = ipx_sk(sk)->intrfc; if (!intrfc) goto out; @@ -268,7 +266,7 @@ static void ipx_destroy_socket(struct sock *sk) * The following code is used to support IPX Interfaces (IPXITF). An * IPX interface is defined by a physical device and a frame type. */ -static ipx_route * ipxrtr_lookup(__u32); +static struct ipx_route *ipxrtr_lookup(__u32 net); /* ipxitf_clear_primary_net has to be called with ipx_interfaces_lock held */ @@ -277,10 +275,10 @@ static void ipxitf_clear_primary_net(void) ipx_primary_net = ipxcfg_auto_select_primary ? ipx_interfaces : NULL; } -static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, - unsigned short datalink) +static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, + unsigned short datalink) { - ipx_interface *i = ipx_interfaces; + struct ipx_interface *i = ipx_interfaces; while (i && (i->if_dev != dev || i->if_dlink_type != datalink)) i = i->if_next; @@ -288,10 +286,10 @@ static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, return i; } -static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, - unsigned short datalink) +static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, + unsigned short datalink) { - ipx_interface *i; + struct ipx_interface *i; spin_lock_bh(&ipx_interfaces_lock); i = __ipxitf_find_using_phys(dev, datalink); @@ -301,9 +299,9 @@ static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, return i; } -static ipx_interface *ipxitf_find_using_net(__u32 net) +static struct ipx_interface *ipxitf_find_using_net(__u32 net) { - ipx_interface *i; + struct ipx_interface *i; spin_lock_bh(&ipx_interfaces_lock); if (net) @@ -320,7 +318,7 @@ static ipx_interface *ipxitf_find_using_net(__u32 net) } /* Sockets are bound to a particular IPX interface. */ -static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) +static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk) { ipxitf_hold(intrfc); sock_hold(sk); @@ -340,7 +338,7 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) } /* caller must hold intrfc->if_sklist_lock */ -static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, +static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, unsigned short port) { struct sock *s = intrfc->if_sklist; @@ -352,7 +350,7 @@ static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, } /* caller must hold a reference to intrfc */ -static struct sock *ipxitf_find_socket(ipx_interface *intrfc, +static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, unsigned short port) { struct sock *s; @@ -367,8 +365,9 @@ static struct sock *ipxitf_find_socket(ipx_interface *intrfc, } #ifdef CONFIG_IPX_INTERN -static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, - unsigned char *node, unsigned short port) +static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, + unsigned char *node, + unsigned short port) { struct sock *s; @@ -391,9 +390,9 @@ static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, } #endif -static void ipxrtr_del_routes(ipx_interface *); +static void ipxrtr_del_routes(struct ipx_interface *intrfc); -static void __ipxitf_down(ipx_interface *intrfc) +static void __ipxitf_down(struct ipx_interface *intrfc) { struct sock *s, *t; @@ -421,7 +420,7 @@ static void __ipxitf_down(ipx_interface *intrfc) if (intrfc == ipx_interfaces) ipx_interfaces = intrfc->if_next; else { - ipx_interface *i = ipx_interfaces; + struct ipx_interface *i = ipx_interfaces; while (i && i->if_next != intrfc) i = i->if_next; if (i && i->if_next == intrfc) @@ -440,7 +439,7 @@ static void __ipxitf_down(ipx_interface *intrfc) MOD_DEC_USE_COUNT; } -static void ipxitf_down(ipx_interface *intrfc) +static void ipxitf_down(struct ipx_interface *intrfc) { spin_lock_bh(&ipx_interfaces_lock); __ipxitf_down(intrfc); @@ -451,7 +450,7 @@ static int ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr) { struct net_device *dev = ptr; - ipx_interface *i, *tmp; + struct ipx_interface *i, *tmp; if (event != NETDEV_DOWN && event != NETDEV_UP) goto out; @@ -484,10 +483,10 @@ static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) /* caller must hold a reference to intrfc */ #ifdef CONFIG_IPX_INTERN -static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, - int copy) +static int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy) { - struct ipxhdr *ipx = skb->nh.ipxh; + struct ipxhdr *ipx = ipx_hdr(skb); int is_broadcast = !memcmp(ipx->ipx_dest.node, ipx_broadcast_node, IPX_NODE_LEN); struct sock *s; @@ -532,7 +531,7 @@ out: spin_unlock_bh(&intrfc->if_sklist_lock); return ret; } #else -static struct sock *ncp_connection_hack(ipx_interface *intrfc, +static struct sock *ncp_connection_hack(struct ipx_interface *intrfc, struct ipxhdr *ipx) { /* The packet's target is a NCP connection handler. We want to hand it @@ -566,10 +565,10 @@ static struct sock *ncp_connection_hack(ipx_interface *intrfc, return sk; } -static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, - int copy) +static int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy) { - struct ipxhdr *ipx = skb->nh.ipxh; + struct ipxhdr *ipx = ipx_hdr(skb); struct sock *sock1 = NULL, *sock2 = NULL; struct sk_buff *skb1 = NULL, *skb2 = NULL; int ret; @@ -651,11 +650,11 @@ out: if (sock1) } #endif /* CONFIG_IPX_INTERN */ -static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, +static struct sk_buff *ipxitf_adjust_skbuff(struct ipx_interface *intrfc, struct sk_buff *skb) { struct sk_buff *skb2; - int in_offset = skb->h.raw - skb->head; + int in_offset = (unsigned char *)ipx_hdr(skb) - skb->head; int out_offset = intrfc->if_ipx_offset; int len; @@ -669,7 +668,7 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, if (skb2) { skb_reserve(skb2, out_offset); skb2->nh.raw = skb2->h.raw = skb_put(skb2, skb->len); - memcpy(skb2->h.raw, skb->h.raw, skb->len); + memcpy(ipx_hdr(skb2), ipx_hdr(skb), skb->len); memcpy(skb2->cb, skb->cb, sizeof(skb->cb)); } kfree_skb(skb); @@ -678,9 +677,10 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, /* caller must hold a reference to intrfc and the skb has to be unshared */ -static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) +static int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, + char *node) { - struct ipxhdr *ipx = skb->nh.ipxh; + struct ipxhdr *ipx = ipx_hdr(skb); struct net_device *dev = intrfc->if_dev; struct datalink_proto *dl = intrfc->if_dlink; char dest_node[IPX_NODE_LEN]; @@ -784,21 +784,24 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) out: return 0; } -static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); +static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, + unsigned char *); -static int ipxitf_add_local_route(ipx_interface *intrfc) +static int ipxitf_add_local_route(struct ipx_interface *intrfc) { return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL); } -static const char * ipx_frame_name(unsigned short); -static const char * ipx_device_name(ipx_interface *); -static void ipxitf_discover_netnum(ipx_interface *intrfc, struct sk_buff *skb); -static int ipxitf_pprop(ipx_interface *intrfc, struct sk_buff *skb); +static const char *ipx_frame_name(unsigned short); +static const char *ipx_device_name(struct ipx_interface *); +static void ipxitf_discover_netnum(struct ipx_interface *intrfc, + struct sk_buff *skb); +static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb); +static int ipxrtr_route_skb(struct sk_buff *skb); -static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) +static int ipxitf_rcv(struct ipx_interface *intrfc, struct sk_buff *skb) { - struct ipxhdr *ipx = skb->nh.ipxh; + struct ipxhdr *ipx = ipx_hdr(skb); int ret = 0; ipxitf_hold(intrfc); @@ -850,13 +853,15 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) return ret; } -static void ipxitf_discover_netnum(ipx_interface *intrfc, struct sk_buff *skb) +static void ipxitf_discover_netnum(struct ipx_interface *intrfc, + struct sk_buff *skb) { const struct ipx_cb *cb = IPX_SKB_CB(skb); /* see if this is an intra packet: source_net == dest_net */ if (cb->ipx_source_net == cb->ipx_dest_net && cb->ipx_source_net) { - ipx_interface *i = ipxitf_find_using_net(cb->ipx_source_net); + struct ipx_interface *i = + ipxitf_find_using_net(cb->ipx_source_net); /* NB: NetWare servers lie about their hop count so we * dropped the test based on it. This is the best way * to determine this is a 0 hop count packet. */ @@ -900,11 +905,11 @@ static void ipxitf_discover_netnum(ipx_interface *intrfc, struct sk_buff *skb) * Returns -EINVAL for invalid packets, so that the calling function drops * the packet without local processing. 0 if packet is to be locally processed. */ -static int ipxitf_pprop(ipx_interface *intrfc, struct sk_buff *skb) +static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) { - struct ipxhdr *ipx = skb->nh.ipxh; + struct ipxhdr *ipx = ipx_hdr(skb); int i, ret = -EINVAL; - ipx_interface *ifcs; + struct ipx_interface *ifcs; char *c; u32 *l; @@ -968,14 +973,14 @@ static int ipxitf_pprop(ipx_interface *intrfc, struct sk_buff *skb) out: return ret; } -static void ipxitf_insert(ipx_interface *intrfc) +static void ipxitf_insert(struct ipx_interface *intrfc) { intrfc->if_next = NULL; spin_lock_bh(&ipx_interfaces_lock); if (!ipx_interfaces) ipx_interfaces = intrfc; else { - ipx_interface *i = ipx_interfaces; + struct ipx_interface *i = ipx_interfaces; while (i->if_next) i = i->if_next; i->if_next = intrfc; @@ -986,12 +991,13 @@ static void ipxitf_insert(ipx_interface *intrfc) ipx_primary_net = intrfc; } -static ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, - unsigned short dlink_type, - struct datalink_proto *dlink, - unsigned char internal, int ipx_offset) +static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, + unsigned short dlink_type, + struct datalink_proto *dlink, + unsigned char internal, + int ipx_offset) { - ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC); + struct ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC); if (intrfc) { intrfc->if_dev = dev; @@ -1010,9 +1016,9 @@ static ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, return intrfc; } -static int ipxitf_create_internal(ipx_interface_definition *idef) +static int ipxitf_create_internal(struct ipx_interface_definition *idef) { - ipx_interface *intrfc; + struct ipx_interface *intrfc; int ret = -EEXIST; /* Only one primary network allowed */ @@ -1061,12 +1067,12 @@ static int ipx_map_frame_type(unsigned char type) return ret; } -static int ipxitf_create(ipx_interface_definition *idef) +static int ipxitf_create(struct ipx_interface_definition *idef) { struct net_device *dev; unsigned short dlink_type = 0; struct datalink_proto *datalink = NULL; - ipx_interface *intrfc; + struct ipx_interface *intrfc; int err; if (idef->ipx_special == IPX_INTERNAL) { @@ -1173,11 +1179,11 @@ static int ipxitf_create(ipx_interface_definition *idef) out: return err; } -static int ipxitf_delete(ipx_interface_definition *idef) +static int ipxitf_delete(struct ipx_interface_definition *idef) { struct net_device *dev = NULL; unsigned short dlink_type = 0; - ipx_interface *intrfc; + struct ipx_interface *intrfc; int ret = 0; spin_lock_bh(&ipx_interfaces_lock); @@ -1211,10 +1217,10 @@ out: spin_unlock_bh(&ipx_interfaces_lock); return ret; } -static ipx_interface *ipxitf_auto_create(struct net_device *dev, - unsigned short dlink_type) +static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, + unsigned short dlink_type) { - ipx_interface *intrfc = NULL; + struct ipx_interface *intrfc = NULL; struct datalink_proto *datalink; if (!dev) @@ -1269,7 +1275,7 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) switch (cmd) { case SIOCSIFADDR: { struct sockaddr_ipx *sipx; - ipx_interface_definition f; + struct ipx_interface_definition f; if (copy_from_user(&ifr, arg, sizeof(ifr))) return -EFAULT; @@ -1294,7 +1300,7 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) case SIOCGIFADDR: { int err = 0; struct sockaddr_ipx *sipx; - ipx_interface *ipxif; + struct ipx_interface *ipxif; struct net_device *dev; if (copy_from_user(&ifr, arg, sizeof(ifr))) @@ -1341,20 +1347,20 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) /* Routing tables for the IPX socket layer. */ -static inline void ipxrtr_hold(ipx_route *rt) +static __inline__ void ipxrtr_hold(struct ipx_route *rt) { atomic_inc(&rt->refcnt); } -static inline void ipxrtr_put(ipx_route *rt) +static __inline__ void ipxrtr_put(struct ipx_route *rt) { if (atomic_dec_and_test(&rt->refcnt)) kfree(rt); } -static ipx_route *ipxrtr_lookup(__u32 net) +static struct ipx_route *ipxrtr_lookup(__u32 net) { - ipx_route *r; + struct ipx_route *r; read_lock_bh(&ipx_routes_lock); for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next) @@ -1368,16 +1374,16 @@ static ipx_route *ipxrtr_lookup(__u32 net) /* caller must hold a reference to intrfc */ -static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, - unsigned char *node) +static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, + unsigned char *node) { - ipx_route *rt; + struct ipx_route *rt; int ret; /* Get a route structure; either existing or create */ rt = ipxrtr_lookup(network); if (!rt) { - rt = kmalloc(sizeof(ipx_route), GFP_ATOMIC); + rt = kmalloc(sizeof(*rt), GFP_ATOMIC); ret = -EAGAIN; if (!rt) goto out; @@ -1410,9 +1416,9 @@ static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, out: return ret; } -static void ipxrtr_del_routes(ipx_interface *intrfc) +static void ipxrtr_del_routes(struct ipx_interface *intrfc) { - ipx_route **r, *tmp; + struct ipx_route **r, *tmp; write_lock_bh(&ipx_routes_lock); for (r = &ipx_routes; (tmp = *r) != NULL;) { @@ -1425,9 +1431,9 @@ static void ipxrtr_del_routes(ipx_interface *intrfc) write_unlock_bh(&ipx_routes_lock); } -static int ipxrtr_create(ipx_route_definition *rd) +static int ipxrtr_create(struct ipx_route_definition *rd) { - ipx_interface *intrfc; + struct ipx_interface *intrfc; int ret = -ENETUNREACH; /* Find the appropriate interface */ @@ -1441,8 +1447,8 @@ out: return ret; static int ipxrtr_delete(long net) { - ipx_route **r; - ipx_route *tmp; + struct ipx_route **r; + struct ipx_route *tmp; int err; write_lock_bh(&ipx_routes_lock); @@ -1513,11 +1519,11 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, { struct sk_buff *skb; struct ipx_opt *ipxs = ipx_sk(sk); - ipx_interface *intrfc; + struct ipx_interface *intrfc; struct ipxhdr *ipx; int size; int ipx_offset; - ipx_route *rt = NULL; + struct ipx_route *rt = NULL; int err; /* Find the appropriate interface on which to send packet */ @@ -1544,11 +1550,11 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, skb->sk = sk; /* Fill in IPX header */ - ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr)); + skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxhdr)); + ipx = ipx_hdr(skb); ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr)); IPX_SKB_CB(skb)->ipx_tctrl = 0; ipx->ipx_type = usipx->sipx_type; - skb->h.raw = (void *)skb->nh.ipxh = ipx; IPX_SKB_CB(skb)->last_hop.index = -1; #ifdef CONFIG_IPX_INTERN @@ -1596,8 +1602,8 @@ out: return err; * modify the packet */ int ipxrtr_route_skb(struct sk_buff *skb) { - struct ipxhdr *ipx = skb->nh.ipxh; - ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net); + struct ipxhdr *ipx = ipx_hdr(skb); + struct ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net); if (!r) { /* no known route */ kfree_skb(skb); @@ -1666,7 +1672,7 @@ static const char *ipx_frame_name(unsigned short frame) return ret; } -static const char *ipx_device_name(ipx_interface *intrfc) +static const char *ipx_device_name(struct ipx_interface *intrfc) { return intrfc->if_internal ? "Internal" : intrfc->if_dev ? intrfc->if_dev->name : "Unknown"; @@ -1676,7 +1682,7 @@ static const char *ipx_device_name(ipx_interface *intrfc) static int ipx_interface_get_info(char *buffer, char **start, off_t offset, int length) { - ipx_interface *i; + struct ipx_interface *i; off_t begin = 0, pos = 0; int len = 0; @@ -1728,7 +1734,7 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, static int ipx_get_info(char *buffer, char **start, off_t offset, int length) { struct sock *s; - ipx_interface *i; + struct ipx_interface *i; off_t begin = 0, pos = 0; int len = 0; @@ -1808,7 +1814,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) { - ipx_route *rt; + struct ipx_route *rt; off_t begin = 0, pos = 0; int len = 0; @@ -1927,17 +1933,11 @@ static int ipx_create(struct socket *sock, int protocol) case SOCK_SEQPACKET: /* - * From this point on SPX sockets are handled - * by af_spx.c and the methods replaced. + * SPX support is not anymore in the kernel sources. If + * you want to ressurrect it, completing it and making + * it understand shared skbs, be fully multithreaded, + * etc, grab the sources in an early 2.5 kernel tree. */ - down_read(&spx_family_ops_lock); - if (spx_family_ops) { - ret = spx_family_ops->create(sock, protocol); - up_read(&spx_family_ops_lock); - goto decmod; - } - up_read(&spx_family_ops_lock); - /* Fall through if SPX is not loaded */ case SOCK_STREAM: /* Allow higher levels to piggyback */ default: goto decmod; @@ -1978,7 +1978,7 @@ out: return 0; /* caller must hold a reference to intrfc */ -static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) +static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) { unsigned short socketNum = intrfc->if_sknum; @@ -2003,7 +2003,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; struct ipx_opt *ipxs = ipx_sk(sk); - ipx_interface *intrfc; + struct ipx_interface *intrfc; struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; int ret = -EINVAL; @@ -2101,7 +2101,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, struct ipx_opt *ipxs = ipx_sk(sk); struct sockaddr_ipx *addr; int ret = -EINVAL; - ipx_route *rt; + struct ipx_route *rt; sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; @@ -2158,7 +2158,7 @@ out: return ret; static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { - ipx_address *addr; + struct ipx_address *addr; struct sockaddr_ipx sipx; struct sock *sk = sock->sk; struct ipx_opt *ipxs = ipx_sk(sk); @@ -2204,7 +2204,7 @@ out: return ret; int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { /* NULL here for pt means the packet was looped back */ - ipx_interface *intrfc; + struct ipx_interface *intrfc; struct ipxhdr *ipx; u16 ipx_pktsize; int ret = 0; @@ -2216,7 +2216,7 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) goto out; - ipx = skb->nh.ipxh; + ipx = ipx_hdr(skb); ipx_pktsize = ntohs(ipx->ipx_pktsize); /* Too small or invalid header? */ @@ -2352,7 +2352,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, if (!skb) goto out; - ipx = skb->nh.ipxh; + ipx = ipx_hdr(skb); copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); if (copied > size) { copied = size; @@ -2461,64 +2461,33 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return 0; } -/* - * SPX interface support - */ - -int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx) -{ - int err; - - err = -EBUSY; - down_write(&spx_family_ops_lock); - if (!spx_family_ops) { - MOD_INC_USE_COUNT; - *p = &ipx_dgram_ops; - spx_family_ops = spx; - } - up_write(&spx_family_ops_lock); - return 0; -} - -int ipx_unregister_spx(void) -{ - down_write(&spx_family_ops_lock); - if (spx_family_ops) { - spx_family_ops = NULL; - MOD_DEC_USE_COUNT; - } - up_write(&spx_family_ops_lock); - return 0; -} - /* * Socket family declarations */ static struct net_proto_family ipx_family_ops = { - .family = PF_IPX, - .create = ipx_create, + .family = PF_IPX, + .create = ipx_create, }; static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { - .family = PF_IPX, - - .release = ipx_release, - .bind = ipx_bind, - .connect = ipx_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = ipx_getname, - .poll = datagram_poll, - .ioctl = ipx_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, /* FIXME: have to support shutdown */ - .setsockopt = ipx_setsockopt, - .getsockopt = ipx_getsockopt, - .sendmsg = ipx_sendmsg, - .recvmsg = ipx_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, + .family = PF_IPX, + .release = ipx_release, + .bind = ipx_bind, + .connect = ipx_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = ipx_getname, + .poll = datagram_poll, + .ioctl = ipx_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, /* FIXME: support shutdown */ + .setsockopt = ipx_setsockopt, + .getsockopt = ipx_getsockopt, + .sendmsg = ipx_sendmsg, + .recvmsg = ipx_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, }; #include <linux/smp_lock.h> @@ -2540,7 +2509,6 @@ static struct notifier_block ipx_dev_notifier = { .notifier_call =ipxitf_device_event, }; - extern struct datalink_proto *make_EII_client(void); extern struct datalink_proto *make_8023_client(void); extern void destroy_EII_client(struct datalink_proto *); @@ -2549,9 +2517,13 @@ extern void destroy_8023_client(struct datalink_proto *); static unsigned char ipx_8022_type = 0xE0; static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; static char ipx_banner[] __initdata = - KERN_INFO "NET4: Linux IPX 0.48 for NET4.0\n" + KERN_INFO "NET4: Linux IPX 0.49 for NET4.0\n" KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \ KERN_INFO "IPX Portions Copyright (c) 2000, 2001 Conectiva, Inc.\n"; +static char ipx_EII_err_msg[] __initdata = + KERN_CRIT "IPX: Unable to register with Ethernet II\n"; +static char ipx_8023_err_msg[] __initdata = + KERN_CRIT "IPX: Unable to register with 802.3\n"; static char ipx_llc_err_msg[] __initdata = KERN_CRIT "IPX: Unable to register with 802.2\n"; static char ipx_snap_err_msg[] __initdata = @@ -2562,10 +2534,16 @@ static int __init ipx_init(void) sock_register(&ipx_family_ops); pEII_datalink = make_EII_client(); - dev_add_pack(&ipx_dix_packet_type); + if (pEII_datalink) + dev_add_pack(&ipx_dix_packet_type); + else + printk(ipx_EII_err_msg); p8023_datalink = make_8023_client(); - dev_add_pack(&ipx_8023_packet_type); + if (p8023_datalink) + dev_add_pack(&ipx_8023_packet_type); + else + printk(ipx_8023_err_msg); p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv); if (!p8022_datalink) @@ -2588,26 +2566,6 @@ static int __init ipx_init(void) module_init(ipx_init); -/* Higher layers need this info to prep tx pkts */ -int ipx_if_offset(unsigned long ipx_net_number) -{ - ipx_route *rt = ipxrtr_lookup(ipx_net_number); - int ret = -ENETUNREACH; - - if (!rt) - goto out; - ret = rt->ir_intrfc->if_ipx_offset; - ipxrtr_put(rt); -out: return ret; -} - -/* Export symbols for higher layers */ -EXPORT_SYMBOL(ipxrtr_route_skb); -EXPORT_SYMBOL(ipx_if_offset); -EXPORT_SYMBOL(ipx_remove_socket); -EXPORT_SYMBOL(ipx_register_spx); -EXPORT_SYMBOL(ipx_unregister_spx); - /* Note on MOD_{INC,DEC}_USE_COUNT: * * Use counts are incremented/decremented when diff --git a/net/ipx/af_spx.c b/net/ipx/af_spx.c deleted file mode 100644 index 761225f007f02ebcb5f708502666d2440f445e60..0000000000000000000000000000000000000000 --- a/net/ipx/af_spx.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * This module implements the (SPP-derived) Sequenced Packet eXchange - * (SPX) protocol for Linux 2.1.X as specified in - * NetWare SPX Services Specification, Semantics and API - * Revision: 1.00 - * Revision Date: February 9, 1993 - * - * Developers: - * Jay Schulist <jschlst@samba.org> - * Jim Freeman <jfree@caldera.com> - * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - * - * Changes: - * Alan Cox : Fixed an skb_unshare check for NULL - * that crashed it under load. Renamed and - * made static the ipx ops. Removed the hack - * ipx methods interface. Dropped AF_SPX - its - * the wrong abstraction. - * Eduardo Trapani : Added a check for the return value of - * ipx_if_offset that crashed sock_alloc_send_skb. - * Added spx_datagram_poll() so that select() - * works now on SPX sockets. Added updating - * of the alloc count to follow rmt_seq. - * Arnaldo C. Melo : Use a private slabcache for the old tp_pinfo - * struct sock member, use spx_sk and ipx_sk - * Arnaldo C. Melo : Big CodingStyle cleanup, fixes some lock leaks, - * removes a leftover of the slabcache patch. - * - * 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. - * - * None of the authors or maintainers or their employers admit - * liability nor provide warranty for any of this software. - * This material is provided "as is" and at no charge. - */ - -#include <linux/module.h> -#include <net/ipx.h> -#include <net/spx.h> -#include <net/tcp.h> -#include <net/sock.h> -#include <asm/byteorder.h> -#include <asm/uaccess.h> -#include <linux/uio.h> -#include <linux/unistd.h> -#include <linux/poll.h> - -static struct proto_ops *ipx_ops; -static struct proto_ops spx_ops; -static __u16 connids; - -/* Functions needed for SPX connection start up */ -static int spx_transmit(struct sock *sk,struct sk_buff *skb,int type,int len); -static void spx_retransmit(unsigned long data); -static void spx_watchdog(unsigned long data); -void spx_rcv(struct sock *sk, int bytes); - -extern void ipx_remove_socket(struct sock *sk); - -/* Datagram poll: the same code as datagram_poll() in net/core - but the right spx buffers are looked at and - there is no question on the type of the socket - */ -static unsigned int spx_datagram_poll(struct file * file, struct socket *sock, - poll_table *wait) -{ - struct sock *sk = sock->sk; - struct spx_opt *pdata = spx_sk(sk); - unsigned int mask; - - poll_wait(file, sk->sleep, wait); - mask = 0; - - /* exceptional events? */ - if (sk->err || !skb_queue_empty(&sk->error_queue)) - mask |= POLLERR; - if (sk->shutdown & RCV_SHUTDOWN) - mask |= POLLHUP; - - /* readable? */ - if (!skb_queue_empty(&pdata->rcv_queue)) - mask |= POLLIN | POLLRDNORM; - - /* Need to check for termination and startup */ - if (sk->state==TCP_CLOSE) - mask |= POLLHUP; - /* connection hasn't started yet? */ - if (sk->state == TCP_SYN_SENT) - goto out; - - /* writable? */ - if (sock_writeable(sk)) - mask |= POLLOUT | POLLWRNORM | POLLWRBAND; - else - set_bit(SOCK_ASYNC_NOSPACE,&sk->socket->flags); -out: return mask; -} - -/* Create the SPX specific data */ -static int spx_sock_init(struct sock *sk) -{ - struct spx_opt *pdata = spx_sk(sk); - - pdata->state = SPX_CLOSED; - pdata->sequence = 0; - pdata->acknowledge = 0; - pdata->source_connid = htons(connids); - pdata->rmt_seq = 0; - connids++; - - pdata->owner = (void *)sk; - pdata->sndbuf = sk->sndbuf; - - pdata->watchdog.function = spx_watchdog; - pdata->watchdog.data = (unsigned long)sk; - pdata->wd_interval = VERIFY_TIMEOUT; - pdata->retransmit.function = spx_retransmit; - pdata->retransmit.data = (unsigned long)sk; - pdata->retransmits = 0; - pdata->retries = 0; - pdata->max_retries = RETRY_COUNT; - - skb_queue_head_init(&pdata->rcv_queue); - skb_queue_head_init(&pdata->transmit_queue); - skb_queue_head_init(&pdata->retransmit_queue); - - return 0; -} - -static int spx_create(struct socket *sock, int protocol) -{ - struct sock *sk; - int rc = -ENOMEM; - - MOD_INC_USE_COUNT; - - /* Called on connection receive so cannot be GFP_KERNEL */ - sk = sk_alloc(PF_IPX, GFP_ATOMIC, 1); - if (!sk) - goto decmod; - - rc = -ESOCKTNOSUPPORT; - switch (sock->type) { - case SOCK_SEQPACKET: - sock->ops = &spx_ops; - break; - default: - sk_free(sk); - goto out; - } - - rc = 0; - sock_init_data(sock, sk); - spx_sock_init(sk); - sk->data_ready = spx_rcv; - sk->destruct = NULL; - sk->no_check = 1; -out: return rc; -decmod: MOD_DEC_USE_COUNT; - goto out; -} - -void spx_close_socket(struct sock *sk) -{ - struct spx_opt *pdata = spx_sk(sk); - - pdata->state = SPX_CLOSED; - sk->state = TCP_CLOSE; - del_timer(&pdata->retransmit); - del_timer(&pdata->watchdog); -} - -void spx_destroy_socket(struct sock *sk) -{ - struct spx_opt *pdata = spx_sk(sk); - - ipx_remove_socket(sk); - skb_queue_purge(&sk->receive_queue); - skb_queue_purge(&pdata->transmit_queue); - skb_queue_purge(&pdata->retransmit_queue); - skb_queue_purge(&pdata->rcv_queue); - sk_free(sk); - MOD_DEC_USE_COUNT; -} - -/* Release an SPX socket */ -static int spx_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - struct spx_opt *pdata = spx_sk(sk); - - if (!sk) - goto out; - if (!sk->dead) - sk->state_change(sk); - sk->dead = 1; - - if (pdata->state != SPX_CLOSED) { - spx_transmit(sk, NULL, DISCON, 0); - spx_close_socket(sk); - } - - sock->sk = NULL; - sk->socket = NULL; - spx_destroy_socket(sk); -out: return 0; -} - -/* Move a socket into listening state. */ -static int spx_listen(struct socket *sock, int backlog) -{ - struct sock *sk = sock->sk; - int rc = -EINVAL; - - if (sock->state != SS_UNCONNECTED) - goto out; - rc = -EOPNOTSUPP; - if (sock->type != SOCK_SEQPACKET) - goto out; - rc = -EAGAIN; - if (sk->zapped) - goto out; - rc = 0; - sk->max_ack_backlog = backlog; - if (sk->state != TCP_LISTEN) { - sk->ack_backlog = 0; - sk->state = TCP_LISTEN; - } - sk->socket->flags |= __SO_ACCEPTCON; -out: return rc; -} - -/* Accept a pending SPX connection */ -static int spx_accept(struct socket *sock, struct socket *newsock, int flags) -{ - struct sock *sk = sock->sk; - struct sock *newsk; - struct sk_buff *skb; - int rc = -EINVAL; - - if (!sk || sk->state != TCP_LISTEN || - sock->state != SS_UNCONNECTED || !(sock->flags & __SO_ACCEPTCON)) - goto out; - rc = -EOPNOTSUPP; - if (sock->type != SOCK_SEQPACKET) - goto out; - cli(); - do { - skb = skb_dequeue(&sk->receive_queue); - if (!skb) { - rc = -EWOULDBLOCK; - if (flags & O_NONBLOCK) - goto out_unlock; - interruptible_sleep_on(sk->sleep); - rc = -ERESTARTSYS; - if (signal_pending(current)) - goto out_unlock; - } - } while (!skb); - - newsk = skb->sk; - newsk->pair = NULL; - sti(); - - rc = spx_transmit(newsk, skb, CONACK, 0); /* Connection ACK */ - if (rc) - goto out; - /* Now attach up the new socket */ - sock->sk = NULL; - sk->ack_backlog--; - newsock->sk = newsk; - newsk->state = TCP_ESTABLISHED; - ipx_sk(newsk)->dest_addr = spx_sk(newsk)->dest_addr; -out: return rc; -out_unlock: - sti(); - goto out; -} - -/* Build a connection to an SPX socket */ -static int spx_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) -{ - struct sock *sk = sock->sk; - struct spx_opt *pdata = spx_sk(sk); - struct sockaddr_ipx src; - struct sk_buff *skb; - int size = sizeof(src); - int rc = ipx_ops->getname(sock, (struct sockaddr *)&src, &size, 0); - - if (rc) - goto out; - - pdata->source_addr.net = src.sipx_network; - memcpy(pdata->source_addr.node, src.sipx_node, IPX_NODE_LEN); - pdata->source_addr.sock = (unsigned short)src.sipx_port; - - rc = ipx_ops->connect(sock, uaddr, addr_len, flags); - if (rc) - goto out; - - pdata->dest_addr = ipx_sk(sk)->dest_addr; - pdata->state = SPX_CONNECTING; - sock->state = SS_CONNECTING; - sk->state = TCP_SYN_SENT; - - /* Send Connection request */ - rc = spx_transmit(sk, NULL, CONREQ, 0); - if (rc) - goto out; - - cli(); - do { - skb = skb_dequeue(&sk->receive_queue); - if (!skb) { - rc = -EWOULDBLOCK; - if (flags & O_NONBLOCK) - goto unlock; - interruptible_sleep_on(sk->sleep); - rc = -ERESTARTSYS; - if (signal_pending(current)) - goto unlock; - } - } while (!skb); - - rc = -ETIMEDOUT; - if (pdata->state == SPX_CLOSED) { - del_timer(&pdata->watchdog); - goto unlock; - } - - rc = 0; - sock->state = SS_CONNECTED; - sk->state = TCP_ESTABLISHED; - kfree_skb(skb); -unlock: sti(); -out: return rc; -} - -/* - * Calculate the timeout for a packet. Thankfully SPX has a large - * fudge factor (3/4 secs) and does not pay much attention to RTT. - * As we simply have a default retry time of 1*HZ and a max retry - * time of 5*HZ. Between those values we increase the timeout based - * on the number of retransmit tries. - * - * FixMe: This is quite fake, but will work for now. (JS) - */ -static inline unsigned long spx_calc_rtt(int tries) -{ - int rc; - - if (tries < 1) - rc = RETRY_TIME; - else if (tries > 5) - rc = MAX_RETRY_DELAY; - else - rc = tries * HZ; - return rc; -} - -static int spx_route_skb(struct spx_opt *pdata, struct sk_buff *skb, int type) -{ - int rc = -ENOBUFS; - - skb = skb_unshare(skb, GFP_ATOMIC); - if (!skb) - goto out; - rc = 0; - - switch (type) { - case CONREQ: - case DATA: - if (!skb_queue_empty(&pdata->retransmit_queue)) { - skb_queue_tail(&pdata->transmit_queue, skb); - goto out; - } - case TQUEUE: { - struct sk_buff *skb2; - pdata->retransmit.expires = jiffies + spx_calc_rtt(0); - add_timer(&pdata->retransmit); - - skb2 = skb_clone(skb, GFP_NOIO); - if (!skb2) { - rc = -ENOBUFS; - goto out; - } - skb_queue_tail(&pdata->retransmit_queue, skb2); - /* Fall thru */ - } - case ACK: - case CONACK: - case WDREQ: - case WDACK: - case DISCON: - case DISACK: - case RETRAN: - default: /* Send data */ - rc = ipxrtr_route_skb(skb); - if (rc) - kfree_skb(skb); - } -out: return rc; -} - -/* SPX packet transmit engine */ -static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len) -{ - struct spx_opt *pdata = spx_sk(sk); - struct ipxspxhdr *ipxh; - unsigned long flags; - int rc; - - if (!skb) { - int offset = ipx_if_offset(pdata->dest_addr.net); - int size = offset + sizeof(struct ipxspxhdr); - - rc = -ENETUNREACH; - if (offset < 0) - goto out; - - save_flags(flags); - cli(); - skb = sock_alloc_send_skb(sk, size, 0, &err); - rc = -ENOMEM; - if (!skb) { - restore_flags(flags); - goto out; - } - skb_reserve(skb, offset); - skb->h.raw = skb->nh.raw = - skb_put(skb, sizeof(struct ipxspxhdr)); - restore_flags(flags); - } - - /* IPX header */ - ipxh = (struct ipxspxhdr *)skb->nh.raw; - ipxh->ipx.ipx_checksum = 0xFFFF; - ipxh->ipx.ipx_pktsize = htons(SPX_SYS_PKT_LEN); - ipxh->ipx.ipx_tctrl = 0; - ipxh->ipx.ipx_type = IPX_TYPE_SPX; - ipxh->ipx.ipx_dest = pdata->dest_addr; - ipxh->ipx.ipx_source = pdata->source_addr; - - /* SPX header */ - ipxh->spx.dtype = 0; - ipxh->spx.sequence = htons(pdata->sequence); - ipxh->spx.ackseq = htons(pdata->rmt_seq); - ipxh->spx.sconn = pdata->source_connid; - ipxh->spx.dconn = pdata->dest_connid; - ipxh->spx.allocseq = htons(pdata->alloc); - - /* Reset/Set WD timer */ - mod_timer(&pdata->watchdog, jiffies+VERIFY_TIMEOUT); - - switch (type) { - case DATA: /* Data */ - ipxh->ipx.ipx_pktsize = htons(SPX_SYS_PKT_LEN + len); - ipxh->spx.cctl = (CCTL_ACK | CCTL_EOM); - pdata->sequence++; - break; - - case ACK: /* ACK */ - pdata->rmt_seq++; - case WDACK: /* WD ACK */ - case CONACK: /* Connection ACK */ - ipxh->spx.cctl = CCTL_SYS; - ipxh->spx.ackseq = htons(pdata->rmt_seq); - break; - - case CONREQ: /* Connection Request */ - del_timer(&pdata->watchdog); - case WDREQ: /* WD Request */ - pdata->source_connid = htons(connids++); - pdata->dest_connid = 0xFFFF; - pdata->alloc = 3 + pdata->rmt_seq; - ipxh->spx.cctl = CCTL_ACK | CCTL_SYS; - ipxh->spx.sconn = pdata->source_connid; - ipxh->spx.dconn = pdata->dest_connid; - ipxh->spx.allocseq = htons(pdata->alloc); - break; - - case DISCON: /* Informed Disconnect */ - ipxh->spx.cctl = CCTL_ACK; - ipxh->spx.dtype = SPX_DTYPE_ECONN; - break; - - case DISACK: /* Informed Disconnect ACK */ - ipxh->spx.cctl = 0; - ipxh->spx.dtype = SPX_DTYPE_ECACK; - ipxh->spx.sequence = 0; - ipxh->spx.ackseq = htons(pdata->rmt_seq++); - break; - - default: - rc = -EOPNOTSUPP; - goto out; - } - - /* Send data */ - rc = spx_route_skb(pdata, skb, type); -out: return rc; -} - -/* Check the state of the connection and send a WD request if needed. */ -static void spx_watchdog(unsigned long data) -{ - struct sock *sk = (struct sock*)data; - struct spx_opt *pdata = spx_sk(sk); - - del_timer(&pdata->watchdog); - if (pdata->state == SPX_CLOSED) - goto out; - if (pdata->retries > pdata->max_retries) { - spx_close_socket(sk); /* Unilateral Abort */ - goto out; - } - /* Send WD request */ - spx_transmit(sk, NULL, WDREQ, 0); - pdata->retries++; -out:; -} - -static void spx_retransmit(unsigned long data) -{ - struct sock *sk = (struct sock*)data; - struct spx_opt *pdata = spx_sk(sk); - struct sk_buff *skb; - unsigned long flags; - - del_timer(&pdata->retransmit); - if (pdata->state == SPX_CLOSED) - goto out; - if (pdata->retransmits > RETRY_COUNT) { - spx_close_socket(sk); /* Unilateral Abort */ - goto out; - } - /* Need to leave skb on the queue, aye the fear */ - save_flags(flags); - cli(); - skb = skb_peek(&pdata->retransmit_queue); - if (skb_cloned(skb)) - skb = skb_copy(skb, GFP_ATOMIC); - else - skb = skb_clone(skb, GFP_ATOMIC); - restore_flags(flags); - - pdata->retransmit.expires = jiffies + spx_calc_rtt(pdata->retransmits); - add_timer(&pdata->retransmit); - - spx_route_skb(pdata, skb, RETRAN); - pdata->retransmits++; -out:; -} - -/* Check packet for retransmission, ConReqAck aware */ -static int spx_retransmit_chk(struct spx_opt *pdata, int ackseq, int type) -{ - struct ipxspxhdr *ipxh; - int rc = -ENOENT; - struct sk_buff *skb = skb_dequeue(&pdata->retransmit_queue); - - if (!skb) - goto out; - rc = 0; - /* Check Data/ACK seq */ - switch (type) { - case ACK: /* Check Sequence, Should == 1 */ - ipxh = (struct ipxspxhdr *)skb->nh.raw; - if (!(ntohs(ipxh->spx.sequence) - htons(ackseq))) - break; - case CONACK: - del_timer(&pdata->retransmit); - pdata->retransmits = 0; - kfree_skb(skb); - if (skb_queue_empty(&pdata->retransmit_queue)) { - skb = skb_dequeue(&pdata->transmit_queue); - if (skb) - spx_route_skb(pdata, skb, TQUEUE); - } - goto out; - } - - skb_queue_head(&pdata->retransmit_queue, skb); - rc = -1; -out: return rc; -} - -/* SPX packet receive engine */ -void spx_rcv(struct sock *sk, int bytes) -{ - struct ipxspxhdr *ipxh; - struct spx_opt *pdata = spx_sk(sk); - struct sk_buff *skb = skb_dequeue(&sk->receive_queue); - - if (!skb) - goto out; - ipxh = (struct ipxspxhdr *)skb->nh.raw; - - /* Can't receive on a closed connection */ - if ((pdata->state == SPX_CLOSED && ipxh->spx.sequence) || - ntohs(ipxh->ipx.ipx_pktsize) < SPX_SYS_PKT_LEN || - ipxh->ipx.ipx_type != IPX_TYPE_SPX || - ntohs(ipxh->spx.ackseq) > pdata->sequence) - goto toss_skb; - - /* Reset WD timer on any received packet */ - del_timer(&pdata->watchdog); - pdata->retries = 0; - pdata->watchdog.expires = jiffies + ABORT_TIMEOUT; - add_timer(&pdata->watchdog); - - switch (ipxh->spx.cctl) { - case (CCTL_SYS | CCTL_ACK): - if (!ipxh->spx.sequence && /* ConReq */ - !ipxh->spx.ackseq && - ipxh->spx.dconn == 0xFFFF) { - pdata->state = SPX_CONNECTED; - pdata->dest_addr = ipxh->ipx.ipx_source; - pdata->source_addr = ipxh->ipx.ipx_dest; - pdata->dest_connid = ipxh->spx.sconn; - pdata->alloc = 3 + ntohs(ipxh->spx.sequence); - - skb_queue_tail(&sk->receive_queue, skb); - wake_up_interruptible(sk->sleep); - } else /* WD Request */ - spx_transmit(sk, skb, WDACK, 0); - goto out; - - case CCTL_SYS: /* ACK */ - if (!ipxh->spx.dtype && /* ConReq ACK */ - ipxh->spx.sconn != 0xFFFF && - ipxh->spx.dconn != 0xFFFF && - !ipxh->spx.sequence && - !ipxh->spx.ackseq && - pdata->state != SPX_CONNECTED) { - pdata->state = SPX_CONNECTED; - pdata->dest_connid = ipxh->spx.sconn; - - if (spx_retransmit_chk(pdata, 0, CONACK) < 0) - goto toss_skb; - - skb_queue_tail(&sk->receive_queue, skb); - wake_up_interruptible(sk->sleep); - goto out; - } - - spx_retransmit_chk(pdata, ipxh->spx.ackseq, ACK); - goto toss_skb; - - case CCTL_ACK: - /* Informed Disconnect */ - if (ipxh->spx.dtype == SPX_DTYPE_ECONN) { - spx_transmit(sk, skb, DISACK, 0); - spx_close_socket(sk); - goto out; - } - /* Fall through */ - default: - if (ntohs(ipxh->spx.sequence) == pdata->rmt_seq) { - pdata->rmt_seq = ntohs(ipxh->spx.sequence); - pdata->rmt_ack = ntohs(ipxh->spx.ackseq); - pdata->alloc = pdata->rmt_seq + 3; - if (pdata->rmt_ack > 0 || !pdata->rmt_ack) - spx_retransmit_chk(pdata, - pdata->rmt_ack, ACK); - - skb_queue_tail(&pdata->rcv_queue, skb); - wake_up_interruptible(sk->sleep); - if (ipxh->spx.cctl&CCTL_ACK) - spx_transmit(sk, NULL, ACK, 0); - goto out; - } - - if (ipxh->spx.dtype == SPX_DTYPE_ECACK) { - if (pdata->state != SPX_CLOSED) - spx_close_socket(sk); - goto toss_skb; - } - } - -toss_skb: /* Catch All */ - kfree_skb(skb); -out:; -} - -/* Get message/packet data from user-land */ -static int spx_sendmsg(struct socket *sock, struct msghdr *msg, int len, - struct scm_cookie *scm) -{ - struct sock *sk = sock->sk; - int flags = msg->msg_flags; - struct sk_buff *skb; - int offset, size, rc = -EMSGSIZE; - - if (len > 534) - goto out; - rc = -ENOTCONN; /* Socket not bound */ - if (sk->zapped) - goto out; - rc = -EINVAL; - if (flags & ~MSG_DONTWAIT) - goto out; - - offset = ipx_if_offset(spx_sk(sk)->dest_addr.net); - size = offset + sizeof(struct ipxspxhdr) + len; - - cli(); - skb = sock_alloc_send_skb(sk, size, flags&MSG_DONTWAIT, &rc); - sti(); - if (!skb) - goto out; - skb->sk = sk; - skb_reserve(skb, offset); - skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr)); - - rc = -EFAULT; - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { - kfree_skb(skb); - goto out; - } - rc = len; - if (!spx_transmit(sk, skb, DATA, len)) - rc = -EAGAIN; -out: return rc; -} - -/* Send message/packet data to user-land */ -static int spx_recvmsg(struct socket *sock, struct msghdr *msg, int size, - int flags, struct scm_cookie *scm) -{ - struct sk_buff *skb; - struct ipxspxhdr *ispxh; - struct sock *sk = sock->sk; - struct spx_opt *pdata = spx_sk(sk); - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name; - int copied, rc = -ENOTCONN; - - if (sk->zapped) /* Socket not bound */ - goto out; - lock_sock(sk); -restart: - while (skb_queue_empty(&pdata->rcv_queue)) { /* No data */ - /* Socket errors? */ - rc = sock_error(sk); - if (rc) - goto out_release_sock; - /* Socket shut down? */ - rc = -ESHUTDOWN; - if (sk->shutdown & RCV_SHUTDOWN) - goto out_release_sock; - /* handle signals */ - rc = -ERESTARTSYS; - if (signal_pending(current)) - goto out_release_sock; - /* User doesn't want to wait */ - rc = -EAGAIN; - if (flags & MSG_DONTWAIT) - goto out_release_sock; - release_sock(sk); - save_flags(flags); - cli(); - if (!skb_peek(&pdata->rcv_queue)) - interruptible_sleep_on(sk->sleep); - restore_flags(flags); - lock_sock(sk); - } - - skb = skb_dequeue(&pdata->rcv_queue); - if (!skb) - goto restart; - - ispxh = (struct ipxspxhdr *)skb->nh.raw; - copied = ntohs(ispxh->ipx.ipx_pktsize) - SPX_SYS_PKT_LEN; - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } - - rc = -EFAULT; - if (memcpy_toiovec(msg->msg_iov, skb->nh.raw + SPX_SYS_PKT_LEN, copied)) - goto out_kfree_skb; - - msg->msg_namelen = sizeof(*sipx); - if (sipx) { - sipx->sipx_family = AF_IPX; - sipx->sipx_port = ispxh->ipx.ipx_source.sock; - memcpy(sipx->sipx_node,ispxh->ipx.ipx_source.node,IPX_NODE_LEN); - sipx->sipx_network = ispxh->ipx.ipx_source.net; - sipx->sipx_type = ispxh->ipx.ipx_type; - } - rc = copied; -out_kfree_skb: - kfree_skb(skb); -out_release_sock: - release_sock(sk); -out: return rc; -} - -/* - * Functions which just wrap their IPX cousins - */ - -static int spx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -{ - return ipx_ops->bind(sock, uaddr, addr_len); -} - -static int spx_getname (struct socket *sock, struct sockaddr *uaddr, - int *usockaddr_len, int peer) -{ - return ipx_ops->getname(sock, uaddr, usockaddr_len, peer); -} - -static int spx_ioctl (struct socket *sock, unsigned int cmd, - unsigned long arg) -{ - return ipx_ops->ioctl(sock, cmd, arg); -} - -static int spx_setsockopt(struct socket *sock, int level, int optname, - char *optval, int optlen) -{ - return ipx_ops->setsockopt(sock, level, optname, optval, optlen); -} - -static int spx_getsockopt(struct socket *sock, int level, int optname, - char *optval, int *optlen) -{ - return ipx_ops->getsockopt(sock, level, optname, optval, optlen); -} - -static struct proto_ops SOCKOPS_WRAPPED(spx_ops) = { - .family = PF_IPX, - - .release = spx_release, - .bind = spx_bind, - .connect = spx_connect, - .socketpair = sock_no_socketpair, - .accept = spx_accept, - .getname = spx_getname, - .poll = spx_datagram_poll, - .ioctl = spx_ioctl, - .listen = spx_listen, - .shutdown = sock_no_shutdown, - .setsockopt = spx_setsockopt, - .getsockopt = spx_getsockopt, - .sendmsg = spx_sendmsg, - .recvmsg = spx_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -}; - -#include <linux/smp_lock.h> -SOCKOPS_WRAP(spx, PF_IPX); - -static struct net_proto_family spx_family_ops = { - .family = PF_IPX, - .create = spx_create, -}; - -static char banner[] __initdata = - KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.03\n"; - -static int __init spx_proto_init(void) -{ - connids = (__u16)jiffies; /* initalize random */ - - /* allocate our sock slab cache */ - - spx_family_ops.sk_cachep = kmem_cache_create("spx_sock", - spx_family_ops.sk_size, - 0, SLAB_HWCACHE_ALIGN, - 0, 0); - if (!spx_family_ops.sk_cachep) - printk(KERN_CRIT __FUNCTION__ - ": Cannot create spx_sock SLAB cache!\n"); - - if (ipx_register_spx(&ipx_ops, &spx_family_ops)) - printk(KERN_ERR "SPX: unable to register with IPX.\n"); - - /* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */ - - printk(banner); - return 0; -} - -static void __exit spx_proto_finito(void) -{ - ipx_unregister_spx(); -} - -module_init(spx_proto_init); -module_exit(spx_proto_finito); -MODULE_LICENSE("GPL"); diff --git a/net/ipx/sysctl_net_ipx.c b/net/ipx/sysctl_net_ipx.c index 2de49526d5cc79d4c8e215a7eea313a75c37a3c5..510eda96d10aa2d3480519474c6c0eddf0cff1e7 100644 --- a/net/ipx/sysctl_net_ipx.c +++ b/net/ipx/sysctl_net_ipx.c @@ -17,21 +17,36 @@ /* From af_ipx.c */ extern int sysctl_ipx_pprop_broadcasting; -ctl_table ipx_table[] = { - { NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting", - &sysctl_ipx_pprop_broadcasting, sizeof(int), 0644, NULL, - &proc_dointvec }, - { 0 } +static struct ctl_table ipx_table[] = { + { + .ctl_name = NET_IPX_PPROP_BROADCASTING, + .procname = "ipx_pprop_broadcasting", + .data = &sysctl_ipx_pprop_broadcasting, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { 0 }, }; -static ctl_table ipx_dir_table[] = { - { NET_IPX, "ipx", NULL, 0, 0555, ipx_table }, - { 0 } +static struct ctl_table ipx_dir_table[] = { + { + .ctl_name = NET_IPX, + .procname = "ipx", + .mode = 0555, + .child = ipx_table, + }, + { 0 }, }; -static ctl_table ipx_root_table[] = { - { CTL_NET, "net", NULL, 0, 0555, ipx_dir_table }, - { 0 } +static struct ctl_table ipx_root_table[] = { + { + .ctl_name = CTL_NET, + .procname = "net", + .mode = 0555, + .child = ipx_dir_table, + }, + { 0 }, }; static struct ctl_table_header *ipx_table_header;