From: HAKAN SARIMAN <hakansariman@std.iyte.edu.tr>
To: xdp-newbies <xdp-newbies@vger.kernel.org>
Subject: Packet Filtering with AF_XDP in Forwarded Traffic
Date: Fri, 26 Apr 2024 17:22:17 +0300 (TRT) [thread overview]
Message-ID: <1920889031.78418857.1714141337441.JavaMail.zimbra@std.iyte.edu.tr> (raw)
Hi folks,
I'm currently working on setting up a packet filter using AF_XDP on my Linux server to manage network traffic in userspace.
I tried to work with xdp-tutorial/AF_XDP example,
I've attached a simple XDP program that redirects to the traffic by using xsks_map on enp8s0.
You can find the XDP code below.
To test my setup, I'm trying to block a specific IPv4 address.
Although I can see the traffic on userspace, I couldn't block any traffic.
You can find the userspace code below.
I think there is something I am missing, can you help me what I am doing wrong?
Here's a brief overview of my current setup:
Network Interfaces: enp1s0 (Egress Interface), ens8s0 (Local Network Interface)
Current iptables Rules:
-A FORWARD -i enp1s0 -o ens8s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i ens8s0 -o enp1s0 -j ACCEPT
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
23461 1790K MASQUERADE 0 -- * enp1s0 0.0.0.0/0 0.0.0.0/0
XDP Code:
-----
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
struct {
__uint(type, BPF_MAP_TYPE_XSKMAP);
__type(key, __u32);
__type(value, __u32);
__uint(max_entries, 64);
} xsks_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, __u32);
__type(value, __u32);
__uint(max_entries, 64);
} xdp_stats_map SEC(".maps");
SEC("xdp")
int xdp_sock_prog(struct xdp_md *ctx)
{
int index = ctx->rx_queue_index;
__u32 *pkt_count;
pkt_count = bpf_map_lookup_elem(&xdp_stats_map, &index);
if (pkt_count) {
/* We pass every other packet */
if ((*pkt_count)++ & 1)
return XDP_PASS;
}
/* A set entry here means that the correspnding queue_id
* has an active AF_XDP socket bound to it. */
if (bpf_map_lookup_elem(&xsks_map, &index))
return bpf_redirect_map(&xsks_map, index, 0);
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
----
Userspace code (rest of the code is identical with xdp-tutorial/AF_XDP [https://github.com/xdp-project/xdp-tutorial/blob/master/advanced03-AF_XDP/af_xdp_user.c]):
static bool process_packet(struct xsk_socket_info *xsk,
uint64_t addr, uint32_t len)
{
uint8_t *pkt = xsk_umem__get_data(xsk->umem->buffer, addr);
struct ethhdr *eth = (struct ethhdr *) pkt;
struct iphdr *ip = (struct iphdr *) (eth + 1);
struct in_addr tmp_ip;
tmp_ip.s_addr = ip->saddr;
char src_ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &tmp_ip, src_ip_str, INET_ADDRSTRLEN);
tmp_ip.s_addr = ip->daddr;
char dest_ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &tmp_ip, dest_ip_str, INET_ADDRSTRLEN);
printf("saddr: %s, daddr: %s\n", src_ip_str, dest_ip_str);
// trying to block an ip
if (strcmp(src_ip_str, "x.y.z.t") == 0 || strcmp(dest_ip_str, "x.y.z.t") == 0) {
return false;
}
int ret;
uint32_t tx_idx = 0;
ret = xsk_ring_prod__reserve(&xsk->tx, 1, &tx_idx);
if (ret != 1) {
/* No more transmit slots, drop the packet */
return false;
}
xsk_ring_prod__tx_desc(&xsk->tx, tx_idx)->addr = addr;
xsk_ring_prod__tx_desc(&xsk->tx, tx_idx)->len = len;
xsk_ring_prod__submit(&xsk->tx, 1);
xsk->outstanding_tx++;
return true;
}
...
/* Process received packets */
for (i = 0; i < rcvd; i++) {
uint64_t addr = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx)->addr;
uint32_t len = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx++)->len;
if (!process_packet(xsk, addr, len))
xsk_free_umem_frame(xsk, addr);
}
reply other threads:[~2024-04-26 14:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1920889031.78418857.1714141337441.JavaMail.zimbra@std.iyte.edu.tr \
--to=hakansariman@std.iyte.edu.tr \
--cc=xdp-newbies@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.