Compare commits

..

No commits in common. "main" and "v5.13.0" have entirely different histories.

171 changed files with 1313 additions and 6758 deletions

View File

@ -1,8 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Top level Makefile for iproute2
-include config.mk
ifeq ("$(origin V)", "command line")
VERBOSE = $(V)
endif
@ -15,6 +13,7 @@ MAKEFLAGS += --no-print-directory
endif
PREFIX?=/usr
LIBDIR?=$(PREFIX)/lib
SBINDIR?=/sbin
CONFDIR?=/etc/iproute2
NETNS_RUN_DIR?=/var/run/netns
@ -41,18 +40,9 @@ DEFINES+=-DCONFDIR=\"$(CONFDIR)\" \
-DNETNS_RUN_DIR=\"$(NETNS_RUN_DIR)\" \
-DNETNS_ETC_DIR=\"$(NETNS_ETC_DIR)\"
#options for AX.25
ADDLIB+=ax25_ntop.o
#options for AX.25
ADDLIB+=rose_ntop.o
#options for mpls
ADDLIB+=mpls_ntop.o mpls_pton.o
#options for NETROM
ADDLIB+=netrom_ntop.o
CC := gcc
HOSTCC ?= $(CC)
DEFINES += -D_GNU_SOURCE
@ -91,9 +81,7 @@ help:
@echo " V=[0|1] - set build verbosity level"
config.mk:
@if [ ! -f config.mk -o configure -nt config.mk ]; then \
sh configure $(KERNEL_INCLUDE); \
fi
sh configure $(KERNEL_INCLUDE)
install: all
install -m 0755 -d $(DESTDIR)$(SBINDIR)

View File

@ -12,9 +12,7 @@ int print_mdb_mon(struct nlmsghdr *n, void *arg);
int print_fdb(struct nlmsghdr *n, void *arg);
void print_stp_state(__u8 state);
int parse_stp_state(const char *arg);
int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor,
bool global_only);
void br_print_router_port_stats(struct rtattr *pattr);
int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor);
int do_fdb(int argc, char **argv);
int do_mdb(int argc, char **argv);

View File

@ -37,10 +37,10 @@ static void usage(void)
fprintf(stderr,
"Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
" bridge [ -force ] -batch filename\n"
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
" -c[ompressvlans] -color -p[retty] -j[son] }\n");
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
" -c[ompressvlans] -color -p[retty] -j[son] }\n");
exit(-1);
}
@ -149,9 +149,9 @@ main(int argc, char **argv)
NEXT_ARG();
if (netns_switch(argv[1]))
exit(-1);
} else if (matches_color(opt, &color)) {
} else if (matches(opt, "-compressvlans") == 0) {
++compress_vlans;
} else if (matches_color(opt, &color)) {
} else if (matches(opt, "-force") == 0) {
++force;
} else if (matches(opt, "-json") == 0) {

View File

@ -192,13 +192,10 @@ int print_fdb(struct nlmsghdr *n, void *arg)
"mac", "%s ", lladdr);
}
if (!filter_index && r->ndm_ifindex) {
print_string(PRINT_FP, NULL, "dev ", NULL);
if (!filter_index && r->ndm_ifindex)
print_color_string(PRINT_ANY, COLOR_IFNAME,
"ifname", "%s ",
"ifname", "dev %s ",
ll_index_to_name(r->ndm_ifindex));
}
if (tb[NDA_DST]) {
int family = AF_INET;
@ -211,11 +208,9 @@ int print_fdb(struct nlmsghdr *n, void *arg)
RTA_PAYLOAD(tb[NDA_DST]),
RTA_DATA(tb[NDA_DST]));
print_string(PRINT_FP, NULL, "dst ", NULL);
print_color_string(PRINT_ANY,
ifa_family_color(family),
"dst", "%s ", dst);
"dst", "dst %s ", dst);
}
if (vid)

View File

@ -59,7 +59,7 @@ static const char *format_timer(__u32 ticks, int align)
return tbuf;
}
void br_print_router_port_stats(struct rtattr *pattr)
static void __print_router_port_stats(FILE *f, struct rtattr *pattr)
{
struct rtattr *tb[MDBA_ROUTER_PATTR_MAX + 1];
@ -101,13 +101,13 @@ static void br_print_router_ports(FILE *f, struct rtattr *attr,
print_string(PRINT_JSON, "port", NULL, port_ifname);
if (show_stats)
br_print_router_port_stats(i);
__print_router_port_stats(f, i);
close_json_object();
} else if (show_stats) {
fprintf(f, "router ports on %s: %s",
brifname, port_ifname);
br_print_router_port_stats(i);
__print_router_port_stats(f, i);
fprintf(f, "\n");
} else {
fprintf(f, "%s ", port_ifname);

View File

@ -71,7 +71,7 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl,
case RTM_DELVLAN:
if (prefix_banner)
fprintf(fp, "[VLAN]");
return print_vlan_rtm(n, arg, true, false);
return print_vlan_rtm(n, arg, true);
default:
return 0;

View File

@ -9,7 +9,6 @@
#include <linux/if_bridge.h>
#include <linux/if_ether.h>
#include <string.h>
#include <errno.h>
#include "json_print.h"
#include "libnetlink.h"
@ -36,23 +35,8 @@ static void usage(void)
" [ pvid ] [ untagged ]\n"
" [ self ] [ master ]\n"
" bridge vlan { set } vid VLAN_ID dev DEV [ state STP_STATE ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n"
" bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
" bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
" bridge vlan global { set } vid VLAN_ID dev DEV\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_querier MULTICAST_QUERIER ]\n"
" [ mcast_igmp_version IGMP_VERSION ]\n"
" [ mcast_mld_version MLD_VERSION ]\n"
" [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
" [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
" [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
" [ mcast_startup_query_interval STARTUP_QUERY_INTERVAL ]\n"
" [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
" [ mcast_querier_interval QUERIER_INTERVAL ]\n"
" [ mcast_query_interval QUERY_INTERVAL ]\n"
" [ mcast_query_response_interval QUERY_RESPONSE_INTERVAL ]\n"
" bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
" bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n");
exit(-1);
}
@ -273,24 +257,16 @@ static int vlan_option_set(int argc, char **argv)
};
struct bridge_vlan_info vinfo = {};
struct rtattr *afspec;
short vid_end = -1;
char *d = NULL;
short vid = -1;
int state = -1;
afspec = addattr_nest(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY);
afspec->rta_type |= NLA_F_NESTED;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
d = *argv;
req.bvm.ifindex = ll_name_to_index(d);
if (req.bvm.ifindex == 0) {
fprintf(stderr,
"Cannot find network device \"%s\"\n",
d);
return -1;
}
} else if (strcmp(*argv, "vid") == 0) {
short vid_end = -1;
char *p;
NEXT_ARG();
@ -308,22 +284,8 @@ static int vlan_option_set(int argc, char **argv)
} else {
vid = atoi(*argv);
}
if (vid >= 4096) {
fprintf(stderr, "Invalid VLAN ID \"%hu\"\n",
vid);
return -1;
}
vinfo.flags = BRIDGE_VLAN_INFO_ONLY_OPTS;
vinfo.vid = vid;
addattr_l(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY_INFO,
&vinfo, sizeof(vinfo));
if (vid_end != -1)
addattr16(&req.n, sizeof(req),
BRIDGE_VLANDB_ENTRY_RANGE, vid_end);
} else if (strcmp(*argv, "state") == 0) {
char *endptr;
int state;
NEXT_ARG();
state = strtol(*argv, &endptr, 10);
@ -333,197 +295,42 @@ static int vlan_option_set(int argc, char **argv)
fprintf(stderr, "Error: invalid STP state\n");
return -1;
}
addattr8(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY_STATE,
state);
} else if (strcmp(*argv, "mcast_router") == 0) {
__u8 mcast_router;
NEXT_ARG();
if (get_u8(&mcast_router, *argv, 0))
invarg("invalid mcast_router", *argv);
addattr8(&req.n, sizeof(req),
BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
mcast_router);
} else {
if (matches(*argv, "help") == 0)
NEXT_ARG();
}
argc--; argv++;
}
addattr_nest_end(&req.n, afspec);
if (d == NULL || vid == -1) {
fprintf(stderr, "Device and VLAN ID are required arguments.\n");
return -1;
}
if (rtnl_talk(&rth, &req.n, NULL) < 0)
req.bvm.ifindex = ll_name_to_index(d);
if (req.bvm.ifindex == 0) {
fprintf(stderr, "Cannot find network device \"%s\"\n", d);
return -1;
}
return 0;
}
static int vlan_global_option_set(int argc, char **argv)
{
struct {
struct nlmsghdr n;
struct br_vlan_msg bvm;
char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_vlan_msg)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = RTM_NEWVLAN,
.bvm.family = PF_BRIDGE,
};
struct rtattr *afspec;
short vid_end = -1;
char *d = NULL;
short vid = -1;
__u64 val64;
__u32 val32;
__u8 val8;
afspec = addattr_nest(&req.n, sizeof(req),
BRIDGE_VLANDB_GLOBAL_OPTIONS);
if (vid >= 4096) {
fprintf(stderr, "Invalid VLAN ID \"%hu\"\n", vid);
return -1;
}
afspec = addattr_nest(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY);
afspec->rta_type |= NLA_F_NESTED;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
d = *argv;
req.bvm.ifindex = ll_name_to_index(d);
if (req.bvm.ifindex == 0) {
fprintf(stderr, "Cannot find network device \"%s\"\n",
d);
return -1;
}
} else if (strcmp(*argv, "vid") == 0) {
char *p;
NEXT_ARG();
p = strchr(*argv, '-');
if (p) {
*p = '\0';
p++;
vid = atoi(*argv);
vid_end = atoi(p);
if (vid >= vid_end || vid_end >= 4096) {
fprintf(stderr, "Invalid VLAN range \"%hu-%hu\"\n",
vid, vid_end);
return -1;
}
} else {
vid = atoi(*argv);
}
if (vid >= 4096) {
fprintf(stderr, "Invalid VLAN ID \"%hu\"\n",
vid);
return -1;
}
addattr16(&req.n, sizeof(req), BRIDGE_VLANDB_GOPTS_ID,
vid);
if (vid_end != -1)
addattr16(&req.n, sizeof(req),
BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
} else if (strcmp(*argv, "mcast_snooping") == 0) {
NEXT_ARG();
if (get_u8(&val8, *argv, 0))
invarg("invalid mcast_snooping", *argv);
addattr8(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
} else if (strcmp(*argv, "mcast_querier") == 0) {
NEXT_ARG();
if (get_u8(&val8, *argv, 0))
invarg("invalid mcast_querier", *argv);
addattr8(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, val8);
} else if (strcmp(*argv, "mcast_igmp_version") == 0) {
NEXT_ARG();
if (get_u8(&val8, *argv, 0))
invarg("invalid mcast_igmp_version", *argv);
addattr8(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION, val8);
} else if (strcmp(*argv, "mcast_mld_version") == 0) {
NEXT_ARG();
if (get_u8(&val8, *argv, 0))
invarg("invalid mcast_mld_version", *argv);
addattr8(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION, val8);
} else if (strcmp(*argv, "mcast_last_member_count") == 0) {
NEXT_ARG();
if (get_u32(&val32, *argv, 0))
invarg("invalid mcast_last_member_count", *argv);
addattr32(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
val32);
} else if (strcmp(*argv, "mcast_startup_query_count") == 0) {
NEXT_ARG();
if (get_u32(&val32, *argv, 0))
invarg("invalid mcast_startup_query_count",
*argv);
addattr32(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
val32);
} else if (strcmp(*argv, "mcast_last_member_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_last_member_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
val64);
} else if (strcmp(*argv, "mcast_membership_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_membership_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
val64);
} else if (strcmp(*argv, "mcast_querier_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_querier_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
val64);
} else if (strcmp(*argv, "mcast_query_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_query_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
val64);
} else if (strcmp(*argv, "mcast_query_response_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_query_response_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
val64);
} else if (strcmp(*argv, "mcast_startup_query_interval") == 0) {
NEXT_ARG();
if (get_u64(&val64, *argv, 0))
invarg("invalid mcast_startup_query_interval",
*argv);
addattr64(&req.n, 1024,
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
val64);
} else {
if (strcmp(*argv, "help") == 0)
NEXT_ARG();
}
argc--; argv++;
}
vinfo.flags = BRIDGE_VLAN_INFO_ONLY_OPTS;
vinfo.vid = vid;
addattr_l(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY_INFO, &vinfo,
sizeof(vinfo));
if (vid_end != -1)
addattr16(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY_RANGE,
vid_end);
if (state >= 0)
addattr8(&req.n, sizeof(req), BRIDGE_VLANDB_ENTRY_STATE, state);
addattr_nest_end(&req.n, afspec);
if (d == NULL || vid == -1) {
fprintf(stderr, "Device and VLAN ID are required arguments.\n");
return -1;
}
if (rtnl_talk(&rth, &req.n, NULL) < 0)
return -1;
@ -814,224 +621,11 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
return 0;
}
static void print_vlan_router_ports(struct rtattr *rattr)
{
int rem = RTA_PAYLOAD(rattr);
struct rtattr *i;
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
open_json_array(PRINT_ANY, is_json_context() ? "router_ports" :
"router ports: ");
for (i = RTA_DATA(rattr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
uint32_t *port_ifindex = RTA_DATA(i);
const char *port_ifname = ll_index_to_name(*port_ifindex);
open_json_object(NULL);
if (show_stats && i != RTA_DATA(rattr)) {
print_nl();
/* start: IFNAMSIZ + 4 + strlen("router ports: ") */
print_string(PRINT_FP, NULL,
"%-" __stringify(IFNAMSIZ) "s "
" ",
"");
}
print_string(PRINT_ANY, "port", "%s ", port_ifname);
if (show_stats)
br_print_router_port_stats(i);
close_json_object();
}
close_json_array(PRINT_JSON, NULL);
print_nl();
}
static void print_vlan_global_opts(struct rtattr *a, int ifindex)
{
struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1], *vattr;
__u16 vid, vrange = 0;
if ((a->rta_type & NLA_TYPE_MASK) != BRIDGE_VLANDB_GLOBAL_OPTIONS)
return;
parse_rtattr_flags(vtb, BRIDGE_VLANDB_GOPTS_MAX, RTA_DATA(a),
RTA_PAYLOAD(a), NLA_F_NESTED);
vid = rta_getattr_u16(vtb[BRIDGE_VLANDB_GOPTS_ID]);
if (vtb[BRIDGE_VLANDB_GOPTS_RANGE])
vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_GOPTS_RANGE]);
else
vrange = vid;
if (filter_vlan && (filter_vlan < vid || filter_vlan > vrange))
return;
if (vlan_rtm_cur_ifidx != ifindex) {
open_vlan_port(ifindex, VLAN_SHOW_VLAN);
open_json_object(NULL);
vlan_rtm_cur_ifidx = ifindex;
} else {
open_json_object(NULL);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
}
print_range("vlan", vid, vrange);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING];
print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ",
rta_getattr_u8(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER];
print_uint(PRINT_ANY, "mcast_querier", "mcast_querier %u ",
rta_getattr_u8(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION];
print_uint(PRINT_ANY, "mcast_igmp_version",
"mcast_igmp_version %u ", rta_getattr_u8(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION];
print_uint(PRINT_ANY, "mcast_mld_version",
"mcast_mld_version %u ", rta_getattr_u8(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT];
print_uint(PRINT_ANY, "mcast_last_member_count",
"mcast_last_member_count %u ",
rta_getattr_u32(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL];
print_lluint(PRINT_ANY, "mcast_last_member_interval",
"mcast_last_member_interval %llu ",
rta_getattr_u64(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT];
print_uint(PRINT_ANY, "mcast_startup_query_count",
"mcast_startup_query_count %u ",
rta_getattr_u32(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL];
print_lluint(PRINT_ANY, "mcast_startup_query_interval",
"mcast_startup_query_interval %llu ",
rta_getattr_u64(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL];
print_lluint(PRINT_ANY, "mcast_membership_interval",
"mcast_membership_interval %llu ",
rta_getattr_u64(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL];
print_lluint(PRINT_ANY, "mcast_querier_interval",
"mcast_querier_interval %llu ",
rta_getattr_u64(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL];
print_lluint(PRINT_ANY, "mcast_query_interval",
"mcast_query_interval %llu ",
rta_getattr_u64(vattr));
}
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL];
print_lluint(PRINT_ANY, "mcast_query_response_interval",
"mcast_query_response_interval %llu ",
rta_getattr_u64(vattr));
}
print_nl();
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]) {
vattr = RTA_DATA(vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]);
print_vlan_router_ports(vattr);
}
close_json_object();
}
static void print_vlan_opts(struct rtattr *a, int ifindex)
{
struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1], *vattr;
struct bridge_vlan_xstats vstats;
struct bridge_vlan_info *vinfo;
__u16 vrange = 0;
__u8 state = 0;
if ((a->rta_type & NLA_TYPE_MASK) != BRIDGE_VLANDB_ENTRY)
return;
parse_rtattr_flags(vtb, BRIDGE_VLANDB_ENTRY_MAX, RTA_DATA(a),
RTA_PAYLOAD(a), NLA_F_NESTED);
vinfo = RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_INFO]);
memset(&vstats, 0, sizeof(vstats));
if (vtb[BRIDGE_VLANDB_ENTRY_RANGE])
vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_ENTRY_RANGE]);
else
vrange = vinfo->vid;
if (filter_vlan && (filter_vlan < vinfo->vid || filter_vlan > vrange))
return;
if (vtb[BRIDGE_VLANDB_ENTRY_STATE])
state = rta_getattr_u8(vtb[BRIDGE_VLANDB_ENTRY_STATE]);
if (vtb[BRIDGE_VLANDB_ENTRY_STATS]) {
struct rtattr *stb[BRIDGE_VLANDB_STATS_MAX+1];
struct rtattr *attr;
attr = vtb[BRIDGE_VLANDB_ENTRY_STATS];
parse_rtattr(stb, BRIDGE_VLANDB_STATS_MAX, RTA_DATA(attr),
RTA_PAYLOAD(attr));
if (stb[BRIDGE_VLANDB_STATS_RX_BYTES]) {
attr = stb[BRIDGE_VLANDB_STATS_RX_BYTES];
vstats.rx_bytes = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_RX_PACKETS]) {
attr = stb[BRIDGE_VLANDB_STATS_RX_PACKETS];
vstats.rx_packets = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_TX_PACKETS]) {
attr = stb[BRIDGE_VLANDB_STATS_TX_PACKETS];
vstats.tx_packets = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_TX_BYTES]) {
attr = stb[BRIDGE_VLANDB_STATS_TX_BYTES];
vstats.tx_bytes = rta_getattr_u64(attr);
}
}
if (vlan_rtm_cur_ifidx != ifindex) {
open_vlan_port(ifindex, VLAN_SHOW_VLAN);
open_json_object(NULL);
vlan_rtm_cur_ifidx = ifindex;
} else {
open_json_object(NULL);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
}
print_range("vlan", vinfo->vid, vrange);
print_vlan_flags(vinfo->flags);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_stp_state(state);
if (vtb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) {
vattr = vtb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER];
print_uint(PRINT_ANY, "mcast_router", "mcast_router %u ",
rta_getattr_u8(vattr));
}
print_nl();
if (show_stats)
__print_one_vlan_stats(&vstats);
close_json_object();
}
int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only)
int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
{
struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1], *a;
struct br_vlan_msg *bvm = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *a;
int rem;
if (n->nlmsg_type != RTM_NEWVLAN && n->nlmsg_type != RTM_DELVLAN &&
@ -1066,21 +660,66 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only
rem = len;
for (a = BRVLAN_RTA(bvm); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) {
unsigned short rta_type = a->rta_type & NLA_TYPE_MASK;
struct bridge_vlan_xstats vstats;
struct bridge_vlan_info *vinfo;
__u32 vrange = 0;
__u8 state = 0;
/* skip unknown attributes */
if (rta_type > BRIDGE_VLANDB_MAX ||
(global_only && rta_type != BRIDGE_VLANDB_GLOBAL_OPTIONS))
continue;
parse_rtattr_flags(vtb, BRIDGE_VLANDB_ENTRY_MAX, RTA_DATA(a),
RTA_PAYLOAD(a), NLA_F_NESTED);
vinfo = RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_INFO]);
switch (rta_type) {
case BRIDGE_VLANDB_ENTRY:
print_vlan_opts(a, bvm->ifindex);
break;
case BRIDGE_VLANDB_GLOBAL_OPTIONS:
print_vlan_global_opts(a, bvm->ifindex);
break;
memset(&vstats, 0, sizeof(vstats));
if (vtb[BRIDGE_VLANDB_ENTRY_RANGE])
vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_ENTRY_RANGE]);
else
vrange = vinfo->vid;
if (vtb[BRIDGE_VLANDB_ENTRY_STATE])
state = rta_getattr_u8(vtb[BRIDGE_VLANDB_ENTRY_STATE]);
if (vtb[BRIDGE_VLANDB_ENTRY_STATS]) {
struct rtattr *stb[BRIDGE_VLANDB_STATS_MAX+1];
struct rtattr *attr;
attr = vtb[BRIDGE_VLANDB_ENTRY_STATS];
parse_rtattr(stb, BRIDGE_VLANDB_STATS_MAX, RTA_DATA(attr),
RTA_PAYLOAD(attr));
if (stb[BRIDGE_VLANDB_STATS_RX_BYTES]) {
attr = stb[BRIDGE_VLANDB_STATS_RX_BYTES];
vstats.rx_bytes = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_RX_PACKETS]) {
attr = stb[BRIDGE_VLANDB_STATS_RX_PACKETS];
vstats.rx_packets = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_TX_PACKETS]) {
attr = stb[BRIDGE_VLANDB_STATS_TX_PACKETS];
vstats.tx_packets = rta_getattr_u64(attr);
}
if (stb[BRIDGE_VLANDB_STATS_TX_BYTES]) {
attr = stb[BRIDGE_VLANDB_STATS_TX_BYTES];
vstats.tx_bytes = rta_getattr_u64(attr);
}
}
if (vlan_rtm_cur_ifidx != bvm->ifindex) {
open_vlan_port(bvm->ifindex, VLAN_SHOW_VLAN);
open_json_object(NULL);
vlan_rtm_cur_ifidx = bvm->ifindex;
} else {
open_json_object(NULL);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
}
print_range("vlan", vinfo->vid, vrange);
print_vlan_flags(vinfo->flags);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_stp_state(state);
print_nl();
if (show_stats)
__print_one_vlan_stats(&vstats);
close_json_object();
}
return 0;
@ -1088,12 +727,7 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only
static int print_vlan_rtm_filter(struct nlmsghdr *n, void *arg)
{
return print_vlan_rtm(n, arg, false, false);
}
static int print_vlan_rtm_global_filter(struct nlmsghdr *n, void *arg)
{
return print_vlan_rtm(n, arg, false, true);
return print_vlan_rtm(n, arg, false);
}
static int vlan_show(int argc, char **argv, int subject)
@ -1211,61 +845,6 @@ out:
return 0;
}
static int vlan_global_show(int argc, char **argv)
{
__u32 dump_flags = BRIDGE_VLANDB_DUMPF_GLOBAL;
int ret = 0, subject = VLAN_SHOW_VLAN;
char *filter_dev = NULL;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
if (filter_dev)
duparg("dev", *argv);
filter_dev = *argv;
} else if (strcmp(*argv, "vid") == 0) {
NEXT_ARG();
if (filter_vlan)
duparg("vid", *argv);
filter_vlan = atoi(*argv);
}
argc--; argv++;
}
if (filter_dev) {
filter_index = ll_name_to_index(filter_dev);
if (!filter_index)
return nodev(filter_dev);
}
new_json_obj(json);
if (rtnl_brvlandump_req(&rth, PF_BRIDGE, dump_flags) < 0) {
perror("Cannot send dump request");
exit(1);
}
if (!is_json_context()) {
printf("%-" __stringify(IFNAMSIZ) "s %-"
__stringify(VLAN_ID_LEN) "s", "port",
"vlan-id");
printf("\n");
}
ret = rtnl_dump_filter(&rth, print_vlan_rtm_global_filter, &subject);
if (ret < 0) {
fprintf(stderr, "Dump terminated\n");
exit(1);
}
if (vlan_rtm_cur_ifidx != -1)
close_vlan_port();
delete_json_obj();
fflush(stdout);
return 0;
}
void print_vlan_info(struct rtattr *tb, int ifindex)
{
struct rtattr *i, *list = tb;
@ -1310,24 +889,6 @@ void print_vlan_info(struct rtattr *tb, int ifindex)
close_vlan_port();
}
static int vlan_global(int argc, char **argv)
{
if (argc > 0) {
if (strcmp(*argv, "show") == 0 ||
strcmp(*argv, "lst") == 0 ||
strcmp(*argv, "list") == 0)
return vlan_global_show(argc-1, argv+1);
else if (strcmp(*argv, "set") == 0)
return vlan_global_option_set(argc-1, argv+1);
else
usage();
} else {
return vlan_global_show(0, NULL);
}
return 0;
}
int do_vlan(int argc, char **argv)
{
ll_init_map(&rth);
@ -1346,8 +907,6 @@ int do_vlan(int argc, char **argv)
}
if (matches(*argv, "set") == 0)
return vlan_option_set(argc-1, argv+1);
if (strcmp(*argv, "global") == 0)
return vlan_global(argc-1, argv+1);
if (matches(*argv, "help") == 0)
usage();
} else {

117
configure vendored
View File

@ -1,10 +1,13 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# This is not an autoconf generated configure
#
# Influential LIBBPF environment variables:
# LIBBPF_FORCE={on,off} on: require link against libbpf;
# off: disable libbpf probing
# LIBBPF_DIR Path to libbpf DESTDIR to use
INCLUDE="$PWD/include"
PREFIX="/usr"
LIBDIR="\${prefix}/lib"
INCLUDE=${1:-"$PWD/include"}
# Output file which is input to Makefile
CONFIG=config.mk
@ -150,15 +153,6 @@ EOF
rm -f $TMPDIR/ipttest.c $TMPDIR/ipttest
}
check_lib_dir()
{
LIBDIR=$(echo $LIBDIR | sed "s|\${prefix}|$PREFIX|")
echo -n "lib directory: "
echo "$LIBDIR"
echo "LIBDIR:=$LIBDIR" >> $CONFIG
}
check_ipt()
{
if ! grep TC_CONFIG_XT $CONFIG > /dev/null; then
@ -208,31 +202,6 @@ EOF
rm -f $TMPDIR/setnstest.c $TMPDIR/setnstest
}
check_name_to_handle_at()
{
cat >$TMPDIR/name_to_handle_at_test.c <<EOF
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
struct file_handle *fhp;
int mount_id, flags, dirfd;
char *pathname;
name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags);
return 0;
}
EOF
if $CC -I$INCLUDE -o $TMPDIR/name_to_handle_at_test $TMPDIR/name_to_handle_at_test.c >/dev/null 2>&1; then
echo "yes"
echo "CFLAGS += -DHAVE_HANDLE_AT" >>$CONFIG
else
echo "no"
fi
rm -f $TMPDIR/name_to_handle_at_test.c $TMPDIR/name_to_handle_at_test
}
check_ipset()
{
cat >$TMPDIR/ipsettest.c <<EOF
@ -492,76 +461,6 @@ endif
EOF
}
usage()
{
cat <<EOF
Usage: $0 [OPTIONS]
--include_dir <dir> Path to iproute2 include dir
--libdir <dir> Path to iproute2 lib dir
--libbpf_dir <dir> Path to libbpf DESTDIR
--libbpf_force <on|off> Enable/disable libbpf by force. Available options:
on: require link against libbpf, quit config if no libbpf support
off: disable libbpf probing
--prefix <dir> Path prefix of the lib files to install
-h | --help Show this usage info
EOF
exit $1
}
# Compat with the old INCLUDE path setting method.
if [ $# -eq 1 ] && [ "$(echo $1 | cut -c 1)" != '-' ]; then
INCLUDE="$1"
else
while [ "$#" -gt 0 ]; do
case "$1" in
--include_dir)
shift
INCLUDE="$1" ;;
--include_dir=*)
INCLUDE="${1#*=}" ;;
--libdir)
shift
LIBDIR="$1" ;;
--libdir=*)
LIBDIR="${1#*=}" ;;
--libbpf_dir)
shift
LIBBPF_DIR="$1" ;;
--libbpf_dir=*)
LIBBPF_DIR="${1#*=}" ;;
--libbpf_force)
shift
LIBBPF_FORCE="$1" ;;
--libbpf_force=*)
LIBBPF_FORCE="${1#*=}" ;;
--prefix)
shift
PREFIX="$1" ;;
--prefix=*)
PREFIX="${1#*=}" ;;
-h | --help)
usage 0 ;;
--*)
;;
*)
usage 1 ;;
esac
[ "$#" -gt 0 ] && shift
done
fi
[ -d "$INCLUDE" ] || usage 1
if [ "${LIBBPF_DIR-unused}" != "unused" ]; then
[ -d "$LIBBPF_DIR" ] || usage 1
fi
if [ "${LIBBPF_FORCE-unused}" != "unused" ]; then
if [ "$LIBBPF_FORCE" != 'on' ] && [ "$LIBBPF_FORCE" != 'off' ]; then
usage 1
fi
fi
[ -z "$PREFIX" ] && usage 1
[ -z "$LIBDIR" ] && usage 1
echo "# Generated config based on" $INCLUDE >$CONFIG
quiet_config >> $CONFIG
@ -585,7 +484,6 @@ if ! grep -q TC_CONFIG_NO_XT $CONFIG; then
fi
echo
check_lib_dir
if ! grep -q TC_CONFIG_NO_XT $CONFIG; then
echo -n "iptables modules directory: "
check_ipt_lib_dir
@ -594,9 +492,6 @@ fi
echo -n "libc has setns: "
check_setns
echo -n "libc has name_to_handle_at: "
check_name_to_handle_at
echo -n "SELinux support: "
check_selinux

View File

@ -571,8 +571,7 @@ int main(int argc, char **argv)
break;
case 'h':
dcb_help();
ret = EXIT_SUCCESS;
goto dcb_free;
return 0;
default:
fprintf(stderr, "Unknown option.\n");
dcb_help();

View File

@ -667,7 +667,7 @@ static int dcb_cmd_app_show(struct dcb *dcb, const char *dev, int argc, char **a
out:
close_json_object();
dcb_app_table_fini(&tab);
return ret;
return 0;
}
static int dcb_cmd_app_flush(struct dcb *dcb, const char *dev, int argc, char **argv)

View File

