103 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 12char LICENSE[] SEC("license") = "GPL";13 14bool seen_tc1;15bool seen_tc2;16bool seen_tc3;17bool seen_tc4;18bool seen_tc5;19bool seen_tc6;20bool seen_tc7;21 22bool set_type;23 24bool seen_eth;25bool seen_host;26bool seen_mcast;27 28SEC("tc/ingress")29int tc1(struct __sk_buff *skb)30{31 struct ethhdr eth = {};32 33 if (skb->protocol != __bpf_constant_htons(ETH_P_IP))34 goto out;35 if (bpf_skb_load_bytes(skb, 0, ð, sizeof(eth)))36 goto out;37 seen_eth = eth.h_proto == bpf_htons(ETH_P_IP);38 seen_host = skb->pkt_type == PACKET_HOST;39 if (seen_host && set_type) {40 eth.h_dest[0] = 4;41 if (bpf_skb_store_bytes(skb, 0, ð, sizeof(eth), 0))42 goto fail;43 bpf_skb_change_type(skb, PACKET_MULTICAST);44 }45out:46 seen_tc1 = true;47fail:48 return TCX_NEXT;49}50 51SEC("tc/egress")52int tc2(struct __sk_buff *skb)53{54 seen_tc2 = true;55 return TCX_NEXT;56}57 58SEC("tc/egress")59int tc3(struct __sk_buff *skb)60{61 seen_tc3 = true;62 return TCX_NEXT;63}64 65SEC("tc/egress")66int tc4(struct __sk_buff *skb)67{68 seen_tc4 = true;69 return TCX_NEXT;70}71 72SEC("tc/egress")73int tc5(struct __sk_buff *skb)74{75 seen_tc5 = true;76 return TCX_PASS;77}78 79SEC("tc/egress")80int tc6(struct __sk_buff *skb)81{82 seen_tc6 = true;83 return TCX_PASS;84}85 86SEC("tc/ingress")87int tc7(struct __sk_buff *skb)88{89 struct ethhdr eth = {};90 91 if (skb->protocol != __bpf_constant_htons(ETH_P_IP))92 goto out;93 if (bpf_skb_load_bytes(skb, 0, ð, sizeof(eth)))94 goto out;95 if (eth.h_dest[0] == 4 && set_type) {96 seen_mcast = skb->pkt_type == PACKET_MULTICAST;97 bpf_skb_change_type(skb, PACKET_HOST);98 }99out:100 seen_tc7 = true;101 return TCX_PASS;102}103