Commit f9cae712 authored by Jiri Benc's avatar Jiri Benc Committed by Greg Kroah-Hartman

selftests: bpf: fix inlines in test_lwt_seg6local

[ Upstream commit 11aca65e ]

Selftests are reporting this failure in test_lwt_seg6local.sh:

+ ip netns exec ns2 ip -6 route add fb00::6 encap bpf in obj test_lwt_seg6local.o sec encap_srh dev veth2
Error fetching program/map!
Failed to parse eBPF program: Operation not permitted

The problem is __attribute__((always_inline)) alone is not enough to prevent
clang from inserting those functions in .text. In that case, .text is not
marked as relocateable.

See the output of objdump -h test_lwt_seg6local.o:

Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00003530  0000000000000000  0000000000000000  00000040  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

This causes the iproute bpf loader to fail in bpf_fetch_prog_sec:
bpf_has_call_data returns true but bpf_fetch_prog_relo fails as there's no
relocateable .text section in the file.

To fix this, convert to 'static __always_inline'.

v2: Use 'static __always_inline' instead of 'static inline
    __attribute__((always_inline))'

Fixes: c99a84ea ("selftests/bpf: test for seg6local End.BPF action")
Signed-off-by: default avatarJiri Benc <jbenc@redhat.com>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent b8bf2e82
...@@ -61,7 +61,7 @@ struct sr6_tlv_t { ...@@ -61,7 +61,7 @@ struct sr6_tlv_t {
unsigned char value[0]; unsigned char value[0];
} BPF_PACKET_HEADER; } BPF_PACKET_HEADER;
__attribute__((always_inline)) struct ip6_srh_t *get_srh(struct __sk_buff *skb) static __always_inline struct ip6_srh_t *get_srh(struct __sk_buff *skb)
{ {
void *cursor, *data_end; void *cursor, *data_end;
struct ip6_srh_t *srh; struct ip6_srh_t *srh;
...@@ -95,7 +95,7 @@ __attribute__((always_inline)) struct ip6_srh_t *get_srh(struct __sk_buff *skb) ...@@ -95,7 +95,7 @@ __attribute__((always_inline)) struct ip6_srh_t *get_srh(struct __sk_buff *skb)
return srh; return srh;
} }
__attribute__((always_inline)) static __always_inline
int update_tlv_pad(struct __sk_buff *skb, uint32_t new_pad, int update_tlv_pad(struct __sk_buff *skb, uint32_t new_pad,
uint32_t old_pad, uint32_t pad_off) uint32_t old_pad, uint32_t pad_off)
{ {
...@@ -125,7 +125,7 @@ int update_tlv_pad(struct __sk_buff *skb, uint32_t new_pad, ...@@ -125,7 +125,7 @@ int update_tlv_pad(struct __sk_buff *skb, uint32_t new_pad,
return 0; return 0;
} }
__attribute__((always_inline)) static __always_inline
int is_valid_tlv_boundary(struct __sk_buff *skb, struct ip6_srh_t *srh, int is_valid_tlv_boundary(struct __sk_buff *skb, struct ip6_srh_t *srh,
uint32_t *tlv_off, uint32_t *pad_size, uint32_t *tlv_off, uint32_t *pad_size,
uint32_t *pad_off) uint32_t *pad_off)
...@@ -184,7 +184,7 @@ int is_valid_tlv_boundary(struct __sk_buff *skb, struct ip6_srh_t *srh, ...@@ -184,7 +184,7 @@ int is_valid_tlv_boundary(struct __sk_buff *skb, struct ip6_srh_t *srh,
return 0; return 0;
} }
__attribute__((always_inline)) static __always_inline
int add_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, uint32_t tlv_off, int add_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, uint32_t tlv_off,
struct sr6_tlv_t *itlv, uint8_t tlv_size) struct sr6_tlv_t *itlv, uint8_t tlv_size)
{ {
...@@ -228,7 +228,7 @@ int add_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, uint32_t tlv_off, ...@@ -228,7 +228,7 @@ int add_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, uint32_t tlv_off,
return update_tlv_pad(skb, new_pad, pad_size, pad_off); return update_tlv_pad(skb, new_pad, pad_size, pad_off);
} }
__attribute__((always_inline)) static __always_inline
int delete_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, int delete_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh,
uint32_t tlv_off) uint32_t tlv_off)
{ {
...@@ -266,7 +266,7 @@ int delete_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, ...@@ -266,7 +266,7 @@ int delete_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh,
return update_tlv_pad(skb, new_pad, pad_size, pad_off); return update_tlv_pad(skb, new_pad, pad_size, pad_off);
} }
__attribute__((always_inline)) static __always_inline
int has_egr_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh) int has_egr_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh)
{ {
int tlv_offset = sizeof(struct ip6_t) + sizeof(struct ip6_srh_t) + int tlv_offset = sizeof(struct ip6_t) + sizeof(struct ip6_srh_t) +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment