Skip to content

Commit

Permalink
bpf(tc): return TC_ACT_UNSPEC instead of TC_ACT_OK to trigger other c…
Browse files Browse the repository at this point in the history
…lassifiers
  • Loading branch information
mozillazg committed Sep 8, 2024
1 parent e95a4d7 commit f5acd68
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 34 deletions.
12 changes: 6 additions & 6 deletions chapter12/net-context/tc-exist-process/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define ETH_P_IP 0x0800 /* Internet Protocol packet */ // ipv4
#define ETH_HLEN 14 /* Total octets in header. */
#define TASK_COMM_LEN 16
#define TC_ACT_OK 0
#define TC_ACT_UNSPEC (-1)


struct sock_key {
Expand Down Expand Up @@ -114,21 +114,21 @@ int on_egress(struct __sk_buff *skb) {
void *data = (void *)(long)skb->data;

if ((data + ETH_HLEN + sizeof(struct iphdr)) > data_end)
return TC_ACT_OK;
return TC_ACT_UNSPEC;
struct iphdr *ip_hdr = data + ETH_HLEN;
if (ip_hdr->protocol != IPPROTO_TCP)
return TC_ACT_OK;
return TC_ACT_UNSPEC;
struct tcphdr *tcp_hdr = (void *)ip_hdr + sizeof(struct iphdr);
if ((void *)tcp_hdr + sizeof(struct tcphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

key.saddr = ip_hdr->saddr;
key.sport = bpf_ntohs(tcp_hdr->source);

value = bpf_map_lookup_elem(&socks, &key);
if (!value) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
u32 daddr = ip_hdr->daddr;
u16 dport = bpf_ntohs(tcp_hdr->dest);
Expand All @@ -137,7 +137,7 @@ int on_egress(struct __sk_buff *skb) {
bpf_printk("%s %pI4:%d", value->comm, &key.saddr, key.sport);
bpf_printk("%s -> %pI4:%d", value->comm, &daddr, dport);

return TC_ACT_OK;
return TC_ACT_UNSPEC;
}


Expand Down
12 changes: 6 additions & 6 deletions chapter12/net-context/tc/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define ETH_P_IP 0x0800 /* Internet Protocol packet */ // ipv4
#define ETH_HLEN 14 /* Total octets in header. */
#define TASK_COMM_LEN 16
#define TC_ACT_OK 0
#define TC_ACT_UNSPEC (-1)


struct sock_key {
Expand Down Expand Up @@ -163,13 +163,13 @@ int on_egress(struct __sk_buff *skb) {
void *data = (void *)(long)skb->data;

if ((data + ETH_HLEN + sizeof(struct iphdr)) > data_end)
return TC_ACT_OK;
return TC_ACT_UNSPEC;
struct iphdr *ip_hdr = data + ETH_HLEN;
if (ip_hdr->protocol != IPPROTO_TCP)
return TC_ACT_OK;
return TC_ACT_UNSPEC;
struct tcphdr *tcp_hdr = (void *)ip_hdr + sizeof(struct iphdr);
if ((void *)tcp_hdr + sizeof(struct tcphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

key.saddr = ip_hdr->saddr;
Expand All @@ -179,7 +179,7 @@ int on_egress(struct __sk_buff *skb) {

value = bpf_map_lookup_elem(&socks, &key);
if (!value) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
u32 daddr = ip_hdr->daddr;
u16 dport = bpf_ntohs(tcp_hdr->dest);
Expand All @@ -188,7 +188,7 @@ int on_egress(struct __sk_buff *skb) {
bpf_printk("%s %pI4:%d", value->comm, &key.saddr, key.sport);
bpf_printk("%s -> %pI4:%d", value->comm, &daddr, dport);

return TC_ACT_OK;
return TC_ACT_UNSPEC;
}


Expand Down
32 changes: 16 additions & 16 deletions chapter14/hijack-tcp-to-send-data/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,27 @@ int on_egress(struct __sk_buff *skb) {
// 从 IP 首部中过滤协议类型,只处理 TCP 协议
struct iphdr *ip_hdr = data + ETH_HLEN;
if ((void *)ip_hdr + sizeof(struct iphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
if (ip_hdr->protocol != IPPROTO_TCP) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// TCP 协议数据过滤
struct tcphdr *tcp_hdr = (void *)ip_hdr + sizeof(struct iphdr);
if ((void *)tcp_hdr + sizeof(struct tcphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
if (tcp_hdr->dest != bpf_htons(8000)) {
bpf_printk("skip port: %d", bpf_ntohs(tcp_hdr->dest));
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// 防止重复劫持,出现一直重传
int zero = 0;
if (bpf_map_lookup_elem(&modify_map, &tcp_hdr->source)) {
bpf_printk("exist");
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
bpf_map_update_elem(&modify_map, &tcp_hdr->source, &zero, BPF_ANY);
bpf_printk("hijack start");
Expand All @@ -72,13 +72,13 @@ int on_egress(struct __sk_buff *skb) {
int ret = bpf_skb_store_bytes(skb, dest_addr_offset, &new_dest_addr, sizeof(u32), 0);
if (ret < 0) {
bpf_printk("replace dest addr failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
// 重新计算 IP 首部 checksum
ret = bpf_l3_csum_replace(skb, ip_checksum_offset, old_dest_addr, new_dest_addr, sizeof(u32));
if (ret < 0) {
bpf_printk("bpf_l3_csum_replace failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// 替换 TCP 首部,修改目的端口
Expand All @@ -89,53 +89,53 @@ int on_egress(struct __sk_buff *skb) {
ret = bpf_skb_store_bytes(skb, dest_port_offset, &new_dest_port, sizeof(u16), 0);
if (ret < 0) {
bpf_printk("replace dest port failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
// 重新计算 TCP 首部 checksum
ret = bpf_l4_csum_replace(skb, tcp_checksum_offset, old_dest_port, new_dest_port, sizeof(u16));
if (ret < 0) {
bpf_printk("bpf_l4_csum_replace failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// 调整 skb 关联的数据包长度信息
ret = bpf_skb_change_tail(skb, skb->len+increment_len, 0);
if (ret < 0) {
bpf_printk("bpf_skb_change_tail failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
ret = bpf_skb_pull_data(skb, 0);
if (ret < 0) {
bpf_printk("bpf_skb_pull_data failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// 调用 bpf_skb_change_tail 后,需要重新执行检查,否则验证器会验证失败
data = (void *)(long)skb->data;
data_end = (void *)(long)skb->data_end;
ip_hdr = data + ETH_HLEN;
if ((void *)ip_hdr + sizeof(struct iphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
if (ip_hdr->protocol != IPPROTO_TCP) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}
tcp_hdr = (void *)ip_hdr + sizeof(struct iphdr);
if ((void *)tcp_hdr + sizeof(struct tcphdr) > data_end) {
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

// 替换 TCP payload
u32 offset = ETH_HLEN + sizeof(struct iphdr) + (tcp_hdr->doff * 4);
ret = bpf_skb_store_bytes(skb, offset, new_payload, sizeof(new_payload), 0);
if (ret < 0) {
bpf_printk("overwrite payload failed: %d", ret);
return TC_ACT_OK;
return TC_ACT_UNSPEC;
}

bpf_printk("hijack end");

return TC_ACT_OK;
return TC_ACT_UNSPEC;
}


Expand Down
8 changes: 2 additions & 6 deletions chapter14/hijack-tcp-to-send-data/main.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_HLEN 14 /* Total octets in header. */

#define TC_ACT_UNSPEC (-1)
#define TC_ACT_OK 0
#define TC_ACT_SHOT 2
#define TC_ACT_STOLEN 4
#define TC_ACT_REDIRECT 7
#define TC_ACT_UNSPEC (-1)


struct event_t {
Expand Down Expand Up @@ -42,4 +38,4 @@ static __always_inline int str_len(const char *s, int max_len)
if (s[max_len - 1] != '\0')
return max_len;
return 0;
}
}

0 comments on commit f5acd68

Please sign in to comment.