samples: bpf: Add max_pckt_size option at xdp_adjust_tail
[linux-2.6-block.git] / samples / bpf / xdp_adjust_tail_kern.c
index 411fdb21f8bcf62efac06bdf8a80997e3615c7f5..c616508befb98ba83ae2e9cc6b3063e1c5f2f7bf 100644 (file)
@@ -25,6 +25,9 @@
 #define ICMP_TOOBIG_SIZE 98
 #define ICMP_TOOBIG_PAYLOAD_SIZE 92
 
+/* volatile to prevent compiler optimizations */
+static volatile __u32 max_pcktsz = MAX_PCKT_SIZE;
+
 struct bpf_map_def SEC("maps") icmpcnt = {
        .type = BPF_MAP_TYPE_ARRAY,
        .key_size = sizeof(__u32),
@@ -92,7 +95,7 @@ static __always_inline int send_icmp4_too_big(struct xdp_md *xdp)
        orig_iph = data + off;
        icmp_hdr->type = ICMP_DEST_UNREACH;
        icmp_hdr->code = ICMP_FRAG_NEEDED;
-       icmp_hdr->un.frag.mtu = htons(MAX_PCKT_SIZE-sizeof(struct ethhdr));
+       icmp_hdr->un.frag.mtu = htons(max_pcktsz - sizeof(struct ethhdr));
        icmp_hdr->checksum = 0;
        ipv4_csum(icmp_hdr, ICMP_TOOBIG_PAYLOAD_SIZE, &csum);
        icmp_hdr->checksum = csum;
@@ -121,7 +124,7 @@ static __always_inline int handle_ipv4(struct xdp_md *xdp)
        int pckt_size = data_end - data;
        int offset;
 
-       if (pckt_size > MAX_PCKT_SIZE) {
+       if (pckt_size > max(max_pcktsz, ICMP_TOOBIG_SIZE)) {
                offset = pckt_size - ICMP_TOOBIG_SIZE;
                if (bpf_xdp_adjust_tail(xdp, 0 - offset))
                        return XDP_PASS;