Skip to content

Commit

Permalink
bpf: do not reset csum on adjust room for newer kernels
Browse files Browse the repository at this point in the history
See also [0]. Fall back to passing in 0 flags for older kernels. We
do not push/pop protocol headers but rather keep the same layers
instead, therefore there is also no point in changing to csum_none.
We can probe on csum_level() helper for this since both are needed
if this gets ever backported somewhere.

  [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=836e66c218f355ec01ba57671c85abf32961dcea
  [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7cdec54f9713256bb170873a1fc5c75c9127c9d2

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
  • Loading branch information
borkmann committed Jun 5, 2020
1 parent 66594be commit 5e36fa9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
3 changes: 1 addition & 2 deletions bpf/include/bpf/ctx/xdp.h
Expand Up @@ -196,7 +196,7 @@ l4_csum_replace(const struct xdp_md *ctx, __u64 off, __u32 from, __u32 to,

static __always_inline __maybe_unused int
ctx_adjust_room(struct xdp_md *ctx, const __s32 len_diff, const __u32 mode,
const __u64 flags)
const __u64 flags __maybe_unused)
{
const __u32 move_len_v4 = 14 + 20;
const __u32 move_len_v6 = 14 + 40;
Expand All @@ -205,7 +205,6 @@ ctx_adjust_room(struct xdp_md *ctx, const __s32 len_diff, const __u32 mode,

build_bug_on(len_diff <= 0 || len_diff >= 64);
build_bug_on(mode != BPF_ADJ_ROOM_NET);
build_bug_on(flags != 0);

ret = xdp_adjust_head(ctx, -len_diff);

Expand Down
4 changes: 4 additions & 0 deletions bpf/include/bpf/features.h
Expand Up @@ -27,4 +27,8 @@
# define BPF_HAVE_JIFFIES 1
#endif

#if HAVE_PROG_TYPE_HELPER(sched_cls, bpf_csum_level)
# define BPF_HAVE_CSUM_LEVEL 1
#endif

#endif /* ____BPF_FEATURES____ */
15 changes: 13 additions & 2 deletions bpf/lib/nodeport.h
Expand Up @@ -146,6 +146,15 @@ bpf_skip_recirculation(const struct __ctx_buff *ctx __maybe_unused)
#endif
}

static __always_inline __u64 ctx_adjust_room_dsr_flags(void)
{
#ifdef BPF_HAVE_CSUM_LEVEL
return BPF_F_ADJ_ROOM_NO_CSUM_RESET;
#else
return 0;
#endif
}

#ifdef ENABLE_IPV6
static __always_inline bool nodeport_uses_dsr6(const struct ipv6_ct_tuple *tuple)
{
Expand Down Expand Up @@ -214,7 +223,8 @@ static __always_inline int set_dsr_ext6(struct __ctx_buff *ctx,
ipv6_addr_copy(&opt.addr, svc_addr);
opt.port = svc_port;

if (ctx_adjust_room(ctx, sizeof(opt), BPF_ADJ_ROOM_NET, 0))
if (ctx_adjust_room(ctx, sizeof(opt), BPF_ADJ_ROOM_NET,
ctx_adjust_room_dsr_flags()))
return DROP_INVALID;

if (ctx_store_bytes(ctx, ETH_HLEN + sizeof(*ip6), &opt, sizeof(opt), 0) < 0)
Expand Down Expand Up @@ -917,7 +927,8 @@ static __always_inline int set_dsr_opt4(struct __ctx_buff *ctx,
sum = csum_diff(&iph_old, 4, &iph_new, 4, 0);
sum = csum_diff(NULL, 0, &opt, sizeof(opt), sum);

if (ctx_adjust_room(ctx, 0x8, BPF_ADJ_ROOM_NET, 0))
if (ctx_adjust_room(ctx, 0x8, BPF_ADJ_ROOM_NET,
ctx_adjust_room_dsr_flags()))
return DROP_INVALID;

if (ctx_store_bytes(ctx, ETH_HLEN + sizeof(*ip4),
Expand Down

0 comments on commit 5e36fa9

Please sign in to comment.