简体   繁体   English

用于 VLAN 优先级的伯克利包过滤器

[英]Berkeley Packet Filters for VLAN priority

I need to filter priority into VLAN header to ensure Voice priority value.我需要将优先级过滤到 VLAN header 以确保语音优先级值。
Using BPF filtering is possible to evaluate which packets contains priority bits value into VLAN header are equals to five?使用 BPF 过滤可以评估哪些数据包包含进入 VLAN header 的优先级值等于 5?
Regards问候
Vincenzo文森佐

Yes you can, the exact way to do it depends on the type of eBPF program.是的,你可以,具体的方法取决于 eBPF 程序的类型。

For programs with __sk_buff contexts( TC , Socket filter , cGroup SKB)对于具有__sk_buff上下文的程序( TC套接字过滤器、cGroup SKB)

eBPF program types which get a __sk_buff as context can just access the vlan_tci field.获得__sk_buff作为上下文的 eBPF 程序类型只能访问vlan_tci字段。 This fields should already be in host byte order so you can just mask and bit shift the value to get the PCP field.该字段应该已经按主机字节顺序排列,因此您只需对值进行掩码和位移即可获得PCP字段。

For XDP programs对于 XDP 程序

In XDP programs we need to manually parse all network layers before we can access the TCI field.在 XDP 程序中,我们需要手动解析所有网络层,然后才能访问 TCI 字段。

XDP tutorial has a few parsing functions which are a good base, including parse_ethhdr_vlan : XDP 教程有一些解析函数是很好的基础,包括parse_ethhdr_vlan

/* Notice, parse_ethhdr() will skip VLAN tags, by advancing nh->pos and returns
 * next header EtherType, BUT the ethhdr pointer supplied still points to the
 * Ethernet header. Thus, caller can look at eth->h_proto to see if this was a
 * VLAN tagged packet.
 */
static __always_inline int parse_ethhdr_vlan(struct hdr_cursor *nh,
                         void *data_end,
                         struct ethhdr **ethhdr,
                         struct collect_vlans *vlans)
{
    struct ethhdr *eth = nh->pos;
    int hdrsize = sizeof(*eth);
    struct vlan_hdr *vlh;
    __u16 h_proto;
    int i;

    /* Byte-count bounds check; check if current pointer + size of header
     * is after data_end.
     */
    if (nh->pos + hdrsize > data_end)
        return -1;

    nh->pos += hdrsize;
    *ethhdr = eth;
    vlh = nh->pos;
    h_proto = eth->h_proto;

    /* Use loop unrolling to avoid the verifier restriction on loops;
     * support up to VLAN_MAX_DEPTH layers of VLAN encapsulation.
     */
    #pragma unroll
    for (i = 0; i < VLAN_MAX_DEPTH; i++) {
        if (!proto_is_vlan(h_proto))
            break;

        if (vlh + 1 > data_end)
            break;

        h_proto = vlh->h_vlan_encapsulated_proto;
        if (vlans) /* collect VLAN ids */
            vlans->id[i] =
                (bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK);

        vlh++;
    }

    nh->pos = vlh;
    return h_proto; /* network-byte-order */
}

You will have to modify this function for your purposes since it currently discards the PCP field you are after vlans->id[i] = (bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK);您将不得不根据您的目的修改此 function,因为它当前会丢弃您在vlans->id[i] = (bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK);之后的PCP字段;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM