X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fdccp%2Fipv4.c;h=a7332f0f85c46cbaa15819e870fca585fc44b292;hb=075ae86611011e1acdda9df6a7e30f8508b31fd6;hp=dc0487b5bacec375dda26bbdc4515b5a5cedc621;hpb=847b9d01474f710e7a018186917d05e59e258309;p=linux-2.6 diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index dc0487b5ba..a7332f0f85 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -28,14 +28,7 @@ #include "ackvec.h" #include "ccid.h" #include "dccp.h" - -struct inet_hashinfo __cacheline_aligned dccp_hashinfo = { - .lhash_lock = RW_LOCK_UNLOCKED, - .lhash_users = ATOMIC_INIT(0), - .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait), -}; - -EXPORT_SYMBOL_GPL(dccp_hashinfo); +#include "feat.h" static int dccp_v4_get_port(struct sock *sk, const unsigned short snum) { @@ -43,18 +36,6 @@ static int dccp_v4_get_port(struct sock *sk, const unsigned short snum) inet_csk_bind_conflict); } -static void dccp_v4_hash(struct sock *sk) -{ - inet_hash(&dccp_hashinfo, sk); -} - -void dccp_unhash(struct sock *sk) -{ - inet_unhash(&dccp_hashinfo, sk); -} - -EXPORT_SYMBOL_GPL(dccp_unhash); - int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct inet_sock *inet = inet_sk(sk); @@ -275,7 +256,10 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, skb = dccp_make_response(sk, dst, req); if (skb != NULL) { const struct inet_request_sock *ireq = inet_rsk(req); + struct dccp_hdr *dh = dccp_hdr(skb); + dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr, + ireq->rmt_addr); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, ireq->rmt_addr, @@ -456,32 +440,6 @@ void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) EXPORT_SYMBOL_GPL(dccp_v4_send_check); -int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code) -{ - struct sk_buff *skb; - /* - * FIXME: what if rebuild_header fails? - * Should we be doing a rebuild_header here? - */ - int err = inet_sk_rebuild_header(sk); - - if (err != 0) - return err; - - skb = dccp_make_reset(sk, sk->sk_dst_cache, code); - if (skb != NULL) { - const struct inet_sock *inet = inet_sk(sk); - - memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); - err = ip_build_and_send_pkt(skb, sk, - inet->saddr, inet->daddr, NULL); - if (err == NET_XMIT_CN) - err = 0; - } - - return err; -} - static inline u64 dccp_v4_init_sequence(const struct sock *sk, const struct sk_buff *skb) { @@ -497,9 +455,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) struct dccp_sock dp; struct request_sock *req; struct dccp_request_sock *dreq; - const __u32 saddr = skb->nh.iph->saddr; - const __u32 daddr = skb->nh.iph->daddr; - const __u32 service = dccp_hdr_request(skb)->dccph_req_service; + const __be32 saddr = skb->nh.iph->saddr; + const __be32 daddr = skb->nh.iph->daddr; + const __be32 service = dccp_hdr_request(skb)->dccph_req_service; struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; @@ -535,7 +493,8 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (req == NULL) goto drop; - /* FIXME: process options */ + if (dccp_parse_options(sk, skb)) + goto drop; dccp_openreq_init(req, &dp, skb); @@ -660,8 +619,8 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) return sk; } -int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, - const u32 daddr) +int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr, + const __be32 daddr) { const struct dccp_hdr* dh = dccp_hdr(skb); int checksum_len; @@ -681,7 +640,7 @@ int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, } static int dccp_v4_verify_checksum(struct sk_buff *skb, - const u32 saddr, const u32 daddr) + const __be32 saddr, const __be32 daddr) { struct dccp_hdr *dh = dccp_hdr(skb); int checksum_len; @@ -1032,98 +991,15 @@ struct inet_connection_sock_af_ops dccp_ipv4_af_ops = { .sockaddr_len = sizeof(struct sockaddr_in), }; -int dccp_v4_init_sock(struct sock *sk) +static int dccp_v4_init_sock(struct sock *sk) { - struct dccp_sock *dp = dccp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); - static int dccp_ctl_socket_init = 1; - - dccp_options_init(&dp->dccps_options); - do_gettimeofday(&dp->dccps_epoch); - - if (dp->dccps_options.dccpo_send_ack_vector) { - dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(DCCP_MAX_ACKVEC_LEN, - GFP_KERNEL); - if (dp->dccps_hc_rx_ackvec == NULL) - return -ENOMEM; - } - - /* - * FIXME: We're hardcoding the CCID, and doing this at this point makes - * the listening (master) sock get CCID control blocks, which is not - * necessary, but for now, to not mess with the test userspace apps, - * lets leave it here, later the real solution is to do this in a - * setsockopt(CCIDs-I-want/accept). -acme - */ - if (likely(!dccp_ctl_socket_init)) { - dp->dccps_hc_rx_ccid = ccid_init(dp->dccps_options.dccpo_rx_ccid, - sk); - dp->dccps_hc_tx_ccid = ccid_init(dp->dccps_options.dccpo_tx_ccid, - sk); - if (dp->dccps_hc_rx_ccid == NULL || - dp->dccps_hc_tx_ccid == NULL) { - ccid_exit(dp->dccps_hc_rx_ccid, sk); - ccid_exit(dp->dccps_hc_tx_ccid, sk); - if (dp->dccps_options.dccpo_send_ack_vector) { - dccp_ackvec_free(dp->dccps_hc_rx_ackvec); - dp->dccps_hc_rx_ackvec = NULL; - } - dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL; - return -ENOMEM; - } - } else - dccp_ctl_socket_init = 0; - - dccp_init_xmit_timers(sk); - icsk->icsk_rto = DCCP_TIMEOUT_INIT; - sk->sk_state = DCCP_CLOSED; - sk->sk_write_space = dccp_write_space; - icsk->icsk_af_ops = &dccp_ipv4_af_ops; - icsk->icsk_sync_mss = dccp_sync_mss; - dp->dccps_mss_cache = 536; - dp->dccps_role = DCCP_ROLE_UNDEFINED; - dp->dccps_service = DCCP_SERVICE_INVALID_VALUE; + const int err = dccp_init_sock(sk); - return 0; -} - -EXPORT_SYMBOL_GPL(dccp_v4_init_sock); - -int dccp_v4_destroy_sock(struct sock *sk) -{ - struct dccp_sock *dp = dccp_sk(sk); - - /* - * DCCP doesn't use sk_write_queue, just sk_send_head - * for retransmissions - */ - if (sk->sk_send_head != NULL) { - kfree_skb(sk->sk_send_head); - sk->sk_send_head = NULL; - } - - /* Clean up a referenced DCCP bind bucket. */ - if (inet_csk(sk)->icsk_bind_hash != NULL) - inet_put_port(&dccp_hashinfo, sk); - - kfree(dp->dccps_service_list); - dp->dccps_service_list = NULL; - - ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk); - ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk); - if (dp->dccps_options.dccpo_send_ack_vector) { - dccp_ackvec_free(dp->dccps_hc_rx_ackvec); - dp->dccps_hc_rx_ackvec = NULL; - } - ccid_exit(dp->dccps_hc_rx_ccid, sk); - ccid_exit(dp->dccps_hc_tx_ccid, sk); - dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL; - - return 0; + if (err == 0) + inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops; + return err; } -EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock); - static void dccp_v4_reqsk_destructor(struct request_sock *req) { kfree(inet_rsk(req)->opt); @@ -1155,12 +1031,12 @@ struct proto dccp_prot = { .sendmsg = dccp_sendmsg, .recvmsg = dccp_recvmsg, .backlog_rcv = dccp_v4_do_rcv, - .hash = dccp_v4_hash, + .hash = dccp_hash, .unhash = dccp_unhash, .accept = inet_csk_accept, .get_port = dccp_v4_get_port, .shutdown = dccp_shutdown, - .destroy = dccp_v4_destroy_sock, + .destroy = dccp_destroy_sock, .orphan_count = &dccp_orphan_count, .max_header = MAX_DCCP_HEADER, .obj_size = sizeof(struct dccp_sock),