sfc: support conntrack NAT offload
Subsystems (3)
cover sfc: support conntrack NAT offload
From: Edward Cree <[email protected]>
The EF100 MAE supports performing NAT (and NPT) on packets which match in
the conntrack table. This series adds that capability to the driver.
Edward Cree (2):
sfc: parse mangle actions (NAT) in conntrack entries
sfc: support offloading ct(nat) action in RHS rules
drivers/net/ethernet/sfc/mae.c | 3 +- drivers/net/ethernet/sfc/tc.c | 8 +++ drivers/net/ethernet/sfc/tc.h | 2 + drivers/net/ethernet/sfc/tc_conntrack.c | 91 ++++++++++++++++++++++++- 4 files changed, 101 insertions(+), 3 deletions(-)
PATCH 1/2 sfc: parse mangle actions (NAT) in conntrack entries
From: Edward Cree <[email protected]>
The MAE can edit either address, L4 port, or both, for either source
or destination. These can't be mixed; i.e. it can edit source addr and source port, but not (say) source addr and dest port.
--- drivers/net/ethernet/sfc/tc_conntrack.c | 91 ++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-)
drivers/net/ethernet/sfc/tc_conntrack.c +89 -2
@@ -276,10 +276,84 @@ static int efx_tc_ct_parse_match(struct efx_nic *efx, struct flow_rule *fr,return 0 ; } +/** +* struct efx_tc_ct_mangler_state - tracks which fields have been pedited +* +* @ipv4: IP source or destination addr has been set +* @tcpudp: TCP/UDP source or destination port has been set +*/ +struct efx_tc_ct_mangler_state { +u8 ipv4:1 ; +u8 tcpudp:1 ; +}; + +static int efx_tc_ct_mangle (struct efx_nic *efx,struct efx_tc_ct_entry *conn, +const struct flow_action_entry *fa, +struct efx_tc_ct_mangler_state *mung) +{ +/* Is this the first mangle we've processed for this rule? */ +bool first = !(mung->ipv4 || mung->tcpudp); +bool dnat = false; + +switch (fa->mangle.htype) { +case FLOW_ACT_MANGLE_HDR_TYPE_IP4 : +switch (fa->mangle.offset) { +case offsetof(struct iphdr , daddr): + dnat = true; + fallthrough; +case offsetof(struct iphdr , saddr): +if (fa->mangle.mask) +return -EOPNOTSUPP ; + conn->nat_ip =htonl (fa->mangle.val); + mung->ipv4 =1 ; +break ; +default : +return -EOPNOTSUPP ; + } +break ; +case FLOW_ACT_MANGLE_HDR_TYPE_TCP : +case FLOW_ACT_MANGLE_HDR_TYPE_UDP : +/* Both struct tcphdr and struct udphdr start with +* __be16 source; +* __be16 dest; +* so we can use the same code for both. +*/ +switch (fa->mangle.offset) { +case offsetof(struct tcphdr , dest): +BUILD_BUG_ON (offsetof(struct tcphdr , dest) != + offsetof(struct udphdr , dest)); + dnat = true; + fallthrough; +case offsetof(struct tcphdr , source): +BUILD_BUG_ON (offsetof(struct tcphdr , source) != + offsetof(struct udphdr , source)); +if (~fa->mangle.mask !=0xffff ) +return -EOPNOTSUPP ; + conn->l4_natport =htons (fa->mangle.val); + mung->tcpudp =1 ; +break ; +default : +return -EOPNOTSUPP ; + } +break ; +default : +return -EOPNOTSUPP ; + } +/* first mangle tells us whether this is SNAT or DNAT; +* subsequent mangles must match that +*/ +if (first) + conn->dnat = dnat; +else if (conn->dnat != dnat) +return -EOPNOTSUPP ; +return 0 ; +} +static int efx_tc_ct_replace (struct efx_tc_ct_zone *ct_zone,struct flow_cls_offload *tc) {struct flow_rule *fr =flow_cls_offload_flow_rule (tc); +struct efx_tc_ct_mangler_state mung = {};struct efx_tc_ct_entry *conn, *old;struct efx_nic *efx = ct_zone->efx;const struct flow_action_entry *fa;
@@ -326,6 +400,17 @@ static int efx_tc_ct_replace(struct efx_tc_ct_zone *ct_zone, goto release; }break ; +case FLOW_ACTION_MANGLE : +if (conn->eth_proto !=htons (ETH_P_IP )) { +netif_dbg (efx, drv, efx->net_dev, +"NAT only supported for IPv4\n" ); + rc = -EOPNOTSUPP ; + goto release; + } + rc =efx_tc_ct_mangle (efx, conn, fa, &mung); +if (rc) + goto release; +break ;default :netif_dbg (efx, drv, efx->net_dev,"Unhandled action %u for conntrack\n" , fa->id);
@@ -335,8 +420,10 @@ static int efx_tc_ct_replace(struct efx_tc_ct_zone *ct_zone, }/* fill in defaults for unmangled values */ - conn->nat_ip = conn->dnat ? conn->dst_ip : conn->src_ip; - conn->l4_natport = conn->dnat ? conn->l4_dport : conn->l4_sport; +if (!mung.ipv4) + conn->nat_ip = conn->dnat ? conn->dst_ip : conn->src_ip; +if (!mung.tcpudp) + conn->l4_natport = conn->dnat ? conn->l4_dport : conn->l4_sport; cnt =efx_tc_flower_allocate_counter (efx,EFX_TC_COUNTER_TYPE_CT );if (IS_ERR (cnt)) {
PATCH 2/2 sfc: support offloading ct(nat) action in RHS rules
In reply to [email protected]From: Edward Cree <[email protected]>
If an IP address and/or L4 port for NAPT is available from a CT match,
the MAE will perform the edits; if no CT lookup has been performed for this packet, the CT lookup did not return a match, or the matched CT entry did not include NAPT, the action will have no effect.
--- drivers/net/ethernet/sfc/mae.c | 3 ++- drivers/net/ethernet/sfc/tc.c | 8 ++++++++ drivers/net/ethernet/sfc/tc.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-)
drivers/net/ethernet/sfc/mae.c +2 -1
@@ -1291,10 +1291,11 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)size_t outlen;int rc; -MCDI_POPULATE_DWORD_4 (inbuf,MAE_ACTION_SET_ALLOC_IN_FLAGS , +MCDI_POPULATE_DWORD_5 (inbuf,MAE_ACTION_SET_ALLOC_IN_FLAGS ,MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH , act->vlan_push,MAE_ACTION_SET_ALLOC_IN_VLAN_POP , act->vlan_pop,MAE_ACTION_SET_ALLOC_IN_DECAP , act->decap, +MAE_ACTION_SET_ALLOC_IN_DO_NAT , act->do_nat,MAE_ACTION_SET_ALLOC_IN_DO_DECR_IP_TTL , act->do_ttl_dec);
drivers/net/ethernet/sfc/tc.c +8 -0
@@ -2457,6 +2457,14 @@ static int efx_tc_flower_replace(struct efx_nic *efx,NL_SET_ERR_MSG_MOD (extack,"Cannot offload tunnel decap action without tunnel device" ); rc = -EOPNOTSUPP ; goto release; +case FLOW_ACTION_CT : +if (fa->ct.action !=TCA_CT_ACT_NAT ) { + rc = -EOPNOTSUPP ; +NL_SET_ERR_MSG_FMT_MOD (extack,"Can only offload CT 'nat' action in RHS rules, not %d" , fa->ct.action); + goto release; + } + act->do_nat =1 ; +break ;default :NL_SET_ERR_MSG_FMT_MOD (extack,"Unhandled action %u" , fa->id);
drivers/net/ethernet/sfc/tc.h +2 -0
@@ -48,6 +48,7 @@ struct efx_tc_encap_action; /* see tc_encap_actions.h */* @vlan_push: the number of vlan headers to push * @vlan_pop: the number of vlan headers to pop * @decap: used to indicate a tunnel header decapsulation should take place +* @do_nat: perform NAT/NPT with values returned by conntrack match * @do_ttl_dec: used to indicate IP TTL / Hop Limit should be decremented * @deliver: used to indicate a deliver action should take place * @vlan_tci: tci fields for vlan push actions
@@ -68,6 +69,7 @@ struct efx_tc_action_set { u16 vlan_push:2; u16 vlan_pop:2; u16 decap:1; + u16 do_nat:1; u16 do_ttl_dec:1; u16 deliver:1;__be16 vlan_tci[2 ];
Quoted 9 lines · On Tue, Oct 10, 2023 at 10:51:58PM +0100, [email protected] wrote:
From: Edward Cree <[email protected]>
The EF100 MAE supports performing NAT (and NPT) on packets which match in
the conntrack table. This series adds that capability to the driver.Edward Cree (2):
sfc: parse mangle actions (NAT) in conntrack entries
sfc: support offloading ct(nat) action in RHS rules
Quoted 5 lines
drivers/net/ethernet/sfc/mae.c | 3 +- drivers/net/ethernet/sfc/tc.c | 8 +++ drivers/net/ethernet/sfc/tc.h | 2 + drivers/net/ethernet/sfc/tc_conntrack.c | 91 ++++++++++++++++++++++++- 4 files changed, 101 insertions(+), 3 deletions(-)
For series,
This series was applied to netdev/net-next.git (main) by David S. Miller <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (main) by David S. Miller <[email protected]>:
Quoted 10 lines · On Tue, 10 Oct 2023 22:51:58 +0100 you wrote:
From: Edward Cree <[email protected]>
The EF100 MAE supports performing NAT (and NPT) on packets which match in
the conntrack table. This series adds that capability to the driver.Edward Cree (2):
sfc: parse mangle actions (NAT) in conntrack entries
sfc: support offloading ct(nat) action in RHS rules[...]
Here is the summary with links:
- [net-next,1/2] sfc: parse mangle actions (NAT) in conntrack entries
https://git.kernel.org/netdev/net-next/c/38f9a08a3e6a - [net-next,2/2] sfc: support offloading ct(nat) action in RHS rules https://git.kernel.org/netdev/net-next/c/0c7fe3b3720e
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html