Skip to content

Commit c0b1bd9

Browse files
pjvuurendavem330
authored andcommitted
nfp: add set ipv4 header action flower offload
Previously we did not have offloading support for set IPv4 actions. This patch enables TC flower offload of set IPv4 src and dst address actions. Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent da83d8f commit c0b1bd9

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

drivers/net/ethernet/netronome/nfp/flower/action.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,54 @@ nfp_fl_set_eth(const struct tc_action *action, int idx, u32 off,
265265
return 0;
266266
}
267267

268+
static int
269+
nfp_fl_set_ip4(const struct tc_action *action, int idx, u32 off,
270+
struct nfp_fl_set_ip4_addrs *set_ip_addr)
271+
{
272+
u16 tmp_set_ipv4_op;
273+
__be32 exact, mask;
274+
275+
/* We are expecting tcf_pedit to return a big endian value */
276+
mask = (__force __be32)~tcf_pedit_mask(action, idx);
277+
exact = (__force __be32)tcf_pedit_val(action, idx);
278+
279+
if (exact & ~mask)
280+
return -EOPNOTSUPP;
281+
282+
switch (off) {
283+
case offsetof(struct iphdr, daddr):
284+
set_ip_addr->ipv4_dst_mask = mask;
285+
set_ip_addr->ipv4_dst = exact;
286+
break;
287+
case offsetof(struct iphdr, saddr):
288+
set_ip_addr->ipv4_src_mask = mask;
289+
set_ip_addr->ipv4_src = exact;
290+
break;
291+
default:
292+
return -EOPNOTSUPP;
293+
}
294+
295+
set_ip_addr->reserved = cpu_to_be16(0);
296+
tmp_set_ipv4_op = FIELD_PREP(NFP_FL_ACT_LEN_LW,
297+
sizeof(*set_ip_addr) >> NFP_FL_LW_SIZ) |
298+
FIELD_PREP(NFP_FL_ACT_JMP_ID,
299+
NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS);
300+
set_ip_addr->a_op = cpu_to_be16(tmp_set_ipv4_op);
301+
302+
return 0;
303+
}
304+
268305
static int
269306
nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
270307
{
308+
struct nfp_fl_set_ip4_addrs set_ip_addr;
271309
struct nfp_fl_set_eth set_eth;
272310
enum pedit_header_type htype;
273311
int idx, nkeys, err;
274312
size_t act_size;
275313
u32 offset, cmd;
276314

315+
memset(&set_ip_addr, 0, sizeof(set_ip_addr));
277316
memset(&set_eth, 0, sizeof(set_eth));
278317
nkeys = tcf_pedit_nkeys(action);
279318

@@ -289,6 +328,9 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
289328
case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH:
290329
err = nfp_fl_set_eth(action, idx, offset, &set_eth);
291330
break;
331+
case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4:
332+
err = nfp_fl_set_ip4(action, idx, offset, &set_ip_addr);
333+
break;
292334
default:
293335
return -EOPNOTSUPP;
294336
}
@@ -300,6 +342,10 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
300342
act_size = sizeof(set_eth);
301343
memcpy(nfp_action, &set_eth, act_size);
302344
*a_len += act_size;
345+
} else if (set_ip_addr.a_op) {
346+
act_size = sizeof(set_ip_addr);
347+
memcpy(nfp_action, &set_ip_addr, act_size);
348+
*a_len += act_size;
303349
}
304350

305351
return 0;

drivers/net/ethernet/netronome/nfp/flower/cmsg.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#define NFP_FL_ACTION_OPCODE_POP_VLAN 2
7979
#define NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL 6
8080
#define NFP_FL_ACTION_OPCODE_SET_ETHERNET 7
81+
#define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS 9
8182
#define NFP_FL_ACTION_OPCODE_PRE_TUNNEL 17
8283
#define NFP_FL_ACTION_OPCODE_NUM 32
8384

@@ -115,6 +116,15 @@ struct nfp_fl_set_eth {
115116
u8 eth_addr_val[ETH_ALEN * 2];
116117
};
117118

119+
struct nfp_fl_set_ip4_addrs {
120+
__be16 a_op;
121+
__be16 reserved;
122+
__be32 ipv4_src_mask;
123+
__be32 ipv4_src;
124+
__be32 ipv4_dst_mask;
125+
__be32 ipv4_dst;
126+
};
127+
118128
struct nfp_fl_output {
119129
__be16 a_op;
120130
__be16 flags;

0 commit comments

Comments
 (0)