flow_dissector: introduce support for ipv6 addressses
authorJiri Pirko <jiri@resnulli.us>
Tue, 12 May 2015 12:56:18 +0000 (14:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 May 2015 19:19:47 +0000 (15:19 -0400)
So far, only hashes made out of ipv6 addresses could be dissected. This
patch introduces support for dissection of full ipv6 addresses.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/flow_dissector.h
net/core/flow_dissector.c

index 1add891..586b123 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <linux/skbuff.h>
+#include <linux/in6.h>
 
 /**
  * struct flow_dissector_key_basic:
@@ -42,11 +43,23 @@ struct flow_dissector_key_ports {
        };
 };
 
+/**
+ * struct flow_dissector_key_ipv6_addrs:
+ * @src: source ip address
+ * @dst: destination ip address
+ */
+struct flow_dissector_key_ipv6_addrs {
+       /* (src,dst) must be grouped, in the same way than in IP header */
+       struct in6_addr src;
+       struct in6_addr dst;
+};
+
 enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
        FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_addrs */
        FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS, /* struct flow_dissector_key_addrs */
        FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
+       FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
 
        FLOW_DISSECTOR_KEY_MAX,
 };
index 6a49aca..1b95d5c 100644 (file)
@@ -175,16 +175,29 @@ ipv6:
                ip_proto = iph->nexthdr;
                nhoff += sizeof(struct ipv6hdr);
 
-               if (!skb_flow_dissector_uses_key(flow_dissector,
-                                                FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS))
-                       break;
-               key_addrs = skb_flow_dissector_target(flow_dissector,
-                                                     FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
-                                                     target_container);
+               if (skb_flow_dissector_uses_key(flow_dissector,
+                                               FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS)) {
+                       key_addrs = skb_flow_dissector_target(flow_dissector,
+                                                             FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
+                                                             target_container);
 
-               key_addrs->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
-               key_addrs->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
+                       key_addrs->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
+                       key_addrs->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
+                       goto flow_label;
+               }
+               if (skb_flow_dissector_uses_key(flow_dissector,
+                                               FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+                       struct flow_dissector_key_ipv6_addrs *key_ipv6_addrs;
 
+                       key_ipv6_addrs = skb_flow_dissector_target(flow_dissector,
+                                                                  FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+                                                                  target_container);
+
+                       memcpy(key_ipv6_addrs, &iph->saddr, sizeof(*key_ipv6_addrs));
+                       goto flow_label;
+               }
+               break;
+flow_label:
                flow_label = ip6_flowlabel(iph);
                if (flow_label) {
                        /* Awesome, IPv6 packet has a flow label so we can