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