diff --git a/etc/iproute2/rt_protos b/etc/iproute2/rt_protos index 2a9ee01b..b3a0ec8f 100644 --- a/etc/iproute2/rt_protos +++ b/etc/iproute2/rt_protos @@ -16,3 +16,8 @@ 15 ntk 16 dhcp 42 babel +186 bgp +187 isis +188 ospf +189 rip +192 eigrp diff --git a/ip/Makefile b/ip/Makefile index 77fadeed..a88f9366 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -10,7 +10,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.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_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ - ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o + ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o RTMONOBJ=rtmon.o diff --git a/ip/ipaddress.c b/ip/ipaddress.c index bbd35e79..5009bfe6 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -2065,6 +2065,16 @@ static bool ipaddr_is_multicast(inet_prefix *a) return false; } +static bool is_valid_label(const char *dev, const char *label) +{ + size_t len = strlen(dev); + + if (strncmp(label, dev, len) != 0) + return false; + + return label[len] == '\0' || label[len] == ':'; +} + static int ipaddr_modify(int cmd, int flags, int argc, char **argv) { struct { @@ -2208,8 +2218,10 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); return -1; } - if (l && matches(d, l) != 0) { - fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); + if (l && !is_valid_label(d, l)) { + fprintf(stderr, + "\"label\" (%s) must match \"dev\" (%s) or be prefixed by \"dev\" with a colon.\n", + l, d); return -1; } diff --git a/ip/iplink.c b/ip/iplink.c index e4d4da96..0ba5f1af 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -121,7 +121,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 | ipvlan | geneve |\n" - " bridge_slave | vrf | macsec | netdevsim }\n"); + " bridge_slave | vrf | macsec | netdevsim | rmnet }\n"); } exit(-1); } diff --git a/ip/iplink_rmnet.c b/ip/iplink_rmnet.c new file mode 100644 index 00000000..1d16440c --- /dev/null +++ b/ip/iplink_rmnet.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * iplink_rmnet.c RMNET device support + * + * Authors: Daniele Palmas + */ + +#include +#include +#include + +#include "utils.h" +#include "ip_common.h" + +static void print_explain(FILE *f) +{ + fprintf(f, + "Usage: ... rmnet mux_id MUXID\n" + "\n" + "MUXID := 1-254\n" + ); +} + +static void explain(void) +{ + print_explain(stderr); +} + +static int rmnet_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + __u16 mux_id; + + while (argc > 0) { + if (matches(*argv, "mux_id") == 0) { + NEXT_ARG(); + if (get_u16(&mux_id, *argv, 0)) + invarg("mux_id is invalid", *argv); + addattr16(n, 1024, IFLA_RMNET_MUX_ID, mux_id); + } else if (matches(*argv, "help") == 0) { + explain(); + return -1; + } else { + fprintf(stderr, "rmnet: unknown command \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +static void rmnet_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) +{ + if (!tb) + return; + + if (!tb[IFLA_RMNET_MUX_ID] || + RTA_PAYLOAD(tb[IFLA_RMNET_MUX_ID]) < sizeof(__u16)) + return; + + print_uint(PRINT_ANY, + "mux_id", + "mux_id %u ", + rta_getattr_u16(tb[IFLA_RMNET_MUX_ID])); +} + +static void rmnet_print_help(struct link_util *lu, int argc, char **argv, + FILE *f) +{ + print_explain(f); +} + +struct link_util rmnet_link_util = { + .id = "rmnet", + .maxattr = IFLA_RMNET_MAX, + .parse_opt = rmnet_parse_opt, + .print_opt = rmnet_print_opt, + .print_help = rmnet_print_help, +}; diff --git a/lib/rt_names.c b/lib/rt_names.c index a02db35e..66d5f2f0 100644 --- a/lib/rt_names.c +++ b/lib/rt_names.c @@ -134,6 +134,11 @@ static char *rtnl_rtprot_tab[256] = { [RTPROT_XORP] = "xorp", [RTPROT_NTK] = "ntk", [RTPROT_DHCP] = "dhcp", + [RTPROT_BGP] = "bgp", + [RTPROT_ISIS] = "isis", + [RTPROT_OSPF] = "ospf", + [RTPROT_RIP] = "rip", + [RTPROT_EIGRP] = "eigrp", }; diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 83ef3cae..fd2c1071 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -219,7 +219,8 @@ ip-link \- network device configuration .BR geneve " |" .BR vrf " |" .BR macsec " |" -.BR netdevsim " ]" +.BR netdevsim " |" +.BR rmnet " ]" .ti -8 .IR ETYPE " := [ " TYPE " |" @@ -342,6 +343,9 @@ Link types: .sp .BR netdevsim - Interface for netdev API tests +.sp +.BR rmnet +- Qualcomm rmnet device .in -8 .TP @@ -1651,6 +1655,21 @@ the following additional arguments are supported: .in -8 +.TP +RMNET Type Support +For a link of type +.I RMNET +the following additional arguments are supported: + +.BI "ip link add link " DEVICE " name " NAME " type rmnet mux_id " MUXID + +.in +8 +.sp +.BI mux_id " MUXID " +- specifies the mux identifier for the rmnet device, possible values 1-254. + +.in -8 + .SS ip link delete - delete virtual link .TP diff --git a/rdma/rdma.h b/rdma/rdma.h index fcaf9e69..d4b7ba19 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include