aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-09-12 17:27:37 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-12 17:27:37 -0400
commite21ce8c7c013fb223a002c70bb0a547de6c26c12 (patch)
tree767b9aae7bdd50cdf867f3cdc1a3e214692146e1
parentd2ce4bc340946d5b78484d638ac10df958c4c3bf (diff)
[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>
-rw-r--r--include/linux/sysctl.h3
-rw-r--r--include/net/netrom.h27
-rw-r--r--net/netrom/af_netrom.c21
-rw-r--r--net/netrom/nr_in.c15
-rw-r--r--net/netrom/nr_subr.c7
-rw-r--r--net/netrom/sysctl_net_netrom.c12
6 files changed, 69 insertions, 16 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 532a6c5c24e9..3a29a9f9b451 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -544,7 +544,8 @@ enum {
544 NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8, 544 NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
545 NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9, 545 NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
546 NET_NETROM_ROUTING_CONTROL=10, 546 NET_NETROM_ROUTING_CONTROL=10,
547 NET_NETROM_LINK_FAILS_COUNT=11 547 NET_NETROM_LINK_FAILS_COUNT=11,
548 NET_NETROM_RESET=12
548}; 549};
549 550
550/* /proc/sys/net/ax25 */ 551/* /proc/sys/net/ax25 */
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 45f2c7616d8b..ad05d7a3c55d 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -22,6 +22,7 @@
22#define NR_DISCACK 0x04 22#define NR_DISCACK 0x04
23#define NR_INFO 0x05 23#define NR_INFO 0x05
24#define NR_INFOACK 0x06 24#define NR_INFOACK 0x06
25#define NR_RESET 0x07
25 26
26#define NR_CHOKE_FLAG 0x80 27#define NR_CHOKE_FLAG 0x80
27#define NR_NAK_FLAG 0x40 28#define NR_NAK_FLAG 0x40
@@ -51,6 +52,7 @@ enum {
51#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ 52#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */
52#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */ 53#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */
53#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */ 54#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */
55#define NR_DEFAULT_RESET 0 /* Sent / accept reset cmds? */
54 56
55#define NR_MODULUS 256 57#define NR_MODULUS 256
56#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ 58#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */
@@ -176,6 +178,8 @@ extern int sysctl_netrom_transport_requested_window_size;
176extern int sysctl_netrom_transport_no_activity_timeout; 178extern int sysctl_netrom_transport_no_activity_timeout;
177extern int sysctl_netrom_routing_control; 179extern int sysctl_netrom_routing_control;
178extern int sysctl_netrom_link_fails_count; 180extern int sysctl_netrom_link_fails_count;
181extern int sysctl_netrom_reset_circuit;
182
179extern int nr_rx_frame(struct sk_buff *, struct net_device *); 183extern int nr_rx_frame(struct sk_buff *, struct net_device *);
180extern void nr_destroy_socket(struct sock *); 184extern void nr_destroy_socket(struct sock *);
181 185
@@ -218,7 +222,28 @@ extern void nr_requeue_frames(struct sock *);
218extern int nr_validate_nr(struct sock *, unsigned short); 222extern int nr_validate_nr(struct sock *, unsigned short);
219extern int nr_in_rx_window(struct sock *, unsigned short); 223extern int nr_in_rx_window(struct sock *, unsigned short);
220extern void nr_write_internal(struct sock *, int); 224extern void nr_write_internal(struct sock *, int);
221extern void nr_transmit_refusal(struct sk_buff *, int); 225
226extern void __nr_transmit_reply(struct sk_buff *skb, int mine,
227 unsigned char cmdflags);
228
229/*
230 * This routine is called when a Connect Acknowledge with the Choke Flag
231 * set is needed to refuse a connection.
232 */
233#define nr_transmit_refusal(skb, mine) \
234do { \
235 __nr_transmit_reply((skb), (mine), NR_CONNACK | NR_CHOKE_FLAG); \
236} while (0)
237
238/*
239 * This routine is called when we don't have a circuit matching an incoming
240 * NET/ROM packet. This is an G8PZT Xrouter extension.
241 */
242#define nr_transmit_reset(skb, mine) \
243do { \
244 __nr_transmit_reply((skb), (mine), NR_RESET); \
245} while (0)
246
222extern void nr_disconnect(struct sock *, int); 247extern void nr_disconnect(struct sock *, int);
223 248
224/* nr_timer.c */ 249/* nr_timer.c */
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 02b1ab52dbbf..8c3d3a78481e 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -56,6 +56,7 @@ int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
56int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE; 56int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE;
57int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING; 57int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING;
58int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS; 58int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS;
59int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET;
59 60
60static unsigned short circuit = 0x101; 61static unsigned short circuit = 0x101;
61 62
@@ -908,17 +909,17 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
908 if (frametype != NR_CONNREQ) { 909 if (frametype != NR_CONNREQ) {
909 /* 910 /*
910 * Here it would be nice to be able to send a reset but 911 * Here it would be nice to be able to send a reset but
911 * NET/ROM doesn't have one. The following hack would 912 * NET/ROM doesn't have one. We've tried to extend the protocol
912 * have been a way to extend the protocol but apparently 913 * by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that
913 * it kills BPQ boxes... :-( 914 * apparently kills BPQ boxes... :-(
915 * So now we try to follow the established behaviour of
916 * G8PZT's Xrouter which is sending packets with command type 7
917 * as an extension of the protocol.
914 */ 918 */
915#if 0 919 if (sysctl_netrom_reset_circuit &&
916 /* 920 (frametype != NR_RESET || flags != 0))
917 * Never reply to a CONNACK/CHOKE. 921 nr_transmit_reset(skb, 1);
918 */ 922
919 if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG)
920 nr_transmit_refusal(skb, 1);
921#endif
922 return 0; 923 return 0;
923 } 924 }
924 925
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 64b81a796907..004e8599b8fe 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -98,6 +98,11 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
98 nr_disconnect(sk, ECONNREFUSED); 98 nr_disconnect(sk, ECONNREFUSED);
99 break; 99 break;
100 100
101 case NR_RESET:
102 if (sysctl_netrom_reset_circuit);
103 nr_disconnect(sk, ECONNRESET);
104 break;
105
101 default: 106 default:
102 break; 107 break;
103 } 108 }
@@ -124,6 +129,11 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
124 nr_disconnect(sk, 0); 129 nr_disconnect(sk, 0);
125 break; 130 break;
126 131
132 case NR_RESET:
133 if (sysctl_netrom_reset_circuit);
134 nr_disconnect(sk, ECONNRESET);
135 break;
136
127 default: 137 default:
128 break; 138 break;
129 } 139 }
@@ -254,6 +264,11 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
254 } 264 }
255 break; 265 break;
256 266
267 case NR_RESET:
268 if (sysctl_netrom_reset_circuit);
269 nr_disconnect(sk, ECONNRESET);
270 break;
271
257 default: 272 default:
258 break; 273 break;
259 } 274 }
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
index 587bed2674bf..bcb9946b4f56 100644
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -210,10 +210,9 @@ void nr_write_internal(struct sock *sk, int frametype)
210} 210}
211 211
212/* 212/*
213 * This routine is called when a Connect Acknowledge with the Choke Flag 213 * This routine is called to send an error reply.
214 * set is needed to refuse a connection.
215 */ 214 */
216void nr_transmit_refusal(struct sk_buff *skb, int mine) 215void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
217{ 216{
218 struct sk_buff *skbn; 217 struct sk_buff *skbn;
219 unsigned char *dptr; 218 unsigned char *dptr;
@@ -254,7 +253,7 @@ void nr_transmit_refusal(struct sk_buff *skb, int mine)
254 *dptr++ = 0; 253 *dptr++ = 0;
255 } 254 }
256 255
257 *dptr++ = NR_CONNACK | NR_CHOKE_FLAG; 256 *dptr++ = cmdflags;
258 *dptr++ = 0; 257 *dptr++ = 0;
259 258
260 if (!nr_route_frame(skbn, NULL)) 259 if (!nr_route_frame(skbn, NULL))
diff --git a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c
index c9ed50382ea7..6bb8dda849dc 100644
--- a/net/netrom/sysctl_net_netrom.c
+++ b/net/netrom/sysctl_net_netrom.c
@@ -30,6 +30,7 @@ static int min_idle[] = {0 * HZ};
30static int max_idle[] = {65535 * HZ}; 30static int max_idle[] = {65535 * HZ};
31static int min_route[] = {0}, max_route[] = {1}; 31static int min_route[] = {0}, max_route[] = {1};
32static int min_fails[] = {1}, max_fails[] = {10}; 32static int min_fails[] = {1}, max_fails[] = {10};
33static int min_reset[] = {0}, max_reset[] = {1};
33 34
34static struct ctl_table_header *nr_table_header; 35static struct ctl_table_header *nr_table_header;
35 36
@@ -155,6 +156,17 @@ static ctl_table nr_table[] = {
155 .extra1 = &min_fails, 156 .extra1 = &min_fails,
156 .extra2 = &max_fails 157 .extra2 = &max_fails
157 }, 158 },
159 {
160 .ctl_name = NET_NETROM_RESET,
161 .procname = "reset",
162 .data = &sysctl_netrom_reset_circuit,
163 .maxlen = sizeof(int),
164 .mode = 0644,
165 .proc_handler = &proc_dointvec_minmax,
166 .strategy = &sysctl_intvec,
167 .extra1 = &min_reset,
168 .extra2 = &max_reset
169 },
158 { .ctl_name = 0 } 170 { .ctl_name = 0 }
159}; 171};
160 172