#include #include #include #include #include #include "bridge_xdp.h" // Definição local para struct vlan_hdr (caso não esteja disponível) #ifndef VLAN_HLEN #define VLAN_HLEN 4 #endif struct vlan_hdr { __be16 h_vlan_TCI; __be16 h_vlan_encapsulated_proto; }; struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(max_entries, 1); __type(key, __u32); __type(value, struct packet_stats); } stats_map SEC(".maps"); SEC("xdp") int bridge_filter(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; struct ethhdr *eth = data; __u16 h_proto; struct iphdr *iph; int action = XDP_PASS; __u32 key = 0; struct packet_stats *stats; if ((void*)(eth + 1) > data_end) return XDP_ABORTED; h_proto = eth->h_proto; // Tráfego broadcast/multicast: libera imediatamente if (eth->h_dest[0] & 1) goto stats; // VLAN if (h_proto == bpf_htons(ETH_P_8021Q) || h_proto == bpf_htons(ETH_P_8021AD)) { struct vlan_hdr *vhdr = (void *)(eth + 1); if ((void *)(vhdr + 1) > data_end) return XDP_ABORTED; h_proto = vhdr->h_vlan_encapsulated_proto; iph = (void *)(vhdr + 1); } else { iph = (void *)(eth + 1); } // IPv4 local: libera imediatamente if (h_proto == bpf_htons(ETH_P_IP)) { if ((void*)(iph + 1) > data_end) goto stats; if ((iph->daddr & bpf_htonl(0xffff0000)) == bpf_htonl(0x0a0f0000)) goto stats; } // ...outros filtros podem ser adicionados aqui... stats: // Atualizar estatísticas apenas uma vez stats = bpf_map_lookup_elem(&stats_map, &key); if (stats) { stats->packets++; stats->bytes += (data_end - data); } return action; } char _license[] SEC("license") = "GPL";