tcp: add const qualifiers where possible
[pandora-kernel.git] / net / ipv4 / tcp_ipv4.c
index 1c12b8e..955c925 100644 (file)
@@ -104,7 +104,7 @@ struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
 struct inet_hashinfo tcp_hashinfo;
 EXPORT_SYMBOL(tcp_hashinfo);
 
-static inline __u32 tcp_v4_init_sequence(struct sk_buff *skb)
+static inline __u32 tcp_v4_init_sequence(const struct sk_buff *skb)
 {
        return secure_tcp_sequence_number(ip_hdr(skb)->daddr,
                                          ip_hdr(skb)->saddr,
@@ -552,7 +552,7 @@ static void __tcp_v4_send_check(struct sk_buff *skb,
 /* This routine computes an IPv4 TCP checksum. */
 void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb)
 {
-       struct inet_sock *inet = inet_sk(sk);
+       const struct inet_sock *inet = inet_sk(sk);
 
        __tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr);
 }
@@ -590,7 +590,7 @@ int tcp_v4_gso_send_check(struct sk_buff *skb)
 
 static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 {
-       struct tcphdr *th = tcp_hdr(skb);
+       const struct tcphdr *th = tcp_hdr(skb);
        struct {
                struct tcphdr th;
 #ifdef CONFIG_TCP_MD5SIG
@@ -668,7 +668,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                            struct tcp_md5sig_key *key,
                            int reply_flags)
 {
-       struct tcphdr *th = tcp_hdr(skb);
+       const struct tcphdr *th = tcp_hdr(skb);
        struct {
                struct tcphdr th;
                __be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2)
@@ -808,20 +808,38 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req)
        kfree(inet_rsk(req)->opt);
 }
 
-static void syn_flood_warning(const struct sk_buff *skb)
+/*
+ * Return 1 if a syncookie should be sent
+ */
+int tcp_syn_flood_action(struct sock *sk,
+                        const struct sk_buff *skb,
+                        const char *proto)
 {
-       const char *msg;
+       const char *msg = "Dropping request";
+       int want_cookie = 0;
+       struct listen_sock *lopt;
+
+
 
 #ifdef CONFIG_SYN_COOKIES
-       if (sysctl_tcp_syncookies)
+       if (sysctl_tcp_syncookies) {
                msg = "Sending cookies";
-       else
+               want_cookie = 1;
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES);
+       } else
 #endif
-               msg = "Dropping request";
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP);
 
-       pr_info("TCP: Possible SYN flooding on port %d. %s.\n",
-                               ntohs(tcp_hdr(skb)->dest), msg);
+       lopt = inet_csk(sk)->icsk_accept_queue.listen_opt;
+       if (!lopt->synflood_warned) {
+               lopt->synflood_warned = 1;
+               pr_info("%s: Possible SYN flooding on port %d. %s. "
+                       " Check SNMP counters.\n",
+                       proto, ntohs(tcp_hdr(skb)->dest), msg);
+       }
+       return want_cookie;
 }
+EXPORT_SYMBOL(tcp_syn_flood_action);
 
 /*
  * Save and compile IPv4 options into the request_sock if needed.
@@ -909,18 +927,21 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
                        }
                        sk_nocaps_add(sk, NETIF_F_GSO_MASK);
                }
-               if (tcp_alloc_md5sig_pool(sk) == NULL) {
+
+               md5sig = tp->md5sig_info;
+               if (md5sig->entries4 == 0 &&
+                   tcp_alloc_md5sig_pool(sk) == NULL) {
                        kfree(newkey);
                        return -ENOMEM;
                }
-               md5sig = tp->md5sig_info;
 
                if (md5sig->alloced4 == md5sig->entries4) {
                        keys = kmalloc((sizeof(*keys) *
                                        (md5sig->entries4 + 1)), GFP_ATOMIC);
                        if (!keys) {
                                kfree(newkey);
-                               tcp_free_md5sig_pool();
+                               if (md5sig->entries4 == 0)
+                                       tcp_free_md5sig_pool();
                                return -ENOMEM;
                        }
 
@@ -964,6 +985,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
                                kfree(tp->md5sig_info->keys4);
                                tp->md5sig_info->keys4 = NULL;
                                tp->md5sig_info->alloced4 = 0;
+                               tcp_free_md5sig_pool();
                        } else if (tp->md5sig_info->entries4 != i) {
                                /* Need to do some manipulation */
                                memmove(&tp->md5sig_info->keys4[i],
@@ -971,7 +993,6 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
                                        (tp->md5sig_info->entries4 - i) *
                                         sizeof(struct tcp4_md5sig_key));
                        }
-                       tcp_free_md5sig_pool();
                        return 0;
                }
        }
@@ -1161,10 +1182,10 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
         * o MD5 hash and we're not expecting one.
         * o MD5 hash and its wrong.
         */
