diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2010-05-25 10:34:27 +0200 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2010-05-25 13:39:39 +0200 |
commit | 6faebfa663fd008fa28f0d69d0663fe80675ebec (patch) | |
tree | 27213e271f2ef64ec627bb31cec5b9fee5f6086c | |
parent | 49ee8393f4d11ee3091dcad41ce36741c6a4b4f8 (diff) | |
download | busybox-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.c | 93 |
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 */ | ||
291 | static 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 */ |
287 | int do_iplink(char **argv) | 374 | int 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); |