Я пытаюсь написать программу XDP, которая вставляет метку времени в полезную нагрузку пакета UDP, но безуспешно.
Я предполагаю, что делаю что-то неправильно с указателями. Пакет не имеет контрольной суммы, и меня вполне устраивает просто перезаписать части полезных данных в соответствии с меткой времени.
Цель состоит в том, чтобы измерить задержку пакета между входом и выходом OVS. Я использую CentOS Stream 9 с xdp-loader. Есть какие-нибудь советы, как это сделать?
При загрузке следующего кода с помощью sudo я получаю следующее:
Код: Выделить всё
Current rlimit 8388608 already >= minimum 1048576
Loading 1 files on interface 'ens16f0np0'.
XDP program 0: Run prio: 50. Chain call actions: XDP_PASS
Couldn't attach XDP program on iface 'ens16f0np0': Permission denied(-13)
Код: Выделить всё
#include
#include "bpf_helpers.h"
#include
#include
#include
#include
#ifndef __bpf_htons
#define __bpf_htons(x) ((__be16)___constant_swab16((x)))
#endif
SEC("udp_timestamp_xdp")
int xdp_timestamp_func(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
struct iphdr *iph = (struct iphdr *)(eth + 1);
struct udphdr *udph = (struct udphdr *)(iph + 1);
__u64 timestamp = bpf_ktime_get_ns();
// Check if the packet is UDP
if (eth->h_proto != __bpf_htons(ETH_P_IP) || iph->protocol != IPPROTO_UDP)
return XDP_PASS;
// Calculate the pointer to the UDP payload
__u8 *payload = (__u8 *)(udph + 1);
// Copy the timestamp into the UDP payload
__builtin_memcpy(payload, ×tamp, sizeof(__u64));
// Adjust packet size if needed to accommodate the timestamp
int ret = bpf_xdp_adjust_tail(ctx, sizeof(__u64));
if (ret < 0) {
// Adjusting tail failed, pass the packet without modification
return XDP_PASS;
}
return XDP_PASS;
}
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#ifndef __bpf_htons
#define __bpf_htons(x) ((__be16)___constant_swab16((x)))
#endif
SEC("udp_timestamp_xdp")
int xdp_timestamp_func(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
struct iphdr *iph = (struct iphdr *)(eth + 1);
struct udphdr *udph = (struct udphdr *)(iph + 1);
__u64 timestamp = bpf_ktime_get_ns();
// Check if the packet contains enough data for UDP and timestamp
if (udph + 1 > (struct udphdr *)data_end)
return XDP_DROP;
// Check if the packet is UDP
if (eth->h_proto != __bpf_htons(ETH_P_IP) || iph->protocol != IPPROTO_UDP)
return XDP_PASS;
// Calculate the pointer to the UDP payload
__u8 *payload = (__u8 *)(udph + 1);
// Check if the payload length is sufficient
if ((void *)(payload + sizeof(__u64)) > data_end)
return XDP_DROP;
// Copy the timestamp into the UDP payload
__builtin_memcpy(payload, ×tamp, sizeof(__u64));
return XDP_PASS;
}
Источник: https://stackoverflow.com/questions/781 ... f-on-linux