Skip to content

Commit

Permalink
refactor l4 csum calc for tcp/udp masquerade
Browse files Browse the repository at this point in the history
  • Loading branch information
r-caamano committed Sep 6, 2024
1 parent 381e48a commit 4b4cbe3
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 70 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---
---
###
# [0.8.17] - 2024-09-06
- Refactor of L4 csum ipv4

###
# [0.8.16] - 2024-09-02
- Fixed incorrect waitpid success/failure conditional checks in zfw.c and zfw_tunnel_wrapper.c. This did not cause an operational issue but would not
Expand Down
2 changes: 1 addition & 1 deletion src/zfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ char *direction_string;
char *masq_interface;
char check_alt[IF_NAMESIZE];

const char *argp_program_version = "0.8.16";
const char *argp_program_version = "0.8.17";
struct ring_buffer *ring_buffer;

__u32 if_list[MAX_IF_LIST_ENTRIES];
Expand Down
2 changes: 1 addition & 1 deletion src/zfw_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ char check_alt[IF_NAMESIZE];
char doc[] = "zfw_monitor -- ebpf firewall monitor tool";
const char *rb_map_path = "/sys/fs/bpf/tc/globals/rb_map";
const char *tproxy_map_path = "/sys/fs/bpf/tc/globals/zt_tproxy_map";
const char *argp_program_version = "0.8.16";
const char *argp_program_version = "0.8.17";
union bpf_attr rb_map;
int rb_fd = -1;

Expand Down
60 changes: 26 additions & 34 deletions src/zfw_tc_ingress.c
Original file line number Diff line number Diff line change
Expand Up @@ -1897,25 +1897,19 @@ int bpf_sk_splice(struct __sk_buff *skb){
}
/*Calculate l4 Checksum*/
int flags = BPF_F_PSEUDO_HDR;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), 0, l3_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr;
if(!tuple){
return TC_ACT_SHOT;
}
tuple_len = sizeof(tuple->ipv4);
if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tcph = (struct tcphdr *)((unsigned long)iph + sizeof(*iph));
if ((unsigned long)(tcph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
struct l4_change_fields{
__u32 daddr;
__u16 dport;
};
struct l4_change_fields old_fields = {0};
struct l4_change_fields new_fields = {0};
old_fields.daddr = local_ip4->ipaddr[0];
old_fields.dport = mk.sport;
new_fields.daddr = mv->__in46_u_origin.ip;
new_fields.dport = mv->o_sport;
__u32 l4_sum = bpf_csum_diff((__u32 *)&old_fields, sizeof(old_fields), (__u32 *)&new_fields, sizeof(new_fields), 0);
tcph->dest = mv->o_sport;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), mk.sport , mv->o_sport, flags | 2);
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), 0, l4_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
Expand All @@ -1931,7 +1925,7 @@ int bpf_sk_splice(struct __sk_buff *skb){
tcph = (struct tcphdr *)((unsigned long)iph + sizeof(*iph));
if ((unsigned long)(tcph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
}
}
}
tcp_state_key.__in46_u_dst.ip = tuple->ipv4.saddr;
Expand Down Expand Up @@ -2121,7 +2115,19 @@ int bpf_sk_splice(struct __sk_buff *skb){
/*Calculate l4 Checksum*/
if(udph->check != 0){
int flags = BPF_F_PSEUDO_HDR;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), 0, l3_sum, flags);
struct l4_change_fields{
__u32 daddr;
__u16 dport;
};
struct l4_change_fields old_fields = {0};
struct l4_change_fields new_fields = {0};
old_fields.daddr = local_ip4->ipaddr[0];
old_fields.dport = mk.sport;
new_fields.daddr = mv->__in46_u_origin.ip;
new_fields.dport = mv->o_sport;
__u32 l4_sum = bpf_csum_diff((__u32 *)&old_fields, sizeof(old_fields), (__u32 *)&new_fields, sizeof(new_fields), 0);
udph->dest = mv->o_sport;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), 0, l4_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
Expand All @@ -2138,20 +2144,6 @@ int bpf_sk_splice(struct __sk_buff *skb){
if ((unsigned long)(udph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
udph->dest = mv->o_sport;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mk.sport , mv->o_sport, flags | 2);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr;
if(!tuple){
return TC_ACT_SHOT;
}
tuple_len = sizeof(tuple->ipv4);
if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
}else{
udph->dest = mv->o_sport;
}
Expand Down
61 changes: 27 additions & 34 deletions src/zfw_tc_outbound_track.c
Original file line number Diff line number Diff line change
Expand Up @@ -2374,25 +2374,19 @@ int bpf_sk_splice6(struct __sk_buff *skb){
}
/*Calculate l4 Checksum*/
int flags = BPF_F_PSEUDO_HDR;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), 0, l3_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr;
if(!tuple){
return TC_ACT_SHOT;
}
tuple_len = sizeof(tuple->ipv4);
if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tcph = (struct tcphdr *)((unsigned long)iph + sizeof(*iph));
if ((unsigned long)(tcph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
struct l4_change_fields{
__u32 saddr;
__u16 sport;
};
struct l4_change_fields old_fields = {0};
struct l4_change_fields new_fields = {0};
old_fields.saddr = mv.__in46_u_origin.ip;
old_fields.sport = tcph->source;
new_fields.saddr = local_ip4->ipaddr[0];
new_fields.sport = rand_source_port;
__u32 l4_sum = bpf_csum_diff((__u32 *)&old_fields, sizeof(old_fields), (__u32 *)&new_fields, sizeof(new_fields), 0);
tcph->source = rand_source_port;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), mv.o_sport , rand_source_port, flags | 2);
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct tcphdr, check), 0, l4_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
Expand All @@ -2408,7 +2402,7 @@ int bpf_sk_splice6(struct __sk_buff *skb){
tcph = (struct tcphdr *)((unsigned long)iph + sizeof(*iph));
if ((unsigned long)(tcph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
}
}
unsigned long long tstamp = bpf_ktime_get_ns();
struct tcp_state *tstate;
Expand Down Expand Up @@ -2630,7 +2624,20 @@ int bpf_sk_splice6(struct __sk_buff *skb){
/*Calculate l4 Checksum if checksum not equal to zero*/
if(udph->check != 0){
int flags = BPF_F_PSEUDO_HDR;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), 0, l3_sum, flags);
struct l4_change_fields{
__u32 saddr;
__u16 sport;
};
struct l4_change_fields old_fields = {0};
struct l4_change_fields new_fields = {0};
old_fields.saddr = mv.__in46_u_origin.ip;
old_fields.sport = udph->source;
new_fields.saddr = local_ip4->ipaddr[0];
new_fields.sport = rand_source_port;
udph->source = rand_source_port;
__u32 l4_sum = bpf_csum_diff((__u32 *)&old_fields, sizeof(old_fields), (__u32 *)&new_fields, sizeof(new_fields), 0);
udph->source = rand_source_port;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), 0, l4_sum, flags);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
Expand All @@ -2647,20 +2654,6 @@ int bpf_sk_splice6(struct __sk_buff *skb){
if ((unsigned long)(udph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
udph->source = rand_source_port;
bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mv.o_sport , rand_source_port, flags | 2);
iph = (struct iphdr *)(skb->data + sizeof(*eth));
if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr;
if(!tuple){
return TC_ACT_SHOT;
}
tuple_len = sizeof(tuple->ipv4);
if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){
return TC_ACT_SHOT;
}
}else{
udph->source = rand_source_port;
}
Expand Down

0 comments on commit 4b4cbe3

Please sign in to comment.