[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>
This commit is contained in:
committed by
David S. Miller
parent
d2ce4bc340
commit
e21ce8c7c0
@@ -56,6 +56,7 @@ int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
|
||||
int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE;
|
||||
int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING;
|
||||
int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS;
|
||||
int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET;
|
||||
|
||||
static unsigned short circuit = 0x101;
|
||||
|
||||
@@ -908,17 +909,17 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
|
||||
if (frametype != NR_CONNREQ) {
|
||||
/*
|
||||
* Here it would be nice to be able to send a reset but
|
||||
* NET/ROM doesn't have one. The following hack would
|
||||
* have been a way to extend the protocol but apparently
|
||||
* it kills BPQ boxes... :-(
|
||||
* NET/ROM doesn't have one. We've tried to extend the protocol
|
||||
* by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that
|
||||
* apparently kills BPQ boxes... :-(
|
||||
* So now we try to follow the established behaviour of
|
||||
* G8PZT's Xrouter which is sending packets with command type 7
|
||||
* as an extension of the protocol.
|
||||
*/
|
||||
#if 0
|
||||
/*
|
||||
* Never reply to a CONNACK/CHOKE.
|
||||
*/
|
||||
if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG)
|
||||
nr_transmit_refusal(skb, 1);
|
||||
#endif
|
||||
if (sysctl_netrom_reset_circuit &&
|
||||
(frametype != NR_RESET || flags != 0))
|
||||
nr_transmit_reset(skb, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -98,6 +98,11 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
|
||||
nr_disconnect(sk, ECONNREFUSED);
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit);
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -124,6 +129,11 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
|
||||
nr_disconnect(sk, 0);
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit);
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -254,6 +264,11 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit);
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -210,10 +210,9 @@ void nr_write_internal(struct sock *sk, int frametype)
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called when a Connect Acknowledge with the Choke Flag
|
||||
* set is needed to refuse a connection.
|
||||
* This routine is called to send an error reply.
|
||||
*/
|
||||
void nr_transmit_refusal(struct sk_buff *skb, int mine)
|
||||
void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
|
||||
{
|
||||
struct sk_buff *skbn;
|
||||
unsigned char *dptr;
|
||||
@@ -254,7 +253,7 @@ void nr_transmit_refusal(struct sk_buff *skb, int mine)
|
||||
*dptr++ = 0;
|
||||
}
|
||||
|
||||
*dptr++ = NR_CONNACK | NR_CHOKE_FLAG;
|
||||
*dptr++ = cmdflags;
|
||||
*dptr++ = 0;
|
||||
|
||||
if (!nr_route_frame(skbn, NULL))
|
||||
|
@@ -30,6 +30,7 @@ static int min_idle[] = {0 * HZ};
|
||||
static int max_idle[] = {65535 * HZ};
|
||||
static int min_route[] = {0}, max_route[] = {1};
|
||||
static int min_fails[] = {1}, max_fails[] = {10};
|
||||
static int min_reset[] = {0}, max_reset[] = {1};
|
||||
|
||||
static struct ctl_table_header *nr_table_header;
|
||||
|
||||
@@ -155,6 +156,17 @@ static ctl_table nr_table[] = {
|
||||
.extra1 = &min_fails,
|
||||
.extra2 = &max_fails
|
||||
},
|
||||
{
|
||||
.ctl_name = NET_NETROM_RESET,
|
||||
.procname = "reset",
|
||||
.data = &sysctl_netrom_reset_circuit,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec_minmax,
|
||||
.strategy = &sysctl_intvec,
|
||||
.extra1 = &min_reset,
|
||||
.extra2 = &max_reset
|
||||
},
|
||||
{ .ctl_name = 0 }
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user