int iplink_parse(int argc, char **argv, struct iplink_req *req, char **name, char **type, char **link, char **dev, int *group, int *index) { int ret, len; char abuf[32]; int qlen = -1; int mtu = -1; int netns = -1; int vf = -1; int numtxqueues = -1; int numrxqueues = -1; int dev_index = 0; *group = -1; ret = argc; while (argc > 0) { if (strcmp(*argv, "up") == 0) { req->i.ifi_change |= IFF_UP; req->i.ifi_flags |= IFF_UP; } else if (strcmp(*argv, "down") == 0) { req->i.ifi_change |= IFF_UP; req->i.ifi_flags &= ~IFF_UP; } else if (strcmp(*argv, "name") == 0) { NEXT_ARG(); *name = *argv; } else if (strcmp(*argv, "index") == 0) { NEXT_ARG(); *index = atoi(*argv); } else if (matches(*argv, "link") == 0) { NEXT_ARG(); *link = *argv; } else if (matches(*argv, "address") == 0) { NEXT_ARG(); len = ll_addr_a2n(abuf, sizeof(abuf), *argv); if (len < 0) return -1; addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); } else if (matches(*argv, "broadcast") == 0 || strcmp(*argv, "brd") == 0) { NEXT_ARG(); len = ll_addr_a2n(abuf, sizeof(abuf), *argv); if (len < 0) return -1; addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); } else if (matches(*argv, "txqueuelen") == 0 || strcmp(*argv, "qlen") == 0 || matches(*argv, "txqlen") == 0) { NEXT_ARG(); if (qlen != -1) duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) invarg("Invalid \"txqueuelen\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); } else if (strcmp(*argv, "netns") == 0) { NEXT_ARG(); if (netns != -1) duparg("netns", *argv); if ((netns = get_netns_fd(*argv)) >= 0) addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); else if (get_integer(&netns, *argv, 0) == 0) addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); else invarg("Invalid \"netns\" value\n", *argv); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_MULTICAST; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_MULTICAST; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_MULTICAST; } else return on_off("multicast", *argv); } else if (strcmp(*argv, "allmulticast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_ALLMULTI; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_ALLMULTI; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_ALLMULTI; } else return on_off("allmulticast", *argv); } else if (strcmp(*argv, "promisc") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_PROMISC; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_PROMISC; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_PROMISC; } else return on_off("promisc", *argv); } else if (strcmp(*argv, "trailers") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOTRAILERS; if (strcmp(*argv, "off") == 0) { req->i.ifi_flags |= IFF_NOTRAILERS; } else if (strcmp(*argv, "on") == 0) { req->i.ifi_flags &= ~IFF_NOTRAILERS; } else return on_off("trailers", *argv); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOARP; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags &= ~IFF_NOARP; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags |= IFF_NOARP; } else return on_off("noarp", *argv); } else if (strcmp(*argv, "vf") == 0) { struct rtattr *vflist; NEXT_ARG(); if (get_integer(&vf, *argv, 0)) { invarg("Invalid \"vf\" value\n", *argv); } vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); if (dev_index == 0) missarg("dev"); len = iplink_parse_vf(vf, &argc, &argv, req, dev_index); if (len < 0) return -1; addattr_nest_end(&req->n, vflist); } else if (matches(*argv, "master") == 0) { int ifindex; NEXT_ARG(); ifindex = ll_name_to_index(*argv); if (!ifindex) invarg("Device does not exist\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_MASTER, &ifindex, 4); } else if (matches(*argv, "nomaster") == 0) { int ifindex = 0; addattr_l(&req->n, sizeof(*req), IFLA_MASTER, &ifindex, 4); } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_DYNAMIC; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_DYNAMIC; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_DYNAMIC; } else return on_off("dynamic", *argv); } else if (matches(*argv, "type") == 0) { NEXT_ARG(); *type = *argv; argc--; argv++; break; } else if (matches(*argv, "alias") == 0) { NEXT_ARG(); addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, *argv, strlen(*argv)); argc--; argv++; break; } else if (strcmp(*argv, "group") == 0) { NEXT_ARG(); if (*group != -1) duparg("group", *argv); if (rtnl_group_a2n(group, *argv)) invarg("Invalid \"group\" value\n", *argv); } else if (strcmp(*argv, "mode") == 0) { int mode; NEXT_ARG(); mode = get_link_mode(*argv); if (mode < 0) invarg("Invalid link mode\n", *argv); addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); } else if (strcmp(*argv, "state") == 0) { int state; NEXT_ARG(); state = get_operstate(*argv); if (state < 0) invarg("Invalid operstate\n", *argv); addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); } else if (matches(*argv, "numtxqueues") == 0) { NEXT_ARG(); if (numtxqueues != -1) duparg("numtxqueues", *argv); if (get_integer(&numtxqueues, *argv, 0)) invarg("Invalid \"numtxqueues\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, &numtxqueues, 4); } else if (matches(*argv, "numrxqueues") == 0) { NEXT_ARG(); if (numrxqueues != -1) duparg("numrxqueues", *argv); if (get_integer(&numrxqueues, *argv, 0)) invarg("Invalid \"numrxqueues\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, &numrxqueues, 4); } else { if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); } if (matches(*argv, "help") == 0) usage(); if (*dev) duparg2("dev", *argv); *dev = *argv; dev_index = ll_name_to_index(*dev); if (dev_index == 0) invarg("Unknown device", *argv); } argc--; argv++; } return ret - argc; }
int iplink_parse(int argc, char **argv, struct iplink_req *req, char **name, char **type, char **link, char **dev) { int ret, len; char abuf[32]; int qlen = -1; int mtu = -1; int netns = -1; int vf = -1; ret = argc; while (argc > 0) { if (strcmp(*argv, "up") == 0) { req->i.ifi_change |= IFF_UP; req->i.ifi_flags |= IFF_UP; } else if (strcmp(*argv, "down") == 0) { req->i.ifi_change |= IFF_UP; req->i.ifi_flags &= ~IFF_UP; } else if (strcmp(*argv, "name") == 0) { NEXT_ARG(); *name = *argv; } else if (matches(*argv, "link") == 0) { NEXT_ARG(); *link = *argv; } else if (matches(*argv, "address") == 0) { NEXT_ARG(); len = ll_addr_a2n(abuf, sizeof(abuf), *argv); if (len < 0) return -1; addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); } else if (matches(*argv, "broadcast") == 0 || strcmp(*argv, "brd") == 0) { NEXT_ARG(); len = ll_addr_a2n(abuf, sizeof(abuf), *argv); if (len < 0) return -1; addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); } else if (matches(*argv, "txqueuelen") == 0 || strcmp(*argv, "qlen") == 0 || matches(*argv, "txqlen") == 0) { NEXT_ARG(); if (qlen != -1) duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) invarg("Invalid \"txqueuelen\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); } else if (strcmp(*argv, "netns") == 0) { NEXT_ARG(); if (netns != -1) duparg("netns", *argv); if (get_integer(&netns, *argv, 0)) invarg("Invalid \"netns\" value\n", *argv); addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_MULTICAST; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_MULTICAST; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_MULTICAST; } else return on_off("multicast"); } else if (strcmp(*argv, "allmulticast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_ALLMULTI; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_ALLMULTI; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_ALLMULTI; } else return on_off("allmulticast"); } else if (strcmp(*argv, "multipath") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOMULTIPATH; req->i.ifi_change |= IFF_MPBACKUP; req->i.ifi_change |= IFF_MPHANDOVER; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags &= ~IFF_NOMULTIPATH; req->i.ifi_flags &= ~IFF_MPBACKUP; req->i.ifi_flags &= ~IFF_MPHANDOVER; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags |= IFF_NOMULTIPATH; } else if (strcmp(*argv, "backup") == 0) { req->i.ifi_flags &= ~IFF_NOMULTIPATH; req->i.ifi_flags |= IFF_MPBACKUP; } else if (strcmp(*argv, "handover") == 0) { req->i.ifi_flags &= ~IFF_NOMULTIPATH; req->i.ifi_flags |= IFF_MPHANDOVER; } else { fprintf(stderr, "Error: argument of \"multipath\" must be" "\"on\", \"off\", \"backup\" or \"handover\"\n"); return -1; } } else if (strcmp(*argv, "promisc") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_PROMISC; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_PROMISC; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_PROMISC; } else return on_off("promisc"); } else if (strcmp(*argv, "trailers") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOTRAILERS; if (strcmp(*argv, "off") == 0) { req->i.ifi_flags |= IFF_NOTRAILERS; } else if (strcmp(*argv, "on") == 0) { req->i.ifi_flags &= ~IFF_NOTRAILERS; } else return on_off("trailers"); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOARP; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags &= ~IFF_NOARP; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags |= IFF_NOARP; } else return on_off("noarp"); } else if (strcmp(*argv, "vf") == 0) { struct rtattr *vflist; NEXT_ARG(); if (get_integer(&vf, *argv, 0)) { invarg("Invalid \"vf\" value\n", *argv); } vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); len = iplink_parse_vf(vf, &argc, &argv, req); if (len < 0) return -1; addattr_nest_end(&req->n, vflist); #ifdef IFF_DYNAMIC } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_DYNAMIC; if (strcmp(*argv, "on") == 0) { req->i.ifi_flags |= IFF_DYNAMIC; } else if (strcmp(*argv, "off") == 0) { req->i.ifi_flags &= ~IFF_DYNAMIC; } else return on_off("dynamic"); #endif } else if (matches(*argv, "type") == 0) { NEXT_ARG(); *type = *argv; argc--; argv++; break; } else if (matches(*argv, "alias") == 0) { NEXT_ARG(); addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, *argv, strlen(*argv)); argc--; argv++; break; } else { if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); } if (matches(*argv, "help") == 0) usage(); if (*dev) duparg2("dev", *argv); *dev = *argv; } argc--; argv++; } return ret - argc; }