简体   繁体   中英

Berkeley Packet Filters for VLAN priority

I need to filter priority into VLAN header to ensure Voice priority value.
Using BPF filtering is possible to evaluate which packets contains priority bits value into VLAN header are equals to five?
Regards
Vincenzo

Yes you can, the exact way to do it depends on the type of eBPF program.

For programs with __sk_buff contexts( TC , Socket filter , cGroup SKB)

eBPF program types which get a __sk_buff as context can just access the vlan_tci field. This fields should already be in host byte order so you can just mask and bit shift the value to get the PCP field.

For XDP programs

In XDP programs we need to manually parse all network layers before we can access the TCI field.

XDP tutorial has a few parsing functions which are a good base, including 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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