zenith-stack 0.1.0

Zenith 全协议栈框架:AF_XDP + eBPF + TLS 1.3 + HTTP/1-2-3 + Web + Proxy + WAF,按需导入
Documentation
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Zenith XSKMAP 重定向逻辑 - 双 Bank 热更新支撑
 *
 * 功能:
 * - 将数据包重定向到对应的 AF_XDP Socket
 * - 支持双 Bank 热更新(由用户态 bpf_link update_prog 原子切换)
 * - 仅做最小化前置校验,来源准入由用户态 SourceAdmissionEngine 完成
 *
 * 设计原则(AGENT.md §4.1 铁律):
 * - 内核态只做可证安全的最小导流
 * - 禁止使用哈希 Map、动态扩容 Map、无界数据结构
 * - 禁止在 eBPF 中实现复杂业务逻辑(如来源准入白名单)
 *   → 来源准入统一在用户态 SourceAdmissionEngine 中完成
 *
 * ⚠️ Bank A/B 语义边界:
 * - Bank A/B 仅用于"已由上游完成准入"的场景或纯诊断观察,不应替代
 *   zenith_xdp_main 用于生产过滤。xdp_main 承载完整的 L2/L3 校验 +
 *   协议白名单 + fail_closed 策略;Bank A/B 仅做最小 EtherType 过滤后
 *   即重定向,不做 IP 头校验、协议白名单或 MTU 检查。
 * - 生产数据面应绑定 zenith_xdp_main;Bank A/B 适用于热更新切换的
 *   过渡窗口或诊断/调试路径。
 */

#include "xdp_common.h"

/*
 * XSKMAP 重定向共享逻辑(Bank A/B 共用)
 * 仅做最小 EtherType 过滤后即重定向,不做 IP 头校验、协议白名单或 MTU 检查。
 */
static __always_inline int
zenith_xdp_redirect_impl(struct xdp_md *ctx)
{
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;
    u32 queue_id;
    u32 fail_closed;

    /* 基础长度校验(保证最小以太网头长度) */
    if ((void *)(data + ETH_HLEN) > data_end) {
        update_stats(STATS_RX_DROP_SHORT, 1);
        return XDP_DROP;
    }

    /* 最小 EtherType 过滤:仅重定向 IPv4/IPv6/ARP 帧,
     * 非 IP/非 ARP 帧(LLDP/STP/mDNS 等)PASS 回退内核协议栈,
     * 不重定向到 AF_XDP(避免非 IP 流量绕过 xdp_main 的过滤链)。 */
    struct ethhdr *eth = data;
    __u16 proto = eth->h_proto;
    if (proto != bpf_htons(ETH_P_IP) &&
        proto != bpf_htons(ETH_P_IPV6) &&
        proto != bpf_htons(ETH_P_ARP)) {
        update_stats(STATS_RX_DROP_PROTO, 1);
        return XDP_PASS;
    }

    /* 读取运行时配置 */
    fail_closed = get_config_u32(CONFIG_KEY_FAIL_CLOSED);

    /* 队列归属与 XSKMAP 查找 */
    queue_id = ctx->rx_queue_index;
    u32 *xsk_fd = bpf_map_lookup_elem(&xsk_map, &queue_id);
    if (!xsk_fd) {
        update_stats(STATS_RX_DROP_NO_XSK, 1);
        if (fail_closed)
            return XDP_DROP;
        return XDP_PASS;
    }

    /* 重定向到 AF_XDP(来源准入由用户态 SourceAdmissionEngine 完成) */
    update_stats(STATS_REDIRECTED, 1);
    return bpf_redirect_map(&xsk_map, queue_id, XDP_PASS);
}

/*
 * XSKMAP 重定向程序 - Bank A
 * 用于双 Bank 热更新场景,与 Bank B 形成原子切换对。
 * Bank 切换由用户态 bpf_link update_prog 原子替换完成,
 * 内核态不再读取活动 Bank 状态(A/B Map 方案已废止)。
 *
 * ⚠️ 本程序仅用于"已由上游完成准入"的场景或纯诊断,不应替代
 * zenith_xdp_main 用于生产过滤。此处仅做最小 EtherType 过滤:
 * 非 IPv4/IPv6/ARP 帧(如 LLDP/STP 等)直接 XDP_PASS 回退内核协议栈,
 * 不重定向到 AF_XDP。IP 头校验/协议白名单/MTU 检查由 xdp_main 承载。
 */
SEC("xdp")
int zenith_xdp_redirect_a(struct xdp_md *ctx)
{
    return zenith_xdp_redirect_impl(ctx);
}

/*
 * XSKMAP 重定向程序 - Bank B
 * 与 Bank A 形成原子切换对,逻辑完全对称。
 *
 * ⚠️ 本程序仅用于"已由上游完成准入"的场景或纯诊断,不应替代
 * zenith_xdp_main 用于生产过滤。此处仅做最小 EtherType 过滤:
 * 非 IPv4/IPv6/ARP 帧(如 LLDP/STP 等)直接 XDP_PASS 回退内核协议栈,
 * 不重定向到 AF_XDP。IP 头校验/协议白名单/MTU 检查由 xdp_main 承载。
 */
SEC("xdp")
int zenith_xdp_redirect_b(struct xdp_md *ctx)
{
    return zenith_xdp_redirect_impl(ctx);
}

char _license[] SEC("license") = "GPL";