mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
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:
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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, ð));
|
proto = parse_ethhdr(&nh, data_end, ð);
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -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));
|
||||||
|
Reference in New Issue
Block a user