Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/include/rxrpc/call.h b/include/rxrpc/call.h
new file mode 100644
index 0000000..f48f27e
--- /dev/null
+++ b/include/rxrpc/call.h
@@ -0,0 +1,212 @@
+/* call.h: Rx call record
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_CALL_H
+#define _LINUX_RXRPC_CALL_H
+
+#include <rxrpc/types.h>
+#include <rxrpc/rxrpc.h>
+#include <rxrpc/packet.h>
+#include <linux/timer.h>
+
+#define RXRPC_CALL_ACK_WINDOW_SIZE	16
+
+extern unsigned rxrpc_call_rcv_timeout;		/* receive activity timeout (secs) */
+
+/* application call state
+ * - only state 0 and ffff are reserved, the state is set to 1 after an opid is received
+ */
+enum rxrpc_app_cstate {
+	RXRPC_CSTATE_COMPLETE		= 0,	/* operation complete */
+	RXRPC_CSTATE_ERROR,			/* operation ICMP error or aborted */
+	RXRPC_CSTATE_SRVR_RCV_OPID,		/* [SERVER] receiving operation ID */
+	RXRPC_CSTATE_SRVR_RCV_ARGS,		/* [SERVER] receiving operation data */
+	RXRPC_CSTATE_SRVR_GOT_ARGS,		/* [SERVER] completely received operation data */
+	RXRPC_CSTATE_SRVR_SND_REPLY,		/* [SERVER] sending operation reply */
+	RXRPC_CSTATE_SRVR_RCV_FINAL_ACK,	/* [SERVER] receiving final ACK */
+	RXRPC_CSTATE_CLNT_SND_ARGS,		/* [CLIENT] sending operation args */
+	RXRPC_CSTATE_CLNT_RCV_REPLY,		/* [CLIENT] receiving operation reply */
+	RXRPC_CSTATE_CLNT_GOT_REPLY,		/* [CLIENT] completely received operation reply */
+} __attribute__((packed));
+
+extern const char *rxrpc_call_states[];
+
+enum rxrpc_app_estate {
+	RXRPC_ESTATE_NO_ERROR		= 0,	/* no error */
+	RXRPC_ESTATE_LOCAL_ABORT,		/* aborted locally by application layer */
+	RXRPC_ESTATE_PEER_ABORT,		/* aborted remotely by peer */
+	RXRPC_ESTATE_LOCAL_ERROR,		/* local ICMP network error */
+	RXRPC_ESTATE_REMOTE_ERROR,		/* remote ICMP network error */
+} __attribute__((packed));
+
+extern const char *rxrpc_call_error_states[];
+
+/*****************************************************************************/
+/*
+ * Rx call record and application scratch buffer
+ * - the call record occupies the bottom of a complete page
+ * - the application scratch buffer occupies the rest
+ */
+struct rxrpc_call
+{
+	atomic_t		usage;
+	struct rxrpc_connection	*conn;		/* connection upon which active */
+	spinlock_t		lock;		/* access lock */
+	struct module		*owner;		/* owner module */
+	wait_queue_head_t	waitq;		/* wait queue for events to happen */
+	struct list_head	link;		/* general internal list link */
+	struct list_head	call_link;	/* master call list link */
+	__be32			chan_ix;	/* connection channel index  */
+	__be32			call_id;	/* call ID on connection  */
+	unsigned long		cjif;		/* jiffies at call creation */
+	unsigned long		flags;		/* control flags */
+#define RXRPC_CALL_ACKS_TIMO	0x00000001	/* ACKS timeout reached */
+#define RXRPC_CALL_ACKR_TIMO	0x00000002	/* ACKR timeout reached */
+#define RXRPC_CALL_RCV_TIMO	0x00000004	/* RCV timeout reached */
+#define RXRPC_CALL_RCV_PKT	0x00000008	/* received packet */
+
+	/* transmission */
+	rxrpc_seq_t		snd_seq_count;	/* outgoing packet sequence number counter */
+	struct rxrpc_message	*snd_nextmsg;	/* next message being constructed for sending */
+	struct rxrpc_message	*snd_ping;	/* last ping message sent */
+	unsigned short		snd_resend_cnt;	/* count of resends since last ACK */
+
+	/* transmission ACK tracking */
+	struct list_head	acks_pendq;	/* messages pending ACK (ordered by seq) */
+	unsigned		acks_pend_cnt;	/* number of un-ACK'd packets */
+	rxrpc_seq_t		acks_dftv_seq;	/* highest definitively ACK'd msg seq */
+	struct timer_list	acks_timeout;	/* timeout on expected ACK */
+
+	/* reception */
+	struct list_head	rcv_receiveq;	/* messages pending reception (ordered by seq) */
+	struct list_head	rcv_krxiodq_lk;	/* krxiod queue for new inbound packets */
+	struct timer_list	rcv_timeout;	/* call receive activity timeout */
+
+	/* reception ACK'ing */
+	rxrpc_seq_t		ackr_win_bot;	/* bottom of ACK window */
+	rxrpc_seq_t		ackr_win_top;	/* top of ACK window */
+	rxrpc_seq_t		ackr_high_seq;	/* highest seqno yet received */
+	rxrpc_seq_net_t		ackr_prev_seq;	/* previous seqno received */
+	unsigned		ackr_pend_cnt;	/* number of pending ACKs */
+	struct timer_list	ackr_dfr_timo;	/* timeout on deferred ACK */
+	char			ackr_dfr_perm;	/* request for deferred ACKs permitted */
+	rxrpc_seq_t		ackr_dfr_seq;	/* seqno for deferred ACK */
+	struct rxrpc_ackpacket	ackr;		/* pending normal ACK packet */
+	uint8_t			ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE];	/* ACK records */
+
+	/* presentation layer */
+	char			app_last_rcv;	/* T if received last packet from remote end */
+	enum rxrpc_app_cstate	app_call_state;	/* call state */
+	enum rxrpc_app_estate	app_err_state;	/* abort/error state */
+	struct list_head	app_readyq;	/* ordered ready received packet queue */
+	struct list_head	app_unreadyq;	/* ordered post-hole recv'd packet queue */
+	rxrpc_seq_t		app_ready_seq;	/* last seq number dropped into readyq */
+	size_t			app_ready_qty;	/* amount of data ready in readyq */
+	unsigned		app_opcode;	/* operation ID */
+	unsigned		app_abort_code;	/* abort code (when aborted) */
+	int			app_errno;	/* error number (when ICMP error received) */
+
+	/* statisics */
+	unsigned		pkt_rcv_count;	/* count of received packets on this call */
+	unsigned		pkt_snd_count;	/* count of sent packets on this call */
+	unsigned		app_read_count;	/* number of reads issued */
+
+	/* bits for the application to use */
+	rxrpc_call_attn_func_t	app_attn_func;	/* callback when attention required */
+	rxrpc_call_error_func_t	app_error_func;	/* callback when abort sent (cleanup and put) */
+	rxrpc_call_aemap_func_t	app_aemap_func;	/* callback to map abort code to/from errno */
+	void			*app_user;	/* application data */
+	struct list_head	app_link;	/* application list linkage */
+	struct list_head	app_attn_link;	/* application attention list linkage */
+	size_t			app_mark;	/* trigger callback when app_ready_qty>=app_mark */
+	char			app_async_read;	/* T if in async-read mode */
+	uint8_t			*app_read_buf;	/* application async read buffer (app_mark size) */
+	uint8_t			*app_scr_alloc;	/* application scratch allocation pointer */
+	void			*app_scr_ptr;	/* application pointer into scratch buffer */
+
+#define RXRPC_APP_MARK_EOF 0xFFFFFFFFU	/* mark at end of input */
+
+	/* application scratch buffer */
+	uint8_t			app_scratch[0] __attribute__((aligned(sizeof(long))));
+};
+
+#define RXRPC_CALL_SCRATCH_SIZE (PAGE_SIZE - sizeof(struct rxrpc_call))
+
+#define rxrpc_call_reset_scratch(CALL) \
+do { (CALL)->app_scr_alloc = (CALL)->app_scratch; } while(0)
+
+#define rxrpc_call_alloc_scratch(CALL,SIZE)						\
+({											\
+	void *ptr;									\
+	ptr = (CALL)->app_scr_alloc;							\
+	(CALL)->app_scr_alloc += (SIZE);						\
+	if ((SIZE)>RXRPC_CALL_SCRATCH_SIZE ||						\
+	    (size_t)((CALL)->app_scr_alloc - (u8*)(CALL)) > RXRPC_CALL_SCRATCH_SIZE) {	\
+		printk("rxrpc_call_alloc_scratch(%p,%Zu)\n",(CALL),(size_t)(SIZE));	\
+		BUG();									\
+	}										\
+	ptr;										\
+})
+
+#define rxrpc_call_alloc_scratch_s(CALL,TYPE)						\
+({											\
+	size_t size = sizeof(TYPE);							\
+	TYPE *ptr;									\
+	ptr = (TYPE*)(CALL)->app_scr_alloc;						\
+	(CALL)->app_scr_alloc += size;							\
+	if (size>RXRPC_CALL_SCRATCH_SIZE ||						\
+	    (size_t)((CALL)->app_scr_alloc - (u8*)(CALL)) > RXRPC_CALL_SCRATCH_SIZE) {	\
+		printk("rxrpc_call_alloc_scratch(%p,%Zu)\n",(CALL),size);		\
+		BUG();									\
+	}										\
+	ptr;										\
+})
+
+#define rxrpc_call_is_ack_pending(CALL) ((CALL)->ackr.reason != 0)
+
+extern int rxrpc_create_call(struct rxrpc_connection *conn,
+			     rxrpc_call_attn_func_t attn,
+			     rxrpc_call_error_func_t error,
+			     rxrpc_call_aemap_func_t aemap,
+			     struct rxrpc_call **_call);
+
+extern int rxrpc_incoming_call(struct rxrpc_connection *conn,
+			       struct rxrpc_message *msg,
+			       struct rxrpc_call **_call);
+
+static inline void rxrpc_get_call(struct rxrpc_call *call)
+{
+	BUG_ON(atomic_read(&call->usage)<=0);
+	atomic_inc(&call->usage);
+	/*printk("rxrpc_get_call(%p{u=%d})\n",(C),atomic_read(&(C)->usage));*/
+}
+
+extern void rxrpc_put_call(struct rxrpc_call *call);
+
+extern void rxrpc_call_do_stuff(struct rxrpc_call *call);
+
+extern int rxrpc_call_abort(struct rxrpc_call *call, int error);
+
+#define RXRPC_CALL_READ_BLOCK	0x0001	/* block if not enough data and not yet EOF */
+#define RXRPC_CALL_READ_ALL	0x0002	/* error if insufficient data received */
+extern int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int flags);
+
+extern int rxrpc_call_write_data(struct rxrpc_call *call,
+				 size_t sioc,
+				 struct kvec *siov,
+				 uint8_t rxhdr_flags,
+				 int alloc_flags,
+				 int dup_data,
+				 size_t *size_sent);
+
+extern void rxrpc_call_handle_error(struct rxrpc_call *conn, int local, int errno);
+
+#endif /* _LINUX_RXRPC_CALL_H */
diff --git a/include/rxrpc/connection.h b/include/rxrpc/connection.h
new file mode 100644
index 0000000..41e6781
--- /dev/null
+++ b/include/rxrpc/connection.h
@@ -0,0 +1,83 @@
+/* connection.h: Rx connection record
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_CONNECTION_H
+#define _LINUX_RXRPC_CONNECTION_H
+
+#include <rxrpc/types.h>
+#include <rxrpc/krxtimod.h>
+
+struct sk_buff;
+
+/*****************************************************************************/
+/*
+ * Rx connection
+ * - connections are matched by (rmt_port,rmt_addr,service_id,conn_id,clientflag)
+ * - connections only retain a refcount on the peer when they are active
+ * - connections with refcount==0 are inactive and reside in the peer's graveyard
+ */
+struct rxrpc_connection
+{
+	atomic_t		usage;
+	struct rxrpc_transport	*trans;		/* transport endpoint */
+	struct rxrpc_peer	*peer;		/* peer from/to which connected */
+	struct rxrpc_service	*service;	/* responsible service (inbound conns) */
+	struct rxrpc_timer	timeout;	/* decaching timer */
+	struct list_head	link;		/* link in peer's list */
+	struct list_head	proc_link;	/* link in proc list */
+	struct list_head	err_link;	/* link in ICMP error processing list */
+	struct list_head	id_link;	/* link in ID grant list */
+	struct sockaddr_in	addr;		/* remote address */
+	struct rxrpc_call	*channels[4];	/* channels (active calls) */
+	wait_queue_head_t	chanwait;	/* wait for channel to become available */
+	spinlock_t		lock;		/* access lock */
+	struct timeval		atime;		/* last access time */
+	size_t			mtu_size;	/* MTU size for outbound messages */
+	unsigned		call_counter;	/* call ID counter */
+	rxrpc_serial_t		serial_counter;	/* packet serial number counter */
+
+	/* the following should all be in net order */
+	__be32			in_epoch;	/* peer's epoch */
+	__be32			out_epoch;	/* my epoch */
+	__be32			conn_id;	/* connection ID, appropriately shifted */
+	__be16			service_id;	/* service ID */
+	uint8_t			security_ix;	/* security ID */
+	uint8_t			in_clientflag;	/* RXRPC_CLIENT_INITIATED if we are server */
+	uint8_t			out_clientflag;	/* RXRPC_CLIENT_INITIATED if we are client */
+};
+
+extern int rxrpc_create_connection(struct rxrpc_transport *trans,
+				   __be16 port,
+				   __be32 addr,
+				   uint16_t service_id,
+				   void *security,
+				   struct rxrpc_connection **_conn);
+
+extern int rxrpc_connection_lookup(struct rxrpc_peer *peer,
+				   struct rxrpc_message *msg,
+				   struct rxrpc_connection **_conn);
+
+static inline void rxrpc_get_connection(struct rxrpc_connection *conn)
+{
+	BUG_ON(atomic_read(&conn->usage)<0);
+	atomic_inc(&conn->usage);
+	//printk("rxrpc_get_conn(%p{u=%d})\n",conn,atomic_read(&conn->usage));
+}
+
+extern void rxrpc_put_connection(struct rxrpc_connection *conn);
+
+extern int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
+					  struct rxrpc_call *call,
+					  struct rxrpc_message *msg);
+
+extern void rxrpc_conn_handle_error(struct rxrpc_connection *conn, int local, int errno);
+
+#endif /* _LINUX_RXRPC_CONNECTION_H */
diff --git a/include/rxrpc/krxiod.h b/include/rxrpc/krxiod.h
new file mode 100644
index 0000000..c0e0e82
--- /dev/null
+++ b/include/rxrpc/krxiod.h
@@ -0,0 +1,27 @@
+/* krxiod.h: Rx RPC I/O kernel thread interface
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_KRXIOD_H
+#define _LINUX_RXRPC_KRXIOD_H
+
+#include <rxrpc/types.h>
+
+extern int rxrpc_krxiod_init(void);
+extern void rxrpc_krxiod_kill(void);
+extern void rxrpc_krxiod_queue_transport(struct rxrpc_transport *trans);
+extern void rxrpc_krxiod_dequeue_transport(struct rxrpc_transport *trans);
+extern void rxrpc_krxiod_queue_peer(struct rxrpc_peer *peer);
+extern void rxrpc_krxiod_dequeue_peer(struct rxrpc_peer *peer);
+extern void rxrpc_krxiod_clear_peers(struct rxrpc_transport *trans);
+extern void rxrpc_krxiod_queue_call(struct rxrpc_call *call);
+extern void rxrpc_krxiod_dequeue_call(struct rxrpc_call *call);
+
+#endif /* _LINUX_RXRPC_KRXIOD_H */
diff --git a/include/rxrpc/krxsecd.h b/include/rxrpc/krxsecd.h
new file mode 100644
index 0000000..55ce43a
--- /dev/null
+++ b/include/rxrpc/krxsecd.h
@@ -0,0 +1,22 @@
+/* krxsecd.h: Rx RPC security kernel thread interface
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_KRXSECD_H
+#define _LINUX_RXRPC_KRXSECD_H
+
+#include <rxrpc/types.h>
+
+extern int rxrpc_krxsecd_init(void);
+extern void rxrpc_krxsecd_kill(void);
+extern void rxrpc_krxsecd_clear_transport(struct rxrpc_transport *trans);
+extern void rxrpc_krxsecd_queue_incoming_call(struct rxrpc_message *msg);
+
+#endif /* _LINUX_RXRPC_KRXSECD_H */
diff --git a/include/rxrpc/krxtimod.h b/include/rxrpc/krxtimod.h
new file mode 100644
index 0000000..b3d298b
--- /dev/null
+++ b/include/rxrpc/krxtimod.h
@@ -0,0 +1,45 @@
+/* krxtimod.h: RxRPC timeout daemon
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_KRXTIMOD_H
+#define _LINUX_RXRPC_KRXTIMOD_H
+
+#include <rxrpc/types.h>
+
+struct rxrpc_timer_ops {
+	/* called when the front of the timer queue has timed out */
+	void (*timed_out)(struct rxrpc_timer *timer);
+};
+
+/*****************************************************************************/
+/*
+ * RXRPC timer/timeout record
+ */
+struct rxrpc_timer
+{
+	struct list_head		link;		/* link in timer queue */
+	unsigned long			timo_jif;	/* timeout time */
+	const struct rxrpc_timer_ops	*ops;		/* timeout expiry function */
+};
+
+static inline void rxrpc_timer_init(rxrpc_timer_t *timer, const struct rxrpc_timer_ops *ops)
+{
+	INIT_LIST_HEAD(&timer->link);
+	timer->ops = ops;
+}
+
+extern int rxrpc_krxtimod_start(void);
+extern void rxrpc_krxtimod_kill(void);
+
+extern void rxrpc_krxtimod_add_timer(rxrpc_timer_t *timer, unsigned long timeout);
+extern int rxrpc_krxtimod_del_timer(rxrpc_timer_t *timer);
+
+#endif /* _LINUX_RXRPC_KRXTIMOD_H */
diff --git a/include/rxrpc/message.h b/include/rxrpc/message.h
new file mode 100644
index 0000000..3a59df6
--- /dev/null
+++ b/include/rxrpc/message.h
@@ -0,0 +1,71 @@
+/* message.h: Rx message caching
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_MESSAGE_H
+#define _LINUX_RXRPC_MESSAGE_H
+
+#include <rxrpc/packet.h>
+
+/*****************************************************************************/
+/*
+ * Rx message record
+ */
+struct rxrpc_message
+{
+	atomic_t		usage;
+	struct list_head	link;		/* list link */
+	struct timeval		stamp;		/* time received or last sent */
+	rxrpc_seq_t		seq;		/* message sequence number */
+
+	int			state;		/* the state the message is currently in */
+#define RXRPC_MSG_PREPARED	0
+#define RXRPC_MSG_SENT		1
+#define RXRPC_MSG_ACKED		2		/* provisionally ACK'd */
+#define RXRPC_MSG_DONE		3		/* definitively ACK'd (msg->seq<ack.firstPacket) */
+#define RXRPC_MSG_RECEIVED	4
+#define RXRPC_MSG_ERROR		-1
+	char			rttdone;	/* used for RTT */
+
+	struct rxrpc_transport	*trans;		/* transport received through */
+	struct rxrpc_connection	*conn;		/* connection received over */
+	struct sk_buff		*pkt;		/* received packet */
+	off_t			offset;		/* offset into pkt of next byte of data */
+
+	struct rxrpc_header	hdr;		/* message header */
+
+	int			dcount;		/* data part count */
+	size_t			dsize;		/* data size */
+#define RXRPC_MSG_MAX_IOCS 8
+	struct kvec		data[RXRPC_MSG_MAX_IOCS]; /* message data */
+	unsigned long		dfree;		/* bit mask indicating kfree(data[x]) if T */
+};
+
+#define rxrpc_get_message(M) do { atomic_inc(&(M)->usage); } while(0)
+
+extern void __rxrpc_put_message(struct rxrpc_message *msg);
+static inline void rxrpc_put_message(struct rxrpc_message *msg)
+{
+	BUG_ON(atomic_read(&msg->usage)<=0);
+	if (atomic_dec_and_test(&msg->usage))
+		__rxrpc_put_message(msg);
+}
+
+extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
+			     struct rxrpc_call *call,
+			     uint8_t type,
+			     int count,
+			     struct kvec *diov,
+			     int alloc_flags,
+			     struct rxrpc_message **_msg);
+
+extern int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg);
+
+#endif /* _LINUX_RXRPC_MESSAGE_H */
diff --git a/include/rxrpc/packet.h b/include/rxrpc/packet.h
new file mode 100644
index 0000000..1447f0a
--- /dev/null
+++ b/include/rxrpc/packet.h
@@ -0,0 +1,127 @@
+/* packet.h: Rx packet layout and definitions
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_PACKET_H
+#define _LINUX_RXRPC_PACKET_H
+
+#include <rxrpc/types.h>
+
+#define RXRPC_IPUDP_SIZE		28
+extern size_t RXRPC_MAX_PACKET_SIZE;
+#define RXRPC_MAX_PACKET_DATA_SIZE	(RXRPC_MAX_PACKET_SIZE - sizeof(struct rxrpc_header))
+#define RXRPC_LOCAL_PACKET_SIZE		RXRPC_MAX_PACKET_SIZE
+#define RXRPC_REMOTE_PACKET_SIZE	(576 - RXRPC_IPUDP_SIZE)
+
+/*****************************************************************************/
+/*
+ * on-the-wire Rx packet header
+ * - all multibyte fields should be in network byte order
+ */
+struct rxrpc_header
+{
+	__be32		epoch;		/* client boot timestamp */
+
+	__be32		cid;		/* connection and channel ID */
+#define RXRPC_MAXCALLS		4			/* max active calls per conn */
+#define RXRPC_CHANNELMASK	(RXRPC_MAXCALLS-1)	/* mask for channel ID */
+#define RXRPC_CIDMASK		(~RXRPC_CHANNELMASK)	/* mask for connection ID */
+#define RXRPC_CIDSHIFT		2			/* shift for connection ID */
+
+	__be32		callNumber;	/* call ID (0 for connection-level packets) */
+#define RXRPC_PROCESS_MAXCALLS	(1<<2)	/* maximum number of active calls per conn (power of 2) */
+
+	__be32		seq;		/* sequence number of pkt in call stream */
+	__be32		serial;		/* serial number of pkt sent to network */
+
+	uint8_t		type;		/* packet type */
+#define RXRPC_PACKET_TYPE_DATA		1	/* data */
+#define RXRPC_PACKET_TYPE_ACK		2	/* ACK */
+#define RXRPC_PACKET_TYPE_BUSY		3	/* call reject */
+#define RXRPC_PACKET_TYPE_ABORT		4	/* call/connection abort */
+#define RXRPC_PACKET_TYPE_ACKALL	5	/* ACK all outstanding packets on call */
+#define RXRPC_PACKET_TYPE_CHALLENGE	6	/* connection security challenge (SRVR->CLNT) */
+#define RXRPC_PACKET_TYPE_RESPONSE	7	/* connection secutity response (CLNT->SRVR) */
+#define RXRPC_PACKET_TYPE_DEBUG		8	/* debug info request */
+#define RXRPC_N_PACKET_TYPES		9	/* number of packet types (incl type 0) */
+
+	uint8_t		flags;		/* packet flags */
+#define RXRPC_CLIENT_INITIATED	0x01		/* signifies a packet generated by a client */
+#define RXRPC_REQUEST_ACK	0x02		/* request an unconditional ACK of this packet */
+#define RXRPC_LAST_PACKET	0x04		/* the last packet from this side for this call */
+#define RXRPC_MORE_PACKETS	0x08		/* more packets to come */
+#define RXRPC_JUMBO_PACKET	0x20		/* [DATA] this is a jumbo packet */
+#define RXRPC_SLOW_START_OK	0x20		/* [ACK] slow start supported */
+
+	uint8_t		userStatus;	/* app-layer defined status */
+	uint8_t		securityIndex;	/* security protocol ID */
+	__be16		_rsvd;		/* reserved (used by kerberos security as cksum) */
+	__be16		serviceId;	/* service ID */
+
+} __attribute__((packed));
+
+#define __rxrpc_header_off(X) offsetof(struct rxrpc_header,X)
+
+extern const char *rxrpc_pkts[];
+
+/*****************************************************************************/
+/*
+ * jumbo packet secondary header
+ * - can be mapped to read header by:
+ *   - new_serial = serial + 1
+ *   - new_seq = seq + 1
+ *   - new_flags = j_flags
+ *   - new__rsvd = j__rsvd
+ *   - duplicating all other fields
+ */
+struct rxrpc_jumbo_header
+{
+	uint8_t		flags;		/* packet flags (as per rxrpc_header) */
+	uint8_t		pad;
+	__be16		_rsvd;		/* reserved (used by kerberos security as cksum) */
+};
+
+#define RXRPC_JUMBO_DATALEN	1412	/* non-terminal jumbo packet data length */
+
+/*****************************************************************************/
+/*
+ * on-the-wire Rx ACK packet data payload
+ * - all multibyte fields should be in network byte order
+ */
+struct rxrpc_ackpacket
+{
+	__be16		bufferSpace;	/* number of packet buffers available */
+	__be16		maxSkew;	/* diff between serno being ACK'd and highest serial no
+					 * received */
+	__be32		firstPacket;	/* sequence no of first ACK'd packet in attached list */
+	__be32		previousPacket;	/* sequence no of previous packet received */
+	__be32		serial;		/* serial no of packet that prompted this ACK */
+
+	uint8_t		reason;		/* reason for ACK */
+#define RXRPC_ACK_REQUESTED		1	/* ACK was requested on packet */
+#define RXRPC_ACK_DUPLICATE		2	/* duplicate packet received */
+#define RXRPC_ACK_OUT_OF_SEQUENCE	3	/* out of sequence packet received */
+#define RXRPC_ACK_EXCEEDS_WINDOW	4	/* packet received beyond end of ACK window */
+#define RXRPC_ACK_NOSPACE		5	/* packet discarded due to lack of buffer space */
+#define RXRPC_ACK_PING			6	/* keep alive ACK */
+#define RXRPC_ACK_PING_RESPONSE		7	/* response to RXRPC_ACK_PING */
+#define RXRPC_ACK_DELAY			8	/* nothing happened since received packet */
+#define RXRPC_ACK_IDLE			9	/* ACK due to fully received ACK window */
+
+	uint8_t		nAcks;		/* number of ACKs */
+#define RXRPC_MAXACKS	255
+
+	uint8_t		acks[0];	/* list of ACK/NAKs */
+#define RXRPC_ACK_TYPE_NACK		0
+#define RXRPC_ACK_TYPE_ACK		1
+
+} __attribute__((packed));
+
+#endif /* _LINUX_RXRPC_PACKET_H */
diff --git a/include/rxrpc/peer.h b/include/rxrpc/peer.h
new file mode 100644
index 0000000..8b8fe97
--- /dev/null
+++ b/include/rxrpc/peer.h
@@ -0,0 +1,82 @@
+/* peer.h: Rx RPC per-transport peer record
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_PEER_H
+#define _LINUX_RXRPC_PEER_H
+
+#include <linux/wait.h>
+#include <rxrpc/types.h>
+#include <rxrpc/krxtimod.h>
+
+struct rxrpc_peer_ops
+{
+	/* peer record being added */
+	int (*adding)(struct rxrpc_peer *peer);
+
+	/* peer record being discarded from graveyard */
+	void (*discarding)(struct rxrpc_peer *peer);
+
+	/* change of epoch detected on connection */
+	void (*change_of_epoch)(struct rxrpc_connection *conn);
+};
+
+/*****************************************************************************/
+/*
+ * Rx RPC per-transport peer record
+ * - peers only retain a refcount on the transport when they are active
+ * - peers with refcount==0 are inactive and reside in the transport's graveyard
+ */
+struct rxrpc_peer
+{
+	atomic_t		usage;
+	struct rxrpc_peer_ops	*ops;		/* operations on this peer */
+	struct rxrpc_transport	*trans;		/* owner transport */
+	struct rxrpc_timer	timeout;	/* timeout for grave destruction */
+	struct list_head	link;		/* link in transport's peer list */
+	struct list_head	proc_link;	/* link in /proc list */
+	rwlock_t		conn_idlock;	/* lock for connection IDs */
+	struct list_head	conn_idlist;	/* list of connections granted IDs */
+	uint32_t		conn_idcounter;	/* connection ID counter */
+	rwlock_t		conn_lock;	/* lock for active/dead connections */
+	struct list_head	conn_active;	/* active connections to/from this peer */
+	struct list_head	conn_graveyard;	/* graveyard for inactive connections */
+	spinlock_t		conn_gylock;	/* lock for conn_graveyard */
+	wait_queue_head_t	conn_gy_waitq;	/* wait queue hit when graveyard is empty */
+	atomic_t		conn_count;	/* number of attached connections */
+	struct in_addr		addr;		/* remote address */
+	size_t			if_mtu;		/* interface MTU for this peer */
+	spinlock_t		lock;		/* access lock */
+
+	void			*user;		/* application layer data */
+
+	/* calculated RTT cache */
+#define RXRPC_RTT_CACHE_SIZE 32
+	suseconds_t		rtt;		/* current RTT estimate (in uS) */
+	unsigned		rtt_point;	/* next entry at which to insert */
+	unsigned		rtt_usage;	/* amount of cache actually used */
+	suseconds_t		rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* calculated RTT cache */
+};
+
+
+extern int rxrpc_peer_lookup(struct rxrpc_transport *trans,
+			     __be32 addr,
+			     struct rxrpc_peer **_peer);
+
+static inline void rxrpc_get_peer(struct rxrpc_peer *peer)
+{
+	BUG_ON(atomic_read(&peer->usage)<0);
+	atomic_inc(&peer->usage);
+	//printk("rxrpc_get_peer(%p{u=%d})\n",peer,atomic_read(&peer->usage));
+}
+
+extern void rxrpc_put_peer(struct rxrpc_peer *peer);
+
+#endif /* _LINUX_RXRPC_PEER_H */
diff --git a/include/rxrpc/rxrpc.h b/include/rxrpc/rxrpc.h
new file mode 100644
index 0000000..8d9874c
--- /dev/null
+++ b/include/rxrpc/rxrpc.h
@@ -0,0 +1,36 @@
+/* rx.h: Rx RPC interface
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_RXRPC_H
+#define _LINUX_RXRPC_RXRPC_H
+
+#ifdef __KERNEL__
+
+extern __be32 rxrpc_epoch;
+
+#ifdef CONFIG_SYSCTL
+extern int rxrpc_ktrace;
+extern int rxrpc_kdebug;
+extern int rxrpc_kproto;
+extern int rxrpc_knet;
+#else
+#define rxrpc_ktrace	0
+#define rxrpc_kdebug	0
+#define rxrpc_kproto	0
+#define rxrpc_knet	0
+#endif
+
+extern int rxrpc_sysctl_init(void);
+extern void rxrpc_sysctl_cleanup(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_RXRPC_RXRPC_H */
diff --git a/include/rxrpc/transport.h b/include/rxrpc/transport.h
new file mode 100644
index 0000000..7c7b968
--- /dev/null
+++ b/include/rxrpc/transport.h
@@ -0,0 +1,106 @@
+/* transport.h: Rx transport management
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_TRANSPORT_H
+#define _LINUX_RXRPC_TRANSPORT_H
+
+#include <rxrpc/types.h>
+#include <rxrpc/krxiod.h>
+#include <rxrpc/rxrpc.h>
+#include <linux/skbuff.h>
+#include <linux/rwsem.h>
+
+typedef int (*rxrpc_newcall_fnx_t)(struct rxrpc_call *call);
+
+extern wait_queue_head_t rxrpc_krxiod_wq;
+
+/*****************************************************************************/
+/*
+ * Rx operation specification
+ * - tables of these must be sorted by op ID so that they can be binary-chop searched
+ */
+struct rxrpc_operation
+{
+	unsigned		id;		/* operation ID */
+	size_t			asize;		/* minimum size of argument block */
+	const char		*name;		/* name of operation */
+	void			*user;		/* initial user data */
+};
+
+/*****************************************************************************/
+/*
+ * Rx transport service record
+ */
+struct rxrpc_service
+{
+	struct list_head	link;		/* link in services list on transport */
+	struct module		*owner;		/* owner module */
+	rxrpc_newcall_fnx_t	new_call;	/* new call handler function */
+	const char		*name;		/* name of service */
+	unsigned short		service_id;	/* Rx service ID */
+	rxrpc_call_attn_func_t	attn_func;	/* call requires attention callback */
+	rxrpc_call_error_func_t	error_func;	/* call error callback */
+	rxrpc_call_aemap_func_t	aemap_func;	/* abort -> errno mapping callback */
+
+	const struct rxrpc_operation	*ops_begin;	/* beginning of operations table */
+	const struct rxrpc_operation	*ops_end;	/* end of operations table */
+};
+
+/*****************************************************************************/
+/*
+ * Rx transport endpoint record
+ */
+struct rxrpc_transport
+{
+	atomic_t		usage;
+	struct socket		*socket;	/* my UDP socket */
+	struct list_head	services;	/* services listening on this socket */
+	struct list_head	link;		/* link in transport list */
+	struct list_head	proc_link;	/* link in transport proc list */
+	struct list_head	krxiodq_link;	/* krxiod attention queue link */
+	spinlock_t		lock;		/* access lock */
+	struct list_head	peer_active;	/* active peers connected to over this socket */
+	struct list_head	peer_graveyard;	/* inactive peer list */
+	spinlock_t		peer_gylock;	/* peer graveyard lock */
+	wait_queue_head_t	peer_gy_waitq;	/* wait queue hit when peer graveyard is empty */
+	rwlock_t		peer_lock;	/* peer list access lock */
+	atomic_t		peer_count;	/* number of peers */
+	struct rxrpc_peer_ops	*peer_ops;	/* default peer operations */
+	unsigned short		port;		/* port upon which listening */
+	volatile char		error_rcvd;	/* T if received ICMP error outstanding */
+};
+
+extern int rxrpc_create_transport(unsigned short port,
+				  struct rxrpc_transport **_trans);
+
+static inline void rxrpc_get_transport(struct rxrpc_transport *trans)
+{
+	BUG_ON(atomic_read(&trans->usage) <= 0);
+	atomic_inc(&trans->usage);
+	//printk("rxrpc_get_transport(%p{u=%d})\n",
+	//       trans, atomic_read(&trans->usage));
+}
+
+extern void rxrpc_put_transport(struct rxrpc_transport *trans);
+
+extern int rxrpc_add_service(struct rxrpc_transport *trans,
+			     struct rxrpc_service *srv);
+
+extern void rxrpc_del_service(struct rxrpc_transport *trans,
+			      struct rxrpc_service *srv);
+
+extern void rxrpc_trans_receive_packet(struct rxrpc_transport *trans);
+
+extern int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
+				       struct rxrpc_message *msg,
+				       int error);
+
+#endif /* _LINUX_RXRPC_TRANSPORT_H */
diff --git a/include/rxrpc/types.h b/include/rxrpc/types.h
new file mode 100644
index 0000000..327a5fc
--- /dev/null
+++ b/include/rxrpc/types.h
@@ -0,0 +1,41 @@
+/* types.h: Rx types
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_RXRPC_TYPES_H
+#define _LINUX_RXRPC_TYPES_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+typedef uint32_t	rxrpc_seq_t;	/* Rx message sequence number */
+typedef uint32_t	rxrpc_serial_t;	/* Rx message serial number */
+typedef __be32	rxrpc_seq_net_t; /* on-the-wire Rx message sequence number */
+typedef __be32	rxrpc_serial_net_t; /* on-the-wire Rx message serial number */
+
+struct rxrpc_call;
+struct rxrpc_connection;
+struct rxrpc_header;
+struct rxrpc_message;
+struct rxrpc_operation;
+struct rxrpc_peer;
+struct rxrpc_service;
+typedef struct rxrpc_timer rxrpc_timer_t;
+struct rxrpc_transport;
+
+typedef void (*rxrpc_call_attn_func_t)(struct rxrpc_call *call);
+typedef void (*rxrpc_call_error_func_t)(struct rxrpc_call *call);
+typedef void (*rxrpc_call_aemap_func_t)(struct rxrpc_call *call);
+
+#endif /* _LINUX_RXRPC_TYPES_H */