return -1;
}
- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
return -1;
return 0;
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;
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;
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;
};
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");
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;
}
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) {
}
errout:
+ free(answer);
rtnl_close(&rth);
return ret;
}
.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");
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;
}
ret = 0;
ctrl_done:
+ free(answer);
rtnl_close(&rth);
return ret;
}
#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));
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;
return -1;
}
- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
return -2;
return 0;
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;
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);
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;
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;
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;
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;
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;
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;
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;
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;
.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]);
}
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;
}
return -1;
}
- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
return -2;
return 0;
.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),
}
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;
}
.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];
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"))
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])
if (!tb_id)
fprintf(stderr, "BUG: VRF %s is missing table id\n", name);
+out:
+ free(answer);
return tb_id;
}
.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;
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;
}
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;
return -1;
}
- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
exit(2);
return 0;
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;
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;
}
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);
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;
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;
};
char *idev = NULL;
char *odev = NULL;
+ struct nlmsghdr *answer;
int connected = 0;
int fib_match = 0;
int from_ok = 0;
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;
}
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])
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;
}
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;
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);
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;
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;
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) {
}
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;
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;
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[16384];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
__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;
if (greinfo[IFLA_GRE_ERSPAN_INDEX])
erspan_idx = rta_getattr_u32(greinfo[IFLA_GRE_ERSPAN_INDEX]);
+
+ free(answer);
}
while (argc > 0) {
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
__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;
if (greinfo[IFLA_GRE_FWMARK])
fwmark = rta_getattr_u32(greinfo[IFLA_GRE_FWMARK]);
+
+ free(answer);
}
while (argc > 0) {
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[2048];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
__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;
if (iptuninfo[IFLA_IPTUN_FWMARK])
fwmark = rta_getattr_u32(iptuninfo[IFLA_IPTUN_FWMARK]);
+
+ free(answer);
}
while (argc > 0) {
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[2048];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
__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;
if (iptuninfo[IFLA_IPTUN_FWMARK])
fwmark = rta_getattr_u32(iptuninfo[IFLA_IPTUN_FWMARK]);
+ free(answer);
}
while (argc > 0) {
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
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;
if (vtiinfo[IFLA_VTI_FWMARK])
fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
+
+ free(answer);
}
while (argc > 0) {
struct {
struct nlmsghdr n;
struct ifinfomsg i;
- char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
.n.nlmsg_flags = NLM_F_REQUEST,
.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];
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;
if (vtiinfo[IFLA_VTI_FWMARK])
fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
+
+ free(answer);
}
while (argc > 0) {
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;
}
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) {
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);
}
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 {
(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);
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;
}
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);
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;
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);
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);
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) {
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;
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);
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;
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);
{
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,
}
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;
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;
}
}
if (answer) {
- memcpy(answer, h,
- MIN(maxlen, h->nlmsg_len));
- free(buf);
+ *answer = (struct nlmsghdr *)buf;
return 0;
}
}
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)
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,
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;
}
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;
}
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;
}
}
}
- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
return 2;
return 0;
}
}
- 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;
}
.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;
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;
}
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;