From a6b206419a48302b2dad181121420d59a3fc7273 Mon Sep 17 00:00:00 2001 From: Stephen Wong Date: Fri, 5 Apr 2019 06:16:53 +0000 Subject: Clovisor ONS demo related fixes Change-Id: I9449ee5f699a3cdf471dc8b405de650325ae09f6 Signed-off-by: Stephen Wong --- clover/clovisor/libclovisor/ebpf/node_interface.c | 158 ++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100755 clover/clovisor/libclovisor/ebpf/node_interface.c (limited to 'clover/clovisor/libclovisor/ebpf') diff --git a/clover/clovisor/libclovisor/ebpf/node_interface.c b/clover/clovisor/libclovisor/ebpf/node_interface.c new file mode 100755 index 0000000..cd14a50 --- /dev/null +++ b/clover/clovisor/libclovisor/ebpf/node_interface.c @@ -0,0 +1,158 @@ +// Copyright (c) Authors of Clover +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Apache License, Version 2.0 +// which accompanies this distribution, and is available at +// http://www.apache.org/licenses/LICENSE-2.0 +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_SESSION_TABLE_ENTRIES 8192 + +typedef struct session_key_ { + u32 src_ip; + u32 dst_ip; + unsigned short src_port; + unsigned short dst_port; +} session_key_t; + +typedef struct session_ { + u64 req_time; + u64 resp_time; +} session_t; + +BPF_HASH(ip2track, u32, u32); +BPF_HASH(node_sessions, session_key_t, session_t, MAX_SESSION_TABLE_ENTRIES); + +struct eth_hdr { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + unsigned short h_proto; +}; + +static inline int ipv4_hdrlen(struct iphdr *ip4) +{ + return ip4->ihl * 4; +} + +static inline int tcp_doff(struct tcphdr *tcp_hdr) +{ + return tcp_hdr->doff * 4; +} + +static inline void fill_up_sess_key(session_key_t *key, u32 src_ip, + u32 dst_ip, u16 src_port, u16 dst_port) +{ + key->src_ip = src_ip; + key->dst_ip = dst_ip; + key->src_port = src_port; + key->dst_port = dst_port; +} + +static inline void process_response(u32 src_ip, u32 dst_ip, u16 src_port, + u16 dst_port) +{ + session_key_t sess_key = {}; + session_t *session_ptr = NULL; + fill_up_sess_key(&sess_key, src_ip, dst_ip, src_port, dst_port); + session_ptr = node_sessions.lookup(&sess_key); + if (session_ptr != NULL) { + u64 resp_time = bpf_ktime_get_ns(); + session_t update_session = { + session_ptr->req_time, + resp_time + }; + node_sessions.update(&sess_key, &update_session); + } +} + +static inline void process_request(u32 src_ip, u32 dst_ip, u16 src_port, + u16 dst_port) +{ + session_key_t sess_key = {}; + session_t *session_ptr = NULL; + session_t new_session = { + bpf_ktime_get_ns(), + 0 + }; + fill_up_sess_key(&sess_key, src_ip, dst_ip, src_port, dst_port); + session_ptr = node_sessions.lookup(&sess_key); + if (! session_ptr) { + node_sessions.insert(&sess_key, &new_session); + } +} + +static inline void ingress_parsing(struct tcphdr *tcp_hdr, + struct iphdr *ipv4_hdr) +{ + unsigned int dst_ip = ntohl(ipv4_hdr->daddr); + int ret = 0; + + unsigned int *proto = ip2track.lookup(&dst_ip); + if (proto != NULL) { + process_response(ntohl(ipv4_hdr->daddr), + ntohl(ipv4_hdr->saddr), + ntohs(tcp_hdr->dest), + ntohs(tcp_hdr->source)); + } +} + +static inline void egress_parsing(struct tcphdr *tcp_hdr, + struct iphdr *ipv4_hdr) +{ + unsigned int src_ip = ntohl(ipv4_hdr->saddr); + + unsigned int *proto = ip2track.lookup(&src_ip); + + if (proto != NULL) { + process_request(ntohl(ipv4_hdr->saddr), + ntohl(ipv4_hdr->daddr), + ntohs(tcp_hdr->source), + ntohs(tcp_hdr->dest)); + } +} + +static inline int handle_packet(struct __sk_buff *skb, int is_ingress) +{ + void *data = (void *)(long)skb->data; + void *data_end = (void *)(long)skb->data_end; + struct eth_hdr *eth = data; + struct iphdr *ipv4_hdr = data + sizeof(*eth); + struct tcphdr *tcp_hdr = data + sizeof(*eth) + sizeof(*ipv4_hdr); + + /* TODO(s3wong): assuming TCP only for now */ + /* single length check */ + if (data + sizeof(*eth) + sizeof(*ipv4_hdr) + sizeof(*tcp_hdr) > data_end) + return TC_ACT_OK; + + if (eth->h_proto != htons(ETH_P_IP)) + return TC_ACT_OK; + + // TODO(s3wong): no support for IP options + if (ipv4_hdr->protocol != IPPROTO_TCP || ipv4_hdr->ihl != 5) + return TC_ACT_OK; + + if (is_ingress == 1) { + ingress_parsing(tcp_hdr, ipv4_hdr); + } else{ + egress_parsing(tcp_hdr, ipv4_hdr); + } + + return TC_ACT_OK; +} + +int handle_ingress(struct __sk_buff *skb) +{ + return handle_packet(skb, 1); +} + +int handle_egress(struct __sk_buff *skb) +{ + return handle_packet(skb, 0); +} -- cgit 1.2.3-korg