offset = sizeof(*eth); /* Make sure packet is large enough for parsing eth + 2 VLAN headers */ if ((void *)eth + offset + (2*sizeof(struct _vlan_hdr)) > data_end) returnfalse;
eth_type = eth->h_proto;
/* Handle outer VLAN tag */ if (eth_type == bpf_htons(ETH_P_8021Q)
|| eth_type == bpf_htons(ETH_P_8021AD)) { struct _vlan_hdr *vlan_hdr;
if (!parse_eth_frame(data, data_end, &pkt)) return XDP_ABORTED;
/* Drop specific VLAN ID example */ if (pkt.vlan_outer == TESTVLAN) return XDP_ABORTED; /* * Using XDP_ABORTED makes it possible to record this event, * via tracepoint xdp:xdp_exception like: * # perf record -a -e xdp:xdp_exception * # perf script
*/ return XDP_PASS;
} /* Commands to setup VLAN on Linux to test packets gets dropped:
export ROOTDEV=ixgbe2 export VLANID=4011 ip link add link $ROOTDEV name $ROOTDEV.$VLANID type vlan id $VLANID ip link set dev $ROOTDEV.$VLANID up
ip link set dev $ROOTDEV mtu 1508 ip addr add 100.64.40.11/24 dev $ROOTDEV.$VLANID
Load prog with ip tool:
ip link set $ROOTDEV xdp off ip link set $ROOTDEV xdp object xdp_vlan01_kern.o section xdp_drop_vlan_4011
*/
/* Changing VLAN to zero, have same practical effect as removing the VLAN. */ #define TO_VLAN 0
/* * Show XDP+TC can cooperate, on creating a VLAN rewriter. * 1. Create a XDP prog that can "pop"/remove a VLAN header. * 2. Create a TC-bpf prog that egress can add a VLAN header.
*/
if (!parse_eth_frame(data, data_end, &pkt)) return XDP_ABORTED;
/* Skip packet if no outer VLAN was detected */ if (pkt.vlan_outer_offset == 0) return XDP_PASS;
/* Moving Ethernet header, dest overlap with src, memmove handle this */
dest = data;
dest += VLAN_HDR_SZ; /* * Notice: Taking over vlan_hdr->h_vlan_encapsulated_proto, by * only moving two MAC addrs (12 bytes), not overwriting last 2 bytes
*/
__builtin_memmove(dest, data, ETH_ALEN * 2); /* Note: LLVM built-in memmove inlining require size to be constant */
/* Move start of packet header seen by Linux kernel stack */
bpf_xdp_adjust_head(ctx, VLAN_HDR_SZ);
/* Assuming VLAN hdr present. The 4 bytes in p[3] that gets * overwritten, is ethhdr->h_proto and vlan_hdr->h_vlan_TCI. * The vlan_hdr->h_vlan_encapsulated_proto take over role as * ethhdr->h_proto.
*/
p[3] = p[2];
p[2] = p[1];
p[1] = p[0];
}
if (!parse_eth_frame(orig_eth, data_end, &pkt)) return XDP_ABORTED;
/* Skip packet if no outer VLAN was detected */ if (pkt.vlan_outer_offset == 0) return XDP_PASS;
/* Simply shift down MAC addrs 4 bytes, overwrite h_proto + TCI */
shift_mac_4bytes_32bit(data);
/* Move start of packet header seen by Linux kernel stack */
bpf_xdp_adjust_head(ctx, VLAN_HDR_SZ);
return XDP_PASS;
}
/*===================================== * BELOW: TC-hook based ebpf programs * ==================================== * The TC-clsact eBPF programs (currently) need to be attach via TC commands
*/
SEC("tc") int tc_vlan_push(struct __sk_buff *ctx)
{
bpf_skb_vlan_push(ctx, bpf_htons(ETH_P_8021Q), TESTVLAN);
return TC_ACT_OK;
} /* Commands to setup TC to use above bpf prog:
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.