@ -71,8 +71,6 @@ static bool g_indent_newline;
#define INDENT_STR_MAXLEN 32
static char g_indent_str[INDENT_STR_MAXLEN + 1] = "";
static bool use_iec = false;
static void __attribute__((format(printf, 1, 2)))
pr_err(const char *fmt, ...)
{
@ -288,12 +286,6 @@ static void ifname_map_free(struct ifname_map *ifname_map)
#define DL_OPT_PORT_PFNUMBER BIT(43)
#define DL_OPT_PORT_SFNUMBER BIT(44)
#define DL_OPT_PORT_FUNCTION_STATE BIT(45)
#define DL_OPT_PORT_CONTROLLER BIT(46)
#define DL_OPT_PORT_FN_RATE_TYPE BIT(47)
#define DL_OPT_PORT_FN_RATE_TX_SHARE BIT(48)
#define DL_OPT_PORT_FN_RATE_TX_MAX BIT(49)
#define DL_OPT_PORT_FN_RATE_NODE_NAME BIT(50)
#define DL_OPT_PORT_FN_RATE_PARENT BIT(51)
struct dl_opts {
uint64_t present; /* flags of present items */
@ -344,16 +336,10 @@ struct dl_opts {
uint32_t overwrite_mask;
enum devlink_reload_action reload_action;
enum devlink_reload_limit reload_limit;
uint32_t port_controller;
uint32_t port_sfnumber;
uint16_t port_flavour;
uint16_t port_pfnumber;
uint8_t port_fn_state;
uint16_t rate_type;
uint64_t rate_tx_share;
uint64_t rate_tx_max;
char *rate_node_name;
const char *rate_parent_node;
};
struct dl {
@ -929,19 +915,6 @@ static int strtobool(const char *str, bool *p_val)
return 0;
}
static int ident_str_validate(char *str, unsigned int expected)
{
if (!str)
return -EINVAL;
if (get_str_char_count(str, '/') != expected) {
pr_err("Wrong identification string format.\n");
return -EINVAL;
}
return 0;
}
static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
{
int err;
@ -957,12 +930,15 @@ static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
static int dl_argv_handle(struct dl *dl, char **p_bus_name, char **p_dev_name)
{
char *str = dl_argv_next(dl);
int err;
err = ident_str_validate(str, 1);
if (err) {
if (!str) {
pr_err("Devlink identification (\"bus_name/dev_name\") expected\n");
return err;
return -EINVAL;
}
if (get_str_char_count(str, '/') != 1) {
pr_err("Wrong devlink identification string format.\n");
pr_err("Expected \"bus_name/dev_name\".\n");
return -EINVAL;
}
return __dl_argv_handle(str, p_bus_name, p_dev_name);
}
@ -1074,103 +1050,44 @@ static int dl_argv_handle_both(struct dl *dl, char **p_bus_name,
return 0;
}
static int __dl_argv_handle_name(char *str, char **p_bus_name,
char **p_dev_name, char **p_name)
static int __dl_argv_handle_region(char *str, char **p_bus_name,
char **p_dev_name, char **p_region)
{
char *handlestr;
int err;
err = str_split_by_char(str, &handlestr, p_name, '/');
if (err)
err = str_split_by_char(str, &handlestr, p_region, '/');
if (err) {
pr_err("Region identification \"%s\" is invalid\n", str);
return err;
return str_split_by_char(handlestr, p_bus_name, p_dev_name, '/');
}
err = str_split_by_char(handlestr, p_bus_name, p_dev_name, '/');
if (err) {
pr_err("Region identification \"%s\" is invalid\n", str);
return err;
}
return 0;
}
static int dl_argv_handle_region(struct dl *dl, char **p_bus_name,
char **p_dev_name, char **p_region)
char **p_dev_name, char **p_region)
{
char *str = dl_argv_next(dl);
int err;
unsigned int slash_count;
err = ident_str_validate(str, 2);
if (err) {
if (!str) {
pr_err("Expected \"bus_name/dev_name/region\" identification.\n");
return err;
}
err = __dl_argv_handle_name(str, p_bus_name, p_dev_name, p_region);
if (err)
pr_err("Region identification \"%s\" is invalid\n", str);
return err;
}
static int dl_argv_handle_rate_node(struct dl *dl, char **p_bus_name,
char **p_dev_name, char **p_node)
{
char *str = dl_argv_next(dl);
int err;
err = ident_str_validate(str, 2);
if (err) {
pr_err("Expected \"bus_name/dev_name/node\" identification.\n");
return err;
}
err = __dl_argv_handle_name(str, p_bus_name, p_dev_name, p_node);
if (err) {
pr_err("Node identification \"%s\" is invalid\n", str);
return err;
}
if (!**p_node || strspn(*p_node, "0123456789") == strlen(*p_node)) {
err = -EINVAL;
pr_err("Node name cannot be a devlink port index or empty.\n");
}
return err;
}
static int dl_argv_handle_rate(struct dl *dl, char **p_bus_name,
char **p_dev_name, uint32_t *p_port_index,
char **p_node_name, uint64_t *p_handle_bit)
{
char *str = dl_argv_next(dl);
char *identifier;
int err;
err = ident_str_validate(str, 2);
if (err) {
pr_err("Expected \"bus_name/dev_name/node\" or "
"\"bus_name/dev_name/port_index\" identification.\n");
return err;
}
err = __dl_argv_handle_name(str, p_bus_name, p_dev_name, &identifier);
if (err) {
pr_err("Identification \"%s\" is invalid\n", str);
return err;
}
if (!*identifier) {
pr_err("Identifier cannot be empty");
return -EINVAL;
}
if (strspn(identifier, "0123456789") == strlen(identifier)) {
err = strtouint32_t(identifier, p_port_index);
if (err) {
pr_err("Port index \"%s\" is not a number"
" or not within range\n", identifier);
return err;
}
*p_handle_bit = DL_OPT_HANDLEP;
} else {
*p_handle_bit = DL_OPT_PORT_FN_RATE_NODE_NAME;
*p_node_name = identifier;
slash_count = get_str_char_count(str, '/');
if (slash_count != 2) {
pr_err("Wrong region identification string format.\n");
pr_err("Expected \"bus_name/dev_name/region\" identification.\n"".\n");
return -EINVAL;
}
return 0;
return __dl_argv_handle_region(str, p_bus_name, p_dev_name, p_region);
}
static int dl_argv_uint64_t(struct dl *dl, uint64_t *p_val)
@ -1482,36 +1399,6 @@ static int port_fn_state_parse(const char *statestr, uint8_t *state)
return 0;
}
static int port_fn_rate_type_get(const char *typestr, uint16_t *type)
{
if (!strcmp(typestr, "leaf"))
*type = DEVLINK_RATE_TYPE_LEAF;
else if (!strcmp(typestr, "node"))
*type = DEVLINK_RATE_TYPE_NODE;
else
return -EINVAL;
return 0;
}
static int port_fn_rate_value_get(struct dl *dl, uint64_t *rate)
{
const char *ratestr;
__u64 rate64;
int err;
err = dl_argv_str(dl, &ratestr);
if (err)
return err;
err = get_rate64(&rate64, ratestr);
if (err) {
pr_err("Invalid rate value: \"%s\"\n", ratestr);
return -EINVAL;
}
*rate = rate64;
return 0;
}
struct dl_args_metadata {
uint64_t o_flag;
char err_msg[DL_ARGS_REQUIRED_MAX_ERR_LEN];
@ -1584,19 +1471,6 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
return err;
o_required &= ~(DL_OPT_HANDLE | DL_OPT_HANDLEP) | handle_bit;
o_found |= handle_bit;
} else if (o_required & DL_OPT_HANDLEP &&
o_required & DL_OPT_PORT_FN_RATE_NODE_NAME) {
uint64_t handle_bit;
err = dl_argv_handle_rate(dl, &opts->bus_name, &opts->dev_name,
&opts->port_index,
&opts->rate_node_name,
&handle_bit);
if (err)
return err;
o_required &= ~(DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME) |
handle_bit;
o_found |= handle_bit;
} else if (o_required & DL_OPT_HANDLE) {
err = dl_argv_handle(dl, &opts->bus_name, &opts->dev_name);
if (err)
@ -1615,13 +1489,6 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
if (err)
return err;
o_found |= DL_OPT_HANDLE_REGION;
} else if (o_required & DL_OPT_PORT_FN_RATE_NODE_NAME) {
err = dl_argv_handle_rate_node(dl, &opts->bus_name,
&opts->dev_name,
&opts->rate_node_name);
if (err)
return err;
o_found |= DL_OPT_PORT_FN_RATE_NODE_NAME;
}
while (dl_argc(dl)) {
@ -2019,50 +1886,6 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
if (err)
return err;
o_found |= DL_OPT_PORT_SFNUMBER;
} else if (dl_argv_match(dl, "controller") && (o_all & DL_OPT_PORT_CONTROLLER)) {
dl_arg_inc(dl);
err = dl_argv_uint32_t(dl, &opts->port_controller);
if (err)
return err;
o_found |= DL_OPT_PORT_CONTROLLER;
} else if (dl_argv_match(dl, "type") &&
(o_all & DL_OPT_PORT_FN_RATE_TYPE)) {
const char *typestr;
dl_arg_inc(dl);
err = dl_argv_str(dl, &typestr);
if (err)
return err;
err = port_fn_rate_type_get(typestr, &opts->rate_type);
if (err)
return err;
o_found |= DL_OPT_PORT_FN_RATE_TYPE;
} else if (dl_argv_match(dl, "tx_share") &&
(o_all & DL_OPT_PORT_FN_RATE_TX_SHARE)) {
dl_arg_inc(dl);
err = port_fn_rate_value_get(dl, &opts->rate_tx_share);
if (err)
return err;
o_found |= DL_OPT_PORT_FN_RATE_TX_SHARE;
} else if (dl_argv_match(dl, "tx_max") &&
(o_all & DL_OPT_PORT_FN_RATE_TX_MAX)) {
dl_arg_inc(dl);
err = port_fn_rate_value_get(dl, &opts->rate_tx_max);
if (err)
return err;
o_found |= DL_OPT_PORT_FN_RATE_TX_MAX;
} else if (dl_argv_match(dl, "parent") &&
(o_all & DL_OPT_PORT_FN_RATE_PARENT)) {
dl_arg_inc(dl);
err = dl_argv_str(dl, &opts->rate_parent_node);
if (err)
return err;
o_found |= DL_OPT_PORT_FN_RATE_PARENT;
} else if (dl_argv_match(dl, "noparent") &&
(o_all & DL_OPT_PORT_FN_RATE_PARENT)) {
dl_arg_inc(dl);
opts->rate_parent_node = "";
o_found |= DL_OPT_PORT_FN_RATE_PARENT;
} else {
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
return -EINVAL;
@ -2135,11 +1958,6 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
mnl_attr_put_strz(nlh, DEVLINK_ATTR_REGION_NAME,
opts->region_name);
} else if (opts->present & DL_OPT_PORT_FN_RATE_NODE_NAME) {
mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, opts->bus_name);
mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_NODE_NAME,
opts->rate_node_name);
}
if (opts->present & DL_OPT_PORT_TYPE)
mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_TYPE,
@ -2261,21 +2079,6 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, opts->port_pfnumber);
if (opts->present & DL_OPT_PORT_SFNUMBER)
mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, opts->port_sfnumber);
if (opts->present & DL_OPT_PORT_CONTROLLER)
mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
opts->port_controller);
if (opts->present & DL_OPT_PORT_FN_RATE_TYPE)
mnl_attr_put_u16(nlh, DEVLINK_ATTR_RATE_TYPE,
opts->rate_type);
if (opts->present & DL_OPT_PORT_FN_RATE_TX_SHARE)
mnl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_SHARE,
opts->rate_tx_share);
if (opts->present & DL_OPT_PORT_FN_RATE_TX_MAX)
mnl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_MAX,
opts->rate_tx_max);
if (opts->present & DL_OPT_PORT_FN_RATE_PARENT)
mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
opts->rate_parent_node);
}
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
@ -3036,7 +2839,6 @@ static int cmd_dev_param_show_cb(const struct nlmsghdr *nlh, void *data)
struct param_ctx {
struct dl *dl;
int nla_type;
bool cmode_found;
union {
uint8_t vu8;
uint16_t vu16;
@ -3089,7 +2891,6 @@ static int cmd_dev_param_set_cb(const struct nlmsghdr *nlh, void *data)
cmode = mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
if (cmode == dl->opts.cmode) {
ctx->cmode_found = true;
val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA];
switch (nla_type) {
case MNL_TYPE_U8:
@ -3142,10 +2943,6 @@ static int cmd_dev_param_set(struct dl *dl)
err = mnlu_gen_socket_sndrcv(&dl->nlg, nlh, cmd_dev_param_set_cb, &ctx);
if (err)
return err;
if (!ctx.cmode_found) {
pr_err("Configuration mode not supported\n");
return -ENOTSUP;
}
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PARAM_SET,
NLM_F_REQUEST | NLM_F_ACK);
@ -3706,7 +3503,7 @@ static int cmd_dev_flash_status_cb(const struct nlmsghdr *nlh, void *data)
strcmp(dev_name, opts->dev_name))
return MNL_CB_ERROR;
if (genl->cmd == DEVLINK_CMD_FLASH_UPDATE_END) {
if (genl->cmd == DEVLINK_CMD_FLASH_UPDATE_END && ctx->not_first) {
pr_out("\n");
free(ctx->last_msg);
free(ctx->last_component);
@ -3994,13 +3791,11 @@ static void cmd_port_help(void)
pr_err(" devlink port set DEV/PORT_INDEX [ type { eth | ib | auto} ]\n");
pr_err(" devlink port split DEV/PORT_INDEX count COUNT\n");
pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ] [ state { active | inactive } ]\n");
pr_err(" devlink port function rate { help | show | add | del | set }\n");
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ] [ state STATE ]\n");
pr_err(" devlink port param set DEV/PORT_INDEX name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n");
pr_err(" devlink port param show [DEV/PORT_INDEX name PARAMETER]\n");
pr_err(" devlink port health show [ DEV/PORT_INDEX reporter REPORTER_NAME ]\n");
pr_err(" devlink port add DEV/PORT_INDEX flavour FLAVOUR pfnum PFNUM\n"
" [ sfnum SFNUM ][ controller CNUM ]\n");
pr_err(" devlink port add DEV/PORT_INDEX flavour FLAVOUR pfnum PFNUM [ sfnum SFNUM ]\n");
pr_err(" devlink port del DEV/PORT_INDEX\n");
}
@ -4290,7 +4085,6 @@ static int cmd_port_param_show(struct dl *dl)
static void cmd_port_function_help(void)
{
pr_err("Usage: devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ] [ state STATE ]\n");
pr_err(" devlink port function rate { help | show | add | del | set }\n");
}
static int cmd_port_function_set(struct dl *dl)
@ -4512,280 +4306,6 @@ static int cmd_port_param(struct dl *dl)
return -ENOENT;
}
static void
pr_out_port_rate_handle_start(struct dl *dl, struct nlattr **tb, bool try_nice)
{
const char *bus_name;
const char *dev_name;
const char *node_name;
static char buf[64];
bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
node_name = mnl_attr_get_str(tb[DEVLINK_ATTR_RATE_NODE_NAME]);
sprintf(buf, "%s/%s/%s", bus_name, dev_name, node_name);
if (dl->json_output)
open_json_object(buf);
else
pr_out("%s:", buf);
}
static char *port_rate_type_name(uint16_t type)
{
switch (type) {
case DEVLINK_RATE_TYPE_LEAF:
return "leaf";
case DEVLINK_RATE_TYPE_NODE:
return "node";
default:
return "<unknown type>";
}
}
static void pr_out_port_fn_rate(struct dl *dl, struct nlattr **tb)
{
if (!tb[DEVLINK_ATTR_RATE_NODE_NAME])
pr_out_port_handle_start(dl, tb, false);
else
pr_out_port_rate_handle_start(dl, tb, false);
check_indent_newline(dl);
if (tb[DEVLINK_ATTR_RATE_TYPE]) {
uint16_t type =
mnl_attr_get_u16(tb[DEVLINK_ATTR_RATE_TYPE]);
print_string(PRINT_ANY, "type", "type %s",
port_rate_type_name(type));
}
if (tb[DEVLINK_ATTR_RATE_TX_SHARE]) {
uint64_t rate =
mnl_attr_get_u64(tb[DEVLINK_ATTR_RATE_TX_SHARE]);
if (rate)
print_rate(use_iec, PRINT_ANY, "tx_share",
" tx_share %s", rate);
}
if (tb[DEVLINK_ATTR_RATE_TX_MAX]) {
uint64_t rate =
mnl_attr_get_u64(tb[DEVLINK_ATTR_RATE_TX_MAX]);
if (rate)
print_rate(use_iec, PRINT_ANY, "tx_max",
" tx_max %s", rate);
}
if (tb[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]) {
const char *parent =
mnl_attr_get_str(tb[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]);
print_string(PRINT_ANY, "parent", " parent %s", parent);
}
pr_out_port_handle_end(dl);
}
static int cmd_port_fn_rate_show_cb(const struct nlmsghdr *nlh, void *data)
{
struct dl *dl = data;
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
if ((!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
!tb[DEVLINK_ATTR_PORT_INDEX]) &&
!tb[DEVLINK_ATTR_RATE_NODE_NAME]) {
return MNL_CB_ERROR;
}
pr_out_port_fn_rate(dl, tb);
return MNL_CB_OK;
}
static void cmd_port_fn_rate_help(void)
{
pr_err("Usage: devlink port function rate help\n");
pr_err(" devlink port function rate show [ DEV/{ PORT_INDEX | NODE_NAME } ]\n");
pr_err(" devlink port function rate add DEV/NODE_NAME\n");
pr_err(" [ tx_share VAL ][ tx_max VAL ][ { parent NODE_NAME | noparent } ]\n");
pr_err(" devlink port function rate del DEV/NODE_NAME\n");
pr_err(" devlink port function rate set DEV/{ PORT_INDEX | NODE_NAME }\n");
pr_err(" [ tx_share VAL ][ tx_max VAL ][ { parent NODE_NAME | noparent } ]\n\n");
pr_err(" VAL - float or integer value in units of bits or bytes per second (bit|bps)\n");
pr_err(" and SI (k-, m-, g-, t-) or IEC (ki-, mi-, gi-, ti-) case-insensitive prefix.\n");
pr_err(" Bare number, means bits per second, is possible.\n\n");
pr_err(" For details refer to devlink-rate(8) man page.\n");
}
static int cmd_port_fn_rate_show(struct dl *dl)
{
struct nlmsghdr *nlh;
uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
int err;
if (dl_argc(dl) == 0)
flags |= NLM_F_DUMP;
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_GET, flags);
if (dl_argc(dl) > 0) {
err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP |
DL_OPT_PORT_FN_RATE_NODE_NAME, 0);
if (err)
return err;
}
pr_out_section_start(dl, "rate");
err = mnlu_gen_socket_sndrcv(&dl->nlg, nlh, cmd_port_fn_rate_show_cb, dl);
pr_out_section_end(dl);
return err;
}
static int port_fn_check_tx_rates(uint64_t min_rate, uint64_t max_rate)
{
if (max_rate && min_rate > max_rate) {
pr_err("Invalid. Expected tx_share <= tx_max or tx_share == 0.\n");
return -EINVAL;
}
return 0;
}
static int port_fn_get_and_check_tx_rates(struct dl_opts *reply,
struct dl_opts *request)
{
uint64_t min = reply->rate_tx_share;
uint64_t max = reply->rate_tx_max;
if (request->present & DL_OPT_PORT_FN_RATE_TX_SHARE)
return port_fn_check_tx_rates(request->rate_tx_share, max);
return port_fn_check_tx_rates(min, request->rate_tx_max);
}
static int cmd_port_fn_rate_add(struct dl *dl)
{
struct nlmsghdr *nlh;
int err;
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_NEW,
NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl, DL_OPT_PORT_FN_RATE_NODE_NAME,
DL_OPT_PORT_FN_RATE_TX_SHARE |
DL_OPT_PORT_FN_RATE_TX_MAX);
if (err)
return err;
if ((dl->opts.present & DL_OPT_PORT_FN_RATE_TX_SHARE) &&
(dl->opts.present & DL_OPT_PORT_FN_RATE_TX_MAX)) {
err = port_fn_check_tx_rates(dl->opts.rate_tx_share,
dl->opts.rate_tx_max);
if (err)
return err;
}
return mnlu_gen_socket_sndrcv(&dl->nlg, nlh, NULL, NULL);
}
static int cmd_port_fn_rate_del(struct dl *dl)
{
struct nlmsghdr *nlh;
int err;
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_DEL,
NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl, DL_OPT_PORT_FN_RATE_NODE_NAME, 0);
if (err)
return err;
return mnlu_gen_socket_sndrcv(&dl->nlg, nlh, NULL, NULL);
}
static int port_fn_get_rates_cb(const struct nlmsghdr *nlh, void *data)
{
struct dl_opts *opts = data;
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
if ((!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
!tb[DEVLINK_ATTR_PORT_INDEX]) &&
!tb[DEVLINK_ATTR_RATE_NODE_NAME]) {
return MNL_CB_ERROR;
}
if (tb[DEVLINK_ATTR_RATE_TX_SHARE])
opts->rate_tx_share =
mnl_attr_get_u64(tb[DEVLINK_ATTR_RATE_TX_SHARE]);
if (tb[DEVLINK_ATTR_RATE_TX_MAX])
opts->rate_tx_max =
mnl_attr_get_u64(tb[DEVLINK_ATTR_RATE_TX_MAX]);
return MNL_CB_OK;
}
static int cmd_port_fn_rate_set(struct dl *dl)
{
struct dl_opts tmp_opts = {0};
struct nlmsghdr *nlh;
int err;
err = dl_argv_parse(dl, DL_OPT_HANDLEP |
DL_OPT_PORT_FN_RATE_NODE_NAME,
DL_OPT_PORT_FN_RATE_TX_SHARE |
DL_OPT_PORT_FN_RATE_TX_MAX |
DL_OPT_PORT_FN_RATE_PARENT);
if (err)
return err;
if ((dl->opts.present & DL_OPT_PORT_FN_RATE_TX_SHARE) &&
(dl->opts.present & DL_OPT_PORT_FN_RATE_TX_MAX)) {
err = port_fn_check_tx_rates(dl->opts.rate_tx_share,
dl->opts.rate_tx_max);
if (err)
return err;
} else if (dl->opts.present &
(DL_OPT_PORT_FN_RATE_TX_SHARE | DL_OPT_PORT_FN_RATE_TX_MAX)) {
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_GET,
NLM_F_REQUEST | NLM_F_ACK);
tmp_opts = dl->opts;
dl->opts.present &= ~(DL_OPT_PORT_FN_RATE_TX_SHARE |
DL_OPT_PORT_FN_RATE_TX_MAX |
DL_OPT_PORT_FN_RATE_PARENT);
dl_opts_put(nlh, dl);
err = mnlu_gen_socket_sndrcv(&dl->nlg, nlh, port_fn_get_rates_cb,
&dl->opts);
if (err)
return err;
err = port_fn_get_and_check_tx_rates(&dl->opts, &tmp_opts);
if (err)
return err;
dl->opts = tmp_opts;
}
nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_SET,
NLM_F_REQUEST | NLM_F_ACK);
dl_opts_put(nlh, dl);
return mnlu_gen_socket_sndrcv(&dl->nlg, nlh, NULL, NULL);
}
static int cmd_port_function_rate(struct dl *dl)
{
if (dl_argv_match(dl, "help")) {
cmd_port_fn_rate_help();
return 0;
} else if (dl_argv_match(dl, "show") || dl_no_arg(dl)) {
dl_arg_inc(dl);
return cmd_port_fn_rate_show(dl);
} else if (dl_argv_match(dl, "add")) {
dl_arg_inc(dl);
return cmd_port_fn_rate_add(dl);
} else if (dl_argv_match(dl, "del")) {
dl_arg_inc(dl);
return cmd_port_fn_rate_del(dl);
} else if (dl_argv_match(dl, "set")) {
dl_arg_inc(dl);
return cmd_port_fn_rate_set(dl);
}
pr_err("Command \"%s\" not found\n", dl_argv(dl));
return -ENOENT;
}
static int cmd_port_function(struct dl *dl)
{
if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
@ -4794,9 +4314,6 @@ static int cmd_port_function(struct dl *dl)
} else if (dl_argv_match(dl, "set")) {
dl_arg_inc(dl);
return cmd_port_function_set(dl);
} else if (dl_argv_match(dl, "rate")) {
dl_arg_inc(dl);
return cmd_port_function_rate(dl);
}
pr_err("Command \"%s\" not found\n", dl_argv(dl));
return -ENOENT;
@ -4807,8 +4324,7 @@ static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port);
static void cmd_port_add_help(void)
{
pr_err(" devlink port add DEV/PORT_INDEX flavour FLAVOUR pfnum PFNUM\n"
" [ sfnum SFNUM ][ controller CNUM ]\n");
pr_err(" devlink port add { DEV | DEV/PORT_INDEX } flavour FLAVOUR pfnum PFNUM [ sfnum SFNUM ]\n");
}
static int cmd_port_add(struct dl *dl)
@ -4826,7 +4342,7 @@ static int cmd_port_add(struct dl *dl)
err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_PORT_FLAVOUR | DL_OPT_PORT_PFNUMBER,
DL_OPT_PORT_SFNUMBER | DL_OPT_PORT_CONTROLLER);
DL_OPT_PORT_SFNUMBER);
if (err)
return err;
@ -7851,10 +7367,6 @@ static void pr_out_region(struct dl *dl, struct nlattr **tb)
if (tb[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
pr_out_snapshot(dl, tb);
if (tb[DEVLINK_ATTR_REGION_MAX_SNAPSHOTS])
pr_out_u64(dl, "max",
mnl_attr_get_u32(tb[DEVLINK_ATTR_REGION_MAX_SNAPSHOTS]));
pr_out_region_handle_end(dl);
}
@ -9097,7 +8609,6 @@ int main(int argc, char **argv)
{ "verbose", no_argument, NULL, 'v' },
{ "statistics", no_argument, NULL, 's' },
{ "Netns", required_argument, NULL, 'N' },
{ "iec", no_argument, NULL, 'i' },
{ NULL, 0, NULL, 0 }
};
const char *batch_file = NULL;
@ -9113,7 +8624,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
while ((opt = getopt_long(argc, argv, "Vfb:njpvsN:i",
while ((opt = getopt_long(argc, argv, "Vfb:njpvsN:",
long_options, NULL)) >= 0) {
switch (opt) {
@ -9148,9 +8659,6 @@ int main(int argc, char **argv)
goto dl_free;
}
break;
case 'i':
use_iec = true;
break;
default:
pr_err("Unknown option.\n");
help();

View File

@ -10,7 +10,7 @@ Where:
ACTION semantics
- pass and ok are equivalent to accept
- continue allows one to restart classification lookup
- continue allows to restart classification lookup
- drop drops packets
- reclassify implies continue classification where we left off

View File

@ -109,27 +109,6 @@ struct rtnl_ctrl_data {
typedef int (*rtnl_filter_t)(struct nlmsghdr *n, void *);
/**
* rtnl error handler called from
* rtnl_dump_done()
* rtnl_dump_error()
*
* Return value is a bitmask of the following values:
* RTNL_LET_NLERR
* error handled as usual
* RTNL_SUPPRESS_NLMSG_DONE_NLERR
* error in nlmsg_type == NLMSG_DONE will be suppressed
* RTNL_SUPPRESS_NLMSG_ERROR_NLERR
* error in nlmsg_type == NLMSG_ERROR will be suppressed
* and nlmsg will be skipped
* RTNL_SUPPRESS_NLERR - suppress error in both previous cases
*/
#define RTNL_LET_NLERR 0x01
#define RTNL_SUPPRESS_NLMSG_DONE_NLERR 0x02
#define RTNL_SUPPRESS_NLMSG_ERROR_NLERR 0x04
#define RTNL_SUPPRESS_NLERR 0x06
typedef int (*rtnl_err_hndlr_t)(struct nlmsghdr *n, void *);
typedef int (*rtnl_listen_filter_t)(struct rtnl_ctrl_data *,
struct nlmsghdr *n, void *);
@ -139,8 +118,6 @@ typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off,
struct rtnl_dump_filter_arg {
rtnl_filter_t filter;
void *arg1;
rtnl_err_hndlr_t errhndlr;
void *arg2;
__u16 nc_flags;
};
@ -149,15 +126,6 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth,
void *arg, __u16 nc_flags);
#define rtnl_dump_filter(rth, filter, arg) \
rtnl_dump_filter_nc(rth, filter, arg, 0)
int rtnl_dump_filter_errhndlr_nc(struct rtnl_handle *rth,
rtnl_filter_t filter,
void *arg1,
rtnl_err_hndlr_t errhndlr,
void *arg2,
__u16 nc_flags);
#define rtnl_dump_filter_errhndlr(rth, filter, farg, errhndlr, earg) \
rtnl_dump_filter_errhndlr_nc(rth, filter, farg, errhndlr, earg, 0)
int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
struct nlmsghdr **answer)
__attribute__((warn_unused_result));

View File

@ -1,62 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2021 Taehee Yoo <ap420073@gmail.com>
*/
#ifndef _AMT_H_
#define _AMT_H_
enum ifla_amt_mode {
/* AMT interface works as Gateway mode.
* The Gateway mode encapsulates IGMP/MLD traffic and decapsulates
* multicast traffic.
*/
AMT_MODE_GATEWAY = 0,
/* AMT interface works as Relay mode.
* The Relay mode encapsulates multicast traffic and decapsulates
* IGMP/MLD traffic.
*/
AMT_MODE_RELAY,
__AMT_MODE_MAX,
};
#define AMT_MODE_MAX (__AMT_MODE_MAX - 1)
enum {
IFLA_AMT_UNSPEC,
/* This attribute specify mode etier Gateway or Relay. */
IFLA_AMT_MODE,
/* This attribute specify Relay port.
* AMT interface is created as Gateway mode, this attribute is used
* to specify relay(remote) port.
* AMT interface is created as Relay mode, this attribute is used
* as local port.
*/
IFLA_AMT_RELAY_PORT,
/* This attribute specify Gateway port.
* AMT interface is created as Gateway mode, this attribute is used
* as local port.
* AMT interface is created as Relay mode, this attribute is not used.
*/
IFLA_AMT_GATEWAY_PORT,
/* This attribute specify physical device */
IFLA_AMT_LINK,
/* This attribute specify local ip address */
IFLA_AMT_LOCAL_IP,
/* This attribute specify Relay ip address.
* So, this is not used by Relay.
*/
IFLA_AMT_REMOTE_IP,
/* This attribute specify Discovery ip address.
* When Gateway get started, it send discovery message to find the
* Relay's ip address.
* So, this is not used by Relay.
*/
IFLA_AMT_DISCOVERY_IP,
/* This attribute specify number of maximum tunnel. */
IFLA_AMT_MAX_TUNNELS,
__IFLA_AMT_MAX,
};
#define IFLA_AMT_MAX (__IFLA_AMT_MAX - 1)
#endif /* _AMT_H_ */

View File

@ -84,7 +84,7 @@ struct bpf_lpm_trie_key {
struct bpf_cgroup_storage_key {
__u64 cgroup_inode_id; /* cgroup inode id */
__u32 attach_type; /* program attach type (enum bpf_attach_type) */
__u32 attach_type; /* program attach type */
};
union bpf_iter_link_info {
@ -324,6 +324,9 @@ union bpf_iter_link_info {
* **BPF_PROG_TYPE_SK_LOOKUP**
* *data_in* and *data_out* must be NULL.
*
* **BPF_PROG_TYPE_XDP**
* *ctx_in* and *ctx_out* must be NULL.
*
* **BPF_PROG_TYPE_RAW_TRACEPOINT**,
* **BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE**
*
@ -524,15 +527,6 @@ union bpf_iter_link_info {
* Look up an element with the given *key* in the map referred to
* by the file descriptor *fd*, and if found, delete the element.
*
* For **BPF_MAP_TYPE_QUEUE** and **BPF_MAP_TYPE_STACK** map
* types, the *flags* argument needs to be set to 0, but for other
* map types, it may be specified as:
*
* **BPF_F_LOCK**
* Look up and delete the value of a spin-locked map
* without returning the lock. This must be specified if
* the elements contain a spinlock.
*
* The **BPF_MAP_TYPE_QUEUE** and **BPF_MAP_TYPE_STACK** map types
* implement this command as a "pop" operation, deleting the top
* element rather than one corresponding to *key*.
@ -542,10 +536,6 @@ union bpf_iter_link_info {
* This command is only valid for the following map types:
* * **BPF_MAP_TYPE_QUEUE**
* * **BPF_MAP_TYPE_STACK**
* * **BPF_MAP_TYPE_HASH**
* * **BPF_MAP_TYPE_PERCPU_HASH**
* * **BPF_MAP_TYPE_LRU_HASH**
* * **BPF_MAP_TYPE_LRU_PERCPU_HASH**
*
* Return
* Returns zero on success. On error, -1 is returned and *errno*
@ -847,7 +837,6 @@ enum bpf_cmd {
BPF_PROG_ATTACH,
BPF_PROG_DETACH,
BPF_PROG_TEST_RUN,
BPF_PROG_RUN = BPF_PROG_TEST_RUN,
BPF_PROG_GET_NEXT_ID,
BPF_MAP_GET_NEXT_ID,
BPF_PROG_GET_FD_BY_ID,
@ -906,7 +895,6 @@ enum bpf_map_type {
BPF_MAP_TYPE_RINGBUF,
BPF_MAP_TYPE_INODE_STORAGE,
BPF_MAP_TYPE_TASK_STORAGE,
BPF_MAP_TYPE_BLOOM_FILTER,
};
/* Note that tracing related programs such as
@ -949,7 +937,6 @@ enum bpf_prog_type {
BPF_PROG_TYPE_EXT,
BPF_PROG_TYPE_LSM,
BPF_PROG_TYPE_SK_LOOKUP,
BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */
};
enum bpf_attach_type {
@ -992,9 +979,6 @@ enum bpf_attach_type {
BPF_SK_LOOKUP,
BPF_XDP,
BPF_SK_SKB_VERDICT,
BPF_SK_REUSEPORT_SELECT,
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
BPF_PERF_EVENT,
__MAX_BPF_ATTACH_TYPE
};
@ -1008,7 +992,6 @@ enum bpf_link_type {
BPF_LINK_TYPE_ITER = 4,
BPF_LINK_TYPE_NETNS = 5,
BPF_LINK_TYPE_XDP = 6,
BPF_LINK_TYPE_PERF_EVENT = 7,
MAX_BPF_LINK_TYPE,
};
@ -1114,8 +1097,8 @@ enum bpf_link_type {
/* When BPF ldimm64's insn[0].src_reg != 0 then this can have
* the following extensions:
*
* insn[0].src_reg: BPF_PSEUDO_MAP_[FD|IDX]
* insn[0].imm: map fd or fd_idx
* insn[0].src_reg: BPF_PSEUDO_MAP_FD
* insn[0].imm: map fd
* insn[1].imm: 0
* insn[0].off: 0
* insn[1].off: 0
@ -1123,19 +1106,15 @@ enum bpf_link_type {
* verifier type: CONST_PTR_TO_MAP
*/
#define BPF_PSEUDO_MAP_FD 1
#define BPF_PSEUDO_MAP_IDX 5
/* insn[0].src_reg: BPF_PSEUDO_MAP_[IDX_]VALUE
* insn[0].imm: map fd or fd_idx
/* insn[0].src_reg: BPF_PSEUDO_MAP_VALUE
* insn[0].imm: map fd
* insn[1].imm: offset into value
* insn[0].off: 0
* insn[1].off: 0
* ldimm64 rewrite: address of map[0]+offset
* verifier type: PTR_TO_MAP_VALUE
*/
#define BPF_PSEUDO_MAP_VALUE 2
#define BPF_PSEUDO_MAP_IDX_VALUE 6
#define BPF_PSEUDO_MAP_VALUE 2
/* insn[0].src_reg: BPF_PSEUDO_BTF_ID
* insn[0].imm: kernel btd id of VAR
* insn[1].imm: 0
@ -1275,13 +1254,6 @@ union bpf_attr {
* struct stored as the
* map value
*/
/* Any per-map-type extra fields
*
* BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
* number of hash functions (if 0, the bloom filter will default
* to using 5 hash functions).
*/
__u64 map_extra;
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
@ -1342,8 +1314,6 @@ union bpf_attr {
/* or valid module BTF object fd or 0 to attach to vmlinux */
__u32 attach_btf_obj_fd;
};
__u32 :32; /* pad */
__aligned_u64 fd_array; /* array of FDs */
};
struct { /* anonymous struct used by BPF_OBJ_* commands */
@ -1456,13 +1426,6 @@ union bpf_attr {
__aligned_u64 iter_info; /* extra bpf_iter_link_info */
__u32 iter_info_len; /* iter_info length */
};
struct {
/* black box user-provided value passed through
* to BPF program at the execution time and
* accessible through bpf_get_attach_cookie() BPF helper
*/
__u64 bpf_cookie;
} perf_event;
};
} link_create;
@ -1637,7 +1600,7 @@ union bpf_attr {
* u32 bpf_get_smp_processor_id(void)
* Description
* Get the SMP (symmetric multiprocessing) processor id. Note that
* all programs run with migration disabled, which means that the
* all programs run with preemption disabled, which means that the
* SMP processor id is stable during all the execution of the
* program.
* Return
@ -2571,12 +2534,8 @@ union bpf_attr {
* The lower two bits of *flags* are used as the return code if
* the map lookup fails. This is so that the return value can be
* one of the XDP program return codes up to **XDP_TX**, as chosen
* by the caller. The higher bits of *flags* can be set to
* BPF_F_BROADCAST or BPF_F_EXCLUDE_INGRESS as defined below.
*
* With BPF_F_BROADCAST the packet will be broadcasted to all the
* interfaces in the map, with BPF_F_EXCLUDE_INGRESS the ingress
* interface will be excluded when do broadcasting.
* by the caller. Any higher bits in the *flags* argument must be
* unset.
*
* See also **bpf_redirect**\ (), which only supports redirecting
* to an ifindex, but doesn't require a map to do so.
@ -3263,7 +3222,7 @@ union bpf_attr {
* long bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
* Description
* Select a **SO_REUSEPORT** socket from a
* **BPF_MAP_TYPE_REUSEPORT_SOCKARRAY** *map*.
* **BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*.
* It checks the selected socket is matching the incoming
* request in the socket buffer.
* Return
@ -4054,7 +4013,7 @@ union bpf_attr {
* arguments. The *data* are a **u64** array and corresponding format string
* values are stored in the array. For strings and pointers where pointees
* are accessed, only the pointer values are stored in the *data* array.
* The *data_len* is the size of *data* in bytes - must be a multiple of 8.
* The *data_len* is the size of *data* in bytes.
*
* Formats **%s**, **%p{i,I}{4,6}** requires to read kernel memory.
* Reading kernel memory may fail due to either invalid address or
@ -4759,8 +4718,7 @@ union bpf_attr {
* Each format specifier in **fmt** corresponds to one u64 element
* in the **data** array. For strings and pointers where pointees
* are accessed, only the pointer values are stored in the *data*
* array. The *data_len* is the size of *data* in bytes - must be
* a multiple of 8.
* array. The *data_len* is the size of *data* in bytes.
*
* Formats **%s** and **%p{i,I}{4,6}** require to read kernel
* memory. Reading kernel memory may fail due to either invalid
@ -4777,167 +4735,6 @@ union bpf_attr {
* be zero-terminated except when **str_size** is 0.
*
* Or **-EBUSY** if the per-CPU memory copy buffer is busy.
*
* long bpf_sys_bpf(u32 cmd, void *attr, u32 attr_size)
* Description
* Execute bpf syscall with given arguments.
* Return
* A syscall result.
*
* long bpf_btf_find_by_name_kind(char *name, int name_sz, u32 kind, int flags)
* Description
* Find BTF type with given name and kind in vmlinux BTF or in module's BTFs.
* Return
* Returns btf_id and btf_obj_fd in lower and upper 32 bits.
*
* long bpf_sys_close(u32 fd)
* Description
* Execute close syscall for given FD.
* Return
* A syscall result.
*
* long bpf_timer_init(struct bpf_timer *timer, struct bpf_map *map, u64 flags)
* Description
* Initialize the timer.
* First 4 bits of *flags* specify clockid.
* Only CLOCK_MONOTONIC, CLOCK_REALTIME, CLOCK_BOOTTIME are allowed.
* All other bits of *flags* are reserved.
* The verifier will reject the program if *timer* is not from
* the same *map*.
* Return
* 0 on success.
* **-EBUSY** if *timer* is already initialized.
* **-EINVAL** if invalid *flags* are passed.
* **-EPERM** if *timer* is in a map that doesn't have any user references.
* The user space should either hold a file descriptor to a map with timers
* or pin such map in bpffs. When map is unpinned or file descriptor is
* closed all timers in the map will be cancelled and freed.
*
* long bpf_timer_set_callback(struct bpf_timer *timer, void *callback_fn)
* Description
* Configure the timer to call *callback_fn* static function.
* Return
* 0 on success.
* **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier.
* **-EPERM** if *timer* is in a map that doesn't have any user references.
* The user space should either hold a file descriptor to a map with timers
* or pin such map in bpffs. When map is unpinned or file descriptor is
* closed all timers in the map will be cancelled and freed.
*
* long bpf_timer_start(struct bpf_timer *timer, u64 nsecs, u64 flags)
* Description
* Set timer expiration N nanoseconds from the current time. The
* configured callback will be invoked in soft irq context on some cpu
* and will not repeat unless another bpf_timer_start() is made.
* In such case the next invocation can migrate to a different cpu.
* Since struct bpf_timer is a field inside map element the map
* owns the timer. The bpf_timer_set_callback() will increment refcnt
* of BPF program to make sure that callback_fn code stays valid.
* When user space reference to a map reaches zero all timers
* in a map are cancelled and corresponding program's refcnts are
* decremented. This is done to make sure that Ctrl-C of a user
* process doesn't leave any timers running. If map is pinned in
* bpffs the callback_fn can re-arm itself indefinitely.
* bpf_map_update/delete_elem() helpers and user space sys_bpf commands
* cancel and free the timer in the given map element.
* The map can contain timers that invoke callback_fn-s from different
* programs. The same callback_fn can serve different timers from
* different maps if key/value layout matches across maps.
* Every bpf_timer_set_callback() can have different callback_fn.
*
* Return
* 0 on success.
* **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier
* or invalid *flags* are passed.
*
* long bpf_timer_cancel(struct bpf_timer *timer)
* Description
* Cancel the timer and wait for callback_fn to finish if it was running.
* Return
* 0 if the timer was not active.
* 1 if the timer was active.
* **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier.
* **-EDEADLK** if callback_fn tried to call bpf_timer_cancel() on its
* own timer which would have led to a deadlock otherwise.
*
* u64 bpf_get_func_ip(void *ctx)
* Description
* Get address of the traced function (for tracing and kprobe programs).
* Return
* Address of the traced function.
*
* u64 bpf_get_attach_cookie(void *ctx)
* Description
* Get bpf_cookie value provided (optionally) during the program
* attachment. It might be different for each individual
* attachment, even if BPF program itself is the same.
* Expects BPF program context *ctx* as a first argument.
*
* Supported for the following program types:
* - kprobe/uprobe;
* - tracepoint;
* - perf_event.
* Return
* Value specified by user at BPF link creation/attachment time
* or 0, if it was not specified.
*
* long bpf_task_pt_regs(struct task_struct *task)
* Description
* Get the struct pt_regs associated with **task**.
* Return
* A pointer to struct pt_regs.
*
* long bpf_get_branch_snapshot(void *entries, u32 size, u64 flags)
* Description
* Get branch trace from hardware engines like Intel LBR. The
* hardware engine is stopped shortly after the helper is
* called. Therefore, the user need to filter branch entries
* based on the actual use case. To capture branch trace
* before the trigger point of the BPF program, the helper
* should be called at the beginning of the BPF program.
*
* The data is stored as struct perf_branch_entry into output
* buffer *entries*. *size* is the size of *entries* in bytes.
* *flags* is reserved for now and must be zero.
*
* Return
* On success, number of bytes written to *buf*. On error, a
* negative value.
*
* **-EINVAL** if *flags* is not zero.
*
* **-ENOENT** if architecture does not support branch records.
*
* long bpf_trace_vprintk(const char *fmt, u32 fmt_size, const void *data, u32 data_len)
* Description
* Behaves like **bpf_trace_printk**\ () helper, but takes an array of u64
* to format and can handle more format args as a result.
*
* Arguments are to be used as in **bpf_seq_printf**\ () helper.
* Return
* The number of bytes written to the buffer, or a negative error
* in case of failure.
*
* struct unix_sock *bpf_skc_to_unix_sock(void *sk)
* Description
* Dynamically cast a *sk* pointer to a *unix_sock* pointer.
* Return
* *sk* if casting is valid, or **NULL** otherwise.
*
* long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res)
* Description
* Get the address of a kernel symbol, returned in *res*. *res* is
* set to 0 if the symbol is not found.
* Return
* On success, zero. On error, a negative value.
*
* **-EINVAL** if *flags* is not zero.
*
* **-EINVAL** if string *name* is not the same size as *name_sz*.
*
* **-ENOENT** if symbol is not found.
*
* **-EPERM** if caller does not have permission to obtain kernel address.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@ -5106,20 +4903,6 @@ union bpf_attr {
FN(check_mtu), \
FN(for_each_map_elem), \
FN(snprintf), \
FN(sys_bpf), \
FN(btf_find_by_name_kind), \
FN(sys_close), \
FN(timer_init), \
FN(timer_set_callback), \
FN(timer_start), \
FN(timer_cancel), \
FN(get_func_ip), \
FN(get_attach_cookie), \
FN(task_pt_regs), \
FN(get_branch_snapshot), \
FN(trace_vprintk), \
FN(skc_to_unix_sock), \
FN(kallsyms_lookup_name), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
@ -5297,12 +5080,6 @@ enum {
BPF_F_BPRM_SECUREEXEC = (1ULL << 0),
};
/* Flags for bpf_redirect_map helper */
enum {
BPF_F_BROADCAST = (1ULL << 3),
BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
};
#define __bpf_md_ptr(type, name) \
union { \
type name; \
@ -5349,8 +5126,6 @@ struct __sk_buff {
__u32 gso_segs;
__bpf_md_ptr(struct bpf_sock *, sk);
__u32 gso_size;
__u32 :32; /* Padding, future use. */
__u64 hwtstamp;
};
struct bpf_tunnel_key {
@ -5589,20 +5364,6 @@ struct sk_reuseport_md {
__u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */
__u32 bind_inany; /* Is sock bound to an INANY address? */
__u32 hash; /* A hash of the packet 4 tuples */
/* When reuse->migrating_sk is NULL, it is selecting a sk for the
* new incoming connection request (e.g. selecting a listen sk for
* the received SYN in the TCP case). reuse->sk is one of the sk
* in the reuseport group. The bpf prog can use reuse->sk to learn
* the local listening ip/port without looking into the skb.
*
* When reuse->migrating_sk is not NULL, reuse->sk is closed and
* reuse->migrating_sk is the socket that needs to be migrated
* to another listening socket. migrating_sk could be a fullsock
* sk that is fully established or a reqsk that is in-the-middle
* of 3-way handshake.
*/
__bpf_md_ptr(struct bpf_sock *, sk);
__bpf_md_ptr(struct bpf_sock *, migrating_sk);
};
#define BPF_TAG_SIZE 8
@ -5644,7 +5405,6 @@ struct bpf_prog_info {
__u64 run_time_ns;
__u64 run_cnt;
__u64 recursion_misses;
__u32 verified_insns;
} __attribute__((aligned(8)));
struct bpf_map_info {
@ -5662,8 +5422,6 @@ struct bpf_map_info {
__u32 btf_id;
__u32 btf_key_type_id;
__u32 btf_value_type_id;
__u32 :32; /* alignment pad */
__u64 map_extra;
} __attribute__((aligned(8)));
struct bpf_btf_info {
@ -6251,11 +6009,6 @@ struct bpf_spin_lock {
__u32 val;
};
struct bpf_timer {
__u64 :64;
__u64 :64;
} __attribute__((aligned(8)));
struct bpf_sysctl {
__u32 write; /* Sysctl is being read (= 0) or written (= 1).
* Allows 1,2,4-byte read, but no write.

View File

@ -43,7 +43,7 @@ struct btf_type {
* "size" tells the size of the type it is describing.
*
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
* FUNC, FUNC_PROTO, VAR and DECL_TAG.
* FUNC, FUNC_PROTO and VAR.
* "type" is a type_id referring to another type.
*/
union {
@ -56,29 +56,25 @@ struct btf_type {
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
#define BTF_INFO_KFLAG(info) ((info) >> 31)
enum {
BTF_KIND_UNKN = 0, /* Unknown */
BTF_KIND_INT = 1, /* Integer */
BTF_KIND_PTR = 2, /* Pointer */
BTF_KIND_ARRAY = 3, /* Array */
BTF_KIND_STRUCT = 4, /* Struct */
BTF_KIND_UNION = 5, /* Union */
BTF_KIND_ENUM = 6, /* Enumeration */
BTF_KIND_FWD = 7, /* Forward */
BTF_KIND_TYPEDEF = 8, /* Typedef */
BTF_KIND_VOLATILE = 9, /* Volatile */
BTF_KIND_CONST = 10, /* Const */
BTF_KIND_RESTRICT = 11, /* Restrict */
BTF_KIND_FUNC = 12, /* Function */
BTF_KIND_FUNC_PROTO = 13, /* Function Proto */
BTF_KIND_VAR = 14, /* Variable */
BTF_KIND_DATASEC = 15, /* Section */
BTF_KIND_FLOAT = 16, /* Floating point */
BTF_KIND_DECL_TAG = 17, /* Decl Tag */
NR_BTF_KINDS,
BTF_KIND_MAX = NR_BTF_KINDS - 1,
};
#define BTF_KIND_UNKN 0 /* Unknown */
#define BTF_KIND_INT 1 /* Integer */
#define BTF_KIND_PTR 2 /* Pointer */
#define BTF_KIND_ARRAY 3 /* Array */
#define BTF_KIND_STRUCT 4 /* Struct */
#define BTF_KIND_UNION 5 /* Union */
#define BTF_KIND_ENUM 6 /* Enumeration */
#define BTF_KIND_FWD 7 /* Forward */
#define BTF_KIND_TYPEDEF 8 /* Typedef */
#define BTF_KIND_VOLATILE 9 /* Volatile */
#define BTF_KIND_CONST 10 /* Const */
#define BTF_KIND_RESTRICT 11 /* Restrict */
#define BTF_KIND_FUNC 12 /* Function */
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
#define BTF_KIND_VAR 14 /* Variable */
#define BTF_KIND_DATASEC 15 /* Section */
#define BTF_KIND_FLOAT 16 /* Floating point */
#define BTF_KIND_MAX BTF_KIND_FLOAT
#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
/* For some specific BTF_KIND, "struct btf_type" is immediately
* followed by extra data.
@ -174,15 +170,4 @@ struct btf_var_secinfo {
__u32 size;
};
/* BTF_KIND_DECL_TAG is followed by a single "struct btf_decl_tag" to describe
* additional information related to the tag applied location.
* If component_idx == -1, the tag is applied to a struct, union,
* variable or function. Otherwise, it is applied to a struct/union
* member or a func argument, and component_idx indicates which member
* or argument (0 ... vlen-1).
*/
struct btf_decl_tag {
__s32 component_idx;
};
#endif /* __LINUX_BTF_H__ */

View File

@ -123,8 +123,8 @@ struct can_frame {
/*
* defined bits for canfd_frame.flags
*
* The use of struct canfd_frame implies the FD Frame (FDF) bit to
* be set in the CAN frame bitstream on the wire. The FDF bit switch turns
* The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
* be set in the CAN frame bitstream on the wire. The EDL bit switch turns
* the CAN controllers bitstream processor into the CAN FD mode which creates
* two new options within the CAN FD frame specification:
*
@ -135,18 +135,9 @@ struct can_frame {
* controller only the CANFD_BRS bit is relevant for real CAN controllers when
* building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
* sense for virtual CAN interfaces to test applications with echoed frames.
*
* The struct can_frame and struct canfd_frame intentionally share the same
* layout to be able to write CAN frame content into a CAN FD frame structure.
* When this is done the former differentiation via CAN_MTU / CANFD_MTU gets
* lost. CANFD_FDF allows programmers to mark CAN FD frames in the case of
* using struct canfd_frame for mixed CAN / CAN FD content (dual use).
* N.B. the Kernel APIs do NOT provide mixed CAN / CAN FD content inside of
* struct canfd_frame therefore the CANFD_FDF flag is disregarded by Linux.
*/
#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
#define CANFD_FDF 0x04 /* mark CAN FD for dual use of struct canfd_frame */
/**
* struct canfd_frame - CAN flexible data rate frame structure

View File

@ -101,8 +101,6 @@ struct can_ctrlmode {
#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */
#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */
#define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */
#define CAN_CTRLMODE_TDC_AUTO 0x200 /* CAN transiver automatically calculates TDCV */
#define CAN_CTRLMODE_TDC_MANUAL 0x400 /* TDCV is manually set up by user */
/*
* CAN device statistics
@ -136,35 +134,10 @@ enum {
IFLA_CAN_BITRATE_CONST,
IFLA_CAN_DATA_BITRATE_CONST,
IFLA_CAN_BITRATE_MAX,
IFLA_CAN_TDC,
/* add new constants above here */
__IFLA_CAN_MAX,
IFLA_CAN_MAX = __IFLA_CAN_MAX - 1
__IFLA_CAN_MAX
};
/*
* CAN FD Transmitter Delay Compensation (TDC)
*
* Please refer to struct can_tdc_const and can_tdc in
* include/linux/can/bittiming.h for further details.
*/
enum {
IFLA_CAN_TDC_UNSPEC,
IFLA_CAN_TDC_TDCV_MIN, /* u32 */
IFLA_CAN_TDC_TDCV_MAX, /* u32 */
IFLA_CAN_TDC_TDCO_MIN, /* u32 */
IFLA_CAN_TDC_TDCO_MAX, /* u32 */
IFLA_CAN_TDC_TDCF_MIN, /* u32 */
IFLA_CAN_TDC_TDCF_MAX, /* u32 */
IFLA_CAN_TDC_TDCV, /* u32 */
IFLA_CAN_TDC_TDCO, /* u32 */
IFLA_CAN_TDC_TDCF, /* u32 */
/* add new constants above here */
__IFLA_CAN_TDC,
IFLA_CAN_TDC_MAX = __IFLA_CAN_TDC - 1
};
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
/* u16 termination range: 1..65535 Ohms */
#define CAN_TERMINATION_DISABLED 0

View File

@ -126,11 +126,6 @@ enum devlink_command {
DEVLINK_CMD_HEALTH_REPORTER_TEST,
DEVLINK_CMD_RATE_GET, /* can dump */
DEVLINK_CMD_RATE_SET,
DEVLINK_CMD_RATE_NEW,
DEVLINK_CMD_RATE_DEL,
/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@ -211,11 +206,6 @@ enum devlink_port_flavour {
*/
};
enum devlink_rate_type {
DEVLINK_RATE_TYPE_LEAF,
DEVLINK_RATE_TYPE_NODE,
};
enum devlink_param_cmode {
DEVLINK_PARAM_CMODE_RUNTIME,
DEVLINK_PARAM_CMODE_DRIVERINIT,
@ -544,15 +534,6 @@ enum devlink_attr {
DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */
DEVLINK_ATTR_PORT_PCI_SF_NUMBER, /* u32 */
DEVLINK_ATTR_RATE_TYPE, /* u16 */
DEVLINK_ATTR_RATE_TX_SHARE, /* u64 */
DEVLINK_ATTR_RATE_TX_MAX, /* u64 */
DEVLINK_ATTR_RATE_NODE_NAME, /* string */
DEVLINK_ATTR_RATE_PARENT_NODE_NAME, /* string */
DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, /* u32 */
/* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX,

View File

@ -54,7 +54,6 @@
#define ARPHRD_X25 271 /* CCITT X.25 */
#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
#define ARPHRD_CAN 280 /* Controller Area Network */
#define ARPHRD_MCTP 290
#define ARPHRD_PPP 512
#define ARPHRD_CISCO 513 /* Cisco HDLC */
#define ARPHRD_HDLC ARPHRD_CISCO

View File

@ -479,22 +479,16 @@ enum {
/* flags used in BRIDGE_VLANDB_DUMP_FLAGS attribute to affect dumps */
#define BRIDGE_VLANDB_DUMPF_STATS (1 << 0) /* Include stats in the dump */
#define BRIDGE_VLANDB_DUMPF_GLOBAL (1 << 1) /* Dump global vlan options only */
/* Bridge vlan RTM attributes
* [BRIDGE_VLANDB_ENTRY] = {
* [BRIDGE_VLANDB_ENTRY_INFO]
* ...
* }
* [BRIDGE_VLANDB_GLOBAL_OPTIONS] = {
* [BRIDGE_VLANDB_GOPTS_ID]
* ...
* }
*/
enum {
BRIDGE_VLANDB_UNSPEC,
BRIDGE_VLANDB_ENTRY,
BRIDGE_VLANDB_GLOBAL_OPTIONS,
__BRIDGE_VLANDB_MAX,
};
#define BRIDGE_VLANDB_MAX (__BRIDGE_VLANDB_MAX - 1)
@ -506,7 +500,6 @@ enum {
BRIDGE_VLANDB_ENTRY_STATE,
BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
BRIDGE_VLANDB_ENTRY_STATS,
BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
__BRIDGE_VLANDB_ENTRY_MAX,
};
#define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
@ -545,29 +538,6 @@ enum {
};
#define BRIDGE_VLANDB_STATS_MAX (__BRIDGE_VLANDB_STATS_MAX - 1)
enum {
BRIDGE_VLANDB_GOPTS_UNSPEC,
BRIDGE_VLANDB_GOPTS_ID,
BRIDGE_VLANDB_GOPTS_RANGE,
BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
BRIDGE_VLANDB_GOPTS_PAD,
BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE,
__BRIDGE_VLANDB_GOPTS_MAX
};
#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
/* Bridge multicast database attributes
* [MDBA_MDB] = {
* [MDBA_MDB_ENTRY] = {
@ -657,9 +627,6 @@ enum {
MDBA_ROUTER_PATTR_UNSPEC,
MDBA_ROUTER_PATTR_TIMER,
MDBA_ROUTER_PATTR_TYPE,
MDBA_ROUTER_PATTR_INET_TIMER,
MDBA_ROUTER_PATTR_INET6_TIMER,
MDBA_ROUTER_PATTR_VID,
__MDBA_ROUTER_PATTR_MAX
};
#define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
@ -751,14 +718,12 @@ struct br_mcast_stats {
/* bridge boolean options
* BR_BOOLOPT_NO_LL_LEARN - disable learning from link-local packets
* BR_BOOLOPT_MCAST_VLAN_SNOOPING - control vlan multicast snooping
*
* IMPORTANT: if adding a new option do not forget to handle
* it in br_boolopt_toggle/get and bridge sysfs
*/
enum br_boolopt_id {
BR_BOOLOPT_NO_LL_LEARN,
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
BR_BOOLOPT_MAX
};
@ -771,17 +736,4 @@ struct br_boolopt_multi {
__u32 optval;
__u32 optmask;
};
enum {
BRIDGE_QUERIER_UNSPEC,
BRIDGE_QUERIER_IP_ADDRESS,
BRIDGE_QUERIER_IP_PORT,
BRIDGE_QUERIER_IP_OTHER_TIMER,
BRIDGE_QUERIER_PAD,
BRIDGE_QUERIER_IPV6_ADDRESS,
BRIDGE_QUERIER_IPV6_PORT,
BRIDGE_QUERIER_IPV6_OTHER_TIMER,
__BRIDGE_QUERIER_MAX
};
#define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)
#endif /* _LINUX_IF_BRIDGE_H */

View File

@ -86,7 +86,6 @@
* over Ethernet
*/
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_REALTEK 0x8899 /* Multiple proprietary protocols */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
@ -117,7 +116,7 @@
#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is more than this value
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value
* then the frame is Ethernet II. Else it is 802.3 */
/*
@ -152,9 +151,6 @@
#define ETH_P_MAP 0x00F9 /* Qualcomm multiplexing and
* aggregation protocol
*/
#define ETH_P_MCTP 0x00FA /* Management component transport
* protocol packets
*/
/*
* This is an Ethernet frame header.

View File

@ -341,13 +341,6 @@ enum {
IFLA_ALT_IFNAME, /* Alternative ifname */
IFLA_PERM_ADDRESS,
IFLA_PROTO_DOWN_REASON,
/* device (sysfs) name as parent, used instead
* of IFLA_LINK where there's no parent netdev
*/
IFLA_PARENT_DEV_NAME,
IFLA_PARENT_DEV_BUS_NAME,
__IFLA_MAX
};
@ -415,7 +408,6 @@ enum {
IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
IFLA_INET6_TOKEN, /* device token */
IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
IFLA_INET6_RA_MTU, /* mtu carried in the RA message */
__IFLA_INET6_MAX
};
@ -478,7 +470,6 @@ enum {
IFLA_BR_MCAST_MLD_VERSION,
IFLA_BR_VLAN_STATS_PER_PORT,
IFLA_BR_MULTI_BOOLOPT,
IFLA_BR_MCAST_QUERIER_STATE,
__IFLA_BR_MAX,
};
@ -855,7 +846,6 @@ enum {
IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
__IFLA_BOND_MAX,
};
@ -1244,8 +1234,6 @@ enum {
#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4)
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5 (1U << 5)
enum {
IFLA_RMNET_UNSPEC,
@ -1261,14 +1249,4 @@ struct ifla_rmnet_flags {
__u32 mask;
};
/* MCTP section */
enum {
IFLA_MCTP_UNSPEC,
IFLA_MCTP_NET,
__IFLA_MCTP_MAX,
};
#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
#endif /* _LINUX_IF_LINK_H */

View File

@ -188,22 +188,11 @@ struct ip_mreq_source {
};
struct ip_msfilter {
union {
struct {
__be32 imsf_multiaddr_aux;
__be32 imsf_interface_aux;
__u32 imsf_fmode_aux;
__u32 imsf_numsrc_aux;
__be32 imsf_slist[1];
};
struct {
__be32 imsf_multiaddr;
__be32 imsf_interface;
__u32 imsf_fmode;
__u32 imsf_numsrc;
__be32 imsf_slist_flex[];
};
};
__be32 imsf_multiaddr;
__be32 imsf_interface;
__u32 imsf_fmode;
__u32 imsf_numsrc;
__be32 imsf_slist[1];
};
#define IP_MSFILTER_SIZE(numsrc) \
@ -222,22 +211,11 @@ struct group_source_req {
};
struct group_filter {
union {
struct {
__u32 gf_interface_aux; /* interface index */
struct __kernel_sockaddr_storage gf_group_aux; /* multicast address */
__u32 gf_fmode_aux; /* filter mode */
__u32 gf_numsrc_aux; /* number of sources */
struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
};
struct {
__u32 gf_interface; /* interface index */
struct __kernel_sockaddr_storage gf_group; /* multicast address */
__u32 gf_fmode; /* filter mode */
__u32 gf_numsrc; /* number of sources */
struct __kernel_sockaddr_storage gf_slist_flex[]; /* interface index */
};
};
__u32 gf_interface; /* interface index */
struct __kernel_sockaddr_storage gf_group; /* multicast address */
__u32 gf_fmode; /* filter mode */
__u32 gf_numsrc; /* number of sources */
struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
};
#define GROUP_FILTER_SIZE(numsrc) \

View File

@ -145,7 +145,6 @@ struct in6_flowlabel_req {
#define IPV6_TLV_PADN 1
#define IPV6_TLV_ROUTERALERT 5
#define IPV6_TLV_CALIPSO 7 /* RFC 5570 */
#define IPV6_TLV_IOAM 49 /* TEMPORARY IANA allocation for IOAM */
#define IPV6_TLV_JUMBO 194
#define IPV6_TLV_HAO 201 /* home address option */

View File

@ -1,133 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* IPv6 IOAM implementation
*
* Author:
* Justin Iurman <justin.iurman@uliege.be>
*/
#ifndef _LINUX_IOAM6_H
#define _LINUX_IOAM6_H
#include <asm/byteorder.h>
#include <linux/types.h>
#define IOAM6_U16_UNAVAILABLE U16_MAX
#define IOAM6_U32_UNAVAILABLE U32_MAX
#define IOAM6_U64_UNAVAILABLE U64_MAX
#define IOAM6_DEFAULT_ID (IOAM6_U32_UNAVAILABLE >> 8)
#define IOAM6_DEFAULT_ID_WIDE (IOAM6_U64_UNAVAILABLE >> 8)
#define IOAM6_DEFAULT_IF_ID IOAM6_U16_UNAVAILABLE
#define IOAM6_DEFAULT_IF_ID_WIDE IOAM6_U32_UNAVAILABLE
/*
* IPv6 IOAM Option Header
*/
struct ioam6_hdr {
__u8 opt_type;
__u8 opt_len;
__u8 :8; /* reserved */
#define IOAM6_TYPE_PREALLOC 0
__u8 type;
} __attribute__((packed));
/*
* IOAM Trace Header
*/
struct ioam6_trace_hdr {
__be16 namespace_id;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 :1, /* unused */
:1, /* unused */
overflow:1,
nodelen:5;
__u8 remlen:7,
:1; /* unused */
union {
__be32 type_be32;
struct {
__u32 bit7:1,
bit6:1,
bit5:1,
bit4:1,
bit3:1,
bit2:1,
bit1:1,
bit0:1,
bit15:1, /* unused */
bit14:1, /* unused */
bit13:1, /* unused */
bit12:1, /* unused */
bit11:1,
bit10:1,
bit9:1,
bit8:1,
bit23:1, /* reserved */
bit22:1,
bit21:1, /* unused */
bit20:1, /* unused */
bit19:1, /* unused */
bit18:1, /* unused */
bit17:1, /* unused */
bit16:1, /* unused */
:8; /* reserved */
} type;
};
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 nodelen:5,
overflow:1,
:1, /* unused */
:1; /* unused */
__u8 :1, /* unused */
remlen:7;
union {
__be32 type_be32;
struct {
__u32 bit0:1,
bit1:1,
bit2:1,
bit3:1,
bit4:1,
bit5:1,
bit6:1,
bit7:1,
bit8:1,
bit9:1,
bit10:1,
bit11:1,
bit12:1, /* unused */
bit13:1, /* unused */
bit14:1, /* unused */
bit15:1, /* unused */
bit16:1, /* unused */
bit17:1, /* unused */
bit18:1, /* unused */
bit19:1, /* unused */
bit20:1, /* unused */
bit21:1, /* unused */
bit22:1,
bit23:1, /* reserved */
:8; /* reserved */
} type;
};
#else
#error "Please fix <asm/byteorder.h>"
#endif
#define IOAM6_TRACE_DATA_SIZE_MAX 244
__u8 data[0];
} __attribute__((packed));
#endif /* _LINUX_IOAM6_H */

View File

@ -1,52 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* IPv6 IOAM Generic Netlink API
*
* Author:
* Justin Iurman <justin.iurman@uliege.be>
*/
#ifndef _LINUX_IOAM6_GENL_H
#define _LINUX_IOAM6_GENL_H
#define IOAM6_GENL_NAME "IOAM6"
#define IOAM6_GENL_VERSION 0x1
enum {
IOAM6_ATTR_UNSPEC,
IOAM6_ATTR_NS_ID, /* u16 */
IOAM6_ATTR_NS_DATA, /* u32 */
IOAM6_ATTR_NS_DATA_WIDE,/* u64 */
#define IOAM6_MAX_SCHEMA_DATA_LEN (255 * 4)
IOAM6_ATTR_SC_ID, /* u32 */
IOAM6_ATTR_SC_DATA, /* Binary */
IOAM6_ATTR_SC_NONE, /* Flag */
IOAM6_ATTR_PAD,
__IOAM6_ATTR_MAX,
};
#define IOAM6_ATTR_MAX (__IOAM6_ATTR_MAX - 1)
enum {
IOAM6_CMD_UNSPEC,
IOAM6_CMD_ADD_NAMESPACE,
IOAM6_CMD_DEL_NAMESPACE,
IOAM6_CMD_DUMP_NAMESPACES,
IOAM6_CMD_ADD_SCHEMA,
IOAM6_CMD_DEL_SCHEMA,
IOAM6_CMD_DUMP_SCHEMAS,
IOAM6_CMD_NS_SET_SCHEMA,
__IOAM6_CMD_MAX,
};
#define IOAM6_CMD_MAX (__IOAM6_CMD_MAX - 1)
#endif /* _LINUX_IOAM6_GENL_H */

View File

@ -1,49 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* IPv6 IOAM Lightweight Tunnel API
*
* Author:
* Justin Iurman <justin.iurman@uliege.be>
*/
#ifndef _LINUX_IOAM6_IPTUNNEL_H
#define _LINUX_IOAM6_IPTUNNEL_H
/* Encap modes:
* - inline: direct insertion
* - encap: ip6ip6 encapsulation
* - auto: __inline__ for local packets, encap for in-transit packets
*/
enum {
__IOAM6_IPTUNNEL_MODE_MIN,
IOAM6_IPTUNNEL_MODE_INLINE,
IOAM6_IPTUNNEL_MODE_ENCAP,
IOAM6_IPTUNNEL_MODE_AUTO,
__IOAM6_IPTUNNEL_MODE_MAX,
};
#define IOAM6_IPTUNNEL_MODE_MIN (__IOAM6_IPTUNNEL_MODE_MIN + 1)
#define IOAM6_IPTUNNEL_MODE_MAX (__IOAM6_IPTUNNEL_MODE_MAX - 1)
enum {
IOAM6_IPTUNNEL_UNSPEC,
/* Encap mode */
IOAM6_IPTUNNEL_MODE, /* u8 */
/* Tunnel dst address.
* For encap,auto modes.
*/
IOAM6_IPTUNNEL_DST, /* struct in6_addr */
/* IOAM Trace Header */
IOAM6_IPTUNNEL_TRACE, /* struct ioam6_trace_hdr */
__IOAM6_IPTUNNEL_MAX,
};
#define IOAM6_IPTUNNEL_MAX (__IOAM6_IPTUNNEL_MAX - 1)
#endif /* _LINUX_IOAM6_IPTUNNEL_H */

View File

@ -169,7 +169,6 @@ enum
IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
IPV4_DEVCONF_BC_FORWARDING,
IPV4_DEVCONF_ARP_EVICT_NOCARRIER,
__IPV4_DEVCONF_MAX
};

View File

@ -14,7 +14,6 @@ enum lwtunnel_encap_types {
LWTUNNEL_ENCAP_BPF,
LWTUNNEL_ENCAP_SEG6_LOCAL,
LWTUNNEL_ENCAP_RPL,
LWTUNNEL_ENCAP_IOAM6,
__LWTUNNEL_ENCAP_MAX,
};

View File

@ -97,6 +97,5 @@
#define DEVMEM_MAGIC 0x454d444d /* "DMEM" */
#define Z3FOLD_MAGIC 0x33
#define PPC_CMM_MAGIC 0xc7571590
#define SECRETMEM_MAGIC 0x5345434d /* "SECM" */
#endif /* __LINUX_MAGIC_H__ */

View File

@ -4,11 +4,6 @@
#include <linux/const.h>
#include <linux/types.h>
#include <linux/in.h> /* for sockaddr_in */
#include <linux/in6.h> /* for sockaddr_in6 */
#include <linux/socket.h> /* for sockaddr_storage and sa_family */
#include <sys/socket.h> /* for struct sockaddr */
#define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
#define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
@ -78,7 +73,6 @@ enum {
#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3)
enum {
MPTCP_PM_CMD_UNSPEC,
@ -111,7 +105,6 @@ struct mptcp_info {
__u64 mptcpi_rcv_nxt;
__u8 mptcpi_local_addr_used;
__u8 mptcpi_local_addr_max;
__u8 mptcpi_csum_enabled;
};
/*
@ -198,32 +191,4 @@ enum mptcp_event_attr {
#define MPTCP_RST_EBADPERF 5
#define MPTCP_RST_EMIDDLEBOX 6
struct mptcp_subflow_data {
__u32 size_subflow_data; /* size of this structure in userspace */
__u32 num_subflows; /* must be 0, set by kernel */
__u32 size_kernel; /* must be 0, set by kernel */
__u32 size_user; /* size of one element in data[] */
} __attribute__((aligned(8)));
struct mptcp_subflow_addrs {
union {
__kernel_sa_family_t sa_family;
struct sockaddr sa_local;
struct sockaddr_in sin_local;
struct sockaddr_in6 sin6_local;
struct __kernel_sockaddr_storage ss_local;
};
union {
struct sockaddr sa_remote;
struct sockaddr_in sin_remote;
struct sockaddr_in6 sin6_remote;
struct __kernel_sockaddr_storage ss_remote;
};
};
/* MPTCP socket options */
#define MPTCP_INFO 1
#define MPTCP_TCPINFO 2
#define MPTCP_SUBFLOW_ADDRS 3
#endif /* _MPTCP_H */

View File

@ -31,7 +31,6 @@ enum {
NDA_PROTOCOL, /* Originator of entry */
NDA_NH_ID,
NDA_FDB_EXT_ATTRS,
NDA_FLAGS_EXT,
__NDA_MAX
};
@ -41,16 +40,14 @@ enum {
* Neighbor Cache Entry Flags
*/
#define NTF_USE (1 << 0)
#define NTF_SELF (1 << 1)
#define NTF_MASTER (1 << 2)
#define NTF_PROXY (1 << 3) /* == ATF_PUBL */
#define NTF_EXT_LEARNED (1 << 4)
#define NTF_OFFLOADED (1 << 5)
#define NTF_STICKY (1 << 6)
#define NTF_ROUTER (1 << 7)
/* Extended flags under NDA_FLAGS_EXT: */
#define NTF_EXT_MANAGED (1 << 0)
#define NTF_USE 0x01
#define NTF_SELF 0x02
#define NTF_MASTER 0x04
#define NTF_PROXY 0x08 /* == ATF_PUBL */
#define NTF_EXT_LEARNED 0x10
#define NTF_OFFLOADED 0x20
#define NTF_STICKY 0x40
#define NTF_ROUTER 0x80
/*
* Neighbor Cache Entry States.
@ -68,22 +65,9 @@ enum {
#define NUD_PERMANENT 0x80
#define NUD_NONE 0x00
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change and make no
* address resolution or NUD.
*
* NUD_PERMANENT also cannot be deleted by garbage collectors. This holds true
* for dynamic entries with NTF_EXT_LEARNED flag as well. However, upon carrier
* down event, NUD_PERMANENT entries are not flushed whereas NTF_EXT_LEARNED
* flagged entries explicitly are (which is also consistent with the routing
* subsystem).
*
* When NTF_EXT_LEARNED is set for a bridge fdb entry the different cache entry
* states don't make sense and thus are ignored. Such entries don't age and
* can roam.
*
* NTF_EXT_MANAGED flagged neigbor entries are managed by the kernel on behalf
* of a user space control plane, and automatically refreshed so that (if
* possible) they remain in NUD_REACHABLE state.
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change
and make no address resolution or NUD.
NUD_PERMANENT also cannot be deleted by garbage collectors.
*/
struct nda_cacheinfo {

View File

@ -49,7 +49,6 @@ enum nf_inet_hooks {
enum nf_dev_hooks {
NF_NETDEV_INGRESS,
NF_NETDEV_EGRESS,
NF_NETDEV_NUMHOOKS
};

View File

@ -91,10 +91,9 @@ struct nlmsghdr {
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
#define NLMSG_DATA(nlh) ((void *)(((char *)nlh) + NLMSG_HDRLEN))
#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
(struct nlmsghdr *)(((char *)(nlh)) + \
NLMSG_ALIGN((nlh)->nlmsg_len)))
(struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
(nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
(nlh)->nlmsg_len <= (len))

View File

@ -22,7 +22,6 @@ enum {
__TCA_ACT_MAX
};
/* See other TCA_ACT_FLAGS_ * flags in include/net/act_api.h. */
#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
* actions stats.
*/

View File

@ -827,8 +827,6 @@ struct tc_codel_xstats {
/* FQ_CODEL */
#define FQ_CODEL_QUANTUM_MAX (1 << 20)
enum {
TCA_FQ_CODEL_UNSPEC,
TCA_FQ_CODEL_TARGET,
@ -840,8 +838,6 @@ enum {
TCA_FQ_CODEL_CE_THRESHOLD,
TCA_FQ_CODEL_DROP_BATCH_SIZE,
TCA_FQ_CODEL_MEMORY_LIMIT,
TCA_FQ_CODEL_CE_THRESHOLD_SELECTOR,
TCA_FQ_CODEL_CE_THRESHOLD_MASK,
__TCA_FQ_CODEL_MAX
};

View File

@ -141,7 +141,6 @@ typedef __s32 sctp_assoc_t;
#define SCTP_EXPOSE_POTENTIALLY_FAILED_STATE 131
#define SCTP_EXPOSE_PF_STATE SCTP_EXPOSE_POTENTIALLY_FAILED_STATE
#define SCTP_REMOTE_UDP_ENCAPS_PORT 132
#define SCTP_PLPMTUD_PROBE_INTERVAL 133
/* PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000
@ -1208,11 +1207,4 @@ enum sctp_sched_type {
SCTP_SS_MAX = SCTP_SS_RR
};
/* Probe Interval socket option */
struct sctp_probeinterval {
sctp_assoc_t spi_assoc_id;
struct sockaddr_storage spi_address;
__u32 spi_interval;
};
#endif /* _SCTP_H */

View File

@ -64,8 +64,6 @@ enum {
SEG6_LOCAL_ACTION_END_AM = 14,
/* custom BPF action */
SEG6_LOCAL_ACTION_END_BPF = 15,
/* decap and lookup of DA in v4 or v6 table */
SEG6_LOCAL_ACTION_END_DT46 = 16,
__SEG6_LOCAL_ACTION_MAX,
};

View File

@ -290,8 +290,6 @@ enum
LINUX_MIB_TCPDUPLICATEDATAREHASH, /* TCPDuplicateDataRehash */
LINUX_MIB_TCPDSACKRECVSEGS, /* TCPDSACKRecvSegs */
LINUX_MIB_TCPDSACKIGNOREDDUBIOUS, /* TCPDSACKIgnoredDubious */
LINUX_MIB_TCPMIGRATEREQSUCCESS, /* TCPMigrateReqSuccess */
LINUX_MIB_TCPMIGRATEREQFAILURE, /* TCPMigrateReqFailure */
__LINUX_MIB_MAX
};

View File

@ -26,9 +26,4 @@ struct __kernel_sockaddr_storage {
};
};
#define SOCK_SNDBUF_LOCK 1
#define SOCK_RCVBUF_LOCK 2
#define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
#endif /* _LINUX_SOCKET_H */

View File

@ -4,40 +4,3 @@
#ifndef __always_inline
#define __always_inline __inline__
#endif
/**
* __struct_group() - Create a mirrored named and anonyomous struct
*
* @TAG: The tag name for the named sub-struct (usually empty)
* @NAME: The identifier name of the mirrored sub-struct
* @ATTRS: Any struct attributes (usually empty)
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical layout
* and size: one anonymous and one named. The former's members can be used
* normally without sub-struct naming, and the latter can be used to
* reason about the start, end, and size of the group of struct members.
* The named struct can also be explicitly tagged for layer reuse, as well
* as both having struct attributes appended.
*/
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
union { \
struct { MEMBERS } ATTRS; \
struct TAG { MEMBERS } ATTRS NAME; \
}
/**
* __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
*
* @TYPE: The type of each flexible array element
* @NAME: The name of the flexible array member
*
* In order to have a flexible array member in a union or alone in a
* struct, it needs to be wrapped in an anonymous struct with at least 1
* named member, but that member can be empty.
*/
#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
struct { \
struct { } __empty_ ## NAME; \
TYPE NAME[]; \
}

View File

@ -17,7 +17,6 @@
#define SKBMOD_F_SMAC 0x2
#define SKBMOD_F_ETYPE 0x4
#define SKBMOD_F_SWAPMAC 0x8
#define SKBMOD_F_ECN 0x10
struct tc_skbmod {
tc_gen;

View File

@ -84,20 +84,6 @@
#define TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE 16
#define TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE 8
#define TLS_CIPHER_SM4_GCM 55
#define TLS_CIPHER_SM4_GCM_IV_SIZE 8
#define TLS_CIPHER_SM4_GCM_KEY_SIZE 16
#define TLS_CIPHER_SM4_GCM_SALT_SIZE 4
#define TLS_CIPHER_SM4_GCM_TAG_SIZE 16
#define TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE 8
#define TLS_CIPHER_SM4_CCM 56
#define TLS_CIPHER_SM4_CCM_IV_SIZE 8
#define TLS_CIPHER_SM4_CCM_KEY_SIZE 16
#define TLS_CIPHER_SM4_CCM_SALT_SIZE 4
#define TLS_CIPHER_SM4_CCM_TAG_SIZE 16
#define TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE 8
#define TLS_SET_RECORD_TYPE 1
#define TLS_GET_RECORD_TYPE 2
@ -138,22 +124,6 @@ struct tls12_crypto_info_chacha20_poly1305 {
unsigned char rec_seq[TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE];
};
struct tls12_crypto_info_sm4_gcm {
struct tls_crypto_info info;
unsigned char iv[TLS_CIPHER_SM4_GCM_IV_SIZE];
unsigned char key[TLS_CIPHER_SM4_GCM_KEY_SIZE];
unsigned char salt[TLS_CIPHER_SM4_GCM_SALT_SIZE];
unsigned char rec_seq[TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE];
};
struct tls12_crypto_info_sm4_ccm {
struct tls_crypto_info info;
unsigned char iv[TLS_CIPHER_SM4_CCM_IV_SIZE];
unsigned char key[TLS_CIPHER_SM4_CCM_KEY_SIZE];
unsigned char salt[TLS_CIPHER_SM4_CCM_SALT_SIZE];
unsigned char rec_seq[TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE];
};
enum {
TLS_INFO_UNSPEC,
TLS_INFO_VERSION,

40
include/uapi/linux/vdpa.h Normal file
View File

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* vdpa device management interface
* Copyright (c) 2020 Mellanox Technologies Ltd. All rights reserved.
*/
#ifndef _LINUX_VDPA_H_
#define _LINUX_VDPA_H_
#define VDPA_GENL_NAME "vdpa"
#define VDPA_GENL_VERSION 0x1
enum vdpa_command {
VDPA_CMD_UNSPEC,
VDPA_CMD_MGMTDEV_NEW,
VDPA_CMD_MGMTDEV_GET, /* can dump */
VDPA_CMD_DEV_NEW,
VDPA_CMD_DEV_DEL,
VDPA_CMD_DEV_GET, /* can dump */
};
enum vdpa_attr {
VDPA_ATTR_UNSPEC,
/* bus name (optional) + dev name together make the parent device handle */
VDPA_ATTR_MGMTDEV_BUS_NAME, /* string */
VDPA_ATTR_MGMTDEV_DEV_NAME, /* string */
VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES, /* u64 */
VDPA_ATTR_DEV_NAME, /* string */
VDPA_ATTR_DEV_ID, /* u32 */
VDPA_ATTR_DEV_VENDOR_ID, /* u32 */
VDPA_ATTR_DEV_MAX_VQS, /* u32 */
VDPA_ATTR_DEV_MAX_VQ_SIZE, /* u16 */
/* new attributes must be added above here */
VDPA_ATTR_MAX,
};
#endif

View File

@ -54,31 +54,7 @@
#define VIRTIO_ID_SOUND 25 /* virtio sound */
#define VIRTIO_ID_FS 26 /* virtio filesystem */
#define VIRTIO_ID_PMEM 27 /* virtio pmem */
#define VIRTIO_ID_RPMB 28 /* virtio rpmb */
#define VIRTIO_ID_MAC80211_HWSIM 29 /* virtio mac80211-hwsim */
#define VIRTIO_ID_VIDEO_ENCODER 30 /* virtio video encoder */
#define VIRTIO_ID_VIDEO_DECODER 31 /* virtio video decoder */
#define VIRTIO_ID_SCMI 32 /* virtio SCMI */
#define VIRTIO_ID_NITRO_SEC_MOD 33 /* virtio nitro secure module*/
#define VIRTIO_ID_I2C_ADAPTER 34 /* virtio i2c adapter */
#define VIRTIO_ID_WATCHDOG 35 /* virtio watchdog */
#define VIRTIO_ID_CAN 36 /* virtio can */
#define VIRTIO_ID_DMABUF 37 /* virtio dmabuf */
#define VIRTIO_ID_PARAM_SERV 38 /* virtio parameter server */
#define VIRTIO_ID_AUDIO_POLICY 39 /* virtio audio policy */
#define VIRTIO_ID_BT 40 /* virtio bluetooth */
#define VIRTIO_ID_GPIO 41 /* virtio gpio */
/*
* Virtio Transitional IDs
*/
#define VIRTIO_TRANS_ID_NET 1000 /* transitional virtio net */
#define VIRTIO_TRANS_ID_BLOCK 1001 /* transitional virtio block */
#define VIRTIO_TRANS_ID_BALLOON 1002 /* transitional virtio balloon */
#define VIRTIO_TRANS_ID_CONSOLE 1003 /* transitional virtio console */
#define VIRTIO_TRANS_ID_SCSI 1004 /* transitional virtio SCSI */
#define VIRTIO_TRANS_ID_RNG 1005 /* transitional virtio rng */
#define VIRTIO_TRANS_ID_9P 1009 /* transitional virtio 9p console */
#endif /* _LINUX_VIRTIO_IDS_H */

View File

@ -1,16 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (C) 2021 Intel Corporation.
*/
#ifndef _WWAN_H_
#define _WWAN_H_
enum {
IFLA_WWAN_UNSPEC,
IFLA_WWAN_LINK_ID, /* u32 */
__IFLA_WWAN_MAX
};
#define IFLA_WWAN_MAX (__IFLA_WWAN_MAX - 1)
#endif /* _WWAN_H_ */

View File

@ -215,11 +215,6 @@ enum {
XFRM_MSG_MAPPING,
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
XFRM_MSG_SETDEFAULT,
#define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
XFRM_MSG_GETDEFAULT,
#define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT
__XFRM_MSG_MAX
};
#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@ -513,15 +508,6 @@ struct xfrm_user_offload {
#define XFRM_OFFLOAD_IPV6 1
#define XFRM_OFFLOAD_INBOUND 2
struct xfrm_userpolicy_default {
#define XFRM_USERPOLICY_UNSPEC 0
#define XFRM_USERPOLICY_BLOCK 1
#define XFRM_USERPOLICY_ACCEPT 2
__u8 in;
__u8 fwd;
__u8 out;
};
/* backwards compatibility for userspace */
#define XFRMGRP_ACQUIRE 1
#define XFRMGRP_EXPIRE 2

View File

@ -51,9 +51,6 @@ void incomplete_command(void) __attribute__((noreturn));
#define NEXT_ARG_FWD() do { argv++; argc--; } while(0)
#define PREV_ARG() do { argv--; argc++; } while(0)
/* Upper limit for batch mode */
#define MAX_ARGS 512
#define TIME_UNITS_PER_SEC 1000000
#define NSEC_PER_USEC 1000
#define NSEC_PER_MSEC 1000000
@ -109,6 +106,17 @@ static inline bool is_addrtype_inet_not_multi(const inet_prefix *p)
return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET;
}
#define DN_MAXADDL 20
#ifndef AF_DECnet
#define AF_DECnet 12
#endif
struct dn_naddr
{
unsigned short a_len;
unsigned char a_addr[DN_MAXADDL];
};
#ifndef AF_MPLS
# define AF_MPLS 28
#endif
@ -198,15 +206,9 @@ bool matches(const char *prefix, const char *string);
int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta);
const char *ax25_ntop(int af, const void *addr, char *str, socklen_t len);
const char *rose_ntop(int af, const void *addr, char *buf, socklen_t buflen);
const char *mpls_ntop(int af, const void *addr, char *str, size_t len);
int mpls_pton(int af, const char *src, void *addr, size_t alen);
const char *netrom_ntop(int af, const void *addr, char *str, socklen_t len);
extern int __iproute2_hz_internal;
int __get_hz(void);

View File

@ -1 +1 @@
static const char version[] = "5.15.0";
static const char version[] = "5.13.0";

View File

@ -11,15 +11,14 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \
ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o \
ipnexthop.o ipmptcp.o iplink_bareudp.o iplink_wwan.o ipioam6.o \
iplink_amt.o
ipnexthop.o ipmptcp.o iplink_bareudp.o
RTMONOBJ=rtmon.o
include ../config.mk
ALLOBJ=$(IPOBJ) $(RTMONOBJ)
SCRIPTS=routel
SCRIPTS=ifcfg rtpr routel routef
TARGETS=ip rtmon
all: $(TARGETS) $(SCRIPTS)

150
ip/ifcfg Executable file
View File

@ -0,0 +1,150 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0
CheckForwarding () {
local sbase fwd
sbase=/proc/sys/net/ipv4/conf
fwd=0
if [ -d $sbase ]; then
for dir in $sbase/*/forwarding; do
fwd=$(( fwd + $(cat "$dir") ))
done
else
fwd=2
fi
return $fwd
}
RestartRDISC () {
killall -HUP rdisc || rdisc -fs
}
ABCMaskLen () {
local class;
class=${1%%.*}
if [ "$1" = "" -o $class -eq 0 -o $class -ge 224 ]; then return 0
elif [ $class -ge 224 ]; then return 0
elif [ $class -ge 192 ]; then return 24
elif [ $class -ge 128 ]; then return 16
else return 8; fi
}
label="label $1"
ldev="$1"
dev=${1%:*}
if [ "$dev" = "" -o "$1" = "help" ]; then
echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2
echo " add - add new address" 1>&2
echo " del - delete address" 1>&2
echo " stop - completely disable IP" 1>&2
exit 1
fi
shift
CheckForwarding
fwd=$?
if [ $fwd -ne 0 ]; then
echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2
fi
deleting=0
case "$1" in
add) shift ;;
stop)
if [ "$ldev" != "$dev" ]; then
echo "Cannot stop alias $ldev" 1>&2
exit 1;
fi
ip -4 addr flush dev $dev $label || exit 1
if [ $fwd -eq 0 ]; then RestartRDISC; fi
exit 0 ;;
del*)
deleting=1; shift ;;
*)
esac
ipaddr=
pfxlen=
if [ "$1" != "" ]; then
ipaddr=${1%/*}
if [ "$1" != "$ipaddr" ]; then
pfxlen=${1#*/}
fi
if [ "$ipaddr" = "" ]; then
echo "$1 is bad IP address." 1>&2
exit 1
fi
fi
shift
peer=$1
if [ "$peer" != "" ]; then
if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then
echo "Peer address with non-trivial netmask." 1>&2
exit 1
fi
pfx="$ipaddr peer $peer"
else
if [ "$ipaddr" = "" ]; then
echo "Missing IP address argument." 1>&2
exit 1
fi
if [ "$pfxlen" = "" ]; then
ABCMaskLen $ipaddr
pfxlen=$?
fi
pfx="$ipaddr/$pfxlen"
fi
if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then
label=
fi
if [ $deleting -ne 0 ]; then
ip addr del $pfx dev $dev $label || exit 1
if [ $fwd -eq 0 ]; then RestartRDISC; fi
exit 0
fi
if ! ip link set up dev $dev ; then
echo "Error: cannot enable interface $dev." 1>&2
exit 1
fi
if [ "$ipaddr" = "" ]; then exit 0; fi
if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then
echo "Error: some host already uses address $ipaddr on $dev." 1>&2
exit 1
fi
if ! ip address add $pfx brd + dev $dev $label; then
echo "Error: failed to add $pfx on $dev." 1>&2
exit 1
fi
arping -q -A -c 1 -I $dev $ipaddr
noarp=$?
( sleep 2 ;
arping -q -U -c 1 -I $dev $ipaddr ) >/dev/null 2>&1 </dev/null &
ip route add unreachable 224.0.0.0/24 >/dev/null 2>&1
ip route add unreachable 255.255.255.255 >/dev/null 2>&1
if [ "`ip link ls $dev | grep -c MULTICAST`" -ge 1 ]; then
ip route add 224.0.0.0/4 dev $dev scope global >/dev/null 2>&1
fi
if [ $fwd -eq 0 ]; then
if [ $noarp -eq 0 ]; then
ip ro append default dev $dev metric 30000 scope global
elif [ "$peer" != "" ]; then
if ping -q -c 2 -w 4 $peer ; then
ip ro append default via $peer dev $dev metric 30001
fi
fi
RestartRDISC
fi
exit 0

View File

@ -64,15 +64,15 @@ static void usage(void)
fprintf(stderr,
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
" ip [ -force ] -batch filename\n"
"where OBJECT := { address | addrlabel | amt | fou | help | ila | ioam | l2tp |\n"
" link | macsec | maddress | monitor | mptcp | mroute | mrule |\n"
"where OBJECT := { address | addrlabel | fou | help | ila | l2tp | link |\n"
" macsec | maddress | monitor | mptcp | mroute | mrule |\n"
" neighbor | neighbour | netconf | netns | nexthop | ntable |\n"
" ntbl | route | rule | sr | tap | tcpmetrics |\n"
" token | tunnel | tuntap | vrf | xfrm }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
" -f[amily] { inet | inet6 | mpls | bridge | link } |\n"
" -4 | -6 | -M | -B | -0 |\n"
" -4 | -6 | -I | -D | -M | -B | -0 |\n"
" -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
" -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |\n"
@ -121,7 +121,6 @@ static const struct cmd {
{ "sr", do_seg6 },
{ "nexthop", do_ipnh },
{ "mptcp", do_mptcp },
{ "ioam", do_ioam6 },
{ "help", do_help },
{ 0 }
};
@ -224,6 +223,8 @@ int main(int argc, char **argv)
preferred_family = AF_INET6;
} else if (strcmp(opt, "-0") == 0) {
preferred_family = AF_PACKET;
} else if (strcmp(opt, "-D") == 0) {
preferred_family = AF_DECnet;
} else if (strcmp(opt, "-M") == 0) {
preferred_family = AF_MPLS;
} else if (strcmp(opt, "-B") == 0) {

View File

@ -53,6 +53,7 @@ int print_prefix(struct nlmsghdr *n, void *arg);
int print_rule(struct nlmsghdr *n, void *arg);
int print_netconf(struct rtnl_ctrl_data *ctrl,
struct nlmsghdr *n, void *arg);
int print_nexthop(struct nlmsghdr *n, void *arg);
int print_nexthop_bucket(struct nlmsghdr *n, void *arg);
void netns_map_init(void);
void netns_nsid_socket_init(void);
@ -89,7 +90,6 @@ int netns_identify_pid(const char *pidstr, char *name, int len);
int do_seg6(int argc, char **argv);
int do_ipnh(int argc, char **argv);
int do_mptcp(int argc, char **argv);
int do_ioam6(int argc, char **argv);
int iplink_get(char *name, __u32 filt_mask);
int iplink_ifla_xstats(int argc, char **argv);
@ -167,8 +167,7 @@ int name_is_vrf(const char *name);
void print_num(FILE *fp, unsigned int width, uint64_t count);
void print_rt_flags(FILE *fp, unsigned int flags);
void print_rta_ifidx(FILE *fp, __u32 ifidx, const char *prefix);
void __print_rta_gateway(FILE *fp, unsigned char family, const char *gateway);
void print_rta_if(FILE *fp, const struct rtattr *rta, const char *prefix);
void print_rta_gateway(FILE *fp, unsigned char family,
const struct rtattr *rta);
#endif /* _IP_COMMON_H_ */

View File

@ -10,7 +10,6 @@
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -60,7 +59,6 @@ static void usage(void)
" ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"
" [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"
" ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
" [ nomaster ]\n"
" [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
" [ label LABEL ] [up] [ vrf NAME ] ]\n"
" ip address {showdump|restore}\n"
@ -546,29 +544,6 @@ static void print_vfinfo(FILE *fp, struct ifinfomsg *ifi, struct rtattr *vfinfo)
print_vf_stats64(fp, vf[IFLA_VF_STATS]);
}
static void size_columns(unsigned int cols[], unsigned int n, ...)
{
unsigned int i, len;
uint64_t val, powi;
va_list args;
va_start(args, n);
for (i = 0; i < n; i++) {
val = va_arg(args, unsigned long long);
if (human_readable)
continue;
for (len = 1, powi = 10; powi < val; len++, powi *= 10)
/* nothing */;
if (len > cols[i])
cols[i] = len;
}
va_end(args);
}
void print_num(FILE *fp, unsigned int width, uint64_t count)
{
const char *prefix = "kMGTPE";
@ -579,7 +554,7 @@ void print_num(FILE *fp, unsigned int width, uint64_t count)
char buf[64];
if (!human_readable || count < base) {
fprintf(fp, "%*"PRIu64" ", width, count);
fprintf(fp, "%-*"PRIu64" ", width, count);
return;
}
@ -606,7 +581,7 @@ void print_num(FILE *fp, unsigned int width, uint64_t count)
snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
(double) count / powi, *prefix, use_iec ? "i" : "");
fprintf(fp, "%*s ", width, buf);
fprintf(fp, "%-*s ", width, buf);
}
static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
@ -684,15 +659,6 @@ static void __print_link_stats(FILE *fp, struct rtattr *tb[])
{
const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
struct rtnl_link_stats64 _s, *s = &_s;
unsigned int cols[] = {
strlen("*X errors:"),
strlen("packets"),
strlen("errors"),
strlen("dropped"),
strlen("heartbt"),
strlen("overrun"),
strlen("compressed"),
};
int ret;
ret = get_rtnl_link_stats_rta(s, tb);
@ -773,98 +739,65 @@ static void __print_link_stats(FILE *fp, struct rtattr *tb[])
close_json_object();
close_json_object();
} else {
size_columns(cols, ARRAY_SIZE(cols),
s->rx_bytes, s->rx_packets, s->rx_errors,
s->rx_dropped, s->rx_missed_errors,
s->multicast, s->rx_compressed);
if (show_stats > 1)
size_columns(cols, ARRAY_SIZE(cols), 0,
s->rx_length_errors, s->rx_crc_errors,
s->rx_frame_errors, s->rx_fifo_errors,
s->rx_over_errors, s->rx_nohandler);
size_columns(cols, ARRAY_SIZE(cols),
s->tx_bytes, s->tx_packets, s->tx_errors,
s->tx_dropped, s->tx_carrier_errors,
s->collisions, s->tx_compressed);
if (show_stats > 1)
size_columns(cols, ARRAY_SIZE(cols), 0, 0,
s->tx_aborted_errors, s->tx_fifo_errors,
s->tx_window_errors,
s->tx_heartbeat_errors,
carrier_changes ?
rta_getattr_u32(carrier_changes) : 0);
/* RX stats */
fprintf(fp, " RX: %*s %*s %*s %*s %*s %*s %*s%s",
cols[0] - 4, "bytes", cols[1], "packets",
cols[2], "errors", cols[3], "dropped",
cols[4], "missed", cols[5], "mcast",
cols[6], s->rx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " RX: bytes packets errors dropped missed mcast %s%s",
s->rx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " ");
print_num(fp, cols[0], s->rx_bytes);
print_num(fp, cols[1], s->rx_packets);
print_num(fp, cols[2], s->rx_errors);
print_num(fp, cols[3], s->rx_dropped);
print_num(fp, cols[4], s->rx_missed_errors);
print_num(fp, cols[5], s->multicast);
print_num(fp, 10, s->rx_bytes);
print_num(fp, 8, s->rx_packets);
print_num(fp, 7, s->rx_errors);
print_num(fp, 7, s->rx_dropped);
print_num(fp, 7, s->rx_missed_errors);
print_num(fp, 7, s->multicast);
if (s->rx_compressed)
print_num(fp, cols[6], s->rx_compressed);
print_num(fp, 7, s->rx_compressed);
/* RX error stats */
if (show_stats > 1) {
fprintf(fp, "%s", _SL_);
fprintf(fp, " RX errors:%*s %*s %*s %*s %*s %*s %*s%s",
cols[0] - 10, "", cols[1], "length",
cols[2], "crc", cols[3], "frame",
cols[4], "fifo", cols[5], "overrun",
cols[6], s->rx_nohandler ? "nohandler" : "",
_SL_);
fprintf(fp, "%*s", cols[0] + 5, "");
print_num(fp, cols[1], s->rx_length_errors);
print_num(fp, cols[2], s->rx_crc_errors);
print_num(fp, cols[3], s->rx_frame_errors);
print_num(fp, cols[4], s->rx_fifo_errors);
print_num(fp, cols[5], s->rx_over_errors);
fprintf(fp, " RX errors: length crc frame fifo overrun%s%s",
s->rx_nohandler ? " nohandler" : "", _SL_);
fprintf(fp, " ");
print_num(fp, 8, s->rx_length_errors);
print_num(fp, 7, s->rx_crc_errors);
print_num(fp, 7, s->rx_frame_errors);
print_num(fp, 7, s->rx_fifo_errors);
print_num(fp, 7, s->rx_over_errors);
if (s->rx_nohandler)
print_num(fp, cols[6], s->rx_nohandler);
print_num(fp, 7, s->rx_nohandler);
}
fprintf(fp, "%s", _SL_);
/* TX stats */
fprintf(fp, " TX: %*s %*s %*s %*s %*s %*s %*s%s",
cols[0] - 4, "bytes", cols[1], "packets",
cols[2], "errors", cols[3], "dropped",
cols[4], "carrier", cols[5], "collsns",
cols[6], s->tx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
s->tx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " ");
print_num(fp, cols[0], s->tx_bytes);
print_num(fp, cols[1], s->tx_packets);
print_num(fp, cols[2], s->tx_errors);
print_num(fp, cols[3], s->tx_dropped);
print_num(fp, cols[4], s->tx_carrier_errors);
print_num(fp, cols[5], s->collisions);
print_num(fp, 10, s->tx_bytes);
print_num(fp, 8, s->tx_packets);
print_num(fp, 7, s->tx_errors);
print_num(fp, 7, s->tx_dropped);
print_num(fp, 7, s->tx_carrier_errors);
print_num(fp, 7, s->collisions);
if (s->tx_compressed)
print_num(fp, cols[6], s->tx_compressed);
print_num(fp, 7, s->tx_compressed);
/* TX error stats */
if (show_stats > 1) {
fprintf(fp, "%s", _SL_);
fprintf(fp, " TX errors:%*s %*s %*s %*s %*s %*s%s",
cols[0] - 10, "", cols[1], "aborted",
cols[2], "fifo", cols[3], "window",
cols[4], "heartbt",
cols[5], carrier_changes ? "transns" : "",
_SL_);
fprintf(fp, "%*s", cols[0] + 5, "");
print_num(fp, cols[1], s->tx_aborted_errors);
print_num(fp, cols[2], s->tx_fifo_errors);
print_num(fp, cols[3], s->tx_window_errors);
print_num(fp, cols[4], s->tx_heartbeat_errors);
fprintf(fp, " TX errors: aborted fifo window heartbeat");
if (carrier_changes)
print_num(fp, cols[5],
fprintf(fp, " transns");
fprintf(fp, "%s", _SL_);
fprintf(fp, " ");
print_num(fp, 8, s->tx_aborted_errors);
print_num(fp, 7, s->tx_fifo_errors);
print_num(fp, 7, s->tx_window_errors);
print_num(fp, 7, s->tx_heartbeat_errors);
if (carrier_changes)
print_num(fp, 7,
rta_getattr_u32(carrier_changes));
}
}
@ -1243,20 +1176,6 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
b1, sizeof(b1)));
}
if (tb[IFLA_PARENT_DEV_BUS_NAME]) {
print_string(PRINT_ANY,
"parentbus",
"parentbus %s ",
rta_getattr_str(tb[IFLA_PARENT_DEV_BUS_NAME]));
}
if (tb[IFLA_PARENT_DEV_NAME]) {
print_string(PRINT_ANY,
"parentdev",
"parentdev %s ",
rta_getattr_str(tb[IFLA_PARENT_DEV_NAME]));
}
}
if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
@ -2124,8 +2043,6 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
if (!name_is_vrf(*argv))
invarg("Not a valid VRF name\n", *argv);
filter.master = ifindex;
} else if (strcmp(*argv, "nomaster") == 0) {
filter.master = -1;
} else if (strcmp(*argv, "type") == 0) {
int soff;

View File

@ -1,333 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* ioam6.c "ip ioam"
*
* Author: Justin Iurman <justin.iurman@uliege.be>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <linux/genetlink.h>
#include <linux/ioam6_genl.h>
#include "utils.h"
#include "ip_common.h"
#include "libgenl.h"
#include "json_print.h"
static void usage(void)
{
fprintf(stderr,
"Usage: ip ioam { COMMAND | help }\n"
" ip ioam namespace show\n"
" ip ioam namespace add ID [ data DATA32 ] [ wide DATA64 ]\n"
" ip ioam namespace del ID\n"
" ip ioam schema show\n"
" ip ioam schema add ID DATA\n"
" ip ioam schema del ID\n"
" ip ioam namespace set ID schema { ID | none }\n");
exit(-1);
}
static struct rtnl_handle grth = { .fd = -1 };
static int genl_family = -1;
#define IOAM6_REQUEST(_req, _bufsiz, _cmd, _flags) \
GENL_REQUEST(_req, _bufsiz, genl_family, 0, \
IOAM6_GENL_VERSION, _cmd, _flags)
static struct {
unsigned int cmd;
__u32 sc_id;
__u32 ns_data;
__u64 ns_data_wide;
__u16 ns_id;
bool has_ns_data;
bool has_ns_data_wide;
bool sc_none;
__u8 sc_data[IOAM6_MAX_SCHEMA_DATA_LEN];
} opts;
static void print_namespace(struct rtattr *attrs[])
{
print_uint(PRINT_ANY, "namespace", "namespace %u",
rta_getattr_u16(attrs[IOAM6_ATTR_NS_ID]));
if (attrs[IOAM6_ATTR_SC_ID])
print_uint(PRINT_ANY, "schema", " [schema %u]",
rta_getattr_u32(attrs[IOAM6_ATTR_SC_ID]));
if (attrs[IOAM6_ATTR_NS_DATA])
print_hex(PRINT_ANY, "data", ", data %#010x",
rta_getattr_u32(attrs[IOAM6_ATTR_NS_DATA]));
if (attrs[IOAM6_ATTR_NS_DATA_WIDE])
print_0xhex(PRINT_ANY, "wide", ", wide %#018lx",
rta_getattr_u64(attrs[IOAM6_ATTR_NS_DATA_WIDE]));
print_nl();
}
static void print_schema(struct rtattr *attrs[])
{
__u8 data[IOAM6_MAX_SCHEMA_DATA_LEN];
int len, i = 0;
print_uint(PRINT_ANY, "schema", "schema %u",
rta_getattr_u32(attrs[IOAM6_ATTR_SC_ID]));
if (attrs[IOAM6_ATTR_NS_ID])
print_uint(PRINT_ANY, "namespace", " [namespace %u]",
rta_getattr_u16(attrs[IOAM6_ATTR_NS_ID]));
len = RTA_PAYLOAD(attrs[IOAM6_ATTR_SC_DATA]);
memcpy(data, RTA_DATA(attrs[IOAM6_ATTR_SC_DATA]), len);
print_null(PRINT_ANY, "data", ", data:", NULL);
while (i < len) {
print_hhu(PRINT_ANY, "", " %02x", data[i]);
i++;
}
print_nl();
}
static int process_msg(struct nlmsghdr *n, void *arg)
{
struct rtattr *attrs[IOAM6_ATTR_MAX + 1];
struct genlmsghdr *ghdr;
int len = n->nlmsg_len;
if (n->nlmsg_type != genl_family)
return -1;
len -= NLMSG_LENGTH(GENL_HDRLEN);
if (len < 0)
return -1;
ghdr = NLMSG_DATA(n);
parse_rtattr(attrs, IOAM6_ATTR_MAX, (void *)ghdr + GENL_HDRLEN, len);
open_json_object(NULL);
switch (ghdr->cmd) {
case IOAM6_CMD_DUMP_NAMESPACES:
print_namespace(attrs);
break;
case IOAM6_CMD_DUMP_SCHEMAS:
print_schema(attrs);
break;
}
close_json_object();
return 0;
}
static int ioam6_do_cmd(void)
{
IOAM6_REQUEST(req, 1056, opts.cmd, NLM_F_REQUEST);
int dump = 0;
if (genl_init_handle(&grth, IOAM6_GENL_NAME, &genl_family))
exit(1);
req.n.nlmsg_type = genl_family;
switch (opts.cmd) {
case IOAM6_CMD_ADD_NAMESPACE:
addattr16(&req.n, sizeof(req), IOAM6_ATTR_NS_ID, opts.ns_id);
if (opts.has_ns_data)
addattr32(&req.n, sizeof(req), IOAM6_ATTR_NS_DATA,
opts.ns_data);
if (opts.has_ns_data_wide)
addattr64(&req.n, sizeof(req), IOAM6_ATTR_NS_DATA_WIDE,
opts.ns_data_wide);
break;
case IOAM6_CMD_DEL_NAMESPACE:
addattr16(&req.n, sizeof(req), IOAM6_ATTR_NS_ID, opts.ns_id);
break;
case IOAM6_CMD_DUMP_NAMESPACES:
case IOAM6_CMD_DUMP_SCHEMAS:
dump = 1;
break;
case IOAM6_CMD_ADD_SCHEMA:
addattr32(&req.n, sizeof(req), IOAM6_ATTR_SC_ID, opts.sc_id);
addattr_l(&req.n, sizeof(req), IOAM6_ATTR_SC_DATA, opts.sc_data,
strlen((const char *)opts.sc_data));
break;
case IOAM6_CMD_DEL_SCHEMA:
addattr32(&req.n, sizeof(req), IOAM6_ATTR_SC_ID, opts.sc_id);
break;
case IOAM6_CMD_NS_SET_SCHEMA:
addattr16(&req.n, sizeof(req), IOAM6_ATTR_NS_ID, opts.ns_id);
if (opts.sc_none)
addattr(&req.n, sizeof(req), IOAM6_ATTR_SC_NONE);
else
addattr32(&req.n, sizeof(req), IOAM6_ATTR_SC_ID,
opts.sc_id);
break;
}
if (!dump) {
if (rtnl_talk(&grth, &req.n, NULL) < 0)
return -1;
} else {
req.n.nlmsg_flags |= NLM_F_DUMP;
req.n.nlmsg_seq = grth.dump = ++grth.seq;
if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
perror("Failed to send dump request");
exit(1);
}
new_json_obj(json);
if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
exit(1);
}
delete_json_obj();
fflush(stdout);
}
return 0;
}
int do_ioam6(int argc, char **argv)
{
bool maybe_wide = false;
if (argc < 1 || strcmp(*argv, "help") == 0)
usage();
memset(&opts, 0, sizeof(opts));
if (strcmp(*argv, "namespace") == 0) {
NEXT_ARG();
if (strcmp(*argv, "show") == 0) {
opts.cmd = IOAM6_CMD_DUMP_NAMESPACES;
} else if (strcmp(*argv, "add") == 0) {
NEXT_ARG();
if (get_u16(&opts.ns_id, *argv, 0))
invarg("Invalid namespace ID", *argv);
if (NEXT_ARG_OK()) {
NEXT_ARG_FWD();
if (strcmp(*argv, "data") == 0) {
NEXT_ARG();
if (get_u32(&opts.ns_data, *argv, 0))
invarg("Invalid data", *argv);
maybe_wide = true;
opts.has_ns_data = true;
} else if (strcmp(*argv, "wide") == 0) {
NEXT_ARG();
if (get_u64(&opts.ns_data_wide, *argv, 16))
invarg("Invalid wide data", *argv);
opts.has_ns_data_wide = true;
} else {
invarg("Invalid argument", *argv);
}
}
if (NEXT_ARG_OK()) {
NEXT_ARG_FWD();
if (!maybe_wide || strcmp(*argv, "wide") != 0)
invarg("Unexpected argument", *argv);
NEXT_ARG();
if (get_u64(&opts.ns_data_wide, *argv, 16))
invarg("Invalid wide data", *argv);
opts.has_ns_data_wide = true;
}
opts.cmd = IOAM6_CMD_ADD_NAMESPACE;
} else if (strcmp(*argv, "del") == 0) {
NEXT_ARG();
if (get_u16(&opts.ns_id, *argv, 0))
invarg("Invalid namespace ID", *argv);
opts.cmd = IOAM6_CMD_DEL_NAMESPACE;
} else if (strcmp(*argv, "set") == 0) {
NEXT_ARG();
if (get_u16(&opts.ns_id, *argv, 0))
invarg("Invalid namespace ID", *argv);
NEXT_ARG();
if (strcmp(*argv, "schema") != 0)
invarg("Unknown", *argv);
NEXT_ARG();
if (strcmp(*argv, "none") == 0) {
opts.sc_none = true;
} else {
if (get_u32(&opts.sc_id, *argv, 0))
invarg("Invalid schema ID", *argv);
opts.sc_none = false;
}
opts.cmd = IOAM6_CMD_NS_SET_SCHEMA;
} else {
invarg("Unknown", *argv);
}
} else if (strcmp(*argv, "schema") == 0) {
NEXT_ARG();
if (strcmp(*argv, "show") == 0) {
opts.cmd = IOAM6_CMD_DUMP_SCHEMAS;
} else if (strcmp(*argv, "add") == 0) {
NEXT_ARG();
if (get_u32(&opts.sc_id, *argv, 0))
invarg("Invalid schema ID", *argv);
NEXT_ARG();
if (strlen(*argv) > IOAM6_MAX_SCHEMA_DATA_LEN)
invarg("Schema DATA too big", *argv);
memcpy(opts.sc_data, *argv, strlen(*argv));
opts.cmd = IOAM6_CMD_ADD_SCHEMA;
} else if (strcmp(*argv, "del") == 0) {
NEXT_ARG();
if (get_u32(&opts.sc_id, *argv, 0))
invarg("Invalid schema ID", *argv);
opts.cmd = IOAM6_CMD_DEL_SCHEMA;
} else {
invarg("Unknown", *argv);
}
} else {
invarg("Unknown", *argv);
}
return ioam6_do_cmd();
}

View File

@ -50,21 +50,20 @@ void iplink_types_usage(void)
{
/* Remember to add new entry here if new type is added. */
fprintf(stderr,
"TYPE := { amt | bareudp | bond | bond_slave | bridge | bridge_slave |\n"
"TYPE := { bareudp | bond | bond_slave | bridge | bridge_slave |\n"
" dummy | erspan | geneve | gre | gretap | ifb |\n"
" ip6erspan | ip6gre | ip6gretap | ip6tnl |\n"
" ipip | ipoib | ipvlan | ipvtap |\n"
" macsec | macvlan | macvtap |\n"
" netdevsim | nlmon | rmnet | sit | team | team_slave |\n"
" vcan | veth | vlan | vrf | vti | vxcan | vxlan | wwan |\n"
" xfrm }\n");
" vcan | veth | vlan | vrf | vti | vxcan | vxlan | xfrm }\n");
}
void iplink_usage(void)
{
if (iplink_have_newlink()) {
fprintf(stderr,
"Usage: ip link add [link DEV | parentdev NAME] [ name ] NAME\n"
"Usage: ip link add [link DEV] [ name ] NAME\n"
" [ txqueuelen PACKETS ]\n"
" [ address LLADDR ]\n"
" [ broadcast LLADDR ]\n"
@ -120,7 +119,6 @@ void iplink_usage(void)
" [ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n"
"\n"
" ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
" [nomaster]\n"
"\n"
" ip link xstats type TYPE [ ARGS ]\n"
"\n"
@ -579,7 +577,6 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
{
bool move_netns = false;
char *name = NULL;
char *dev = NULL;
char *link = NULL;
@ -685,7 +682,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
IFLA_NET_NS_PID, &netns, 4);
else
invarg("Invalid \"netns\" value\n", *argv);
move_netns = true;
} else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG();
req->i.ifi_change |= IFF_MULTICAST;
@ -942,10 +938,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
*argv);
addattr32(&req->n, sizeof(*req),
IFLA_GSO_MAX_SEGS, max_segs);
} else if (strcmp(*argv, "parentdev") == 0) {
NEXT_ARG();
addattr_l(&req->n, sizeof(*req), IFLA_PARENT_DEV_NAME,
*argv, strlen(*argv) + 1);
} else {
if (matches(*argv, "help") == 0)
usage();
@ -983,11 +975,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
}
}
if (index &&
(!(req->n.nlmsg_flags & NLM_F_CREATE) &&
!move_netns)) {
if (!(req->n.nlmsg_flags & NLM_F_CREATE) && index) {
fprintf(stderr,
"index can be used only when creating devices or when moving device to another netns.\n");
"index can be used only when creating devices.\n");
exit(-1);
}
@ -1024,9 +1014,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
/* Not renaming to the same name */
if (name == dev)
name = NULL;
if (index)
addattr32(&req->n, sizeof(*req), IFLA_NEW_IFINDEX, index);
} else {
if (name != dev) {
fprintf(stderr,

View File

@ -1,200 +0,0 @@
/*
* iplink_amt.c AMT device support
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Taehee Yoo <ap420073@gmail.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <linux/ip.h>
#include <linux/if_link.h>
#include <arpa/inet.h>
#include <linux/amt.h>
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
#define AMT_ATTRSET(attrs, type) (((attrs) & (1L << (type))) != 0)
static void print_usage(FILE *f)
{
fprintf(f,
"Usage: ... amt\n"
" [ discovery IP_ADDRESS ]\n"
" [ mode MODE ]\n"
" [ local ADDR ]\n"
" [ dev PHYS_DEV ]\n"
" [ relay_port PORT ]\n"
" [ gateway_port PORT ]\n"
" [ max_tunnels NUMBER ]\n"
"\n"
"Where: ADDR := { IP_ADDRESS }\n"
" MODE := { gateway | relay }\n"
);
}
static char *modename[] = {"gateway", "relay"};
static void usage(void)
{
print_usage(stderr);
}
static void check_duparg(__u64 *attrs, int type, const char *key,
const char *argv)
{
if (!AMT_ATTRSET(*attrs, type)) {
*attrs |= (1L << type);
return;
}
duparg2(key, argv);
}
static int amt_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
unsigned int mode, max_tunnels;
inet_prefix saddr, daddr;
__u64 attrs = 0;
__u16 port;
saddr.family = daddr.family = AF_UNSPEC;
inet_prefix_reset(&saddr);
inet_prefix_reset(&daddr);
while (argc > 0) {
if (strcmp(*argv, "mode") == 0) {
NEXT_ARG();
if (strcmp(*argv, "gateway") == 0) {
mode = 0;
} else if (strcmp(*argv, "relay") == 0) {
mode = 1;
} else {
usage();
return -1;
}
addattr32(n, 1024, IFLA_AMT_MODE, mode);
} else if (strcmp(*argv, "relay_port") == 0) {
NEXT_ARG();
if (get_u16(&port, *argv, 0))
invarg("relay_port", *argv);
addattr16(n, 1024, IFLA_AMT_RELAY_PORT, htons(port));
} else if (strcmp(*argv, "gateway_port") == 0) {
NEXT_ARG();
if (get_u16(&port, *argv, 0))
invarg("gateway_port", *argv);
addattr16(n, 1024, IFLA_AMT_GATEWAY_PORT, htons(port));
} else if (strcmp(*argv, "max_tunnels") == 0) {
NEXT_ARG();
if (get_u32(&max_tunnels, *argv, 0))
invarg("max_tunnels", *argv);
addattr32(n, 1024, IFLA_AMT_MAX_TUNNELS, max_tunnels);
} else if (strcmp(*argv, "dev") == 0) {
unsigned int link;
NEXT_ARG();
link = ll_name_to_index(*argv);
if (!link)
exit(nodev(*argv));
addattr32(n, 1024, IFLA_AMT_LINK, link);
} else if (strcmp(*argv, "local") == 0) {
NEXT_ARG();
check_duparg(&attrs, IFLA_AMT_LOCAL_IP, "local", *argv);
get_addr(&saddr, *argv, daddr.family);
if (is_addrtype_inet(&saddr))
addattr_l(n, 1024, IFLA_AMT_LOCAL_IP,
saddr.data, saddr.bytelen);
} else if (strcmp(*argv, "discovery") == 0) {
NEXT_ARG();
check_duparg(&attrs, IFLA_AMT_DISCOVERY_IP,
"discovery", *argv);
get_addr(&daddr, *argv, daddr.family);
if (is_addrtype_inet(&daddr))
addattr_l(n, 1024, IFLA_AMT_DISCOVERY_IP,
daddr.data, daddr.bytelen);
} else if (strcmp(*argv, "help") == 0) {
usage();
return -1;
} else {
fprintf(stderr, "amt: unknown command \"%s\"?\n", *argv);
usage();
return -1;
}
argc--, argv++;
}
return 0;
}
static void amt_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
if (!tb)
return;
if (tb[IFLA_AMT_MODE])
print_string(PRINT_ANY, "mode", "%s ",
modename[rta_getattr_u32(tb[IFLA_AMT_MODE])]);
if (tb[IFLA_AMT_GATEWAY_PORT])
print_uint(PRINT_ANY, "gateway_port", "gateway_port %u ",
rta_getattr_be16(tb[IFLA_AMT_GATEWAY_PORT]));
if (tb[IFLA_AMT_RELAY_PORT])
print_uint(PRINT_ANY, "relay_port", "relay_port %u ",
rta_getattr_be16(tb[IFLA_AMT_RELAY_PORT]));
if (tb[IFLA_AMT_LOCAL_IP]) {
__be32 addr = rta_getattr_u32(tb[IFLA_AMT_LOCAL_IP]);
print_string(PRINT_ANY, "local", "local %s ",
format_host(AF_INET, 4, &addr));
}
if (tb[IFLA_AMT_REMOTE_IP]) {
__be32 addr = rta_getattr_u32(tb[IFLA_AMT_REMOTE_IP]);
print_string(PRINT_ANY, "remote", "remote %s ",
format_host(AF_INET, 4, &addr));
}
if (tb[IFLA_AMT_DISCOVERY_IP]) {
__be32 addr = rta_getattr_u32(tb[IFLA_AMT_DISCOVERY_IP]);
print_string(PRINT_ANY, "discovery", "discovery %s ",
format_host(AF_INET, 4, &addr));
}
if (tb[IFLA_AMT_LINK]) {
unsigned int link = rta_getattr_u32(tb[IFLA_AMT_LINK]);
print_string(PRINT_ANY, "link", "dev %s ",
ll_index_to_name(link));
}
if (tb[IFLA_AMT_MAX_TUNNELS])
print_uint(PRINT_ANY, "max_tunnels", "max_tunnels %u ",
rta_getattr_u32(tb[IFLA_AMT_MAX_TUNNELS]));
}
static void amt_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
{
print_usage(f);
}
struct link_util amt_link_util = {
.id = "amt",
.maxattr = IFLA_AMT_MAX,
.parse_opt = amt_parse_opt,
.print_opt = amt_print_opt,
.print_help = amt_print_help,
};

View File

@ -41,9 +41,6 @@ static const char *arp_validate_tbl[] = {
"active",
"backup",
"all",
"filter",
"filter_active",
"filter_backup",
NULL,
};
@ -77,12 +74,6 @@ static const char *xmit_hash_policy_tbl[] = {
NULL,
};
static const char *lacp_active_tbl[] = {
"off",
"on",
NULL,
};
static const char *lacp_rate_tbl[] = {
"slow",
"fast",
@ -148,19 +139,17 @@ static void print_explain(FILE *f)
" [ packets_per_slave PACKETS_PER_SLAVE ]\n"
" [ tlb_dynamic_lb TLB_DYNAMIC_LB ]\n"
" [ lacp_rate LACP_RATE ]\n"
" [ lacp_active LACP_ACTIVE]\n"
" [ ad_select AD_SELECT ]\n"
" [ ad_user_port_key PORTKEY ]\n"
" [ ad_actor_sys_prio SYSPRIO ]\n"
" [ ad_actor_system LLADDR ]\n"
"\n"
"BONDMODE := balance-rr|active-backup|balance-xor|broadcast|802.3ad|balance-tlb|balance-alb\n"
"ARP_VALIDATE := none|active|backup|all|filter|filter_active|filter_backup\n"
"ARP_VALIDATE := none|active|backup|all\n"
"ARP_ALL_TARGETS := any|all\n"
"PRIMARY_RESELECT := always|better|failure\n"
"FAIL_OVER_MAC := none|active|follow\n"
"XMIT_HASH_POLICY := layer2|layer2+3|layer3+4|encap2+3|encap3+4|vlan+srcmac\n"
"LACP_ACTIVE := off|on\n"
"LACP_RATE := slow|fast\n"
"AD_SELECT := stable|bandwidth|count\n"
);
@ -176,7 +165,7 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
{
__u8 mode, use_carrier, primary_reselect, fail_over_mac;
__u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
__u8 lacp_active, lacp_rate, ad_select, tlb_dynamic_lb;
__u8 lacp_rate, ad_select, tlb_dynamic_lb;
__u16 ad_user_port_key, ad_actor_sys_prio;
__u32 miimon, updelay, downdelay, peer_notify_delay, arp_interval, arp_validate;
__u32 arp_all_targets, resend_igmp, min_links, lp_interval;
@ -334,13 +323,6 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
lacp_rate = get_index(lacp_rate_tbl, *argv);
addattr8(n, 1024, IFLA_BOND_AD_LACP_RATE, lacp_rate);
} else if (strcmp(*argv, "lacp_active") == 0) {
NEXT_ARG();
if (get_index(lacp_active_tbl, *argv) < 0)
invarg("invalid lacp_active", *argv);
lacp_active = get_index(lacp_active_tbl, *argv);
addattr8(n, 1024, IFLA_BOND_AD_LACP_ACTIVE, lacp_active);
} else if (matches(*argv, "ad_select") == 0) {
NEXT_ARG();
if (get_index(ad_select_tbl, *argv) < 0)
@ -579,15 +561,6 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
"packets_per_slave %u ",
rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]));
if (tb[IFLA_BOND_AD_LACP_ACTIVE]) {
const char *lacp_active = get_name(lacp_active_tbl,
rta_getattr_u8(tb[IFLA_BOND_AD_LACP_ACTIVE]));
print_string(PRINT_ANY,
"ad_lacp_active",
"lacp_active %s ",
lacp_active);
}
if (tb[IFLA_BOND_AD_LACP_RATE]) {
const char *lacp_rate = get_name(lacp_rate_tbl,
rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE]));

View File

@ -43,7 +43,6 @@ static void print_explain(FILE *f)
" [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
" [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_vlan_snooping MULTICAST_VLAN_SNOOPING ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n"
" [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n"
" [ mcast_querier MULTICAST_QUERIER ]\n"
@ -84,7 +83,6 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
struct br_boolopt_multi bm = {};
__u32 val;
while (argc > 0) {
@ -202,18 +200,6 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
invarg("invalid mcast_snooping", *argv);
addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
} else if (strcmp(*argv, "mcast_vlan_snooping") == 0) {
__u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
__u8 mcast_vlan_snooping;
NEXT_ARG();
if (get_u8(&mcast_vlan_snooping, *argv, 0))
invarg("invalid mcast_vlan_snooping", *argv);
bm.optmask |= 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
if (mcast_vlan_snooping)
bm.optval |= mcvl_bit;
else
bm.optval &= ~mcvl_bit;
} else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
__u8 mcast_qui;
@ -393,9 +379,6 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
argc--, argv++;
}
if (bm.optmask)
addattr_l(n, 1024, IFLA_BR_MULTI_BOOLOPT,
&bm, sizeof(bm));
return 0;
}
@ -576,18 +559,6 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
"mcast_snooping %u ",
rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
if (tb[IFLA_BR_MULTI_BOOLOPT]) {
__u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
struct br_boolopt_multi *bm;
bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]);
if (bm->optmask & mcvl_bit)
print_uint(PRINT_ANY,
"mcast_vlan_snooping",
"mcast_vlan_snooping %u ",
!!(bm->optval & mcvl_bit));
}
if (tb[IFLA_BR_MCAST_ROUTER])
print_uint(PRINT_ANY,
"mcast_router",

View File

@ -28,7 +28,6 @@ static void print_usage(FILE *f)
"\n"
"\t[ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |\n"
"\t[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1\n \t dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]\n"
"\t[ tdcv TDCV tdco TDCO tdcf TDCF ]\n"
"\n"
"\t[ loopback { on | off } ]\n"
"\t[ listen-only { on | off } ]\n"
@ -39,24 +38,20 @@ static void print_usage(FILE *f)
"\t[ fd-non-iso { on | off } ]\n"
"\t[ presume-ack { on | off } ]\n"
"\t[ cc-len8-dlc { on | off } ]\n"
"\t[ tdc-mode { auto | manual | off } ]\n"
"\n"
"\t[ restart-ms TIME-MS ]\n"
"\t[ restart ]\n"
"\n"
"\t[ termination { 0..65535 } ]\n"
"\n"
"\tWhere: BITRATE := { NUMBER in bps }\n"
"\tWhere: BITRATE := { 1..1000000 }\n"
"\t SAMPLE-POINT := { 0.000..0.999 }\n"
"\t TQ := { NUMBER in ns }\n"
"\t PROP-SEG := { NUMBER in tq }\n"
"\t PHASE-SEG1 := { NUMBER in tq }\n"
"\t PHASE-SEG2 := { NUMBER in tq }\n"
"\t SJW := { NUMBER in tq }\n"
"\t TDCV := { NUMBER in tc}\n"
"\t TDCO := { NUMBER in tc}\n"
"\t TDCF := { NUMBER in tc}\n"
"\t RESTART-MS := { 0 | NUMBER in ms }\n"
"\t TQ := { NUMBER }\n"
"\t PROP-SEG := { 1..8 }\n"
"\t PHASE-SEG1 := { 1..8 }\n"
"\t PHASE-SEG2 := { 1..8 }\n"
"\t SJW := { 1..4 }\n"
"\t RESTART-MS := { 0 | NUMBER }\n"
);
}
@ -93,47 +88,34 @@ static void set_ctrlmode(char *name, char *arg,
cm->mask |= flags;
}
static void print_flag(enum output_type t, __u32 *flags, __u32 flag,
const char* name)
static void print_ctrlmode(FILE *f, __u32 cm)
{
if (*flags & flag) {
*flags &= ~flag;
print_string(t, NULL, *flags ? "%s," : "%s", name);
open_json_array(PRINT_ANY, is_json_context() ? "ctrlmode" : "<");
#define _PF(cmflag, cmname) \
if (cm & cmflag) { \
cm &= ~cmflag; \
print_string(PRINT_ANY, NULL, cm ? "%s," : "%s", cmname); \
}
}
static void print_ctrlmode(enum output_type t, __u32 flags, const char* key)
{
if (!flags)
return;
open_json_array(t, is_json_context() ? key : "<");
print_flag(t, &flags, CAN_CTRLMODE_LOOPBACK, "LOOPBACK");
print_flag(t, &flags, CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY");
print_flag(t, &flags, CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING");
print_flag(t, &flags, CAN_CTRLMODE_ONE_SHOT, "ONE-SHOT");
print_flag(t, &flags, CAN_CTRLMODE_BERR_REPORTING, "BERR-REPORTING");
print_flag(t, &flags, CAN_CTRLMODE_FD, "FD");
print_flag(t, &flags, CAN_CTRLMODE_FD_NON_ISO, "FD-NON-ISO");
print_flag(t, &flags, CAN_CTRLMODE_PRESUME_ACK, "PRESUME-ACK");
print_flag(t, &flags, CAN_CTRLMODE_CC_LEN8_DLC, "CC-LEN8-DLC");
print_flag(t, &flags, CAN_CTRLMODE_TDC_AUTO, "TDC-AUTO");
print_flag(t, &flags, CAN_CTRLMODE_TDC_MANUAL, "TDC-MANUAL");
if (flags)
print_hex(t, NULL, "%x", flags);
close_json_array(t, "> ");
_PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK");
_PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY");
_PF(CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING");
_PF(CAN_CTRLMODE_ONE_SHOT, "ONE-SHOT");
_PF(CAN_CTRLMODE_BERR_REPORTING, "BERR-REPORTING");
_PF(CAN_CTRLMODE_FD, "FD");
_PF(CAN_CTRLMODE_FD_NON_ISO, "FD-NON-ISO");
_PF(CAN_CTRLMODE_PRESUME_ACK, "PRESUME-ACK");
_PF(CAN_CTRLMODE_CC_LEN8_DLC, "CC-LEN8-DLC");
#undef _PF
if (cm)
print_hex(PRINT_ANY, NULL, "%x", cm);
close_json_array(PRINT_ANY, "> ");
}
static int can_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
struct can_bittiming bt = {}, dbt = {};
struct can_ctrlmode cm = { 0 };
struct rtattr *tdc;
__u32 tdcv = -1, tdco = -1, tdcf = -1;
struct can_ctrlmode cm = {0, 0};
while (argc > 0) {
if (matches(*argv, "bitrate") == 0) {
@ -199,18 +181,6 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG();
if (get_u32(&dbt.sjw, *argv, 0))
invarg("invalid \"dsjw\" value\n", *argv);
} else if (matches(*argv, "tdcv") == 0) {
NEXT_ARG();
if (get_u32(&tdcv, *argv, 0))
invarg("invalid \"tdcv\" value\n", *argv);
} else if (matches(*argv, "tdco") == 0) {
NEXT_ARG();
if (get_u32(&tdco, *argv, 0))
invarg("invalid \"tdco\" value\n", *argv);
} else if (matches(*argv, "tdcf") == 0) {
NEXT_ARG();
if (get_u32(&tdcf, *argv, 0))
invarg("invalid \"tdcf\" value\n", *argv);
} else if (matches(*argv, "loopback") == 0) {
NEXT_ARG();
set_ctrlmode("loopback", *argv, &cm,
@ -247,23 +217,6 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG();
set_ctrlmode("cc-len8-dlc", *argv, &cm,
CAN_CTRLMODE_CC_LEN8_DLC);
} else if (matches(*argv, "tdc-mode") == 0) {
NEXT_ARG();
if (strcmp(*argv, "auto") == 0) {
cm.flags |= CAN_CTRLMODE_TDC_AUTO;
cm.mask |= CAN_CTRLMODE_TDC_AUTO;
} else if (strcmp(*argv, "manual") == 0) {
cm.flags |= CAN_CTRLMODE_TDC_MANUAL;
cm.mask |= CAN_CTRLMODE_TDC_MANUAL;
} else if (strcmp(*argv, "off") == 0) {
cm.mask |= CAN_CTRLMODE_TDC_AUTO |
CAN_CTRLMODE_TDC_MANUAL;
} else {
fprintf(stderr,
"Error: argument of \"tdc-mode\" must be \"auto\", \"manual\" or \"off\", not \"%s\"\n",
*argv);
exit (-1);
}
} else if (matches(*argv, "restart") == 0) {
__u32 val = 1;
@ -301,17 +254,6 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
if (cm.mask)
addattr_l(n, 1024, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
if (tdcv != -1 || tdco != -1 || tdcf != -1) {
tdc = addattr_nest(n, 1024, IFLA_CAN_TDC | NLA_F_NESTED);
if (tdcv != -1)
addattr32(n, 1024, IFLA_CAN_TDC_TDCV, tdcv);
if (tdco != -1)
addattr32(n, 1024, IFLA_CAN_TDC_TDCO, tdco);
if (tdcf != -1)
addattr32(n, 1024, IFLA_CAN_TDC_TDCF, tdcf);
addattr_nest_end(n, tdc);
}
return 0;
}
@ -324,75 +266,11 @@ static const char *can_state_names[CAN_STATE_MAX] = {
[CAN_STATE_SLEEPING] = "SLEEPING"
};
static void can_print_nl_indent(void)
static void can_print_json_timing_min_max(const char *attr, int min, int max)
{
print_nl();
print_string(PRINT_FP, NULL, "%s", "\t ");
}
static void can_print_timing_min_max(const char *json_attr, const char *fp_attr,
int min, int max)
{
print_null(PRINT_FP, NULL, fp_attr, NULL);
open_json_object(json_attr);
print_uint(PRINT_ANY, "min", " %d", min);
print_uint(PRINT_ANY, "max", "..%d", max);
close_json_object();
}
static void can_print_tdc_opt(FILE *f, struct rtattr *tdc_attr)
{
struct rtattr *tb[IFLA_CAN_TDC_MAX + 1];
parse_rtattr_nested(tb, IFLA_CAN_TDC_MAX, tdc_attr);
if (tb[IFLA_CAN_TDC_TDCV] || tb[IFLA_CAN_TDC_TDCO] ||
tb[IFLA_CAN_TDC_TDCF]) {
open_json_object("tdc");
can_print_nl_indent();
if (tb[IFLA_CAN_TDC_TDCV]) {
__u32 *tdcv = RTA_DATA(tb[IFLA_CAN_TDC_TDCV]);
print_uint(PRINT_ANY, "tdcv", " tdcv %u", *tdcv);
}
if (tb[IFLA_CAN_TDC_TDCO]) {
__u32 *tdco = RTA_DATA(tb[IFLA_CAN_TDC_TDCO]);
print_uint(PRINT_ANY, "tdco", " tdco %u", *tdco);
}
if (tb[IFLA_CAN_TDC_TDCF]) {
__u32 *tdcf = RTA_DATA(tb[IFLA_CAN_TDC_TDCF]);
print_uint(PRINT_ANY, "tdcf", " tdcf %u", *tdcf);
}
close_json_object();
}
}
static void can_print_tdc_const_opt(FILE *f, struct rtattr *tdc_attr)
{
struct rtattr *tb[IFLA_CAN_TDC_MAX + 1];
parse_rtattr_nested(tb, IFLA_CAN_TDC_MAX, tdc_attr);
open_json_object("tdc");
can_print_nl_indent();
if (tb[IFLA_CAN_TDC_TDCV_MIN] && tb[IFLA_CAN_TDC_TDCV_MAX]) {
__u32 *tdcv_min = RTA_DATA(tb[IFLA_CAN_TDC_TDCV_MIN]);
__u32 *tdcv_max = RTA_DATA(tb[IFLA_CAN_TDC_TDCV_MAX]);
can_print_timing_min_max("tdcv", " tdcv", *tdcv_min, *tdcv_max);
}
if (tb[IFLA_CAN_TDC_TDCO_MIN] && tb[IFLA_CAN_TDC_TDCO_MAX]) {
__u32 *tdco_min = RTA_DATA(tb[IFLA_CAN_TDC_TDCO_MIN]);
__u32 *tdco_max = RTA_DATA(tb[IFLA_CAN_TDC_TDCO_MAX]);
can_print_timing_min_max("tdco", " tdco", *tdco_min, *tdco_max);
}
if (tb[IFLA_CAN_TDC_TDCF_MIN] && tb[IFLA_CAN_TDC_TDCF_MAX]) {
__u32 *tdcf_min = RTA_DATA(tb[IFLA_CAN_TDC_TDCF_MIN]);
__u32 *tdcf_max = RTA_DATA(tb[IFLA_CAN_TDC_TDCF_MAX]);
can_print_timing_min_max("tdcf", " tdcf", *tdcf_min, *tdcf_max);
}
open_json_object(attr);
print_int(PRINT_JSON, "min", NULL, min);
print_int(PRINT_JSON, "max", NULL, max);
close_json_object();
}
@ -404,7 +282,8 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_CAN_CTRLMODE]) {
struct can_ctrlmode *cm = RTA_DATA(tb[IFLA_CAN_CTRLMODE]);
print_ctrlmode(PRINT_ANY, cm->flags, "ctrlmode");
if (cm->flags)
print_ctrlmode(f, cm->flags);
}
if (tb[IFLA_CAN_STATE]) {
@ -418,39 +297,56 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
struct can_berr_counter *bc =
RTA_DATA(tb[IFLA_CAN_BERR_COUNTER]);
open_json_object("berr_counter");
print_uint(PRINT_ANY, "tx", "(berr-counter tx %u", bc->txerr);
print_uint(PRINT_ANY, "rx", " rx %u) ", bc->rxerr);
close_json_object();
if (is_json_context()) {
open_json_object("berr_counter");
print_int(PRINT_JSON, "tx", NULL, bc->txerr);
print_int(PRINT_JSON, "rx", NULL, bc->rxerr);
close_json_object();
} else {
fprintf(f, "(berr-counter tx %d rx %d) ",
bc->txerr, bc->rxerr);
}
}
if (tb[IFLA_CAN_RESTART_MS]) {
__u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]);
print_uint(PRINT_ANY, "restart_ms", "restart-ms %u ",
*restart_ms);
print_int(PRINT_ANY,
"restart_ms",
"restart-ms %d ",
*restart_ms);
}
/* bittiming is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_BITTIMING] && !tb[IFLA_CAN_BITRATE_CONST]) {
struct can_bittiming *bt = RTA_DATA(tb[IFLA_CAN_BITTIMING]);
char sp[6];
open_json_object("bittiming");
can_print_nl_indent();
print_uint(PRINT_ANY, "bitrate", " bitrate %u", bt->bitrate);
snprintf(sp, sizeof(sp), "%.3f", bt->sample_point / 1000.);
print_string(PRINT_ANY, "sample_point", " sample-point %s", sp);
can_print_nl_indent();
print_uint(PRINT_ANY, "tq", " tq %u", bt->tq);
print_uint(PRINT_ANY, "prop_seg", " prop-seg %u", bt->prop_seg);
print_uint(PRINT_ANY, "phase_seg1", " phase-seg1 %u",
bt->phase_seg1);
print_uint(PRINT_ANY, "phase_seg2", " phase-seg2 %u",
bt->phase_seg2);
print_uint(PRINT_ANY, "sjw", " sjw %u", bt->sjw);
print_uint(PRINT_ANY, "brp", " brp %u", bt->brp);
close_json_object();
if (is_json_context()) {
json_writer_t *jw;
open_json_object("bittiming");
print_int(PRINT_ANY, "bitrate", NULL, bt->bitrate);
jw = get_json_writer();
jsonw_name(jw, "sample_point");
jsonw_printf(jw, "%.3f",
(float) bt->sample_point / 1000);
print_int(PRINT_ANY, "tq", NULL, bt->tq);
print_int(PRINT_ANY, "prop_seg", NULL, bt->prop_seg);
print_int(PRINT_ANY, "phase_seg1",
NULL, bt->phase_seg1);
print_int(PRINT_ANY, "phase_seg2",
NULL, bt->phase_seg2);
print_int(PRINT_ANY, "sjw", NULL, bt->sjw);
close_json_object();
} else {
fprintf(f, "\n bitrate %d sample-point %.3f ",
bt->bitrate, (float) bt->sample_point / 1000.);
fprintf(f,
"\n tq %d prop-seg %d phase-seg1 %d phase-seg2 %d sjw %d",
bt->tq, bt->prop_seg,
bt->phase_seg1, bt->phase_seg2,
bt->sjw);
}
}
/* bittiming const is irrelevant if fixed bitrate is defined */
@ -458,18 +354,28 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
struct can_bittiming_const *btc =
RTA_DATA(tb[IFLA_CAN_BITTIMING_CONST]);
open_json_object("bittiming_const");
can_print_nl_indent();
print_string(PRINT_ANY, "name", " %s:", btc->name);
can_print_timing_min_max("tseg1", " tseg1",
btc->tseg1_min, btc->tseg1_max);
can_print_timing_min_max("tseg2", " tseg2",
btc->tseg2_min, btc->tseg2_max);
can_print_timing_min_max("sjw", " sjw", 1, btc->sjw_max);
can_print_timing_min_max("brp", " brp",
btc->brp_min, btc->brp_max);
print_uint(PRINT_ANY, "brp_inc", " brp_inc %u", btc->brp_inc);
close_json_object();
if (is_json_context()) {
open_json_object("bittiming_const");
print_string(PRINT_JSON, "name", NULL, btc->name);
can_print_json_timing_min_max("tseg1",
btc->tseg1_min,
btc->tseg1_max);
can_print_json_timing_min_max("tseg2",
btc->tseg2_min,
btc->tseg2_max);
can_print_json_timing_min_max("sjw", 1, btc->sjw_max);
can_print_json_timing_min_max("brp",
btc->brp_min,
btc->brp_max);
print_int(PRINT_JSON, "brp_inc", NULL, btc->brp_inc);
close_json_object();
} else {
fprintf(f, "\n %s: tseg1 %d..%d tseg2 %d..%d "
"sjw 1..%d brp %d..%d brp-inc %d",
btc->name, btc->tseg1_min, btc->tseg1_max,
btc->tseg2_min, btc->tseg2_max, btc->sjw_max,
btc->brp_min, btc->brp_max, btc->brp_inc);
}
}
if (tb[IFLA_CAN_BITRATE_CONST]) {
@ -485,52 +391,64 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
bitrate = bt->bitrate;
}
can_print_nl_indent();
print_uint(PRINT_ANY, "bittiming_bitrate", " bitrate %u",
bitrate);
can_print_nl_indent();
open_json_array(PRINT_ANY, is_json_context() ?
"bitrate_const" : " [");
for (i = 0; i < bitrate_cnt; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i) {
can_print_nl_indent();
print_string(PRINT_FP, NULL, "%s", " ");
if (is_json_context()) {
print_uint(PRINT_JSON,
"bittiming_bitrate",
NULL, bitrate);
open_json_array(PRINT_JSON, "bitrate_const");
for (i = 0; i < bitrate_cnt; ++i)
print_uint(PRINT_JSON, NULL, NULL,
bitrate_const[i]);
close_json_array(PRINT_JSON, NULL);
} else {
fprintf(f, "\n bitrate %u", bitrate);
fprintf(f, "\n [");
for (i = 0; i < bitrate_cnt - 1; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u, ", bitrate_const[i]);
}
print_uint(PRINT_ANY, NULL,
i < bitrate_cnt - 1 ? "%8u, " : "%8u",
bitrate_const[i]);
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u ]", bitrate_const[i]);
}
close_json_array(PRINT_JSON, " ]");
}
/* data bittiming is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_DATA_BITTIMING] && !tb[IFLA_CAN_DATA_BITRATE_CONST]) {
struct can_bittiming *dbt =
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]);
char dsp[6];
open_json_object("data_bittiming");
can_print_nl_indent();
print_uint(PRINT_ANY, "bitrate", " dbitrate %u", dbt->bitrate);
snprintf(dsp, sizeof(dsp), "%.3f", dbt->sample_point / 1000.);
print_string(PRINT_ANY, "sample_point", " dsample-point %s",
dsp);
can_print_nl_indent();
print_uint(PRINT_ANY, "tq", " dtq %u", dbt->tq);
print_uint(PRINT_ANY, "prop_seg", " dprop-seg %u",
dbt->prop_seg);
print_uint(PRINT_ANY, "phase_seg1", " dphase-seg1 %u",
dbt->phase_seg1);
print_uint(PRINT_ANY, "phase_seg2", " dphase-seg2 %u",
dbt->phase_seg2);
print_uint(PRINT_ANY, "sjw", " dsjw %u", dbt->sjw);
print_uint(PRINT_ANY, "brp", " dbrp %u", dbt->brp);
if (is_json_context()) {
json_writer_t *jw;
if (tb[IFLA_CAN_TDC])
can_print_tdc_opt(f, tb[IFLA_CAN_TDC]);
close_json_object();
open_json_object("data_bittiming");
print_int(PRINT_JSON, "bitrate", NULL, dbt->bitrate);
jw = get_json_writer();
jsonw_name(jw, "sample_point");
jsonw_printf(jw, "%.3f",
(float) dbt->sample_point / 1000.);
print_int(PRINT_JSON, "tq", NULL, dbt->tq);
print_int(PRINT_JSON, "prop_seg", NULL, dbt->prop_seg);
print_int(PRINT_JSON, "phase_seg1",
NULL, dbt->phase_seg1);
print_int(PRINT_JSON, "phase_seg2",
NULL, dbt->phase_seg2);
print_int(PRINT_JSON, "sjw", NULL, dbt->sjw);
close_json_object();
} else {
fprintf(f, "\n dbitrate %d dsample-point %.3f ",
dbt->bitrate,
(float) dbt->sample_point / 1000.);
fprintf(f, "\n dtq %d dprop-seg %d dphase-seg1 %d "
"dphase-seg2 %d dsjw %d",
dbt->tq, dbt->prop_seg, dbt->phase_seg1,
dbt->phase_seg2, dbt->sjw);
}
}
/* data bittiming const is irrelevant if fixed bitrate is defined */
@ -539,22 +457,29 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
struct can_bittiming_const *dbtc =
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING_CONST]);
open_json_object("data_bittiming_const");
can_print_nl_indent();
print_string(PRINT_ANY, "name", " %s:", dbtc->name);
can_print_timing_min_max("tseg1", " dtseg1",
dbtc->tseg1_min, dbtc->tseg1_max);
can_print_timing_min_max("tseg2", " dtseg2",
dbtc->tseg2_min, dbtc->tseg2_max);
can_print_timing_min_max("sjw", " dsjw", 1, dbtc->sjw_max);
can_print_timing_min_max("brp", " dbrp",
dbtc->brp_min, dbtc->brp_max);
print_uint(PRINT_ANY, "brp_inc", " dbrp_inc %u", dbtc->brp_inc);
if (is_json_context()) {
open_json_object("data_bittiming_const");
print_string(PRINT_JSON, "name", NULL, dbtc->name);
can_print_json_timing_min_max("tseg1",
dbtc->tseg1_min,
dbtc->tseg1_max);
can_print_json_timing_min_max("tseg2",
dbtc->tseg2_min,
dbtc->tseg2_max);
can_print_json_timing_min_max("sjw", 1, dbtc->sjw_max);
can_print_json_timing_min_max("brp",
dbtc->brp_min,
dbtc->brp_max);
if (tb[IFLA_CAN_TDC])
can_print_tdc_const_opt(f, tb[IFLA_CAN_TDC]);
close_json_object();
print_int(PRINT_JSON, "brp_inc", NULL, dbtc->brp_inc);
close_json_object();
} else {
fprintf(f, "\n %s: dtseg1 %d..%d dtseg2 %d..%d "
"dsjw 1..%d dbrp %d..%d dbrp-inc %d",
dbtc->name, dbtc->tseg1_min, dbtc->tseg1_max,
dbtc->tseg2_min, dbtc->tseg2_max, dbtc->sjw_max,
dbtc->brp_min, dbtc->brp_max, dbtc->brp_inc);
}
}
if (tb[IFLA_CAN_DATA_BITRATE_CONST]) {
@ -572,23 +497,30 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
dbitrate = dbt->bitrate;
}
can_print_nl_indent();
print_uint(PRINT_ANY, "data_bittiming_bitrate", " dbitrate %u",
dbitrate);
can_print_nl_indent();
open_json_array(PRINT_ANY, is_json_context() ?
"data_bitrate_const" : " [");
for (i = 0; i < dbitrate_cnt; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i) {
can_print_nl_indent();
print_string(PRINT_FP, NULL, "%s", " ");
if (is_json_context()) {
print_uint(PRINT_JSON, "data_bittiming_bitrate",
NULL, dbitrate);
open_json_array(PRINT_JSON, "data_bitrate_const");
for (i = 0; i < dbitrate_cnt; ++i)
print_uint(PRINT_JSON, NULL, NULL,
dbitrate_const[i]);
close_json_array(PRINT_JSON, NULL);
} else {
fprintf(f, "\n dbitrate %u", dbitrate);
fprintf(f, "\n [");
for (i = 0; i < dbitrate_cnt - 1; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u, ", dbitrate_const[i]);
}
print_uint(PRINT_ANY, NULL,
i < dbitrate_cnt - 1 ? "%8u, " : "%8u",
dbitrate_const[i]);
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u ]", dbitrate_const[i]);
}
close_json_array(PRINT_JSON, " ]");
}
if (tb[IFLA_CAN_TERMINATION_CONST] && tb[IFLA_CAN_TERMINATION]) {
@ -598,21 +530,29 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
sizeof(*trm_const);
int i;
can_print_nl_indent();
print_hu(PRINT_ANY, "termination", " termination %hu [ ", *trm);
open_json_array(PRINT_JSON, "termination_const");
for (i = 0; i < trm_cnt; ++i)
print_hu(PRINT_ANY, NULL,
i < trm_cnt - 1 ? "%hu, " : "%hu",
trm_const[i]);
close_json_array(PRINT_JSON, " ]");
if (is_json_context()) {
print_hu(PRINT_JSON, "termination", NULL, *trm);
open_json_array(PRINT_JSON, "termination_const");
for (i = 0; i < trm_cnt; ++i)
print_hu(PRINT_JSON, NULL, NULL, trm_const[i]);
close_json_array(PRINT_JSON, NULL);
} else {
fprintf(f, "\n termination %hu [ ", *trm);
for (i = 0; i < trm_cnt - 1; ++i)
fprintf(f, "%hu, ", trm_const[i]);
fprintf(f, "%hu ]", trm_const[i]);
}
}
if (tb[IFLA_CAN_CLOCK]) {
struct can_clock *clock = RTA_DATA(tb[IFLA_CAN_CLOCK]);
can_print_nl_indent();
print_uint(PRINT_ANY, "clock", " clock %u ", clock->freq);
print_int(PRINT_ANY,
"clock",
"\n clock %d ",
clock->freq);
}
}
@ -625,23 +565,31 @@ static void can_print_xstats(struct link_util *lu,
if (xstats && RTA_PAYLOAD(xstats) == sizeof(*stats)) {
stats = RTA_DATA(xstats);
can_print_nl_indent();
print_string(PRINT_FP, NULL, "%s",
" re-started bus-errors arbit-lost error-warn error-pass bus-off");
can_print_nl_indent();
print_uint(PRINT_ANY, "restarts", " %-10u", stats->restarts);
print_uint(PRINT_ANY, "bus_error", " %-10u", stats->bus_error);
print_uint(PRINT_ANY, "arbitration_lost", " %-10u",
stats->arbitration_lost);
print_uint(PRINT_ANY, "error_warning", " %-10u",
stats->error_warning);
print_uint(PRINT_ANY, "error_passive", " %-10u",
stats->error_passive);
print_uint(PRINT_ANY, "bus_off", " %-10u", stats->bus_off);
if (is_json_context()) {
print_int(PRINT_JSON, "restarts",
NULL, stats->restarts);
print_int(PRINT_JSON, "bus_error",
NULL, stats->bus_error);
print_int(PRINT_JSON, "arbitration_lost",
NULL, stats->arbitration_lost);
print_int(PRINT_JSON, "error_warning",
NULL, stats->error_warning);
print_int(PRINT_JSON, "error_passive",
NULL, stats->error_passive);
print_int(PRINT_JSON, "bus_off", NULL, stats->bus_off);
} else {
fprintf(f, "\n re-started bus-errors arbit-lost "
"error-warn error-pass bus-off");
fprintf(f, "\n %-10d %-10d %-10d %-10d %-10d %-10d",
stats->restarts, stats->bus_error,
stats->arbitration_lost, stats->error_warning,
stats->error_passive, stats->bus_off);
}
}
}
static void can_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
static void can_print_help(struct link_util *lu, int argc, char **argv,
FILE *f)
{
print_usage(f);
}

View File

@ -243,6 +243,7 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
static void geneve_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
__u32 vni;
__u8 ttl = 0;
__u8 tos = 0;
@ -251,12 +252,15 @@ static void geneve_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_GENEVE_COLLECT_METADATA]) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
if (tb[IFLA_GENEVE_ID] &&
RTA_PAYLOAD(tb[IFLA_GENEVE_ID]) >= sizeof(__u32)) {
print_uint(PRINT_ANY, "id", "id %u ", rta_getattr_u32(tb[IFLA_GENEVE_ID]));
}
if (!tb[IFLA_GENEVE_ID] ||
RTA_PAYLOAD(tb[IFLA_GENEVE_ID]) < sizeof(__u32))
return;
vni = rta_getattr_u32(tb[IFLA_GENEVE_ID]);
print_uint(PRINT_ANY, "id", "id %u ", vni);
if (tb[IFLA_GENEVE_REMOTE]) {
__be32 addr = rta_getattr_u32(tb[IFLA_GENEVE_REMOTE]);

View File

@ -33,7 +33,7 @@ static void print_explain(struct link_util *lu, FILE *f)
"Usage: ... %s mode MODE [flag MODE_FLAG] MODE_OPTS [bcqueuelen BC_QUEUE_LEN]\n"
"\n"
"MODE: private | vepa | bridge | passthru | source\n"
"MODE_FLAG: null | nopromisc | nodst\n"
"MODE_FLAG: null | nopromisc\n"
"MODE_OPTS: for mode \"source\":\n"
"\tmacaddr { { add | del } <macaddr> | set [ <macaddr> [ <macaddr> ... ] ] | flush }\n"
"BC_QUEUE_LEN: Length of the rx queue for broadcast/multicast: [0-4294967295]\n",
@ -58,7 +58,7 @@ static int mode_arg(const char *arg)
static int flag_arg(const char *arg)
{
fprintf(stderr,
"Error: argument of \"flag\" must be \"nopromisc\", \"nodst\" or \"null\", not \"%s\"\n",
"Error: argument of \"flag\" must be \"nopromisc\" or \"null\", not \"%s\"\n",
arg);
return -1;
}
@ -102,8 +102,6 @@ static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
if (strcmp(*argv, "nopromisc") == 0)
flags |= MACVLAN_FLAG_NOPROMISC;
else if (strcmp(*argv, "nodst") == 0)
flags |= MACVLAN_FLAG_NODST;
else if (strcmp(*argv, "null") == 0)
flags |= 0;
else
@ -161,9 +159,6 @@ static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
} else if (matches(*argv, "nopromisc") == 0) {
flags |= MACVLAN_FLAG_NOPROMISC;
has_flags = 1;
} else if (matches(*argv, "nodst") == 0) {
flags |= MACVLAN_FLAG_NODST;
has_flags = 1;
} else if (matches(*argv, "bcqueuelen") == 0) {
__u32 bc_queue_len;
NEXT_ARG();
@ -234,9 +229,6 @@ static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]
if (flags & MACVLAN_FLAG_NOPROMISC)
print_bool(PRINT_ANY, "nopromisc", "nopromisc ", true);
if (flags & MACVLAN_FLAG_NODST)
print_bool(PRINT_ANY, "nodst", "nodst ", true);
if (tb[IFLA_MACVLAN_BC_QUEUE_LEN] &&
RTA_PAYLOAD(tb[IFLA_MACVLAN_BC_QUEUE_LEN]) >= sizeof(__u32)) {
__u32 bc_queue_len = rta_getattr_u32(tb[IFLA_MACVLAN_BC_QUEUE_LEN]);

View File

@ -408,6 +408,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
__u32 vni;
__u8 ttl = 0;
__u8 tos = 0;
__u32 maxaddr;
@ -418,12 +419,15 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_VXLAN_COLLECT_METADATA] &&
rta_getattr_u8(tb[IFLA_VXLAN_COLLECT_METADATA])) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
if (tb[IFLA_VXLAN_ID] &&
RTA_PAYLOAD(tb[IFLA_VXLAN_ID]) >= sizeof(__u32)) {
print_uint(PRINT_ANY, "id", "id %u ", rta_getattr_u32(tb[IFLA_VXLAN_ID]));
}
if (!tb[IFLA_VXLAN_ID] ||
RTA_PAYLOAD(tb[IFLA_VXLAN_ID]) < sizeof(__u32))
return;
vni = rta_getattr_u32(tb[IFLA_VXLAN_ID]);
print_uint(PRINT_ANY, "id", "id %u ", vni);
if (tb[IFLA_VXLAN_GROUP]) {
__be32 addr = rta_getattr_u32(tb[IFLA_VXLAN_GROUP]);

View File

@ -1,72 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <stdio.h>
#include <linux/netlink.h>
#include <linux/wwan.h>
#include "utils.h"
#include "ip_common.h"
static void print_explain(FILE *f)
{
fprintf(f,
"Usage: ... wwan linkid LINKID\n"
"\n"
"Where: LINKID := 0-4294967295\n"
);
}
static void explain(void)
{
print_explain(stderr);
}
static int wwan_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
while (argc > 0) {
if (matches(*argv, "linkid") == 0) {
__u32 linkid;
NEXT_ARG();
if (get_u32(&linkid, *argv, 0))
invarg("linkid", *argv);
addattr32(n, 1024, IFLA_WWAN_LINK_ID, linkid);
} else if (matches(*argv, "help") == 0) {
explain();
return -1;
} else {
fprintf(stderr, "wwan: unknown command \"%s\"?\n",
*argv);
explain();
return -1;
}
argc--, argv++;
}
return 0;
}
static void wwan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
if (!tb)
return;
if (tb[IFLA_WWAN_LINK_ID])
print_uint(PRINT_ANY, "linkid", "linkid %u ",
rta_getattr_u32(tb[IFLA_WWAN_LINK_ID]));
}
static void wwan_print_help(struct link_util *lu, int argc, char **argv,
FILE *f)
{
print_explain(f);
}
struct link_util wwan_link_util = {
.id = "wwan",
.maxattr = IFLA_WWAN_MAX,
.parse_opt = wwan_parse_opt,
.print_opt = wwan_print_opt,
.print_help = wwan_print_help,
};

View File

@ -22,7 +22,6 @@
#include "utils.h"
#include "ip_common.h"
#include "nh_common.h"
static void usage(void) __attribute__((noreturn));
static int prefix_banner;
@ -89,7 +88,7 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl,
case RTM_NEWNEXTHOP:
case RTM_DELNEXTHOP:
print_headers(fp, "[NEXTHOP]", ctrl);
print_cache_nexthop(n, arg, true);
print_nexthop(n, arg);
return 0;
case RTM_NEWNEXTHOPBUCKET:

View File

@ -1,23 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rt_names.h>
#include <errno.h>
#include <linux/genetlink.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/mptcp.h>
#include "utils.h"
#include "ip_common.h"
#include "json_print.h"
#include "libgenl.h"
#include "libnetlink.h"
#include "ll_map.h"
#include "json_print.h"
static void usage(void)
{
@ -149,9 +143,6 @@ static int mptcp_parse_opt(int argc, char **argv, struct nlmsghdr *n,
if (!id_set && !adding)
missarg("ID");
if (port && !(flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
invarg("flags must have signal when using port", "port");
attr_addr = addattr_nest(n, MPTCP_BUFLEN,
MPTCP_PM_ATTR_ADDR | NLA_F_NESTED);
if (id_set)
@ -284,7 +275,7 @@ static int mptcp_addr_dump(void)
return -2;
}
delete_json_obj();
close_json_object();
fflush(stdout);
return 0;
}
@ -305,11 +296,7 @@ static int mptcp_addr_show(int argc, char **argv)
if (rtnl_talk(&genl_rth, &req.n, &answer) < 0)
return -2;
new_json_obj(json);
ret = print_mptcp_addr(answer, stdout);
delete_json_obj();
fflush(stdout);
return ret;
return print_mptcp_addr(answer, stdout);
}
static int mptcp_addr_flush(int argc, char **argv)

View File

@ -37,8 +37,8 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip mroute show [ [ to ] PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n"
" [ table TABLE_ID ]\n"
"TABLE_ID := [ local | main | default | all | NUMBER ]\n"
" [ table TABLE_ID ]\n"
"TABLE_ID := [ local | main | default | all | NUMBER ]\n"
#if 0
"Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n"
#endif

View File

@ -50,12 +50,11 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip neigh { add | del | change | replace }\n"
" { ADDR [ lladdr LLADDR ] [ nud STATE ] proxy ADDR }\n"
" [ dev DEV ] [ router ] [ use ] [ managed ] [ extern_learn ]\n"
" [ protocol PROTO ]\n"
" { ADDR [ lladdr LLADDR ] [ nud STATE ] proxy ADDR }\n"
" [ dev DEV ] [ router ] [ extern_learn ] [ protocol PROTO ]\n"
"\n"
" ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n"
" [ vrf NAME ] [ nomaster ]\n"
" [ vrf NAME ]\n"
" ip neigh get { ADDR | proxy ADDR } dev DEV\n"
"\n"
"STATE := { delay | failed | incomplete | noarp | none |\n"
@ -116,7 +115,6 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
.ndm.ndm_family = preferred_family,
.ndm.ndm_state = NUD_PERMANENT,
};
__u32 ext_flags = 0;
char *dev = NULL;
int dst_ok = 0;
int dev_ok = 0;
@ -150,11 +148,6 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
req.ndm.ndm_flags |= NTF_PROXY;
} else if (strcmp(*argv, "router") == 0) {
req.ndm.ndm_flags |= NTF_ROUTER;
} else if (strcmp(*argv, "use") == 0) {
req.ndm.ndm_flags |= NTF_USE;
} else if (strcmp(*argv, "managed") == 0) {
ext_flags |= NTF_EXT_MANAGED;
req.ndm.ndm_state = NUD_NONE;
} else if (matches(*argv, "extern_learn") == 0) {
req.ndm.ndm_flags |= NTF_EXT_LEARNED;
} else if (strcmp(*argv, "dev") == 0) {
@ -190,10 +183,7 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
req.ndm.ndm_family = dst.family;
if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0)
return -1;
if (ext_flags &&
addattr_l(&req.n, sizeof(req), NDA_FLAGS_EXT, &ext_flags,
sizeof(ext_flags)) < 0)
return -1;
if (lla && strcmp(lla, "null")) {
char llabuf[20];
int l;
@ -245,7 +235,7 @@ static void print_neigh_state(unsigned int nud)
#define PRINT_FLAG(f) \
if (nud & NUD_##f) { \
nud &= ~NUD_##f; \
print_string(PRINT_ANY, NULL, "%s ", #f); \
print_string(PRINT_ANY, NULL, " %s", #f); \
}
PRINT_FLAG(INCOMPLETE);
@ -261,51 +251,6 @@ static void print_neigh_state(unsigned int nud)
close_json_array(PRINT_JSON, NULL);
}
static int print_neigh_brief(FILE *fp, struct ndmsg *r, struct rtattr *tb[])
{
if (tb[NDA_DST]) {
const char *dst;
int family = r->ndm_family;
if (family == AF_BRIDGE) {
if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr))
family = AF_INET6;
else
family = AF_INET;
}
dst = format_host_rta(family, tb[NDA_DST]);
print_color_string(PRINT_ANY, ifa_family_color(family),
"dst", "%-39s ", dst);
}
if (!filter.index && r->ndm_ifindex) {
print_color_string(PRINT_ANY, COLOR_IFNAME,
"dev", "%-16s ",
ll_index_to_name(r->ndm_ifindex));
}
if (tb[NDA_LLADDR]) {
const char *lladdr;
SPRINT_BUF(b1);
lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
RTA_PAYLOAD(tb[NDA_LLADDR]),
ll_index_to_type(r->ndm_ifindex),
b1, sizeof(b1));
print_color_string(PRINT_ANY, COLOR_MAC,
"lladdr", "%s", lladdr);
}
print_string(PRINT_FP, NULL, "%s", "\n");
close_json_object();
fflush(fp);
return 0;
}
int print_neigh(struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE *)arg;
@ -313,7 +258,6 @@ int print_neigh(struct nlmsghdr *n, void *arg)
int len = n->nlmsg_len;
struct rtattr *tb[NDA_MAX+1];
static int logit = 1;
__u32 ext_flags = 0;
__u8 protocol = 0;
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH &&
@ -339,7 +283,8 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (!(filter.state&r->ndm_state) &&
!(r->ndm_flags & NTF_PROXY) &&
!(r->ndm_flags & NTF_EXT_LEARNED) &&
(r->ndm_state || !(filter.state&0x100)))
(r->ndm_state || !(filter.state&0x100)) &&
(r->ndm_family != AF_DECnet))
return 0;
if (filter.master && !(n->nlmsg_flags & NLM_F_DUMP_FILTERED)) {
@ -357,8 +302,6 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (tb[NDA_PROTOCOL])
protocol = rta_getattr_u8(tb[NDA_PROTOCOL]);
if (tb[NDA_FLAGS_EXT])
ext_flags = rta_getattr_u32(tb[NDA_FLAGS_EXT]);
if (filter.protocol && filter.protocol != protocol)
return 0;
@ -394,9 +337,6 @@ int print_neigh(struct nlmsghdr *n, void *arg)
else if (n->nlmsg_type == RTM_GETNEIGH)
print_null(PRINT_ANY, "miss", "%s ", "miss");
if (brief)
return print_neigh_brief(fp, r, tb);
if (tb[NDA_DST]) {
const char *dst;
int family = r->ndm_family;
@ -436,26 +376,27 @@ int print_neigh(struct nlmsghdr *n, void *arg)
fprintf(fp, "lladdr ");
print_color_string(PRINT_ANY, COLOR_MAC,
"lladdr", "%s ", lladdr);
"lladdr", "%s", lladdr);
}
if (r->ndm_flags & NTF_ROUTER)
print_null(PRINT_ANY, "router", "%s ", "router");
print_null(PRINT_ANY, "router", " %s", "router");
if (r->ndm_flags & NTF_PROXY)
print_null(PRINT_ANY, "proxy", "%s ", "proxy");
if (ext_flags & NTF_EXT_MANAGED)
print_null(PRINT_ANY, "managed", "%s ", "managed");
print_null(PRINT_ANY, "proxy", " %s", "proxy");
if (r->ndm_flags & NTF_EXT_LEARNED)
print_null(PRINT_ANY, "extern_learn", "%s ", "extern_learn");
print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn");
if (r->ndm_flags & NTF_OFFLOADED)
print_null(PRINT_ANY, "offload", "%s ", "offload");
print_null(PRINT_ANY, "offload", " %s", "offload");
if (show_stats) {
if (tb[NDA_CACHEINFO])
print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));
if (tb[NDA_PROBES])
print_uint(PRINT_ANY, "probes", "probes %u ",
print_uint(PRINT_ANY, "probes", " probes %u",
rta_getattr_u32(tb[NDA_PROBES]));
}
@ -465,13 +406,13 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (protocol) {
SPRINT_BUF(b1);
print_string(PRINT_ANY, "protocol", "proto %s ",
print_string(PRINT_ANY, "protocol", " proto %s ",
rtnl_rtprot_n2a(protocol, b1, sizeof(b1)));
}
print_string(PRINT_FP, NULL, "\n", "");
close_json_object();
fflush(fp);
fflush(stdout);
return 0;
}
@ -547,8 +488,6 @@ static int do_show_or_flush(int argc, char **argv, int flush)
if (!name_is_vrf(*argv))
invarg("Not a valid VRF name\n", *argv);
filter.master = ifindex;
} else if (strcmp(*argv, "nomaster") == 0) {
filter.master = -1;
} else if (strcmp(*argv, "unused") == 0) {
filter.unused_only = 1;
} else if (strcmp(*argv, "nud") == 0) {

View File

@ -6,7 +6,6 @@
*/
#include <linux/nexthop.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <rt_names.h>
@ -14,7 +13,6 @@
#include "utils.h"
#include "ip_common.h"
#include "nh_common.h"
static struct {
unsigned int flushed;
@ -35,9 +33,6 @@ enum {
#define RTM_NHA(h) ((struct rtattr *)(((char *)(h)) + \
NLMSG_ALIGN(sizeof(struct nhmsg))))
static struct hlist_head nh_cache[NH_CACHE_SIZE];
static struct rtnl_handle nh_cache_rth = { .fd = -1 };
static void usage(void) __attribute__((noreturn));
static void usage(void)
@ -217,29 +212,28 @@ out:
return rc;
}
static bool __valid_nh_group_attr(const struct rtattr *g_attr)
{
int num = RTA_PAYLOAD(g_attr) / sizeof(struct nexthop_grp);
return num && num * sizeof(struct nexthop_grp) == RTA_PAYLOAD(g_attr);
}
static void print_nh_group(const struct nh_entry *nhe)
static void print_nh_group(FILE *fp, const struct rtattr *grps_attr)
{
struct nexthop_grp *nhg = RTA_DATA(grps_attr);
int num = RTA_PAYLOAD(grps_attr) / sizeof(*nhg);
int i;
if (!num || num * sizeof(*nhg) != RTA_PAYLOAD(grps_attr)) {
fprintf(fp, "<invalid nexthop group>");
return;
}
open_json_array(PRINT_JSON, "group");
print_string(PRINT_FP, NULL, "%s", "group ");
for (i = 0; i < nhe->nh_groups_cnt; ++i) {
for (i = 0; i < num; ++i) {
open_json_object(NULL);
if (i)
print_string(PRINT_FP, NULL, "%s", "/");
print_uint(PRINT_ANY, "id", "%u", nhe->nh_groups[i].id);
if (nhe->nh_groups[i].weight)
print_uint(PRINT_ANY, "weight", ",%u",
nhe->nh_groups[i].weight + 1);
print_uint(PRINT_ANY, "id", "%u", nhg[i].id);
if (nhg[i].weight)
print_uint(PRINT_ANY, "weight", ",%u", nhg[i].weight + 1);
close_json_object();
}
@ -259,59 +253,50 @@ static const char *nh_group_type_name(__u16 type)
}
}
static void print_nh_group_type(__u16 nh_grp_type)
static void print_nh_group_type(FILE *fp, const struct rtattr *grp_type_attr)
{
if (nh_grp_type == NEXTHOP_GRP_TYPE_MPATH)
__u16 type = rta_getattr_u16(grp_type_attr);
if (type == NEXTHOP_GRP_TYPE_MPATH)
/* Do not print type in order not to break existing output. */
return;
print_string(PRINT_ANY, "type", "type %s ", nh_group_type_name(nh_grp_type));
print_string(PRINT_ANY, "type", "type %s ", nh_group_type_name(type));
}
static void parse_nh_res_group_rta(const struct rtattr *res_grp_attr,
struct nha_res_grp *res_grp)
static void print_nh_res_group(FILE *fp, const struct rtattr *res_grp_attr)
{
struct rtattr *tb[NHA_RES_GROUP_MAX + 1];
struct rtattr *rta;
struct timeval tv;
memset(res_grp, 0, sizeof(*res_grp));
parse_rtattr_nested(tb, NHA_RES_GROUP_MAX, res_grp_attr);
open_json_object("resilient_args");
if (tb[NHA_RES_GROUP_BUCKETS])
res_grp->buckets = rta_getattr_u16(tb[NHA_RES_GROUP_BUCKETS]);
print_uint(PRINT_ANY, "buckets", "buckets %u ",
rta_getattr_u16(tb[NHA_RES_GROUP_BUCKETS]));
if (tb[NHA_RES_GROUP_IDLE_TIMER]) {
rta = tb[NHA_RES_GROUP_IDLE_TIMER];
res_grp->idle_timer = rta_getattr_u32(rta);
__jiffies_to_tv(&tv, rta_getattr_u32(rta));
print_tv(PRINT_ANY, "idle_timer", "idle_timer %g ", &tv);
}
if (tb[NHA_RES_GROUP_UNBALANCED_TIMER]) {
rta = tb[NHA_RES_GROUP_UNBALANCED_TIMER];
res_grp->unbalanced_timer = rta_getattr_u32(rta);
__jiffies_to_tv(&tv, rta_getattr_u32(rta));
print_tv(PRINT_ANY, "unbalanced_timer", "unbalanced_timer %g ",
&tv);
}
if (tb[NHA_RES_GROUP_UNBALANCED_TIME]) {
rta = tb[NHA_RES_GROUP_UNBALANCED_TIME];
res_grp->unbalanced_time = rta_getattr_u64(rta);
__jiffies_to_tv(&tv, rta_getattr_u32(rta));
print_tv(PRINT_ANY, "unbalanced_time", "unbalanced_time %g ",
&tv);
}
}
static void print_nh_res_group(const struct nha_res_grp *res_grp)
{
struct timeval tv;
open_json_object("resilient_args");
print_uint(PRINT_ANY, "buckets", "buckets %u ", res_grp->buckets);
__jiffies_to_tv(&tv, res_grp->idle_timer);
print_tv(PRINT_ANY, "idle_timer", "idle_timer %g ", &tv);
__jiffies_to_tv(&tv, res_grp->unbalanced_timer);
print_tv(PRINT_ANY, "unbalanced_timer", "unbalanced_timer %g ", &tv);
__jiffies_to_tv(&tv, res_grp->unbalanced_time);
print_tv(PRINT_ANY, "unbalanced_time", "unbalanced_time %g ", &tv);
close_json_object();
}
@ -343,325 +328,14 @@ static void print_nh_res_bucket(FILE *fp, const struct rtattr *res_bucket_attr)
close_json_object();
}
static void ipnh_destroy_entry(struct nh_entry *nhe)
{
if (nhe->nh_encap)
free(nhe->nh_encap);
if (nhe->nh_groups)
free(nhe->nh_groups);
}
/* parse nhmsg into nexthop entry struct which must be destroyed by
* ipnh_destroy_enty when it's not needed anymore
*/
static int ipnh_parse_nhmsg(FILE *fp, const struct nhmsg *nhm, int len,
struct nh_entry *nhe)
{
struct rtattr *tb[NHA_MAX+1];
int err = 0;
memset(nhe, 0, sizeof(*nhe));
parse_rtattr_flags(tb, NHA_MAX, RTM_NHA(nhm), len, NLA_F_NESTED);
if (tb[NHA_ID])
nhe->nh_id = rta_getattr_u32(tb[NHA_ID]);
if (tb[NHA_OIF])
nhe->nh_oif = rta_getattr_u32(tb[NHA_OIF]);
if (tb[NHA_GROUP_TYPE])
nhe->nh_grp_type = rta_getattr_u16(tb[NHA_GROUP_TYPE]);
if (tb[NHA_GATEWAY]) {
if (RTA_PAYLOAD(tb[NHA_GATEWAY]) > sizeof(nhe->nh_gateway)) {
fprintf(fp, "<nexthop id %u invalid gateway length %lu>\n",
nhe->nh_id, RTA_PAYLOAD(tb[NHA_GATEWAY]));
err = -EINVAL;
goto out_err;
}
nhe->nh_gateway_len = RTA_PAYLOAD(tb[NHA_GATEWAY]);
memcpy(&nhe->nh_gateway, RTA_DATA(tb[NHA_GATEWAY]),
RTA_PAYLOAD(tb[NHA_GATEWAY]));
}
if (tb[NHA_ENCAP]) {
nhe->nh_encap = malloc(RTA_LENGTH(RTA_PAYLOAD(tb[NHA_ENCAP])));
if (!nhe->nh_encap) {
err = -ENOMEM;
goto out_err;
}
memcpy(nhe->nh_encap, tb[NHA_ENCAP],
RTA_LENGTH(RTA_PAYLOAD(tb[NHA_ENCAP])));
memcpy(&nhe->nh_encap_type, tb[NHA_ENCAP_TYPE],
sizeof(nhe->nh_encap_type));
}
if (tb[NHA_GROUP]) {
if (!__valid_nh_group_attr(tb[NHA_GROUP])) {
fprintf(fp, "<nexthop id %u invalid nexthop group>",
nhe->nh_id);
err = -EINVAL;
goto out_err;
}
nhe->nh_groups = malloc(RTA_PAYLOAD(tb[NHA_GROUP]));
if (!nhe->nh_groups) {
err = -ENOMEM;
goto out_err;
}
nhe->nh_groups_cnt = RTA_PAYLOAD(tb[NHA_GROUP]) /
sizeof(struct nexthop_grp);
memcpy(nhe->nh_groups, RTA_DATA(tb[NHA_GROUP]),
RTA_PAYLOAD(tb[NHA_GROUP]));
}
if (tb[NHA_RES_GROUP]) {
parse_nh_res_group_rta(tb[NHA_RES_GROUP], &nhe->nh_res_grp);
nhe->nh_has_res_grp = true;
}
nhe->nh_blackhole = !!tb[NHA_BLACKHOLE];
nhe->nh_fdb = !!tb[NHA_FDB];
nhe->nh_family = nhm->nh_family;
nhe->nh_protocol = nhm->nh_protocol;
nhe->nh_scope = nhm->nh_scope;
nhe->nh_flags = nhm->nh_flags;
return 0;
out_err:
ipnh_destroy_entry(nhe);
return err;
}
static void __print_nexthop_entry(FILE *fp, const char *jsobj,
struct nh_entry *nhe,
bool deleted)
{
SPRINT_BUF(b1);
open_json_object(jsobj);
if (deleted)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
print_uint(PRINT_ANY, "id", "id %u ", nhe->nh_id);
if (nhe->nh_groups)
print_nh_group(nhe);
print_nh_group_type(nhe->nh_grp_type);
if (nhe->nh_has_res_grp)
print_nh_res_group(&nhe->nh_res_grp);
if (nhe->nh_encap)
lwt_print_encap(fp, &nhe->nh_encap_type.rta, nhe->nh_encap);
if (nhe->nh_gateway_len)
__print_rta_gateway(fp, nhe->nh_family,
format_host(nhe->nh_family,
nhe->nh_gateway_len,
&nhe->nh_gateway));
if (nhe->nh_oif)
print_rta_ifidx(fp, nhe->nh_oif, "dev");
if (nhe->nh_scope != RT_SCOPE_UNIVERSE || show_details > 0) {
print_string(PRINT_ANY, "scope", "scope %s ",
rtnl_rtscope_n2a(nhe->nh_scope, b1, sizeof(b1)));
}
if (nhe->nh_blackhole)
print_null(PRINT_ANY, "blackhole", "blackhole ", NULL);
if (nhe->nh_protocol != RTPROT_UNSPEC || show_details > 0) {
print_string(PRINT_ANY, "protocol", "proto %s ",
rtnl_rtprot_n2a(nhe->nh_protocol, b1, sizeof(b1)));
}
print_rt_flags(fp, nhe->nh_flags);
if (nhe->nh_fdb)
print_null(PRINT_ANY, "fdb", "fdb", NULL);
close_json_object();
}
static int __ipnh_get_id(struct rtnl_handle *rthp, __u32 nh_id,
struct nlmsghdr **answer)
{
struct {
struct nlmsghdr n;
struct nhmsg nhm;
char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = RTM_GETNEXTHOP,
.nhm.nh_family = preferred_family,
};
addattr32(&req.n, sizeof(req), NHA_ID, nh_id);
return rtnl_talk(rthp, &req.n, answer);
}
static struct hlist_head *ipnh_cache_head(__u32 nh_id)
{
nh_id ^= nh_id >> 20;
nh_id ^= nh_id >> 10;
return &nh_cache[nh_id % NH_CACHE_SIZE];
}
static void ipnh_cache_link_entry(struct nh_entry *nhe)
{
struct hlist_head *head = ipnh_cache_head(nhe->nh_id);
hlist_add_head(&nhe->nh_hash, head);
}
static void ipnh_cache_unlink_entry(struct nh_entry *nhe)
{
hlist_del(&nhe->nh_hash);
}
static struct nh_entry *ipnh_cache_get(__u32 nh_id)
{
struct hlist_head *head = ipnh_cache_head(nh_id);
struct nh_entry *nhe;
struct hlist_node *n;
hlist_for_each(n, head) {
nhe = container_of(n, struct nh_entry, nh_hash);
if (nhe->nh_id == nh_id)
return nhe;
}
return NULL;
}
static int __ipnh_cache_parse_nlmsg(const struct nlmsghdr *n,
struct nh_entry *nhe)
{
int err, len;
len = n->nlmsg_len - NLMSG_SPACE(sizeof(struct nhmsg));
if (len < 0) {
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
return -EINVAL;
}
err = ipnh_parse_nhmsg(stderr, NLMSG_DATA(n), len, nhe);
if (err) {
fprintf(stderr, "Error parsing nexthop: %s\n", strerror(-err));
return err;
}
return 0;
}
static struct nh_entry *ipnh_cache_add(__u32 nh_id)
{
struct nlmsghdr *answer = NULL;
struct nh_entry *nhe = NULL;
if (nh_cache_rth.fd < 0 && rtnl_open(&nh_cache_rth, 0) < 0) {
nh_cache_rth.fd = -1;
goto out;
}
if (__ipnh_get_id(&nh_cache_rth, nh_id, &answer) < 0)
goto out;
nhe = malloc(sizeof(*nhe));
if (!nhe)
goto out;
if (__ipnh_cache_parse_nlmsg(answer, nhe))
goto out_free_nhe;
ipnh_cache_link_entry(nhe);
out:
if (answer)
free(answer);
return nhe;
out_free_nhe:
free(nhe);
nhe = NULL;
goto out;
}
static void ipnh_cache_del(struct nh_entry *nhe)
{
ipnh_cache_unlink_entry(nhe);
ipnh_destroy_entry(nhe);
free(nhe);
}
/* update, add or delete a nexthop entry based on nlmsghdr */
static int ipnh_cache_process_nlmsg(const struct nlmsghdr *n,
struct nh_entry *new_nhe)
{
struct nh_entry *nhe;
nhe = ipnh_cache_get(new_nhe->nh_id);
switch (n->nlmsg_type) {
case RTM_DELNEXTHOP:
if (nhe)
ipnh_cache_del(nhe);
ipnh_destroy_entry(new_nhe);
break;
case RTM_NEWNEXTHOP:
if (!nhe) {
nhe = malloc(sizeof(*nhe));
if (!nhe) {
ipnh_destroy_entry(new_nhe);
return -1;
}
} else {
/* this allows us to save 1 allocation on updates by
* reusing the old nh entry, but we need to cleanup its
* internal storage
*/
ipnh_cache_unlink_entry(nhe);
ipnh_destroy_entry(nhe);
}
memcpy(nhe, new_nhe, sizeof(*nhe));
ipnh_cache_link_entry(nhe);
break;
}
return 0;
}
void print_cache_nexthop_id(FILE *fp, const char *fp_prefix, const char *jsobj,
__u32 nh_id)
{
struct nh_entry *nhe = ipnh_cache_get(nh_id);
if (!nhe) {
nhe = ipnh_cache_add(nh_id);
if (!nhe)
return;
}
if (fp_prefix)
print_string(PRINT_FP, NULL, "%s", fp_prefix);
__print_nexthop_entry(fp, jsobj, nhe, false);
}
int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache)
int print_nexthop(struct nlmsghdr *n, void *arg)
{
struct nhmsg *nhm = NLMSG_DATA(n);
struct rtattr *tb[NHA_MAX+1];
FILE *fp = (FILE *)arg;
struct nh_entry nhe;
int len, err;
int len;
SPRINT_BUF(b1);
if (n->nlmsg_type != RTM_DELNEXTHOP &&
n->nlmsg_type != RTM_NEWNEXTHOP) {
@ -680,29 +354,60 @@ int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache)
if (filter.proto && filter.proto != nhm->nh_protocol)
return 0;
err = ipnh_parse_nhmsg(fp, nhm, len, &nhe);
if (err) {
close_json_object();
fprintf(stderr, "Error parsing nexthop: %s\n", strerror(-err));
return -1;
parse_rtattr_flags(tb, NHA_MAX, RTM_NHA(nhm), len, NLA_F_NESTED);
open_json_object(NULL);
if (n->nlmsg_type == RTM_DELNEXTHOP)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
if (tb[NHA_ID])
print_uint(PRINT_ANY, "id", "id %u ",
rta_getattr_u32(tb[NHA_ID]));
if (tb[NHA_GROUP])
print_nh_group(fp, tb[NHA_GROUP]);
if (tb[NHA_GROUP_TYPE])
print_nh_group_type(fp, tb[NHA_GROUP_TYPE]);
if (tb[NHA_RES_GROUP])
print_nh_res_group(fp, tb[NHA_RES_GROUP]);
if (tb[NHA_ENCAP])
lwt_print_encap(fp, tb[NHA_ENCAP_TYPE], tb[NHA_ENCAP]);
if (tb[NHA_GATEWAY])
print_rta_gateway(fp, nhm->nh_family, tb[NHA_GATEWAY]);
if (tb[NHA_OIF])
print_rta_if(fp, tb[NHA_OIF], "dev");
if (nhm->nh_scope != RT_SCOPE_UNIVERSE || show_details > 0) {
print_string(PRINT_ANY, "scope", "scope %s ",
rtnl_rtscope_n2a(nhm->nh_scope, b1, sizeof(b1)));
}
__print_nexthop_entry(fp, NULL, &nhe, n->nlmsg_type == RTM_DELNEXTHOP);
if (tb[NHA_BLACKHOLE])
print_null(PRINT_ANY, "blackhole", "blackhole ", NULL);
if (nhm->nh_protocol != RTPROT_UNSPEC || show_details > 0) {
print_string(PRINT_ANY, "protocol", "proto %s ",
rtnl_rtprot_n2a(nhm->nh_protocol, b1, sizeof(b1)));
}
print_rt_flags(fp, nhm->nh_flags);
if (tb[NHA_FDB])
print_null(PRINT_ANY, "fdb", "fdb", NULL);
print_string(PRINT_FP, NULL, "%s", "\n");
close_json_object();
fflush(fp);
if (process_cache)
ipnh_cache_process_nlmsg(n, &nhe);
else
ipnh_destroy_entry(&nhe);
return 0;
}
static int print_nexthop_nocache(struct nlmsghdr *n, void *arg)
{
return print_cache_nexthop(n, arg, false);
}
int print_nexthop_bucket(struct nlmsghdr *n, void *arg)
{
struct nhmsg *nhm = NLMSG_DATA(n);
@ -841,7 +546,7 @@ static void parse_nh_group_type_res(struct nlmsghdr *n, int maxlen, int *argcp,
NEXT_ARG();
if (get_unsigned(&idle_timer, *argv, 0) ||
idle_timer >= UINT32_MAX / 100)
idle_timer >= ~0UL / 100)
invarg("invalid idle timer value", *argv);
addattr32(n, maxlen, NHA_RES_GROUP_IDLE_TIMER,
@ -851,7 +556,7 @@ static void parse_nh_group_type_res(struct nlmsghdr *n, int maxlen, int *argcp,
NEXT_ARG();
if (get_unsigned(&unbalanced_timer, *argv, 0) ||
unbalanced_timer >= UINT32_MAX / 100)
unbalanced_timer >= ~0UL / 100)
invarg("invalid unbalanced timer value", *argv);
addattr32(n, maxlen, NHA_RES_GROUP_UNBALANCED_TIMER,
@ -1007,14 +712,26 @@ static int ipnh_modify(int cmd, unsigned int flags, int argc, char **argv)
static int ipnh_get_id(__u32 id)
{
struct {
struct nlmsghdr n;
struct nhmsg nhm;
char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = RTM_GETNEXTHOP,
.nhm.nh_family = preferred_family,
};
struct nlmsghdr *answer;
if (__ipnh_get_id(&rth, id, &answer) < 0)
addattr32(&req.n, sizeof(req), NHA_ID, id);
if (rtnl_talk(&rth, &req.n, &answer) < 0)
return -2;
new_json_obj(json);
if (print_nexthop_nocache(answer, (void *)stdout) < 0) {
if (print_nexthop(answer, (void *)stdout) < 0) {
free(answer);
return -1;
}
@ -1099,7 +816,7 @@ static int ipnh_list_flush(int argc, char **argv, int action)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_nexthop_nocache, stdout) < 0) {
if (rtnl_dump_filter(&rth, print_nexthop, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
return -2;
}

View File

@ -47,15 +47,15 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip ntable change name NAME [ dev DEV ]\n"
" [ thresh1 VAL ] [ thresh2 VAL ] [ thresh3 VAL ] [ gc_int MSEC ]\n"
" [ PARMS ]\n"
" [ thresh1 VAL ] [ thresh2 VAL ] [ thresh3 VAL ] [ gc_int MSEC ]\n"
" [ PARMS ]\n"
"Usage: ip ntable show [ dev DEV ] [ name NAME ]\n"
"PARMS := [ base_reachable MSEC ] [ retrans MSEC ] [ gc_stale MSEC ]\n"
" [ delay_probe MSEC ] [ queue LEN ]\n"
" [ app_probes VAL ] [ ucast_probes VAL ] [ mcast_probes VAL ]\n"
" [ anycast_delay MSEC ] [ proxy_delay MSEC ] [ proxy_queue LEN ]\n"
" [ locktime MSEC ]\n"
" [ delay_probe MSEC ] [ queue LEN ]\n"
" [ app_probes VAL ] [ ucast_probes VAL ] [ mcast_probes VAL ]\n"
" [ anycast_delay MSEC ] [ proxy_delay MSEC ] [ proxy_queue LEN ]\n"
" [ locktime MSEC ]\n"
);
exit(-1);

View File

@ -28,7 +28,6 @@
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
#include "nh_common.h"
#ifndef RTAX_RTTVAR
#define RTAX_RTTVAR RTAX_HOPS
@ -83,7 +82,7 @@ static void usage(void)
" [ ttl-propagate { enabled | disabled } ]\n"
"INFO_SPEC := { NH | nhid ID } OPTIONS FLAGS [ nexthop NH ]...\n"
"NH := [ encap ENCAPTYPE ENCAPHDR ] [ via [ FAMILY ] ADDRESS ]\n"
" [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"
" [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"
"FAMILY := [ inet | inet6 | mpls | bridge | link ]\n"
"OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ]\n"
" [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]\n"
@ -102,18 +101,10 @@ static void usage(void)
"TIME := NUMBER[s|ms]\n"
"BOOL := [1|0]\n"
"FEATURES := ecn\n"
"ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl | ioam6 ]\n"
"ENCAPHDR := [ MPLSLABEL | SEG6HDR | SEG6LOCAL | IOAM6HDR ]\n"
"ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl ]\n"
"ENCAPHDR := [ MPLSLABEL | SEG6HDR ]\n"
"SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]\n"
"SEGMODE := [ encap | inline ]\n"
"SEG6LOCAL := action ACTION [ OPTIONS ] [ count ]\n"
"ACTION := { End | End.X | End.T | End.DX2 | End.DX6 | End.DX4 |\n"
" End.DT6 | End.DT4 | End.DT46 | End.B6 | End.B6.Encaps |\n"
" End.BM | End.S | End.AS | End.AM | End.BPF }\n"
"OPTIONS := OPTION [ OPTIONS ]\n"
"OPTION := { srh SEG6HDR | nh4 ADDR | nh6 ADDR | iif DEV | oif DEV |\n"
" table TABLEID | vrftable TABLEID | endpoint PROGNAME }\n"
"IOAM6HDR := trace prealloc type IOAM6_TRACE_TYPE ns IOAM6_NAMESPACE size IOAM6_TRACE_SIZE\n"
"ROUTE_GET_FLAGS := [ fibmatch ]\n");
exit(-1);
}
@ -411,13 +402,13 @@ static void print_rt_pref(FILE *fp, unsigned int pref)
}
}
void print_rta_ifidx(FILE *fp, __u32 ifidx, const char *prefix)
void print_rta_if(FILE *fp, const struct rtattr *rta, const char *prefix)
{
const char *ifname = ll_index_to_name(ifidx);
const char *ifname = ll_index_to_name(rta_getattr_u32(rta));
if (is_json_context()) {
if (is_json_context())
print_string(PRINT_JSON, prefix, NULL, ifname);
} else {
else {
fprintf(fp, "%s ", prefix);
color_fprintf(fp, COLOR_IFNAME, "%s ", ifname);
}
@ -548,11 +539,13 @@ static void print_rta_newdst(FILE *fp, const struct rtmsg *r,
}
}
void __print_rta_gateway(FILE *fp, unsigned char family, const char *gateway)
void print_rta_gateway(FILE *fp, unsigned char family, const struct rtattr *rta)
{
if (is_json_context()) {
const char *gateway = format_host_rta(family, rta);
if (is_json_context())
print_string(PRINT_JSON, "gateway", NULL, gateway);
} else {
else {
fprintf(fp, "via ");
print_color_string(PRINT_FP,
ifa_family_color(family),
@ -560,13 +553,6 @@ void __print_rta_gateway(FILE *fp, unsigned char family, const char *gateway)
}
}
void print_rta_gateway(FILE *fp, unsigned char family, const struct rtattr *rta)
{
const char *gateway = format_host_rta(family, rta);
__print_rta_gateway(fp, family, gateway);
}
static void print_rta_via(FILE *fp, const struct rtattr *rta)
{
size_t len = RTA_PAYLOAD(rta) - 2;
@ -868,7 +854,7 @@ int print_route(struct nlmsghdr *n, void *arg)
print_rta_via(fp, tb[RTA_VIA]);
if (tb[RTA_OIF] && filter.oifmask != -1)
print_rta_ifidx(fp, rta_getattr_u32(tb[RTA_OIF]), "dev");
print_rta_if(fp, tb[RTA_OIF], "dev");
if (table && (table != RT_TABLE_MAIN || show_details > 0) && !filter.tb)
print_string(PRINT_ANY,
@ -952,7 +938,7 @@ int print_route(struct nlmsghdr *n, void *arg)
print_rta_metrics(fp, tb[RTA_METRICS]);
if (tb[RTA_IIF] && filter.iifmask != -1)
print_rta_ifidx(fp, rta_getattr_u32(tb[RTA_IIF]), "iif");
print_rta_if(fp, tb[RTA_IIF], "iif");
if (tb[RTA_PREF])
print_rt_pref(fp, rta_getattr_u8(tb[RTA_PREF]));
@ -969,10 +955,6 @@ int print_route(struct nlmsghdr *n, void *arg)
propagate ? "enabled" : "disabled");
}
if (tb[RTA_NH_ID] && show_details)
print_cache_nexthop_id(fp, "\n\tnh_info ", "nh_info",
rta_getattr_u32(tb[RTA_NH_ID]));
if (tb[RTA_MULTIPATH])
print_rta_multipath(fp, r, tb[RTA_MULTIPATH]);
@ -1745,18 +1727,6 @@ static int iproute_flush(int family, rtnl_filter_t filter_fn)
}
}
static int save_route_errhndlr(struct nlmsghdr *n, void *arg)
{
int err = -*(int *)NLMSG_DATA(n);
if (n->nlmsg_type == NLMSG_DONE &&
filter.tb == RT_TABLE_MAIN &&
err == ENOENT)
return RTNL_SUPPRESS_NLMSG_DONE_NLERR;
return RTNL_LET_NLERR;
}
static int iproute_list_flush_or_save(int argc, char **argv, int action)
{
int dump_family = preferred_family;
@ -1969,8 +1939,7 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
new_json_obj(json);
if (rtnl_dump_filter_errhndlr(&rth, filter_fn, stdout,
save_route_errhndlr, NULL) < 0) {
if (rtnl_dump_filter(&rth, filter_fn, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
return -2;
}

View File

@ -34,8 +34,6 @@
#include <linux/seg6_hmac.h>
#include <linux/seg6_local.h>
#include <linux/if_tunnel.h>
#include <linux/ioam6.h>
#include <linux/ioam6_iptunnel.h>
static const char *format_encap_type(int type)
{
@ -56,8 +54,6 @@ static const char *format_encap_type(int type)
return "seg6local";
case LWTUNNEL_ENCAP_RPL:
return "rpl";
case LWTUNNEL_ENCAP_IOAM6:
return "ioam6";
default:
return "unknown";
}
@ -94,8 +90,6 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_SEG6_LOCAL;
else if (strcmp(name, "rpl") == 0)
return LWTUNNEL_ENCAP_RPL;
else if (strcmp(name, "ioam6") == 0)
return LWTUNNEL_ENCAP_IOAM6;
else if (strcmp(name, "help") == 0)
encap_type_usage();
@ -210,63 +204,6 @@ static void print_encap_rpl(FILE *fp, struct rtattr *encap)
print_rpl_srh(fp, srh);
}
static const char *ioam6_mode_types[IOAM6_IPTUNNEL_MODE_MAX + 1] = {
[IOAM6_IPTUNNEL_MODE_INLINE] = "inline",
[IOAM6_IPTUNNEL_MODE_ENCAP] = "encap",
[IOAM6_IPTUNNEL_MODE_AUTO] = "auto",
};
static const char *format_ioam6mode_type(int mode)
{
if (mode < IOAM6_IPTUNNEL_MODE_MIN ||
mode > IOAM6_IPTUNNEL_MODE_MAX ||
!ioam6_mode_types[mode])
return "<unknown>";
return ioam6_mode_types[mode];
}
static __u8 read_ioam6mode_type(const char *mode)
{
__u8 i;
for (i = IOAM6_IPTUNNEL_MODE_MIN; i <= IOAM6_IPTUNNEL_MODE_MAX; i++) {
if (ioam6_mode_types[i] && !strcmp(mode, ioam6_mode_types[i]))
return i;
}
return 0;
}
static void print_encap_ioam6(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[IOAM6_IPTUNNEL_MAX + 1];
struct ioam6_trace_hdr *trace;
__u8 mode;
parse_rtattr_nested(tb, IOAM6_IPTUNNEL_MAX, encap);
if (!tb[IOAM6_IPTUNNEL_MODE] || !tb[IOAM6_IPTUNNEL_TRACE])
return;
mode = rta_getattr_u8(tb[IOAM6_IPTUNNEL_MODE]);
if (!tb[IOAM6_IPTUNNEL_DST] && mode != IOAM6_IPTUNNEL_MODE_INLINE)
return;
print_string(PRINT_ANY, "mode", "mode %s ", format_ioam6mode_type(mode));
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
print_string(PRINT_ANY, "tundst", "tundst %s ",
rt_addr_n2a_rta(AF_INET6, tb[IOAM6_IPTUNNEL_DST]));
trace = RTA_DATA(tb[IOAM6_IPTUNNEL_TRACE]);
print_null(PRINT_ANY, "trace", "trace ", NULL);
print_null(PRINT_ANY, "prealloc", "prealloc ", NULL);
print_hex(PRINT_ANY, "type", "type %#08x ", ntohl(trace->type_be32) >> 8);
print_uint(PRINT_ANY, "ns", "ns %u ", ntohs(trace->namespace_id));
print_uint(PRINT_ANY, "size", "size %u ", trace->remlen * 4);
}
static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
[SEG6_LOCAL_ACTION_END] = "End",
[SEG6_LOCAL_ACTION_END_X] = "End.X",
@ -283,7 +220,6 @@ static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
[SEG6_LOCAL_ACTION_END_AS] = "End.AS",
[SEG6_LOCAL_ACTION_END_AM] = "End.AM",
[SEG6_LOCAL_ACTION_END_BPF] = "End.BPF",
[SEG6_LOCAL_ACTION_END_DT46] = "End.DT46",
};
static const char *format_action_type(int action)
@ -330,42 +266,6 @@ static void print_encap_bpf_prog(FILE *fp, struct rtattr *encap,
}
}
static void print_seg6_local_counters(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[SEG6_LOCAL_CNT_MAX + 1];
__u64 packets = 0, bytes = 0, errors = 0;
parse_rtattr_nested(tb, SEG6_LOCAL_CNT_MAX, encap);
if (tb[SEG6_LOCAL_CNT_PACKETS])
packets = rta_getattr_u64(tb[SEG6_LOCAL_CNT_PACKETS]);
if (tb[SEG6_LOCAL_CNT_BYTES])
bytes = rta_getattr_u64(tb[SEG6_LOCAL_CNT_BYTES]);
if (tb[SEG6_LOCAL_CNT_ERRORS])
errors = rta_getattr_u64(tb[SEG6_LOCAL_CNT_ERRORS]);
if (is_json_context()) {
open_json_object("stats64");
print_u64(PRINT_JSON, "packets", NULL, packets);
print_u64(PRINT_JSON, "bytes", NULL, bytes);
print_u64(PRINT_JSON, "errors", NULL, errors);
close_json_object();
} else {
print_string(PRINT_FP, NULL, "%s ", "packets");
print_num(fp, 1, packets);
print_string(PRINT_FP, NULL, "%s ", "bytes");
print_num(fp, 1, bytes);
print_string(PRINT_FP, NULL, "%s ", "errors");
print_num(fp, 1, errors);
}
}
static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[SEG6_LOCAL_MAX + 1];
@ -425,9 +325,6 @@ static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
if (tb[SEG6_LOCAL_BPF])
print_encap_bpf_prog(fp, tb[SEG6_LOCAL_BPF], "endpoint");
if (tb[SEG6_LOCAL_COUNTERS] && show_stats)
print_seg6_local_counters(fp, tb[SEG6_LOCAL_COUNTERS]);
}
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
@ -720,9 +617,6 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
case LWTUNNEL_ENCAP_RPL:
print_encap_rpl(fp, encap);
break;
case LWTUNNEL_ENCAP_IOAM6:
print_encap_ioam6(fp, encap);
break;
}
}
@ -919,122 +813,6 @@ out:
return ret;
}
static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
int ns_found = 0, argc = *argcp;
__u16 trace_ns, trace_size = 0;
struct ioam6_trace_hdr *trace;
char **argv = *argvp;
__u32 trace_type = 0;
inet_prefix addr;
__u8 mode;
if (strcmp(*argv, "mode") != 0) {
mode = IOAM6_IPTUNNEL_MODE_INLINE;
} else {
NEXT_ARG();
mode = read_ioam6mode_type(*argv);
if (!mode)
invarg("Invalid mode", *argv);
NEXT_ARG();
}
if (strcmp(*argv, "tundst") != 0) {
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
missarg("tundst");
} else {
if (mode == IOAM6_IPTUNNEL_MODE_INLINE)
invarg("Inline mode does not need tundst", *argv);
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
if (addr.family != AF_INET6 || addr.bytelen != 16)
invarg("Invalid IPv6 address for tundst", *argv);
NEXT_ARG();
}
if (strcmp(*argv, "trace") != 0)
missarg("trace");
NEXT_ARG();
if (strcmp(*argv, "prealloc") != 0)
missarg("prealloc");
while (NEXT_ARG_OK()) {
NEXT_ARG_FWD();
if (strcmp(*argv, "type") == 0) {
NEXT_ARG();
if (trace_type)
duparg2("type", *argv);
if (get_u32(&trace_type, *argv, 0) || !trace_type)
invarg("Invalid trace type", *argv);
} else if (strcmp(*argv, "ns") == 0) {
NEXT_ARG();
if (ns_found++)
duparg2("ns", *argv);
if (get_u16(&trace_ns, *argv, 0))
invarg("Invalid namespace ID", *argv);
} else if (strcmp(*argv, "size") == 0) {
NEXT_ARG();
if (trace_size)
duparg2("size", *argv);
if (get_u16(&trace_size, *argv, 0) || !trace_size)
invarg("Invalid trace size", *argv);
if (trace_size % 4)
invarg("Trace size must be a 4-octet multiple",
*argv);
if (trace_size > IOAM6_TRACE_DATA_SIZE_MAX)
invarg("Trace size is too big", *argv);
} else {
break;
}
}
if (!trace_type)
missarg("type");
if (!ns_found)
missarg("ns");
if (!trace_size)
missarg("size");
trace = calloc(1, sizeof(*trace));
if (!trace)
return -1;
trace->type_be32 = htonl(trace_type << 8);
trace->namespace_id = htons(trace_ns);
trace->remlen = (__u8)(trace_size / 4);
if (rta_addattr8(rta, len, IOAM6_IPTUNNEL_MODE, mode) ||
(mode != IOAM6_IPTUNNEL_MODE_INLINE &&
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_DST, &addr.data, addr.bytelen)) ||
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_TRACE, trace, sizeof(*trace))) {
free(trace);
return -1;
}
*argcp = argc + 1;
*argvp = argv - 1;
free(trace);
return 0;
}
struct lwt_x {
struct rtattr *rta;
size_t len;
@ -1084,39 +862,13 @@ static int lwt_parse_bpf(struct rtattr *rta, size_t len,
return 0;
}
/* for the moment, counters are always initialized to zero by the kernel; so we
* do not expect to parse any argument here.
*/
static int seg6local_fill_counters(struct rtattr *rta, size_t len, int attr)
{
struct rtattr *nest;
int ret;
nest = rta_nest(rta, len, attr);
ret = rta_addattr64(rta, len, SEG6_LOCAL_CNT_PACKETS, 0);
if (ret < 0)
return ret;
ret = rta_addattr64(rta, len, SEG6_LOCAL_CNT_BYTES, 0);
if (ret < 0)
return ret;
ret = rta_addattr64(rta, len, SEG6_LOCAL_CNT_ERRORS, 0);
if (ret < 0)
return ret;
rta_nest_end(rta, nest);
return 0;
}
static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
int segs_ok = 0, hmac_ok = 0, table_ok = 0, vrftable_ok = 0;
int action_ok = 0, srh_ok = 0, bpf_ok = 0, counters_ok = 0;
int nh4_ok = 0, nh6_ok = 0, iif_ok = 0, oif_ok = 0;
__u32 action = 0, table, vrftable, iif, oif;
int action_ok = 0, srh_ok = 0, bpf_ok = 0;
struct ipv6_sr_hdr *srh;
char **argv = *argvp;
int argc = *argcp;
@ -1180,11 +932,6 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
if (!oif)
exit(nodev(*argv));
ret = rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
} else if (strcmp(*argv, "count") == 0) {
if (counters_ok++)
duparg2("count", *argv);
ret = seg6local_fill_counters(rta, len,
SEG6_LOCAL_COUNTERS);
} else if (strcmp(*argv, "srh") == 0) {
NEXT_ARG();
if (srh_ok++)
@ -1926,9 +1673,6 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp,
case LWTUNNEL_ENCAP_RPL:
ret = parse_encap_rpl(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_IOAM6:
ret = parse_encap_ioam6(rta, len, &argc, &argv);
break;
default:
fprintf(stderr, "Error: unsupported encap type\n");
break;

View File

@ -34,10 +34,10 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip sr { COMMAND | help }\n"
" ip sr hmac show\n"
" ip sr hmac set KEYID ALGO\n"
" ip sr tunsrc show\n"
" ip sr tunsrc set ADDRESS\n"
" ip sr hmac show\n"
" ip sr hmac set KEYID ALGO\n"
" ip sr tunsrc show\n"
" ip sr tunsrc set ADDRESS\n"
"where ALGO := { sha1 | sha256 }\n");
exit(-1);
}

View File

@ -34,18 +34,18 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]\n"
" [ mode { gre | ipip | isatap | sit | vti } ]\n"
" [ remote ADDR ] [ local ADDR ]\n"
" [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"
" [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n"
" [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n"
" [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"
" [ mode { gre | ipip | isatap | sit | vti } ]\n"
" [ remote ADDR ] [ local ADDR ]\n"
" [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"
" [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n"
" [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n"
" [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"
"\n"
"Where: NAME := STRING\n"
" ADDR := { IP_ADDRESS | any }\n"
" TOS := { STRING | 00..ff | inherit | inherit/STRING | inherit/00..ff }\n"
" TTL := { 1..255 | inherit }\n"
" KEY := { DOTTED_QUAD | NUMBER }\n");
"Where: NAME := STRING\n"
" ADDR := { IP_ADDRESS | any }\n"
" TOS := { STRING | 00..ff | inherit | inherit/STRING | inherit/00..ff }\n"
" TTL := { 1..255 | inherit }\n"
" KEY := { DOTTED_QUAD | NUMBER }\n");
exit(-1);
}

