summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-04-15 15:55:45 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-16 14:08:49 -0400
commita166151cbe33b53221c24259e4a7201064b3ba79 (patch)
treebbc94226f42d4baa1b6ee5203d58d55fa9a69919 /samples
parent51b5df886874816ff986fe66fe0d7b7eca9f6cd1 (diff)
bpf: fix bpf helpers to use skb->mac_header relative offsets
For the short-term solution, lets fix bpf helper functions to use skb->mac_header relative offsets instead of skb->data in order to get the same eBPF programs with cls_bpf and act_bpf work on ingress and egress qdisc path. We need to ensure that mac_header is set before calling into programs. This is effectively the first option from below referenced discussion. More long term solution for LD_ABS|LD_IND instructions will be more intrusive but also more beneficial than this, and implemented later as it's too risky at this point in time. I.e., we plan to look into the option of moving skb_pull() out of eth_type_trans() and into netif_receive_skb() as has been suggested as second option. Meanwhile, this solution ensures ingress can be used with eBPF, too, and that we won't run into ABI troubles later. For dealing with negative offsets inside eBPF helper functions, we've implemented bpf_skb_clone_unwritable() to test for unwriteable headers. Reference: http://thread.gmane.org/gmane.linux.network/359129/focus=359694 Fixes: 608cd71a9c7c ("tc: bpf: generalize pedit action") Fixes: 91bc4822c3d6 ("tc: bpf: add checksum helpers") Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/tcbpf1_kern.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/samples/bpf/tcbpf1_kern.c b/samples/bpf/tcbpf1_kern.c
index 7cf3f42a6e39..7c27710f8296 100644
--- a/samples/bpf/tcbpf1_kern.c
+++ b/samples/bpf/tcbpf1_kern.c
@@ -4,6 +4,8 @@
4#include <uapi/linux/ip.h> 4#include <uapi/linux/ip.h>
5#include <uapi/linux/in.h> 5#include <uapi/linux/in.h>
6#include <uapi/linux/tcp.h> 6#include <uapi/linux/tcp.h>
7#include <uapi/linux/filter.h>
8
7#include "bpf_helpers.h" 9#include "bpf_helpers.h"
8 10
9/* compiler workaround */ 11/* compiler workaround */
@@ -14,18 +16,12 @@ static inline void set_dst_mac(struct __sk_buff *skb, char *mac)
14 bpf_skb_store_bytes(skb, 0, mac, ETH_ALEN, 1); 16 bpf_skb_store_bytes(skb, 0, mac, ETH_ALEN, 1);
15} 17}
16 18
17/* use 1 below for ingress qdisc and 0 for egress */
18#if 0
19#undef ETH_HLEN
20#define ETH_HLEN 0
21#endif
22
23#define IP_CSUM_OFF (ETH_HLEN + offsetof(struct iphdr, check)) 19#define IP_CSUM_OFF (ETH_HLEN + offsetof(struct iphdr, check))
24#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos)) 20#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
25 21
26static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos) 22static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos)
27{ 23{
28 __u8 old_tos = load_byte(skb, TOS_OFF); 24 __u8 old_tos = load_byte(skb, BPF_LL_OFF + TOS_OFF);
29 25
30 bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2); 26 bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2);
31 bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0); 27 bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0);
@@ -38,7 +34,7 @@ static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos)
38 34
39static inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip) 35static inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip)
40{ 36{
41 __u32 old_ip = _htonl(load_word(skb, IP_SRC_OFF)); 37 __u32 old_ip = _htonl(load_word(skb, BPF_LL_OFF + IP_SRC_OFF));
42 38
43 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_ip, new_ip, IS_PSEUDO | sizeof(new_ip)); 39 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_ip, new_ip, IS_PSEUDO | sizeof(new_ip));
44 bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip)); 40 bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip));
@@ -48,7 +44,7 @@ static inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip)
48#define TCP_DPORT_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest)) 44#define TCP_DPORT_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest))
49static inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port) 45static inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port)
50{ 46{
51 __u16 old_port = htons(load_half(skb, TCP_DPORT_OFF)); 47 __u16 old_port = htons(load_half(skb, BPF_LL_OFF + TCP_DPORT_OFF));
52 48
53 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port)); 49 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port));
54 bpf_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0); 50 bpf_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0);
@@ -57,7 +53,7 @@ static inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port)
57SEC("classifier") 53SEC("classifier")
58int bpf_prog1(struct __sk_buff *skb) 54int bpf_prog1(struct __sk_buff *skb)
59{ 55{
60 __u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); 56 __u8 proto = load_byte(skb, BPF_LL_OFF + ETH_HLEN + offsetof(struct iphdr, protocol));
61 long *value; 57 long *value;
62 58
63 if (proto == IPPROTO_TCP) { 59 if (proto == IPPROTO_TCP) {