Skip to content

Commit 43bcf70

Browse files
borkmanndavem330
authored andcommitted
bpf: fix _htons occurences in test_progs
Dave reported that on sparc test_progs generates buggy swapped eth->h_proto protocol comparisons: 10: (15) if r3 == 0xdd86 goto pc+9 R0=imm2,min_value=2,max_value=2 R1=pkt(id=0,off=0,r=14) R2=pkt_end R3=inv R4=pkt(id=0,off=14,r=14) R5=inv56 R10=fp This is due to the unconditional ... #define htons __builtin_bswap16 #define ntohs __builtin_bswap16 ... in test_progs that causes this. Make use of asm/byteorder.h and use __constant_htons() where possible and only perform the bswap16 when on little endian in non-constant case. Fixes: 6882804 ("selftests/bpf: add a test for overlapping packet range checks") Fixes: 3782161 ("selftests/bpf: add l4 load balancer test based on sched_cls") Reported-by: David S. Miller <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d24f7c7 commit 43bcf70

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

tools/testing/selftests/bpf/bpf_util.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@
66
#include <string.h>
77
#include <errno.h>
88

9+
#include <asm/byteorder.h>
10+
11+
#if __BYTE_ORDER == __LITTLE_ENDIAN
12+
# define __bpf_ntohs(x) __builtin_bswap16(x)
13+
# define __bpf_htons(x) __builtin_bswap16(x)
14+
#elif __BYTE_ORDER == __BIG_ENDIAN
15+
# define __bpf_ntohs(x) (x)
16+
# define __bpf_htons(x) (x)
17+
#else
18+
# error "Fix your __BYTE_ORDER?!"
19+
#endif
20+
21+
#define bpf_htons(x) \
22+
(__builtin_constant_p(x) ? \
23+
__constant_htons(x) : __bpf_htons(x))
24+
#define bpf_ntohs(x) \
25+
(__builtin_constant_p(x) ? \
26+
__constant_ntohs(x) : __bpf_ntohs(x))
27+
928
static inline unsigned int bpf_num_possible_cpus(void)
1029
{
1130
static const char *fcpu = "/sys/devices/system/cpu/possible";

tools/testing/selftests/bpf/test_l4lb.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919
#include <linux/udp.h>
2020
#include "bpf_helpers.h"
2121
#include "test_iptunnel_common.h"
22+
#include "bpf_util.h"
2223

23-
#define htons __builtin_bswap16
24-
#define ntohs __builtin_bswap16
2524
int _version SEC("version") = 1;
2625

2726
static inline __u32 rol32(__u32 word, unsigned int shift)
@@ -355,7 +354,7 @@ static __always_inline int process_packet(void *data, __u64 off, void *data_end,
355354
iph_len = sizeof(struct ipv6hdr);
356355
protocol = ip6h->nexthdr;
357356
pckt.proto = protocol;
358-
pkt_bytes = ntohs(ip6h->payload_len);
357+
pkt_bytes = bpf_ntohs(ip6h->payload_len);
359358
off += iph_len;
360359
if (protocol == IPPROTO_FRAGMENT) {
361360
return TC_ACT_SHOT;
@@ -377,7 +376,7 @@ static __always_inline int process_packet(void *data, __u64 off, void *data_end,
377376

378377
protocol = iph->protocol;
379378
pckt.proto = protocol;
380-
pkt_bytes = ntohs(iph->tot_len);
379+
pkt_bytes = bpf_ntohs(iph->tot_len);
381380
off += IPV4_HDR_LEN_NO_OPT;
382381

383382
if (iph->frag_off & PCKT_FRAGMENTED)
@@ -464,9 +463,9 @@ int balancer_ingress(struct __sk_buff *ctx)
464463
if (data + nh_off > data_end)
465464
return TC_ACT_SHOT;
466465
eth_proto = eth->eth_proto;
467-
if (eth_proto == htons(ETH_P_IP))
466+
if (eth_proto == bpf_htons(ETH_P_IP))
468467
return process_packet(data, nh_off, data_end, false, ctx);
469-
else if (eth_proto == htons(ETH_P_IPV6))
468+
else if (eth_proto == bpf_htons(ETH_P_IPV6))
470469
return process_packet(data, nh_off, data_end, true, ctx);
471470
else
472471
return TC_ACT_SHOT;

tools/testing/selftests/bpf/test_pkt_access.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <linux/tcp.h>
1515
#include <linux/pkt_cls.h>
1616
#include "bpf_helpers.h"
17+
#include "bpf_util.h"
1718

18-
#define _htons __builtin_bswap16
1919
#define barrier() __asm__ __volatile__("": : :"memory")
2020
int _version SEC("version") = 1;
2121

@@ -32,15 +32,15 @@ int process(struct __sk_buff *skb)
3232
if (eth + 1 > data_end)
3333
return TC_ACT_SHOT;
3434

35-
if (eth->h_proto == _htons(ETH_P_IP)) {
35+
if (eth->h_proto == bpf_htons(ETH_P_IP)) {
3636
struct iphdr *iph = (struct iphdr *)(eth + 1);
3737

3838
if (iph + 1 > data_end)
3939
return TC_ACT_SHOT;
4040
ihl_len = iph->ihl * 4;
4141
proto = iph->protocol;
4242
tcp = (struct tcphdr *)((void *)(iph) + ihl_len);
43-
} else if (eth->h_proto == _htons(ETH_P_IPV6)) {
43+
} else if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
4444
struct ipv6hdr *ip6h = (struct ipv6hdr *)(eth + 1);
4545

4646
if (ip6h + 1 > data_end)

tools/testing/selftests/bpf/test_progs.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ typedef __u16 __sum16;
3030
#include "test_iptunnel_common.h"
3131
#include "bpf_util.h"
3232

33-
#define _htons __builtin_bswap16
34-
3533
static int error_cnt, pass_cnt;
3634

3735
#define MAGIC_BYTES 123
@@ -42,10 +40,10 @@ static struct {
4240
struct iphdr iph;
4341
struct tcphdr tcp;
4442
} __packed pkt_v4 = {
45-
.eth.h_proto = _htons(ETH_P_IP),
43+
.eth.h_proto = bpf_htons(ETH_P_IP),
4644
.iph.ihl = 5,
4745
.iph.protocol = 6,
48-
.iph.tot_len = _htons(MAGIC_BYTES),
46+
.iph.tot_len = bpf_htons(MAGIC_BYTES),
4947
.tcp.urg_ptr = 123,
5048
};
5149

@@ -55,9 +53,9 @@ static struct {
5553
struct ipv6hdr iph;
5654
struct tcphdr tcp;
5755
} __packed pkt_v6 = {
58-
.eth.h_proto = _htons(ETH_P_IPV6),
56+
.eth.h_proto = bpf_htons(ETH_P_IPV6),
5957
.iph.nexthdr = 6,
60-
.iph.payload_len = _htons(MAGIC_BYTES),
58+
.iph.payload_len = bpf_htons(MAGIC_BYTES),
6159
.tcp.urg_ptr = 123,
6260
};
6361

0 commit comments

Comments
 (0)