aboutsummaryrefslogtreecommitdiff
path: root/networking/libiproute/libnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/libnetlink.c')
-rw-r--r--networking/libiproute/libnetlink.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index 40955fcae..b0d4166ac 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -34,7 +34,7 @@ void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
34 rth->seq = time(NULL); 34 rth->seq = time(NULL);
35} 35}
36 36
37int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 37void FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
38{ 38{
39 struct { 39 struct {
40 struct nlmsghdr nlh; 40 struct nlmsghdr nlh;
@@ -48,18 +48,45 @@ int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int ty
48 req.nlh.nlmsg_seq = rth->dump = ++rth->seq; 48 req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
49 req.g.rtgen_family = family; 49 req.g.rtgen_family = family;
50 50
51 return rtnl_send(rth, (void*)&req, sizeof(req)); 51 rtnl_send(rth, (void*)&req, sizeof(req));
52} 52}
53 53
54//TODO: pass rth->fd instead of full rth? 54/* A version which checks for e.g. EPERM errors.
55int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) 55 * Try: setuidgid 1:1 ip addr flush dev eth0
56 */
57int FAST_FUNC rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len)
56{ 58{
57 struct sockaddr_nl nladdr; 59 struct nlmsghdr *h;
60 int status;
61 char resp[1024];
58 62
59 memset(&nladdr, 0, sizeof(nladdr)); 63 status = write(rth->fd, buf, len);
60 nladdr.nl_family = AF_NETLINK; 64 if (status < 0)
65 return status;
66
67 /* Check for immediate errors */
68 status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT|MSG_PEEK);
69 if (status < 0) {
70 if (errno == EAGAIN) /* if no error, this happens */
71 return 0;
72 return -1;
73 }
61 74
62 return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); 75 for (h = (struct nlmsghdr *)resp;
76 NLMSG_OK(h, status);
77 h = NLMSG_NEXT(h, status)
78 ) {
79 if (h->nlmsg_type == NLMSG_ERROR) {
80 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
81 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
82 bb_error_msg("ERROR truncated");
83 else
84 errno = -err->error;
85 return -1;
86 }
87 }
88
89 return 0;
63} 90}
64 91
65int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) 92int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)