diff --git a/include/libnetlink.h b/include/libnetlink.h index 616a1117b..92eded420 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -7,7 +7,8 @@ extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int le #define parse_rtattr_nested(tb, max, rta) \ (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) extern int do_rtnl_req(int nl, void *req, int size, - int (*receive_callback)(struct nlmsghdr *h, void *), void *); + int (*receive_callback)(struct nlmsghdr *h, void *), + int (*error_callback)(int err, void *), void *); extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen); diff --git a/libnetlink.c b/libnetlink.c index f3ed7cce5..84ee6eb2b 100644 --- a/libnetlink.c +++ b/libnetlink.c @@ -21,7 +21,8 @@ int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) return 0; } -static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), void *arg) +static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), + int (*err_cb)(int, void *), void *arg) { struct nlmsghdr *hdr; @@ -50,8 +51,7 @@ static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void * if (err->error == 0) return 0; - pr_warn("ERROR %d reported by netlink\n", err->error); - return err->error; + return err_cb(err->error, arg); } if (cb(hdr, arg)) return -1; @@ -60,8 +60,15 @@ static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void * return 1; } +static int rtnl_return_err(int err, void *arg) +{ + pr_warn("ERROR %d reported by netlink\n", err); + return err; +} + int do_rtnl_req(int nl, void *req, int size, - int (*receive_callback)(struct nlmsghdr *h, void *), void *arg) + int (*receive_callback)(struct nlmsghdr *h, void *), + int (*error_callback)(int err, void *), void *arg) { struct msghdr msg; struct sockaddr_nl nladdr; @@ -69,6 +76,9 @@ int do_rtnl_req(int nl, void *req, int size, static char buf[4096]; int err; + if (!error_callback) + error_callback = rtnl_return_err; + memset(&msg, 0, sizeof(msg)); msg.msg_name = &nladdr; msg.msg_namelen = sizeof(nladdr); @@ -111,7 +121,7 @@ int do_rtnl_req(int nl, void *req, int size, if (err == 0) break; - err = nlmsg_receive(buf, err, receive_callback, arg); + err = nlmsg_receive(buf, err, receive_callback, error_callback, arg); if (err < 0) goto err; if (err == 0) diff --git a/net.c b/net.c index 23ef597bf..015aeda90 100644 --- a/net.c +++ b/net.c @@ -234,7 +234,7 @@ static int dump_links(struct cr_imgset *fds) req.nlh.nlmsg_seq = CR_NLMSG_SEQ; req.g.rtgen_family = AF_PACKET; - ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, fds); + ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, fds); close(sk); out: return ret; @@ -297,7 +297,7 @@ static int do_rtm_link_req(int msg_type, NetDeviceEntry *nde, int nlsk, linkinfo->rta_len = (void *)NLMSG_TAIL(&req.h) - (void *)linkinfo; } - return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL); + return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL); } int restore_link_parms(NetDeviceEntry *nde, int nlsk) diff --git a/sockets.c b/sockets.c index 6c71503b5..dd0ff4fb5 100644 --- a/sockets.c +++ b/sockets.c @@ -538,7 +538,7 @@ static int do_collect_req(int nl, struct sock_diag_req *req, int size, { int tmp; - tmp = do_rtnl_req(nl, req, size, receive_callback, arg); + tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, arg); if (tmp == 0) set_collect_bit(req->r.n.sdiag_family, req->r.n.sdiag_protocol);