]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - net/ipv6/syncookies.c
ipv4: fix redirect handling
[linux-2.6.git] / net / ipv6 / syncookies.c
index 0b4cf350631beabcd42db20ce0e02cd544f2fdeb..ac838965ff34551693a44f758b5a2e8bcef79c74 100644 (file)
@@ -66,7 +66,7 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
 static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
                      ipv6_cookie_scratch);
 
-static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr,
+static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr,
                       __be16 sport, __be16 dport, u32 count, int c)
 {
        __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch);
@@ -86,7 +86,8 @@ static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr,
        return tmp[17];
 }
 
-static __u32 secure_tcp_syn_cookie(struct in6_addr *saddr, struct in6_addr *daddr,
+static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr,
+                                  const struct in6_addr *daddr,
                                   __be16 sport, __be16 dport, __u32 sseq,
                                   __u32 count, __u32 data)
 {
@@ -96,8 +97,8 @@ static __u32 secure_tcp_syn_cookie(struct in6_addr *saddr, struct in6_addr *dadd
                & COOKIEMASK));
 }
 
-static __u32 check_tcp_syn_cookie(__u32 cookie, struct in6_addr *saddr,
-                                 struct in6_addr *daddr, __be16 sport,
+static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr,
+                                 const struct in6_addr *daddr, __be16 sport,
                                  __be16 dport, __u32 sseq, __u32 count,
                                  __u32 maxdiff)
 {
@@ -116,7 +117,7 @@ static __u32 check_tcp_syn_cookie(__u32 cookie, struct in6_addr *saddr,
 
 __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
 {
-       struct ipv6hdr *iph = ipv6_hdr(skb);
+       const struct ipv6hdr *iph = ipv6_hdr(skb);
        const struct tcphdr *th = tcp_hdr(skb);
        int mssind;
        const __u16 mss = *mssp;
@@ -138,7 +139,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
 
 static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
 {
-       struct ipv6hdr *iph = ipv6_hdr(skb);
+       const struct ipv6hdr *iph = ipv6_hdr(skb);
        const struct tcphdr *th = tcp_hdr(skb);
        __u32 seq = ntohl(th->seq) - 1;
        __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr,
@@ -164,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        int mss;
        struct dst_entry *dst;
        __u8 rcv_wscale;
-       bool ecn_ok;
+       bool ecn_ok = false;
 
        if (!sysctl_tcp_syncookies || !th->ack || th->rst)
                goto out;
@@ -222,6 +223,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        ireq->wscale_ok         = tcp_opt.wscale_ok;
        ireq->tstamp_ok         = tcp_opt.saw_tstamp;
        req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
+       treq->snt_synack        = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsecr : 0;
        treq->rcv_isn = ntohl(th->seq) - 1;
        treq->snt_isn = cookie;
 
@@ -232,19 +234,19 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
         */
        {
                struct in6_addr *final_p, final;
-               struct flowi fl;
-               memset(&fl, 0, sizeof(fl));
-               fl.proto = IPPROTO_TCP;
-               ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
-               final_p = fl6_update_dst(&fl, np->opt, &final);
-               ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
-               fl.oif = sk->sk_bound_dev_if;
-               fl.mark = sk->sk_mark;
-               fl.fl_ip_dport = inet_rsk(req)->rmt_port;
-               fl.fl_ip_sport = inet_sk(sk)->inet_sport;
-               security_req_classify_flow(req, &fl);
-
-               dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+               struct flowi6 fl6;
+               memset(&fl6, 0, sizeof(fl6));
+               fl6.flowi6_proto = IPPROTO_TCP;
+               ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
+               final_p = fl6_update_dst(&fl6, np->opt, &final);
+               ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
+               fl6.flowi6_oif = sk->sk_bound_dev_if;
+               fl6.flowi6_mark = sk->sk_mark;
+               fl6.fl6_dport = inet_rsk(req)->rmt_port;
+               fl6.fl6_sport = inet_sk(sk)->inet_sport;
+               security_req_classify_flow(req, flowi6_to_flowi(&fl6));
+
+               dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
                if (IS_ERR(dst))
                        goto out_free;
        }