File Index
Files and directories
Sign in
FILE

test_tc_link.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/test_tc_link.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2023 Isovalent */
  3#include <stdbool.h>
  4
  5#include <linux/bpf.h>
  6#include <linux/if_ether.h>
  7#include <linux/stddef.h>
  8#include <linux/if_packet.h>
  9#include <bpf/bpf_endian.h>
 10#include <bpf/bpf_helpers.h>
 11#include <bpf/bpf_core_read.h>
 12
 13char LICENSE[] SEC("license") = "GPL";
 14
 15bool seen_tc1;
 16bool seen_tc2;
 17bool seen_tc3;
 18bool seen_tc4;
 19bool seen_tc5;
 20bool seen_tc6;
 21bool seen_tc7;
 22bool seen_tc8;
 23
 24bool set_type;
 25
 26bool seen_eth;
 27bool seen_host;
 28bool seen_mcast;
 29
 30int mark, prio;
 31unsigned short headroom, tailroom;
 32
 33SEC("tc/ingress")
 34int tc1(struct __sk_buff *skb)
 35{
 36	struct ethhdr eth = {};
 37
 38	if (skb->protocol != __bpf_constant_htons(ETH_P_IP))
 39		goto out;
 40	if (bpf_skb_load_bytes(skb, 0, &eth, sizeof(eth)))
 41		goto out;
 42	seen_eth = eth.h_proto == bpf_htons(ETH_P_IP);
 43	seen_host = skb->pkt_type == PACKET_HOST;
 44	if (seen_host && set_type) {
 45		eth.h_dest[0] = 4;
 46		if (bpf_skb_store_bytes(skb, 0, &eth, sizeof(eth), 0))
 47			goto fail;
 48		bpf_skb_change_type(skb, PACKET_MULTICAST);
 49	}
 50out:
 51	seen_tc1 = true;
 52fail:
 53	return TCX_NEXT;
 54}
 55
 56SEC("tc/egress")
 57int tc2(struct __sk_buff *skb)
 58{
 59	seen_tc2 = true;
 60	return TCX_NEXT;
 61}
 62
 63SEC("tc/egress")
 64int tc3(struct __sk_buff *skb)
 65{
 66	seen_tc3 = true;
 67	return TCX_NEXT;
 68}
 69
 70SEC("tc/egress")
 71int tc4(struct __sk_buff *skb)
 72{
 73	seen_tc4 = true;
 74	return TCX_NEXT;
 75}
 76
 77SEC("tc/egress")
 78int tc5(struct __sk_buff *skb)
 79{
 80	seen_tc5 = true;
 81	return TCX_PASS;
 82}
 83
 84SEC("tc/egress")
 85int tc6(struct __sk_buff *skb)
 86{
 87	seen_tc6 = true;
 88	return TCX_PASS;
 89}
 90
 91SEC("tc/ingress")
 92int tc7(struct __sk_buff *skb)
 93{
 94	struct ethhdr eth = {};
 95
 96	if (skb->protocol != __bpf_constant_htons(ETH_P_IP))
 97		goto out;
 98	if (bpf_skb_load_bytes(skb, 0, &eth, sizeof(eth)))
 99		goto out;
100	if (eth.h_dest[0] == 4 && set_type) {
101		seen_mcast = skb->pkt_type == PACKET_MULTICAST;
102		bpf_skb_change_type(skb, PACKET_HOST);
103	}
104out:
105	seen_tc7 = true;
106	return TCX_PASS;
107}
108
109struct sk_buff {
110	struct net_device *dev;
111};
112
113struct net_device {
114	unsigned short needed_headroom;
115	unsigned short needed_tailroom;
116};
117
118SEC("tc/egress")
119int tc8(struct __sk_buff *skb)
120{
121	struct net_device *dev = BPF_CORE_READ((struct sk_buff *)skb, dev);
122
123	seen_tc8 = true;
124	mark = skb->mark;
125	prio = skb->priority;
126	headroom = BPF_CORE_READ(dev, needed_headroom);
127	tailroom = BPF_CORE_READ(dev, needed_tailroom);
128	return TCX_PASS;
129}
~/ Read-only file preview.