};
 };
 
+/**
+ * flow_dissector_key_icmp:
+ *     @ports: type and code of ICMP header
+ *             icmp: ICMP type (high) and code (low)
+ *             type: ICMP type
+ *             code: ICMP code
+ */
+struct flow_dissector_key_icmp {
+       union {
+               __be16 icmp;
+               struct {
+                       u8 type;
+                       u8 code;
+               };
+       };
+};
 
 /**
  * struct flow_dissector_key_eth_addrs:
        FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
        FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
        FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
+       FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
        FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
        FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
        FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
 
 }
 EXPORT_SYMBOL(skb_flow_dissector_init);
 
+/**
+ * skb_flow_get_be16 - extract be16 entity
+ * @skb: sk_buff to extract from
+ * @poff: offset to extract at
+ * @data: raw buffer pointer to the packet
+ * @hlen: packet header length
+ *
+ * The function will try to retrieve a be32 entity at
+ * offset poff
+ */
+__be16 skb_flow_get_be16(const struct sk_buff *skb, int poff, void *data,
+                        int hlen)
+{
+       __be16 *u, _u;
+
+       u = __skb_header_pointer(skb, poff, sizeof(_u), data, hlen, &_u);
+       if (u)
+               return *u;
+
+       return 0;
+}
+
 /**
  * __skb_flow_get_ports - extract the upper layer ports and return them
  * @skb: sk_buff to extract the ports from
        struct flow_dissector_key_basic *key_basic;
        struct flow_dissector_key_addrs *key_addrs;
        struct flow_dissector_key_ports *key_ports;
+       struct flow_dissector_key_icmp *key_icmp;
        struct flow_dissector_key_tags *key_tags;
        struct flow_dissector_key_vlan *key_vlan;
        struct flow_dissector_key_keyid *key_keyid;
                                                        data, hlen);
        }
 
+       if (dissector_uses_key(flow_dissector,
+                              FLOW_DISSECTOR_KEY_ICMP)) {
+               key_icmp = skb_flow_dissector_target(flow_dissector,
+                                                    FLOW_DISSECTOR_KEY_ICMP,
+                                                    target_container);
+               key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
+       }
+
 out_good:
        ret = true;