Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/bpf/progs/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  test_check_mtu.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Jesper Dangaard Brouer */

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <linux/if_ether.h>

#include <stddef.h>
#include <stdint.h>

char _license[] SEC("license") = "GPL";

/* Userspace will update with MTU it can see on device */
volatile const int GLOBAL_USER_MTU;
volatile const __u32 GLOBAL_USER_IFINDEX;

/* BPF-prog will update these with MTU values it can see */
__u32 global_bpf_mtu_xdp = 0;
__u32 global_bpf_mtu_tc  = 0;

SEC("xdp")
int xdp_use_helper_basic(struct xdp_md *ctx)
{
 __u32 mtu_len = 0;

 if (bpf_check_mtu(ctx, 0, &mtu_len, 0, 0))
  return XDP_ABORTED;

 return XDP_PASS;
}

SEC("xdp")
int xdp_use_helper(struct xdp_md *ctx)
{
 int retval = XDP_PASS; /* Expected retval on successful test */
 __u32 mtu_len = 0;
 __u32 ifindex = 0;
 int delta = 0;

 /* When ifindex is zero, save net_device lookup and use ctx netdev */
 if (GLOBAL_USER_IFINDEX > 0)
  ifindex = GLOBAL_USER_IFINDEX;

 if (bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0)) {
  /* mtu_len is also valid when check fail */
  retval = XDP_ABORTED;
  goto out;
 }

 if (mtu_len != GLOBAL_USER_MTU)
  retval = XDP_DROP;

out:
 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("xdp")
int xdp_exceed_mtu(struct xdp_md *ctx)
{
 void *data_end = (void *)(long)ctx->data_end;
 void *data = (void *)(long)ctx->data;
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 __u32 data_len = data_end - data;
 int retval = XDP_ABORTED; /* Fail */
 __u32 mtu_len = 0;
 int delta;
 int err;

 /* Exceed MTU with 1 via delta adjust */
 delta = GLOBAL_USER_MTU - (data_len - ETH_HLEN) + 1;

 err = bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0);
 if (err) {
  retval = XDP_PASS; /* Success in exceeding MTU check */
  if (err != BPF_MTU_CHK_RET_FRAG_NEEDED)
   retval = XDP_DROP;
 }

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("xdp")
int xdp_minus_delta(struct xdp_md *ctx)
{
 int retval = XDP_PASS; /* Expected retval on successful test */
 void *data_end = (void *)(long)ctx->data_end;
 void *data = (void *)(long)ctx->data;
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 __u32 data_len = data_end - data;
 __u32 mtu_len = 0;
 int delta;

 /* Borderline test case: Minus delta exceeding packet length allowed */
 delta = -((data_len - ETH_HLEN) + 1);

 /* Minus length (adjusted via delta) still pass MTU check, other helpers
 * are responsible for catching this, when doing actual size adjust
 */

 if (bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0))
  retval = XDP_ABORTED;

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("xdp")
int xdp_input_len(struct xdp_md *ctx)
{
 int retval = XDP_PASS; /* Expected retval on successful test */
 void *data_end = (void *)(long)ctx->data_end;
 void *data = (void *)(long)ctx->data;
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 __u32 data_len = data_end - data;

 /* API allow user give length to check as input via mtu_len param,
 * resulting MTU value is still output in mtu_len param after call.
 *
 * Input len is L3, like MTU and iph->tot_len.
 * Remember XDP data_len is L2.
 */

 __u32 mtu_len = data_len - ETH_HLEN;

 if (bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0))
  retval = XDP_ABORTED;

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("xdp")
int xdp_input_len_exceed(struct xdp_md *ctx)
{
 int retval = XDP_ABORTED; /* Fail */
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 int err;

 /* API allow user give length to check as input via mtu_len param,
 * resulting MTU value is still output in mtu_len param after call.
 *
 * Input length value is L3 size like MTU.
 */

 __u32 mtu_len = GLOBAL_USER_MTU;

 mtu_len += 1; /* Exceed with 1 */

 err = bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0);
 if (err == BPF_MTU_CHK_RET_FRAG_NEEDED)
  retval = XDP_PASS ; /* Success in exceeding MTU check */

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("tc")
int tc_use_helper(struct __sk_buff *ctx)
{
 int retval = BPF_OK; /* Expected retval on successful test */
 __u32 mtu_len = 0;
 int delta = 0;

 if (bpf_check_mtu(ctx, 0, &mtu_len, delta, 0)) {
  retval = BPF_DROP;
  goto out;
 }

 if (mtu_len != GLOBAL_USER_MTU)
  retval = BPF_REDIRECT;
out:
 global_bpf_mtu_tc = mtu_len;
 return retval;
}

