Introduce new @struct iplink_parse_args data structure to consolidate arguments to iplink_parse(). This will reduce number of arguments passed to it.
Pass this data structure to ->parse_opt() in iplink specific modules: it may be used to get network device name and other information. Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- ip/ip_common.h | 16 +++++++++++++--- ip/iplink.c | 34 ++++++++++++++++++++++------------ ip/iplink_bond.c | 4 +++- ip/iplink_bond_slave.c | 4 +++- ip/iplink_bridge.c | 4 +++- ip/iplink_bridge_slave.c | 4 +++- ip/iplink_can.c | 4 +++- ip/iplink_geneve.c | 4 +++- ip/iplink_hsr.c | 4 +++- ip/iplink_ipoib.c | 4 +++- ip/iplink_ipvlan.c | 4 +++- ip/iplink_macvlan.c | 4 +++- ip/iplink_vlan.c | 4 +++- ip/iplink_vrf.c | 5 ++++- ip/iplink_vxcan.c | 14 ++++++-------- ip/iplink_vxlan.c | 4 +++- ip/ipmacsec.c | 4 +++- ip/link_gre.c | 6 ++++-- ip/link_gre6.c | 6 ++++-- ip/link_ip6tnl.c | 6 ++++-- ip/link_iptnl.c | 6 ++++-- ip/link_veth.c | 14 ++++++-------- ip/link_vti.c | 6 ++++-- ip/link_vti6.c | 6 ++++-- 24 files changed, 114 insertions(+), 57 deletions(-) diff --git a/ip/ip_common.h b/ip/ip_common.h index f762821..aef70de 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -112,12 +112,23 @@ struct iplink_req { char buf[1024]; }; +struct iplink_parse_args { + const char *dev; + const char *name; + const char *type; + + /* This definitely must be the last one and initialized + * by the caller of iplink_parse() that will initialize rest. + */ + struct iplink_req *req; +}; + struct link_util { struct link_util *next; const char *id; int maxattr; int (*parse_opt)(struct link_util *, int, char **, - struct nlmsghdr *); + struct iplink_parse_args *); void (*print_opt)(struct link_util *, FILE *, struct rtattr *[]); void (*print_xstats)(struct link_util *, FILE *, @@ -132,8 +143,7 @@ struct link_util { struct link_util *get_link_kind(const char *kind); -int iplink_parse(int argc, char **argv, struct iplink_req *req, - char **name, char **type, char **dev); +int iplink_parse(int argc, char **argv, struct iplink_parse_args *pa); /* iplink_bridge.c */ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len); diff --git a/ip/iplink.c b/ip/iplink.c index e53d890..837e2b0 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -10,6 +10,7 @@ * */ +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -577,9 +578,12 @@ static void has_dev(const char *dev, int dev_index) exit(nodev(dev)); } -int iplink_parse(int argc, char **argv, struct iplink_req *req, - char **name, char **type, char **dev) +int iplink_parse(int argc, char **argv, struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + const char **dev = &pa->dev; + const char **name = &pa->name; + const char **type = &pa->type; char *link = NULL; int ret, len; char abuf[32]; @@ -597,6 +601,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ret = argc; + memset(pa, 0, offsetof(struct iplink_parse_args, req)); + while (argc > 0) { if (strcmp(*argv, "up") == 0) { req->i.ifi_change |= IFF_UP; @@ -1016,32 +1022,32 @@ out: static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) { - char *dev = NULL; - char *name = NULL; - char *type = NULL; struct iplink_req req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), .n.nlmsg_flags = NLM_F_REQUEST | flags, .n.nlmsg_type = cmd, .i.ifi_family = preferred_family, }; + struct iplink_parse_args pa; int ret; - ret = iplink_parse(argc, argv, &req, &name, &type, &dev); + pa.req = &req; + + ret = iplink_parse(argc, argv, &pa); if (ret < 0) return ret; - if (type) { + if (pa.type) { struct link_util *lu; struct rtattr *linkinfo; - char *ulinep = strchr(type, '_'); + char *ulinep = strchr(pa.type, '_'); int iflatype; linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO); - addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, - strlen(type)); + addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, pa.type, + strlen(pa.type)); - lu = get_link_kind(type); + lu = get_link_kind(pa.type); if (ulinep && !strcmp(ulinep, "_slave")) iflatype = IFLA_INFO_SLAVE_DATA; else @@ -1056,9 +1062,13 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) data = addattr_nest(&req.n, sizeof(req), iflatype); if (lu->parse_opt && - lu->parse_opt(lu, argc, argv, &req.n)) + lu->parse_opt(lu, argc, argv, &pa)) return -1; + /* Must not assume that anything except pa.req is valid + * after calling ->parse_opt() as one might reuse pa + * with iplink_parse(). See link_veth.c as an example. + */ addattr_nest_end(&req.n, data); } else if (argc) { if (matches(*argv, "help") == 0) diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c index f906e7f..bf03a6e 100644 --- a/ip/iplink_bond.c +++ b/ip/iplink_bond.c @@ -157,8 +157,10 @@ static void explain(void) } static int bond_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u8 mode, use_carrier, primary_reselect, fail_over_mac; __u8 xmit_hash_policy, num_peer_notif, all_slaves_active; __u8 lacp_rate, ad_select, tlb_dynamic_lb; diff --git a/ip/iplink_bond_slave.c b/ip/iplink_bond_slave.c index 67219c6..d7e2a1e 100644 --- a/ip/iplink_bond_slave.c +++ b/ip/iplink_bond_slave.c @@ -120,8 +120,10 @@ static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *t } static int bond_slave_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u16 queue_id; while (argc > 0) { diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c index 3008e44..9a8560a 100644 --- a/ip/iplink_bridge.c +++ b/ip/iplink_bridge.c @@ -80,8 +80,10 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len) } static int bridge_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u32 val; while (argc > 0) { diff --git a/ip/iplink_bridge_slave.c b/ip/iplink_bridge_slave.c index 3fbfb87..31fde1c 100644 --- a/ip/iplink_bridge_slave.c +++ b/ip/iplink_bridge_slave.c @@ -292,8 +292,10 @@ static void bridge_slave_parse_on_off(char *arg_name, char *arg_val, } static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u8 state; __u16 priority; __u32 cost; diff --git a/ip/iplink_can.c b/ip/iplink_can.c index 587413d..36ef917 100644 --- a/ip/iplink_can.c +++ b/ip/iplink_can.c @@ -110,8 +110,10 @@ static void print_ctrlmode(FILE *f, __u32 cm) } static int can_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; struct can_bittiming bt = {}, dbt = {}; struct can_ctrlmode cm = {0, 0}; diff --git a/ip/iplink_geneve.c b/ip/iplink_geneve.c index 1fcdd83..4b2bf29 100644 --- a/ip/iplink_geneve.c +++ b/ip/iplink_geneve.c @@ -55,8 +55,10 @@ static void check_duparg(__u64 *attrs, int type, const char *key, } static int geneve_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; inet_prefix daddr; __u32 vni = 0; __u32 label = 0; diff --git a/ip/iplink_hsr.c b/ip/iplink_hsr.c index c673ccf..d020676 100644 --- a/ip/iplink_hsr.c +++ b/ip/iplink_hsr.c @@ -44,8 +44,10 @@ static void usage(void) } static int hsr_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; int ifindex; unsigned char multicast_spec; unsigned char protocol_version; diff --git a/ip/iplink_ipoib.c b/ip/iplink_ipoib.c index e69bda0..f95c79c 100644 --- a/ip/iplink_ipoib.c +++ b/ip/iplink_ipoib.c @@ -42,8 +42,10 @@ static int mode_arg(void) } static int ipoib_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u16 pkey, mode, umcast; while (argc > 0) { diff --git a/ip/iplink_ipvlan.c b/ip/iplink_ipvlan.c index 8889808..2b8a3cc 100644 --- a/ip/iplink_ipvlan.c +++ b/ip/iplink_ipvlan.c @@ -30,8 +30,10 @@ static void ipvlan_explain(FILE *f) } static int ipvlan_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u16 flags = 0; bool mflag_given = false; diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c index b966a61..6f97415 100644 --- a/ip/iplink_macvlan.c +++ b/ip/iplink_macvlan.c @@ -63,8 +63,10 @@ static int flag_arg(const char *arg) } static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u32 mode = 0; __u16 flags = 0; __u32 mac_mode = 0; diff --git a/ip/iplink_vlan.c b/ip/iplink_vlan.c index 74f4614..6c0c12d 100644 --- a/ip/iplink_vlan.c +++ b/ip/iplink_vlan.c @@ -82,8 +82,10 @@ static int vlan_parse_qos_map(int *argcp, char ***argvp, struct nlmsghdr *n, } static int vlan_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; struct ifla_vlan_flags flags = { 0 }; __u16 id, proto; diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c index e9dd0df..b943ed9 100644 --- a/ip/iplink_vrf.c +++ b/ip/iplink_vrf.c @@ -30,8 +30,11 @@ static void explain(void) } static int vrf_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; + while (argc > 0) { if (matches(*argv, "table") == 0) { __u32 table; diff --git a/ip/iplink_vxcan.c b/ip/iplink_vxcan.c index 7d44e48..66d5a53 100644 --- a/ip/iplink_vxcan.c +++ b/ip/iplink_vxcan.c @@ -31,11 +31,10 @@ static void usage(void) } static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { - char *dev = NULL; - char *name = NULL; - char *type = NULL; + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; int err; struct rtattr *data; struct ifinfomsg ifm_save, *ifm, *peer_ifm; @@ -45,7 +44,7 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv, return -1; } - ifm = NLMSG_DATA(n); + ifm = &req->i; memcpy(&ifm_save, ifm, sizeof(*ifm)); memset(ifm, 0, sizeof(*ifm)); @@ -53,12 +52,11 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv, n->nlmsg_len += sizeof(struct ifinfomsg); - err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, - &name, &type, &dev); + err = iplink_parse(argc - 1, argv + 1, pa); if (err < 0) return err; - if (type) + if (pa->type) duparg("type", argv[err]); peer_ifm = RTA_DATA(data); diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c index be9f35e..f76a2c4 100644 --- a/ip/iplink_vxlan.c +++ b/ip/iplink_vxlan.c @@ -72,8 +72,10 @@ static void check_duparg(__u64 *attrs, int type, const char *key, } static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; inet_prefix saddr, daddr; __u32 vni = 0; __u8 learning = 1; diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index c0b45f5..144141f 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -1132,8 +1132,10 @@ static void usage(FILE *f) } static int macsec_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; int ret; __u8 encoding_sa = 0xff; __u32 window = -1; diff --git a/ip/link_gre.c b/ip/link_gre.c index 6654525..f7b194f 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -64,8 +64,10 @@ static void gre_print_help(struct link_util *lu, int argc, char **argv, FILE *f) } static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u16 iflags = 0; __u16 oflags = 0; __be32 ikey = 0; @@ -91,7 +93,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&daddr); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; diff --git a/ip/link_gre6.c b/ip/link_gre6.c index a92854d..fb3e259 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -75,8 +75,10 @@ static void gre_print_help(struct link_util *lu, int argc, char **argv, FILE *f) } static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __u16 iflags = 0; __u16 oflags = 0; __be32 ikey = 0; @@ -102,7 +104,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&daddr); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index edd7632..6d9361c 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -75,8 +75,10 @@ static void ip6tunnel_print_help(struct link_util *lu, int argc, char **argv, } static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; inet_prefix saddr, daddr; __u8 hop_limit = DEFAULT_TNL_HOP_LIMIT; __u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; @@ -95,7 +97,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&daddr); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c index 0dc0db0..6df4dca 100644 --- a/ip/link_iptnl.c +++ b/ip/link_iptnl.c @@ -72,8 +72,10 @@ static void iptunnel_print_help(struct link_util *lu, int argc, char **argv, } static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; inet_prefix saddr, daddr, ip6rdprefix, ip6rdrelayprefix; __u8 pmtudisc = 1; __u8 tos = 0; @@ -95,7 +97,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&ip6rdrelayprefix); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; diff --git a/ip/link_veth.c b/ip/link_veth.c index a42ea4e..6a91729 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -29,11 +29,10 @@ static void usage(void) } static int veth_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { - char *dev = NULL; - char *name = NULL; - char *type = NULL; + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; int err; struct rtattr *data; struct ifinfomsg ifm_save, *ifm, *peer_ifm; @@ -43,7 +42,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, return -1; } - ifm = NLMSG_DATA(n); + ifm = &req->i; memcpy(&ifm_save, ifm, sizeof(*ifm)); memset(ifm, 0, sizeof(*ifm)); @@ -51,12 +50,11 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, n->nlmsg_len += sizeof(struct ifinfomsg); - err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, - &name, &type, &dev); + err = iplink_parse(argc - 1, argv + 1, pa); if (err < 0) return err; - if (type) + if (pa->type) duparg("type", argv[err]); peer_ifm = RTA_DATA(data); diff --git a/ip/link_vti.c b/ip/link_vti.c index 47c3b7f..10508e6 100644 --- a/ip/link_vti.c +++ b/ip/link_vti.c @@ -45,8 +45,10 @@ static void vti_print_help(struct link_util *lu, int argc, char **argv, FILE *f) } static int vti_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __be32 ikey = 0; __be32 okey = 0; inet_prefix saddr, daddr; @@ -57,7 +59,7 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&daddr); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; diff --git a/ip/link_vti6.c b/ip/link_vti6.c index 48c67b0..91c8521 100644 --- a/ip/link_vti6.c +++ b/ip/link_vti6.c @@ -47,8 +47,10 @@ static void vti6_print_help(struct link_util *lu, int argc, char **argv, } static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *n) + struct iplink_parse_args *pa) { + struct iplink_req *req = pa->req; + struct nlmsghdr *n = &req->n; __be32 ikey = 0; __be32 okey = 0; inet_prefix saddr, daddr; @@ -59,7 +61,7 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, inet_prefix_reset(&daddr); if (!(n->nlmsg_flags & NLM_F_CREATE)) { - struct ifinfomsg *ifi = NLMSG_DATA(n); + struct ifinfomsg *ifi = &req->i; struct { struct nlmsghdr n; struct ifinfomsg i; -- 1.7.10.4