flow_dissector: introduce support for Ethernet addresses
authorJiri Pirko <jiri@resnulli.us>
Tue, 12 May 2015 12:56:19 +0000 (14:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 May 2015 19:19:47 +0000 (15:19 -0400)
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 586b12306a52f9ca6d510230a1a86bc2c229aa3a..5eac9870689c3bdfa51f8b69c1aef030e7223021 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <linux/in6.h>
+#include <uapi/linux/if_ether.h>
 
 /**
  * struct flow_dissector_key_basic:
@@ -54,12 +55,24 @@ struct flow_dissector_key_ipv6_addrs {
        struct in6_addr dst;
 };
 
+/**
+ * struct flow_dissector_key_eth_addrs:
+ * @src: source Ethernet address
+ * @dst: destination Ethernet address
+ */
+struct flow_dissector_key_eth_addrs {
+       /* (dst,src) must be grouped, in the same way than in ETH header */
+       unsigned char dst[ETH_ALEN];
+       unsigned char src[ETH_ALEN];
+};
+
 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_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
 
        FLOW_DISSECTOR_KEY_MAX,
 };
index 1b95d5ccc9d62742048616f31d729752cf876bb3..7a0b391114a51a0427fa27a52af010e19e1002a5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/if_pppox.h>
 #include <linux/ppp_defs.h>
 #include <linux/stddef.h>
+#include <linux/if_ether.h>
 #include <net/flow_dissector.h>
 #include <scsi/fc/fc_fcoe.h>
 
@@ -138,6 +139,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
                                              FLOW_DISSECTOR_KEY_BASIC,
                                              target_container);
 
+       if (skb_flow_dissector_uses_key(flow_dissector,
+                                       FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
+               struct ethhdr *eth = eth_hdr(skb);
+               struct flow_dissector_key_eth_addrs *key_eth_addrs;
+
+               key_eth_addrs = skb_flow_dissector_target(flow_dissector,
+                                                         FLOW_DISSECTOR_KEY_ETH_ADDRS,
+                                                         target_container);
+               memcpy(key_eth_addrs, &eth->h_dest, sizeof(*key_eth_addrs));
+       }
+
 again:
        switch (proto) {
        case htons(ETH_P_IP): {