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 43c80e7..a234e34 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));
        ifm->ifi_index = 0;
        ifm->ifi_flags = 0;
@@ -55,12 +54,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 bd8f36e..00d5cf7 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));
        ifm->ifi_index = 0;
        ifm->ifi_flags = 0;
@@ -53,12 +52,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

Reply via email to