blob: 36fdb85c974dd299b78161a2faa21091fda8aae1 [file] [log] [blame]
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +01001#ifndef _NET_FLOW_OFFLOAD_H
2#define _NET_FLOW_OFFLOAD_H
3
Edward Creefa859992019-05-31 22:47:21 +01004#include <linux/kernel.h>
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +01005#include <net/flow_dissector.h>
6
7struct flow_match {
8 struct flow_dissector *dissector;
9 void *mask;
10 void *key;
11};
12
13struct flow_match_basic {
14 struct flow_dissector_key_basic *key, *mask;
15};
16
17struct flow_match_control {
18 struct flow_dissector_key_control *key, *mask;
19};
20
21struct flow_match_eth_addrs {
22 struct flow_dissector_key_eth_addrs *key, *mask;
23};
24
25struct flow_match_vlan {
26 struct flow_dissector_key_vlan *key, *mask;
27};
28
29struct flow_match_ipv4_addrs {
30 struct flow_dissector_key_ipv4_addrs *key, *mask;
31};
32
33struct flow_match_ipv6_addrs {
34 struct flow_dissector_key_ipv6_addrs *key, *mask;
35};
36
37struct flow_match_ip {
38 struct flow_dissector_key_ip *key, *mask;
39};
40
41struct flow_match_ports {
42 struct flow_dissector_key_ports *key, *mask;
43};
44
45struct flow_match_icmp {
46 struct flow_dissector_key_icmp *key, *mask;
47};
48
49struct flow_match_tcp {
50 struct flow_dissector_key_tcp *key, *mask;
51};
52
53struct flow_match_mpls {
54 struct flow_dissector_key_mpls *key, *mask;
55};
56
57struct flow_match_enc_keyid {
58 struct flow_dissector_key_keyid *key, *mask;
59};
60
61struct flow_match_enc_opts {
62 struct flow_dissector_key_enc_opts *key, *mask;
63};
64
65struct flow_rule;
66
67void flow_rule_match_basic(const struct flow_rule *rule,
68 struct flow_match_basic *out);
69void flow_rule_match_control(const struct flow_rule *rule,
70 struct flow_match_control *out);
71void flow_rule_match_eth_addrs(const struct flow_rule *rule,
72 struct flow_match_eth_addrs *out);
73void flow_rule_match_vlan(const struct flow_rule *rule,
74 struct flow_match_vlan *out);
Edward Creebae9ed62019-05-14 21:18:12 +010075void flow_rule_match_cvlan(const struct flow_rule *rule,
76 struct flow_match_vlan *out);
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +010077void flow_rule_match_ipv4_addrs(const struct flow_rule *rule,
78 struct flow_match_ipv4_addrs *out);
79void flow_rule_match_ipv6_addrs(const struct flow_rule *rule,
80 struct flow_match_ipv6_addrs *out);
81void flow_rule_match_ip(const struct flow_rule *rule,
82 struct flow_match_ip *out);
83void flow_rule_match_ports(const struct flow_rule *rule,
84 struct flow_match_ports *out);
85void flow_rule_match_tcp(const struct flow_rule *rule,
86 struct flow_match_tcp *out);
87void flow_rule_match_icmp(const struct flow_rule *rule,
88 struct flow_match_icmp *out);
89void flow_rule_match_mpls(const struct flow_rule *rule,
90 struct flow_match_mpls *out);
91void flow_rule_match_enc_control(const struct flow_rule *rule,
92 struct flow_match_control *out);
93void flow_rule_match_enc_ipv4_addrs(const struct flow_rule *rule,
94 struct flow_match_ipv4_addrs *out);
95void flow_rule_match_enc_ipv6_addrs(const struct flow_rule *rule,
96 struct flow_match_ipv6_addrs *out);
97void flow_rule_match_enc_ip(const struct flow_rule *rule,
98 struct flow_match_ip *out);
99void flow_rule_match_enc_ports(const struct flow_rule *rule,
100 struct flow_match_ports *out);
101void flow_rule_match_enc_keyid(const struct flow_rule *rule,
102 struct flow_match_enc_keyid *out);
103void flow_rule_match_enc_opts(const struct flow_rule *rule,
104 struct flow_match_enc_opts *out);
105
Pablo Neira Ayusoe3ab7862019-02-02 12:50:45 +0100106enum flow_action_id {
107 FLOW_ACTION_ACCEPT = 0,
108 FLOW_ACTION_DROP,
109 FLOW_ACTION_TRAP,
110 FLOW_ACTION_GOTO,
111 FLOW_ACTION_REDIRECT,
112 FLOW_ACTION_MIRRED,
113 FLOW_ACTION_VLAN_PUSH,
114 FLOW_ACTION_VLAN_POP,
115 FLOW_ACTION_VLAN_MANGLE,
116 FLOW_ACTION_TUNNEL_ENCAP,
117 FLOW_ACTION_TUNNEL_DECAP,
118 FLOW_ACTION_MANGLE,
119 FLOW_ACTION_ADD,
120 FLOW_ACTION_CSUM,
121 FLOW_ACTION_MARK,
Pablo Neira Ayuso8bec2832019-02-02 12:50:50 +0100122 FLOW_ACTION_WAKE,
123 FLOW_ACTION_QUEUE,
Pieter Jansen van Vuurena7a7be62019-05-04 04:46:16 -0700124 FLOW_ACTION_SAMPLE,
Pieter Jansen van Vuuren8c8cfc62019-05-04 04:46:22 -0700125 FLOW_ACTION_POLICE,
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +0100126};
127
Pablo Neira Ayusoe3ab7862019-02-02 12:50:45 +0100128/* This is mirroring enum pedit_header_type definition for easy mapping between
129 * tc pedit action. Legacy TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK is mapped to
130 * FLOW_ACT_MANGLE_UNSPEC, which is supported by no driver.
131 */
132enum flow_action_mangle_base {
133 FLOW_ACT_MANGLE_UNSPEC = 0,
134 FLOW_ACT_MANGLE_HDR_TYPE_ETH,
135 FLOW_ACT_MANGLE_HDR_TYPE_IP4,
136 FLOW_ACT_MANGLE_HDR_TYPE_IP6,
137 FLOW_ACT_MANGLE_HDR_TYPE_TCP,
138 FLOW_ACT_MANGLE_HDR_TYPE_UDP,
139};
140
141struct flow_action_entry {
142 enum flow_action_id id;
143 union {
144 u32 chain_index; /* FLOW_ACTION_GOTO */
145 struct net_device *dev; /* FLOW_ACTION_REDIRECT */
146 struct { /* FLOW_ACTION_VLAN */
147 u16 vid;
148 __be16 proto;
149 u8 prio;
150 } vlan;
151 struct { /* FLOW_ACTION_PACKET_EDIT */
152 enum flow_action_mangle_base htype;
153 u32 offset;
154 u32 mask;
155 u32 val;
156 } mangle;
157 const struct ip_tunnel_info *tunnel; /* FLOW_ACTION_TUNNEL_ENCAP */
158 u32 csum_flags; /* FLOW_ACTION_CSUM */
159 u32 mark; /* FLOW_ACTION_MARK */
Pablo Neira Ayuso8bec2832019-02-02 12:50:50 +0100160 struct { /* FLOW_ACTION_QUEUE */
161 u32 ctx;
162 u32 index;
163 u8 vf;
164 } queue;
Pieter Jansen van Vuurena7a7be62019-05-04 04:46:16 -0700165 struct { /* FLOW_ACTION_SAMPLE */
166 struct psample_group *psample_group;
167 u32 rate;
168 u32 trunc_size;
169 bool truncate;
170 } sample;
Pieter Jansen van Vuuren8c8cfc62019-05-04 04:46:22 -0700171 struct { /* FLOW_ACTION_POLICE */
172 s64 burst;
173 u64 rate_bytes_ps;
174 } police;
Pablo Neira Ayusoe3ab7862019-02-02 12:50:45 +0100175 };
176};
177
178struct flow_action {
179 unsigned int num_entries;
180 struct flow_action_entry entries[0];
181};
182
183static inline bool flow_action_has_entries(const struct flow_action *action)
184{
185 return action->num_entries;
186}
187
Pieter Jansen van Vuurenab79af32019-05-04 04:46:18 -0700188/**
189 * flow_action_has_one_action() - check if exactly one action is present
190 * @action: tc filter flow offload action
191 *
192 * Returns true if exactly one action is present.
193 */
194static inline bool flow_offload_has_one_action(const struct flow_action *action)
195{
196 return action->num_entries == 1;
197}
198
Pablo Neira Ayusoe3ab7862019-02-02 12:50:45 +0100199#define flow_action_for_each(__i, __act, __actions) \
Eli Britstein6663cf82019-02-11 09:52:59 +0200200 for (__i = 0, __act = &(__actions)->entries[0]; __i < (__actions)->num_entries; __act = &(__actions)->entries[++__i])
Pablo Neira Ayusoe3ab7862019-02-02 12:50:45 +0100201
202struct flow_rule {
203 struct flow_match match;
204 struct flow_action action;
205};
206
207struct flow_rule *flow_rule_alloc(unsigned int num_actions);
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +0100208
209static inline bool flow_rule_match_key(const struct flow_rule *rule,
210 enum flow_dissector_key_id key)
211{
212 return dissector_uses_key(rule->match.dissector, key);
213}
214
Pablo Neira Ayuso3b1903e2019-02-02 12:50:47 +0100215struct flow_stats {
216 u64 pkts;
217 u64 bytes;
218 u64 lastused;
219};
220
221static inline void flow_stats_update(struct flow_stats *flow_stats,
222 u64 bytes, u64 pkts, u64 lastused)
223{
John Hurley9f9dc492019-02-13 00:23:52 +0000224 flow_stats->pkts += pkts;
225 flow_stats->bytes += bytes;
226 flow_stats->lastused = max_t(u64, flow_stats->lastused, lastused);
Pablo Neira Ayuso3b1903e2019-02-02 12:50:47 +0100227}
228
Pablo Neira Ayuso8f256622019-02-02 12:50:43 +0100229#endif /* _NET_FLOW_OFFLOAD_H */