/* These are the identifiers of the BPF programs that will be used in tail * calls. Name is limited to 16 characters, with the terminating character and * bpf_func_ above, we have only 6 to work with, anything after will be cropped.
*/ #define IP 0 #define IPV6 1 #define IPV6OP 2 /* Destination/Hop-by-Hop Options IPv6 Ext. Header */ #define IPV6FR 3 /* Fragmentation IPv6 Extension Header */ #define MPLS 4 #define VLAN 5 #define MAX_PROG 6
switch (proto) { case IPPROTO_ICMP:
icmp = bpf_flow_dissect_get_header(skb, sizeof(*icmp), &_icmp); if (!icmp) return export_flow_keys(keys, BPF_DROP); return export_flow_keys(keys, BPF_OK); case IPPROTO_IPIP:
keys->is_encap = true; if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) return export_flow_keys(keys, BPF_OK);
return parse_eth_proto(skb, bpf_htons(ETH_P_IP)); case IPPROTO_IPV6:
keys->is_encap = true; if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) return export_flow_keys(keys, BPF_OK);
return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6)); case IPPROTO_GRE:
gre = bpf_flow_dissect_get_header(skb, sizeof(*gre), &_gre); if (!gre) return export_flow_keys(keys, BPF_DROP);
if (bpf_htons(gre->flags & GRE_VERSION)) /* Only inspect standard GRE packets with version 0 */ return export_flow_keys(keys, BPF_OK);
keys->thoff += sizeof(*gre); /* Step over GRE Flags and Proto */ if (GRE_IS_CSUM(gre->flags))
keys->thoff += 4; /* Step over chksum and Padding */ if (GRE_IS_KEY(gre->flags))
keys->thoff += 4; /* Step over key */ if (GRE_IS_SEQ(gre->flags))
keys->thoff += 4; /* Step over sequence number */
keys->is_encap = true; if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) return export_flow_keys(keys, BPF_OK);
if (gre->proto == bpf_htons(ETH_P_TEB)) {
eth = bpf_flow_dissect_get_header(skb, sizeof(*eth),
&_eth); if (!eth) return export_flow_keys(keys, BPF_DROP);
if (iph->frag_off & bpf_htons(IP_MF | IP_OFFSET)) {
keys->is_frag = true; if (iph->frag_off & bpf_htons(IP_OFFSET)) { /* From second fragment on, packets do not have headers * we can parse.
*/
done = true;
} else {
keys->is_first_frag = true; /* No need to parse fragmented packet unless * explicitly asked for.
*/ if (!(keys->flags &
BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG))
done = true;
}
}
ip6h = bpf_flow_dissect_get_header(skb, sizeof(*ip6h), &_ip6h); if (!ip6h) return export_flow_keys(keys, BPF_DROP);
/* hlen is in 8-octets and does not include the first 8 bytes * of the header
*/
keys->thoff += (1 + ip6h->hdrlen) << 3;
keys->ip_proto = ip6h->nexthdr;
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.