]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
lib/libnetlink: update rtnl_talk to support malloc buff at run time
authorHangbin Liu <liuhangbin@gmail.com>
Thu, 26 Oct 2017 01:41:47 +0000 (09:41 +0800)
committerStephen Hemminger <sthemmin@microsoft.com>
Thu, 26 Oct 2017 10:29:29 +0000 (12:29 +0200)
This is an update for 460c03f3f3cc ("iplink: double the buffer size also in
iplink_get()"). After update, we will not need to double the buffer size
every time when VFs number increased.

With call like rtnl_talk(&rth, &req.n, NULL, 0), we can simply remove the
length parameter.

With call like rtnl_talk(&rth, nlh, nlh, sizeof(req), I add a new variable
answer to avoid overwrite data in nlh, because it may has more info after
nlh. also this will avoid nlh buffer not enough issue.

We need to free answer after using.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
37 files changed:
bridge/fdb.c
bridge/link.c
bridge/mdb.c
bridge/vlan.c
genl/ctrl.c
include/libnetlink.h
ip/ipaddress.c
ip/ipaddrlabel.c
ip/ipfou.c
ip/ipila.c
ip/ipl2tp.c
ip/iplink.c
ip/iplink_vrf.c
ip/ipmacsec.c
ip/ipneigh.c
ip/ipnetns.c
ip/ipntable.c
ip/iproute.c
ip/iprule.c
ip/ipseg6.c
ip/iptoken.c
ip/link_gre.c
ip/link_gre6.c
ip/link_ip6tnl.c
ip/link_iptnl.c
ip/link_vti.c
ip/link_vti6.c
ip/tcp_metrics.c
ip/xfrm_policy.c
ip/xfrm_state.c
lib/libgenl.c
lib/libnetlink.c
misc/ss.c
tc/m_action.c
tc/tc_class.c
tc/tc_filter.c
tc/tc_qdisc.c

index e5cebf9ba69c1807bfc21578142b5b00f9af825d..807914f03d60600952ad28f593c52af5c2e27a05 100644 (file)
@@ -535,7 +535,7 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
                return -1;
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -1;
 
        return 0;
index d3a211ef01dc66b9f00115cc4121ec4b601d3b24..70aaa01b9c4e03dad716585ce1961def37b92acb 100644 (file)
@@ -439,7 +439,7 @@ static int brlink_modify(int argc, char **argv)
                addattr_nest_end(&req.n, nest);
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -1;
 
        return 0;
index 748091b8d83a7e7886c1cbe75aa2515c27f47d18..f38e326e457a0cd3c481cb2bff0b00ee362f1c63 100644 (file)
@@ -440,7 +440,7 @@ static int mdb_modify(int cmd, int flags, int argc, char **argv)
        entry.vid = vid;
        addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry));
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -1;
 
        return 0;
index ebcdacee309bc96c42b50282a173b855d097f6e7..5d683595e0e3294143cf4b80842d174b8fc4cebd 100644 (file)
@@ -133,7 +133,7 @@ static int vlan_modify(int cmd, int argc, char **argv)
 
        addattr_nest_end(&req.n, afspec);
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -1;
 
        return 0;
index 448988eb90e2b4a9307b4bfefa7c53a0b0f05b39..a6d31b04e5679f8162016e50eb71f05274c0ca84 100644 (file)
@@ -55,6 +55,7 @@ int genl_ctrl_resolve_family(const char *family)
        };
        struct nlmsghdr *nlh = &req.n;
        struct genlmsghdr *ghdr = &req.g;
+       struct nlmsghdr *answer = NULL;
 
        if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) {
                fprintf(stderr, "Cannot open generic netlink socket\n");
@@ -63,19 +64,19 @@ int genl_ctrl_resolve_family(const char *family)
 
        addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family, strlen(family) + 1);
 
-       if (rtnl_talk(&rth, nlh, nlh, sizeof(req)) < 0) {
+       if (rtnl_talk(&rth, nlh, &answer) < 0) {
                fprintf(stderr, "Error talking to the kernel\n");
                goto errout;
        }
 
        {
                struct rtattr *tb[CTRL_ATTR_MAX + 1];
-               int len = nlh->nlmsg_len;
+               int len = answer->nlmsg_len;
                struct rtattr *attrs;
 
-               if (nlh->nlmsg_type !=  GENL_ID_CTRL) {
+               if (answer->nlmsg_type !=  GENL_ID_CTRL) {
                        fprintf(stderr, "Not a controller message, nlmsg_len=%d "
-                               "nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type);
+                               "nlmsg_type=0x%x\n", answer->nlmsg_len, answer->nlmsg_type);
                        goto errout;
                }
 
@@ -88,10 +89,11 @@ int genl_ctrl_resolve_family(const char *family)
 
                if (len < 0) {
                        fprintf(stderr, "wrong controller message len %d\n", len);
+                       free(answer);
                        return -1;
                }
 
-               attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
+               attrs = (struct rtattr *) ((char *) answer + NLMSG_LENGTH(GENL_HDRLEN));
                parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
 
                if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
@@ -103,6 +105,7 @@ int genl_ctrl_resolve_family(const char *family)
        }
 
 errout:
+       free(answer);
        rtnl_close(&rth);
        return ret;
 }
@@ -299,6 +302,7 @@ static int ctrl_list(int cmd, int argc, char **argv)
                .g.cmd = CTRL_CMD_GETFAMILY,
        };
        struct nlmsghdr *nlh = &req.n;
+       struct nlmsghdr *answer = NULL;
 
        if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) {
                fprintf(stderr, "Cannot open generic netlink socket\n");
@@ -331,12 +335,12 @@ static int ctrl_list(int cmd, int argc, char **argv)
                        goto ctrl_done;
                }
 
-               if (rtnl_talk(&rth, nlh, nlh, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, nlh, &answer) < 0) {
                        fprintf(stderr, "Error talking to the kernel\n");
                        goto ctrl_done;
                }
 
-               if (print_ctrl2(NULL, nlh, (void *) stdout) < 0) {
+               if (print_ctrl2(NULL, answer, (void *) stdout) < 0) {
                        fprintf(stderr, "Dump terminated\n");
                        goto ctrl_done;
                }
@@ -358,6 +362,7 @@ static int ctrl_list(int cmd, int argc, char **argv)
 
        ret = 0;
 ctrl_done:
+       free(answer);
        rtnl_close(&rth);
        return ret;
 }
index 69257f0e605154936185b6ea5581751e6099dc90..77b62605a76c85216e1f6dacffeda60ca9525572 100644 (file)
@@ -93,13 +93,13 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth,
 #define rtnl_dump_filter(rth, filter, arg) \
        rtnl_dump_filter_nc(rth, filter, arg, 0)
 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-             struct nlmsghdr *answer, size_t len)
+             struct nlmsghdr **answer)
        __attribute__((warn_unused_result));
 int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-             struct nlmsghdr *answer, size_t len, nl_ext_ack_fn_t errfn)
+             struct nlmsghdr **answer, nl_ext_ack_fn_t errfn)
        __attribute__((warn_unused_result));
 int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-                                  struct nlmsghdr *answer, size_t len)
+                                  struct nlmsghdr **answer)
        __attribute__((warn_unused_result));
 int rtnl_send(struct rtnl_handle *rth, const void *buf, int)
        __attribute__((warn_unused_result));
index 9e9a7e0a6477fdc7f79346cd81e6a6b73e042354..c8db769e52f4a1d96259bdbd0239c9a8b42e7e2f 100644 (file)
@@ -1838,7 +1838,7 @@ static int restore_handler(const struct sockaddr_nl *nl,
 
        ll_init_map(&rth);
 
-       ret = rtnl_talk(&rth, n, n, sizeof(*n));
+       ret = rtnl_talk(&rth, n, NULL);
        if ((ret < 0) && (errno == EEXIST))
                ret = 0;
 
@@ -2534,7 +2534,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
                return -1;
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 1d324dac02119acffaa34ce77205f5eacb39b2ab..6ea9bfffdd0d1cfcc186bc58c1ef460d9f6446c7 100644 (file)
@@ -176,7 +176,7 @@ static int ipaddrlabel_modify(int cmd, int argc, char **argv)
        if (req.ifal.ifal_family == AF_UNSPEC)
                req.ifal.ifal_family = AF_INET6;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -203,7 +203,7 @@ static int flush_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, vo
                if (rtnl_open(&rth2, 0) < 0)
                        return -1;
 
-               if (rtnl_talk(&rth2, n, NULL, 0) < 0)
+               if (rtnl_talk(&rth2, n, NULL) < 0)
                        return -2;
 
                rtnl_close(&rth2);
index 00dbe150710d2135bf62dfb47bd7c61168259133..23000dc696d6ae8148d69e9d6f6066c978fb0b24 100644 (file)
@@ -116,7 +116,7 @@ static int do_add(int argc, char **argv)
 
        fou_parse_opt(argc, argv, &req.n, true);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -128,7 +128,7 @@ static int do_del(int argc, char **argv)
 
        fou_parse_opt(argc, argv, &req.n, false);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 843cc1652589f1c668af836215d2ce4234bca199..0403fc4238b9d8b301c6e08e704f07bfce7c53e8 100644 (file)
@@ -220,7 +220,7 @@ static int do_add(int argc, char **argv)
 
        ila_parse_opt(argc, argv, &req.n, true);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -232,7 +232,7 @@ static int do_del(int argc, char **argv)
 
        ila_parse_opt(argc, argv, &req.n, false);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 1e37b175e33150fb07239d4fe8e37144afcfd873..7c5ed313b186ff7d44745c901d0ff15c7cf25434 100644 (file)
@@ -129,7 +129,7 @@ static int create_tunnel(struct l2tp_parm *p)
                        addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_RX);
        }
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -142,7 +142,7 @@ static int delete_tunnel(struct l2tp_parm *p)
 
        addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->tunnel_id);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -185,7 +185,7 @@ static int create_session(struct l2tp_parm *p)
        if (p->ifname)
                addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname);
 
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -198,7 +198,7 @@ static int delete_session(struct l2tp_parm *p)
 
        addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id);
        addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id);
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 6a96ea9ff56a7f7694c267a1524d696c1225a16c..0daca3f9d476399e6d4ddd423bbfb83732a05a56 100644 (file)
@@ -249,19 +249,26 @@ static int nl_get_ll_addr_len(unsigned int dev_index)
                        .ifi_index = dev_index,
                }
        };
+       struct nlmsghdr *answer;
        struct rtattr *tb[IFLA_MAX+1];
 
-       if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                return -1;
 
-       len = req.n.nlmsg_len - NLMSG_LENGTH(sizeof(req.i));
-       if (len < 0)
+       len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
+       if (len < 0) {
+               free(answer);
                return -1;
+       }
 
-       parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(&req.i), len, NLA_F_NESTED);
-       if (!tb[IFLA_ADDRESS])
+       parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)),
+                          len, NLA_F_NESTED);
+       if (!tb[IFLA_ADDRESS]) {
+               free(answer);
                return -1;
+       }
 
