aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/x25_facilities.c
diff options
context:
space:
mode:
authorJohn Hughes <john@Calva.COM>2010-04-04 02:48:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-08 00:33:02 -0400
commitddd0451fc8dbf94446c81500ff0dcee06c4057cb (patch)
tree89d5f4de47e506c8c7ddb25486fff0dd7362a287 /net/x25/x25_facilities.c
parentf5eb917b861828da18dc28854308068c66d1449a (diff)
x.25 attempts to negotiate invalid throughput
The current X.25 code has some bugs in throughput negotiation: 1. It does negotiation in all cases, usually there is no need 2. It incorrectly attempts to negotiate the throughput class in one direction only. There are separate throughput classes for input and output and if either is negotiated both mist be negotiates. This is bug https://bugzilla.kernel.org/show_bug.cgi?id=15681 This bug was first reported by Daniel Ferenci to the linux-x25 mailing list on 6/8/2004, but is still present. The current (2.6.34) x.25 code doesn't seem to know that the X.25 throughput facility includes two values, one for the required throughput outbound, one for inbound. This causes it to attempt to negotiate throughput 0x0A, which is throughput 9600 inbound and the illegal value "0" for inbound throughput. Because of this some X.25 devices (e.g. Cisco 1600) refuse to connect to Linux X.25. The following patch fixes this behaviour. Unless the user specifies a required throughput it does not attempt to negotiate. If the user does not specify a throughput it accepts the suggestion of the remote X.25 system. If the user requests a throughput then it validates both the input and output throughputs and correctly negotiates them with the remote end. Signed-off-by: John Hughes <john@calva.com> Tested-by: Andrew Hendry <andrew.hendry@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/x25/x25_facilities.c')
-rw-r--r--net/x25/x25_facilities.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index a2765c6b1f1a..771bab00754b 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -269,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
269 new->reverse = theirs.reverse; 269 new->reverse = theirs.reverse;
270 270
271 if (theirs.throughput) { 271 if (theirs.throughput) {
272 if (theirs.throughput < ours->throughput) { 272 int theirs_in = theirs.throughput & 0x0f;
273 SOCK_DEBUG(sk, "X.25: throughput negotiated down\n"); 273 int theirs_out = theirs.throughput & 0xf0;
274 new->throughput = theirs.throughput; 274 int ours_in = ours->throughput & 0x0f;
275 int ours_out = ours->throughput & 0xf0;
276 if (!ours_in || theirs_in < ours_in) {
277 SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n");
278 new->throughput = (new->throughput & 0xf0) | theirs_in;
279 }
280 if (!ours_out || theirs_out < ours_out) {
281 SOCK_DEBUG(sk,
282 "X.25: outbound throughput negotiated\n");
283 new->throughput = (new->throughput & 0x0f) | theirs_out;
275 } 284 }
276 } 285 }
277 286