Top Banner
49

Specializing the Data Path - Hooking into the Linux Network Stack

Jan 14, 2017

Download

Software

Kernel TLV
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 2: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●

Page 3: Specializing the Data Path - Hooking into the Linux Network Stack

●○○○

●○

Page 4: Specializing the Data Path - Hooking into the Linux Network Stack
Page 5: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●

Page 6: Specializing the Data Path - Hooking into the Linux Network Stack
Page 7: Specializing the Data Path - Hooking into the Linux Network Stack

Page 8: Specializing the Data Path - Hooking into the Linux Network Stack
Page 9: Specializing the Data Path - Hooking into the Linux Network Stack
Page 10: Specializing the Data Path - Hooking into the Linux Network Stack
Page 11: Specializing the Data Path - Hooking into the Linux Network Stack

packet_socket = socket(AF_PACKET, int socket_type, int protocol);

Page 12: Specializing the Data Path - Hooking into the Linux Network Stack

●○

●○

●○

●○

●●

Page 13: Specializing the Data Path - Hooking into the Linux Network Stack

●○ htons(ETH_P_EAPOL), htons(ETH_P_IP)

Page 14: Specializing the Data Path - Hooking into the Linux Network Stack

●○○○

… …

Page 15: Specializing the Data Path - Hooking into the Linux Network Stack

●○

●○

●○

struct sockaddr_ll { unsigned short sll_family; unsigned short sll_protocol; int sll_ifindex; unsigned short sll_hatype; unsigned char sll_pkttype; unsigned char sll_halen; unsigned char sll_addr[8];};

Page 16: Specializing the Data Path - Hooking into the Linux Network Stack

●○ setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, …)

# sudo tcpdump -d arp(000) ldh [12](001) jeq #0x806 jt 2 jf 3(002) ret #262144(003) ret #0

# sudo tcpdump -dd arp{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 1, 0x00000806 },{ 0x6, 0, 0, 0x00040000 },{ 0x6, 0, 0, 0x00000000 },

Page 17: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●

Page 18: Specializing the Data Path - Hooking into the Linux Network Stack
Page 19: Specializing the Data Path - Hooking into the Linux Network Stack

●●

○○

Page 20: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●●●●

○ …

Page 21: Specializing the Data Path - Hooking into the Linux Network Stack
Page 22: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●

Page 23: Specializing the Data Path - Hooking into the Linux Network Stack

int nf_register_net_hook(struct net *net, const struct nf_hook_ops *ops);

int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, unsigned int n);

int nf_register_hook(struct nf_hook_ops *reg);

int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);

Page 24: Specializing the Data Path - Hooking into the Linux Network Stack

static struct nf_hook_ops ipv4_synproxy_ops[] = { { .hook = ipv4_synproxy_hook, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priv = NULL, }, { .hook = ipv4_synproxy_hook, .pf = NFPROTO_IPV4, .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priv = NULL, },};

Page 25: Specializing the Data Path - Hooking into the Linux Network Stack

static unsigned int ipv4_synproxy_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *nhs)

{ do_stuff();

if (...) return NF_ACCEPT;

do_more_stuff();

if (...) return NF_DROP;

return NF_ACCEPT;}

Page 26: Specializing the Data Path - Hooking into the Linux Network Stack

●○

●○

●○

●○

●○

Page 27: Specializing the Data Path - Hooking into the Linux Network Stack

●●

○●

○○

●●

Page 28: Specializing the Data Path - Hooking into the Linux Network Stack

●●●

○○○

●○

Page 29: Specializing the Data Path - Hooking into the Linux Network Stack

●●●

○●●●

○○

Page 30: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●●

Page 31: Specializing the Data Path - Hooking into the Linux Network Stack
Page 32: Specializing the Data Path - Hooking into the Linux Network Stack

●○○○○○

Page 33: Specializing the Data Path - Hooking into the Linux Network Stack
Page 34: Specializing the Data Path - Hooking into the Linux Network Stack

Page 35: Specializing the Data Path - Hooking into the Linux Network Stack

●●

Page 36: Specializing the Data Path - Hooking into the Linux Network Stack

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 \ u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff \ flowid 1:3

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 \ u32 match u16 0x0000 0xffc0 at 2 flowid 1:4

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 \ handle 1 fw classid 1:10

# tc filter add dev eth0 parent 1: \ basic match 'meta(priority eq 6)' classid 1:10

# tc filter add dev eth0 parent 1:0 \ bpf obj bpf.o sec mycls flowid 1:1

Page 37: Specializing the Data Path - Hooking into the Linux Network Stack

●●●

○●

Page 38: Specializing the Data Path - Hooking into the Linux Network Stack

Page 39: Specializing the Data Path - Hooking into the Linux Network Stack

# tc qdisc add dev eth0 ingress# tc filter add dev eth0 parent ffff: protocol all prio 1 \ u32 match u32 0 0 \ action mirred egress redirect dev eth1

# tc filter add dev eth0 parent ffff: protocol ip prio 6 \ u32 match ip src 10.0.0.9/32 action drop

# tc filter add dev eth0 parent ffff: pref 11 protocol ip \ u32 match ip protocol 1 0xff flowid 1:1 \ u32 match ip src 10.0.0.2 flowid 1:1 \ action vlan push id 123

# tc filter replace dev eth0 parent ffff: \ basic \ action bpf obj bpf.o sec my-action

Page 40: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●

○●

○●

Page 41: Specializing the Data Path - Hooking into the Linux Network Stack

●○○○

●○○○

● →

Page 42: Specializing the Data Path - Hooking into the Linux Network Stack

●●

Page 43: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●●●●●●

Page 44: Specializing the Data Path - Hooking into the Linux Network Stack

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_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0);

bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port));

}

__attribute__((section("redirect_xmit"), used))

int _redirect_xmit(struct __sk_buff *skb)

{

__u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));

if (proto == IPPROTO_TCP)

set_tcp_dest_port(skb, 5001);

return bpf_redirect(skb->ifindex + 1, 0);

}

Page 45: Specializing the Data Path - Hooking into the Linux Network Stack

struct bpf_map_def __attribute__((section("maps"), used)) my_map = {

.type = BPF_MAP_TYPE_ARRAY,

.key_size = sizeof(u32),

.value_size = sizeof(long),

.max_entries = 256,

};

__attribute__((section("socket1"), used))

int bpf_prog1(struct __sk_buff *skb)

{

int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));

long *value;

if (skb->pkt_type != PACKET_OUTGOING)

return 0;

value = bpf_map_lookup_elem(&my_map, &index);

if (value)

__sync_fetch_and_add(value, skb->len);

return 0;

}

Page 46: Specializing the Data Path - Hooking into the Linux Network Stack

●●

○○○○

●●●

Page 47: Specializing the Data Path - Hooking into the Linux Network Stack
Page 48: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●

Page 49: Specializing the Data Path - Hooking into the Linux Network Stack

●●●●●●●●