]> err.no Git - linux-2.6/blobdiff - net/dccp/ipv4.c
[DCCP]: Move dccp_hashinfo from ipv4.c to the core
[linux-2.6] / net / dccp / ipv4.c
index 00f983226672a6c70aca4a67368cceae2d7a118b..a7332f0f85c46cbaa15819e870fca585fc44b292 100644 (file)
 #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);
@@ -119,7 +100,8 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        if (err != 0)
                goto failure;
 
-       err = ip_route_newports(&rt, inet->sport, inet->dport, sk);
+       err = ip_route_newports(&rt, IPPROTO_DCCP, inet->sport, inet->dport,
+                               sk);
        if (err != 0)
                goto failure;
 
@@ -274,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,
@@ -455,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)
 {
@@ -496,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;
 
@@ -534,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);
 
@@ -659,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;
@@ -680,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;
@@ -1031,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);
@@ -1154,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),