cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xdp_rxq_info_kern.c (3231B)


      1/* SPDX-License-Identifier: GPL-2.0
      2 * Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
      3 *
      4 *  Example howto extract XDP RX-queue info
      5 */
      6#include <uapi/linux/bpf.h>
      7#include <uapi/linux/if_ether.h>
      8#include <uapi/linux/in.h>
      9#include <bpf/bpf_helpers.h>
     10
     11/* Config setup from with userspace
     12 *
     13 * User-side setup ifindex in config_map, to verify that
     14 * ctx->ingress_ifindex is correct (against configured ifindex)
     15 */
     16struct config {
     17	__u32 action;
     18	int ifindex;
     19	__u32 options;
     20};
     21enum cfg_options_flags {
     22	NO_TOUCH = 0x0U,
     23	READ_MEM = 0x1U,
     24	SWAP_MAC = 0x2U,
     25};
     26
     27struct {
     28	__uint(type, BPF_MAP_TYPE_ARRAY);
     29	__type(key, int);
     30	__type(value, struct config);
     31	__uint(max_entries, 1);
     32} config_map SEC(".maps");
     33
     34/* Common stats data record (shared with userspace) */
     35struct datarec {
     36	__u64 processed;
     37	__u64 issue;
     38};
     39
     40struct {
     41	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
     42	__type(key, u32);
     43	__type(value, struct datarec);
     44	__uint(max_entries, 1);
     45} stats_global_map SEC(".maps");
     46
     47#define MAX_RXQs 64
     48
     49/* Stats per rx_queue_index (per CPU) */
     50struct {
     51	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
     52	__type(key, u32);
     53	__type(value, struct datarec);
     54	__uint(max_entries, MAX_RXQs + 1);
     55} rx_queue_index_map SEC(".maps");
     56
     57static __always_inline
     58void swap_src_dst_mac(void *data)
     59{
     60	unsigned short *p = data;
     61	unsigned short dst[3];
     62
     63	dst[0] = p[0];
     64	dst[1] = p[1];
     65	dst[2] = p[2];
     66	p[0] = p[3];
     67	p[1] = p[4];
     68	p[2] = p[5];
     69	p[3] = dst[0];
     70	p[4] = dst[1];
     71	p[5] = dst[2];
     72}
     73
     74SEC("xdp_prog0")
     75int  xdp_prognum0(struct xdp_md *ctx)
     76{
     77	void *data_end = (void *)(long)ctx->data_end;
     78	void *data     = (void *)(long)ctx->data;
     79	struct datarec *rec, *rxq_rec;
     80	int ingress_ifindex;
     81	struct config *config;
     82	u32 key = 0;
     83
     84	/* Global stats record */
     85	rec = bpf_map_lookup_elem(&stats_global_map, &key);
     86	if (!rec)
     87		return XDP_ABORTED;
     88	rec->processed++;
     89
     90	/* Accessing ctx->ingress_ifindex, cause BPF to rewrite BPF
     91	 * instructions inside kernel to access xdp_rxq->dev->ifindex
     92	 */
     93	ingress_ifindex = ctx->ingress_ifindex;
     94
     95	config = bpf_map_lookup_elem(&config_map, &key);
     96	if (!config)
     97		return XDP_ABORTED;
     98
     99	/* Simple test: check ctx provided ifindex is as expected */
    100	if (ingress_ifindex != config->ifindex) {
    101		/* count this error case */
    102		rec->issue++;
    103		return XDP_ABORTED;
    104	}
    105
    106	/* Update stats per rx_queue_index. Handle if rx_queue_index
    107	 * is larger than stats map can contain info for.
    108	 */
    109	key = ctx->rx_queue_index;
    110	if (key >= MAX_RXQs)
    111		key = MAX_RXQs;
    112	rxq_rec = bpf_map_lookup_elem(&rx_queue_index_map, &key);
    113	if (!rxq_rec)
    114		return XDP_ABORTED;
    115	rxq_rec->processed++;
    116	if (key == MAX_RXQs)
    117		rxq_rec->issue++;
    118
    119	/* Default: Don't touch packet data, only count packets */
    120	if (unlikely(config->options & (READ_MEM|SWAP_MAC))) {
    121		struct ethhdr *eth = data;
    122
    123		if (eth + 1 > data_end)
    124			return XDP_ABORTED;
    125
    126		/* Avoid compiler removing this: Drop non 802.3 Ethertypes */
    127		if (ntohs(eth->h_proto) < ETH_P_802_3_MIN)
    128			return XDP_ABORTED;
    129
    130		/* XDP_TX requires changing MAC-addrs, else HW may drop.
    131		 * Can also be enabled with --swapmac (for test purposes)
    132		 */
    133		if (unlikely(config->options & SWAP_MAC))
    134			swap_src_dst_mac(data);
    135	}
    136
    137	return config->action;
    138}
    139
    140char _license[] SEC("license") = "GPL";