-       __u8 *hash_location = NULL;
+       const __u8 *hash_location = NULL;
        struct tcp_md5sig_key *hash_expected;
        const struct iphdr *iph = ip_hdr(skb);
-       struct tcphdr *th = tcp_hdr(skb);
+       const struct tcphdr *th = tcp_hdr(skb);
        int genhash;
        unsigned char newhash[16];
 
@@ -1227,7 +1248,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_extend_values tmp_ext;
        struct tcp_options_received tmp_opt;
-       u8 *hash_location;
+       const u8 *hash_location;
        struct request_sock *req;
        struct inet_request_sock *ireq;
        struct tcp_sock *tp = tcp_sk(sk);
@@ -1235,11 +1256,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        __be32 saddr = ip_hdr(skb)->saddr;
        __be32 daddr = ip_hdr(skb)->daddr;
        __u32 isn = TCP_SKB_CB(skb)->when;
-#ifdef CONFIG_SYN_COOKIES
        int want_cookie = 0;
-#else
-#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */
-#endif
 
        /* Never answer to SYNs send to broadcast or multicast */
        if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
@@ -1250,14 +1267,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
         * evidently real one.
         */
        if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
-               if (net_ratelimit())
-                       syn_flood_warning(skb);
-#ifdef CONFIG_SYN_COOKIES
-               if (sysctl_tcp_syncookies) {
-                       want_cookie = 1;
-               } else
-#endif
-               goto drop;
+               want_cookie = tcp_syn_flood_action(sk, skb, "TCP");
+               if (!want_cookie)
+                       goto drop;
        }
 
        /* Accept backlog is full. If we have already queued enough
@@ -1303,9 +1315,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
                while (l-- > 0)
                        *c++ ^= *hash_location++;
 
-#ifdef CONFIG_SYN_COOKIES
                want_cookie = 0;        /* not our kind of cookie */
-#endif
                tmp_ext.cookie_out_never = 0; /* false */
                tmp_ext.cookie_plus = tmp_opt.cookie_plus;
        } else if (!tp->rx_opt.cookie_in_always) {
@@ -1578,7 +1588,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 #endif
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
                        rsk = sk;
                        goto reset;
@@ -1595,7 +1605,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                        goto discard;
 
                if (nsk != sk) {
-                       sock_rps_save_rxhash(nsk, skb->rxhash);
+                       sock_rps_save_rxhash(nsk, skb);
                        if (tcp_child_process(sk, nsk, skb)) {
                                rsk = nsk;
                                goto reset;
@@ -1603,7 +1613,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                        return 0;
                }
        } else
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
 
        if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
                rsk = sk;
@@ -1635,7 +1645,7 @@ EXPORT_SYMBOL(tcp_v4_do_rcv);
 int tcp_v4_rcv(struct sk_buff *skb)
 {
        const struct iphdr *iph;
-       struct tcphdr *th;
+       const struct tcphdr *th;
        struct sock *sk;
        int ret;
        struct net *net = dev_net(skb->dev);
@@ -1670,7 +1680,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
                                    skb->len - th->doff * 4);
        TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
        TCP_SKB_CB(skb)->when    = 0;
-       TCP_SKB_CB(skb)->flags   = iph->tos;
+       TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
        TCP_SKB_CB(skb)->sacked  = 0;
 
        sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
@@ -1799,7 +1809,7 @@ EXPORT_SYMBOL(tcp_v4_get_peer);
 
 void *tcp_v4_tw_get_peer(struct sock *sk)
 {
-       struct inet_timewait_sock *tw = inet_twsk(sk);
+       const struct inet_timewait_sock *tw = inet_twsk(sk);
 
        return inet_getpeer_v4(tw->tw_daddr, 1);
 }
@@ -2371,7 +2381,7 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)
 }
 EXPORT_SYMBOL(tcp_proc_unregister);
 
-static void get_openreq4(struct sock *sk, struct request_sock *req,
+static void get_openreq4(const struct sock *sk, const struct request_sock *req,
                         struct seq_file *f, int i, int uid, int *len)
 {
        const struct inet_request_sock *ireq = inet_rsk(req);
@@ -2401,9 +2411,9 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
 {
        int timer_active;
        unsigned long timer_expires;
-       struct tcp_sock *tp = tcp_sk(sk);
+       const struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
-       struct inet_sock *inet = inet_sk(sk);
+       const struct inet_sock *inet = inet_sk(sk);
        __be32 dest = inet->inet_daddr;
        __be32 src = inet->inet_rcv_saddr;
        __u16 destp = ntohs(inet->inet_dport);
@@ -2452,7 +2462,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
                len);
 }
 
-static void get_timewait4_sock(struct inet_timewait_sock *tw,
+static void get_timewait4_sock(const struct inet_timewait_sock *tw,
                               struct seq_file *f, int i, int *len)
 {
        __be32 dest, src;