View File

@ -42,11 +42,11 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip tuntap { add | del | show | list | lst | help } [ dev PHYS_DEV ]\n"
" [ mode { tun | tap } ] [ user USER ] [ group GROUP ]\n"
" [ one_queue ] [ pi ] [ vnet_hdr ] [ multi_queue ] [ name NAME ]\n"
" [ mode { tun | tap } ] [ user USER ] [ group GROUP ]\n"
" [ one_queue ] [ pi ] [ vnet_hdr ] [ multi_queue ] [ name NAME ]\n"
"\n"
"Where: USER := { STRING | NUMBER }\n"
" GROUP := { STRING | NUMBER }\n");
"Where: USER := { STRING | NUMBER }\n"
" GROUP := { STRING | NUMBER }\n");
exit(-1);
}
@ -243,9 +243,6 @@ static void print_flags(long flags)
if (flags & IFF_ONE_QUEUE)
print_string(PRINT_ANY, NULL, " %s", "one_queue");
if (flags & IFF_MULTI_QUEUE)
print_string(PRINT_ANY, NULL, " %s", "multi_queue");
if (flags & IFF_VNET_HDR)
print_string(PRINT_ANY, NULL, " %s", "vnet_hdr");
@ -256,10 +253,9 @@ static void print_flags(long flags)
print_string(PRINT_ANY, NULL, " %s", "filter");
flags &= ~(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
IFF_MULTI_QUEUE | IFF_VNET_HDR | IFF_PERSIST |
IFF_NOFILTER);
IFF_VNET_HDR | IFF_PERSIST | IFF_NOFILTER);
if (flags)
print_0xhex(PRINT_ANY, NULL, " %#llx", flags);
print_0xhex(PRINT_ANY, NULL, "%#llx", flags);
close_json_array(PRINT_JSON, NULL);
}

