forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit 608cd71 ("tc: bpf: generalize pedit action") has added the possibility to mangle packet data to BPF programs in the tc pipeline. This patch adds two helpers bpf_l3_csum_replace() and bpf_l4_csum_replace() for fixing up the protocol checksums after the packet mangling. It also adds 'flags' argument to bpf_skb_store_bytes() helper to avoid unnecessary checksum recomputations when BPF programs adjusting l3/l4 checksums and documents all three helpers in uapi header. Moreover, a sample program is added to show how BPF programs can make use of the mangle and csum helpers. Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
- Loading branch information
Showing
5 changed files
with
220 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include <uapi/linux/bpf.h> | ||
#include <uapi/linux/if_ether.h> | ||
#include <uapi/linux/if_packet.h> | ||
#include <uapi/linux/ip.h> | ||
#include <uapi/linux/in.h> | ||
#include <uapi/linux/tcp.h> | ||
#include "bpf_helpers.h" | ||
|
||
/* compiler workaround */ | ||
#define _htonl __builtin_bswap32 | ||
|
||
static inline void set_dst_mac(struct __sk_buff *skb, char *mac) | ||
{ | ||
bpf_skb_store_bytes(skb, 0, mac, ETH_ALEN, 1); | ||
} | ||
|
||
/* use 1 below for ingress qdisc and 0 for egress */ | ||
#if 0 | ||
#undef ETH_HLEN | ||
#define ETH_HLEN 0 | ||
#endif | ||
|
||
#define IP_CSUM_OFF (ETH_HLEN + offsetof(struct iphdr, check)) | ||
#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos)) | ||
|
||
static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos) | ||
{ | ||
__u8 old_tos = load_byte(skb, TOS_OFF); | ||
|
||
bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2); | ||
bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0); | ||
} | ||
|
||
#define TCP_CSUM_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, check)) | ||
#define IP_SRC_OFF (ETH_HLEN + offsetof(struct iphdr, saddr)) | ||
|
||
#define IS_PSEUDO 0x10 | ||
|
||
static inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip) | ||
{ | ||
__u32 old_ip = _htonl(load_word(skb, IP_SRC_OFF)); | ||
|
||
bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_ip, new_ip, IS_PSEUDO | sizeof(new_ip)); | ||
bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip)); | ||
bpf_skb_store_bytes(skb, IP_SRC_OFF, &new_ip, sizeof(new_ip), 0); | ||
} | ||
|
||
#define TCP_DPORT_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest)) | ||
static inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port) | ||
{ | ||
__u16 old_port = htons(load_half(skb, TCP_DPORT_OFF)); | ||
|
||
bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port)); | ||
bpf_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0); | ||
} | ||
|
||
SEC("classifier") | ||
int bpf_prog1(struct __sk_buff *skb) | ||
{ | ||
__u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); | ||
long *value; | ||
|
||
if (proto == IPPROTO_TCP) { | ||
set_ip_tos(skb, 8); | ||
set_tcp_ip_src(skb, 0xA010101); | ||
set_tcp_dest_port(skb, 5001); | ||
} | ||
|
||
return 0; | ||
} | ||
char _license[] SEC("license") = "GPL"; |