2016-10-26 01:37:53 +03:00
# define KBUILD_MODNAME "foo"
2015-04-02 03:12:13 +03:00
# 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>
2015-04-15 22:55:45 +03:00
# include <uapi/linux/filter.h>
2015-09-16 09:05:43 +03:00
# include <uapi/linux/pkt_cls.h>
2020-01-20 16:06:49 +03:00
# include <bpf/bpf_helpers.h>
2019-10-08 20:59:37 +03:00
# include "bpf_legacy.h"
2015-04-02 03:12:13 +03:00
/* 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 ) ;
}
# 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 )
{
2015-06-04 20:11:53 +03:00
__u8 old_tos = load_byte ( skb , TOS_OFF ) ;
2015-04-02 03:12:13 +03:00
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 )
{
2015-06-04 20:11:53 +03:00
__u32 old_ip = _htonl ( load_word ( skb , IP_SRC_OFF ) ) ;
2015-04-02 03:12:13 +03:00
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 )
{
2015-06-04 20:11:53 +03:00
__u16 old_port = htons ( load_half ( skb , TCP_DPORT_OFF ) ) ;
2015-04-02 03:12:13 +03:00
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 )
{
2015-06-04 20:11:53 +03:00
__u8 proto = load_byte ( skb , ETH_HLEN + offsetof ( struct iphdr , protocol ) ) ;
2015-04-02 03:12:13 +03:00
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 ;
}
2015-09-16 09:05:43 +03:00
SEC ( " redirect_xmit " )
int _redirect_xmit ( struct __sk_buff * skb )
{
return bpf_redirect ( skb - > ifindex + 1 , 0 ) ;
}
SEC ( " redirect_recv " )
int _redirect_recv ( struct __sk_buff * skb )
{
return bpf_redirect ( skb - > ifindex + 1 , 1 ) ;
}
SEC ( " clone_redirect_xmit " )
int _clone_redirect_xmit ( struct __sk_buff * skb )
{
bpf_clone_redirect ( skb , skb - > ifindex + 1 , 0 ) ;
return TC_ACT_SHOT ;
}
SEC ( " clone_redirect_recv " )
int _clone_redirect_recv ( struct __sk_buff * skb )
{
bpf_clone_redirect ( skb , skb - > ifindex + 1 , 1 ) ;
return TC_ACT_SHOT ;
}
2015-04-02 03:12:13 +03:00
char _license [ ] SEC ( " license " ) = " GPL " ;