bypass: compress flow keys structure

pull/3952/head
Eric Leblond 6 years ago committed by Victor Julien
parent 69d2c8eb75
commit d119845d98

@ -33,31 +33,32 @@
#define LINUX_VERSION_CODE 263682
struct flowv4_keys {
__be32 src;
__be32 dst;
__u32 src;
__u32 dst;
union {
__be32 ports;
__be16 port16[2];
__u32 ports;
__u16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct flowv6_keys {
__be32 src[4];
__be32 dst[4];
__u32 src[4];
__u32 dst[4];
union {
__be32 ports;
__be16 port16[2];
__u32 ports;
__u16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct pair {
__u32 packets;
__u32 bytes;
__u32 hash;
__u64 packets;
__u64 bytes;
};
struct bpf_map_def SEC("maps") flow_table_v4 = {
@ -90,14 +91,18 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb, __u16 vlan0, __u16
struct flowv4_keys tuple;
struct pair *value;
__u16 port;
__u8 ip_proto;
nhoff = skb->cb[0];
tuple.ip_proto = load_byte(skb, nhoff + offsetof(struct iphdr, protocol));
ip_proto = load_byte(skb, nhoff + offsetof(struct iphdr, protocol));
/* only support TCP and UDP for now */
switch (tuple.ip_proto) {
switch (ip_proto) {
case IPPROTO_TCP:
tuple.ip_proto = 1;
break;
case IPPROTO_UDP:
tuple.ip_proto = 0;
break;
default:
return -1;
@ -112,8 +117,8 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb, __u16 vlan0, __u16
port = tuple.port16[1];
tuple.port16[1] = tuple.port16[0];
tuple.port16[0] = port;
tuple.vlan_id[0] = vlan0;
tuple.vlan_id[1] = vlan1;
tuple.vlan0 = vlan0;
tuple.vlan1 = vlan1;
#if 0
if ((tuple.port16[0] == 22) || (tuple.port16[1] == 22))
@ -163,7 +168,10 @@ static __always_inline int ipv6_filter(struct __sk_buff *skb, __u16 vlan0, __u16
/* only support direct TCP and UDP for now */
switch (nhdr) {
case IPPROTO_TCP:
tuple.ip_proto = 1;
break;
case IPPROTO_UDP:
tuple.ip_proto = 0;
break;
default:
return -1;
@ -183,10 +191,9 @@ static __always_inline int ipv6_filter(struct __sk_buff *skb, __u16 vlan0, __u16
port = tuple.port16[1];
tuple.port16[1] = tuple.port16[0];
tuple.port16[0] = port;
tuple.ip_proto = nhdr;
tuple.vlan_id[0] = vlan0;
tuple.vlan_id[1] = vlan1;
tuple.vlan0 = vlan0;
tuple.vlan1 = vlan1;
//char fmt[] = "Now Got IPv6 port %u and %u\n";
//bpf_trace_printk(fmt, sizeof(fmt), tuple.port16[0], tuple.port16[1]);

@ -72,8 +72,9 @@ struct flowv4_keys {
__u32 ports;
__u16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct flowv6_keys {
@ -83,13 +84,14 @@ struct flowv6_keys {
__u32 ports;
__u16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct pair {
__u32 packets;
__u32 bytes;
__u64 packets;
__u64 bytes;
};
struct bpf_map_def SEC("maps") flow_table_v4 = {
@ -258,7 +260,11 @@ static int __always_inline filter_ipv4(struct xdp_md *ctx, void *data, __u64 nh_
if ((void *)(iph + 1) > data_end)
return XDP_PASS;
tuple.ip_proto = (__u32) iph->protocol;
if (iph->protocol == IPPROTO_TCP) {
tuple.ip_proto = 1;
} else {
tuple.ip_proto = 0;
}
tuple.src = iph->saddr;
tuple.dst = iph->daddr;
@ -273,8 +279,8 @@ static int __always_inline filter_ipv4(struct xdp_md *ctx, void *data, __u64 nh_
tuple.port16[0] = (__u16)sport;
tuple.port16[1] = (__u16)dport;
tuple.vlan_id[0] = vlan0;
tuple.vlan_id[1] = vlan1;
tuple.vlan0 = vlan0;
tuple.vlan1 = vlan1;
value = bpf_map_lookup_elem(&flow_table_v4, &tuple);
#if 0
@ -404,14 +410,18 @@ static int __always_inline filter_ipv6(struct xdp_md *ctx, void *data, __u64 nh_
if (sport == -1)
return XDP_PASS;
tuple.ip_proto = ip6h->nexthdr;
if (ip6h->nexthdr == IPPROTO_TCP) {
tuple.ip_proto = 1;
} else {
tuple.ip_proto = 0;
}
__builtin_memcpy(tuple.src, ip6h->saddr.s6_addr32, sizeof(tuple.src));
__builtin_memcpy(tuple.dst, ip6h->daddr.s6_addr32, sizeof(tuple.dst));
tuple.port16[0] = sport;
tuple.port16[1] = dport;
tuple.vlan_id[0] = vlan0;
tuple.vlan_id[1] = vlan1;
tuple.vlan0 = vlan0;
tuple.vlan1 = vlan1;
value = bpf_map_lookup_elem(&flow_table_v6, &tuple);
if (value) {

@ -2403,10 +2403,14 @@ static int AFPBypassCallback(Packet *p)
keys[0]->dst = htonl(GET_IPV4_DST_ADDR_U32(p));
keys[0]->port16[0] = GET_TCP_SRC_PORT(p);
keys[0]->port16[1] = GET_TCP_DST_PORT(p);
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->vlan0 = p->vlan_id[0];
keys[0]->vlan1 = p->vlan_id[1];
keys[0]->ip_proto = IPV4_GET_IPPROTO(p);
if (IPV4_GET_IPPROTO(p) == IPPROTO_TCP) {
keys[0]->ip_proto = 1;
} else {
keys[0]->ip_proto = 0;
}
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2421,10 +2425,10 @@ static int AFPBypassCallback(Packet *p)
keys[1]->dst = htonl(GET_IPV4_SRC_ADDR_U32(p));
keys[1]->port16[0] = GET_TCP_DST_PORT(p);
keys[1]->port16[1] = GET_TCP_SRC_PORT(p);
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->vlan0 = p->vlan_id[0];
keys[1]->vlan1 = p->vlan_id[1];
keys[1]->ip_proto = IPV4_GET_IPPROTO(p);
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2453,9 +2457,14 @@ static int AFPBypassCallback(Packet *p)
}
keys[0]->port16[0] = GET_TCP_SRC_PORT(p);
keys[0]->port16[1] = GET_TCP_DST_PORT(p);
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV6_GET_NH(p);
keys[0]->vlan0 = p->vlan_id[0];
keys[0]->vlan1 = p->vlan_id[1];
if (IPV6_GET_NH(p) == IPPROTO_TCP) {
keys[0]->ip_proto = 1;
} else {
keys[0]->ip_proto = 0;
}
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2472,9 +2481,10 @@ static int AFPBypassCallback(Packet *p)
}
keys[1]->port16[0] = GET_TCP_DST_PORT(p);
keys[1]->port16[1] = GET_TCP_SRC_PORT(p);
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV6_GET_NH(p);
keys[1]->vlan0 = p->vlan_id[0];
keys[1]->vlan1 = p->vlan_id[1];
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2537,9 +2547,13 @@ static int AFPXDPBypassCallback(Packet *p)
* (as in eBPF filter) so we need to pass from host to network order */
keys[0]->port16[0] = htons(p->sp);
keys[0]->port16[1] = htons(p->dp);
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV4_GET_IPPROTO(p);
keys[0]->vlan0 = p->vlan_id[0];
keys[0]->vlan1 = p->vlan_id[1];
if (IPV4_GET_IPPROTO(p) == IPPROTO_TCP) {
keys[0]->ip_proto = 1;
} else {
keys[0]->ip_proto = 0;
}
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2554,9 +2568,9 @@ static int AFPXDPBypassCallback(Packet *p)
keys[1]->dst = p->src.addr_data32[0];
keys[1]->port16[0] = htons(p->dp);
keys[1]->port16[1] = htons(p->sp);
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV4_GET_IPPROTO(p);
keys[1]->vlan0 = p->vlan_id[0];
keys[1]->vlan1 = p->vlan_id[1];
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2585,9 +2599,13 @@ static int AFPXDPBypassCallback(Packet *p)
}
keys[0]->port16[0] = htons(GET_TCP_SRC_PORT(p));
keys[0]->port16[1] = htons(GET_TCP_DST_PORT(p));
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV6_GET_NH(p);
keys[0]->vlan0 = p->vlan_id[0];
keys[0]->vlan1 = p->vlan_id[1];
if (IPV6_GET_NH(p) == IPPROTO_TCP) {
keys[0]->ip_proto = 1;
} else {
keys[0]->ip_proto = 0;
}
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
@ -2604,9 +2622,9 @@ static int AFPXDPBypassCallback(Packet *p)
}
keys[1]->port16[0] = htons(GET_TCP_DST_PORT(p));
keys[1]->port16[1] = htons(GET_TCP_SRC_PORT(p));
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV6_GET_NH(p);
keys[1]->vlan0 = p->vlan_id[0];
keys[1]->vlan1 = p->vlan_id[1];
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);

@ -724,9 +724,13 @@ static int EBPFForEachFlowV4Table(ThreadVars *th_v, LiveDevice *dev, const char
flow_key.dst.addr_data32[1] = 0;
flow_key.dst.addr_data32[2] = 0;
flow_key.dst.addr_data32[3] = 0;
flow_key.vlan_id[0] = next_key.vlan_id[0];
flow_key.vlan_id[1] = next_key.vlan_id[1];
flow_key.proto = next_key.ip_proto;
flow_key.vlan_id[0] = next_key.vlan0;
flow_key.vlan_id[1] = next_key.vlan1;
if (next_key.ip_proto == 1) {
flow_key.proto = IPPROTO_TCP;
} else {
flow_key.proto = IPPROTO_UDP;
}
flow_key.recursion_level = 0;
dead_flow = EBPFOpFlowForKey(flowstats, &next_key, &flow_key,
ctime, pkts_cnt, bytes_cnt,
@ -833,9 +837,13 @@ static int EBPFForEachFlowV6Table(ThreadVars *th_v,
flow_key.dst.addr_data32[2] = ntohl(next_key.dst[2]);
flow_key.dst.addr_data32[3] = ntohl(next_key.dst[3]);
}
flow_key.vlan_id[0] = next_key.vlan_id[0];
flow_key.vlan_id[1] = next_key.vlan_id[1];
flow_key.proto = next_key.ip_proto;
flow_key.vlan_id[0] = next_key.vlan0;
flow_key.vlan_id[1] = next_key.vlan1;
if (next_key.ip_proto == 1) {
flow_key.proto = IPPROTO_TCP;
} else {
flow_key.proto = IPPROTO_UDP;
}
flow_key.recursion_level = 0;
pkts_cnt = EBPFOpFlowForKey(flowstats, &next_key, &flow_key,
ctime, pkts_cnt, bytes_cnt,

@ -40,8 +40,9 @@ struct flowv4_keys {
__be32 ports;
__be16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct flowv6_keys {
@ -51,13 +52,14 @@ struct flowv6_keys {
__be32 ports;
__be16 port16[2];
};
__u32 ip_proto;
__u16 vlan_id[2];
__u8 ip_proto:1;
__u16 vlan0:15;
__u16 vlan1;
};
struct pair {
uint32_t packets;
uint32_t bytes;
uint64_t packets;
uint64_t bytes;
};
typedef struct EBPFBypassData_ {

Loading…
Cancel
Save