Open
Description
This piece of XDP code is not working (I mean map is not woking for read and write) when snprintf or bpf_snprintf exists.
At bpf side, is there any possibility to cast __u64,__u16,__u32 types to string(char array)
#include <stdbool.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <linux/if_ether.h> // Include this for struct ethhdr
#include <linux/ip.h> // Include this for struct iphdr
#include <linux/tcp.h> // Include this for struct tcphdr
#include <stdint.h>
#include <arpa/inet.h>
#include <stdio.h>
#define MAX_ENTRIES_FLOW 65535
#define min(x, y) ((x) < (y) ? x : y)
char _license[] SEC("license") = "GPL";
struct pkt_trace_metadata {
__u32 ifindex;
__u32 rx_queue;
__u16 pkt_len;
__u16 cap_len;
__u16 flags;
__u16 prog_index;
int action;
} __packed;
// Define the structure for BPF map
// A helper structure used by eBPF C program
// to describe map attributes to BPF program loader
struct bpf_map_def {
__u32 map_type;
__u32 key_size;
__u32 value_size;
__u32 max_entries;
__u32 map_flags;
// Array/Hash of maps use case: pointer to inner map template
void *inner_map_def;
// Define this to make map system wide ("object pinning")
// path could be anything, like '/sys/fs/bpf/foo'
// WARN: You must have BPF filesystem mounted on provided location
const char *persistent_path;
};
#define BPF_MAP(_name, _type, _key_type, _value_type, _max_entries) \
struct bpf_map_def SEC("maps") _name = { \
.map_type = _type, \
.key_size = sizeof(_key_type), \
.value_size = sizeof(_value_type), \
.max_entries = _max_entries, \
};
#define BPF_HASH(_name, _key_type, _value_type) \
BPF_MAP(_name, BPF_MAP_TYPE_HASH, _key_type, _value_type, 10240);
#define BPF_PACKET_MAP(_name) \
BPF_MAP(_name, BPF_MAP_TYPE_PERF_EVENT_ARRAY, int, __u32, MAX_ENTRIES_FLOW);
BPF_PACKET_MAP(packetmap)
BPF_HASH(blacklistmap,int,int)
// XDP program //
SEC("xdp")
int xdp_dump(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct pkt_trace_metadata metadata;
//
metadata.prog_index = 0;
metadata.ifindex = ctx->ingress_ifindex;
metadata.rx_queue = ctx->rx_queue_index;
metadata.pkt_len = (__u16)(data_end - data);
metadata.cap_len = min(metadata.pkt_len, 65535);
metadata.action = 0;
metadata.flags = 0;
// L2
struct ethhdr *ether = data;
if (data + sizeof(*ether) > data_end) {
return XDP_ABORTED;
}
// L3
if (ether->h_proto != 0x08) {
// Non IPv4
return XDP_PASS;
}
data += sizeof(*ether);
struct iphdr *ip = data;
if (data + sizeof(*ip) > data_end) {
return XDP_ABORTED;
}
data += ip->ihl * 4;
struct tcphdr *tcp = data;
if (data + sizeof(*tcp) > data_end) {
return XDP_ABORTED;
}
__u64 sourceport = (__u64)tcp->source;
__u64 destport = (__u64)tcp->dest;
__u64 saddr = (__u64)ip->saddr;
__u64 daddr = (__u64)ip->daddr;
char sourceport_str[6];
char destport_str[6];
char saddr_str[16];
char daddr_str[16];
sprintf(sourceport_str, "%hu", (unsigned short)sourceport);
sprintf(destport_str, "%hu", (unsigned short)destport);
sprintf(saddr_str, "%u", (unsigned int)saddr);
sprintf(daddr_str, "%u", (unsigned int)daddr);
//
bpf_perf_event_output(ctx, &packetmap, ((__u64)metadata.cap_len << 32) | BPF_F_CURRENT_CPU, &metadata, sizeof(metadata));
return XDP_PASS;
}
Metadata
Metadata
Assignees
Labels
No labels