@@ -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 iplink_bareudp.o
+ ipnexthop.o ipmptcp.o iplink_bareudp.o iplink_wwan.o
RTMONOBJ=rtmon.o
@@ -56,7 +56,8 @@ void iplink_types_usage(void)
" ipip | ipoib | ipvlan | ipvtap |\n"
" macsec | macvlan | macvtap |\n"
" netdevsim | nlmon | rmnet | sit | team | team_slave |\n"
- " vcan | veth | vlan | vrf | vti | vxcan | vxlan | xfrm }\n");
+ " vcan | veth | vlan | vrf | vti | vxcan | vxlan | wwan |\n"
+ " xfrm }\n");
}
void iplink_usage(void)
new file mode 100644
@@ -0,0 +1,72 @@
+/* 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,
+};
The WWAN subsystem has been extended to generalize the per data channel network interfaces management. This change implements support for WWAN links handling. And actively uses the earlier introduced ip-link capability to specify the parent by its device name. The WWAN interface for a new data channel should be created with a command like this: ip link add dev wwan0-2 parentdev-name wwan0 type wwan linkid 2 Where: wwan0 is the modem HW device name (should be taken from /sys/class/wwan) and linkid is an identifier of the opened data channel. Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> --- ip/Makefile | 2 +- ip/iplink.c | 3 +- ip/iplink_wwan.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 ip/iplink_wwan.c