iplink: support add/delete
function old new delta do_change - 490 +490 .rodata 135193 135225 +32 do_iplink 1146 1169 +23 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 545/0) Total: 545 bytes Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
This commit is contained in:
parent
49ee8393f4
commit
6faebfa663
@ -283,11 +283,98 @@ static int ipaddr_list_link(char **argv)
|
|||||||
return ipaddr_list_or_flush(argv, 0);
|
return ipaddr_list_or_flush(argv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NLMSG_TAIL
|
||||||
|
#define NLMSG_TAIL(nmsg) \
|
||||||
|
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
|
||||||
|
#endif
|
||||||
|
/* Return value becomes exitcode. It's okay to not return at all */
|
||||||
|
static int do_change(char **argv, const unsigned rtm)
|
||||||
|
{
|
||||||
|
static const char keywords[] ALIGN1 =
|
||||||
|
"link\0""name\0""type\0""dev\0";
|
||||||
|
enum {
|
||||||
|
ARG_link,
|
||||||
|
ARG_name,
|
||||||
|
ARG_type,
|
||||||
|
ARG_dev,
|
||||||
|
};
|
||||||
|
struct rtnl_handle rth;
|
||||||
|
struct {
|
||||||
|
struct nlmsghdr n;
|
||||||
|
struct ifinfomsg i;
|
||||||
|
char buf[1024];
|
||||||
|
} req;
|
||||||
|
int arg;
|
||||||
|
char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
req.i.ifi_family = preferred_family;
|
||||||
|
if (rtm == RTM_NEWLINK)
|
||||||
|
req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
|
||||||
|
|
||||||
|
while (*argv) {
|
||||||
|
arg = index_in_substrings(keywords, *argv);
|
||||||
|
if (arg == ARG_link) {
|
||||||
|
NEXT_ARG();
|
||||||
|
link_str = *argv;
|
||||||
|
} else if (arg == ARG_name) {
|
||||||
|
NEXT_ARG();
|
||||||
|
name_str = *argv;
|
||||||
|
} else if (arg == ARG_type) {
|
||||||
|
NEXT_ARG();
|
||||||
|
type_str = *argv;
|
||||||
|
} else {
|
||||||
|
if (arg == ARG_dev) {
|
||||||
|
if (dev_str)
|
||||||
|
duparg(*argv, "dev");
|
||||||
|
NEXT_ARG();
|
||||||
|
}
|
||||||
|
dev_str = *argv;
|
||||||
|
}
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
xrtnl_open(&rth);
|
||||||
|
ll_init_map(&rth);
|
||||||
|
if (type_str) {
|
||||||
|
struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
|
||||||
|
|
||||||
|
addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
|
||||||
|
addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str,
|
||||||
|
strlen(type_str));
|
||||||
|
linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
|
||||||
|
}
|
||||||
|
if (rtm != RTM_NEWLINK) {
|
||||||
|
if (!dev_str)
|
||||||
|
return 1; /* Need a device to delete */
|
||||||
|
req.i.ifi_index = xll_name_to_index(dev_str);
|
||||||
|
} else {
|
||||||
|
if (!name_str)
|
||||||
|
name_str = dev_str;
|
||||||
|
if (link_str) {
|
||||||
|
int idx = xll_name_to_index(link_str);
|
||||||
|
addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name_str) {
|
||||||
|
const size_t name_len = strlen(name_str) + 1;
|
||||||
|
if (name_len < 2 || name_len > IFNAMSIZ)
|
||||||
|
invarg(name_str, "name");
|
||||||
|
addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
|
||||||
|
}
|
||||||
|
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return value becomes exitcode. It's okay to not return at all */
|
/* Return value becomes exitcode. It's okay to not return at all */
|
||||||
int do_iplink(char **argv)
|
int do_iplink(char **argv)
|
||||||
{
|
{
|
||||||
static const char keywords[] ALIGN1 =
|
static const char keywords[] ALIGN1 =
|
||||||
"set\0""show\0""lst\0""list\0";
|
"add\0""delete\0""set\0""show\0""lst\0""list\0";
|
||||||
int key;
|
int key;
|
||||||
if (!*argv)
|
if (!*argv)
|
||||||
return ipaddr_list_link(argv);
|
return ipaddr_list_link(argv);
|
||||||
@ -295,7 +382,9 @@ int do_iplink(char **argv)
|
|||||||
if (key < 0)
|
if (key < 0)
|
||||||
bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
|
bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
|
||||||
argv++;
|
argv++;
|
||||||
if (key == 0) /* set */
|
if (key <= 1) /* add/delete */
|
||||||
|
return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
|
||||||
|
else if (key == 2) /* set */
|
||||||
return do_set(argv);
|
return do_set(argv);
|
||||||
/* show, lst, list */
|
/* show, lst, list */
|
||||||
return ipaddr_list_link(argv);
|
return ipaddr_list_link(argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user