View File

@ -442,6 +442,7 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_GRE_COLLECT_METADATA]) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
tnl_print_endpoint("remote", tb[IFLA_GRE_REMOTE], AF_INET);

View File

@ -461,6 +461,7 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_GRE_COLLECT_METADATA]) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
if (tb[IFLA_GRE_FLAGS])

View File

@ -344,6 +344,7 @@ static void ip6tunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb
if (tb[IFLA_IPTUN_COLLECT_METADATA]) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
if (tb[IFLA_IPTUN_FLAGS])

View File

@ -368,6 +368,7 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
if (tb[IFLA_IPTUN_COLLECT_METADATA]) {
print_bool(PRINT_ANY, "external", "external ", true);
return;
}
if (tb[IFLA_IPTUN_PROTO]) {

View File

@ -1,53 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __NH_COMMON_H__
#define __NH_COMMON_H__ 1
#include <list.h>
#define NH_CACHE_SIZE 1024
struct nha_res_grp {
__u16 buckets;
__u32 idle_timer;
__u32 unbalanced_timer;
__u64 unbalanced_time;
};
struct nh_entry {
struct hlist_node nh_hash;
__u32 nh_id;
__u32 nh_oif;
__u32 nh_flags;
__u16 nh_grp_type;
__u8 nh_family;
__u8 nh_scope;
__u8 nh_protocol;
bool nh_blackhole;
bool nh_fdb;
int nh_gateway_len;
union {
__be32 ipv4;
struct in6_addr ipv6;
} nh_gateway;
struct rtattr *nh_encap;
union {
struct rtattr rta;
__u8 _buf[RTA_LENGTH(sizeof(__u16))];
} nh_encap_type;
bool nh_has_res_grp;
struct nha_res_grp nh_res_grp;
int nh_groups_cnt;
struct nexthop_grp *nh_groups;
};
void print_cache_nexthop_id(FILE *fp, const char *fp_prefix, const char *jsobj,
__u32 nh_id);
int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache);
#endif /* __NH_COMMON_H__ */

