[NETROM]: Implement G8PZT Circuit reset for NET/ROM

NET/ROM is lacking a connection reset like TCP's RST flag which at times
may result in a connecting having to slowly timing out instead of just being
reset.  An earlier attempt to reset the connection by sending a
NR_CONNACK | NR_CHOKE_FLAG transport was inacceptable as it did result in
crashes of BPQ systems.  An alternative approach of introducing a new
transport type 7 (NR_RESET) has be implemented several years ago in
Paula Jayne Dowie G8PZT's Xrouter.

Implement NR_RESET for Linux's NET/ROM but like any messing with the state
engine consider this experimental for now and thus control it by a sysctl
(net.netrom.reset) which for the time being defaults to off.

Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 45f2c76..ad05d7a 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -22,6 +22,7 @@
 #define	NR_DISCACK			0x04
 #define	NR_INFO				0x05
 #define	NR_INFOACK			0x06
+#define	NR_RESET			0x07
 
 #define	NR_CHOKE_FLAG			0x80
 #define	NR_NAK_FLAG			0x40
@@ -51,6 +52,7 @@
 #define	NR_DEFAULT_TTL			16		/* Default Time To Live - 16 */
 #define	NR_DEFAULT_ROUTING		1		/* Is routing enabled ? */
 #define	NR_DEFAULT_FAILS		2		/* Link fails until route fails */
+#define	NR_DEFAULT_RESET		0		/* Sent / accept reset cmds? */
 
 #define NR_MODULUS 			256
 #define NR_MAX_WINDOW_SIZE		127			/* Maximum Window Allowable - 127 */
@@ -176,6 +178,8 @@
 extern int  sysctl_netrom_transport_no_activity_timeout;
 extern int  sysctl_netrom_routing_control;
 extern int  sysctl_netrom_link_fails_count;
+extern int  sysctl_netrom_reset_circuit;
+
 extern int  nr_rx_frame(struct sk_buff *, struct net_device *);
 extern void nr_destroy_socket(struct sock *);
 
@@ -218,7 +222,28 @@
 extern int  nr_validate_nr(struct sock *, unsigned short);
 extern int  nr_in_rx_window(struct sock *, unsigned short);
 extern void nr_write_internal(struct sock *, int);
-extern void nr_transmit_refusal(struct sk_buff *, int);
+
+extern void __nr_transmit_reply(struct sk_buff *skb, int mine,
+	unsigned char cmdflags);
+
+/*
+ * This routine is called when a Connect Acknowledge with the Choke Flag
+ * set is needed to refuse a connection.
+ */
+#define nr_transmit_refusal(skb, mine)					\
+do {									\
+	__nr_transmit_reply((skb), (mine), NR_CONNACK | NR_CHOKE_FLAG);	\
+} while (0)
+
+/*
+ * This routine is called when we don't have a circuit matching an incoming
+ * NET/ROM packet.  This is an G8PZT Xrouter extension.
+ */
+#define nr_transmit_reset(skb, mine)					\
+do {									\
+	__nr_transmit_reply((skb), (mine), NR_RESET);			\
+} while (0)
+
 extern void nr_disconnect(struct sock *, int);
 
 /* nr_timer.c */