pping: Fix struct alginment issues

Move some members in network_tuple and rtt_event around to avoid holes.

Also remove some uncecessary parentheses before & operator, and add
local definitions of AF_INET and AF_INET6.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
This commit is contained in:
Simon Sundberg
2021-02-09 13:00:28 +01:00
parent 670df84bd9
commit eafdf87d80
5 changed files with 18 additions and 21 deletions

View File

@ -248,7 +248,7 @@ static int format_ip_address(int af, const struct in6_addr *addr, char *buf,
size_t size) size_t size)
{ {
if (af == AF_INET) if (af == AF_INET)
return inet_ntop(af, &(addr->s6_addr[12]), return inet_ntop(af, &addr->s6_addr[12],
buf, size) ? -errno : 0; buf, size) ? -errno : 0;
else if (af == AF_INET6) else if (af == AF_INET6)
return inet_ntop(af, addr, buf, size) ? -errno : 0; return inet_ntop(af, addr, buf, size) ? -errno : 0;
@ -261,8 +261,8 @@ static void handle_rtt_event(void *ctx, int cpu, void *data, __u32 data_size)
char saddr[INET6_ADDRSTRLEN]; char saddr[INET6_ADDRSTRLEN];
char daddr[INET6_ADDRSTRLEN]; char daddr[INET6_ADDRSTRLEN];
format_ip_address(e->flow.ipv, &(e->flow.saddr), saddr, sizeof(saddr)); format_ip_address(e->flow.ipv, &e->flow.saddr, saddr, sizeof(saddr));
format_ip_address(e->flow.ipv, &(e->flow.daddr), daddr, sizeof(daddr)); format_ip_address(e->flow.ipv, &e->flow.daddr, daddr, sizeof(daddr));
printf("%llu.%06llu ms %s:%d+%s:%d\n", e->rtt / NS_PER_MS, printf("%llu.%06llu ms %s:%d+%s:%d\n", e->rtt / NS_PER_MS,
e->rtt % NS_PER_MS, saddr, ntohs(e->flow.sport), daddr, e->rtt % NS_PER_MS, saddr, ntohs(e->flow.sport), daddr,

View File

@ -18,12 +18,12 @@
* is extended to work for other protocols than TCP * is extended to work for other protocols than TCP
*/ */
struct network_tuple { struct network_tuple {
__u8 ipv; //AF_INET or AF_INET6
struct in6_addr saddr; struct in6_addr saddr;
struct in6_addr daddr; struct in6_addr daddr;
__u16 sport; __u16 sport;
__u16 dport; __u16 dport;
__u16 proto; //IPPROTO_TCP, IPPROTO_ICMP, QUIC etc __u16 proto; //IPPROTO_TCP, IPPROTO_ICMP, QUIC etc
__u16 ipv; //AF_INET or AF_INET6
}; };
struct packet_id { struct packet_id {
@ -37,8 +37,8 @@ struct packet_timestamp {
}; };
struct rtt_event { struct rtt_event {
struct network_tuple flow;
__u64 rtt; __u64 rtt;
struct network_tuple flow;
}; };
#endif #endif

View File

@ -7,6 +7,8 @@
#include <string.h> #include <string.h>
#include "pping.h" #include "pping.h"
#define AF_INET 2
#define AF_INET6 10
#define MAX_TCP_OPTIONS 10 #define MAX_TCP_OPTIONS 10
/* /*
@ -15,14 +17,10 @@
static __always_inline void map_ipv4_to_ipv6(__be32 ipv4, struct in6_addr *ipv6) static __always_inline void map_ipv4_to_ipv6(__be32 ipv4, struct in6_addr *ipv6)
{ {
/* __u16 ipv4_prefix[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff}; */ /* __u16 ipv4_prefix[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff}; */
/* memcpy(&(ipv6->in6_u.u6_addr8), ipv4_prefix, sizeof(ipv4_prefix)); */ /* memcpy(ipv6, ipv4_prefix, sizeof(ipv4_prefix)); // Won't load on TC */
memset(&(ipv6->in6_u.u6_addr8[0]), 0x00, 10); memset(&ipv6->in6_u.u6_addr8[0], 0x00, 10);
memset(&(ipv6->in6_u.u6_addr8[10]), 0xff, 2); memset(&ipv6->in6_u.u6_addr8[10], 0xff, 2);
#if __UAPI_DEF_IN6_ADDR_ALT
ipv6->in6_u.u6_addr32[3] = ipv4; ipv6->in6_u.u6_addr32[3] = ipv4;
#else
memcpy(&(ipv6->in6_u.u6_addr8[12]), &ipv4, sizeof(ipv4));
#endif
} }
/* /*

View File

@ -56,13 +56,13 @@ int tc_bpf_prog_egress(struct __sk_buff *skb)
struct packet_id p_id = { 0 }; struct packet_id p_id = { 0 };
struct packet_timestamp p_ts = { 0 }; struct packet_timestamp p_ts = { 0 };
proto = bpf_ntohs(parse_ethhdr(&nh, data_end, &eth)); proto = parse_ethhdr(&nh, data_end, &eth);
// Parse IPv4/6 header // Parse IPv4/6 header
if (proto == ETH_P_IP) { if (proto == bpf_htons(ETH_P_IP)) {
p_id.flow.ipv = AF_INET; p_id.flow.ipv = AF_INET;
proto = parse_iphdr(&nh, data_end, &iph); proto = parse_iphdr(&nh, data_end, &iph);
} else if (proto == ETH_P_IPV6) { } else if (proto == bpf_htons(ETH_P_IPV6)) {
p_id.flow.ipv = AF_INET6; p_id.flow.ipv = AF_INET6;
proto = parse_ip6hdr(&nh, data_end, &ip6h); proto = parse_ip6hdr(&nh, data_end, &ip6h);
} else } else
@ -79,8 +79,8 @@ int tc_bpf_prog_egress(struct __sk_buff *skb)
// We have a TCP timestamp, try adding it to the map // We have a TCP timestamp, try adding it to the map
p_id.identifier = tsval; p_id.identifier = tsval;
if (p_id.flow.ipv == AF_INET) { if (p_id.flow.ipv == AF_INET) {
map_ipv4_to_ipv6(iph->saddr, &(p_id.flow.saddr)); map_ipv4_to_ipv6(iph->saddr, &p_id.flow.saddr);
map_ipv4_to_ipv6(iph->daddr, &(p_id.flow.daddr)); map_ipv4_to_ipv6(iph->daddr, &p_id.flow.daddr);
} else { // IPv6 } else { // IPv6
p_id.flow.saddr = ip6h->saddr; p_id.flow.saddr = ip6h->saddr;
p_id.flow.daddr = ip6h->daddr; p_id.flow.daddr = ip6h->daddr;

View File

@ -76,8 +76,8 @@ int xdp_prog_ingress(struct xdp_md *ctx)
p_id.flow.proto == proto; p_id.flow.proto == proto;
// Fill in reverse order of egress (dest <--> source) // Fill in reverse order of egress (dest <--> source)
if (p_id.flow.ipv == AF_INET) { if (p_id.flow.ipv == AF_INET) {
map_ipv4_to_ipv6(iph->daddr, &(p_id.flow.saddr)); map_ipv4_to_ipv6(iph->daddr, &p_id.flow.saddr);
map_ipv4_to_ipv6(iph->saddr, &(p_id.flow.daddr)); map_ipv4_to_ipv6(iph->saddr, &p_id.flow.daddr);
} else { // IPv6 } else { // IPv6
p_id.flow.saddr = ip6h->daddr; p_id.flow.saddr = ip6h->daddr;
p_id.flow.daddr = ip6h->saddr; p_id.flow.daddr = ip6h->saddr;
@ -98,8 +98,7 @@ int xdp_prog_ingress(struct xdp_md *ctx)
p_ts->used = 1; p_ts->used = 1;
// TODO - Optional delete of entry (if identifier is garantued unique) // TODO - Optional delete of entry (if identifier is garantued unique)
memcpy(&(event.flow), &(p_id.flow), memcpy(&event.flow, &p_id.flow, sizeof(struct network_tuple));
sizeof(struct network_tuple));
event.rtt = bpf_ktime_get_ns() - p_ts->timestamp; event.rtt = bpf_ktime_get_ns() - p_ts->timestamp;
bpf_perf_event_output(ctx, &rtt_events, BPF_F_CURRENT_CPU, bpf_perf_event_output(ctx, &rtt_events, BPF_F_CURRENT_CPU,
&event, sizeof(event)); &event, sizeof(event));