1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ |
2 | /* Copyright (c) 2020-2021 Marvell International Ltd. All rights reserved. */ |
3 | |
4 | #ifndef _PRESTERA_ACL_H_ |
5 | #define _PRESTERA_ACL_H_ |
6 | |
7 | #include <linux/types.h> |
8 | #include "prestera_counter.h" |
9 | |
10 | #define PRESTERA_ACL_KEYMASK_PCL_ID 0x3FF |
11 | #define PRESTERA_ACL_KEYMASK_PCL_ID_USER \ |
12 | (PRESTERA_ACL_KEYMASK_PCL_ID & 0x00FF) |
13 | #define PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN \ |
14 | (PRESTERA_ACL_KEYMASK_PCL_ID & 0xFF00) |
15 | #define PRESTERA_ACL_CHAIN_MASK \ |
16 | (PRESTERA_ACL_KEYMASK_PCL_ID >> 8) |
17 | |
18 | #define PRESTERA_ACL_PCL_ID_MAKE(uid, chain_id) \ |
19 | (((uid) & PRESTERA_ACL_KEYMASK_PCL_ID_USER) | \ |
20 | (((chain_id) << 8) & PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN)) |
21 | |
22 | #define rule_match_set_n(match_p, type, val_p, size) \ |
23 | memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type], \ |
24 | val_p, size) |
25 | #define rule_match_set(match_p, type, val) \ |
26 | memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type], \ |
27 | &(val), sizeof(val)) |
28 | |
29 | enum prestera_acl_match_type { |
30 | PRESTERA_ACL_RULE_MATCH_TYPE_PCL_ID, |
31 | PRESTERA_ACL_RULE_MATCH_TYPE_ETH_TYPE, |
32 | PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_0, |
33 | PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_1, |
34 | PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_0, |
35 | PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_1, |
36 | PRESTERA_ACL_RULE_MATCH_TYPE_IP_PROTO, |
37 | PRESTERA_ACL_RULE_MATCH_TYPE_SYS_PORT, |
38 | PRESTERA_ACL_RULE_MATCH_TYPE_SYS_DEV, |
39 | PRESTERA_ACL_RULE_MATCH_TYPE_IP_SRC, |
40 | PRESTERA_ACL_RULE_MATCH_TYPE_IP_DST, |
41 | PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_SRC, |
42 | PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_DST, |
43 | PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_SRC, |
44 | PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_DST, |
45 | PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_ID, |
46 | PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_TPID, |
47 | PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_TYPE, |
48 | PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_CODE, |
49 | |
50 | __PRESTERA_ACL_RULE_MATCH_TYPE_MAX |
51 | }; |
52 | |
53 | enum prestera_acl_rule_action { |
54 | PRESTERA_ACL_RULE_ACTION_ACCEPT = 0, |
55 | PRESTERA_ACL_RULE_ACTION_DROP = 1, |
56 | PRESTERA_ACL_RULE_ACTION_TRAP = 2, |
57 | PRESTERA_ACL_RULE_ACTION_JUMP = 5, |
58 | PRESTERA_ACL_RULE_ACTION_COUNT = 7, |
59 | PRESTERA_ACL_RULE_ACTION_POLICE = 8, |
60 | |
61 | PRESTERA_ACL_RULE_ACTION_MAX |
62 | }; |
63 | |
64 | enum { |
65 | PRESTERA_ACL_IFACE_TYPE_PORT, |
66 | PRESTERA_ACL_IFACE_TYPE_INDEX |
67 | }; |
68 | |
69 | struct prestera_acl_match { |
70 | __be32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; |
71 | __be32 mask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; |
72 | }; |
73 | |
74 | struct prestera_acl_action_jump { |
75 | u32 index; |
76 | }; |
77 | |
78 | struct prestera_acl_action_police { |
79 | u32 id; |
80 | }; |
81 | |
82 | struct prestera_acl_action_count { |
83 | u32 id; |
84 | }; |
85 | |
86 | struct prestera_acl_rule_entry_key { |
87 | u32 prio; |
88 | struct prestera_acl_match match; |
89 | }; |
90 | |
91 | struct prestera_acl_hw_action_info { |
92 | enum prestera_acl_rule_action id; |
93 | union { |
94 | struct prestera_acl_action_police police; |
95 | struct prestera_acl_action_count count; |
96 | struct prestera_acl_action_jump jump; |
97 | }; |
98 | }; |
99 | |
100 | /* This struct (arg) used only to be passed as parameter for |
101 | * acl_rule_entry_create. Must be flat. Can contain object keys, which will be |
102 | * resolved to object links, before saving to acl_rule_entry struct |
103 | */ |
104 | struct prestera_acl_rule_entry_arg { |
105 | u32 vtcam_id; |
106 | struct { |
107 | struct { |
108 | u8 valid:1; |
109 | } accept, drop, trap; |
110 | struct { |
111 | struct prestera_acl_action_jump i; |
112 | u8 valid:1; |
113 | } jump; |
114 | struct { |
115 | u8 valid:1; |
116 | u64 rate; |
117 | u64 burst; |
118 | bool ingress; |
119 | } police; |
120 | struct { |
121 | u8 valid:1; |
122 | u32 client; |
123 | } count; |
124 | }; |
125 | }; |
126 | |
127 | struct prestera_acl_rule { |
128 | struct rhash_head ht_node; /* Member of acl HT */ |
129 | struct list_head list; |
130 | struct prestera_acl_ruleset *ruleset; |
131 | struct prestera_acl_ruleset *jump_ruleset; |
132 | unsigned long cookie; |
133 | u32 chain_index; |
134 | u32 priority; |
135 | struct prestera_acl_rule_entry_key re_key; |
136 | struct prestera_acl_rule_entry_arg re_arg; |
137 | struct prestera_acl_rule_entry *re; |
138 | }; |
139 | |
140 | struct prestera_acl_iface { |
141 | union { |
142 | struct prestera_port *port; |
143 | u32 index; |
144 | }; |
145 | u8 type; |
146 | }; |
147 | |
148 | struct prestera_acl; |
149 | struct prestera_switch; |
150 | struct prestera_flow_block; |
151 | |
152 | int prestera_acl_init(struct prestera_switch *sw); |
153 | void prestera_acl_fini(struct prestera_switch *sw); |
154 | |
155 | struct prestera_acl_rule * |
156 | prestera_acl_rule_create(struct prestera_acl_ruleset *ruleset, |
157 | unsigned long cookie, u32 chain_index); |
158 | void prestera_acl_rule_priority_set(struct prestera_acl_rule *rule, |
159 | u32 priority); |
160 | void prestera_acl_rule_destroy(struct prestera_acl_rule *rule); |
161 | struct prestera_acl_rule * |
162 | prestera_acl_rule_lookup(struct prestera_acl_ruleset *ruleset, |
163 | unsigned long cookie); |
164 | int prestera_acl_rule_add(struct prestera_switch *sw, |
165 | struct prestera_acl_rule *rule); |
166 | void prestera_acl_rule_del(struct prestera_switch *sw, |
167 | struct prestera_acl_rule *rule); |
168 | int prestera_acl_rule_get_stats(struct prestera_acl *acl, |
169 | struct prestera_acl_rule *rule, |
170 | u64 *packets, u64 *bytes, u64 *last_use); |
171 | struct prestera_acl_rule_entry * |
172 | prestera_acl_rule_entry_find(struct prestera_acl *acl, |
173 | struct prestera_acl_rule_entry_key *key); |
174 | void prestera_acl_rule_entry_destroy(struct prestera_acl *acl, |
175 | struct prestera_acl_rule_entry *e); |
176 | struct prestera_acl_rule_entry * |
177 | prestera_acl_rule_entry_create(struct prestera_acl *acl, |
178 | struct prestera_acl_rule_entry_key *key, |
179 | struct prestera_acl_rule_entry_arg *arg); |
180 | struct prestera_acl_ruleset * |
181 | prestera_acl_ruleset_get(struct prestera_acl *acl, |
182 | struct prestera_flow_block *block, |
183 | u32 chain_index); |
184 | struct prestera_acl_ruleset * |
185 | prestera_acl_ruleset_lookup(struct prestera_acl *acl, |
186 | struct prestera_flow_block *block, |
187 | u32 chain_index); |
188 | int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset, |
189 | void *keymask); |
190 | bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset); |
191 | int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset); |
192 | void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset); |
193 | int prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset, |
194 | struct prestera_port *port); |
195 | int prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset, |
196 | struct prestera_port *port); |
197 | u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset); |
198 | void prestera_acl_ruleset_prio_get(struct prestera_acl_ruleset *ruleset, |
199 | u32 *prio_min, u32 *prio_max); |
200 | void |
201 | prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule, |
202 | u16 pcl_id); |
203 | |
204 | int prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup, u8 dir, |
205 | void *keymask, u32 *vtcam_id); |
206 | int prestera_acl_vtcam_id_put(struct prestera_acl *acl, u32 vtcam_id); |
207 | int prestera_acl_chain_to_client(u32 chain_index, bool ingress, u32 *client); |
208 | |
209 | #endif /* _PRESTERA_ACL_H_ */ |
210 | |