+       free(answer);
        return RTA_PAYLOAD(tb[IFLA_ADDRESS]);
 }
 
@@ -916,7 +923,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 
                        req.i.ifi_index = 0;
                        addattr32(&req.n, sizeof(req), IFLA_GROUP, group);
-                       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+                       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                                return -2;
                        return 0;
                }
@@ -1006,7 +1013,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
                return -1;
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -1020,10 +1027,7 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
                .n.nlmsg_type = RTM_GETLINK,
                .i.ifi_family = preferred_family,
        };
-       struct {
-               struct nlmsghdr n;
-               char buf[32768];
-       } answer;
+       struct nlmsghdr *answer;
 
        if (name) {
                addattr_l(&req.n, sizeof(req),
@@ -1031,21 +1035,17 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
        }
        addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
 
-       if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
-               return -2;
-       if (answer.n.nlmsg_len > sizeof(answer.buf)) {
-               fprintf(stderr, "Message truncated from %u to %lu\n",
-                       answer.n.nlmsg_len, sizeof(answer.buf));
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                return -2;
-       }
 
        open_json_object(NULL);
        if (brief)
-               print_linkinfo_brief(NULL, &answer.n, stdout, NULL);
+               print_linkinfo_brief(NULL, answer, stdout, NULL);
        else
-               print_linkinfo(NULL, &answer.n, stdout);
+               print_linkinfo(NULL, answer, stdout);
        close_json_object();
 
+       free(answer);
        return 0;
 }
 
index 7a1bb5e765e16b430fe0e0e53e3087541b70b9cb..e9dd0df9841294dfc3b13478b904dbe3e027ded5 100644 (file)
@@ -119,10 +119,7 @@ __u32 ipvrf_get_table(const char *name)
                        .ifi_family  = preferred_family,
                },
        };
-       struct {
-               struct nlmsghdr n;
-               char buf[8192];
-       } answer;
+       struct nlmsghdr *answer;
        struct rtattr *tb[IFLA_MAX+1];
        struct rtattr *li[IFLA_INFO_MAX+1];
        struct rtattr *vrf_attr[IFLA_VRF_MAX + 1];
@@ -132,8 +129,7 @@ __u32 ipvrf_get_table(const char *name)
 
        addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
 
-       if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n,
-                                          &answer.n, sizeof(answer)) < 0) {
+       if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0) {
                /* special case "default" vrf to be the main table */
                if (errno == ENODEV && !strcmp(name, "default"))
                        if (rtnl_rttable_a2n(&tb_id, "main"))
@@ -143,25 +139,25 @@ __u32 ipvrf_get_table(const char *name)
                return tb_id;
        }
 
-       ifi = NLMSG_DATA(&answer.n);
-       len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+       ifi = NLMSG_DATA(answer);
+       len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
        if (len < 0) {
                fprintf(stderr, "BUG: Invalid response to link query.\n");
-               return 0;
+               goto out;
        }
 
        parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 
        if (!tb[IFLA_LINKINFO])
-               return 0;
+               goto out;
 
        parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
 
        if (!li[IFLA_INFO_KIND] || !li[IFLA_INFO_DATA])
-               return 0;
+               goto out;
 
        if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
-               return 0;
+               goto out;
 
        parse_rtattr_nested(vrf_attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]);
        if (vrf_attr[IFLA_VRF_TABLE])
@@ -170,6 +166,8 @@ __u32 ipvrf_get_table(const char *name)
        if (!tb_id)
                fprintf(stderr, "BUG: VRF %s is missing table id\n", name);
 
+out:
+       free(answer);
        return tb_id;
 }
 
@@ -189,10 +187,7 @@ int name_is_vrf(const char *name)
                        .ifi_family  = preferred_family,
                },
        };
-       struct {
-               struct nlmsghdr n;
-               char buf[8192];
-       } answer;
+       struct nlmsghdr *answer;
        struct rtattr *tb[IFLA_MAX+1];
        struct rtattr *li[IFLA_INFO_MAX+1];
        struct ifinfomsg *ifi;
@@ -200,29 +195,30 @@ int name_is_vrf(const char *name)
 
        addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
 
-       if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n,
-                                          &answer.n, sizeof(answer)) < 0)
+       if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0)
                return 0;
 
-       ifi = NLMSG_DATA(&answer.n);
-       len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+       ifi = NLMSG_DATA(answer);
+       len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
        if (len < 0) {
                fprintf(stderr, "BUG: Invalid response to link query.\n");
-               return 0;
+               goto out;
        }
 
        parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 
        if (!tb[IFLA_LINKINFO])
-               return 0;
+               goto out;
 
        parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
 
        if (!li[IFLA_INFO_KIND])
-               return 0;
+               goto out;
 
        if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
-               return 0;
+               goto out;
 
+out:
+       free(answer);
        return ifi->ifi_index;
 }
index ecc371a51a207fffd2122d34d3c07532d9b3f1d1..345a7073c76b69e6721cc429a8725fe7100e2112 100644 (file)
@@ -421,7 +421,7 @@ static int do_modify_nl(enum cmd c, enum macsec_nl_commands cmd, int ifindex,
        addattr_nest_end(&req.n, attr_sa);
 
 talk:
-       if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 9c38a60ddf4fee5f0a0208874d32136cf281a0ed..32f2d553c712f1629c0700d742a97e65ed8882d0 100644 (file)
@@ -184,7 +184,7 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
                return -1;
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        return 0;
index afb4978a5be7da0caa5f5993d8f8d5ff0d960208..bc70997e7757bd826930989ded58053ed1a73b4a 100644 (file)
@@ -95,12 +95,13 @@ static int get_netnsid_from_name(const char *name)
                struct nlmsghdr n;
                struct rtgenmsg g;
                char            buf[1024];
-       } answer, req = {
+       } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
                .n.nlmsg_flags = NLM_F_REQUEST,
                .n.nlmsg_type = RTM_GETNSID,
                .g.rtgen_family = AF_UNSPEC,
        };
