]>
git.proxmox.com Git - mirror_iproute2.git/blob - lib/mnl_utils.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * mnl_utils.c Helpers for working with libmnl.
9 #include <libmnl/libmnl.h>
11 #include "libnetlink.h"
12 #include "mnl_utils.h"
15 struct mnl_socket
*mnlu_socket_open(int bus
)
17 struct mnl_socket
*nl
;
20 nl
= mnl_socket_open(bus
);
24 mnl_socket_setsockopt(nl
, NETLINK_CAP_ACK
, &one
, sizeof(one
));
25 mnl_socket_setsockopt(nl
, NETLINK_EXT_ACK
, &one
, sizeof(one
));
27 if (mnl_socket_bind(nl
, 0, MNL_SOCKET_AUTOPID
) < 0)
37 struct nlmsghdr
*mnlu_msg_prepare(void *buf
, uint32_t nlmsg_type
, uint16_t flags
,
38 void *extra_header
, size_t extra_header_size
)
43 nlh
= mnl_nlmsg_put_header(buf
);
44 nlh
->nlmsg_type
= nlmsg_type
;
45 nlh
->nlmsg_flags
= flags
;
46 nlh
->nlmsg_seq
= time(NULL
);
48 eh
= mnl_nlmsg_put_extra_header(nlh
, extra_header_size
);
49 memcpy(eh
, extra_header
, extra_header_size
);
54 static int mnlu_cb_noop(const struct nlmsghdr
*nlh
, void *data
)
59 static int mnlu_cb_error(const struct nlmsghdr
*nlh
, void *data
)
61 const struct nlmsgerr
*err
= mnl_nlmsg_get_payload(nlh
);
63 /* Netlink subsystems returns the errno value with different signess */
69 if (nl_dump_ext_ack(nlh
, NULL
))
72 return err
->error
== 0 ? MNL_CB_STOP
: MNL_CB_ERROR
;
75 static int mnlu_cb_stop(const struct nlmsghdr
*nlh
, void *data
)
77 int len
= *(int *)NLMSG_DATA(nlh
);
81 nl_dump_ext_ack_done(nlh
, len
);
87 static mnl_cb_t mnlu_cb_array
[NLMSG_MIN_TYPE
] = {
88 [NLMSG_NOOP
] = mnlu_cb_noop
,
89 [NLMSG_ERROR
] = mnlu_cb_error
,
90 [NLMSG_DONE
] = mnlu_cb_stop
,
91 [NLMSG_OVERRUN
] = mnlu_cb_noop
,
94 int mnlu_socket_recv_run(struct mnl_socket
*nl
, unsigned int seq
, void *buf
, size_t buf_size
,
95 mnl_cb_t cb
, void *data
)
97 unsigned int portid
= mnl_socket_get_portid(nl
);
101 err
= mnl_socket_recvfrom(nl
, buf
, buf_size
);
104 err
= mnl_cb_run2(buf
, err
, seq
, portid
,
105 cb
, data
, mnlu_cb_array
,
106 ARRAY_SIZE(mnlu_cb_array
));