Merge branch 'main' into next
Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
commit
b78c480532
|
|
@ -678,7 +678,7 @@ _devlink_trap_set_action()
|
|||
COMPREPLY=( $( compgen -W "action" -- "$cur" ) )
|
||||
;;
|
||||
$((7 + $i)))
|
||||
COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "trap drop mirror" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ _devlink_trap_group_set()
|
|||
|
||||
case $prev in
|
||||
action)
|
||||
COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "trap drop mirror" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
policer)
|
||||
|
|
|
|||
|
|
@ -635,10 +635,16 @@ static int fdb_get(int argc, char **argv)
|
|||
if (rtnl_talk(&rth, &req.n, &answer) < 0)
|
||||
return -2;
|
||||
|
||||
/*
|
||||
* Initialize a json_writer and open an array object
|
||||
* if -json was specified.
|
||||
*/
|
||||
new_json_obj(json);
|
||||
if (print_fdb(answer, stdout) < 0) {
|
||||
fprintf(stderr, "An error :-)\n");
|
||||
return -1;
|
||||
}
|
||||
delete_json_obj();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ typedef unsigned short ip_set_id_t;
|
|||
#include <linux/netfilter/xt_set.h>
|
||||
|
||||
struct xt_set_info info;
|
||||
#if IPSET_PROTOCOL == 6
|
||||
#if IPSET_PROTOCOL == 6 || IPSET_PROTOCOL == 7
|
||||
int main(void)
|
||||
{
|
||||
return IPSET_MAXNAMELEN;
|
||||
|
|
|
|||
|
|
@ -19,19 +19,26 @@
|
|||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#define _LINUX_SYSINFO_H /* avoid collision with musl header */
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/devlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <rt_names.h>
|
||||
|
||||
#include "SNAPSHOT.h"
|
||||
#include "list.h"
|
||||
#include "mnlg.h"
|
||||
#include "json_writer.h"
|
||||
#include "json_print.h"
|
||||
#include "utils.h"
|
||||
#include "namespace.h"
|
||||
|
||||
|
|
@ -1298,6 +1305,8 @@ static int trap_action_get(const char *actionstr,
|
|||
*p_action = DEVLINK_TRAP_ACTION_DROP;
|
||||
} else if (strcmp(actionstr, "trap") == 0) {
|
||||
*p_action = DEVLINK_TRAP_ACTION_TRAP;
|
||||
} else if (strcmp(actionstr, "mirror") == 0) {
|
||||
*p_action = DEVLINK_TRAP_ACTION_MIRROR;
|
||||
} else {
|
||||
pr_err("Unknown trap action \"%s\"\n", actionstr);
|
||||
return -EINVAL;
|
||||
|
|
@ -2417,6 +2426,11 @@ static const struct param_val_conv param_val_conv[] = {
|
|||
.vstr = "flash",
|
||||
.vuint = DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
|
||||
},
|
||||
{
|
||||
.name = "fw_load_policy",
|
||||
.vstr = "disk",
|
||||
.vuint = DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK,
|
||||
},
|
||||
{
|
||||
.name = "reset_dev_on_drv_probe",
|
||||
.vstr = "unknown",
|
||||
|
|
@ -7209,6 +7223,8 @@ static const char *trap_type_name(uint8_t type)
|
|||
return "drop";
|
||||
case DEVLINK_TRAP_TYPE_EXCEPTION:
|
||||
return "exception";
|
||||
case DEVLINK_TRAP_TYPE_CONTROL:
|
||||
return "control";
|
||||
default:
|
||||
return "<unknown type>";
|
||||
}
|
||||
|
|
@ -7221,6 +7237,8 @@ static const char *trap_action_name(uint8_t action)
|
|||
return "drop";
|
||||
case DEVLINK_TRAP_ACTION_TRAP:
|
||||
return "trap";
|
||||
case DEVLINK_TRAP_ACTION_MIRROR:
|
||||
return "mirror";
|
||||
default:
|
||||
return "<unknown action>";
|
||||
}
|
||||
|
|
@ -7295,9 +7313,9 @@ static int cmd_trap_show_cb(const struct nlmsghdr *nlh, void *data)
|
|||
|
||||
static void cmd_trap_help(void)
|
||||
{
|
||||
pr_err("Usage: devlink trap set DEV trap TRAP [ action { trap | drop } ]\n");
|
||||
pr_err("Usage: devlink trap set DEV trap TRAP [ action { trap | drop | mirror } ]\n");
|
||||
pr_err(" devlink trap show [ DEV trap TRAP ]\n");
|
||||
pr_err(" devlink trap group set DEV group GROUP [ action { trap | drop } ]\n");
|
||||
pr_err(" devlink trap group set DEV group GROUP [ action { trap | drop | mirror } ]\n");
|
||||
pr_err(" [ policer POLICER ] [ nopolicer ]\n");
|
||||
pr_err(" devlink trap group show [ DEV group GROUP ]\n");
|
||||
pr_err(" devlink trap policer set DEV policer POLICER [ rate RATE ] [ burst BURST ]\n");
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@
|
|||
#ifndef _TC_UTIL_H_
|
||||
#define _TC_UTIL_H_ 1
|
||||
|
||||
#include <linux/genetlink.h>
|
||||
#include "utils.h"
|
||||
#include "linux/genetlink.h"
|
||||
|
||||
struct genl_util
|
||||
{
|
||||
struct genl_util {
|
||||
struct genl_util *next;
|
||||
char name[16];
|
||||
int (*parse_genlopt)(struct genl_util *fu, int argc, char **argv);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ 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
|
||||
ipnexthop.o ipmptcp.o iplink_bareudp.o
|
||||
|
||||
RTMONOBJ=rtmon.o
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/sockios.h>
|
||||
#include <linux/net_namespace.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "rt_names.h"
|
||||
#include "utils.h"
|
||||
#include "ll_map.h"
|
||||
|
|
@ -1257,7 +1256,9 @@ static const struct ifa_flag_data_t {
|
|||
|
||||
/* Returns a pointer to the data structure for a particular interface flag, or null if no flag could be found */
|
||||
static const struct ifa_flag_data_t* lookup_flag_data_by_name(const char* flag_name) {
|
||||
for (int i = 0; i < ARRAY_SIZE(ifa_flag_data); ++i) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ifa_flag_data); ++i) {
|
||||
if (strcmp(flag_name, ifa_flag_data[i].name) == 0)
|
||||
return &ifa_flag_data[i];
|
||||
}
|
||||
|
|
|
|||
10
ip/ipfou.c
10
ip/ipfou.c
|
|
@ -27,10 +27,10 @@
|
|||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: ip fou add port PORT { ipproto PROTO | gue } [ -6 ]\n"
|
||||
"Usage: ip fou add port PORT { ipproto PROTO | gue }\n"
|
||||
" [ local IFADDR ] [ peer IFADDR ]\n"
|
||||
" [ peer_port PORT ] [ dev IFNAME ]\n"
|
||||
" ip fou del port PORT [ -6 ] [ local IFADDR ]\n"
|
||||
" ip fou del port PORT [ local IFADDR ]\n"
|
||||
" [ peer IFADDR ] [ peer_port PORT ]\n"
|
||||
" [ dev IFNAME ]\n"
|
||||
" ip fou show\n"
|
||||
|
|
@ -55,13 +55,17 @@ static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
|
|||
{
|
||||
const char *local = NULL, *peer = NULL;
|
||||
__u16 port, peer_port = 0;
|
||||
__u8 family = AF_INET;
|
||||
__u8 family = preferred_family;
|
||||
bool gue_set = false;
|
||||
int ipproto_set = 0;
|
||||
__u8 ipproto, type;
|
||||
int port_set = 0;
|
||||
int index = 0;
|
||||
|
||||
if (preferred_family == AF_UNSPEC) {
|
||||
family = AF_INET;
|
||||
}
|
||||
|
||||
while (argc > 0) {
|
||||
if (!matches(*argv, "port")) {
|
||||
NEXT_ARG();
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ void iplink_usage(void)
|
|||
" bridge | bond | team | ipoib | ip6tnl | ipip | sit | vxlan |\n"
|
||||
" gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan |\n"
|
||||
" vti | nlmon | team_slave | bond_slave | bridge_slave |\n"
|
||||
" ipvlan | ipvtap | geneve | vrf | macsec | netdevsim | rmnet |\n"
|
||||
" ipvlan | ipvtap | geneve | bareudp | vrf | macsec | netdevsim | rmnet |\n"
|
||||
" xfrm }\n");
|
||||
}
|
||||
exit(-1);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "libnetlink.h"
|
||||
#include "rt_names.h"
|
||||
#include "utils.h"
|
||||
#include "ip_common.h"
|
||||
#include "json_print.h"
|
||||
|
||||
#define BAREUDP_ATTRSET(attrs, type) (((attrs) & (1L << (type))) != 0)
|
||||
|
||||
static void print_explain(FILE *f)
|
||||
{
|
||||
fprintf(f,
|
||||
"Usage: ... bareudp dstport PORT\n"
|
||||
" ethertype PROTO\n"
|
||||
" [ srcportmin PORT ]\n"
|
||||
" [ [no]multiproto ]\n"
|
||||
"\n"
|
||||
"Where: PORT := 0-65535\n"
|
||||
" PROTO := NUMBER | ip | mpls\n"
|
||||
" SRCPORTMIN := 0-65535\n"
|
||||
);
|
||||
}
|
||||
|
||||
static void explain(void)
|
||||
{
|
||||
print_explain(stderr);
|
||||
}
|
||||
|
||||
static void check_duparg(__u64 *attrs, int type, const char *key,
|
||||
const char *argv)
|
||||
{
|
||||
if (!BAREUDP_ATTRSET(*attrs, type)) {
|
||||
*attrs |= (1L << type);
|
||||
return;
|
||||
}
|
||||
duparg2(key, argv);
|
||||
}
|
||||
|
||||
static int bareudp_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||
struct nlmsghdr *n)
|
||||
{
|
||||
bool multiproto = false;
|
||||
__u16 srcportmin = 0;
|
||||
__be16 ethertype = 0;
|
||||
__be16 dstport = 0;
|
||||
__u64 attrs = 0;
|
||||
|
||||
while (argc > 0) {
|
||||
if (matches(*argv, "dstport") == 0) {
|
||||
NEXT_ARG();
|
||||
check_duparg(&attrs, IFLA_BAREUDP_PORT, "dstport",
|
||||
*argv);
|
||||
if (get_be16(&dstport, *argv, 0))
|
||||
invarg("dstport", *argv);
|
||||
} else if (matches(*argv, "ethertype") == 0) {
|
||||
NEXT_ARG();
|
||||
check_duparg(&attrs, IFLA_BAREUDP_ETHERTYPE,
|
||||
"ethertype", *argv);
|
||||
if (ll_proto_a2n(ðertype, *argv))
|
||||
invarg("ethertype", *argv);
|
||||
} else if (matches(*argv, "srcportmin") == 0) {
|
||||
NEXT_ARG();
|
||||
check_duparg(&attrs, IFLA_BAREUDP_SRCPORT_MIN,
|
||||
"srcportmin", *argv);
|
||||
if (get_u16(&srcportmin, *argv, 0))
|
||||
invarg("srcportmin", *argv);
|
||||
} else if (matches(*argv, "multiproto") == 0) {
|
||||
check_duparg(&attrs, IFLA_BAREUDP_MULTIPROTO_MODE,
|
||||
*argv, *argv);
|
||||
multiproto = true;
|
||||
} else if (matches(*argv, "nomultiproto") == 0) {
|
||||
check_duparg(&attrs, IFLA_BAREUDP_MULTIPROTO_MODE,
|
||||
*argv, *argv);
|
||||
multiproto = false;
|
||||
} else if (matches(*argv, "help") == 0) {
|
||||
explain();
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "bareudp: unknown command \"%s\"?\n",
|
||||
*argv);
|
||||
explain();
|
||||
return -1;
|
||||
}
|
||||
argc--, argv++;
|
||||
}
|
||||
|
||||
if (!BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_PORT))
|
||||
missarg("dstport");
|
||||
if (!BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_ETHERTYPE))
|
||||
missarg("ethertype");
|
||||
|
||||
addattr16(n, 1024, IFLA_BAREUDP_PORT, dstport);
|
||||
addattr16(n, 1024, IFLA_BAREUDP_ETHERTYPE, ethertype);
|
||||
if (BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_SRCPORT_MIN))
|
||||
addattr16(n, 1024, IFLA_BAREUDP_SRCPORT_MIN, srcportmin);
|
||||
if (multiproto)
|
||||
addattr(n, 1024, IFLA_BAREUDP_MULTIPROTO_MODE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bareudp_print_opt(struct link_util *lu, FILE *f,
|
||||
struct rtattr *tb[])
|
||||
{
|
||||
if (!tb)
|
||||
return;
|
||||
|
||||
if (tb[IFLA_BAREUDP_PORT])
|
||||
print_uint(PRINT_ANY, "dstport", "dstport %u ",
|
||||
rta_getattr_be16(tb[IFLA_BAREUDP_PORT]));
|
||||
|
||||
if (tb[IFLA_BAREUDP_ETHERTYPE]) {
|
||||
struct rtattr *attr = tb[IFLA_BAREUDP_ETHERTYPE];
|
||||
SPRINT_BUF(ethertype);
|
||||
|
||||
print_string(PRINT_ANY, "ethertype", "ethertype %s ",
|
||||
ll_proto_n2a(rta_getattr_u16(attr),
|
||||
ethertype, sizeof(ethertype)));
|
||||
}
|
||||
|
||||
if (tb[IFLA_BAREUDP_SRCPORT_MIN])
|
||||
print_uint(PRINT_ANY, "srcportmin", "srcportmin %u ",
|
||||
rta_getattr_u16(tb[IFLA_BAREUDP_SRCPORT_MIN]));
|
||||
|
||||
if (tb[IFLA_BAREUDP_MULTIPROTO_MODE])
|
||||
print_bool(PRINT_ANY, "multiproto", "multiproto ", true);
|
||||
else
|
||||
print_bool(PRINT_ANY, "multiproto", "nomultiproto ", false);
|
||||
}
|
||||
|
||||
static void bareudp_print_help(struct link_util *lu, int argc, char **argv,
|
||||
FILE *f)
|
||||
{
|
||||
print_explain(f);
|
||||
}
|
||||
|
||||
struct link_util bareudp_link_util = {
|
||||
.id = "bareudp",
|
||||
.maxattr = IFLA_BAREUDP_MAX,
|
||||
.parse_opt = bareudp_parse_opt,
|
||||
.print_opt = bareudp_print_opt,
|
||||
.print_help = bareudp_print_help,
|
||||
};
|
||||
|
|
@ -59,6 +59,7 @@ static void usage(void)
|
|||
" [ if_id IF_ID ] [ LIMIT-LIST ] [ TMPL-LIST ]\n"
|
||||
"Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n"
|
||||
" [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n"
|
||||
" [ if_id IF_ID ]\n"
|
||||
"Usage: ip xfrm policy { deleteall | list } [ nosock ] [ SELECTOR ] [ dir DIR ]\n"
|
||||
" [ index INDEX ] [ ptype PTYPE ] [ action ACTION ] [ priority PRIORITY ]\n"
|
||||
" [ flag FLAG-LIST ]\n"
|
||||
|
|
@ -582,6 +583,8 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|||
struct xfrm_user_sec_ctx sctx;
|
||||
char str[CTX_BUF_SIZE];
|
||||
} ctx = {};
|
||||
bool is_if_id_set = false;
|
||||
__u32 if_id = 0;
|
||||
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "dir") == 0) {
|
||||
|
|
@ -619,7 +622,11 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|||
|
||||
NEXT_ARG();
|
||||
xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
|
||||
|
||||
} else if (strcmp(*argv, "if_id") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&if_id, *argv, 0))
|
||||
invarg("IF_ID value is invalid", *argv);
|
||||
is_if_id_set = true;
|
||||
} else {
|
||||
if (selp)
|
||||
invarg("unknown", *argv);
|
||||
|
|
@ -669,6 +676,9 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|||
(void *)&ctx, ctx.sctx.len);
|
||||
}
|
||||
|
||||
if (is_if_id_set)
|
||||
addattr32(&req.n, sizeof(req.buf), XFRMA_IF_ID, if_id);
|
||||
|
||||
if (rtnl_talk(&rth, &req.n, answer) < 0)
|
||||
exit(2);
|
||||
|
||||
|
|
@ -767,6 +777,11 @@ static int xfrm_policy_keep(struct nlmsghdr *n, void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (tb[XFRMA_IF_ID]) {
|
||||
addattr32(new_n, xb->size, XFRMA_IF_ID,
|
||||
rta_getattr_u32(tb[XFRMA_IF_ID]));
|
||||
}
|
||||
|
||||
xb->offset += new_n->nlmsg_len;
|
||||
xb->nlmsg_count++;
|
||||
|
||||
|
|
|
|||
8
lib/fs.c
8
lib/fs.c
|
|
@ -148,10 +148,10 @@ __u64 get_cgroup2_id(const char *path)
|
|||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
if (fhp->handle_bytes != sizeof(__u64)) {
|
||||
fprintf(stderr, "Invalid size of cgroup2 ID\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (fhp->handle_bytes != sizeof(__u64)) {
|
||||
fprintf(stderr, "Invalid size of cgroup2 ID\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(cg_id.bytes, fhp->f_handle, sizeof(__u64));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
|
|||
int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)
|
||||
.SH DESCRIPTION
|
||||
libnetlink provides a higher level interface to
|
||||
.BR rtnetlink(7).
|
||||
.BR rtnetlink (7).
|
||||
The read functions return 0 on success and a negative errno on failure.
|
||||
The send functions return the amount of data sent, or -1 on error.
|
||||
.TP
|
||||
|
|
@ -129,9 +129,9 @@ for parsing. The file should contain raw data as received from a rtnetlink socke
|
|||
The following functions are useful to construct custom rtnetlink messages. For
|
||||
simple database dumping with filtering it is better to use the higher level
|
||||
functions above. See
|
||||
.BR rtnetlink(3)
|
||||
.BR rtnetlink (3)
|
||||
and
|
||||
.BR netlink(3)
|
||||
.BR netlink (3)
|
||||
on how to generate a rtnetlink message. The following utility functions
|
||||
require a continuous buffer that already contains a netlink message header
|
||||
and a rtnetlink request.
|
||||
|
|
@ -194,7 +194,7 @@ netlink/rtnetlink was designed and written by Alexey Kuznetsov.
|
|||
Andi Kleen wrote the man page.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR netlink(7),
|
||||
.BR rtnetlink(7)
|
||||
.BR netlink (7),
|
||||
.BR rtnetlink (7)
|
||||
.br
|
||||
/usr/include/linux/rtnetlink.h
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@ bridge \- show / manipulate bridge addresses and devices
|
|||
\fB\-o\fR[\fIneline\fr] }
|
||||
|
||||
.ti -8
|
||||
.BR "bridge link set"
|
||||
.B "bridge link set"
|
||||
.B dev
|
||||
.IR DEV
|
||||
.IR " [ "
|
||||
.IR DEV " [ "
|
||||
.B cost
|
||||
.IR COST " ] [ "
|
||||
.B priority
|
||||
|
|
@ -108,9 +107,9 @@ bridge \- show / manipulate bridge addresses and devices
|
|||
.ti -8
|
||||
.BR "bridge mdb" " { " add " | " del " } "
|
||||
.B dev
|
||||
.IR DEV
|
||||
.I DEV
|
||||
.B port
|
||||
.IR PORT
|
||||
.I PORT
|
||||
.B grp
|
||||
.IR GROUP " [ "
|
||||
.BR permanent " | " temp " ] [ "
|
||||
|
|
@ -125,10 +124,10 @@ bridge \- show / manipulate bridge addresses and devices
|
|||
.ti -8
|
||||
.BR "bridge vlan" " { " add " | " del " } "
|
||||
.B dev
|
||||
.IR DEV
|
||||
.I DEV
|
||||
.B vid
|
||||
.IR VID " [ "
|
||||
.BR tunnel_info
|
||||
.B tunnel_info
|
||||
.IR TUNNEL_ID " ] [ "
|
||||
.BR pvid " ] [ " untagged " ] [ "
|
||||
.BR self " ] [ " master " ] "
|
||||
|
|
@ -168,7 +167,7 @@ to the specified network namespace
|
|||
Actually it just simplifies executing of:
|
||||
|
||||
.B ip netns exec
|
||||
.IR NETNS
|
||||
.I NETNS
|
||||
.B bridge
|
||||
.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
|
||||
.BR help " }"
|
||||
|
|
@ -185,7 +184,7 @@ Read commands from provided file or standard input and invoke them.
|
|||
First failure will cause termination of bridge command.
|
||||
|
||||
.TP
|
||||
.BR "\-force"
|
||||
.B "\-force"
|
||||
Don't terminate bridge command on errors in batch mode.
|
||||
If there were any errors during execution of the commands, the application
|
||||
return code will be non zero.
|
||||
|
|
@ -395,7 +394,7 @@ bridge FDB.
|
|||
Controls whether a given port will flood unicast traffic for which there is no FDB entry. By default this flag is on.
|
||||
|
||||
.TP
|
||||
.BI hwmode
|
||||
.B hwmode
|
||||
Some network interface cards support HW bridge functionality and they may be
|
||||
configured in different modes. Currently support modes are:
|
||||
|
||||
|
|
@ -419,7 +418,7 @@ instead of multicast. By default this flag is off.
|
|||
This is done by copying the packet per host and
|
||||
changing the multicast destination MAC to a unicast one accordingly.
|
||||
|
||||
.BR mcast_to_unicast
|
||||
.B mcast_to_unicast
|
||||
works on top of the multicast snooping feature of
|
||||
the bridge. Which means unicast copies are only delivered to hosts which
|
||||
are interested in it and signalized this via IGMP/MLD reports
|
||||
|
|
@ -464,15 +463,15 @@ If the port loses carrier all traffic will be redirected to the
|
|||
configured backup port
|
||||
|
||||
.TP
|
||||
.BR nobackup_port
|
||||
.B nobackup_port
|
||||
Removes the currently configured backup port
|
||||
|
||||
.TP
|
||||
.BI self
|
||||
.B self
|
||||
link setting is configured on specified physical device
|
||||
|
||||
.TP
|
||||
.BI master
|
||||
.B master
|
||||
link setting is configured on the software bridge (default)
|
||||
|
||||
.TP
|
||||
|
|
@ -501,7 +500,7 @@ and delete old ones.
|
|||
This command creates a new fdb entry.
|
||||
|
||||
.TP
|
||||
.BI "LLADDR"
|
||||
.B LLADDR
|
||||
the Ethernet MAC address.
|
||||
|
||||
.TP
|
||||
|
|
@ -633,7 +632,7 @@ and last used time for each entry.
|
|||
lookup a bridge forwarding table entry.
|
||||
|
||||
.TP
|
||||
.BI "LLADDR"
|
||||
.B LLADDR
|
||||
the Ethernet MAC address.
|
||||
|
||||
.TP
|
||||
|
|
@ -757,21 +756,21 @@ dst_metadata for every packet that belongs to this vlan (applicable to
|
|||
bridge ports with vlan_tunnel flag set).
|
||||
|
||||
.TP
|
||||
.BI pvid
|
||||
.B pvid
|
||||
the vlan specified is to be considered a PVID at ingress.
|
||||
Any untagged frames will be assigned to this VLAN.
|
||||
|
||||
.TP
|
||||
.BI untagged
|
||||
.B untagged
|
||||
the vlan specified is to be treated as untagged on egress.
|
||||
|
||||
.TP
|
||||
.BI self
|
||||
.B self
|
||||
the vlan is configured on the specified physical device. Required if the
|
||||
device is the bridge device.
|
||||
|
||||
.TP
|
||||
.BI master
|
||||
.B master
|
||||
the vlan is configured on the software bridge (default).
|
||||
|
||||
.SS bridge vlan delete - delete a vlan filter entry
|
||||
|
|
|
|||
|
|
@ -26,61 +26,60 @@ devlink-dev \- devlink device configuration
|
|||
.B devlink dev help
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev eswitch set"
|
||||
.IR DEV
|
||||
.RI "[ "
|
||||
.B devlink dev eswitch set
|
||||
.I DEV
|
||||
[
|
||||
.BR mode " { " legacy " | " switchdev " } "
|
||||
.RI "]"
|
||||
.RI "[ "
|
||||
] [
|
||||
.BR inline-mode " { " none " | " link " | " network " | " transport " } "
|
||||
.RI "]"
|
||||
.RI "[ "
|
||||
] [
|
||||
.BR encap-mode " { " none " | " basic " } "
|
||||
.RI "]"
|
||||
]
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev eswitch show"
|
||||
.IR DEV
|
||||
.B devlink dev eswitch show
|
||||
.I DEV
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev param set"
|
||||
.IR DEV
|
||||
.BR name
|
||||
.IR PARAMETER
|
||||
.BR value
|
||||
.IR VALUE
|
||||
.B devlink dev param set
|
||||
.I DEV
|
||||
.B name
|
||||
.I PARAMETER
|
||||
.B value
|
||||
.I VALUE
|
||||
.BR cmode " { " runtime " | " driverinit " | " permanent " } "
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev param show"
|
||||
.RI "[ "
|
||||
.IR DEV
|
||||
.BR name
|
||||
.IR PARAMETER
|
||||
.RI "]"
|
||||
.B devlink dev param show
|
||||
[
|
||||
.I DEV
|
||||
.B name
|
||||
.I PARAMETER
|
||||
]
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev reload"
|
||||
.IR DEV
|
||||
.RI "[ "
|
||||
.BI "netns { " PID " | " NAME " | " ID " }
|
||||
.RI "]"
|
||||
.B devlink dev reload
|
||||
.I DEV
|
||||
[
|
||||
.B netns
|
||||
.RI "{ " PID " | " NAME " | " ID " }"
|
||||
]
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev info"
|
||||
.RI "[ "
|
||||
.IR DEV
|
||||
.RI "]"
|
||||
.B devlink dev info
|
||||
[
|
||||
.I DEV
|
||||
]
|
||||
|
||||
.ti -8
|
||||
.BR "devlink dev flash"
|
||||
.IR DEV
|
||||
.BR file
|
||||
.IR PATH
|
||||
.RI "["
|
||||
.BR target
|
||||
.IR ID
|
||||
.RI "]"
|
||||
.B devlink dev flash
|
||||
.I DEV
|
||||
.B file
|
||||
.I PATH
|
||||
[
|
||||
.B target
|
||||
.I ID
|
||||
]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.SS devlink dev show - display devlink device attributes
|
||||
|
|
@ -159,8 +158,8 @@ Configuration mode in which the new value is set.
|
|||
|
||||
.SS devlink dev param show - display devlink device supported configuration parameters attributes
|
||||
|
||||
.BR name
|
||||
.IR PARAMETER
|
||||
.B name
|
||||
.I PARAMETER
|
||||
Specify parameter name to show.
|
||||
If this argument is omitted all parameters supported by devlink devices are listed.
|
||||
|
||||
|
|
@ -170,8 +169,8 @@ If this argument is omitted all parameters supported by devlink devices are list
|
|||
.I "DEV"
|
||||
- Specifies the devlink device to reload.
|
||||
|
||||
.BR netns
|
||||
.BI { " PID " | " NAME " | " ID " }
|
||||
.B netns
|
||||
.RI { " PID " | " NAME " | " ID " }
|
||||
- Specifies the network namespace to reload into, either by pid, name or id.
|
||||
|
||||
.SS devlink dev info - display device information.
|
||||
|
|
@ -200,13 +199,13 @@ If this argument is omitted all devices are listed.
|
|||
.I "DEV"
|
||||
- specifies the devlink device to write to.
|
||||
|
||||
.BR file
|
||||
.B file
|
||||
.I PATH
|
||||
- Path to the file which will be written into device's flash. The path needs
|
||||
to be relative to one of the directories searched by the kernel firmware loaded,
|
||||
such as /lib/firmware.
|
||||
|
||||
.BR component
|
||||
.B component
|
||||
.I NAME
|
||||
- If device stores multiple firmware images in non-volatile memory, this
|
||||
parameter may be used to indicate which firmware image should be written.
|
||||
|
|
|
|||
|
|
@ -18,49 +18,47 @@ devlink-health \- devlink health reporting and recovery
|
|||
\fB\-V\fR[\fIersion\fR] }
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health show"
|
||||
.B devlink health show
|
||||
.RI "[ " DEV ""
|
||||
.B reporter
|
||||
.RI ""REPORTER " ] "
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health recover"
|
||||
.B devlink health recover
|
||||
.RI "" DEV ""
|
||||
.B reporter
|
||||
.RI "" REPORTER ""
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health diagnose"
|
||||
.B devlink health diagnose
|
||||
.RI "" DEV ""
|
||||
.B reporter
|
||||
.RI "" REPORTER ""
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health dump show"
|
||||
.B devlink health dump show
|
||||
.RI "" DEV ""
|
||||
.B reporter
|
||||
.RI "" REPORTER ""
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health dump clear"
|
||||
.B devlink health dump clear
|
||||
.RI "" DEV ""
|
||||
.B reporter
|
||||
.RI "" REPORTER ""
|
||||
|
||||
.ti -8
|
||||
.BR "devlink health set"
|
||||
.B devlink health set
|
||||
.RI "" DEV ""
|
||||
.B reporter
|
||||
.RI "" REPORTER ""
|
||||
.RI "[ "
|
||||
[
|
||||
.BI "grace_period " MSEC "
|
||||
.RI "]"
|
||||
.RI "[ "
|
||||
] [
|
||||
.BR auto_recover " { " true " | " false " } "
|
||||
.RI "]"
|
||||
.RI "[ "
|
||||
] [
|
||||
.BR auto_dump " { " true " | " false " } "
|
||||
.RI "]"
|
||||
]
|
||||
|
||||
.ti -8
|
||||
.B devlink health help
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ devlink-trap \- devlink trap configuration
|
|||
|
||||
.ti -8
|
||||
.BI "devlink trap set " DEV " trap " TRAP
|
||||
.RB "[ " action " { " trap " | " drop " } ]"
|
||||
.RB "[ " action " { " trap " | " drop " | " mirror " } ]"
|
||||
|
||||
.ti -8
|
||||
.B "devlink trap group show"
|
||||
|
|
@ -36,7 +36,7 @@ devlink-trap \- devlink trap configuration
|
|||
|
||||
.ti -8
|
||||
.BI "devlink trap group set " DEV " group " GROUP
|
||||
.RB "[ " action " { " trap " | " drop " } ]"
|
||||
.RB "[ " action " { " trap " | " drop " | " mirror " } ]"
|
||||
.br
|
||||
.RB "[ " policer
|
||||
.IB "POLICER " ]
|
||||
|
|
@ -76,7 +76,7 @@ Only applicable if a devlink device is also specified.
|
|||
- specifies the packet trap.
|
||||
|
||||
.TP
|
||||
.BR action " { " trap " | " drop " } "
|
||||
.BR action " { " trap " | " drop " | " mirror " } "
|
||||
packet trap action.
|
||||
|
||||
.I trap
|
||||
|
|
@ -85,6 +85,9 @@ packet trap action.
|
|||
.I drop
|
||||
- the packet is dropped by the underlying device and a copy is not sent to the CPU.
|
||||
|
||||
.I mirror
|
||||
- the packet is forwarded by the underlying device and a copy is sent to the CPU.
|
||||
|
||||
.SS devlink trap group show - display available packet trap groups and their attributes
|
||||
|
||||
.PP
|
||||
|
|
@ -108,14 +111,15 @@ Only applicable if a devlink device is also specified.
|
|||
- specifies the packet trap group.
|
||||
|
||||
.TP
|
||||
.BR action " { " trap " | " drop " } "
|
||||
.BR action " { " trap " | " drop " | " mirror " } "
|
||||
packet trap action. The action is set for all the packet traps member in the
|
||||
trap group. The actions of non-drop traps cannot be changed and are thus
|
||||
skipped.
|
||||
|
||||
.TP
|
||||
.BI policer " POLICER"
|
||||
packet trap policer. The policer to bind to the packet trap group.
|
||||
packet trap policer. The policer to bind to the packet trap group. A value of
|
||||
"0" will unbind the currently bound policer.
|
||||
|
||||
.TP
|
||||
.B nopolicer
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Read commands from provided file or standard input and invoke them.
|
|||
First failure will cause termination of devlink.
|
||||
|
||||
.TP
|
||||
.BR "\-force"
|
||||
.B \-force
|
||||
Don't terminate devlink on errors in batch mode.
|
||||
If there were any errors during execution of the commands, the application return code will be non zero.
|
||||
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ ip-link \- network device configuration
|
|||
.BR ipvtap " |"
|
||||
.BR lowpan " |"
|
||||
.BR geneve " |"
|
||||
.BR bareudp " |"
|
||||
.BR vrf " |"
|
||||
.BR macsec " |"
|
||||
.BR netdevsim " |"
|
||||
|
|
@ -356,6 +357,9 @@ Link types:
|
|||
.BR geneve
|
||||
- GEneric NEtwork Virtualization Encapsulation
|
||||
.sp
|
||||
.BR bareudp
|
||||
- Bare UDP L3 encapsulation support
|
||||
.sp
|
||||
.BR macsec
|
||||
- Interface for IEEE 802.1AE MAC Security (MACsec)
|
||||
.sp
|
||||
|
|
@ -1293,6 +1297,46 @@ options.
|
|||
|
||||
.in -8
|
||||
|
||||
.TP
|
||||
Bareudp Type Support
|
||||
For a link of type
|
||||
.I Bareudp
|
||||
the following additional arguments are supported:
|
||||
|
||||
.BI "ip link add " DEVICE
|
||||
.BI type " bareudp " dstport " PORT " ethertype " ETHERTYPE"
|
||||
[
|
||||
.BI srcportmin " SRCPORTMIN "
|
||||
] [
|
||||
.RB [ no ] multiproto
|
||||
]
|
||||
|
||||
.in +8
|
||||
.sp
|
||||
.BI dstport " PORT"
|
||||
- specifies the destination port for the UDP tunnel.
|
||||
|
||||
.sp
|
||||
.BI ethertype " ETHERTYPE"
|
||||
- specifies the ethertype of the L3 protocol being tunnelled.
|
||||
|
||||
.sp
|
||||
.BI srcportmin " SRCPORTMIN"
|
||||
- selects the lowest value of the UDP tunnel source port range.
|
||||
|
||||
.sp
|
||||
.RB [ no ] multiproto
|
||||
- activates support for protocols similar to the one
|
||||
.RB "specified by " ethertype .
|
||||
When
|
||||
.I ETHERTYPE
|
||||
is "mpls_uc" (that is, unicast MPLS), this allows the tunnel to also handle
|
||||
multicast MPLS.
|
||||
When
|
||||
.I ETHERTYPE
|
||||
is "ipv4", this allows the tunnel to also handle IPv6. This option is disabled
|
||||
by default.
|
||||
|
||||
.TP
|
||||
MACVLAN and MACVTAP Type Support
|
||||
For a link of type
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ ip-xfrm \- transform configuration
|
|||
.IR EXTRA-FLAG-LIST " ]"
|
||||
.RB "[ " output-mark
|
||||
.IR OUTPUT-MARK " ]"
|
||||
.RB "[ " if_id
|
||||
.IR IF-ID " ]"
|
||||
|
||||
.ti -8
|
||||
.B "ip xfrm state allocspi"
|
||||
|
|
@ -238,6 +240,8 @@ ip-xfrm \- transform configuration
|
|||
.IR PRIORITY " ]"
|
||||
.RB "[ " flag
|
||||
.IR FLAG-LIST " ]"
|
||||
.RB "[ " if_id
|
||||
.IR IF-ID " ]"
|
||||
.RI "[ " LIMIT-LIST " ] [ " TMPL-LIST " ]"
|
||||
|
||||
.ti -8
|
||||
|
|
@ -255,6 +259,8 @@ ip-xfrm \- transform configuration
|
|||
.IR MASK " ] ]"
|
||||
.RB "[ " ptype
|
||||
.IR PTYPE " ]"
|
||||
.RB "[ " if_id
|
||||
.IR IF-ID " ]"
|
||||
|
||||
.ti -8
|
||||
.BR ip " [ " -4 " | " -6 " ] " "xfrm policy" " { " deleteall " | " list " }"
|
||||
|
|
@ -561,6 +567,10 @@ used to match xfrm policies and states
|
|||
used to set the output mark to influence the routing
|
||||
of the packets emitted by the state
|
||||
|
||||
.TP
|
||||
.I IF-ID
|
||||
xfrm interface identifier used to in both xfrm policies and states
|
||||
|
||||
.sp
|
||||
.PP
|
||||
.TS
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ flower \- flow based traffic control filter
|
|||
.IR PRIORITY " | "
|
||||
.BR cvlan_ethtype " { " ipv4 " | " ipv6 " | "
|
||||
.IR ETH_TYPE " } | "
|
||||
.B mpls
|
||||
.IR LSE_LIST " | "
|
||||
.B mpls_label
|
||||
.IR LABEL " | "
|
||||
.B mpls_tc
|
||||
|
|
@ -96,7 +98,24 @@ flower \- flow based traffic control filter
|
|||
}
|
||||
.IR OPTIONS " | "
|
||||
.BR ip_flags
|
||||
.IR IP_FLAGS
|
||||
.IR IP_FLAGS " }"
|
||||
|
||||
.ti -8
|
||||
.IR LSE_LIST " := [ " LSE_LIST " ] " LSE
|
||||
|
||||
.ti -8
|
||||
.IR LSE " := "
|
||||
.B lse depth
|
||||
.IR DEPTH " { "
|
||||
.B label
|
||||
.IR LABEL " | "
|
||||
.B tc
|
||||
.IR TC " | "
|
||||
.B bos
|
||||
.IR BOS " | "
|
||||
.B ttl
|
||||
.IR TTL " }"
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B flower
|
||||
|
|
@ -182,6 +201,56 @@ Match on QinQ layer three protocol.
|
|||
may be either
|
||||
.BR ipv4 ", " ipv6
|
||||
or an unsigned 16bit value in hexadecimal format.
|
||||
|
||||
.TP
|
||||
.BI mpls " LSE_LIST"
|
||||
Match on the MPLS label stack.
|
||||
.I LSE_LIST
|
||||
is a list of Label Stack Entries, each introduced by the
|
||||
.BR lse " keyword."
|
||||
This option can't be used together with the standalone
|
||||
.BR mpls_label ", " mpls_tc ", " mpls_bos " and " mpls_ttl " options."
|
||||
.RS
|
||||
.TP
|
||||
.BI lse " LSE_OPTIONS"
|
||||
Match on an MPLS Label Stack Entry.
|
||||
.I LSE_OPTIONS
|
||||
is a list of options that describe the properties of the LSE to match.
|
||||
.RS
|
||||
.TP
|
||||
.BI depth " DEPTH"
|
||||
The depth of the Label Stack Entry to consider. Depth starts at 1 (the
|
||||
outermost Label Stack Entry). The maximum usable depth may be limited by the
|
||||
kernel. This option is mandatory.
|
||||
.I DEPTH
|
||||
is an unsigned 8 bit value in decimal format.
|
||||
.TP
|
||||
.BI label " LABEL"
|
||||
Match on the MPLS Label field at the specified
|
||||
.BR depth .
|
||||
.I LABEL
|
||||
is an unsigned 20 bit value in decimal format.
|
||||
.TP
|
||||
.BI tc " TC"
|
||||
Match on the MPLS Traffic Class field at the specified
|
||||
.BR depth .
|
||||
.I TC
|
||||
is an unsigned 3 bit value in decimal format.
|
||||
.TP
|
||||
.BI bos " BOS"
|
||||
Match on the MPLS Bottom Of Stack field at the specified
|
||||
.BR depth .
|
||||
.I BOS
|
||||
is a 1 bit value in decimal format.
|
||||
.TP
|
||||
.BI ttl " TTL"
|
||||
Match on the MPLS Time To Live field at the specified
|
||||
.BR depth .
|
||||
.I TTL
|
||||
is an unsigned 8 bit value in decimal format.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.BI mpls_label " LABEL"
|
||||
Match the label id in the outermost MPLS label stack entry.
|
||||
|
|
@ -393,7 +462,7 @@ on the matches of the next lower layer. Precisely, layer one and two matches
|
|||
(\fBindev\fR, \fBdst_mac\fR and \fBsrc_mac\fR)
|
||||
have no dependency,
|
||||
MPLS and layer three matches
|
||||
(\fBmpls_label\fR, \fBmpls_tc\fR, \fBmpls_bos\fR, \fBmpls_ttl\fR,
|
||||
(\fBmpls\fR, \fBmpls_label\fR, \fBmpls_tc\fR, \fBmpls_bos\fR, \fBmpls_ttl\fR,
|
||||
\fBip_proto\fR, \fBdst_ip\fR, \fBsrc_ip\fR, \fBarp_tip\fR, \fBarp_sip\fR,
|
||||
\fBarp_op\fR, \fBarp_tha\fR, \fBarp_sha\fR and \fBip_flags\fR)
|
||||
depend on the
|
||||
|
|
|
|||
|
|
@ -77,9 +77,13 @@ tc \- show / manipulate traffic control settings
|
|||
.B tc
|
||||
.RI "[ " OPTIONS " ]"
|
||||
.RI "[ " FORMAT " ]"
|
||||
.B qdisc show [ dev
|
||||
.B qdisc { show | list } [ dev
|
||||
\fIDEV\fR
|
||||
.B ]
|
||||
.B ] [ root | ingress | handle
|
||||
\fIQHANDLE\fR
|
||||
.B | parent
|
||||
\fICLASSID\fR
|
||||
.B ] [ invisible ]
|
||||
.P
|
||||
.B tc
|
||||
.RI "[ " OPTIONS " ]"
|
||||
|
|
@ -473,7 +477,7 @@ qdiscs will use all three:
|
|||
tc filters
|
||||
If tc filters are attached to a class, they are consulted first
|
||||
for relevant instructions. Filters can match on all fields of a packet header,
|
||||
as well as on the firewall mark applied by ipchains or iptables.
|
||||
as well as on the firewall mark applied by iptables.
|
||||
.TP
|
||||
Type of Service
|
||||
Some qdiscs have built in rules for classifying packets based on the TOS field.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <fnmatch.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
|
|
|||
221
tc/f_flower.c
221
tc/f_flower.c
|
|
@ -59,6 +59,7 @@ static void explain(void)
|
|||
" ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
|
||||
" ip_tos MASKED-IP_TOS |\n"
|
||||
" ip_ttl MASKED-IP_TTL |\n"
|
||||
" mpls LSE-LIST |\n"
|
||||
" mpls_label LABEL |\n"
|
||||
" mpls_tc TC |\n"
|
||||
" mpls_bos BOS |\n"
|
||||
|
|
@ -89,6 +90,8 @@ static void explain(void)
|
|||
" ct_label MASKED_CT_LABEL |\n"
|
||||
" ct_mark MASKED_CT_MARK |\n"
|
||||
" ct_zone MASKED_CT_ZONE }\n"
|
||||
" LSE-LIST := [ LSE-LIST ] LSE\n"
|
||||
" LSE := lse depth DEPTH { label LABEL | tc TC | bos BOS | ttl TTL }\n"
|
||||
" FILTERID := X:Y:Z\n"
|
||||
" MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
|
||||
" MASKED_CT_STATE := combination of {+|-} and flags trk,est,new\n"
|
||||
|
|
@ -1199,11 +1202,127 @@ static int flower_parse_enc_opts_erspan(char *str, struct nlmsghdr *n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int flower_parse_mpls_lse(int *argc_p, char ***argv_p,
|
||||
struct nlmsghdr *nlh)
|
||||
{
|
||||
struct rtattr *lse_attr;
|
||||
char **argv = *argv_p;
|
||||
int argc = *argc_p;
|
||||
__u8 depth = 0;
|
||||
int ret;
|
||||
|
||||
lse_attr = addattr_nest(nlh, MAX_MSG,
|
||||
TCA_FLOWER_KEY_MPLS_OPTS_LSE | NLA_F_NESTED);
|
||||
|
||||
while (argc > 0) {
|
||||
if (matches(*argv, "depth") == 0) {
|
||||
NEXT_ARG();
|
||||
ret = get_u8(&depth, *argv, 10);
|
||||
if (ret < 0 || depth < 1) {
|
||||
fprintf(stderr, "Illegal \"depth\"\n");
|
||||
return -1;
|
||||
}
|
||||
addattr8(nlh, MAX_MSG,
|
||||
TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH, depth);
|
||||
} else if (matches(*argv, "label") == 0) {
|
||||
__u32 label;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = get_u32(&label, *argv, 10);
|
||||
if (ret < 0 ||
|
||||
label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"label\"\n");
|
||||
return -1;
|
||||
}
|
||||
addattr32(nlh, MAX_MSG,
|
||||
TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL, label);
|
||||
} else if (matches(*argv, "tc") == 0) {
|
||||
__u8 tc;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = get_u8(&tc, *argv, 10);
|
||||
if (ret < 0 ||
|
||||
tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"tc\"\n");
|
||||
return -1;
|
||||
}
|
||||
addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_TC,
|
||||
tc);
|
||||
} else if (matches(*argv, "bos") == 0) {
|
||||
__u8 bos;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = get_u8(&bos, *argv, 10);
|
||||
if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"bos\"\n");
|
||||
return -1;
|
||||
}
|
||||
addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS,
|
||||
bos);
|
||||
} else if (matches(*argv, "ttl") == 0) {
|
||||
__u8 ttl;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = get_u8(&ttl, *argv, 10);
|
||||
if (ret < 0 || ttl & ~(MPLS_LS_TTL_MASK >> MPLS_LS_TTL_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"ttl\"\n");
|
||||
return -1;
|
||||
}
|
||||
addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL,
|
||||
ttl);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
if (!depth) {
|
||||
missarg("depth");
|
||||
return -1;
|
||||
}
|
||||
|
||||
addattr_nest_end(nlh, lse_attr);
|
||||
|
||||
*argc_p = argc;
|
||||
*argv_p = argv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flower_parse_mpls(int *argc_p, char ***argv_p, struct nlmsghdr *nlh)
|
||||
{
|
||||
struct rtattr *mpls_attr;
|
||||
char **argv = *argv_p;
|
||||
int argc = *argc_p;
|
||||
|
||||
mpls_attr = addattr_nest(nlh, MAX_MSG,
|
||||
TCA_FLOWER_KEY_MPLS_OPTS | NLA_F_NESTED);
|
||||
|
||||
while (argc > 0) {
|
||||
if (matches(*argv, "lse") == 0) {
|
||||
NEXT_ARG();
|
||||
if (flower_parse_mpls_lse(&argc, &argv, nlh) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addattr_nest_end(nlh, mpls_attr);
|
||||
|
||||
*argc_p = argc;
|
||||
*argv_p = argv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flower_parse_opt(struct filter_util *qu, char *handle,
|
||||
int argc, char **argv, struct nlmsghdr *n)
|
||||
{
|
||||
int ret;
|
||||
struct tcmsg *t = NLMSG_DATA(n);
|
||||
bool mpls_format_old = false;
|
||||
bool mpls_format_new = false;
|
||||
struct rtattr *tail;
|
||||
__be16 eth_type = TC_H_MIN(t->tcm_info);
|
||||
__be16 vlan_ethtype = 0;
|
||||
|
|
@ -1381,6 +1500,23 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
&cvlan_ethtype, n);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
} else if (matches(*argv, "mpls") == 0) {
|
||||
NEXT_ARG();
|
||||
if (eth_type != htons(ETH_P_MPLS_UC) &&
|
||||
eth_type != htons(ETH_P_MPLS_MC)) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls\" if ethertype isn't MPLS\n");
|
||||
return -1;
|
||||
}
|
||||
if (mpls_format_old) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls\" if \"mpls_label\", \"mpls_tc\", \"mpls_bos\" or \"mpls_ttl\" is set\n");
|
||||
return -1;
|
||||
}
|
||||
mpls_format_new = true;
|
||||
if (flower_parse_mpls(&argc, &argv, n) < 0)
|
||||
return -1;
|
||||
continue;
|
||||
} else if (matches(*argv, "mpls_label") == 0) {
|
||||
__u32 label;
|
||||
|
||||
|
|
@ -1391,6 +1527,12 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
"Can't set \"mpls_label\" if ethertype isn't MPLS\n");
|
||||
return -1;
|
||||
}
|
||||
if (mpls_format_new) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls_label\" if \"mpls\" is set\n");
|
||||
return -1;
|
||||
}
|
||||
mpls_format_old = true;
|
||||
ret = get_u32(&label, *argv, 10);
|
||||
if (ret < 0 || label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"mpls_label\"\n");
|
||||
|
|
@ -1407,6 +1549,12 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
"Can't set \"mpls_tc\" if ethertype isn't MPLS\n");
|
||||
return -1;
|
||||
}
|
||||
if (mpls_format_new) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls_tc\" if \"mpls\" is set\n");
|
||||
return -1;
|
||||
}
|
||||
mpls_format_old = true;
|
||||
ret = get_u8(&tc, *argv, 10);
|
||||
if (ret < 0 || tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"mpls_tc\"\n");
|
||||
|
|
@ -1423,6 +1571,12 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
"Can't set \"mpls_bos\" if ethertype isn't MPLS\n");
|
||||
return -1;
|
||||
}
|
||||
if (mpls_format_new) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls_bos\" if \"mpls\" is set\n");
|
||||
return -1;
|
||||
}
|
||||
mpls_format_old = true;
|
||||
ret = get_u8(&bos, *argv, 10);
|
||||
if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"mpls_bos\"\n");
|
||||
|
|
@ -1439,6 +1593,12 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
"Can't set \"mpls_ttl\" if ethertype isn't MPLS\n");
|
||||
return -1;
|
||||
}
|
||||
if (mpls_format_new) {
|
||||
fprintf(stderr,
|
||||
"Can't set \"mpls_ttl\" if \"mpls\" is set\n");
|
||||
return -1;
|
||||
}
|
||||
mpls_format_old = true;
|
||||
ret = get_u8(&ttl, *argv, 10);
|
||||
if (ret < 0 || ttl & ~(MPLS_LS_TTL_MASK >> MPLS_LS_TTL_SHIFT)) {
|
||||
fprintf(stderr, "Illegal \"mpls_ttl\"\n");
|
||||
|
|
@ -2316,6 +2476,66 @@ static void flower_print_u32(const char *name, struct rtattr *attr)
|
|||
print_uint(PRINT_ANY, name, namefrm, rta_getattr_u32(attr));
|
||||
}
|
||||
|
||||
static void flower_print_mpls_opt_lse(const char *name, struct rtattr *lse)
|
||||
{
|
||||
struct rtattr *tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX + 1];
|
||||
struct rtattr *attr;
|
||||
|
||||
if (lse->rta_type != (TCA_FLOWER_KEY_MPLS_OPTS_LSE | NLA_F_NESTED)) {
|
||||
fprintf(stderr, "rta_type 0x%x, expecting 0x%x (0x%x & 0x%x)\n",
|
||||
lse->rta_type,
|
||||
TCA_FLOWER_KEY_MPLS_OPTS_LSE & NLA_F_NESTED,
|
||||
TCA_FLOWER_KEY_MPLS_OPTS_LSE, NLA_F_NESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_rtattr(tb, TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX, RTA_DATA(lse),
|
||||
RTA_PAYLOAD(lse));
|
||||
|
||||
print_nl();
|
||||
open_json_array(PRINT_ANY, name);
|
||||
attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH];
|
||||
if (attr)
|
||||
print_hhu(PRINT_ANY, "depth", " depth %u",
|
||||
rta_getattr_u8(attr));
|
||||
attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL];
|
||||
if (attr)
|
||||
print_uint(PRINT_ANY, "label", " label %u",
|
||||
rta_getattr_u32(attr));
|
||||
attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TC];
|
||||
if (attr)
|
||||
print_hhu(PRINT_ANY, "tc", " tc %u", rta_getattr_u8(attr));
|
||||
attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS];
|
||||
if (attr)
|
||||
print_hhu(PRINT_ANY, "bos", " bos %u", rta_getattr_u8(attr));
|
||||
attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL];
|
||||
if (attr)
|
||||
print_hhu(PRINT_ANY, "ttl", " ttl %u", rta_getattr_u8(attr));
|
||||
close_json_array(PRINT_JSON, NULL);
|
||||
}
|
||||
|
||||
static void flower_print_mpls_opts(const char *name, struct rtattr *attr)
|
||||
{
|
||||
struct rtattr *lse;
|
||||
int rem;
|
||||
|
||||
if (!attr || !(attr->rta_type & NLA_F_NESTED))
|
||||
return;
|
||||
|
||||
print_nl();
|
||||
open_json_array(PRINT_ANY, name);
|
||||
rem = RTA_PAYLOAD(attr);
|
||||
lse = RTA_DATA(attr);
|
||||
while (RTA_OK(lse, rem)) {
|
||||
flower_print_mpls_opt_lse(" lse", lse);
|
||||
lse = RTA_NEXT(lse, rem);
|
||||
};
|
||||
if (rem)
|
||||
fprintf(stderr, "!!!Deficit %d, rta_len=%d\n",
|
||||
rem, lse->rta_len);
|
||||
close_json_array(PRINT_JSON, NULL);
|
||||
}
|
||||
|
||||
static void flower_print_arp_op(const char *name,
|
||||
struct rtattr *op_attr,
|
||||
struct rtattr *mask_attr)
|
||||
|
|
@ -2430,6 +2650,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
|
|||
flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
|
||||
tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
|
||||
|
||||
flower_print_mpls_opts(" mpls", tb[TCA_FLOWER_KEY_MPLS_OPTS]);
|
||||
flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
|
||||
flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
|
||||
flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
|
||||
|
|
|
|||
|
|
@ -35,11 +35,12 @@ static int usage(void)
|
|||
" [ ingress_block BLOCK_INDEX ] [ egress_block BLOCK_INDEX ]\n"
|
||||
" [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n"
|
||||
"\n"
|
||||
" tc qdisc show [ dev STRING ] [ ingress | clsact ] [ invisible ]\n"
|
||||
" tc qdisc { show | list } [ dev STRING ] [ QDISC_ID ] [ invisible ]\n"
|
||||
"Where:\n"
|
||||
"QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n"
|
||||
"OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help\n"
|
||||
"STAB_OPTIONS := ... try tc qdisc add stab help\n");
|
||||
"STAB_OPTIONS := ... try tc qdisc add stab help\n"
|
||||
"QDISC_ID := { root | ingress | handle QHANDLE | parent CLASSID }\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +213,8 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|||
}
|
||||
|
||||
static int filter_ifindex;
|
||||
static __u32 filter_parent;
|
||||
static __u32 filter_handle;
|
||||
|
||||
int print_qdisc(struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
|
|
@ -235,6 +238,12 @@ int print_qdisc(struct nlmsghdr *n, void *arg)
|
|||
if (filter_ifindex && filter_ifindex != t->tcm_ifindex)
|
||||
return 0;
|
||||
|
||||
if (filter_handle && filter_handle != t->tcm_handle)
|
||||
return 0;
|
||||
|
||||
if (filter_parent && filter_parent != t->tcm_parent)
|
||||
return 0;
|
||||
|
||||
parse_rtattr_flags(tb, TCA_MAX, TCA_RTA(t), len, NLA_F_NESTED);
|
||||
|
||||
if (tb[TCA_KIND] == NULL) {
|
||||
|
|
@ -344,21 +353,55 @@ int print_qdisc(struct nlmsghdr *n, void *arg)
|
|||
|
||||
static int tc_qdisc_list(int argc, char **argv)
|
||||
{
|
||||
struct tcmsg t = { .tcm_family = AF_UNSPEC };
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct tcmsg t;
|
||||
char buf[256];
|
||||
} req = {
|
||||
.n.nlmsg_type = RTM_GETQDISC,
|
||||
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
|
||||
.t.tcm_family = AF_UNSPEC,
|
||||
};
|
||||
|
||||
char d[IFNAMSIZ] = {};
|
||||
bool dump_invisible = false;
|
||||
__u32 handle;
|
||||
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "dev") == 0) {
|
||||
NEXT_ARG();
|
||||
strncpy(d, *argv, sizeof(d)-1);
|
||||
} else if (strcmp(*argv, "root") == 0) {
|
||||
if (filter_parent)
|
||||
invarg("parent is already specified", *argv);
|
||||
else if (filter_handle)
|
||||
invarg("handle is already specified", *argv);
|
||||
filter_parent = TC_H_ROOT;
|
||||
} else if (strcmp(*argv, "ingress") == 0 ||
|
||||
strcmp(*argv, "clsact") == 0) {
|
||||
if (t.tcm_parent) {
|
||||
fprintf(stderr, "Duplicate parent ID\n");
|
||||
usage();
|
||||
}
|
||||
t.tcm_parent = TC_H_INGRESS;
|
||||
strcmp(*argv, "clsact") == 0) {
|
||||
if (filter_parent)
|
||||
invarg("parent is already specified", *argv);
|
||||
else if (filter_handle)
|
||||
invarg("handle is already specified", *argv);
|
||||
filter_parent = TC_H_INGRESS;
|
||||
} else if (matches(*argv, "parent") == 0) {
|
||||
if (filter_parent)
|
||||
invarg("parent is already specified", *argv);
|
||||
else if (filter_handle)
|
||||
invarg("handle is already specified", *argv);
|
||||
NEXT_ARG();
|
||||
if (get_tc_classid(&handle, *argv))
|
||||
invarg("invalid parent ID", *argv);
|
||||
filter_parent = handle;
|
||||
} else if (matches(*argv, "handle") == 0) {
|
||||
if (filter_parent)
|
||||
invarg("parent is already specified", *argv);
|
||||
else if (filter_handle)
|
||||
invarg("handle is already specified", *argv);
|
||||
NEXT_ARG();
|
||||
if (get_qdisc_handle(&handle, *argv))
|
||||
invarg("invalid handle ID", *argv);
|
||||
filter_handle = handle;
|
||||
} else if (matches(*argv, "help") == 0) {
|
||||
usage();
|
||||
} else if (strcmp(*argv, "invisible") == 0) {
|
||||
|
|
@ -374,32 +417,18 @@ static int tc_qdisc_list(int argc, char **argv)
|
|||
ll_init_map(&rth);
|
||||
|
||||
if (d[0]) {
|
||||
t.tcm_ifindex = ll_name_to_index(d);
|
||||
if (!t.tcm_ifindex)
|
||||
req.t.tcm_ifindex = ll_name_to_index(d);
|
||||
if (!req.t.tcm_ifindex)
|
||||
return -nodev(d);
|
||||
filter_ifindex = t.tcm_ifindex;
|
||||
filter_ifindex = req.t.tcm_ifindex;
|
||||
}
|
||||
|
||||
if (dump_invisible) {
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct tcmsg t;
|
||||
char buf[256];
|
||||
} req = {
|
||||
.n.nlmsg_type = RTM_GETQDISC,
|
||||
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
|
||||
};
|
||||
|
||||
req.t.tcm_family = AF_UNSPEC;
|
||||
|
||||
addattr(&req.n, 256, TCA_DUMP_INVISIBLE);
|
||||
if (rtnl_dump_request_n(&rth, &req.n) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
if (rtnl_dump_request_n(&rth, &req.n) < 0) {
|
||||
perror("Cannot send request");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -427,10 +456,6 @@ int do_qdisc(int argc, char **argv)
|
|||
return tc_qdisc_modify(RTM_NEWQDISC, NLM_F_REPLACE, argc-1, argv+1);
|
||||
if (matches(*argv, "delete") == 0)
|
||||
return tc_qdisc_modify(RTM_DELQDISC, 0, argc-1, argv+1);
|
||||
#if 0
|
||||
if (matches(*argv, "get") == 0)
|
||||
return tc_qdisc_get(RTM_GETQDISC, 0, argc-1, argv+1);
|
||||
#endif
|
||||
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|
||||
|| matches(*argv, "lst") == 0)
|
||||
return tc_qdisc_list(argc-1, argv+1);
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ static int cmd_link_get_bcast_cb(const struct nlmsghdr *nlh, void *data)
|
|||
print_string(PRINT_ANY, "method", "%s", "AUTOSELECT");
|
||||
close_json_object();
|
||||
open_json_object(NULL);
|
||||
print_uint(PRINT_ANY, "ratio", " ratio:%u%\n",
|
||||
print_uint(PRINT_ANY, "ratio", " ratio:%u\n",
|
||||
mnl_attr_get_u32(props[prop_ratio]));
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in New Issue