root/tools/bpf/bpftool/netlink_dumper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xdp_dump_prog_id
  2. do_xdp_dump_one
  3. do_xdp_dump
  4. do_bpf_dump_one_act
  5. do_dump_one_act
  6. do_bpf_act_dump
  7. do_bpf_filter_dump
  8. do_filter_dump

   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 <libbpf.h>
   7 #include <linux/rtnetlink.h>
   8 #include <linux/tc_act/tc_bpf.h>
   9 
  10 #include <nlattr.h>
  11 #include "main.h"
  12 #include "netlink_dumper.h"
  13 
  14 static 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 
  29 static 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 
  72 int 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 
  81 static 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 
 102 static 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 
 119 static 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 
 138 static 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 
 161 int 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 }

/* [<][>][^][v][top][bottom][index][help] */