aboutsummaryrefslogtreecommitdiff
path: root/networking/libiproute/iplink.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/iplink.c')
-rw-r--r--networking/libiproute/iplink.c300
1 files changed, 135 insertions, 165 deletions
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index ae3ef0ceb..aef5f6490 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -52,6 +52,9 @@ struct ifla_vlan_flags {
52# define dbg(...) ((void)0) 52# define dbg(...) ((void)0)
53#endif 53#endif
54 54
55
56#define str_on_off "on\0""off\0"
57
55/* Exits on error */ 58/* Exits on error */
56static int get_ctl_fd(void) 59static int get_ctl_fd(void)
57{ 60{
@@ -204,12 +207,14 @@ static int do_set(char **argv)
204 struct ifreq ifr0, ifr1; 207 struct ifreq ifr0, ifr1;
205 char *newname = NULL; 208 char *newname = NULL;
206 int htype, halen; 209 int htype, halen;
210 /* If you add stuff here, update iplink_full_usage */
207 static const char keywords[] ALIGN1 = 211 static const char keywords[] ALIGN1 =
208 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" 212 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
209 "arp\0""address\0""dev\0"; 213 "arp\0""promisc\0""address\0"
214 "dev\0" /* must be last */;
210 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, 215 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
211 ARG_arp, ARG_addr, ARG_dev }; 216 ARG_arp, ARG_promisc, ARG_addr,
212 static const char str_on_off[] ALIGN1 = "on\0""off\0"; 217 ARG_dev };
213 enum { PARM_on = 0, PARM_off }; 218 enum { PARM_on = 0, PARM_off };
214 smalluint key; 219 smalluint key;
215 220
@@ -232,6 +237,7 @@ static int do_set(char **argv)
232 duparg("mtu", *argv); 237 duparg("mtu", *argv);
233 mtu = get_unsigned(*argv, "mtu"); 238 mtu = get_unsigned(*argv, "mtu");
234 } else if (key == ARG_qlen) { 239 } else if (key == ARG_qlen) {
240//TODO: txqueuelen, txqlen are synonyms to qlen
235 NEXT_ARG(); 241 NEXT_ARG();
236 if (qlen != -1) 242 if (qlen != -1)
237 duparg("qlen", *argv); 243 duparg("qlen", *argv);
@@ -240,6 +246,7 @@ static int do_set(char **argv)
240 NEXT_ARG(); 246 NEXT_ARG();
241 newaddr = *argv; 247 newaddr = *argv;
242 } else if (key >= ARG_dev) { 248 } else if (key >= ARG_dev) {
249 /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */
243 if (key == ARG_dev) { 250 if (key == ARG_dev) {
244 NEXT_ARG(); 251 NEXT_ARG();
245 } 252 }
@@ -247,6 +254,7 @@ static int do_set(char **argv)
247 duparg2("dev", *argv); 254 duparg2("dev", *argv);
248 dev = *argv; 255 dev = *argv;
249 } else { 256 } else {
257 /* "on|off" options */
250 int param; 258 int param;
251 NEXT_ARG(); 259 NEXT_ARG();
252 param = index_in_strings(str_on_off, *argv); 260 param = index_in_strings(str_on_off, *argv);
@@ -266,8 +274,132 @@ static int do_set(char **argv)
266 flags &= ~IFF_NOARP; 274 flags &= ~IFF_NOARP;
267 else 275 else
268 flags |= IFF_NOARP; 276 flags |= IFF_NOARP;
277 } else if (key == ARG_promisc) {
278 if (param < 0)
279 die_must_be_on_off("promisc");
280 mask |= IFF_PROMISC;
281 if (param == PARM_on)
282 flags |= IFF_PROMISC;
283 else
284 flags &= ~IFF_PROMISC;
269 } 285 }
270 } 286 }
287
288/* Other keywords recognized by iproute2-3.12.0: */
289#if 0
290 } else if (matches(*argv, "broadcast") == 0 ||
291 strcmp(*argv, "brd") == 0) {
292 NEXT_ARG();
293 len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
294 if (len < 0)
295 return -1;
296 addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
297 } else if (strcmp(*argv, "netns") == 0) {
298 NEXT_ARG();
299 if (netns != -1)
300 duparg("netns", *argv);
301 if ((netns = get_netns_fd(*argv)) >= 0)
302 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
303 else if (get_integer(&netns, *argv, 0) == 0)
304 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
305 else
306 invarg_1_to_2(*argv, "netns");
307 } else if (strcmp(*argv, "allmulticast") == 0) {
308 NEXT_ARG();
309 req->i.ifi_change |= IFF_ALLMULTI;
310 if (strcmp(*argv, "on") == 0) {
311 req->i.ifi_flags |= IFF_ALLMULTI;
312 } else if (strcmp(*argv, "off") == 0) {
313 req->i.ifi_flags &= ~IFF_ALLMULTI;
314 } else
315 return on_off("allmulticast", *argv);
316 } else if (strcmp(*argv, "trailers") == 0) {
317 NEXT_ARG();
318 req->i.ifi_change |= IFF_NOTRAILERS;
319 if (strcmp(*argv, "off") == 0) {
320 req->i.ifi_flags |= IFF_NOTRAILERS;
321 } else if (strcmp(*argv, "on") == 0) {
322 req->i.ifi_flags &= ~IFF_NOTRAILERS;
323 } else
324 return on_off("trailers", *argv);
325 } else if (strcmp(*argv, "vf") == 0) {
326 struct rtattr *vflist;
327 NEXT_ARG();
328 if (get_integer(&vf, *argv, 0)) {
329 invarg_1_to_2(*argv, "vf");
330 }
331 vflist = addattr_nest(&req->n, sizeof(*req),
332 IFLA_VFINFO_LIST);
333 len = iplink_parse_vf(vf, &argc, &argv, req);
334 if (len < 0)
335 return -1;
336 addattr_nest_end(&req->n, vflist);
337 } else if (matches(*argv, "master") == 0) {
338 int ifindex;
339 NEXT_ARG();
340 ifindex = ll_name_to_index(*argv);
341 if (!ifindex)
342 invarg_1_to_2(*argv, "master");
343 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
344 &ifindex, 4);
345 } else if (matches(*argv, "nomaster") == 0) {
346 int ifindex = 0;
347 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
348 &ifindex, 4);
349 } else if (matches(*argv, "dynamic") == 0) {
350 NEXT_ARG();
351 req->i.ifi_change |= IFF_DYNAMIC;
352 if (strcmp(*argv, "on") == 0) {
353 req->i.ifi_flags |= IFF_DYNAMIC;
354 } else if (strcmp(*argv, "off") == 0) {
355 req->i.ifi_flags &= ~IFF_DYNAMIC;
356 } else
357 return on_off("dynamic", *argv);
358 } else if (matches(*argv, "alias") == 0) {
359 NEXT_ARG();
360 addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
361 *argv, strlen(*argv));
362 argc--; argv++;
363 break;
364 } else if (strcmp(*argv, "group") == 0) {
365 NEXT_ARG();
366 if (*group != -1)
367 duparg("group", *argv);
368 if (rtnl_group_a2n(group, *argv))
369 invarg_1_to_2(*argv, "group");
370 } else if (strcmp(*argv, "mode") == 0) {
371 int mode;
372 NEXT_ARG();
373 mode = get_link_mode(*argv);
374 if (mode < 0)
375 invarg_1_to_2(*argv, "mode");
376 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
377 } else if (strcmp(*argv, "state") == 0) {
378 int state;
379 NEXT_ARG();
380 state = get_operstate(*argv);
381 if (state < 0)
382 invarg_1_to_2(*argv, "state");
383 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
384 } else if (matches(*argv, "numtxqueues") == 0) {
385 NEXT_ARG();
386 if (numtxqueues != -1)
387 duparg("numtxqueues", *argv);
388 if (get_integer(&numtxqueues, *argv, 0))
389 invarg_1_to_2(*argv, "numtxqueues");
390 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
391 &numtxqueues, 4);
392 } else if (matches(*argv, "numrxqueues") == 0) {
393 NEXT_ARG();
394 if (numrxqueues != -1)
395 duparg("numrxqueues", *argv);
396 if (get_integer(&numrxqueues, *argv, 0))
397 invarg_1_to_2(*argv, "numrxqueues");
398 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
399 &numrxqueues, 4);
400 }
401#endif
402
271 argv++; 403 argv++;
272 } 404 }
273 405
@@ -322,10 +454,6 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size)
322 "802.1q\0" 454 "802.1q\0"
323 "802.1ad\0" 455 "802.1ad\0"
324 ; 456 ;
325 static const char str_on_off[] ALIGN1 =
326 "on\0"
327 "off\0"
328 ;
329 enum { 457 enum {
330 ARG_id = 0, 458 ARG_id = 0,
331 ARG_reorder_hdr, 459 ARG_reorder_hdr,
@@ -520,164 +648,6 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
520 return 0; 648 return 0;
521} 649}
522 650
523/* Other keywords recognized by iproute2-3.12.0: */
524#if 0
525 } else if (matches(*argv, "broadcast") == 0 ||
526 strcmp(*argv, "brd") == 0) {
527 NEXT_ARG();
528 len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
529 if (len < 0)
530 return -1;
531 addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
532 } else if (matches(*argv, "txqueuelen") == 0 ||
533 strcmp(*argv, "qlen") == 0 ||
534 matches(*argv, "txqlen") == 0) {
535 NEXT_ARG();
536 if (qlen != -1)
537 duparg("txqueuelen", *argv);
538 if (get_integer(&qlen, *argv, 0))
539 invarg_1_to_2(*argv, "txqueuelen");
540 addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
541 } else if (strcmp(*argv, "mtu") == 0) {
542 NEXT_ARG();
543 if (mtu != -1)
544 duparg("mtu", *argv);
545 if (get_integer(&mtu, *argv, 0))
546 invarg_1_to_2(*argv, "mtu");
547 addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
548 } else if (strcmp(*argv, "netns") == 0) {
549 NEXT_ARG();
550 if (netns != -1)
551 duparg("netns", *argv);
552 if ((netns = get_netns_fd(*argv)) >= 0)
553 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
554 else if (get_integer(&netns, *argv, 0) == 0)
555 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
556 else
557 invarg_1_to_2(*argv, "netns");
558 } else if (strcmp(*argv, "multicast") == 0) {
559 NEXT_ARG();
560 req->i.ifi_change |= IFF_MULTICAST;
561 if (strcmp(*argv, "on") == 0) {
562 req->i.ifi_flags |= IFF_MULTICAST;
563 } else if (strcmp(*argv, "off") == 0) {
564 req->i.ifi_flags &= ~IFF_MULTICAST;
565 } else
566 return on_off("multicast", *argv);
567 } else if (strcmp(*argv, "allmulticast") == 0) {
568 NEXT_ARG();
569 req->i.ifi_change |= IFF_ALLMULTI;
570 if (strcmp(*argv, "on") == 0) {
571 req->i.ifi_flags |= IFF_ALLMULTI;
572 } else if (strcmp(*argv, "off") == 0) {
573 req->i.ifi_flags &= ~IFF_ALLMULTI;
574 } else
575 return on_off("allmulticast", *argv);
576 } else if (strcmp(*argv, "promisc") == 0) {
577 NEXT_ARG();
578 req->i.ifi_change |= IFF_PROMISC;
579 if (strcmp(*argv, "on") == 0) {
580 req->i.ifi_flags |= IFF_PROMISC;
581 } else if (strcmp(*argv, "off") == 0) {
582 req->i.ifi_flags &= ~IFF_PROMISC;
583 } else
584 return on_off("promisc", *argv);
585 } else if (strcmp(*argv, "trailers") == 0) {
586 NEXT_ARG();
587 req->i.ifi_change |= IFF_NOTRAILERS;
588 if (strcmp(*argv, "off") == 0) {
589 req->i.ifi_flags |= IFF_NOTRAILERS;
590 } else if (strcmp(*argv, "on") == 0) {
591 req->i.ifi_flags &= ~IFF_NOTRAILERS;
592 } else
593 return on_off("trailers", *argv);
594 } else if (strcmp(*argv, "arp") == 0) {
595 NEXT_ARG();
596 req->i.ifi_change |= IFF_NOARP;
597 if (strcmp(*argv, "on") == 0) {
598 req->i.ifi_flags &= ~IFF_NOARP;
599 } else if (strcmp(*argv, "off") == 0) {
600 req->i.ifi_flags |= IFF_NOARP;
601 } else
602 return on_off("noarp", *argv);
603 } else if (strcmp(*argv, "vf") == 0) {
604 struct rtattr *vflist;
605 NEXT_ARG();
606 if (get_integer(&vf, *argv, 0)) {
607 invarg_1_to_2(*argv, "vf");
608 }
609 vflist = addattr_nest(&req->n, sizeof(*req),
610 IFLA_VFINFO_LIST);
611 len = iplink_parse_vf(vf, &argc, &argv, req);
612 if (len < 0)
613 return -1;
614 addattr_nest_end(&req->n, vflist);
615 } else if (matches(*argv, "master") == 0) {
616 int ifindex;
617 NEXT_ARG();
618 ifindex = ll_name_to_index(*argv);
619 if (!ifindex)
620 invarg_1_to_2(*argv, "master");
621 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
622 &ifindex, 4);
623 } else if (matches(*argv, "nomaster") == 0) {
624 int ifindex = 0;
625 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
626 &ifindex, 4);
627 } else if (matches(*argv, "dynamic") == 0) {
628 NEXT_ARG();
629 req->i.ifi_change |= IFF_DYNAMIC;
630 if (strcmp(*argv, "on") == 0) {
631 req->i.ifi_flags |= IFF_DYNAMIC;
632 } else if (strcmp(*argv, "off") == 0) {
633 req->i.ifi_flags &= ~IFF_DYNAMIC;
634 } else
635 return on_off("dynamic", *argv);
636 } else if (matches(*argv, "alias") == 0) {
637 NEXT_ARG();
638 addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
639 *argv, strlen(*argv));
640 argc--; argv++;
641 break;
642 } else if (strcmp(*argv, "group") == 0) {
643 NEXT_ARG();
644 if (*group != -1)
645 duparg("group", *argv);
646 if (rtnl_group_a2n(group, *argv))
647 invarg_1_to_2(*argv, "group");
648 } else if (strcmp(*argv, "mode") == 0) {
649 int mode;
650 NEXT_ARG();
651 mode = get_link_mode(*argv);
652 if (mode < 0)
653 invarg_1_to_2(*argv, "mode");
654 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
655 } else if (strcmp(*argv, "state") == 0) {
656 int state;
657 NEXT_ARG();
658 state = get_operstate(*argv);
659 if (state < 0)
660 invarg_1_to_2(*argv, "state");
661 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
662 } else if (matches(*argv, "numtxqueues") == 0) {
663 NEXT_ARG();
664 if (numtxqueues != -1)
665 duparg("numtxqueues", *argv);
666 if (get_integer(&numtxqueues, *argv, 0))
667 invarg_1_to_2(*argv, "numtxqueues");
668 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
669 &numtxqueues, 4);
670 } else if (matches(*argv, "numrxqueues") == 0) {
671 NEXT_ARG();
672 if (numrxqueues != -1)
673 duparg("numrxqueues", *argv);
674 if (get_integer(&numrxqueues, *argv, 0))
675 invarg_1_to_2(*argv, "numrxqueues");
676 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
677 &numrxqueues, 4);
678 }
679#endif
680
681/* Return value becomes exitcode. It's okay to not return at all */ 651/* Return value becomes exitcode. It's okay to not return at all */
682int FAST_FUNC do_iplink(char **argv) 652int FAST_FUNC do_iplink(char **argv)
683{ 653{