10
ip/routef Executable file
View File

@ -0,0 +1,10 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0
if [ -z "$*" ] ; then
exec ip -4 ro flush scope global type unicast
else
echo "Usage: routef"
echo
echo "This script will flush the IPv4 routing table"
fi

124
ip/routel
View File

@ -1,62 +1,72 @@
#! /usr/bin/env python3
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Script created by: Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18
# Donated to the public domain.
#
# This script transforms the output of "ip" into more readable text.
# "ip" is the Linux-advanced-routing configuration tool part of the
# iproute package.
#
# This is simple script to process JSON output from ip route
# command and format it. Based on earlier shell script version.
"""Script to parse ip route output into more readable text."""
import sys
import json
import getopt
import subprocess
test "X-h" = "X$1" && echo "Usage: $0 [tablenr [raw ip args...]]" && exit 64
test -z "$*" && set 0
def usage():
'''Print usage and exit'''
print("Usage: {} [tablenr [raw ip args...]]".format(sys.argv[0]))
sys.exit(64)
def main():
'''Process the arguments'''
family = 'inet'
try:
opts, args = getopt.getopt(sys.argv[1:], "h46f:", ["help", "family="])
except getopt.GetoptError as err:
print(err)
usage()
for opt, arg in opts:
if opt in ["-h", "--help"]:
usage()
elif opt == '-6':
family = 'inet6'
elif opt == "-4":
family = 'inet'
elif opt in ["-f", "--family"]:
family = arg
else:
assert False, "unhandled option"
if not args:
args = ['0']
cmd = ['ip', '-f', family, '-j', 'route', 'list', 'table'] + args
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
tbl = json.load(process.stdout)
if family == 'inet':
fmt = '{:15} {:15} {:15} {:8} {:8}{:<16} {}'
else:
fmt = '{:32} {:32} {:32} {:8} {:8}{:<16} {}'
# ip route json keys
keys = ['dst', 'gateway', 'prefsrc', 'protocol', 'scope', 'dev', 'table']
print(fmt.format(*map(lambda x: x.capitalize(), keys)))
for record in tbl:
fields = [record[k] if k in record else '' for k in keys]
print(fmt.format(*fields))
if __name__ == "__main__":
main()
ip route list table "$@" |
while read network rest
do set xx $rest
shift
proto=""
via=""
dev=""
scope=""
src=""
table=""
case $network in
broadcast|local|unreachable) via=$network
network=$1
shift
;;
esac
while test $# != 0
do
case "$1" in
proto|via|dev|scope|src|table)
key=$1
val=$2
eval "$key='$val'"
shift 2
;;
dead|onlink|pervasive|offload|notify|linkdown|unresolved)
shift
;;
*)
# avoid infinite loop on unknown keyword without value at line end
shift
shift
;;
esac
done
echo "$network $via $src $proto $scope $dev $table"
done | awk -F ' ' '
BEGIN {
format="%15s%-3s %15s %15s %8s %8s%7s %s\n";
printf(format,"target","","gateway","source","proto","scope","dev","tbl");
}
{ network=$1;
mask="";
if(match(network,"/"))
{ mask=" "substr(network,RSTART+1);
network=substr(network,0,RSTART);
}
via=$2;
src=$3;
proto=$4;
scope=$5;
dev=$6;
table=$7;
printf(format,network,mask,via,src,proto,scope,dev,table);
}
'

