[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