diff options
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 112 |
1 files changed, 38 insertions, 74 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 35d1d347541c..b4a51d0355a5 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | * Reason for maths here is to avoid 32 bit overflow when a is big. | 46 | * Reason for maths here is to avoid 32 bit overflow when a is big. |
| 47 | * With this we get close to the limit. | 47 | * With this we get close to the limit. |
| 48 | */ | 48 | */ |
| 49 | static inline u32 usecs_div(const u32 a, const u32 b) | 49 | static u32 usecs_div(const u32 a, const u32 b) |
| 50 | { | 50 | { |
| 51 | const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 : | 51 | const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 : |
| 52 | a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 : | 52 | a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 : |
| @@ -76,15 +76,6 @@ static struct dccp_tx_hist *ccid3_tx_hist; | |||
| 76 | static struct dccp_rx_hist *ccid3_rx_hist; | 76 | static struct dccp_rx_hist *ccid3_rx_hist; |
| 77 | static struct dccp_li_hist *ccid3_li_hist; | 77 | static struct dccp_li_hist *ccid3_li_hist; |
| 78 | 78 | ||
| 79 | static int ccid3_init(struct sock *sk) | ||
| 80 | { | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static void ccid3_exit(struct sock *sk) | ||
| 85 | { | ||
| 86 | } | ||
| 87 | |||
| 88 | /* TFRC sender states */ | 79 | /* TFRC sender states */ |
| 89 | enum ccid3_hc_tx_states { | 80 | enum ccid3_hc_tx_states { |
| 90 | TFRC_SSTATE_NO_SENT = 1, | 81 | TFRC_SSTATE_NO_SENT = 1, |
| @@ -107,8 +98,8 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) | |||
| 107 | } | 98 | } |
| 108 | #endif | 99 | #endif |
| 109 | 100 | ||
| 110 | static inline void ccid3_hc_tx_set_state(struct sock *sk, | 101 | static void ccid3_hc_tx_set_state(struct sock *sk, |
| 111 | enum ccid3_hc_tx_states state) | 102 | enum ccid3_hc_tx_states state) |
| 112 | { | 103 | { |
| 113 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 104 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
| 114 | enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state; | 105 | enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state; |
| @@ -316,8 +307,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, | |||
| 316 | 307 | ||
| 317 | switch (hctx->ccid3hctx_state) { | 308 | switch (hctx->ccid3hctx_state) { |
| 318 | case TFRC_SSTATE_NO_SENT: | 309 | case TFRC_SSTATE_NO_SENT: |
| 319 | hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer; | ||
| 320 | hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk; | ||
| 321 | sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, | 310 | sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, |
| 322 | jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)); | 311 | jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)); |
| 323 | hctx->ccid3hctx_last_win_count = 0; | 312 | hctx->ccid3hctx_last_win_count = 0; |
| @@ -585,16 +574,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 585 | } | 574 | } |
| 586 | } | 575 | } |
| 587 | 576 | ||
| 588 | static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) | 577 | static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) |
| 589 | { | 578 | { |
| 590 | const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 579 | const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
| 591 | 580 | ||
| 592 | BUG_ON(hctx == NULL); | 581 | BUG_ON(hctx == NULL); |
| 593 | 582 | ||
| 594 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) | 583 | if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN) |
| 595 | return; | 584 | DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; |
| 596 | 585 | return 0; | |
| 597 | DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; | ||
| 598 | } | 586 | } |
| 599 | 587 | ||
| 600 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | 588 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, |
| @@ -626,7 +614,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 626 | __FUNCTION__, dccp_role(sk), sk); | 614 | __FUNCTION__, dccp_role(sk), sk); |
| 627 | rc = -EINVAL; | 615 | rc = -EINVAL; |
| 628 | } else { | 616 | } else { |
| 629 | opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value); | 617 | opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value); |
| 630 | ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n", | 618 | ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n", |
| 631 | dccp_role(sk), sk, | 619 | dccp_role(sk), sk, |
| 632 | opt_recv->ccid3or_loss_event_rate); | 620 | opt_recv->ccid3or_loss_event_rate); |
| @@ -647,7 +635,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 647 | __FUNCTION__, dccp_role(sk), sk); | 635 | __FUNCTION__, dccp_role(sk), sk); |
| 648 | rc = -EINVAL; | 636 | rc = -EINVAL; |
| 649 | } else { | 637 | } else { |
| 650 | opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value); | 638 | opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value); |
| 651 | ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n", | 639 | ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n", |
| 652 | dccp_role(sk), sk, | 640 | dccp_role(sk), sk, |
| 653 | opt_recv->ccid3or_receive_rate); | 641 | opt_recv->ccid3or_receive_rate); |
| @@ -658,17 +646,10 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 658 | return rc; | 646 | return rc; |
| 659 | } | 647 | } |
| 660 | 648 | ||
| 661 | static int ccid3_hc_tx_init(struct sock *sk) | 649 | static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) |
| 662 | { | 650 | { |
| 663 | struct dccp_sock *dp = dccp_sk(sk); | 651 | struct dccp_sock *dp = dccp_sk(sk); |
| 664 | struct ccid3_hc_tx_sock *hctx; | 652 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); |
| 665 | |||
| 666 | dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any()); | ||
| 667 | if (dp->dccps_hc_tx_ccid_private == NULL) | ||
| 668 | return -ENOMEM; | ||
| 669 | |||
| 670 | hctx = ccid3_hc_tx_sk(sk); | ||
| 671 | memset(hctx, 0, sizeof(*hctx)); | ||
| 672 | 653 | ||
| 673 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && | 654 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && |
| 674 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) | 655 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) |
| @@ -681,6 +662,9 @@ static int ccid3_hc_tx_init(struct sock *sk) | |||
| 681 | hctx->ccid3hctx_t_rto = USEC_PER_SEC; | 662 | hctx->ccid3hctx_t_rto = USEC_PER_SEC; |
| 682 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; | 663 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; |
| 683 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); | 664 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); |
| 665 | |||
| 666 | hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer; | ||
| 667 | hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk; | ||
| 684 | init_timer(&hctx->ccid3hctx_no_feedback_timer); | 668 | init_timer(&hctx->ccid3hctx_no_feedback_timer); |
| 685 | 669 | ||
| 686 | return 0; | 670 | return 0; |
| @@ -688,7 +672,6 @@ static int ccid3_hc_tx_init(struct sock *sk) | |||
| 688 | 672 | ||
| 689 | static void ccid3_hc_tx_exit(struct sock *sk) | 673 | static void ccid3_hc_tx_exit(struct sock *sk) |
| 690 | { | 674 | { |
| 691 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 692 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 675 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
| 693 | 676 | ||
| 694 | BUG_ON(hctx == NULL); | 677 | BUG_ON(hctx == NULL); |
| @@ -698,9 +681,6 @@ static void ccid3_hc_tx_exit(struct sock *sk) | |||
| 698 | 681 | ||
| 699 | /* Empty packet history */ | 682 | /* Empty packet history */ |
| 700 | dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); | 683 | dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); |
| 701 | |||
| 702 | kfree(dp->dccps_hc_tx_ccid_private); | ||
| 703 | dp->dccps_hc_tx_ccid_private = NULL; | ||
| 704 | } | 684 | } |
| 705 | 685 | ||
| 706 | /* | 686 | /* |
| @@ -727,8 +707,8 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) | |||
| 727 | } | 707 | } |
| 728 | #endif | 708 | #endif |
| 729 | 709 | ||
| 730 | static inline void ccid3_hc_rx_set_state(struct sock *sk, | 710 | static void ccid3_hc_rx_set_state(struct sock *sk, |
| 731 | enum ccid3_hc_rx_states state) | 711 | enum ccid3_hc_rx_states state) |
| 732 | { | 712 | { |
| 733 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 713 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
| 734 | enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state; | 714 | enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state; |
| @@ -793,31 +773,35 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk) | |||
| 793 | dccp_send_ack(sk); | 773 | dccp_send_ack(sk); |
| 794 | } | 774 | } |
| 795 | 775 | ||
| 796 | static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) | 776 | static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) |
| 797 | { | 777 | { |
| 798 | const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 778 | const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
| 799 | u32 x_recv, pinv; | 779 | __be32 x_recv, pinv; |
| 800 | 780 | ||
| 801 | BUG_ON(hcrx == NULL); | 781 | BUG_ON(hcrx == NULL); |
| 802 | 782 | ||
| 803 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) | 783 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) |
| 804 | return; | 784 | return 0; |
| 805 | 785 | ||
| 806 | DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; | 786 | DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; |
| 807 | 787 | ||
| 808 | if (dccp_packet_without_ack(skb)) | 788 | if (dccp_packet_without_ack(skb)) |
| 809 | return; | 789 | return 0; |
| 810 | 790 | ||
| 811 | if (hcrx->ccid3hcrx_elapsed_time != 0) | ||
| 812 | dccp_insert_option_elapsed_time(sk, skb, | ||
| 813 | hcrx->ccid3hcrx_elapsed_time); | ||
| 814 | dccp_insert_option_timestamp(sk, skb); | ||
| 815 | x_recv = htonl(hcrx->ccid3hcrx_x_recv); | 791 | x_recv = htonl(hcrx->ccid3hcrx_x_recv); |
| 816 | pinv = htonl(hcrx->ccid3hcrx_pinv); | 792 | pinv = htonl(hcrx->ccid3hcrx_pinv); |
| 817 | dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, | 793 | |
| 818 | &pinv, sizeof(pinv)); | 794 | if ((hcrx->ccid3hcrx_elapsed_time != 0 && |
| 819 | dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, | 795 | dccp_insert_option_elapsed_time(sk, skb, |
| 820 | &x_recv, sizeof(x_recv)); | 796 | hcrx->ccid3hcrx_elapsed_time)) || |
| 797 | dccp_insert_option_timestamp(sk, skb) || | ||
| 798 | dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, | ||
| 799 | &pinv, sizeof(pinv)) || | ||
| 800 | dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, | ||
| 801 | &x_recv, sizeof(x_recv))) | ||
| 802 | return -1; | ||
| 803 | |||
| 804 | return 0; | ||
| 821 | } | 805 | } |
| 822 | 806 | ||
| 823 | /* calculate first loss interval | 807 | /* calculate first loss interval |
| @@ -1047,20 +1031,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 1047 | } | 1031 | } |
| 1048 | } | 1032 | } |
| 1049 | 1033 | ||
| 1050 | static int ccid3_hc_rx_init(struct sock *sk) | 1034 | static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) |
| 1051 | { | 1035 | { |
| 1052 | struct dccp_sock *dp = dccp_sk(sk); | 1036 | struct dccp_sock *dp = dccp_sk(sk); |
| 1053 | struct ccid3_hc_rx_sock *hcrx; | 1037 | struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); |
| 1054 | 1038 | ||
| 1055 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); | 1039 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); |
| 1056 | 1040 | ||
| 1057 | dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any()); | ||
| 1058 | if (dp->dccps_hc_rx_ccid_private == NULL) | ||
| 1059 | return -ENOMEM; | ||
| 1060 | |||
| 1061 | hcrx = ccid3_hc_rx_sk(sk); | ||
| 1062 | memset(hcrx, 0, sizeof(*hcrx)); | ||
| 1063 | |||
| 1064 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && | 1041 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && |
| 1065 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) | 1042 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) |
| 1066 | hcrx->ccid3hcrx_s = dp->dccps_packet_size; | 1043 | hcrx->ccid3hcrx_s = dp->dccps_packet_size; |
| @@ -1079,7 +1056,6 @@ static int ccid3_hc_rx_init(struct sock *sk) | |||
| 1079 | static void ccid3_hc_rx_exit(struct sock *sk) | 1056 | static void ccid3_hc_rx_exit(struct sock *sk) |
| 1080 | { | 1057 | { |
| 1081 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 1058 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
| 1082 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 1083 | 1059 | ||
| 1084 | BUG_ON(hcrx == NULL); | 1060 | BUG_ON(hcrx == NULL); |
| 1085 | 1061 | ||
| @@ -1090,9 +1066,6 @@ static void ccid3_hc_rx_exit(struct sock *sk) | |||
| 1090 | 1066 | ||
| 1091 | /* Empty loss interval history */ | 1067 | /* Empty loss interval history */ |
| 1092 | dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); | 1068 | dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); |
| 1093 | |||
| 1094 | kfree(dp->dccps_hc_rx_ccid_private); | ||
| 1095 | dp->dccps_hc_rx_ccid_private = NULL; | ||
| 1096 | } | 1069 | } |
| 1097 | 1070 | ||
| 1098 | static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) | 1071 | static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) |
| @@ -1178,12 +1151,11 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, | |||
| 1178 | return 0; | 1151 | return 0; |
| 1179 | } | 1152 | } |
| 1180 | 1153 | ||
| 1181 | static struct ccid ccid3 = { | 1154 | static struct ccid_operations ccid3 = { |
| 1182 | .ccid_id = 3, | 1155 | .ccid_id = 3, |
| 1183 | .ccid_name = "ccid3", | 1156 | .ccid_name = "ccid3", |
| 1184 | .ccid_owner = THIS_MODULE, | 1157 | .ccid_owner = THIS_MODULE, |
| 1185 | .ccid_init = ccid3_init, | 1158 | .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock), |
| 1186 | .ccid_exit = ccid3_exit, | ||
| 1187 | .ccid_hc_tx_init = ccid3_hc_tx_init, | 1159 | .ccid_hc_tx_init = ccid3_hc_tx_init, |
| 1188 | .ccid_hc_tx_exit = ccid3_hc_tx_exit, | 1160 | .ccid_hc_tx_exit = ccid3_hc_tx_exit, |
| 1189 | .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, | 1161 | .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, |
| @@ -1191,6 +1163,7 @@ static struct ccid ccid3 = { | |||
| 1191 | .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, | 1163 | .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, |
| 1192 | .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options, | 1164 | .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options, |
| 1193 | .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, | 1165 | .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, |
| 1166 | .ccid_hc_rx_obj_size = sizeof(struct ccid3_hc_rx_sock), | ||
| 1194 | .ccid_hc_rx_init = ccid3_hc_rx_init, | 1167 | .ccid_hc_rx_init = ccid3_hc_rx_init, |
| 1195 | .ccid_hc_rx_exit = ccid3_hc_rx_exit, | 1168 | .ccid_hc_rx_exit = ccid3_hc_rx_exit, |
| 1196 | .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, | 1169 | .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, |
| @@ -1241,15 +1214,6 @@ module_init(ccid3_module_init); | |||
| 1241 | 1214 | ||
| 1242 | static __exit void ccid3_module_exit(void) | 1215 | static __exit void ccid3_module_exit(void) |
| 1243 | { | 1216 | { |
| 1244 | #ifdef CONFIG_IP_DCCP_UNLOAD_HACK | ||
| 1245 | /* | ||
| 1246 | * Hack to use while developing, so that we get rid of the control | ||
| 1247 | * sock, that is what keeps a refcount on dccp.ko -acme | ||
| 1248 | */ | ||
| 1249 | extern void dccp_ctl_sock_exit(void); | ||
| 1250 | |||
| 1251 | dccp_ctl_sock_exit(); | ||
| 1252 | #endif | ||
| 1253 | ccid_unregister(&ccid3); | 1217 | ccid_unregister(&ccid3); |
| 1254 | 1218 | ||
| 1255 | if (ccid3_tx_hist != NULL) { | 1219 | if (ccid3_tx_hist != NULL) { |
