iplink_macvlan.o ipl2tp.o link_vti.o link_vti6.o link_xfrm.o \
iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
- iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
+ iplink_bridge.o iplink_bridge_slave.o iplink_dsa.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 \
/* Remember to add new entry here if new type is added. */
fprintf(stderr,
"TYPE := { amt | bareudp | bond | bond_slave | bridge | bridge_slave |\n"
- " dummy | erspan | geneve | gre | gretap | gtp | ifb |\n"
+ " dsa | dummy | erspan | geneve | gre | gretap | gtp | ifb |\n"
" ip6erspan | ip6gre | ip6gretap | ip6tnl |\n"
" ipip | ipoib | ipvlan | ipvtap |\n"
" macsec | macvlan | macvtap |\n"
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * iplink_dsa.c DSA switch support
+ */
+
+#include "utils.h"
+#include "ip_common.h"
+
+static void print_usage(FILE *f)
+{
+ fprintf(f, "Usage: ... dsa [ conduit DEVICE ]\n");
+}
+
+static int dsa_parse_opt(struct link_util *lu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ while (argc > 0) {
+ if (strcmp(*argv, "conduit") == 0 ||
+ strcmp(*argv, "master") == 0) {
+ __u32 ifindex;
+
+ NEXT_ARG();
+ ifindex = ll_name_to_index(*argv);
+ if (!ifindex)
+ invarg("Device does not exist\n", *argv);
+ addattr_l(n, 1024, IFLA_DSA_MASTER, &ifindex, 4);
+ } else if (strcmp(*argv, "help") == 0) {
+ print_usage(stderr);
+ return -1;
+ } else {
+ fprintf(stderr, "dsa: unknown command \"%s\"?\n", *argv);
+ print_usage(stderr);
+ return -1;
+ }
+ argc--;
+ argv++;
+ }
+
+ return 0;
+}
+
+static void dsa_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+ if (!tb)
+ return;
+
+ if (tb[IFLA_DSA_MASTER]) {
+ __u32 conduit = rta_getattr_u32(tb[IFLA_DSA_MASTER]);
+
+ print_string(PRINT_ANY,
+ "conduit", "conduit %s ",
+ ll_index_to_name(conduit));
+ }
+}
+
+static void dsa_print_help(struct link_util *lu, int argc, char **argv,
+ FILE *f)
+{
+ print_usage(f);
+}
+
+struct link_util dsa_link_util = {
+ .id = "dsa",
+ .maxattr = IFLA_DSA_MAX,
+ .parse_opt = dsa_parse_opt,
+ .print_opt = dsa_print_opt,
+ .print_help = dsa_print_help,
+};
.BR bond " | "
.BR bridge " | "
.BR can " | "
+.BR dsa " | "
.BR dummy " | "
.BR erspan " |"
.BR geneve " |"
.B can
- Controller Area Network
.sp
+.B dsa
+- Distributed Switch Architecture
+.sp
.B dummy
- Dummy network interface
.sp
the user understand the setting.
.in -8
+.TP
+DSA user port support
+For a link having the DSA user port type, the following additional arguments
+are supported:
+
+.B "ip link set type dsa "
+[
+.BI conduit " DEVICE"
+]
+
+.in +8
+.sp
+.BI conduit " DEVICE"
+- change the DSA conduit (host network interface) responsible for handling the
+locally terminated traffic for the given DSA switch user port. For a
+description of which network interfaces are suitable for serving as conduit
+interfaces of this user port, please see
+https://www.kernel.org/doc/html/latest/networking/dsa/configuration.html#affinity-of-user-ports-to-cpu-ports
+as well as what is supported by the driver in use.
+
+.sp
+.BI master " DEVICE"
+- this is a synonym for "conduit".
+
+.in -8
+
.SS ip link show - display device attributes
.TP
.RS 4
Creates a IP6ERSPAN version 2 interface named ip6erspan00.
.RE
+.PP
+ip link set dev swp0 type dsa conduit eth1
+.RS 4
+Changes the conduit interface of the swp0 user port to eth1.
+.RE
.SH SEE ALSO
.br