lisp: Use IP addresses rather than flow on hash failure.
authorJesse Gross <jesse@nicira.com>
Tue, 10 Jun 2014 17:38:33 +0000 (10:38 -0700)
committerJesse Gross <jesse@nicira.com>
Fri, 13 Jun 2014 19:09:47 +0000 (12:09 -0700)
When calculating the source port for the UDP header, LISP primarily
uses skb_get_hash() but needs a backup in case this fails. The
current backup is a hash of the entire flow key but this includes
many fields that probably would not be considered to be part of a
flow in many situations. It assumes that all fields, including those
not used, are zeroed out which will soon not be the case.

This switches to using a hash of the IP addresses instead, which
solves both problems. These should always be present since LISP
encapsulates L3 packets.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
datapath/vport-lisp.c

index a1e2b2b..86c7c5b 100644 (file)
@@ -173,8 +173,15 @@ static u16 get_src_port(struct net *net, struct sk_buff *skb)
        if (!hash) {
                struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
 
-               hash = jhash2((const u32 *)pkt_key,
-                           sizeof(*pkt_key) / sizeof(u32), 0);
+               if (skb->protocol == htons(ETH_P_IP))
+                       hash = jhash2((const u32 *)&pkt_key->ipv4.addr,
+                                  sizeof(pkt_key->ipv4.addr) / sizeof(u32), 0);
+               else if (skb->protocol == htons(ETH_P_IPV6))
+                       hash = jhash2((const u32 *)&pkt_key->ipv6.addr,
+                                  sizeof(pkt_key->ipv6.addr) / sizeof(u32), 0);
+               else
+                       pr_warn_once("LISP inner protocol is not IP when "
+                                    "calculating hash.\n");
        }
 
        inet_get_local_port_range(net, &low, &high);