Skip to content

Commit 185067a

Browse files
committed
Merge branch 'bpf-max-pkt-offset'
Jiong Wang says: ==================== The maximum packet offset accessed by one BPF program is useful information. Because sometimes there could be packet split and it is possible for some reasons (for example performance) we want to reject the BPF program if the maximum packet size would trigger such split. Normally, MTU value is treated as the maximum packet size, but one BPF program does not always access the whole packet, it could only access the head portion of the data. We could let verifier calculate the maximum packet offset ever used and record it inside prog auxiliar information structure as a new field "max_pkt_offset". ==================== Signed-off-by: Daniel Borkmann <[email protected]>
2 parents bce6a14 + cf599f5 commit 185067a

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

drivers/net/ethernet/netronome/nfp/bpf/offload.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,14 +489,15 @@ nfp_net_bpf_load(struct nfp_net *nn, struct bpf_prog *prog,
489489
struct netlink_ext_ack *extack)
490490
{
491491
struct nfp_prog *nfp_prog = prog->aux->offload->dev_priv;
492-
unsigned int max_mtu, max_stack, max_prog_len;
492+
unsigned int fw_mtu, pkt_off, max_stack, max_prog_len;
493493
dma_addr_t dma_addr;
494494
void *img;
495495
int err;
496496

497-
max_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32;
498-
if (max_mtu < nn->dp.netdev->mtu) {
499-
NL_SET_ERR_MSG_MOD(extack, "BPF offload not supported with MTU larger than HW packet split boundary");
497+
fw_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32;
498+
pkt_off = min(prog->aux->max_pkt_offset, nn->dp.netdev->mtu);
499+
if (fw_mtu < pkt_off) {
500+
NL_SET_ERR_MSG_MOD(extack, "BPF offload not supported with potential packet access beyond HW packet split boundary");
500501
return -EOPNOTSUPP;
501502
}
502503

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ struct bpf_prog_aux {
293293
atomic_t refcnt;
294294
u32 used_map_cnt;
295295
u32 max_ctx_offset;
296+
u32 max_pkt_offset;
296297
u32 stack_depth;
297298
u32 id;
298299
u32 func_cnt;

kernel/bpf/verifier.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,6 +1455,17 @@ static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off,
14551455
verbose(env, "R%d offset is outside of the packet\n", regno);
14561456
return err;
14571457
}
1458+
1459+
/* __check_packet_access has made sure "off + size - 1" is within u16.
1460+
* reg->umax_value can't be bigger than MAX_PACKET_OFF which is 0xffff,
1461+
* otherwise find_good_pkt_pointers would have refused to set range info
1462+
* that __check_packet_access would have rejected this pkt access.
1463+
* Therefore, "off + reg->umax_value + size - 1" won't overflow u32.
1464+
*/
1465+
env->prog->aux->max_pkt_offset =
1466+
max_t(u32, env->prog->aux->max_pkt_offset,
1467+
off + reg->umax_value + size - 1);
1468+
14581469
return err;
14591470
}
14601471

@@ -6138,6 +6149,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
61386149
*/
61396150
prog->cb_access = 1;
61406151
env->prog->aux->stack_depth = MAX_BPF_STACK;
6152+
env->prog->aux->max_pkt_offset = MAX_PACKET_OFF;
61416153

61426154
/* mark bpf_tail_call as different opcode to avoid
61436155
* conditional branch in the interpeter for every normal

0 commit comments

Comments
 (0)