[PATCH net-next 4/9] net: microchip: vcap: expose helpers in vcap api and update debugfs
Jens Emil Schulz Østergaard
jensemil.schulzostergaard at microchip.com
Fri Jun 12 05:37:13 PDT 2026
Add new helpers to the vcap client api, in preparation for L3 routing
functionality:
- vcap_val_add_rule(): wraps vcap_val_rule() + vcap_add_rule().
- vcap_rule_mod_action_bit(): modify a bit-typed action on an existing
rule.
Rename VCAP_CID_PREROUTING to VCAP_CID_PREROUTING_L0 and add
VCAP_USER_L3, both needed by the upcoming LPM VCAP user.
Extend the debugfs display to handle the new IP4_XIP and IP6_XIP key
fields.
Fix a latent undefined-behaviour bug in the debugfs action-field
printer. The old mask expression (1 << width) - 1 is UB when width is
32. The bug is unreachable before this series, since no existing field
in any client hits this, but the LPM VCAP introduces VCAP_AF_MAC_LSB
which is 32 bit wide.
Reviewed-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Signed-off-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard at microchip.com>
---
drivers/net/ethernet/microchip/vcap/vcap_api.c | 25 ++++++++++++++++++++++
drivers/net/ethernet/microchip/vcap/vcap_api.h | 4 +++-
.../net/ethernet/microchip/vcap/vcap_api_client.h | 6 ++++++
.../net/ethernet/microchip/vcap/vcap_api_debugfs.c | 13 ++++++++---
4 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c
index 30700648672f..0905e4f192a0 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api.c
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c
@@ -2379,6 +2379,19 @@ int vcap_add_rule(struct vcap_rule *rule)
}
EXPORT_SYMBOL_GPL(vcap_add_rule);
+/* Validate and add rule to a VCAP instance */
+int vcap_val_add_rule(struct vcap_rule *rule, u16 l3_proto)
+{
+ int err;
+
+ err = vcap_val_rule(rule, l3_proto);
+ if (err)
+ return err;
+
+ return vcap_add_rule(rule);
+}
+EXPORT_SYMBOL_GPL(vcap_val_add_rule);
+
/* Allocate a new rule with the provided arguments */
struct vcap_rule *vcap_alloc_rule(struct vcap_control *vctrl,
struct net_device *ndev, int vcap_chain_id,
@@ -3547,6 +3560,18 @@ int vcap_rule_mod_action_u32(struct vcap_rule *rule,
}
EXPORT_SYMBOL_GPL(vcap_rule_mod_action_u32);
+/* Modify a bit action with value in the rule */
+int vcap_rule_mod_action_bit(struct vcap_rule *rule,
+ enum vcap_action_field action,
+ enum vcap_bit val)
+{
+ struct vcap_client_actionfield_data data;
+
+ vcap_rule_set_action_bitsize(&data.u1, val);
+ return vcap_rule_mod_action(rule, action, VCAP_FIELD_BIT, &data);
+}
+EXPORT_SYMBOL_GPL(vcap_rule_mod_action_bit);
+
/* 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,
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.h b/drivers/net/ethernet/microchip/vcap/vcap_api.h
index 6069ad95c27e..e197e7257560 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api.h
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api.h
@@ -22,7 +22,7 @@
#define VCAP_CID_INGRESS_L5 1500000 /* Ingress Stage 1 Lookup 5 */
#define VCAP_CID_PREROUTING_IPV6 3000000 /* Prerouting Stage */
-#define VCAP_CID_PREROUTING 6000000 /* Prerouting Stage */
+#define VCAP_CID_PREROUTING_L0 6000000 /* Prerouting Stage Lookup 0 */
#define VCAP_CID_INGRESS_STAGE2_L0 8000000 /* Ingress Stage 2 Lookup 0 */
#define VCAP_CID_INGRESS_STAGE2_L1 8100000 /* Ingress Stage 2 Lookup 1 */
@@ -41,7 +41,9 @@ enum vcap_user {
VCAP_USER_MRP,
VCAP_USER_CFM,
VCAP_USER_VLAN,
+ VCAP_USER_L3,
VCAP_USER_QOS,
+ /* permanent enabled users above here */
VCAP_USER_VCAP_UTIL,
VCAP_USER_TC,
VCAP_USER_TC_EXTRA,
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
index cdf79e17ca54..3f17e1e76b7d 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
@@ -167,6 +167,8 @@ void vcap_free_rule(struct vcap_rule *rule);
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);
+/* Validate and add rule to a VCAP instance */
+int vcap_val_add_rule(struct vcap_rule *rule, u16 l3_proto);
/* 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 */
@@ -266,6 +268,10 @@ int vcap_rule_mod_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
int vcap_rule_mod_action_u32(struct vcap_rule *rule,
enum vcap_action_field action,
u32 value);
+/* Modify a bit action with value in the rule */
+int vcap_rule_mod_action_bit(struct vcap_rule *rule,
+ enum vcap_action_field action,
+ enum vcap_bit val);
/* 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,
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
index 59bfbda29bb3..56464ece8e6b 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
@@ -40,7 +40,8 @@ static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl,
value = (u8 *)(&data->u32.value);
mask = (u8 *)(&data->u32.mask);
- if (key == VCAP_KF_L3_IP4_SIP || key == VCAP_KF_L3_IP4_DIP) {
+ if (key == VCAP_KF_L3_IP4_SIP || key == VCAP_KF_L3_IP4_DIP ||
+ key == VCAP_KF_IP4_XIP) {
out->prf(out->dst, "%pI4h/%pI4h", &data->u32.value,
&data->u32.mask);
} else if (key == VCAP_KF_ETYPE ||
@@ -88,7 +89,8 @@ static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl,
case VCAP_FIELD_U128:
value = data->u128.value;
mask = data->u128.mask;
- if (key == VCAP_KF_L3_IP6_SIP || key == VCAP_KF_L3_IP6_DIP) {
+ if (key == VCAP_KF_L3_IP6_SIP || key == VCAP_KF_L3_IP6_DIP ||
+ key == VCAP_KF_IP6_XIP) {
u8 nvalue[16], nmask[16];
vcap_netbytes_copy(nvalue, data->u128.value,
@@ -133,7 +135,12 @@ vcap_debugfs_show_rule_actionfield(struct vcap_control *vctrl,
out->prf(out->dst, "%d", value[0]);
break;
case VCAP_FIELD_U32:
- fmsk = (1 << actionfield[action].width) - 1;
+ if (action == VCAP_AF_MAC_LSB || action == VCAP_AF_MAC_MSB) {
+ hex = true;
+ break;
+ }
+ fmsk = actionfield[action].width ?
+ GENMASK(actionfield[action].width - 1, 0) : 0;
val = *(u32 *)value;
out->prf(out->dst, "%u", val & fmsk);
break;
--
2.52.0
More information about the linux-arm-kernel
mailing list