View File

@ -65,7 +65,7 @@ static void usage(void)
fprintf(stderr,
"Usage: rtmon [ OPTIONS ] file FILE [ all | LISTofOBJECTS ]\n"
"OPTIONS := { -f[amily] { inet | inet6 | link | help } |\n"
" -4 | -6 | -0 | -V[ersion] }\n"
" -4 | -6 | -0 | -V[ersion] }\n"
"LISTofOBJECTS := [ link ] [ address ] [ route ]\n");
exit(-1);
}

5
ip/rtpr Executable file
View File

@ -0,0 +1,5 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0
exec tr "[\\\\]" "[
]"

View File

@ -132,7 +132,6 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
struct rtattr *tb[], FILE *fp, const char *prefix,
const char *title);
int xfrm_policy_default_print(struct nlmsghdr *n, FILE *fp);
int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
int loose, int *argcp, char ***argvp);
int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp);

View File

@ -323,9 +323,6 @@ static int xfrm_accept_msg(struct rtnl_ctrl_data *ctrl,
case XFRM_MSG_MAPPING:
xfrm_mapping_print(n, arg);
return 0;
case XFRM_MSG_GETDEFAULT:
xfrm_policy_default_print(n, arg);
return 0;
default:
break;
}

View File

@ -66,8 +66,6 @@ static void usage(void)
"Usage: ip xfrm policy flush [ ptype PTYPE ]\n"
"Usage: ip xfrm policy count\n"
"Usage: ip xfrm policy set [ hthresh4 LBITS RBITS ] [ hthresh6 LBITS RBITS ]\n"
"Usage: ip xfrm policy setdefault DIR ACTION [ DIR ACTION ] [ DIR ACTION ]\n"
"Usage: ip xfrm policy getdefault\n"
"SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n"
"UPSPEC := proto { { tcp | udp | sctp | dccp } [ sport PORT ] [ dport PORT ] |\n"
" { icmp | ipv6-icmp | mobility-header } [ type NUMBER ] [ code NUMBER ] |\n"
@ -1126,133 +1124,6 @@ static int xfrm_spd_getinfo(int argc, char **argv)
return 0;
}
static int xfrm_str_to_policy(char *name, uint8_t *policy)
{
if (strcmp(name, "block") == 0) {
*policy = XFRM_USERPOLICY_BLOCK;
return 0;
} else if (strcmp(name, "accept") == 0) {
*policy = XFRM_USERPOLICY_ACCEPT;
return 0;
}
return -1;
}
static char *xfrm_policy_to_str(uint8_t policy)
{
switch (policy) {
case XFRM_USERPOLICY_UNSPEC:
return "unspec";
case XFRM_USERPOLICY_BLOCK:
return "block";
case XFRM_USERPOLICY_ACCEPT:
return "accept";
default:
return "unknown";
}
}
static int xfrm_spd_setdefault(int argc, char **argv)
{
struct rtnl_handle rth;
struct {
struct nlmsghdr n;
struct xfrm_userpolicy_default up;
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_default)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = XFRM_MSG_SETDEFAULT,
};
while (argc > 0) {
if (strcmp(*argv, "in") == 0) {
if (req.up.in)
duparg("in", *argv);
NEXT_ARG();
if (xfrm_str_to_policy(*argv, &req.up.in) < 0)
invarg("in policy value is invalid", *argv);
} else if (strcmp(*argv, "fwd") == 0) {
if (req.up.fwd)
duparg("fwd", *argv);
NEXT_ARG();
if (xfrm_str_to_policy(*argv, &req.up.fwd) < 0)
invarg("fwd policy value is invalid", *argv);
} else if (strcmp(*argv, "out") == 0) {
if (req.up.out)
duparg("out", *argv);
NEXT_ARG();
if (xfrm_str_to_policy(*argv, &req.up.out) < 0)
invarg("out policy value is invalid", *argv);
} else {
invarg("unknown direction", *argv);
}
argc--; argv++;
}
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
if (rtnl_talk(&rth, &req.n, NULL) < 0)
exit(2);
rtnl_close(&rth);
return 0;
}
int xfrm_policy_default_print(struct nlmsghdr *n, FILE *fp)
{
struct xfrm_userpolicy_default *up = NLMSG_DATA(n);
int len = n->nlmsg_len - NLMSG_SPACE(sizeof(*up));
if (len < 0) {
fprintf(stderr,
"BUG: short nlmsg len %u (expect %lu) for XFRM_MSG_GETDEFAULT\n",
n->nlmsg_len, NLMSG_SPACE(sizeof(*up)));
return -1;
}
fprintf(fp, "Default policies:\n");
fprintf(fp, " in: %s\n", xfrm_policy_to_str(up->in));
fprintf(fp, " fwd: %s\n", xfrm_policy_to_str(up->fwd));
fprintf(fp, " out: %s\n", xfrm_policy_to_str(up->out));
fflush(fp);
return 0;
}
static int xfrm_spd_getdefault(int argc, char **argv)
{
struct rtnl_handle rth;
struct {
struct nlmsghdr n;
struct xfrm_userpolicy_default up;
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_default)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = XFRM_MSG_GETDEFAULT,
};
struct nlmsghdr *answer;
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
if (rtnl_talk(&rth, &req.n, &answer) < 0)
exit(2);
xfrm_policy_default_print(answer, (FILE *)stdout);
free(answer);
rtnl_close(&rth);
return 0;
}
static int xfrm_policy_flush(int argc, char **argv)
{
struct rtnl_handle rth;
@ -1326,10 +1197,6 @@ int do_xfrm_policy(int argc, char **argv)
return xfrm_spd_getinfo(argc, argv);
if (matches(*argv, "set") == 0)
return xfrm_spd_setinfo(argc-1, argv+1);
if (matches(*argv, "setdefault") == 0)
return xfrm_spd_setdefault(argc-1, argv+1);
if (matches(*argv, "getdefault") == 0)
return xfrm_spd_getdefault(argc-1, argv+1);
if (matches(*argv, "help") == 0)
usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);

