diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-04-29 03:36:24 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-04-29 03:36:24 -0400 |
commit | 7407cf355fdf5500430be966dbbde84a27293bad (patch) | |
tree | 922861288ff38558ed721a79653f52b17b13bb95 /net/x25/x25_facilities.c | |
parent | 6a47dc1418682c83d603b491df1d048f73aa973e (diff) | |
parent | 79dba2eaa771c3173957eccfd288e0e0d12e4d3f (diff) |
Merge branch 'master' into for-2.6.35
Conflicts:
fs/block_dev.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'net/x25/x25_facilities.c')
-rw-r--r-- | net/x25/x25_facilities.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index a21f6646eb3a..771bab00754b 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) | 35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
36 | { | 36 | { |
37 | unsigned char *p = skb->data; | 37 | unsigned char *p = skb->data; |
38 | unsigned int len = *p++; | 38 | unsigned int len; |
39 | 39 | ||
40 | *vc_fac_mask = 0; | 40 | *vc_fac_mask = 0; |
41 | 41 | ||
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); | 50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); |
51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); | 51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); |
52 | 52 | ||
53 | if (skb->len < 1) | ||
54 | return 0; | ||
55 | |||
56 | len = *p++; | ||
57 | |||
58 | if (len >= skb->len) | ||
59 | return -1; | ||
60 | |||
53 | while (len > 0) { | 61 | while (len > 0) { |
54 | switch (*p & X25_FAC_CLASS_MASK) { | 62 | switch (*p & X25_FAC_CLASS_MASK) { |
55 | case X25_FAC_CLASS_A: | 63 | case X25_FAC_CLASS_A: |
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
247 | memcpy(new, ours, sizeof(*new)); | 255 | memcpy(new, ours, sizeof(*new)); |
248 | 256 | ||
249 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); | 257 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); |
258 | if (len < 0) | ||
259 | return len; | ||
250 | 260 | ||
251 | /* | 261 | /* |
252 | * They want reverse charging, we won't accept it. | 262 | * They want reverse charging, we won't accept it. |
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
259 | new->reverse = theirs.reverse; | 269 | new->reverse = theirs.reverse; |
260 | 270 | ||
261 | if (theirs.throughput) { | 271 | if (theirs.throughput) { |
262 | if (theirs.throughput < ours->throughput) { | 272 | int theirs_in = theirs.throughput & 0x0f; |
263 | SOCK_DEBUG(sk, "X.25: throughput negotiated down\n"); | 273 | int theirs_out = theirs.throughput & 0xf0; |
264 | 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; | ||
265 | } | 284 | } |
266 | } | 285 | } |
267 | 286 | ||