|
@@ -5,6 +5,7 @@
|
|
#include <linux/ipv6.h>
|
|
#include <linux/ipv6.h>
|
|
#include <linux/if_vlan.h>
|
|
#include <linux/if_vlan.h>
|
|
#include <net/dsa.h>
|
|
#include <net/dsa.h>
|
|
|
|
+#include <net/dst_metadata.h>
|
|
#include <net/ip.h>
|
|
#include <net/ip.h>
|
|
#include <net/ipv6.h>
|
|
#include <net/ipv6.h>
|
|
#include <net/gre.h>
|
|
#include <net/gre.h>
|
|
@@ -115,6 +116,102 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(__skb_flow_get_ports);
|
|
EXPORT_SYMBOL(__skb_flow_get_ports);
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
|
|
|
|
+ struct flow_dissector *flow_dissector,
|
|
|
|
+ void *target_container)
|
|
|
|
+{
|
|
|
|
+ struct flow_dissector_key_control *ctrl;
|
|
|
|
+
|
|
|
|
+ if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ ctrl = skb_flow_dissector_target(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_CONTROL,
|
|
|
|
+ target_container);
|
|
|
|
+ ctrl->addr_type = type;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+__skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
|
|
|
|
+ struct flow_dissector *flow_dissector,
|
|
|
|
+ void *target_container)
|
|
|
|
+{
|
|
|
|
+ struct ip_tunnel_info *info;
|
|
|
|
+ struct ip_tunnel_key *key;
|
|
|
|
+
|
|
|
|
+ /* A quick check to see if there might be something to do. */
|
|
|
|
+ if (!dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_KEYID) &&
|
|
|
|
+ !dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) &&
|
|
|
|
+ !dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) &&
|
|
|
|
+ !dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_CONTROL) &&
|
|
|
|
+ !dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_PORTS))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ info = skb_tunnel_info(skb);
|
|
|
|
+ if (!info)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ key = &info->key;
|
|
|
|
+
|
|
|
|
+ switch (ip_tunnel_info_af(info)) {
|
|
|
|
+ case AF_INET:
|
|
|
|
+ skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
|
|
|
|
+ flow_dissector,
|
|
|
|
+ target_container);
|
|
|
|
+ if (dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
|
|
|
|
+ struct flow_dissector_key_ipv4_addrs *ipv4;
|
|
|
|
+
|
|
|
|
+ ipv4 = skb_flow_dissector_target(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
|
|
|
|
+ target_container);
|
|
|
|
+ ipv4->src = key->u.ipv4.src;
|
|
|
|
+ ipv4->dst = key->u.ipv4.dst;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case AF_INET6:
|
|
|
|
+ skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
|
|
|
|
+ flow_dissector,
|
|
|
|
+ target_container);
|
|
|
|
+ if (dissector_uses_key(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
|
|
|
|
+ struct flow_dissector_key_ipv6_addrs *ipv6;
|
|
|
|
+
|
|
|
|
+ ipv6 = skb_flow_dissector_target(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
|
|
|
|
+ target_container);
|
|
|
|
+ ipv6->src = key->u.ipv6.src;
|
|
|
|
+ ipv6->dst = key->u.ipv6.dst;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
|
|
|
|
+ struct flow_dissector_key_keyid *keyid;
|
|
|
|
+
|
|
|
|
+ keyid = skb_flow_dissector_target(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_KEYID,
|
|
|
|
+ target_container);
|
|
|
|
+ keyid->keyid = tunnel_id_to_key32(key->tun_id);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
|
|
|
|
+ struct flow_dissector_key_ports *tp;
|
|
|
|
+
|
|
|
|
+ tp = skb_flow_dissector_target(flow_dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_ENC_PORTS,
|
|
|
|
+ target_container);
|
|
|
|
+ tp->src = key->tp_src;
|
|
|
|
+ tp->dst = key->tp_dst;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static enum flow_dissect_ret
|
|
static enum flow_dissect_ret
|
|
__skb_flow_dissect_mpls(const struct sk_buff *skb,
|
|
__skb_flow_dissect_mpls(const struct sk_buff *skb,
|
|
struct flow_dissector *flow_dissector,
|
|
struct flow_dissector *flow_dissector,
|
|
@@ -478,6 +575,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
|
|
FLOW_DISSECTOR_KEY_BASIC,
|
|
FLOW_DISSECTOR_KEY_BASIC,
|
|
target_container);
|
|
target_container);
|
|
|
|
|
|
|
|
+ __skb_flow_dissect_tunnel_info(skb, flow_dissector,
|
|
|
|
+ target_container);
|
|
|
|
+
|
|
if (dissector_uses_key(flow_dissector,
|
|
if (dissector_uses_key(flow_dissector,
|
|
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
|
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
|
struct ethhdr *eth = eth_hdr(skb);
|
|
struct ethhdr *eth = eth_hdr(skb);
|