diff options
| -rw-r--r-- | net/dccp/ccid.h | 46 | ||||
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 14 | ||||
| -rw-r--r-- | net/dccp/options.c | 16 |
3 files changed, 35 insertions, 41 deletions
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 6df6f8ac9636..6d16a9070ff0 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
| @@ -62,18 +62,14 @@ struct ccid_operations { | |||
| 62 | void (*ccid_hc_tx_exit)(struct sock *sk); | 62 | void (*ccid_hc_tx_exit)(struct sock *sk); |
| 63 | void (*ccid_hc_rx_packet_recv)(struct sock *sk, | 63 | void (*ccid_hc_rx_packet_recv)(struct sock *sk, |
| 64 | struct sk_buff *skb); | 64 | struct sk_buff *skb); |
| 65 | int (*ccid_hc_rx_parse_options)(struct sock *sk, | 65 | int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt, |
| 66 | unsigned char option, | 66 | u8 opt, u8 *val, u8 len); |
| 67 | unsigned char len, u16 idx, | ||
| 68 | unsigned char* value); | ||
| 69 | int (*ccid_hc_rx_insert_options)(struct sock *sk, | 67 | int (*ccid_hc_rx_insert_options)(struct sock *sk, |
| 70 | struct sk_buff *skb); | 68 | struct sk_buff *skb); |
| 71 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, | 69 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, |
| 72 | struct sk_buff *skb); | 70 | struct sk_buff *skb); |
| 73 | int (*ccid_hc_tx_parse_options)(struct sock *sk, | 71 | int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt, |
| 74 | unsigned char option, | 72 | u8 opt, u8 *val, u8 len); |
| 75 | unsigned char len, u16 idx, | ||
| 76 | unsigned char* value); | ||
| 77 | int (*ccid_hc_tx_send_packet)(struct sock *sk, | 73 | int (*ccid_hc_tx_send_packet)(struct sock *sk, |
| 78 | struct sk_buff *skb); | 74 | struct sk_buff *skb); |
| 79 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, | 75 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, |
| @@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk, | |||
| 168 | ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); | 164 | ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); |
| 169 | } | 165 | } |
| 170 | 166 | ||
| 167 | /** | ||
| 168 | * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver | ||
| 169 | * @pkt: type of packet that @opt appears on (RFC 4340, 5.1) | ||
| 170 | * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3) | ||
| 171 | * @val: value of @opt | ||
| 172 | * @len: length of @val in bytes | ||
| 173 | */ | ||
| 171 | static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, | 174 | static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, |
| 172 | unsigned char option, | 175 | u8 pkt, u8 opt, u8 *val, u8 len) |
| 173 | unsigned char len, u16 idx, | ||
| 174 | unsigned char* value) | ||
| 175 | { | 176 | { |
| 176 | int rc = 0; | 177 | if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL) |
| 177 | if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL) | 178 | return 0; |
| 178 | rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx, | 179 | return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len); |
| 179 | value); | ||
| 180 | return rc; | ||
| 181 | } | 180 | } |
| 182 | 181 | ||
| 182 | /** | ||
| 183 | * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender | ||
| 184 | * Arguments are analogous to ccid_hc_tx_parse_options() | ||
| 185 | */ | ||
| 183 | static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, | 186 | static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, |
| 184 | unsigned char option, | 187 | u8 pkt, u8 opt, u8 *val, u8 len) |
| 185 | unsigned char len, u16 idx, | ||
| 186 | unsigned char* value) | ||
| 187 | { | 188 | { |
| 188 | int rc = 0; | 189 | if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL) |
| 189 | if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL) | 190 | return 0; |
| 190 | rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value); | 191 | return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len); |
| 191 | return rc; | ||
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, | 194 | static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index ce8059130070..be1b8baaf298 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
| @@ -481,9 +481,8 @@ done_computing_x: | |||
| 481 | jiffies + usecs_to_jiffies(t_nfb)); | 481 | jiffies + usecs_to_jiffies(t_nfb)); |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | 484 | static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, |
| 485 | unsigned char len, u16 idx, | 485 | u8 option, u8 *optval, u8 optlen) |
| 486 | unsigned char *value) | ||
| 487 | { | 486 | { |
| 488 | struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); | 487 | struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); |
| 489 | struct ccid3_options_received *opt_recv = &hc->tx_options_received; | 488 | struct ccid3_options_received *opt_recv = &hc->tx_options_received; |
| @@ -492,12 +491,15 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 492 | switch (option) { | 491 | switch (option) { |
| 493 | case TFRC_OPT_RECEIVE_RATE: | 492 | case TFRC_OPT_RECEIVE_RATE: |
| 494 | case TFRC_OPT_LOSS_EVENT_RATE: | 493 | case TFRC_OPT_LOSS_EVENT_RATE: |
| 495 | if (unlikely(len != 4)) { | 494 | /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */ |
| 495 | if (packet_type == DCCP_PKT_DATA) | ||
| 496 | break; | ||
| 497 | if (unlikely(optlen != 4)) { | ||
| 496 | DCCP_WARN("%s(%p), invalid len %d for %u\n", | 498 | DCCP_WARN("%s(%p), invalid len %d for %u\n", |
| 497 | dccp_role(sk), sk, len, option); | 499 | dccp_role(sk), sk, optlen, option); |
| 498 | return -EINVAL; | 500 | return -EINVAL; |
| 499 | } | 501 | } |
| 500 | opt_val = ntohl(get_unaligned((__be32 *)value)); | 502 | opt_val = ntohl(get_unaligned((__be32 *)optval)); |
| 501 | 503 | ||
| 502 | if (option == TFRC_OPT_RECEIVE_RATE) { | 504 | if (option == TFRC_OPT_RECEIVE_RATE) { |
| 503 | opt_recv->ccid3or_receive_rate = opt_val; | 505 | opt_recv->ccid3or_receive_rate = opt_val; |
diff --git a/net/dccp/options.c b/net/dccp/options.c index bfda087bd90d..e4983e3d2616 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
| @@ -226,23 +226,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, | |||
| 226 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", | 226 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", |
| 227 | dccp_role(sk), elapsed_time); | 227 | dccp_role(sk), elapsed_time); |
| 228 | break; | 228 | break; |
| 229 | case 128 ... 191: { | 229 | case 128 ... 191: |
| 230 | const u16 idx = value - options; | ||
| 231 | |||
| 232 | if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, | 230 | if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, |
| 233 | opt, len, idx, | 231 | pkt_type, opt, value, len)) |
| 234 | value) != 0) | ||
| 235 | goto out_invalid_option; | 232 | goto out_invalid_option; |
| 236 | } | ||
| 237 | break; | 233 | break; |
| 238 | case 192 ... 255: { | 234 | case 192 ... 255: |
| 239 | const u16 idx = value - options; | ||
| 240 | |||
| 241 | if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, | 235 | if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, |
| 242 | opt, len, idx, | 236 | pkt_type, opt, value, len)) |
| 243 | value) != 0) | ||
| 244 | goto out_invalid_option; | 237 | goto out_invalid_option; |
| 245 | } | ||
| 246 | break; | 238 | break; |
| 247 | default: | 239 | default: |
| 248 | DCCP_CRIT("DCCP(%p): option %d(len=%d) not " | 240 | DCCP_CRIT("DCCP(%p): option %d(len=%d) not " |
