18c2ecf20Sopenharmony_ci#define KBUILD_MODNAME "foo" 28c2ecf20Sopenharmony_ci#include <uapi/linux/bpf.h> 38c2ecf20Sopenharmony_ci#include <uapi/linux/if_ether.h> 48c2ecf20Sopenharmony_ci#include <uapi/linux/if_packet.h> 58c2ecf20Sopenharmony_ci#include <uapi/linux/ip.h> 68c2ecf20Sopenharmony_ci#include <uapi/linux/in.h> 78c2ecf20Sopenharmony_ci#include <uapi/linux/tcp.h> 88c2ecf20Sopenharmony_ci#include <uapi/linux/filter.h> 98c2ecf20Sopenharmony_ci#include <uapi/linux/pkt_cls.h> 108c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h> 118c2ecf20Sopenharmony_ci#include "bpf_legacy.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* compiler workaround */ 148c2ecf20Sopenharmony_ci#define _htonl __builtin_bswap32 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic inline void set_dst_mac(struct __sk_buff *skb, char *mac) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci bpf_skb_store_bytes(skb, 0, mac, ETH_ALEN, 1); 198c2ecf20Sopenharmony_ci} 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define IP_CSUM_OFF (ETH_HLEN + offsetof(struct iphdr, check)) 228c2ecf20Sopenharmony_ci#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos)) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci __u8 old_tos = load_byte(skb, TOS_OFF); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2); 298c2ecf20Sopenharmony_ci bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define TCP_CSUM_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, check)) 338c2ecf20Sopenharmony_ci#define IP_SRC_OFF (ETH_HLEN + offsetof(struct iphdr, saddr)) 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define IS_PSEUDO 0x10 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci __u32 old_ip = _htonl(load_word(skb, IP_SRC_OFF)); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_ip, new_ip, IS_PSEUDO | sizeof(new_ip)); 428c2ecf20Sopenharmony_ci bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip)); 438c2ecf20Sopenharmony_ci bpf_skb_store_bytes(skb, IP_SRC_OFF, &new_ip, sizeof(new_ip), 0); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define TCP_DPORT_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest)) 478c2ecf20Sopenharmony_cistatic inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci __u16 old_port = htons(load_half(skb, TCP_DPORT_OFF)); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port)); 528c2ecf20Sopenharmony_ci bpf_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciSEC("classifier") 568c2ecf20Sopenharmony_ciint bpf_prog1(struct __sk_buff *skb) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci __u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); 598c2ecf20Sopenharmony_ci long *value; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci if (proto == IPPROTO_TCP) { 628c2ecf20Sopenharmony_ci set_ip_tos(skb, 8); 638c2ecf20Sopenharmony_ci set_tcp_ip_src(skb, 0xA010101); 648c2ecf20Sopenharmony_ci set_tcp_dest_port(skb, 5001); 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci return 0; 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ciSEC("redirect_xmit") 708c2ecf20Sopenharmony_ciint _redirect_xmit(struct __sk_buff *skb) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci return bpf_redirect(skb->ifindex + 1, 0); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ciSEC("redirect_recv") 758c2ecf20Sopenharmony_ciint _redirect_recv(struct __sk_buff *skb) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci return bpf_redirect(skb->ifindex + 1, 1); 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ciSEC("clone_redirect_xmit") 808c2ecf20Sopenharmony_ciint _clone_redirect_xmit(struct __sk_buff *skb) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci bpf_clone_redirect(skb, skb->ifindex + 1, 0); 838c2ecf20Sopenharmony_ci return TC_ACT_SHOT; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ciSEC("clone_redirect_recv") 868c2ecf20Sopenharmony_ciint _clone_redirect_recv(struct __sk_buff *skb) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci bpf_clone_redirect(skb, skb->ifindex + 1, 1); 898c2ecf20Sopenharmony_ci return TC_ACT_SHOT; 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_cichar _license[] SEC("license") = "GPL"; 92