+       struct nlmsghdr *answer;
        struct rtattr *tb[NETNSA_MAX + 1];
        struct rtgenmsg *rthdr;
        int len, fd;
@@ -110,26 +111,30 @@ static int get_netnsid_from_name(const char *name)
                return fd;
 
        addattr32(&req.n, 1024, NETNSA_FD, fd);
-       if (rtnl_talk(&rtnsh, &req.n, &answer.n, sizeof(answer)) < 0) {
+       if (rtnl_talk(&rtnsh, &req.n, &answer) < 0) {
                close(fd);
                return -2;
        }
        close(fd);
 
        /* Validate message and parse attributes */
-       if (answer.n.nlmsg_type == NLMSG_ERROR)
-               return -1;
+       if (answer->nlmsg_type == NLMSG_ERROR)
+               goto err_out;
 
-       rthdr = NLMSG_DATA(&answer.n);
-       len = answer.n.nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
+       rthdr = NLMSG_DATA(answer);
+       len = answer->nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
        if (len < 0)
-               return -1;
+               goto err_out;
 
        parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);
 
-       if (tb[NETNSA_NSID])
+       if (tb[NETNSA_NSID]) {
+               free(answer);
                return rta_getattr_u32(tb[NETNSA_NSID]);
+       }
 
+err_out:
+       free(answer);
        return -1;
 }
 
@@ -689,7 +694,7 @@ static int set_netnsid_from_name(const char *name, int nsid)
 
        addattr32(&req.n, 1024, NETNSA_FD, fd);
        addattr32(&req.n, 1024, NETNSA_NSID, nsid);
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                err = -2;
 
        close(fd);
index 88236ce0ec1e16083458caf67f465ecafe374ff4..2f72c989f35dfcecc176dafead8a2872e6a10505 100644 (file)
@@ -304,7 +304,7 @@ static int ipntable_modify(int cmd, int flags, int argc, char **argv)
                          RTA_PAYLOAD(parms_rta));
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        return 0;
index e81bc05ec16cb2985bc8685cda8f3e60f6d6a4c2..531af776e595609fb75cc5052cc02a4c8c30167b 100644 (file)
@@ -1300,7 +1300,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
        if (!type_ok && req.r.rtm_family == AF_MPLS)
                req.r.rtm_type = RTN_UNICAST;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
@@ -1680,6 +1680,7 @@ static int iproute_get(int argc, char **argv)
        };
        char  *idev = NULL;
        char  *odev = NULL;
+       struct nlmsghdr *answer;
        int connected = 0;
        int fib_match = 0;
        int from_ok = 0;
@@ -1800,26 +1801,29 @@ static int iproute_get(int argc, char **argv)
        if (fib_match)
                req.r.rtm_flags |= RTM_F_FIB_MATCH;
 
-       if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                return -2;
 
        if (connected && !from_ok) {
-               struct rtmsg *r = NLMSG_DATA(&req.n);
-               int len = req.n.nlmsg_len;
+               struct rtmsg *r = NLMSG_DATA(answer);
+               int len = answer->nlmsg_len;
                struct rtattr *tb[RTA_MAX+1];
 
-               if (print_route(NULL, &req.n, (void *)stdout) < 0) {
+               if (print_route(NULL, answer, (void *)stdout) < 0) {
                        fprintf(stderr, "An error :-)\n");
+                       free(answer);
                        return -1;
                }
 
-               if (req.n.nlmsg_type != RTM_NEWROUTE) {
+               if (answer->nlmsg_type != RTM_NEWROUTE) {
                        fprintf(stderr, "Not a route?\n");
+                       free(answer);
                        return -1;
                }
                len -= NLMSG_LENGTH(sizeof(*r));
                if (len < 0) {
                        fprintf(stderr, "Wrong len %d\n", len);
+                       free(answer);
                        return -1;
                }
 
@@ -1830,6 +1834,7 @@ static int iproute_get(int argc, char **argv)
                        r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
                } else if (!tb[RTA_SRC]) {
                        fprintf(stderr, "Failed to connect the route\n");
+                       free(answer);
                        return -1;
                }
                if (!odev && tb[RTA_OIF])
@@ -1843,15 +1848,18 @@ static int iproute_get(int argc, char **argv)
                req.n.nlmsg_flags = NLM_F_REQUEST;
                req.n.nlmsg_type = RTM_GETROUTE;
 
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
+               free(answer);
+               if (rtnl_talk(&rth, &req.n, &answer) < 0)
                        return -2;
        }
 
-       if (print_route(NULL, &req.n, (void *)stdout) < 0) {
+       if (print_route(NULL, answer, (void *)stdout) < 0) {
                fprintf(stderr, "An error :-)\n");
+               free(answer);
                return -1;
        }
 
+       free(answer);
        return 0;
 }
 
@@ -1895,7 +1903,7 @@ restore:
 
        ll_init_map(&rth);
 
-       ret = rtnl_talk(&rth, n, n, sizeof(*n));
+       ret = rtnl_talk(&rth, n, NULL);
        if ((ret < 0) && (errno == EEXIST))
                ret = 0;
 
index 36c57fa70b74a1cbdd3692c8f3342633a2cf6c4a..201d3bdc204278e9c3866276f2b0001f29806edf 100644 (file)
@@ -393,7 +393,7 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
                if (rtnl_open(&rth2, 0) < 0)
                        return -1;
 
-               if (rtnl_talk(&rth2, n, NULL, 0) < 0)
+               if (rtnl_talk(&rth2, n, NULL) < 0)
                        return -2;
 
                rtnl_close(&rth2);
@@ -555,7 +555,7 @@ static int restore_handler(const struct sockaddr_nl *nl,
 
        ll_init_map(&rth);
 
-       ret = rtnl_talk(&rth, n, n, sizeof(*n));
+       ret = rtnl_talk(&rth, n, NULL);
        if ((ret < 0) && (errno == EEXIST))
                ret = 0;
 
@@ -766,7 +766,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
        if (!table_ok && cmd == RTM_NEWRULE)
                req.r.rtm_table = RT_TABLE_MAIN;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index a8f5c69182f54800df5b58d87c7d0713074a8498..461a3c1c15d45a97be7067d359367fb968859777 100644 (file)
@@ -125,6 +125,7 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
 static int seg6_do_cmd(void)
 {
        SEG6_REQUEST(req, 1024, opts.cmd, NLM_F_REQUEST);
+       struct nlmsghdr *answer;
        int repl = 0, dump = 0;
 
        if (genl_family < 0) {
@@ -163,15 +164,16 @@ static int seg6_do_cmd(void)
        }
 
        if (!repl && !dump) {
-               if (rtnl_talk(&grth, &req.n, NULL, 0) < 0)
+               if (rtnl_talk(&grth, &req.n, NULL) < 0)
                        return -1;
        } else if (repl) {
-               if (rtnl_talk(&grth, &req.n, &req.n, sizeof(req)) < 0)
+               if (rtnl_talk(&grth, &req.n, &answer) < 0)
                        return -2;
-               if (process_msg(NULL, &req.n, stdout) < 0) {
+               if (process_msg(NULL, answer, stdout) < 0) {
                        fprintf(stderr, "Error parsing reply\n");
                        exit(1);
                }
+               free(answer);
        } else {
                req.n.nlmsg_flags |= NLM_F_DUMP;
                req.n.nlmsg_seq = grth.dump = ++grth.seq;
index 1869f764424ff92b157e271095dc7c1b3132297f..0528bad70a80e6357b8107a8cd687a84f47c2e26 100644 (file)
@@ -166,7 +166,7 @@ static int iptoken_set(int argc, char **argv, bool delete)
        addattr_nest_end(&req.n, afs6);
        addattr_nest_end(&req.n, afs);
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -2;
 
        return 0;
index 9ea2970cadc24ecfbe6aafa0fe9e11f85148e5e8..35782caaa68b4c193b6873f370d9590110ed1a4a 100644 (file)
@@ -68,7 +68,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[16384];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -76,6 +75,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *greinfo[IFLA_GRE_MAX + 1];
@@ -100,19 +100,20 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
        __u32 erspan_idx = 0;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -177,6 +178,8 @@ get_failed:
 
                if (greinfo[IFLA_GRE_ERSPAN_INDEX])
                        erspan_idx = rta_getattr_u32(greinfo[IFLA_GRE_ERSPAN_INDEX]);
+
+               free(answer);
        }
 
        while (argc > 0) {
index 7d07932a60f01f93f314fb6c2f79981b10ec9527..2eedec85df6fa8318933af2607e5729467bc4e7e 100644 (file)
@@ -78,7 +78,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[1024];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -86,6 +85,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *greinfo[IFLA_GRE_MAX + 1];
@@ -108,19 +108,20 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
        __u32 fwmark = 0;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -180,6 +181,8 @@ get_failed:
 
                if (greinfo[IFLA_GRE_FWMARK])
                        fwmark = rta_getattr_u32(greinfo[IFLA_GRE_FWMARK]);
+
+               free(answer);
        }
 
        while (argc > 0) {
index a41990068f0f7258ee3a0e2bbdfed5bcac457911..2f8c3f3400327f36ee48852ab8090a7db7f3aa24 100644 (file)
@@ -75,7 +75,6 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[2048];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -83,6 +82,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
@@ -103,19 +103,20 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
        __u32 fwmark = 0;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -158,6 +159,8 @@ get_failed:
 
                if (iptuninfo[IFLA_IPTUN_FWMARK])
                        fwmark = rta_getattr_u32(iptuninfo[IFLA_IPTUN_FWMARK]);
+
+               free(answer);
        }
 
        while (argc > 0) {
index 6a725e91ea7065958ea429dc1fbec6434a419a45..4940b8b0e7b7d211127fc6c653e30eef5425ad31 100644 (file)
@@ -76,7 +76,6 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[2048];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -84,6 +83,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
@@ -108,19 +108,20 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
        __u32 fwmark = 0;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -188,6 +189,7 @@ get_failed:
                if (iptuninfo[IFLA_IPTUN_FWMARK])
                        fwmark = rta_getattr_u32(iptuninfo[IFLA_IPTUN_FWMARK]);
 
+               free(answer);
        }
 
        while (argc > 0) {
index 8bd4d90059fc1cceb2d6a63403025330404482db..07ac94e7dc6669b95c9e2c8f99174c6f51b99467 100644 (file)
@@ -53,7 +53,6 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[1024];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -61,6 +60,7 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
@@ -73,19 +73,20 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
        int len;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -115,6 +116,8 @@ get_failed:
 
                if (vtiinfo[IFLA_VTI_FWMARK])
                        fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
+
+               free(answer);
        }
 
        while (argc > 0) {
index 8198d4680b93fad21c427969e4d83f5b24528014..6d08bfe0f7990f74bb466770e3b38c152de60544 100644 (file)
@@ -48,7 +48,6 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
        struct {
                struct nlmsghdr n;
                struct ifinfomsg i;
-               char buf[1024];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
                .n.nlmsg_flags = NLM_F_REQUEST,
@@ -56,6 +55,7 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
                .i.ifi_family = preferred_family,
                .i.ifi_index = ifi->ifi_index,
        };
+       struct nlmsghdr *answer = NULL;
        struct rtattr *tb[IFLA_MAX + 1];
        struct rtattr *linkinfo[IFLA_INFO_MAX+1];
        struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
@@ -68,19 +68,20 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
        int len;
 
        if (!(n->nlmsg_flags & NLM_F_CREATE)) {
-               if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
+               if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
                        fprintf(stderr,
                                "Failed to get existing tunnel info.\n");
+                       free(answer);
                        return -1;
                }
 
-               len = req.n.nlmsg_len;
+               len = answer->nlmsg_len;
                len -= NLMSG_LENGTH(sizeof(*ifi));
                if (len < 0)
                        goto get_failed;
 
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
+               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
 
                if (!tb[IFLA_LINKINFO])
                        goto get_failed;
@@ -110,6 +111,8 @@ get_failed:
 
                if (vtiinfo[IFLA_VTI_FWMARK])
                        fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
+
+               free(answer);
        }
 
        while (argc > 0) {
index 8972acd05fb28fd91d052c89a8ae9e90eb80c8b0..3f9790e8fedde4a60cea53c0d283ebbffdbc3512 100644 (file)
@@ -306,6 +306,7 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
 static int tcpm_do_cmd(int cmd, int argc, char **argv)
 {
        TCPM_REQUEST(req, 1024, TCP_METRICS_CMD_GET, NLM_F_REQUEST);
+       struct nlmsghdr *answer;
        int atype = -1, stype = -1;
        int ack;
 
@@ -457,15 +458,16 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv)
        }
 
        if (ack) {
-               if (rtnl_talk(&grth, &req.n, NULL, 0) < 0)
+               if (rtnl_talk(&grth, &req.n, NULL) < 0)
                        return -2;
        } else if (atype >= 0) {
-               if (rtnl_talk(&grth, &req.n, &req.n, sizeof(req)) < 0)
+               if (rtnl_talk(&grth, &req.n, &answer) < 0)
                        return -2;
-               if (process_msg(NULL, &req.n, stdout) < 0) {
+               if (process_msg(NULL, answer, stdout) < 0) {
                        fprintf(stderr, "Dump terminated\n");
                        exit(1);
                }
+               free(answer);
        } else {
                req.n.nlmsg_seq = grth.dump = ++grth.seq;
                if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
index de689c4d86c4df0223bb05033c2b0156014b2a0a..98460a072bd4e6c736b3c131b9d9a33cf731e3a8 100644 (file)
@@ -386,7 +386,7 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv
        if (req.xpinfo.sel.family == AF_UNSPEC)
                req.xpinfo.sel.family = AF_INET;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        rtnl_close(&rth);
@@ -548,7 +548,7 @@ int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
 }
 
 static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
-                                    void *res_nlbuf, size_t res_size)
+                                    struct nlmsghdr **answer)
 {
        struct rtnl_handle rth;
        struct {
@@ -659,7 +659,7 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
                          (void *)&ctx, ctx.sctx.len);
        }
 
-       if (rtnl_talk(&rth, &req.n, res_nlbuf, res_size) < 0)
+       if (rtnl_talk(&rth, &req.n, answer) < 0)
                exit(2);
 
        rtnl_close(&rth);
@@ -669,21 +669,21 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
 
 static int xfrm_policy_delete(int argc, char **argv)
 {
-       return xfrm_policy_get_or_delete(argc, argv, 1, NULL, 0);
+       return xfrm_policy_get_or_delete(argc, argv, 1, NULL);
 }
 
 static int xfrm_policy_get(int argc, char **argv)
 {
-       char buf[NLMSG_BUF_SIZE] = {};
-       struct nlmsghdr *n = (struct nlmsghdr *)buf;
+       struct nlmsghdr *n = NULL;
 
-       xfrm_policy_get_or_delete(argc, argv, 0, n, sizeof(buf));
+       xfrm_policy_get_or_delete(argc, argv, 0, &n);
 
        if (xfrm_policy_print(NULL, n, (void *)stdout) < 0) {
                fprintf(stderr, "An error :-)\n");
                exit(1);
        }
 
+       free(n);
        return 0;
 }
 
@@ -1049,7 +1049,7 @@ static int xfrm_spd_setinfo(int argc, char **argv)
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        rtnl_close(&rth);
@@ -1063,22 +1063,23 @@ static int xfrm_spd_getinfo(int argc, char **argv)
        struct {
                struct nlmsghdr                 n;
                __u32                           flags;
-               char                            ans[128];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32)),
                .n.nlmsg_flags = NLM_F_REQUEST,
                .n.nlmsg_type = XFRM_MSG_GETSPDINFO,
                .flags = 0XFFFFFFFF,
        };
+       struct nlmsghdr *answer;
 
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);
 
-       if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                exit(2);
 
-       print_spdinfo(&req.n, (void *)stdout);
+       print_spdinfo(answer, (void *)stdout);
 
+       free(answer);
        rtnl_close(&rth);
 
        return 0;
@@ -1123,7 +1124,7 @@ static int xfrm_policy_flush(int argc, char **argv)
        if (show_stats > 1)
                fprintf(stderr, "Flush policy\n");
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        rtnl_close(&rth);
index 99fdec2325ec026856b458484865bbf4c939450a..3e20d6ed08d1c1e9c2ee9a15ce10ec9df86036a1 100644 (file)
@@ -726,7 +726,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)
        if (req.xsinfo.family == AF_UNSPEC)
                req.xsinfo.family = AF_INET;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        rtnl_close(&rth);
@@ -757,8 +757,7 @@ static int xfrm_state_allocspi(int argc, char **argv)
        char *minp = NULL;
        char *maxp = NULL;
        struct xfrm_mark mark = {0, 0};
-       char res_buf[NLMSG_BUF_SIZE] = {};
-       struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
+       struct nlmsghdr *answer;
 
        while (argc > 0) {
                if (strcmp(*argv, "mode") == 0) {
@@ -858,14 +857,15 @@ static int xfrm_state_allocspi(int argc, char **argv)
                req.xspi.info.family = AF_INET;
 
 
-       if (rtnl_talk(&rth, &req.n, res_n, sizeof(res_buf)) < 0)
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                exit(2);
 
-       if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) {
+       if (xfrm_state_print(NULL, answer, (void *)stdout) < 0) {
                fprintf(stderr, "An error :-)\n");
                exit(1);
        }
 
+       free(answer);
        rtnl_close(&rth);
 
        return 0;
@@ -1046,19 +1046,20 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
                req.xsid.family = AF_INET;
 
        if (delete) {
-               if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+               if (rtnl_talk(&rth, &req.n, NULL) < 0)
                        exit(2);
        } else {
-               char buf[NLMSG_BUF_SIZE] = {};
-               struct nlmsghdr *res_n = (struct nlmsghdr *)buf;
+               struct nlmsghdr *answer;
 
-               if (rtnl_talk(&rth, &req.n, res_n, sizeof(req)) < 0)
+               if (rtnl_talk(&rth, &req.n, &answer) < 0)
                        exit(2);
 
-               if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) {
+               if (xfrm_state_print(NULL, answer, (void *)stdout) < 0) {
                        fprintf(stderr, "An error :-)\n");
                        exit(1);
                }
+
+               free(answer);
        }
 
        rtnl_close(&rth);
@@ -1314,22 +1315,23 @@ static int xfrm_sad_getinfo(int argc, char **argv)
        struct {
                struct nlmsghdr                 n;
                __u32                           flags;
-               char                            ans[64];
        } req = {
                .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.flags)),
                .n.nlmsg_flags = NLM_F_REQUEST,
                .n.nlmsg_type = XFRM_MSG_GETSADINFO,
                .flags = 0XFFFFFFFF,
        };
+       struct nlmsghdr *answer;
 
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);
 
-       if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
+       if (rtnl_talk(&rth, &req.n, &answer) < 0)
                exit(2);
 
-       print_sadinfo(&req.n, (void *)stdout);
+       print_sadinfo(answer, (void *)stdout);
 
+       free(answer);
        rtnl_close(&rth);
 
        return 0;
@@ -1376,7 +1378,7 @@ static int xfrm_state_flush(int argc, char **argv)
                fprintf(stderr, "Flush state with XFRM-PROTO value \"%s\"\n",
                        strxf_xfrmproto(req.xsf.proto));
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                exit(2);
 
        rtnl_close(&rth);
index 50d2d9217dcbc7dd7f1d22618e69eac84f44571d..bb5fbb5f518d2f6ce64b031acf8d566190529edf 100644 (file)
@@ -49,16 +49,21 @@ int genl_resolve_family(struct rtnl_handle *grth, const char *family)
 {
        GENL_REQUEST(req, 1024, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY,
                     NLM_F_REQUEST);
+       struct nlmsghdr *answer;
+       int fnum;
 
        addattr_l(&req.n, sizeof(req), CTRL_ATTR_FAMILY_NAME,
                  family, strlen(family) + 1);
 
-       if (rtnl_talk(grth, &req.n, &req.n, sizeof(req)) < 0) {
+       if (rtnl_talk(grth, &req.n, &answer) < 0) {
                fprintf(stderr, "Error talking to the kernel\n");
                return -2;
        }
 
-       return genl_parse_getfamily(&req.n);
+       fnum = genl_parse_getfamily(answer);
+       free(answer);
+
+       return fnum;
 }
 
 int genl_init_handle(struct rtnl_handle *grth, const char *family,
index 1847c0be6d6b3459ffe092fbcd661f744d694e2d..4618dc0e3247051c3701eae28d4a2a69541295e9 100644 (file)
@@ -577,7 +577,7 @@ static void rtnl_talk_error(struct nlmsghdr *h, struct nlmsgerr *err,
 }
 
 static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-                      struct nlmsghdr *answer, size_t maxlen,
+                      struct nlmsghdr **answer,
                       bool show_rtnl_err, nl_ext_ack_fn_t errfn)
 {
        int status;
@@ -651,9 +651,9 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
                                        fprintf(stderr, "ERROR truncated\n");
                                } else if (!err->error) {
                                        if (answer)
-                                               memcpy(answer, h,
-                                                      MIN(maxlen, h->nlmsg_len));
-                                       free(buf);
+                                               *answer = (struct nlmsghdr *)buf;
+                                       else
+                                               free(buf);
                                        return 0;
                                }
 
@@ -667,9 +667,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
                        }
 
                        if (answer) {
-                               memcpy(answer, h,
-                                      MIN(maxlen, h->nlmsg_len));
-                               free(buf);
+                               *answer = (struct nlmsghdr *)buf;
                                return 0;
                        }
 
@@ -693,22 +691,22 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 }
 
 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-             struct nlmsghdr *answer, size_t maxlen)
+             struct nlmsghdr **answer)
 {
-       return __rtnl_talk(rtnl, n, answer, maxlen, true, NULL);
+       return __rtnl_talk(rtnl, n, answer, true, NULL);
 }
 
 int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-                    struct nlmsghdr *answer, size_t maxlen,
+                    struct nlmsghdr **answer,
                     nl_ext_ack_fn_t errfn)
 {
-       return __rtnl_talk(rtnl, n, answer, maxlen, true, errfn);
+       return __rtnl_talk(rtnl, n, answer, true, errfn);
 }
 
 int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-                                  struct nlmsghdr *answer, size_t maxlen)
+                                  struct nlmsghdr **answer)
 {
-       return __rtnl_talk(rtnl, n, answer, maxlen, false, NULL);
+       return __rtnl_talk(rtnl, n, answer, false, NULL);
 }
 
 int rtnl_listen_all_nsid(struct rtnl_handle *rth)
index 6b8eee6ba5726360f6fb7830d1658e67e8b3de56..23710045efb5235957e641bff61d8b430203e6d6 100644 (file)
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2696,7 +2696,7 @@ static int kill_inet_sock(struct nlmsghdr *h, void *arg, struct sockstat *s)
                raw->sdiag_raw_protocol = s->raw_prot;
        }
 
-       return rtnl_talk(rth, &req.nlh, NULL, 0);
+       return rtnl_talk(rth, &req.nlh, NULL);
 }
 
 static int show_one_inet_sock(const struct sockaddr_nl *addr,
index 402228bbf833daad54d374be6b89f3c7d7a6dbbf..8cbf764138a1f2ade4e16815f5cdf884f4c466a8 100644 (file)
@@ -518,18 +518,18 @@ static int tc_action_gd(int cmd, unsigned int flags, int *argc_p, char ***argv_p
        tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
 
        req.n.nlmsg_seq = rth.dump = ++rth.seq;
-       if (cmd == RTM_GETACTION)
-               ans = &req.n;
 
-       if (rtnl_talk(&rth, &req.n, ans, MAX_MSG) < 0) {
+       if (rtnl_talk(&rth, &req.n, &ans) < 0) {
                fprintf(stderr, "We have an error talking to the kernel\n");
                return 1;
        }
 
-       if (ans && print_action(NULL, &req.n, (void *)stdout) < 0) {
+       if (cmd == RTM_GETACTION && print_action(NULL, ans, stdout) < 0) {
                fprintf(stderr, "Dump terminated\n");
+               free(ans);
                return 1;
        }
+       free(ans);
 
        *argc_p = argc;
        *argv_p = argv;
@@ -562,7 +562,7 @@ static int tc_action_modify(int cmd, unsigned int flags, int *argc_p, char ***ar
        }
        tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) {
+       if (rtnl_talk(&rth, &req.n, NULL) < 0) {
                fprintf(stderr, "We have an error talking to the kernel\n");
                ret = -1;
        }
@@ -653,7 +653,7 @@ static int tc_act_list_or_flush(int *argc_p, char ***argv_p, int event)
                req.n.nlmsg_type = RTM_DELACTION;
                req.n.nlmsg_flags |= NLM_F_ROOT;
                req.n.nlmsg_flags |= NLM_F_REQUEST;
-               if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) {
+               if (rtnl_talk(&rth, &req.n, NULL) < 0) {
                        fprintf(stderr, "We have an error flushing\n");
                        return 1;
                }
index 1a1f1fa225b40aab80001d6c715cb798ee6e2b35..0214775b95a6ca83b0a2ce4255d3af7ccef2203e 100644 (file)
@@ -149,7 +149,7 @@ static int tc_class_modify(int cmd, unsigned int flags, int argc, char **argv)
                }
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return 2;
 
        return 0;
index cf290ae8e252c50bbdc5c79ac80f04350ce0faa2..8dbebf1ffa32a4aeaeb18414e6640c3cd545b26b 100644 (file)
@@ -194,7 +194,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
                }
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) {
+       if (rtnl_talk(&rth, &req.n, NULL) < 0) {
                fprintf(stderr, "We have an error talking to the kernel\n");
                return 2;
        }
@@ -331,6 +331,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
                .t.tcm_parent = TC_H_UNSPEC,
                .t.tcm_family = AF_UNSPEC,
        };
+       struct nlmsghdr *answer;
        struct filter_util *q = NULL;
        __u32 prio = 0;
        __u32 protocol = 0;
@@ -484,13 +485,14 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
                return -1;
        }
 
-       if (rtnl_talk(&rth, &req.n, &req.n, MAX_MSG) < 0) {
+       if (rtnl_talk(&rth, &req.n, &answer) < 0) {
                fprintf(stderr, "We have an error talking to the kernel\n");
                return 2;
        }
 
-       print_filter(NULL, &req.n, (void *)stdout);
+       print_filter(NULL, answer, (void *)stdout);
 
+       free(answer);
        return 0;
 }
 
index 1e9d909789e60637173c8a9cc5e1975eccb156a9..c52114a272cf61c7a88a1af4cd3e72869e941fc5 100644 (file)
@@ -190,7 +190,7 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv)
                req.t.tcm_ifindex = idx;
        }
 
-       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+       if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return 2;
 
        return 0;