net/tcp: Verify inbound TCP-AO signed segments
[linux-2.6-microblaze.git] / net / ipv4 / tcp.c
index 369e2a4..eb71212 100644 (file)
@@ -4375,42 +4375,23 @@ EXPORT_SYMBOL(tcp_md5_hash_key);
 enum skb_drop_reason
 tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
                     const void *saddr, const void *daddr,
-                    int family, int dif, int sdif)
+                    int family, int l3index, const __u8 *hash_location)
 {
-       /*
-        * This gets called for each TCP segment that arrives
-        * so we want to be efficient.
+       /* This gets called for each TCP segment that has TCP-MD5 option.
         * We have 3 drop cases:
         * o No MD5 hash and one expected.
         * o MD5 hash and we're not expecting one.
         * o MD5 hash and its wrong.
         */
-       const __u8 *hash_location = NULL;
-       struct tcp_md5sig_key *hash_expected;
        const struct tcphdr *th = tcp_hdr(skb);
        const struct tcp_sock *tp = tcp_sk(sk);
-       int genhash, l3index;
+       struct tcp_md5sig_key *key;
        u8 newhash[16];
+       int genhash;
 
-       /* sdif set, means packet ingressed via a device
-        * in an L3 domain and dif is set to the l3mdev
-        */
-       l3index = sdif ? dif : 0;
-
-       hash_expected = tcp_md5_do_lookup(sk, l3index, saddr, family);
-       if (tcp_parse_auth_options(th, &hash_location, NULL))
-               return SKB_DROP_REASON_TCP_AUTH_HDR;
-
-       /* We've parsed the options - do we have a hash? */
-       if (!hash_expected && !hash_location)
-               return SKB_NOT_DROPPED_YET;
+       key = tcp_md5_do_lookup(sk, l3index, saddr, family);
 
-       if (hash_expected && !hash_location) {
-               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
-               return SKB_DROP_REASON_TCP_MD5NOTFOUND;
-       }
-
-       if (!hash_expected && hash_location) {
+       if (!key && hash_location) {
                NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
                return SKB_DROP_REASON_TCP_MD5UNEXPECTED;
        }
@@ -4420,14 +4401,10 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
         * IPv4-mapped case.
         */
        if (family == AF_INET)
-               genhash = tcp_v4_md5_hash_skb(newhash,
-                                             hash_expected,
-                                             NULL, skb);
+               genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb);
        else
-               genhash = tp->af_specific->calc_md5_hash(newhash,
-                                                        hash_expected,
+               genhash = tp->af_specific->calc_md5_hash(newhash, key,
                                                         NULL, skb);
-
        if (genhash || memcmp(hash_location, newhash, 16) != 0) {
                NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
                if (family == AF_INET) {