View File

@ -1,82 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#include <errno.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include "utils.h"
const char *ax25_ntop1(const ax25_address *src, char *dst, socklen_t size);
/*
* AX.25 addresses are based on Amateur radio callsigns followed by an SSID
* like XXXXXX-SS where the callsign consists of up to 6 ASCII characters
* which are either letters or digits and the SSID is a decimal number in the
* range 0..15.
* Amateur radio callsigns are assigned by a country's relevant authorities
* and are 3..6 characters though a few countries have assigned callsigns
* longer than that. AX.25 is not able to handle such longer callsigns.
* There are further restrictions on the format of valid callsigns by
* applicable national and international law. Linux doesn't need to care and
* will happily accept anything that consists of 6 ASCII characters in the
* range of A-Z and 0-9 for a callsign such as the default AX.25 MAC address
* LINUX-1 and the default broadcast address QST-0.
* The SSID is just a number and not encoded in ASCII digits.
*
* Being based on HDLC AX.25 encodes addresses by shifting them one bit left
* thus zeroing bit 0, the HDLC extension bit for all but the last bit of
* a packet's address field but for our purposes here we're not considering
* the HDLC extension bit that is it will always be zero.
*
* Linux' internal representation of AX.25 addresses in Linux is very similar
* to this on the on-air or on-the-wire format. The callsign is padded to
* 6 octets by adding spaces, followed by the SSID octet then all 7 octets
* are left-shifted by one bit.
*
* For example, for the address "LINUX-1" the callsign is LINUX and SSID is 1
* the internal format is 98:92:9c:aa:b0:40:02.
*/
const char *ax25_ntop1(const ax25_address *src, char *dst, socklen_t size)
{
char c, *s;
int n;
for (n = 0, s = dst; n < 6; n++) {
c = (src->ax25_call[n] >> 1) & 0x7f;
if (c != ' ')
*s++ = c;
}
*s++ = '-';
n = ((src->ax25_call[6] >> 1) & 0x0f);
if (n > 9) {
*s++ = '1';
n -= 10;
}
*s++ = n + '0';
*s++ = '\0';
if (*dst == '\0' || *dst == '-') {
dst[0] = '*';
dst[1] = '\0';
}
return dst;
}
const char *ax25_ntop(int af, const void *addr, char *buf, socklen_t buflen)
{
switch (af) {
case AF_AX25:
errno = 0;
return ax25_ntop1((ax25_address *)addr, buf, buflen);
default:
errno = EAFNOSUPPORT;
}
return NULL;
}

