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_redirect_user.c (4425B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright (c) 2016 John Fastabend <john.r.fastabend@intel.com>
      3 */
      4static const char *__doc__ =
      5"XDP redirect tool, using bpf_redirect helper\n"
      6"Usage: xdp_redirect <IFINDEX|IFNAME>_IN <IFINDEX|IFNAME>_OUT\n";
      7
      8#include <linux/bpf.h>
      9#include <linux/if_link.h>
     10#include <assert.h>
     11#include <errno.h>
     12#include <signal.h>
     13#include <stdio.h>
     14#include <stdlib.h>
     15#include <stdbool.h>
     16#include <string.h>
     17#include <net/if.h>
     18#include <unistd.h>
     19#include <libgen.h>
     20#include <getopt.h>
     21#include <bpf/bpf.h>
     22#include <bpf/libbpf.h>
     23#include "bpf_util.h"
     24#include "xdp_sample_user.h"
     25#include "xdp_redirect.skel.h"
     26
     27static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT |
     28		  SAMPLE_EXCEPTION_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI;
     29
     30DEFINE_SAMPLE_INIT(xdp_redirect);
     31
     32static const struct option long_options[] = {
     33	{"help",	no_argument,		NULL, 'h' },
     34	{"skb-mode",	no_argument,		NULL, 'S' },
     35	{"force",	no_argument,		NULL, 'F' },
     36	{"stats",	no_argument,		NULL, 's' },
     37	{"interval",	required_argument,	NULL, 'i' },
     38	{"verbose",	no_argument,		NULL, 'v' },
     39	{}
     40};
     41
     42int main(int argc, char **argv)
     43{
     44	int ifindex_in, ifindex_out, opt;
     45	char str[2 * IF_NAMESIZE + 1];
     46	char ifname_out[IF_NAMESIZE];
     47	char ifname_in[IF_NAMESIZE];
     48	int ret = EXIT_FAIL_OPTION;
     49	unsigned long interval = 2;
     50	struct xdp_redirect *skel;
     51	bool generic = false;
     52	bool force = false;
     53	bool error = true;
     54
     55	while ((opt = getopt_long(argc, argv, "hSFi:vs",
     56				  long_options, NULL)) != -1) {
     57		switch (opt) {
     58		case 'S':
     59			generic = true;
     60			mask &= ~(SAMPLE_DEVMAP_XMIT_CNT |
     61				  SAMPLE_DEVMAP_XMIT_CNT_MULTI);
     62			break;
     63		case 'F':
     64			force = true;
     65			break;
     66		case 'i':
     67			interval = strtoul(optarg, NULL, 0);
     68			break;
     69		case 'v':
     70			sample_switch_mode();
     71			break;
     72		case 's':
     73			mask |= SAMPLE_REDIRECT_CNT;
     74			break;
     75		case 'h':
     76			error = false;
     77		default:
     78			sample_usage(argv, long_options, __doc__, mask, error);
     79			return ret;
     80		}
     81	}
     82
     83	if (argc <= optind + 1) {
     84		sample_usage(argv, long_options, __doc__, mask, true);
     85		return ret;
     86	}
     87
     88	ifindex_in = if_nametoindex(argv[optind]);
     89	if (!ifindex_in)
     90		ifindex_in = strtoul(argv[optind], NULL, 0);
     91
     92	ifindex_out = if_nametoindex(argv[optind + 1]);
     93	if (!ifindex_out)
     94		ifindex_out = strtoul(argv[optind + 1], NULL, 0);
     95
     96	if (!ifindex_in || !ifindex_out) {
     97		fprintf(stderr, "Bad interface index or name\n");
     98		sample_usage(argv, long_options, __doc__, mask, true);
     99		goto end;
    100	}
    101
    102	skel = xdp_redirect__open();
    103	if (!skel) {
    104		fprintf(stderr, "Failed to xdp_redirect__open: %s\n", strerror(errno));
    105		ret = EXIT_FAIL_BPF;
    106		goto end;
    107	}
    108
    109	ret = sample_init_pre_load(skel);
    110	if (ret < 0) {
    111		fprintf(stderr, "Failed to sample_init_pre_load: %s\n", strerror(-ret));
    112		ret = EXIT_FAIL_BPF;
    113		goto end_destroy;
    114	}
    115
    116	skel->rodata->from_match[0] = ifindex_in;
    117	skel->rodata->to_match[0] = ifindex_out;
    118	skel->rodata->ifindex_out = ifindex_out;
    119
    120	ret = xdp_redirect__load(skel);
    121	if (ret < 0) {
    122		fprintf(stderr, "Failed to xdp_redirect__load: %s\n", strerror(errno));
    123		ret = EXIT_FAIL_BPF;
    124		goto end_destroy;
    125	}
    126
    127	ret = sample_init(skel, mask);
    128	if (ret < 0) {
    129		fprintf(stderr, "Failed to initialize sample: %s\n", strerror(-ret));
    130		ret = EXIT_FAIL;
    131		goto end_destroy;
    132	}
    133
    134	ret = EXIT_FAIL_XDP;
    135	if (sample_install_xdp(skel->progs.xdp_redirect_prog, ifindex_in,
    136			       generic, force) < 0)
    137		goto end_destroy;
    138
    139	/* Loading dummy XDP prog on out-device */
    140	sample_install_xdp(skel->progs.xdp_redirect_dummy_prog, ifindex_out,
    141			   generic, force);
    142
    143	ret = EXIT_FAIL;
    144	if (!if_indextoname(ifindex_in, ifname_in)) {
    145		fprintf(stderr, "Failed to if_indextoname for %d: %s\n", ifindex_in,
    146			strerror(errno));
    147		goto end_destroy;
    148	}
    149
    150	if (!if_indextoname(ifindex_out, ifname_out)) {
    151		fprintf(stderr, "Failed to if_indextoname for %d: %s\n", ifindex_out,
    152			strerror(errno));
    153		goto end_destroy;
    154	}
    155
    156	safe_strncpy(str, get_driver_name(ifindex_in), sizeof(str));
    157	printf("Redirecting from %s (ifindex %d; driver %s) to %s (ifindex %d; driver %s)\n",
    158	       ifname_in, ifindex_in, str, ifname_out, ifindex_out, get_driver_name(ifindex_out));
    159	snprintf(str, sizeof(str), "%s->%s", ifname_in, ifname_out);
    160
    161	ret = sample_run(interval, NULL, NULL);
    162	if (ret < 0) {
    163		fprintf(stderr, "Failed during sample run: %s\n", strerror(-ret));
    164		ret = EXIT_FAIL;
    165		goto end_destroy;
    166	}
    167	ret = EXIT_OK;
    168end_destroy:
    169	xdp_redirect__destroy(skel);
    170end:
    171	sample_exit(ret);
    172}