sfc: add decrement ttl by offloading set ipv4 ttl actions
authorPieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
Thu, 24 Aug 2023 11:28:39 +0000 (12:28 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 27 Aug 2023 05:56:54 +0000 (06:56 +0100)
Offload pedit set ipv4 ttl field, where the ttl field has already been
matched and the new value is one less, by translating it to a decrement.

Co-developed-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/mae.c
drivers/net/ethernet/sfc/tc.c
drivers/net/ethernet/sfc/tc.h

index a7ad7ab..c3e2b4a 100644 (file)
@@ -1291,10 +1291,12 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)
        size_t outlen;
        int rc;
 
-       MCDI_POPULATE_DWORD_3(inbuf, MAE_ACTION_SET_ALLOC_IN_FLAGS,
+       MCDI_POPULATE_DWORD_4(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_DECAP, act->decap,
+                             MAE_ACTION_SET_ALLOC_IN_DO_DECR_IP_TTL,
+                             act->do_ttl_dec);
 
        if (act->src_mac)
                MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID,
index b9d7c4b..57bdd56 100644 (file)
@@ -31,6 +31,7 @@ enum efx_encap_type efx_tc_indr_netdev_type(struct net_device *net_dev)
        return EFX_ENCAP_TYPE_NONE;
 }
 
+#define EFX_TC_HDR_TYPE_TTL_MASK ((u32)0xff)
 #define EFX_EFV_PF     NULL
 /* Look up the representor information (efv) for a device.
  * May return NULL for the PF (us), or an error pointer for a device that
@@ -757,6 +758,7 @@ static const char *efx_tc_encap_type_name(enum efx_encap_type typ)
 /* For details of action order constraints refer to SF-123102-TC-1ยง12.6.1 */
 enum efx_tc_action_order {
        EFX_TC_AO_DECAP,
+       EFX_TC_AO_DEC_TTL,
        EFX_TC_AO_PEDIT_MAC_ADDRS,
        EFX_TC_AO_VLAN_POP,
        EFX_TC_AO_VLAN_PUSH,
@@ -777,6 +779,10 @@ static bool efx_tc_flower_action_order_ok(const struct efx_tc_action_set *act,
                 */
                if (act->dst_mac || act->src_mac)
                        return false;
+
+               /* Decrementing ttl must not happen before DECAP */
+               if (act->do_ttl_dec)
+                       return false;
                fallthrough;
        case EFX_TC_AO_VLAN_POP:
                if (act->vlan_pop >= 2)
@@ -803,6 +809,10 @@ static bool efx_tc_flower_action_order_ok(const struct efx_tc_action_set *act,
                fallthrough;
        case EFX_TC_AO_DELIVER:
                return !act->deliver;
+       case EFX_TC_AO_DEC_TTL:
+               if (act->encap_md)
+                       return false;
+               return !act->do_ttl_dec;
        default:
                /* Bad caller.  Whatever they wanted to do, say they can't. */
                WARN_ON_ONCE(1);
@@ -1049,6 +1059,7 @@ static int efx_tc_complete_mac_mangle(struct efx_nic *efx,
  * @fa:                FLOW_ACTION_MANGLE action metadata
  * @mung:      accumulator for partial mangles
  * @extack:    netlink extended ack for reporting errors
+ * @match:     original match used along with the mangle action
  *
  * Identify the fields written by a FLOW_ACTION_MANGLE, and record
  * the partial mangle state in @mung.  If this mangle completes an
@@ -1059,10 +1070,12 @@ static int efx_tc_complete_mac_mangle(struct efx_nic *efx,
 static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
                         const struct flow_action_entry *fa,
                         struct efx_tc_mangler_state *mung,
-                        struct netlink_ext_ack *extack)
+                        struct netlink_ext_ack *extack,
+                        struct efx_tc_match *match)
 {
        __le32 mac32;
        __le16 mac16;
+       u8 tr_ttl;
 
        switch (fa->mangle.htype) {
        case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
@@ -1119,6 +1132,64 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
                        return -EOPNOTSUPP;
                }
                break;
+       case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
+               switch (fa->mangle.offset) {
+               case offsetof(struct iphdr, ttl):
+                       /* we currently only support pedit IP4 when it applies
+                        * to TTL and then only when it can be achieved with a
+                        * decrement ttl action
+                        */
+
+                       /* check that pedit applies to ttl only */
+                       if (fa->mangle.mask != ~EFX_TC_HDR_TYPE_TTL_MASK) {
+                               NL_SET_ERR_MSG_FMT_MOD(extack,
+                                                      "Unsupported: mask (%#x) out of range, only support mangle action on ipv4.ttl",
+                                                      fa->mangle.mask);
+                               return -EOPNOTSUPP;
+                       }
+
+                       /* we can only convert to a dec ttl when we have an
+                        * exact match on the ttl field
+                        */
+                       if (match->mask.ip_ttl != U8_MAX) {
+                               NL_SET_ERR_MSG_FMT_MOD(extack,
+                                                      "Unsupported: only support mangle ipv4.ttl when we have an exact match on ttl, mask used for match (%#x)",
+                                                      match->mask.ip_ttl);
+                               return -EOPNOTSUPP;
+                       }
+
+                       /* check that we don't try to decrement 0, which equates
+                        * to setting the ttl to 0xff
+                        */
+                       if (match->value.ip_ttl == 0) {
+                               NL_SET_ERR_MSG_MOD(extack,
+                                                  "Unsupported: we cannot decrement ttl past 0");
+                               return -EOPNOTSUPP;
+                       }
+
+                       /* check that we do not decrement ttl twice */
+                       if (!efx_tc_flower_action_order_ok(act,
+                                                          EFX_TC_AO_DEC_TTL)) {
+                               NL_SET_ERR_MSG_MOD(extack,
+                                                  "Unsupported: multiple dec ttl");
+                               return -EOPNOTSUPP;
+                       }
+
+                       /* check pedit can be achieved with decrement action */
+                       tr_ttl = match->value.ip_ttl - 1;
+                       if ((fa->mangle.val & EFX_TC_HDR_TYPE_TTL_MASK) == tr_ttl) {
+                               act->do_ttl_dec = 1;
+                               return 0;
+                       }
+
+                       fallthrough;
+               default:
+                       NL_SET_ERR_MSG_FMT_MOD(extack,
+                                              "Unsupported: only support mangle on the ttl field (offset is %u)",
+                                              fa->mangle.offset);
+                       return -EOPNOTSUPP;
+               }
+               break;
        default:
                NL_SET_ERR_MSG_FMT_MOD(extack, "Unhandled mangle htype %u for action rule",
                                       fa->mangle.htype);
@@ -1885,7 +1956,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
                        act->vlan_push++;
                        break;
                case FLOW_ACTION_MANGLE:
-                       rc = efx_tc_mangle(efx, act, fa, &mung, extack);
+                       rc = efx_tc_mangle(efx, act, fa, &mung, extack, &match);
                        if (rc < 0)
                                goto release;
                        break;
index 7b6a6a3..4dd2c37 100644 (file)
@@ -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_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
  * @vlan_proto: ethernet types for vlan push actions
@@ -67,6 +68,7 @@ struct efx_tc_action_set {
        u16 vlan_push:2;
        u16 vlan_pop:2;
        u16 decap:1;
+       u16 do_ttl_dec:1;
        u16 deliver:1;
        __be16 vlan_tci[2];
        __be16 vlan_proto[2];