net/flow_dissector: add support for dissection of misc ip header fields
authorOr Gerlitz <ogerlitz@mellanox.com>
Thu, 1 Jun 2017 18:37:37 +0000 (21:37 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sun, 4 Jun 2017 22:12:23 +0000 (18:12 -0400)
Add support for dissection of ip tos and ttl and ipv6 traffic-class
and hoplimit. Both are dissected into the same struct.

Uses similar call to ip dissection function as with tcp, arp and others.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/flow_dissector.h
net/core/flow_dissector.c

index efe34eec61dccc125fe59741e45de2c2e61cd250..e2663e900b0a4bcc827888927c4b3f8e3bb68179 100644 (file)
@@ -165,6 +165,16 @@ struct flow_dissector_key_tcp {
        __be16 flags;
 };
 
+/**
+ * struct flow_dissector_key_ip:
+ * @tos: tos
+ * @ttl: ttl
+ */
+struct flow_dissector_key_ip {
+       __u8    tos;
+       __u8    ttl;
+};
+
 enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
        FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -186,6 +196,7 @@ enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
        FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
        FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
+       FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
 
        FLOW_DISSECTOR_KEY_MAX,
 };
index 5a45943081f5ff7723389bee3c7f80786add6c00..fc5fc4594c908049c5141858338848c8d12eb0d5 100644 (file)
@@ -367,6 +367,40 @@ __skb_flow_dissect_tcp(const struct sk_buff *skb,
        key_tcp->flags = (*(__be16 *) &tcp_flag_word(th) & htons(0x0FFF));
 }
 
+static void
+__skb_flow_dissect_ipv4(const struct sk_buff *skb,
+                       struct flow_dissector *flow_dissector,
+                       void *target_container, void *data, const struct iphdr *iph)
+{
+       struct flow_dissector_key_ip *key_ip;
+
+       if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
+               return;
+
+       key_ip = skb_flow_dissector_target(flow_dissector,
+                                          FLOW_DISSECTOR_KEY_IP,
+                                          target_container);
+       key_ip->tos = iph->tos;
+       key_ip->ttl = iph->ttl;
+}
+
+static void
+__skb_flow_dissect_ipv6(const struct sk_buff *skb,
+                       struct flow_dissector *flow_dissector,
+                       void *target_container, void *data, const struct ipv6hdr *iph)
+{
+       struct flow_dissector_key_ip *key_ip;
+
+       if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
+               return;
+
+       key_ip = skb_flow_dissector_target(flow_dissector,
+                                          FLOW_DISSECTOR_KEY_IP,
+                                          target_container);
+       key_ip->tos = ipv6_get_dsfield(iph);
+       key_ip->ttl = iph->hop_limit;
+}
+
 /**
  * __skb_flow_dissect - extract the flow_keys struct and return it
  * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
@@ -469,6 +503,9 @@ ip:
                        }
                }
 
+               __skb_flow_dissect_ipv4(skb, flow_dissector,
+                                       target_container, data, iph);
+
                if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
                        goto out_good;
 
@@ -514,6 +551,9 @@ ipv6:
                                goto out_good;
                }
 
+               __skb_flow_dissect_ipv6(skb, flow_dissector,
+                                       target_container, data, iph);
+
                if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
                        goto out_good;