Commit | Line | Data |
---|---|---|
1bd758eb JP |
1 | #ifndef _NET_FLOW_DISSECTOR_H |
2 | #define _NET_FLOW_DISSECTOR_H | |
0744dd00 | 3 | |
c3f8eaeb JP |
4 | #include <linux/types.h> |
5 | #include <linux/skbuff.h> | |
b924933c | 6 | #include <linux/in6.h> |
67a900cc | 7 | #include <uapi/linux/if_ether.h> |
c3f8eaeb | 8 | |
fbff949e JP |
9 | /** |
10 | * struct flow_dissector_key_basic: | |
11 | * @thoff: Transport header offset | |
12 | * @n_proto: Network header protocol (eg. IPv4/IPv6) | |
13 | * @ip_proto: Transport header protocol (eg. TCP/UDP) | |
14 | */ | |
15 | struct flow_dissector_key_basic { | |
16 | u16 thoff; | |
17 | __be16 n_proto; | |
18 | u8 ip_proto; | |
19 | }; | |
20 | ||
21 | /** | |
22 | * struct flow_dissector_key_addrs: | |
23 | * @src: source ip address in case of IPv4 | |
24 | * For IPv6 it contains 32bit hash of src address | |
25 | * @dst: destination ip address in case of IPv4 | |
26 | * For IPv6 it contains 32bit hash of dst address | |
27 | */ | |
28 | struct flow_dissector_key_addrs { | |
29 | /* (src,dst) must be grouped, in the same way than in IP header */ | |
30 | __be32 src; | |
31 | __be32 dst; | |
32 | }; | |
33 | ||
34 | /** | |
35 | * flow_dissector_key_tp_ports: | |
36 | * @ports: port numbers of Transport header | |
59346afe JP |
37 | * src: source port number |
38 | * dst: destination port number | |
fbff949e JP |
39 | */ |
40 | struct flow_dissector_key_ports { | |
41 | union { | |
42 | __be32 ports; | |
59346afe JP |
43 | struct { |
44 | __be16 src; | |
45 | __be16 dst; | |
46 | }; | |
fbff949e JP |
47 | }; |
48 | }; | |
49 | ||
b924933c JP |
50 | /** |
51 | * struct flow_dissector_key_ipv6_addrs: | |
52 | * @src: source ip address | |
53 | * @dst: destination ip address | |
54 | */ | |
55 | struct flow_dissector_key_ipv6_addrs { | |
56 | /* (src,dst) must be grouped, in the same way than in IP header */ | |
57 | struct in6_addr src; | |
58 | struct in6_addr dst; | |
59 | }; | |
60 | ||
67a900cc JP |
61 | /** |
62 | * struct flow_dissector_key_eth_addrs: | |
63 | * @src: source Ethernet address | |
64 | * @dst: destination Ethernet address | |
65 | */ | |
66 | struct flow_dissector_key_eth_addrs { | |
67 | /* (dst,src) must be grouped, in the same way than in ETH header */ | |
68 | unsigned char dst[ETH_ALEN]; | |
69 | unsigned char src[ETH_ALEN]; | |
70 | }; | |
71 | ||
fbff949e JP |
72 | enum flow_dissector_key_id { |
73 | FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ | |
74 | FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_addrs */ | |
75 | FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS, /* struct flow_dissector_key_addrs */ | |
76 | FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */ | |
b924933c | 77 | FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */ |
67a900cc | 78 | FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */ |
fbff949e JP |
79 | |
80 | FLOW_DISSECTOR_KEY_MAX, | |
81 | }; | |
82 | ||
83 | struct flow_dissector_key { | |
84 | enum flow_dissector_key_id key_id; | |
85 | size_t offset; /* offset of struct flow_dissector_key_* | |
86 | in target the struct */ | |
87 | }; | |
88 | ||
89 | struct flow_dissector { | |
90 | unsigned int used_keys; /* each bit repesents presence of one key id */ | |
91 | unsigned short int offset[FLOW_DISSECTOR_KEY_MAX]; | |
92 | }; | |
93 | ||
fbff949e JP |
94 | void skb_flow_dissector_init(struct flow_dissector *flow_dissector, |
95 | const struct flow_dissector_key *key, | |
96 | unsigned int key_count); | |
06635a35 JP |
97 | |
98 | bool __skb_flow_dissect(const struct sk_buff *skb, | |
99 | struct flow_dissector *flow_dissector, | |
100 | void *target_container, | |
453a940e | 101 | void *data, __be16 proto, int nhoff, int hlen); |
1bd758eb JP |
102 | |
103 | static inline bool skb_flow_dissect(const struct sk_buff *skb, | |
06635a35 JP |
104 | struct flow_dissector *flow_dissector, |
105 | void *target_container) | |
106 | { | |
107 | return __skb_flow_dissect(skb, flow_dissector, target_container, | |
108 | NULL, 0, 0, 0); | |
109 | } | |
110 | ||
111 | struct flow_keys { | |
112 | struct flow_dissector_key_addrs addrs; | |
113 | struct flow_dissector_key_ports ports; | |
114 | struct flow_dissector_key_basic basic; | |
115 | }; | |
116 | ||
117 | extern struct flow_dissector flow_keys_dissector; | |
118 | extern struct flow_dissector flow_keys_buf_dissector; | |
119 | ||
120 | static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb, | |
121 | struct flow_keys *flow) | |
122 | { | |
123 | memset(flow, 0, sizeof(*flow)); | |
124 | return __skb_flow_dissect(skb, &flow_keys_dissector, flow, | |
125 | NULL, 0, 0, 0); | |
126 | } | |
127 | ||
128 | static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow, | |
129 | void *data, __be16 proto, | |
130 | int nhoff, int hlen) | |
690e36e7 | 131 | { |
06635a35 JP |
132 | memset(flow, 0, sizeof(*flow)); |
133 | return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow, | |
134 | data, proto, nhoff, hlen); | |
690e36e7 | 135 | } |
1bd758eb | 136 | |
690e36e7 DM |
137 | __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto, |
138 | void *data, int hlen_proto); | |
1bd758eb JP |
139 | |
140 | static inline __be32 skb_flow_get_ports(const struct sk_buff *skb, | |
141 | int thoff, u8 ip_proto) | |
690e36e7 DM |
142 | { |
143 | return __skb_flow_get_ports(skb, thoff, ip_proto, NULL, 0); | |
144 | } | |
1bd758eb | 145 | |
5ed20a68 | 146 | u32 flow_hash_from_keys(struct flow_keys *keys); |
9c684b50 | 147 | void __skb_get_hash(struct sk_buff *skb); |
10b89ee4 JP |
148 | u32 skb_get_poff(const struct sk_buff *skb); |
149 | u32 __skb_get_poff(const struct sk_buff *skb, void *data, | |
150 | const struct flow_keys *keys, int hlen); | |
1bd758eb | 151 | |
2f59e1eb TH |
152 | /* struct flow_keys_digest: |
153 | * | |
154 | * This structure is used to hold a digest of the full flow keys. This is a | |
155 | * larger "hash" of a flow to allow definitively matching specific flows where | |
156 | * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so | |
157 | * that it can by used in CB of skb (see sch_choke for an example). | |
158 | */ | |
159 | #define FLOW_KEYS_DIGEST_LEN 16 | |
160 | struct flow_keys_digest { | |
161 | u8 data[FLOW_KEYS_DIGEST_LEN]; | |
162 | }; | |
163 | ||
164 | void make_flow_keys_digest(struct flow_keys_digest *digest, | |
165 | const struct flow_keys *flow); | |
166 | ||
0744dd00 | 167 | #endif |