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

netlink_dumper.c (4315B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
      2// Copyright (C) 2018 Facebook
      3
      4#include <stdlib.h>
      5#include <string.h>
      6#include <bpf/libbpf.h>
      7#include <linux/rtnetlink.h>
      8#include <linux/tc_act/tc_bpf.h>
      9
     10#include "bpf/nlattr.h"
     11#include "main.h"
     12#include "netlink_dumper.h"
     13
     14static void xdp_dump_prog_id(struct nlattr **tb, int attr,
     15			     const char *mode,
     16			     bool new_json_object)
     17{
     18	if (!tb[attr])
     19		return;
     20
     21	if (new_json_object)
     22		NET_START_OBJECT
     23	NET_DUMP_STR("mode", " %s", mode);
     24	NET_DUMP_UINT("id", " id %u", libbpf_nla_getattr_u32(tb[attr]))
     25	if (new_json_object)
     26		NET_END_OBJECT
     27}
     28
     29static int do_xdp_dump_one(struct nlattr *attr, unsigned int ifindex,
     30			   const char *name)
     31{
     32	struct nlattr *tb[IFLA_XDP_MAX + 1];
     33	unsigned char mode;
     34
     35	if (libbpf_nla_parse_nested(tb, IFLA_XDP_MAX, attr, NULL) < 0)
     36		return -1;
     37
     38	if (!tb[IFLA_XDP_ATTACHED])
     39		return 0;
     40
     41	mode = libbpf_nla_getattr_u8(tb[IFLA_XDP_ATTACHED]);
     42	if (mode == XDP_ATTACHED_NONE)
     43		return 0;
     44
     45	NET_START_OBJECT;
     46	if (name)
     47		NET_DUMP_STR("devname", "%s", name);
     48	NET_DUMP_UINT("ifindex", "(%d)", ifindex);
     49
     50	if (mode == XDP_ATTACHED_MULTI) {
     51		if (json_output) {
     52			jsonw_name(json_wtr, "multi_attachments");
     53			jsonw_start_array(json_wtr);
     54		}
     55		xdp_dump_prog_id(tb, IFLA_XDP_SKB_PROG_ID, "generic", true);
     56		xdp_dump_prog_id(tb, IFLA_XDP_DRV_PROG_ID, "driver", true);
     57		xdp_dump_prog_id(tb, IFLA_XDP_HW_PROG_ID, "offload", true);
     58		if (json_output)
     59			jsonw_end_array(json_wtr);
     60	} else if (mode == XDP_ATTACHED_DRV) {
     61		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "driver", false);
     62	} else if (mode == XDP_ATTACHED_SKB) {
     63		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "generic", false);
     64	} else if (mode == XDP_ATTACHED_HW) {
     65		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "offload", false);
     66	}
     67
     68	NET_END_OBJECT_FINAL;
     69	return 0;
     70}
     71
     72int do_xdp_dump(struct ifinfomsg *ifinfo, struct nlattr **tb)
     73{
     74	if (!tb[IFLA_XDP])
     75		return 0;
     76
     77	return do_xdp_dump_one(tb[IFLA_XDP], ifinfo->ifi_index,
     78			       libbpf_nla_getattr_str(tb[IFLA_IFNAME]));
     79}
     80
     81static int do_bpf_dump_one_act(struct nlattr *attr)
     82{
     83	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
     84
     85	if (libbpf_nla_parse_nested(tb, TCA_ACT_BPF_MAX, attr, NULL) < 0)
     86		return -LIBBPF_ERRNO__NLPARSE;
     87
     88	if (!tb[TCA_ACT_BPF_PARMS])
     89		return -LIBBPF_ERRNO__NLPARSE;
     90
     91	NET_START_OBJECT_NESTED2;
     92	if (tb[TCA_ACT_BPF_NAME])
     93		NET_DUMP_STR("name", "%s",
     94			     libbpf_nla_getattr_str(tb[TCA_ACT_BPF_NAME]));
     95	if (tb[TCA_ACT_BPF_ID])
     96		NET_DUMP_UINT("id", " id %u",
     97			      libbpf_nla_getattr_u32(tb[TCA_ACT_BPF_ID]));
     98	NET_END_OBJECT_NESTED;
     99	return 0;
    100}
    101
    102static int do_dump_one_act(struct nlattr *attr)
    103{
    104	struct nlattr *tb[TCA_ACT_MAX + 1];
    105
    106	if (!attr)
    107		return 0;
    108
    109	if (libbpf_nla_parse_nested(tb, TCA_ACT_MAX, attr, NULL) < 0)
    110		return -LIBBPF_ERRNO__NLPARSE;
    111
    112	if (tb[TCA_ACT_KIND] &&
    113	    strcmp(libbpf_nla_data(tb[TCA_ACT_KIND]), "bpf") == 0)
    114		return do_bpf_dump_one_act(tb[TCA_ACT_OPTIONS]);
    115
    116	return 0;
    117}
    118
    119static int do_bpf_act_dump(struct nlattr *attr)
    120{
    121	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
    122	int act, ret;
    123
    124	if (libbpf_nla_parse_nested(tb, TCA_ACT_MAX_PRIO, attr, NULL) < 0)
    125		return -LIBBPF_ERRNO__NLPARSE;
    126
    127	NET_START_ARRAY("act", " %s [");
    128	for (act = 0; act <= TCA_ACT_MAX_PRIO; act++) {
    129		ret = do_dump_one_act(tb[act]);
    130		if (ret)
    131			break;
    132	}
    133	NET_END_ARRAY("] ");
    134
    135	return ret;
    136}
    137
    138static int do_bpf_filter_dump(struct nlattr *attr)
    139{
    140	struct nlattr *tb[TCA_BPF_MAX + 1];
    141	int ret;
    142
    143	if (libbpf_nla_parse_nested(tb, TCA_BPF_MAX, attr, NULL) < 0)
    144		return -LIBBPF_ERRNO__NLPARSE;
    145
    146	if (tb[TCA_BPF_NAME])
    147		NET_DUMP_STR("name", " %s",
    148			     libbpf_nla_getattr_str(tb[TCA_BPF_NAME]));
    149	if (tb[TCA_BPF_ID])
    150		NET_DUMP_UINT("id", " id %u",
    151			      libbpf_nla_getattr_u32(tb[TCA_BPF_ID]));
    152	if (tb[TCA_BPF_ACT]) {
    153		ret = do_bpf_act_dump(tb[TCA_BPF_ACT]);
    154		if (ret)
    155			return ret;
    156	}
    157
    158	return 0;
    159}
    160
    161int do_filter_dump(struct tcmsg *info, struct nlattr **tb, const char *kind,
    162		   const char *devname, int ifindex)
    163{
    164	int ret = 0;
    165
    166	if (tb[TCA_OPTIONS] &&
    167	    strcmp(libbpf_nla_data(tb[TCA_KIND]), "bpf") == 0) {
    168		NET_START_OBJECT;
    169		if (devname[0] != '\0')
    170			NET_DUMP_STR("devname", "%s", devname);
    171		NET_DUMP_UINT("ifindex", "(%u)", ifindex);
    172		NET_DUMP_STR("kind", " %s", kind);
    173		ret = do_bpf_filter_dump(tb[TCA_OPTIONS]);
    174		NET_END_OBJECT_FINAL;
    175	}
    176
    177	return ret;
    178}