linux/drivers/net/ethernet/microchip/vcap/vcap_api_client.h

285 lines
8.4 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.
* Microchip VCAP API
*/
#ifndef __VCAP_API_CLIENT__
#define __VCAP_API_CLIENT__
#include <linux/types.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <net/flow_offload.h>
#include "vcap_api.h"
/* Client supplied VCAP rule key control part */
struct vcap_client_keyfield_ctrl {
struct list_head list; /* For insertion into a rule */
enum vcap_key_field key;
enum vcap_field_type type;
};
struct vcap_u1_key {
u8 value;
u8 mask;
};
struct vcap_u32_key {
u32 value;
u32 mask;
};
struct vcap_u48_key {
u8 value[6];
u8 mask[6];
};
struct vcap_u56_key {
u8 value[7];
u8 mask[7];
};
struct vcap_u64_key {
u8 value[8];
u8 mask[8];
};
struct vcap_u72_key {
u8 value[9];
u8 mask[9];
};
struct vcap_u112_key {
u8 value[14];
u8 mask[14];
};
struct vcap_u128_key {
u8 value[16];
u8 mask[16];
};
/* Client supplied VCAP rule field data */
struct vcap_client_keyfield_data {
union {
struct vcap_u1_key u1;
struct vcap_u32_key u32;
struct vcap_u48_key u48;
struct vcap_u56_key u56;
struct vcap_u64_key u64;
struct vcap_u72_key u72;
struct vcap_u112_key u112;
struct vcap_u128_key u128;
};
};
/* Client supplied VCAP rule key (value, mask) */
struct vcap_client_keyfield {
struct vcap_client_keyfield_ctrl ctrl;
struct vcap_client_keyfield_data data;
};
/* Client supplied VCAP rule action control part */
struct vcap_client_actionfield_ctrl {
struct list_head list; /* For insertion into a rule */
enum vcap_action_field action;
enum vcap_field_type type;
};
struct vcap_u1_action {
u8 value;
};
struct vcap_u32_action {
u32 value;
};
struct vcap_u48_action {
u8 value[6];
};
struct vcap_u56_action {
u8 value[7];
};
struct vcap_u64_action {
u8 value[8];
};
struct vcap_u72_action {
u8 value[9];
};
struct vcap_u112_action {
u8 value[14];
};
struct vcap_u128_action {
u8 value[16];
};
struct vcap_client_actionfield_data {
union {
struct vcap_u1_action u1;
struct vcap_u32_action u32;
struct vcap_u48_action u48;
struct vcap_u56_action u56;
struct vcap_u64_action u64;
struct vcap_u72_action u72;
struct vcap_u112_action u112;
struct vcap_u128_action u128;
};
};
struct vcap_client_actionfield {
struct vcap_client_actionfield_ctrl ctrl;
struct vcap_client_actionfield_data data;
};
enum vcap_bit {
VCAP_BIT_ANY,
VCAP_BIT_0,
VCAP_BIT_1
};
struct vcap_counter {
u32 value;
bool sticky;
};
/* Enable/Disable the VCAP instance lookups */
int vcap_enable_lookups(struct vcap_control *vctrl, struct net_device *ndev,
int from_cid, int to_cid, unsigned long cookie,
bool enable);
/* VCAP rule operations */
/* Allocate a rule and fill in the basic information */
struct vcap_rule *vcap_alloc_rule(struct vcap_control *vctrl,
struct net_device *ndev,
int vcap_chain_id,
enum vcap_user user,
u16 priority,
u32 id);
/* Free mem of a rule owned by client */
void vcap_free_rule(struct vcap_rule *rule);
/* Validate a rule before adding it to the VCAP */
int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto);
/* Add rule to a VCAP instance */
int vcap_add_rule(struct vcap_rule *rule);
/* Delete rule in a VCAP instance */
int vcap_del_rule(struct vcap_control *vctrl, struct net_device *ndev, u32 id);
/* Make a full copy of an existing rule with a new rule id */
struct vcap_rule *vcap_copy_rule(struct vcap_rule *rule);
/* Get rule from a VCAP instance */
struct vcap_rule *vcap_get_rule(struct vcap_control *vctrl, u32 id);
/* Update existing rule */
int vcap_mod_rule(struct vcap_rule *rule);
/* Update the keyset for the rule */
int vcap_set_rule_set_keyset(struct vcap_rule *rule,
enum vcap_keyfield_set keyset);
/* Update the actionset for the rule */
int vcap_set_rule_set_actionset(struct vcap_rule *rule,
enum vcap_actionfield_set actionset);
/* Set a rule counter id (for certain VCAPs only) */
void vcap_rule_set_counter_id(struct vcap_rule *rule, u32 counter_id);
/* VCAP rule field operations */
int vcap_rule_add_key_bit(struct vcap_rule *rule, enum vcap_key_field key,
enum vcap_bit val);
int vcap_rule_add_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
u32 value, u32 mask);
int vcap_rule_add_key_u48(struct vcap_rule *rule, enum vcap_key_field key,
struct vcap_u48_key *fieldval);
int vcap_rule_add_key_u72(struct vcap_rule *rule, enum vcap_key_field key,
struct vcap_u72_key *fieldval);
net: microchip: sparx5: Adding more tc flower keys for the IS2 VCAP This adds the following TC flower filter keys to Sparx5 for IS2: - ipv4_addr (sip and dip) - ipv6_addr (sip and dip) - control (IPv4 fragments) - portnum (tcp and udp port numbers) - basic (L3 and L4 protocol) - vlan (outer vlan tag info) - tcp (tcp flags) - ip (tos field) as well as an 128 bit keyfield interface on the VCAP API to set the IPv6 addresses. IS2 supports the classified VLAN information which amounts to the outer VLAN info in case of multiple tags. Here are some examples of the tc flower filter operations that are now supported for the IS2 VCAP: - IPv4 Addresses tc filter add dev eth12 ingress chain 8000000 prio 12 handle 12 \ protocol ip flower skip_sw dst_ip 1.0.1.1 src_ip 2.0.2.2 \ action trap action goto chain 81000000 - IPv6 Addresses tc filter add dev eth12 ingress chain 8000000 prio 13 handle 13 \ protocol ipv6 flower skip_sw dst_ip 1::1:1 src_ip 2::2:2 \ action trap action goto chain 81000000 - IPv4 fragments tc filter add dev eth12 ingress chain 8000000 prio 14 handle 14 \ protocol ip flower skip_sw dst_ip 3.0.3.3 src_ip 2.0.2.2 \ ip_flags frag/nofirstfrag action trap action goto chain 81000000 - TCP and UDP portnumbers tc filter add dev eth12 ingress chain 8000000 prio 21 handle 21 \ protocol ip flower skip_sw dst_ip 8.8.8.8 src_ip 2.0.2.2 \ ip_proto tcp dst_port 100 src_port 12000 action trap action goto chain 81000000 tc filter add dev eth12 ingress chain 8000000 prio 23 handle 23 \ protocol ipv6 flower skip_sw dst_ip 5::5:5 src_ip 2::2:2 \ ip_proto tcp dst_port 300 src_port 13000 action trap action goto chain 81000000 - Layer 3 and Layer 4 protocol info tc filter add dev eth12 ingress chain 8000000 prio 28 handle 28 \ protocol ipv4 flower skip_sw dst_ip 9.0.9.9 src_ip 2.0.2.2 \ ip_proto icmp action trap action goto chain 81000000 - VLAN tag info (outer tag) tc filter add dev eth12 ingress chain 8000000 prio 29 handle 29 \ protocol 802.1q flower skip_sw vlan_id 600 vlan_prio 6 \ vlan_ethtype ipv4 action trap action goto chain 81000000 tc filter add dev eth12 ingress chain 8000000 prio 31 handle 31 \ protocol 802.1q flower skip_sw vlan_id 600 vlan_prio 5 \ vlan_ethtype ipv6 action trap action goto chain 81000000 - TCP flags tc filter add dev eth12 ingress chain 8000000 prio 15 handle 15 \ protocol ip flower skip_sw dst_ip 4.0.4.4 src_ip 2.0.2.2 \ ip_proto tcp tcp_flags 0x2a/0x3f action trap action goto chain 81000000 - IP info (IPv4 TOS field) tc filter add dev eth12 ingress chain 8000000 prio 16 handle 16 \ protocol ip flower skip_sw ip_tos 0x35 dst_ip 5.0.5.5 \ src_ip 2.0.2.2 action trap action goto chain 81000000 Notes: - The "protocol all" selection is not supported yet. - The MAC address rule now needs to use non-ip and non "protocol all". Here is an example: tc filter add dev eth12 ingress chain 8000000 prio 10 handle 10 \ protocol 0xbeef flower skip_sw \ dst_mac 0a:0b:0c:0d:0e:0f \ src_mac 2:0:0:0:0:1 \ action trap action goto chain 81000000 - The VLAN rules use classified VLAN information, and to get the classification information into the frame metadata, the ingress port need to be added to a bridge with the VID and vlan filtering enabled, like this (using VID 600 and four ports eth12, eth13, eth14 and eth15): ip link add name br5 type bridge ip link set dev br5 up ip link set eth12 master br5 ip link set eth13 master br5 ip link set eth14 master br5 ip link set eth15 master br5 sysctl -w net.ipv6.conf.eth12.disable_ipv6=1 sysctl -w net.ipv6.conf.eth13.disable_ipv6=1 sysctl -w net.ipv6.conf.eth14.disable_ipv6=1 sysctl -w net.ipv6.conf.eth15.disable_ipv6=1 sysctl -w net.ipv6.conf.br5.disable_ipv6=1 ip link set dev br5 type bridge vlan_filtering 1 bridge vlan add dev eth12 vid 600 bridge vlan add dev eth13 vid 600 bridge vlan add dev eth14 vid 600 bridge vlan add dev eth15 vid 600 bridge vlan add dev br5 vid 600 self Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com> Tested-by: Casper Andersson <casper.casan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2022-11-09 12:41:10 +01:00
int vcap_rule_add_key_u128(struct vcap_rule *rule, enum vcap_key_field key,
struct vcap_u128_key *fieldval);
int vcap_rule_add_action_bit(struct vcap_rule *rule,
enum vcap_action_field action, enum vcap_bit val);
int vcap_rule_add_action_u32(struct vcap_rule *rule,
enum vcap_action_field action, u32 value);
int vcap_rule_add_action_u72(struct vcap_rule *rule, enum vcap_action_field action,
struct vcap_u72_action *fieldval);
/* Get number of rules in a vcap instance lookup chain id range */
int vcap_admin_rule_count(struct vcap_admin *admin, int cid);
/* VCAP rule counter operations */
int vcap_get_rule_count_by_cookie(struct vcap_control *vctrl,
struct vcap_counter *ctr, u64 cookie);
int vcap_rule_set_counter(struct vcap_rule *rule, struct vcap_counter *ctr);
int vcap_rule_get_counter(struct vcap_rule *rule, struct vcap_counter *ctr);
/* VCAP lookup operations */
/* Convert a chain id to a VCAP lookup index */
int vcap_chain_id_to_lookup(struct vcap_admin *admin, int cur_cid);
/* Lookup a vcap instance using chain id */
struct vcap_admin *vcap_find_admin(struct vcap_control *vctrl, int cid);
/* Find information on a key field in a rule */
const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule,
enum vcap_key_field key);
/* Find a rule id with a provided cookie */
int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie);
/* Calculate the value used for chaining VCAP rules */
int vcap_chain_offset(struct vcap_control *vctrl, int from_cid, int to_cid);
/* Is the next chain id in the following lookup, possible in another VCAP */
bool vcap_is_next_lookup(struct vcap_control *vctrl, int cur_cid, int next_cid);
/* Is this chain id the last lookup of all VCAPs */
bool vcap_is_last_chain(struct vcap_control *vctrl, int cid, bool ingress);
/* Match a list of keys against the keysets available in a vcap type */
bool vcap_rule_find_keysets(struct vcap_rule *rule,
struct vcap_keyset_list *matches);
/* Return the keyset information for the keyset */
const struct vcap_set *vcap_keyfieldset(struct vcap_control *vctrl,
enum vcap_type vt,
enum vcap_keyfield_set keyset);
/* Copy to host byte order */
void vcap_netbytes_copy(u8 *dst, u8 *src, int count);
/* Convert validation error code into tc extack error message */
void vcap_set_tc_exterr(struct flow_cls_offload *fco, struct vcap_rule *vrule);
/* Cleanup a VCAP instance */
int vcap_del_rules(struct vcap_control *vctrl, struct vcap_admin *admin);
/* Add a keyset to a keyset list */
bool vcap_keyset_list_add(struct vcap_keyset_list *keysetlist,
enum vcap_keyfield_set keyset);
/* Drop keys in a keylist and any keys that are not supported by the keyset */
int vcap_filter_rule_keys(struct vcap_rule *rule,
enum vcap_key_field keylist[], int length,
bool drop_unsupported);
/* map keyset id to a string with the keyset name */
const char *vcap_keyset_name(struct vcap_control *vctrl,
enum vcap_keyfield_set keyset);
/* map key field id to a string with the key name */
const char *vcap_keyfield_name(struct vcap_control *vctrl,
enum vcap_key_field key);
/* Modify a 32 bit key field with value and mask in the rule */
int vcap_rule_mod_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
u32 value, u32 mask);
/* Modify a 32 bit action field with value in the rule */
int vcap_rule_mod_action_u32(struct vcap_rule *rule,
enum vcap_action_field action,
u32 value);
/* Get a 32 bit key field value and mask from the rule */
int vcap_rule_get_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
u32 *value, u32 *mask);
/* Remove a key field with value and mask in the rule */
int vcap_rule_rem_key(struct vcap_rule *rule, enum vcap_key_field key);
/* Select the keyset from the list that results in the smallest rule size */
enum vcap_keyfield_set
vcap_select_min_rule_keyset(struct vcap_control *vctrl, enum vcap_type vtype,
struct vcap_keyset_list *kslist);
struct vcap_client_actionfield *
vcap_find_actionfield(struct vcap_rule *rule, enum vcap_action_field act);
#endif /* __VCAP_API_CLIENT__ */