diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-09-12 17:27:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-09-12 17:27:37 -0400 |
commit | e21ce8c7c013fb223a002c70bb0a547de6c26c12 (patch) | |
tree | 767b9aae7bdd50cdf867f3cdc1a3e214692146e1 /net/netrom | |
parent | d2ce4bc340946d5b78484d638ac10df958c4c3bf (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>
Diffstat (limited to 'net/netrom')
-rw-r--r-- | net/netrom/af_netrom.c | 21 | ||||
-rw-r--r-- | net/netrom/nr_in.c | 15 | ||||
-rw-r--r-- | net/netrom/nr_subr.c | 7 | ||||
-rw-r--r-- | net/netrom/sysctl_net_netrom.c | 12 |
4 files changed, 41 insertions, 14 deletions
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; | |||
56 | int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE; | 56 | int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE; |
57 | int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING; | 57 | int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING; |
58 | int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS; | 58 | int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS; |
59 | int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET; | ||
59 | 60 | ||
60 | static unsigned short circuit = 0x101; | 61 | static 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 | */ |
216 | void nr_transmit_refusal(struct sk_buff *skb, int mine) | 215 | void __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}; | |||
30 | static int max_idle[] = {65535 * HZ}; | 30 | static int max_idle[] = {65535 * HZ}; |
31 | static int min_route[] = {0}, max_route[] = {1}; | 31 | static int min_route[] = {0}, max_route[] = {1}; |
32 | static int min_fails[] = {1}, max_fails[] = {10}; | 32 | static int min_fails[] = {1}, max_fails[] = {10}; |
33 | static int min_reset[] = {0}, max_reset[] = {1}; | ||
33 | 34 | ||
34 | static struct ctl_table_header *nr_table_header; | 35 | static 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 | ||