[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: Re: [PATCH] ip link: support "type can bitrate NUM" argument
From: Nikolaus Voss <nv () vosn ! de>
Date: 2022-09-28 13:10:14
Message-ID: f8dbcea-514e-7775-bfe4-ad7e3ffe2ab1 () vosn ! de
[Download RAW message or body]
Any comments on this? Saves can interfaces users from compiling
iproute2 ;-)
Niko
On Tue, 9 Aug 2022, Nikolaus Voss wrote:
> This is the minimum needed to set up SocketCAN interfaces.
> Setting the bitrate is usually required before upping the device, e.g.
>
> ip link set can0 type can bitrate 1000000
> ip link set up can0
>
> iproute2 supports more options to "type can" but these are not
> mandatory for using the device.
>
> Signed-off-by: Nikolaus Voss <nikolaus.voss@haag-streit.com>
> ---
> networking/ip.c | 2 +-
> networking/libiproute/iplink.c | 57 ++++++++++++++++++++++++++++--
> networking/libiproute/libnetlink.c | 14 ++++++++
> networking/libiproute/libnetlink.h | 5 +++
> 4 files changed, 75 insertions(+), 3 deletions(-)
>
> diff --git a/networking/ip.c b/networking/ip.c
> index 7c3208699..f0159912a 100644
> --- a/networking/ip.c
> +++ b/networking/ip.c
> @@ -152,7 +152,7 @@
> //usage:#define iplink_trivial_usage
> //usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n"
> //usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n"
> -//usage: " [master IFACE | nomaster] [netns PID]"
> +//usage: " [master IFACE | nomaster] [netns PID] [type can bitrate NUM]"
> // * short help shows only "set" command, long help continues (with just one "\n")
> // * and shows all other commands:
> //usage:#define iplink_full_usage "\n"
> diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
> index 68d199044..c751087d8 100644
> --- a/networking/libiproute/iplink.c
> +++ b/networking/libiproute/iplink.c
> @@ -10,6 +10,7 @@
> #include <netpacket/packet.h>
> #include <netinet/if_ether.h>
>
> +#include <linux/can/netlink.h>
> #include <linux/if_vlan.h>
> #include "ip_common.h" /* #include "libbb.h" is inside */
> #include "rt_names.h"
> @@ -241,6 +242,55 @@ static void die_must_be_on_off(const char *msg)
> bb_error_msg_and_die("argument of \"%s\" must be \"on\" or \"off\"", msg);
> }
>
> +/* Return value becomes exitcode. It's okay to not return at all */
> +static int do_set_type(char **argv, char *dev)
> +{
> + struct rtnl_handle rth;
> + struct {
> + struct nlmsghdr n;
> + struct ifinfomsg i;
> + char buf[1024];
> + } req;
> + struct rtattr *linkinfo;
> + struct rtattr *data;
> +
> + memset(&req, 0, sizeof(req));
> + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
> + req.n.nlmsg_flags = NLM_F_REQUEST;
> + req.n.nlmsg_type = RTM_NEWLINK;
> + req.i.ifi_family = preferred_family;
> +
> + xrtnl_open(&rth);
> + req.i.ifi_index = xll_name_to_index(dev);
> + linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO);
> +
> + if (!strcmp(*argv, "can")) {
> + struct can_bittiming bt = { 0 };
> +
> + addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, *argv,
> + strlen(*argv));
> + data = addattr_nest(&req.n, sizeof(req), IFLA_INFO_DATA);
> + NEXT_ARG();
> + if (!strcmp(*argv, "bitrate")) {
> + NEXT_ARG();
> + bt.bitrate = get_u32(*argv, "bitrate");
> + addattr_l(&req.n, sizeof(req), IFLA_CAN_BITTIMING, &bt,
> + sizeof(bt));
> + } else {
> + bb_error_msg_and_die("arg \"%s\" unkown", *argv);
> + }
> + addattr_nest_end(&req.n, data);
> + } else {
> + invarg_1_to_2(*argv, "type");
> + }
> + addattr_nest_end(&req.n, linkinfo);
> +
> + if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
> + xfunc_die();
> +
> + return 0;
> +}
> +
> /* Return value becomes exitcode. It's okay to not return at all */
> static int do_set(char **argv)
> {
> @@ -260,11 +310,11 @@ static int do_set(char **argv)
> static const char keywords[] ALIGN1 =
> "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
> "arp\0""promisc\0""address\0""netns\0"
> - "master\0""nomaster\0"
> + "master\0""nomaster\0" "type\0"
> "dev\0" /* must be last */;
> enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
> ARG_arp, ARG_promisc, ARG_addr, ARG_netns,
> - ARG_master, ARG_nomaster,
> + ARG_master, ARG_nomaster, ARG_type,
> ARG_dev };
> enum { PARM_on = 0, PARM_off };
> smalluint key;
> @@ -304,6 +354,9 @@ static int do_set(char **argv)
> } else if (key == ARG_netns) {
> NEXT_ARG();
> netns = get_unsigned(*argv, "netns");
> + } else if (key == ARG_type) {
> + NEXT_ARG();
> + return do_set_type(argv, dev);
> } else if (key >= ARG_dev) {
> /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */
> if (key == ARG_dev) {
> diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
> index 7e3473a1c..5b6273245 100644
> --- a/networking/libiproute/libnetlink.c
> +++ b/networking/libiproute/libnetlink.c
> @@ -390,6 +390,20 @@ int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, in
> return 0;
> }
>
> +struct rtattr * FAST_FUNC addattr_nest(struct nlmsghdr *n, int maxlen, int type)
> +{
> + struct rtattr *nest = NLMSG_TAIL(n);
> +
> + addattr_l(n, maxlen, type, NULL, 0);
> + return nest;
> +}
> +
> +int FAST_FUNC addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
> +{
> + nest->rta_len = (void *)NLMSG_TAIL(n) - (void *)nest;
> + return n->nlmsg_len;
> +}
> +
> int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
> {
> int len = RTA_LENGTH(4);
> diff --git a/networking/libiproute/libnetlink.h b/networking/libiproute/libnetlink.h
> index 1b082e019..b7eefa1e5 100644
> --- a/networking/libiproute/libnetlink.h
> +++ b/networking/libiproute/libnetlink.h
> @@ -54,11 +54,16 @@ static ALWAYS_INLINE void rtnl_send(struct rtnl_handle *rth, const void *buf, in
>
> extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) FAST_FUNC;
> extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) FAST_FUNC;
> +extern struct rtattr * addattr_nest(struct nlmsghdr *n, int maxlen, int type) FAST_FUNC;
> +extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest) FAST_FUNC;
> extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) FAST_FUNC;
> extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) FAST_FUNC;
>
> extern void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) FAST_FUNC;
>
> +#define NLMSG_TAIL(nmsg) \
> + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
> +
> POP_SAVED_FUNCTION_VISIBILITY
>
> #endif
>
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic