بنقرة واحدة
ebpf-networking
Fast packet processing with XDP, TC filtering, socket programs, load balancing, and Cilium networking
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Fast packet processing with XDP, TC filtering, socket programs, load balancing, and Cilium networking
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Index of Build Systems Skills
Coordination patterns for distributed dataflow systems including barriers, epochs, and distributed snapshots
Windowing, sessionization, time-series aggregation, and late data handling for streaming systems
Comprehensive guide to GNU Debugger (GDB) for debugging C/C++/Rust programs. Covers breakpoints, stack traces, variable inspection, TUI mode, .gdbinit customization, Python scripting, remote debugging, and core file analysis.
Paxos consensus algorithm including Basic Paxos, Multi-Paxos, roles, phases, and practical implementations
Gossip protocols for disseminating information, failure detection, and eventual consistency in large-scale distributed systems
استنادا إلى تصنيف SOC المهني
| name | ebpf-networking |
| description | Fast packet processing with XDP, TC filtering, socket programs, load balancing, and Cilium networking |
Scope: XDP packet processing, TC filtering, socket programs, L4/L7 load balancing, and Cilium for Kubernetes Lines: ~340 Last Updated: 2025-10-25 Format Version: 1.0 (Atomic)
Activate this skill when:
Actions: XDP_PASS, XDP_DROP, XDP_TX, XDP_REDIRECT, XDP_ABORTED
Execution point: Earliest possible (before SKB allocation)
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <bpf/bpf_helpers.h>
SEC("xdp")
int xdp_firewall(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
// Parse Ethernet header
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
// Only process IP packets
if (eth->h_proto != htons(ETH_P_IP))
return XDP_PASS;
// Parse IP header
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_DROP;
// Drop ICMP packets (simple firewall)
if (ip->protocol == IPPROTO_ICMP)
return XDP_DROP;
// Drop packets from specific IP
__u32 blocked_ip = 0x0a000001; // 10.0.0.1
if (ip->saddr == htonl(blocked_ip))
return XDP_DROP;
return XDP_PASS;
}
char LICENSE[] SEC("license") = "GPL";
XDP modes:
Hook points: Ingress (incoming), Egress (outgoing)
Capabilities: Packet modification, redirection, drop, pass
#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <bpf/bpf_helpers.h>
SEC("tc")
int tc_modify_port(struct __sk_buff *skb) {
void *data_end = (void *)(long)skb->data_end;
void *data = (void *)(long)skb->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return TC_ACT_OK;
if (eth->h_proto != htons(ETH_P_IP))
return TC_ACT_OK;
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return TC_ACT_OK;
if (ip->protocol != IPPROTO_TCP)
return TC_ACT_OK;
struct tcphdr *tcp = (void *)(ip + 1);
if ((void *)(tcp + 1) > data_end)
return TC_ACT_OK;
// Redirect port 80 traffic to port 8080
if (tcp->dest == htons(80)) {
__u16 new_port = htons(8080);
// Recalculate TCP checksum
__u32 csum = tcp->check;
csum = bpf_csum_diff(&tcp->dest, sizeof(__u16),
&new_port, sizeof(__u16), ~csum);
tcp->check = csum_fold(csum);
tcp->dest = new_port;
}
return TC_ACT_OK;
}
char LICENSE[] SEC("license") = "GPL";
Types: Socket filter, sockops, sk_msg, sk_skb
Use case: Per-socket policy, connection steering
// Socket filter: Drop packets for specific socket
SEC("socket")
int socket_filter(struct __sk_buff *skb) {
// Access socket info
__u32 protocol = load_byte(skb, offsetof(struct iphdr, protocol));
if (protocol == IPPROTO_UDP)
return 0; // Drop UDP
return -1; // Pass others
}
// Sockops: Attach to socket operations
SEC("sockops")
int sockops_prog(struct bpf_sock_ops *skops) {
__u32 op = skops->op;
switch (op) {
case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
// Socket established
bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_ALL_CB_FLAGS);
break;
case BPF_SOCK_OPS_RTO_CB:
// Retransmit timeout
bpf_printk("RTO event\n");
break;
}
return 1;
}
char LICENSE[] SEC("license") = "GPL";
XDP_REDIRECT: Send packet to another interface or CPU
struct {
__uint(type, BPF_MAP_TYPE_DEVMAP);
__uint(max_entries, 256);
__type(key, __u32);
__type(value, __u32);
} tx_port SEC(".maps");
SEC("xdp")
int xdp_redirect(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
// Redirect to interface in map
__u32 key = 0;
return bpf_redirect_map(&tx_port, key, 0);
}
// User space setup
int main() {
int map_fd = bpf_map__fd(tx_port);
__u32 key = 0;
__u32 ifindex = if_nametoindex("eth1"); // Target interface
bpf_map_update_elem(map_fd, &key, &ifindex, BPF_ANY);
// Packets now redirect to eth1
}
When to use: Protect against network floods
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 1000000);
__type(key, __u32); // Source IP
__type(value, __u64); // Packet count
} rate_limit SEC(".maps");
SEC("xdp")
int xdp_rate_limit(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
if (eth->h_proto != htons(ETH_P_IP))
return XDP_PASS;
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_DROP;
__u32 src_ip = ip->saddr;
__u64 *count = bpf_map_lookup_elem(&rate_limit, &src_ip);
if (count) {
// Limit: 10,000 packets per second
if (*count > 10000)
return XDP_DROP;
__sync_fetch_and_add(count, 1);
} else {
__u64 init = 1;
bpf_map_update_elem(&rate_limit, &src_ip, &init, BPF_ANY);
}
return XDP_PASS;
}
// User space: Reset counts every second
void reset_counters(int map_fd) {
while (1) {
sleep(1);
// LRU automatically evicts old entries
}
}
Use case: Distribute connections across backends
struct backend {
__u32 ip;
__u16 port;
};
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 4);
__type(key, __u32);
__type(value, struct backend);
} backends SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 100000);
__type(key, __u64); // Connection hash
__type(value, __u32); // Backend index
} conn_table SEC(".maps");
SEC("xdp")
int xdp_lb(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
if (eth->h_proto != htons(ETH_P_IP))
return XDP_PASS;
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_DROP;
if (ip->protocol != IPPROTO_TCP)
return XDP_PASS;
struct tcphdr *tcp = (void *)(ip + 1);
if ((void *)(tcp + 1) > data_end)
return XDP_DROP;
// Hash connection
__u64 conn_hash = ((__u64)ip->saddr << 32) | ip->daddr;
conn_hash ^= ((__u64)tcp->source << 16) | tcp->dest;
// Lookup existing connection
__u32 *backend_idx = bpf_map_lookup_elem(&conn_table, &conn_hash);
__u32 idx;
if (!backend_idx) {
// New connection: Round-robin selection
idx = (conn_hash % 4); // 4 backends
bpf_map_update_elem(&conn_table, &conn_hash, &idx, BPF_ANY);
} else {
idx = *backend_idx;
}
// Get backend
struct backend *be = bpf_map_lookup_elem(&backends, &idx);
if (!be)
return XDP_DROP;
// Rewrite destination IP and port
ip->daddr = be->ip;
tcp->dest = htons(be->port);
// Recalculate checksums
ip->check = 0;
ip->check = ip_checksum(ip);
return XDP_TX; // Send back out same interface
}
When to use: Network monitoring with low overhead
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
} events SEC(".maps");
struct packet_sample {
__u32 src_ip;
__u32 dst_ip;
__u16 src_port;
__u16 dst_port;
__u8 protocol;
__u32 len;
};
SEC("xdp")
int xdp_sample(struct xdp_md *ctx) {
// Sample 1 out of 1000 packets
if ((bpf_get_prandom_u32() % 1000) != 0)
return XDP_PASS;
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_PASS;
if (eth->h_proto != htons(ETH_P_IP))
return XDP_PASS;
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_PASS;
struct packet_sample sample = {
.src_ip = ip->saddr,
.dst_ip = ip->daddr,
.protocol = ip->protocol,
.len = ctx->data_end - ctx->data,
};
if (ip->protocol == IPPROTO_TCP) {
struct tcphdr *tcp = (void *)(ip + 1);
if ((void *)(tcp + 1) <= data_end) {
sample.src_port = tcp->source;
sample.dst_port = tcp->dest;
}
}
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
&sample, sizeof(sample));
return XDP_PASS;
}
Use case: Kubernetes networking with eBPF
# Cilium NetworkPolicy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-frontend
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
Under the hood: Cilium generates eBPF programs
// Simplified Cilium-style policy enforcement
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10000);
__type(key, __u32); // Identity
__type(value, __u8); // Allowed
} policy_map SEC(".maps");
SEC("from-container")
int enforce_egress(struct __sk_buff *skb) {
__u32 src_identity = skb->cb[0]; // Cilium sets this
__u32 dst_identity = skb->cb[1];
struct policy_key {
__u32 src;
__u32 dst;
} key = {
.src = src_identity,
.dst = dst_identity,
};
// Lookup policy
__u8 *allowed = bpf_map_lookup_elem(&policy_map, &key);
if (!allowed || *allowed == 0)
return TC_ACT_SHOT; // Drop
return TC_ACT_OK; // Allow
}
Use case: Stateful firewalling
struct conn_key {
__u32 src_ip;
__u32 dst_ip;
__u16 src_port;
__u16 dst_port;
__u8 protocol;
};
struct conn_state {
__u64 packets;
__u64 bytes;
__u64 last_seen;
__u8 state; // NEW, ESTABLISHED, etc.
};
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 1000000);
__type(key, struct conn_key);
__type(value, struct conn_state);
} conntrack SEC(".maps");
SEC("xdp")
int xdp_conntrack(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
if (eth->h_proto != htons(ETH_P_IP))
return XDP_PASS;
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_DROP;
if (ip->protocol != IPPROTO_TCP)
return XDP_PASS;
struct tcphdr *tcp = (void *)(ip + 1);
if ((void *)(tcp + 1) > data_end)
return XDP_DROP;
struct conn_key key = {
.src_ip = ip->saddr,
.dst_ip = ip->daddr,
.src_port = tcp->source,
.dst_port = tcp->dest,
.protocol = ip->protocol,
};
struct conn_state *state = bpf_map_lookup_elem(&conntrack, &key);
if (!state) {
// New connection
if (!(tcp->syn && !tcp->ack))
return XDP_DROP; // Must start with SYN
struct conn_state new_state = {
.packets = 1,
.bytes = ctx->data_end - ctx->data,
.last_seen = bpf_ktime_get_ns(),
.state = 0, // NEW
};
bpf_map_update_elem(&conntrack, &key, &new_state, BPF_ANY);
} else {
// Existing connection
__sync_fetch_and_add(&state->packets, 1);
__sync_fetch_and_add(&state->bytes, ctx->data_end - ctx->data);
state->last_seen = bpf_ktime_get_ns();
}
return XDP_PASS;
}
When to use: High-performance packet rewriting
SEC("xdp")
int xdp_rewrite_mac(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
// Rewrite MAC addresses in-place (zero-copy)
__u8 src_mac[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
__u8 dst_mac[6] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
__builtin_memcpy(eth->h_source, src_mac, 6);
__builtin_memcpy(eth->h_dest, dst_mac, 6);
return XDP_TX; // Transmit modified packet
}
Action | Description | Use Case
---------------|--------------------------------|------------------
XDP_PASS | Pass to kernel stack | Normal processing
XDP_DROP | Drop packet | Firewall, DDoS
XDP_TX | Bounce back same interface | Reflection
XDP_REDIRECT | Redirect to another interface | Forwarding, LB
XDP_ABORTED | Drop + trace event | Error handling
Action | Description
-------------|----------------------------------
TC_ACT_OK | Pass packet
TC_ACT_SHOT | Drop packet
TC_ACT_STOLEN| Consumed, don't process further
TC_ACT_REDIRECT | Redirect to another device
# XDP
ip link set dev eth0 xdp obj program.o sec xdp
# TC ingress
tc qdisc add dev eth0 clsact
tc filter add dev eth0 ingress bpf da obj program.o sec tc
# Cilium
cilium install
kubectl apply -f policy.yaml
✅ DO: Use XDP for earliest packet processing
✅ DO: Validate all packet bounds before access
✅ DO: Use LRU maps for connection tracking
✅ DO: Test with different packet sizes and types
✅ DO: Measure performance impact
❌ DON'T: Modify packets without checksum updates
❌ DON'T: Access packet data without bounds checking
❌ DON'T: Use XDP for complex packet inspection (use TC)
// ❌ NEVER: Access packet data without bounds check
SEC("xdp")
int bad_xdp(struct xdp_md *ctx) {
struct ethhdr *eth = (void *)(long)ctx->data;
__u16 proto = eth->h_proto; // REJECTED - no bounds check
return XDP_PASS;
}
// ✅ CORRECT: Always validate bounds
SEC("xdp")
int good_xdp(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_DROP;
__u16 proto = eth->h_proto; // ACCEPTED
return XDP_PASS;
}
❌ No bounds checking: Verifier rejection, crashes ✅ Correct approach: Validate before every access
// ❌ Don't: Modify checksums without recalculation
tcp->dest = htons(8080);
// Checksum now invalid! Packet will be dropped
// ✅ Correct: Recalculate checksums
__u16 old_port = tcp->dest;
__u16 new_port = htons(8080);
tcp->check = bpf_csum_diff(&old_port, sizeof(old_port),
&new_port, sizeof(new_port),
~tcp->check);
tcp->dest = new_port;
❌ Invalid checksums: Packets dropped by receivers ✅ Better: Always update checksums when modifying headers
ebpf-fundamentals.md - Core eBPF concepts and verifierebpf-tracing-observability.md - Network observabilitynetwork-protocols.md - Understanding TCP/IP stackkubernetes-networking.md - Container networkingLast Updated: 2025-10-25 Format Version: 1.0 (Atomic)