View File

@ -63,7 +63,7 @@ const char *get_libbpf_version(void)
if (fp == NULL)
goto out;
while (fgets(buf, sizeof(buf), fp) != NULL) {
while ((s = fgets(buf, sizeof(buf), fp)) != NULL) {
if ((s = strstr(buf, "libbpf.so.")) != NULL) {
strncpy(_libbpf_version, s+10, sizeof(_libbpf_version)-1);
strtok(_libbpf_version, "\n");

View File

@ -203,30 +203,12 @@ int bpf_dump_prog_info(FILE *f, uint32_t id)
if (!ret && len) {
int jited = !!info.jited_prog_len;
print_string(PRINT_ANY, "name", "name %s ", info.name);
print_string(PRINT_ANY, "tag", "tag %s ",
hexstring_n2a(info.tag, sizeof(info.tag),
tmp, sizeof(tmp)));
print_uint(PRINT_JSON, "jited", NULL, jited);
if (jited && !is_json_context())
fprintf(f, "jited ");
if (show_details) {
if (info.load_time) {
/* ns since boottime */
print_lluint(PRINT_ANY, "load_time",
"load_time %llu ", info.load_time);
print_luint(PRINT_ANY, "created_by_uid",
"created_by_uid %lu ",
info.created_by_uid);
}
if (info.btf_id)
print_luint(PRINT_ANY, "btf_id", "btf_id %lu ",
info.btf_id);
}
dump_ok = 1;
}
@ -531,12 +513,9 @@ static int bpf_mnt_check_target(const char *target)
int ret;
ret = mkdir(target, S_IRWXU);
if (ret) {
if (errno == EEXIST)
return 0;
if (ret && errno != EEXIST)
fprintf(stderr, "mkdir %s failed: %s\n", target,
strerror(errno));
}
return ret;
}
@ -1552,7 +1531,7 @@ retry:
* into our buffer. Still, try to give a debuggable error
* log for the user, so enlarge it and re-fail.
*/
if (fd < 0 && errno == ENOSPC) {
if (fd < 0 && (errno == ENOSPC || !ctx->log_size)) {
if (tries++ < 10 && !bpf_log_realloc(ctx))
goto retry;
@ -2090,7 +2069,7 @@ retry:
fd = bpf_btf_load(ctx->btf_data->d_buf, ctx->btf_data->d_size,
ctx->log, ctx->log_size);
if (fd < 0 || ctx->verbose) {
if (fd < 0 && errno == ENOSPC) {
if (fd < 0 && (errno == ENOSPC || !ctx->log_size)) {
if (tries++ < 10 && !bpf_log_realloc(ctx))
goto retry;
@ -3013,7 +2992,7 @@ static int bpf_obj_open(const char *pathname, enum bpf_prog_type type,
out:
bpf_elf_ctx_destroy(ctx, ret < 0);
if (ret < 0) {
if (fd >= 0)
if (fd)
close(fd);
return ret;
}
@ -3305,7 +3284,8 @@ bool iproute2_is_map_in_map(const char *libbpf_map_name, struct bpf_elf_map *ima
continue;
if (!ctx->maps[i].id ||
ctx->maps[i].inner_id)
ctx->maps[i].inner_id ||
ctx->maps[i].inner_idx == -1)
continue;
*imap = ctx->maps[i];
@ -3318,9 +3298,6 @@ bool iproute2_is_map_in_map(const char *libbpf_map_name, struct bpf_elf_map *ima
*omap = ctx->maps[j];
outer_map_name = bpf_map_fetch_name(ctx, j);
if (!outer_map_name)
return false;
memcpy(omap_name, outer_map_name, strlen(outer_map_name) + 1);
return true;

View File

@ -268,12 +268,10 @@ static int load_bpf_object(struct bpf_cfg_in *cfg)
}
bpf_object__for_each_program(p, obj) {
bool prog_to_attach = !prog && cfg->section &&
!strcmp(get_bpf_program__section_name(p), cfg->section);
/* Only load the programs that will either be subsequently
* attached or inserted into a tail call map */
if (find_legacy_tail_calls(p, obj) < 0 && !prog_to_attach) {
if (find_legacy_tail_calls(p, obj) < 0 && cfg->section &&
strcmp(get_bpf_program__section_name(p), cfg->section)) {
ret = bpf_program__set_autoload(p, false);
if (ret)
return -EINVAL;
@ -282,8 +280,7 @@ static int load_bpf_object(struct bpf_cfg_in *cfg)
bpf_program__set_type(p, cfg->type);
bpf_program__set_ifindex(p, cfg->ifindex);
if (prog_to_attach)
if (!prog)
prog = p;
}

View File

@ -25,36 +25,11 @@
#include "utils.h"
#ifndef HAVE_HANDLE_AT
# include <sys/syscall.h>
#endif
#define CGROUP2_FS_NAME "cgroup2"
/* if not already mounted cgroup2 is mounted here for iproute2's use */
#define MNT_CGRP2_PATH "/var/run/cgroup2"
#ifndef HAVE_HANDLE_AT
struct file_handle {
unsigned handle_bytes;
int handle_type;
unsigned char f_handle[];
};
static int name_to_handle_at(int dirfd, const char *pathname,
struct file_handle *handle, int *mount_id, int flags)
{
return syscall(__NR_name_to_handle_at, dirfd, pathname, handle,
mount_id, flags);
}
static int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags)
{
return syscall(__NR_open_by_handle_at, mount_fd, handle, flags);
}
#endif
/* return mount path of first occurrence of given fstype */
static char *find_fs_mount(const char *fs_to_find)
{
@ -364,3 +339,4 @@ char *get_task_name(pid_t pid)
return comm;
}

View File

@ -718,8 +718,7 @@ int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n)
return sendmsg(rth->fd, &msg, 0);
}
static int rtnl_dump_done(struct nlmsghdr *h,
const struct rtnl_dump_filter_arg *a)
static int rtnl_dump_done(struct nlmsghdr *h)
{
int len = *(int *)NLMSG_DATA(h);
@ -729,15 +728,11 @@ static int rtnl_dump_done(struct nlmsghdr *h,
}
if (len < 0) {
errno = -len;
if (a->errhndlr && (a->errhndlr(h, a->arg2) & RTNL_SUPPRESS_NLMSG_DONE_NLERR))
return 0;
/* check for any messages returned from kernel */
if (nl_dump_ext_ack_done(h, len))
return len;
errno = -len;
switch (errno) {
case ENOENT:
case EOPNOTSUPP:
@ -758,9 +753,8 @@ static int rtnl_dump_done(struct nlmsghdr *h,
return 0;
}
static int rtnl_dump_error(const struct rtnl_handle *rth,
struct nlmsghdr *h,
const struct rtnl_dump_filter_arg *a)
static void rtnl_dump_error(const struct rtnl_handle *rth,
struct nlmsghdr *h)
{
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
@ -772,16 +766,11 @@ static int rtnl_dump_error(const struct rtnl_handle *rth,
if (rth->proto == NETLINK_SOCK_DIAG &&
(errno == ENOENT ||
errno == EOPNOTSUPP))
return -1;
if (a->errhndlr && (a->errhndlr(h, a->arg2) & RTNL_SUPPRESS_NLMSG_ERROR_NLERR))
return 0;
return;
if (!(rth->flags & RTNL_HANDLE_F_SUPPRESS_NLERR))
perror("RTNETLINK answers");
}
return -1;
}
static int __rtnl_recvmsg(int fd, struct msghdr *msg, int flags)
@ -890,7 +879,7 @@ static int rtnl_dump_filter_l(struct rtnl_handle *rth,
dump_intr = 1;
if (h->nlmsg_type == NLMSG_DONE) {
err = rtnl_dump_done(h, a);
err = rtnl_dump_done(h);
if (err < 0) {
free(buf);
return -1;
@ -901,13 +890,9 @@ static int rtnl_dump_filter_l(struct rtnl_handle *rth,
}
if (h->nlmsg_type == NLMSG_ERROR) {
err = rtnl_dump_error(rth, h, a);
if (err < 0) {
free(buf);
return -1;
}
goto skip_it;
rtnl_dump_error(rth, h);
free(buf);
return -1;
}
if (!rth->dump_fp) {
@ -943,34 +928,12 @@ skip_it:
}
int rtnl_dump_filter_nc(struct rtnl_handle *rth,
rtnl_filter_t filter,
void *arg1, __u16 nc_flags)
{
const struct rtnl_dump_filter_arg a[] = {
{
.filter = filter, .arg1 = arg1,
.nc_flags = nc_flags,
},
{ },
};
return rtnl_dump_filter_l(rth, a);
}
int rtnl_dump_filter_errhndlr_nc(struct rtnl_handle *rth,
rtnl_filter_t filter,
void *arg1,
rtnl_err_hndlr_t errhndlr,
void *arg2,
__u16 nc_flags)
void *arg1, __u16 nc_flags)
{
const struct rtnl_dump_filter_arg a[] = {
{
.filter = filter, .arg1 = arg1,
.errhndlr = errhndlr, .arg2 = arg2,
.nc_flags = nc_flags,
},
{ },
const struct rtnl_dump_filter_arg a[2] = {
{ .filter = filter, .arg1 = arg1, .nc_flags = nc_flags, },
{ .filter = NULL, .arg1 = NULL, .nc_flags = 0, },
};
return rtnl_dump_filter_l(rth, a);
@ -1175,16 +1138,16 @@ int rtnl_listen(struct rtnl_handle *rtnl,
char buf[16384];
char cmsgbuf[BUFSIZ];
if (rtnl->flags & RTNL_HANDLE_F_LISTEN_ALL_NSID) {
msg.msg_control = &cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
}
iov.iov_base = buf;
while (1) {
struct rtnl_ctrl_data ctrl;
struct cmsghdr *cmsg;
if (rtnl->flags & RTNL_HANDLE_F_LISTEN_ALL_NSID) {
msg.msg_control = &cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
}
iov.iov_len = sizeof(buf);
status = recvmsg(rtnl->fd, &msg, 0);

View File

@ -39,12 +39,6 @@ const char *ll_addr_n2a(const unsigned char *addr, int alen, int type,
if (alen == 16 && (type == ARPHRD_TUNNEL6 || type == ARPHRD_IP6GRE))
return inet_ntop(AF_INET6, addr, buf, blen);
if (alen == 7 && type == ARPHRD_AX25)
return ax25_ntop(AF_AX25, addr, buf, blen);
if (alen == 7 && type == ARPHRD_NETROM)
return netrom_ntop(AF_NETROM, addr, buf, blen);
if (alen == 5 && type == ARPHRD_ROSE)
return rose_ntop(AF_ROSE, addr, buf, blen);
snprintf(buf, blen, "%02x", addr[0]);
for (i = 1, l = 2; i < alen && l < blen; i++, l += 3)

View File

@ -1,23 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <sys/socket.h>
#include <errno.h>
#include <linux/ax25.h>
#include "utils.h"
const char *ax25_ntop1(const ax25_address *src, char *dst, socklen_t size);
const char *netrom_ntop(int af, const void *addr, char *buf, socklen_t buflen)
{
switch (af) {
case AF_NETROM:
errno = 0;
return ax25_ntop1((ax25_address *)addr, buf, buflen);
default:
errno = EAFNOSUPPORT;
}
return NULL;
}

View File

@ -1,56 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/sockios.h>
#include <linux/rose.h>
#include "rt_names.h"
#include "utils.h"
static const char *rose_ntop1(const rose_address *src, char *dst,
socklen_t size)
{
char *p = dst;
int i;
if (size < 10)
return NULL;
for (i = 0; i < 5; i++) {
*p++ = '0' + ((src->rose_addr[i] >> 4) & 0xf);
*p++ = '0' + ((src->rose_addr[i] ) & 0xf);
}
if (size == 10)
return dst;
*p = '\0';
return dst;
}
const char *rose_ntop(int af, const void *addr, char *buf, socklen_t buflen)
{
switch (af) {
case AF_ROSE:
errno = 0;
return rose_ntop1((rose_address *)addr, buf, buflen);
default:
errno = EAFNOSUPPORT;
}
return NULL;
}

View File

@ -540,7 +540,7 @@ static int __get_addr_1(inet_prefix *addr, const char *name, int family)
memset(addr, 0, sizeof(*addr));
if (strcmp(name, "default") == 0) {
if (family == AF_MPLS)
if ((family == AF_DECnet) || (family == AF_MPLS))
return -1;
addr->family = family;
addr->bytelen = af_byte_len(addr->family);
@ -551,7 +551,7 @@ static int __get_addr_1(inet_prefix *addr, const char *name, int family)
if (strcmp(name, "all") == 0 ||
strcmp(name, "any") == 0) {
if (family == AF_MPLS)
if ((family == AF_DECnet) || (family == AF_MPLS))
return -1;
addr->family = family;
addr->bytelen = 0;
@ -636,6 +636,10 @@ int af_bit_len(int af)
return 128;
case AF_INET:
return 32;
case AF_DECnet:
return 16;
case AF_IPX:
return 80;
case AF_MPLS:
return 20;
}
@ -725,6 +729,16 @@ int get_addr_rta(inet_prefix *dst, const struct rtattr *rta, int family)
dst->bytelen = 16;
memcpy(dst->data, data, 16);
break;
case 2:
dst->family = AF_DECnet;
dst->bytelen = 2;
memcpy(dst->data, data, 2);
break;
case 10:
dst->family = AF_IPX;
dst->bytelen = 10;
memcpy(dst->data, data, 10);
break;
default:
return -1;
}
@ -1015,6 +1029,8 @@ int read_family(const char *name)
family = AF_INET6;
else if (strcmp(name, "link") == 0)
family = AF_PACKET;
else if (strcmp(name, "ipx") == 0)
family = AF_IPX;
else if (strcmp(name, "mpls") == 0)
family = AF_MPLS;
else if (strcmp(name, "bridge") == 0)
@ -1030,6 +1046,8 @@ const char *family_name(int family)
return "inet6";
if (family == AF_PACKET)
return "link";
if (family == AF_IPX)
return "ipx";
if (family == AF_MPLS)
return "mpls";
if (family == AF_BRIDGE)
@ -1696,10 +1714,10 @@ int do_batch(const char *name, bool force,
cmdlineno = 0;
while (getcmdline(&line, &len, stdin) != -1) {
char *largv[MAX_ARGS];
char *largv[100];
int largc;
largc = makeargs(line, largv, MAX_ARGS);
largc = makeargs(line, largv, 100);
if (!largc)
continue; /* blank line */

View File

@ -22,7 +22,7 @@ bridge \- show / manipulate bridge addresses and devices
\fB\-s\fR[\fItatistics\fR] |
\fB\-n\fR[\fIetns\fR] name |
\fB\-b\fR[\fIatch\fR] filename |
\fB\-c\fR[\fIolor\fR] |
\fB\-c\fR[\folor\fR] |
\fB\-p\fR[\fIretty\fR] |
\fB\-j\fR[\fIson\fR] |
\fB\-o\fR[\fIneline\fr] }
@ -145,53 +145,13 @@ bridge \- show / manipulate bridge addresses and devices
.B vid
.IR VID " [ "
.B state
.IR STP_STATE " ] [ "
.B mcast_router
.IR MULTICAST_ROUTER " ]"
.IR STP_STATE " ] "
.ti -8
.BR "bridge vlan" " [ " show " | " tunnelshow " ] [ "
.B dev
.IR DEV " ]"
.ti -8
.BR "bridge vlan global set"
.B dev
.I DEV
.B vid
.IR VID " [ "
.B mcast_snooping
.IR MULTICAST_SNOOPING " ] [ "
.B mcast_querier
.IR MULTICAST_QUERIER " ] [ "
.B mcast_igmp_version
.IR IGMP_VERSION " ] [ "
.B mcast_mld_version
.IR MLD_VERSION " ] [ "
.B mcast_last_member_count
.IR LAST_MEMBER_COUNT " ] [ "
.B mcast_last_member_interval
.IR LAST_MEMBER_INTERVAL " ] [ "
.B mcast_startup_query_count
.IR STARTUP_QUERY_COUNT " ] [ "
.B mcast_startup_query_interval
.IR STARTUP_QUERY_INTERVAL " ] [ "
.B mcast_membership_interval
.IR MEMBERSHIP_INTERVAL " ] [ "
.B mcast_querier_interval
.IR QUERIER_INTERVAL " ] [ "
.B mcast_query_interval
.IR QUERY_INTERVAL " ] [ "
.B mcast_query_response_interval
.IR QUERY_RESPONSE_INTERVAL " ]"
.ti -8
.BR "bridge vlan global" " [ " show " ] [ "
.B dev
.IR DEV " ] [ "
.B vid
.IR VID " ]"
.ti -8
.BR "bridge monitor" " [ " all " | " neigh " | " link " | " mdb " | " vlan " ]"
@ -917,31 +877,6 @@ is used during the STP election process. In this state, the vlan will only proce
STP BPDUs.
.sp
.TP
.BI mcast_router " MULTICAST_ROUTER "
configure this vlan and interface's multicast router mode, note that only modes
0 - 2 are available for bridge devices.
A vlan and interface with a multicast router will receive all multicast traffic.
.I MULTICAST_ROUTER
may be either
.sp
.B 0
- to disable multicast router.
.sp
.B 1
- to let the system detect the presence of routers (default).
.sp
.B 2
- to permanently enable multicast traffic forwarding on this vlan and interface.
.sp
.B 3
- to temporarily mark this vlan and port as having a multicast router, i.e.
enable multicast traffic forwarding. This mode is available only for ports.
.sp
.SS bridge vlan show - list vlan configuration.
This command displays the current VLAN filter table.
@ -960,98 +895,6 @@ option, the command displays per-vlan traffic statistics.
This command displays the current vlan tunnel info mapping.
.SS bridge vlan global set - change vlan filter entry's global options
This command changes vlan filter entry's global options.
.TP
.BI dev " NAME"
the interface with which this vlan is associated. Only bridge devices are
supported for global options.
.TP
.BI vid " VID"
the VLAN ID that identifies the vlan.
.TP
.BI mcast_snooping " MULTICAST_SNOOPING "
turn multicast snooping for VLAN entry with VLAN ID on
.RI ( MULTICAST_SNOOPING " > 0) "
or off
.RI ( MULTICAST_SNOOPING " == 0). Default is on. "
.TP
.BI mcast_querier " MULTICAST_QUERIER "
enable
.RI ( MULTICAST_QUERIER " > 0) "
or disable
.RI ( MULTICAST_QUERIER " == 0) "
IGMP/MLD querier, ie sending of multicast queries by the bridge. Default is disabled.
.TP
.BI mcast_igmp_version " IGMP_VERSION "
set the IGMP version. Default is 2.
.TP
.BI mcast_mld_version " MLD_VERSION "
set the MLD version. Default is 1.
.TP
.BI mcast_last_member_count " LAST_MEMBER_COUNT "
set multicast last member count, ie the number of queries the bridge
will send before stopping forwarding a multicast group after a "leave"
message has been received. Default is 2.
.TP
.BI mcast_last_member_interval " LAST_MEMBER_INTERVAL "
interval between queries to find remaining members of a group,
after a "leave" message is received.
.TP
.BI mcast_startup_query_count " STARTUP_QUERY_COUNT "
set the number of queries to send during startup phase. Default is 2.
.TP
.BI mcast_startup_query_interval " STARTUP_QUERY_INTERVAL "
interval between queries in the startup phase.
.TP
.BI mcast_membership_interval " MEMBERSHIP_INTERVAL "
delay after which the bridge will leave a group,
if no membership reports for this group are received.
.TP
.BI mcast_querier_interval " QUERIER_INTERVAL "
interval between queries sent by other routers. If no queries are seen
after this delay has passed, the bridge will start to send its own queries
(as if
.BI mcast_querier
was enabled).
.TP
.BI mcast_query_interval " QUERY_INTERVAL "
interval between queries sent by the bridge after the end of the
startup phase.
.TP
.BI mcast_query_response_interval " QUERY_RESPONSE_INTERVAL "
set the Max Response Time/Maximum Response Delay for IGMP/MLD
queries sent by the bridge.
.SS bridge vlan global show - list global vlan options.
This command displays the global VLAN options for each VLAN entry.
.TP
.BI dev " DEV"
the interface only whose VLAN global options should be listed. Default is to list
all bridge interfaces.
.TP
.BI vid " VID"
the VLAN ID only whose global options should be listed. Default is to list
all vlans.
.SH bridge monitor - state monitoring
The

View File

@ -45,17 +45,15 @@ devlink-port \- devlink port configuration
.ti -8
.BI "devlink port add"
.RB "{"
.RB "["
.IR "DEV | DEV/PORT_INDEX"
.RB "} "
.RB "] "
.RB "[ " flavour
.IR FLAVOUR " ]"
.RB "[ " pfnum
.RB "[ " pcipf
.IR PFNUMBER " ]"
.RB "[ " sfnum
.IR SFNUMBER " ]"
.RB "[ " controller
.IR CNUM " ]"
.RB "{ " pcisf
.IR SFNUMBER " }"
.br
.ti -8
@ -65,16 +63,12 @@ devlink-port \- devlink port configuration
.ti -8
.BR "devlink port function set "
.IR DEV/PORT_INDEX
.RI "[ "
.RI "{ "
.BR "hw_addr "
.RI "ADDR ]"
.RI "[ "
.BR state " { " active " | " inactive " }"
.RI "]"
.ti -8
.BR "devlink port function rate "
.RI "{ " show " | " set " | " add " | " del " | " help " }"
.RI "ADDR }"
.RI "{ "
.BR "state"
.RI "STATE }"
.ti -8
.B devlink dev param set
@ -100,7 +94,7 @@ devlink-port \- devlink port configuration
.SS devlink port set - change devlink port attributes
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.in +4
@ -124,7 +118,7 @@ set port type
.SS devlink port split - split devlink port into more
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.TP
@ -135,7 +129,7 @@ number of ports to split to.
Could be performed on any split port of the same split group.
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.SS devlink port show - display devlink port attributes
@ -152,13 +146,13 @@ Is an alias for
.ti -8
.SS devlink port add - add a devlink port
.PP
.I "DEV"
.B "DEV"
- specifies the devlink device to operate on. or
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port index to use for the requested new port.
This is optional. When omitted, driver allocates unique port index.
This is optional. When ommited, driver allocates unique port index.
.TP
.BR flavour " { " pcipf " | " pcisf " } "
@ -171,36 +165,30 @@ set port flavour
- PCI SF port
.TP
.BI pfnum " PFNUMBER "
.BR pfnum " { " pfnumber " } "
Specifies PCI pfnumber to use on which a SF device to create
.TP
.BI sfnum " SFNUMBER "
.BR sfnum " { " sfnumber " } "
Specifies sfnumber to assign to the device of the SF.
This field is optional for those devices which supports auto assignment of the
SF number.
.TP
.BI controller " CNUM "
Specifies controller number for which the SF port is created.
This field is optional. It is used only when SF port is created for the
external controller.
.ti -8
.SS devlink port function set - Set the port function attribute(s).
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.TP
.BI hw_addr " ADDR"
Hardware address of the function to set. This is a Ethernet MAC address when
.BR hw_addr " ADDR"
- hardware address of the function to set. This is a Ethernet MAC address when
port type is Ethernet.
.TP
.BR state " { " active " | " inactive " } "
New state of the function to change to.
- new state of the function to change to.
.I active
- Once configuration of the function is done, activate the function.
@ -211,13 +199,13 @@ New state of the function to change to.
.ti -8
.SS devlink port del - delete a devlink port
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to delete.
.ti -8
.SS devlink port param set - set new value to devlink port configuration parameter
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.TP
@ -244,7 +232,7 @@ Configuration mode in which the new value is set.
.SS devlink port param show - display devlink port supported configuration parameters attributes
.PP
.I "DEV/PORT_INDEX"
.B "DEV/PORT_INDEX"
- specifies the devlink port to operate on.
.B name
@ -252,10 +240,6 @@ Configuration mode in which the new value is set.
Specify parameter name to show.
If this argument, as well as port index, are omitted - all parameters supported by devlink device ports are listed.
.SS devlink port function rate - manage devlink rate objects
Is an alias for
.BR devlink-rate (8).
.SH "EXAMPLES"
.PP
devlink port show
@ -343,17 +327,6 @@ devlink dev param set pci/0000:01:00.0/1 name internal_error_reset value true cm
.RS 4
Sets the parameter internal_error_reset of specified devlink port (#1) to true.
.RE
.PP
devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88 controller 1
.RS 4
Add a devlink port of flavour PCI SF on controller 1 which has PCI PF of number
0 with SF number 88. To make use of the function an example sequence is to add
a port, configure the function attribute and activate the function. Once
the function usage is completed, deactivate the function and finally delete
the port. When there is desire to reuse the port without deletion, it can be
reconfigured and activated again when function is in inactive state and
function's operational state is detached.
.RE
.SH SEE ALSO
.BR devlink (8),

Some files were not shown because too many files have changed in this diff Show More