SEC("tc")
int tc_exceed_mtu(struct __sk_buff *ctx)
{
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 int retval = BPF_DROP; /* Fail */
 __u32 skb_len = ctx->len;
 __u32 mtu_len = 0;
 int delta;
 int err;

 /* Exceed MTU with 1 via delta adjust */
 delta = GLOBAL_USER_MTU - (skb_len - ETH_HLEN) + 1;

 err = bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0);
 if (err) {
  retval = BPF_OK; /* Success in exceeding MTU check */
  if (err != BPF_MTU_CHK_RET_FRAG_NEEDED)
   retval = BPF_DROP;
 }

 global_bpf_mtu_tc = mtu_len;
 return retval;
}

SEC("tc")
int tc_exceed_mtu_da(struct __sk_buff *ctx)
{
 /* SKB Direct-Access variant */
 void *data_end = (void *)(long)ctx->data_end;
 void *data = (void *)(long)ctx->data;
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 __u32 data_len = data_end - data;
 int retval = BPF_DROP; /* Fail */
 __u32 mtu_len = 0;
 int delta;
 int err;

 /* Exceed MTU with 1 via delta adjust */
 delta = GLOBAL_USER_MTU - (data_len - ETH_HLEN) + 1;

 err = bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0);
 if (err) {
  retval = BPF_OK; /* Success in exceeding MTU check */
  if (err != BPF_MTU_CHK_RET_FRAG_NEEDED)
   retval = BPF_DROP;
 }

 global_bpf_mtu_tc = mtu_len;
 return retval;
}

SEC("tc")
int tc_minus_delta(struct __sk_buff *ctx)
{
 int retval = BPF_OK; /* Expected retval on successful test */
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 __u32 skb_len = ctx->len;
 __u32 mtu_len = 0;
 int delta;

 /* Borderline test case: Minus delta exceeding packet length allowed */
 delta = -((skb_len - ETH_HLEN) + 1);

 /* Minus length (adjusted via delta) still pass MTU check, other helpers
 * are responsible for catching this, when doing actual size adjust
 */

 if (bpf_check_mtu(ctx, ifindex, &mtu_len, delta, 0))
  retval = BPF_DROP;

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("tc")
int tc_input_len(struct __sk_buff *ctx)
{
 int retval = BPF_OK; /* Expected retval on successful test */
 __u32 ifindex = GLOBAL_USER_IFINDEX;

 /* API allow user give length to check as input via mtu_len param,
 * resulting MTU value is still output in mtu_len param after call.
 *
 * Input length value is L3 size.
 */

 __u32 mtu_len = GLOBAL_USER_MTU;

 if (bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0))
  retval = BPF_DROP;

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

SEC("tc")
int tc_input_len_exceed(struct __sk_buff *ctx)
{
 int retval = BPF_DROP; /* Fail */
 __u32 ifindex = GLOBAL_USER_IFINDEX;
 int err;

 /* API allow user give length to check as input via mtu_len param,
 * resulting MTU value is still output in mtu_len param after call.
 *
 * Input length value is L3 size like MTU.
 */

 __u32 mtu_len = GLOBAL_USER_MTU;

 mtu_len += 1; /* Exceed with 1 */

 err = bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0);
 if (err == BPF_MTU_CHK_RET_FRAG_NEEDED)
  retval = BPF_OK; /* Success in exceeding MTU check */

 global_bpf_mtu_xdp = mtu_len;
 return retval;
}

Messung V0.5
C=88 H=97 G=92

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.