aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-05-25 10:34:27 +0200
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-05-25 13:39:39 +0200
commit6faebfa663fd008fa28f0d69d0663fe80675ebec (patch)
tree27213e271f2ef64ec627bb31cec5b9fee5f6086c
parent49ee8393f4d11ee3091dcad41ce36741c6a4b4f8 (diff)
downloadbusybox-w32-6faebfa663fd008fa28f0d69d0663fe80675ebec.tar.gz
busybox-w32-6faebfa663fd008fa28f0d69d0663fe80675ebec.tar.bz2
busybox-w32-6faebfa663fd008fa28f0d69d0663fe80675ebec.zip
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>
-rw-r--r--networking/libiproute/iplink.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index df8a354a1..a28df6e79 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -283,11 +283,98 @@ static int ipaddr_list_link(char **argv)
283 return ipaddr_list_or_flush(argv, 0); 283 return ipaddr_list_or_flush(argv, 0);
284} 284}
285 285
286#ifndef NLMSG_TAIL
287#define NLMSG_TAIL(nmsg) \
288 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
289#endif
290/* Return value becomes exitcode. It's okay to not return at all */
291static int do_change(char **argv, const unsigned rtm)
292{
293 static const char keywords[] ALIGN1 =
294 "link\0""name\0""type\0""dev\0";
295 enum {
296 ARG_link,
297 ARG_name,
298 ARG_type,
299 ARG_dev,
300 };
301 struct rtnl_handle rth;
302 struct {
303 struct nlmsghdr n;
304 struct ifinfomsg i;
305 char buf[1024];
306 } req;
307 int arg;
308 char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL;
309
310 memset(&req, 0, sizeof(req));
311
312 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
313 req.n.nlmsg_flags = NLM_F_REQUEST;
314 req.n.nlmsg_type = rtm;
315 req.i.ifi_family = preferred_family;
316 if (rtm == RTM_NEWLINK)
317 req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
318
319 while (*argv) {
320 arg = index_in_substrings(keywords, *argv);
321 if (arg == ARG_link) {
322 NEXT_ARG();
323 link_str = *argv;
324 } else if (arg == ARG_name) {
325 NEXT_ARG();
326 name_str = *argv;
327 } else if (arg == ARG_type) {
328 NEXT_ARG();
329 type_str = *argv;
330 } else {
331 if (arg == ARG_dev) {
332 if (dev_str)
333 duparg(*argv, "dev");
334 NEXT_ARG();
335 }
336 dev_str = *argv;
337 }
338 argv++;
339 }
340 xrtnl_open(&rth);
341 ll_init_map(&rth);
342 if (type_str) {
343 struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
344
345 addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
346 addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str,
347 strlen(type_str));
348 linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
349 }
350 if (rtm != RTM_NEWLINK) {
351 if (!dev_str)
352 return 1; /* Need a device to delete */
353 req.i.ifi_index = xll_name_to_index(dev_str);
354 } else {
355 if (!name_str)
356 name_str = dev_str;
357 if (link_str) {
358 int idx = xll_name_to_index(link_str);
359 addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
360 }
361 }
362 if (name_str) {
363 const size_t name_len = strlen(name_str) + 1;
364 if (name_len < 2 || name_len > IFNAMSIZ)
365 invarg(name_str, "name");
366 addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
367 }
368 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
369 return 2;
370 return 0;
371}
372
286/* Return value becomes exitcode. It's okay to not return at all */ 373/* Return value becomes exitcode. It's okay to not return at all */
287int do_iplink(char **argv) 374int do_iplink(char **argv)
288{ 375{
289 static const char keywords[] ALIGN1 = 376 static const char keywords[] ALIGN1 =
290 "set\0""show\0""lst\0""list\0"; 377 "add\0""delete\0""set\0""show\0""lst\0""list\0";
291 int key; 378 int key;
292 if (!*argv) 379 if (!*argv)
293 return ipaddr_list_link(argv); 380 return ipaddr_list_link(argv);
@@ -295,7 +382,9 @@ int do_iplink(char **argv)
295 if (key < 0) 382 if (key < 0)
296 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 383 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
297 argv++; 384 argv++;
298 if (key == 0) /* set */ 385 if (key <= 1) /* add/delete */
386 return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
387 else if (key == 2) /* set */
299 return do_set(argv); 388 return do_set(argv);
300 /* show, lst, list */ 389 /* show, lst, list */
301 return ipaddr_list_link(argv); 390 return ipaddr_list_link(argv);