Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b924933c authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

flow_dissector: introduce support for ipv6 addressses



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: default avatarJiri Pirko <jiri@resnulli.us>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3f8eaeb
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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,
};
+21 −8
Original line number Diff line number Diff line
@@ -175,16 +175,29 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
		ip_proto = iph->nexthdr;
		nhoff += sizeof(struct ipv6hdr);

		if (!skb_flow_dissector_uses_key(flow_dissector,
						 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS))
			break;
		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);
			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