@@ -229,6 +229,16 @@ extern int mnl_ring_poll(const struct mnl_ring_socket *nlm, int timeout);
extern struct nl_mmap_hdr *mnl_ring_poll_rxframe(struct mnl_ring_socket *nlm);
extern int mnl_ring_discard_frames(struct mnl_ring_socket *nlm, enum mnl_ring_types type);
+/* non-minimalistic 2 [nonmin2] */
+/* nlmsghdr building callback which returns buffer len */
+typedef int (*mnl_ring_build_t)(void *buf, void *data);
+extern int mnl_ring_build_frame(struct mnl_ring_socket *nlm, mnl_ring_build_t cb, void *data);
+extern int mnl_ring_parse_frame2(struct mnl_ring_socket *nlm, unsigned int seq, unsigned int portid,
+ mnl_cb_t cb, void *data,
+ mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len);
+extern int mnl_ring_parse_frame(struct mnl_ring_socket *nlm, unsigned int seq, unsigned int portid,
+ mnl_cb_t cb, void *data);
+
/*
* other declarations
*/
@@ -82,4 +82,7 @@ LIBMNL_1.2 {
mnl_ring_poll;
mnl_ring_poll_rxframe;
mnl_ring_discard_frames;
+ mnl_ring_build_frame;
+ mnl_ring_parse_frame2;
+ mnl_ring_parse_frame;
} LIBMNL_1.1;
@@ -384,3 +384,73 @@ int mnl_ring_discard_frames(struct mnl_ring_socket *nlm, enum mnl_ring_types typ
return 1;
}
EXPORT_SYMBOL(mnl_ring_discard_frames);
+
+/****
+ * non-minimalistic 2 [nonmin2]
+ ****/
+
+/**
+ * mnl_ring_build_frame - build tx frame using callback
+ * \param nlm ring descriptor
+ * \param cb frame building function
+ * \param data passing to cb
+ *
+ * shoud advance ring or not?
+ * cb receive tx frame pointer for nlmsghdr and should return whole nlmsgs
+ * length. Users do not need take care of struct nl_mmap_hdr
+ */
+int mnl_ring_build_frame(struct mnl_ring_socket *nlm, mnl_ring_build_t cb, void *data) {
+ struct nl_mmap_hdr *hdr;
+ int ret;
+
+ hdr = mnl_ring_get_frame(nlm, MNL_RING_TX);
+ if (hdr == NULL)
+ return -1;
+
+ ret = cb(MNL_MMAP_MSGHDR(hdr), data);
+ if (ret <= 0)
+ return ret;
+ hdr->nm_len = ret;
+ hdr->nm_status = NL_MMAP_STATUS_VALID;
+ /* mnl_ring_advance(nlm, MNL_RING_TX); */
+
+ return ret;
+}
+EXPORT_SYMBOL(mnl_ring_build_frame);
+
+/**
+ * mnl_ring_parse_frame2
+ *
+ * advance ring.
+ * Just wrapping mnl_cb_run2 to let users not take care of
+ * struct nl_mmap_hdr
+ */
+int mnl_ring_parse_frame2(struct mnl_ring_socket *nlm, unsigned int seq,
+ unsigned int portid, mnl_cb_t cb, void *data,
+ mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
+{
+ struct nl_mmap_hdr *hdr;
+ int ret;
+
+ hdr = mnl_ring_poll_rxframe(nlm);
+ if (hdr == NULL)
+ return MNL_CB_ERROR;
+
+ ret = mnl_cb_run2(MNL_MMAP_MSGHDR(hdr), hdr->nm_len, seq, portid,
+ cb, data, cb_ctl_array, cb_ctl_array_len);
+ hdr->nm_status = NL_MMAP_STATUS_UNUSED;
+ mnl_ring_advance(nlm, MNL_RING_RX);
+
+ return ret;
+}
+EXPORT_SYMBOL(mnl_ring_parse_frame2);
+
+/**
+ * mnl_ring_parse_frame
+ */
+int mnl_ring_parse_frame(struct mnl_ring_socket *nlm, unsigned int seq, unsigned int portid,
+ mnl_cb_t cb, void *data)
+{
+ return mnl_ring_parse_frame2(nlm, seq, portid, cb, data, NULL, 0);
+}
+EXPORT_SYMBOL(mnl_ring_parse_frame);
added to not handle struct nl_mmap_hdr * mnl_ring_build_frame introduce new callback which takes buf to build nlmsghdr * mnl_ring_parse_frame2 * mnl_ring_parse_frame wrap cb_run Signed-off-by: Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp> --- include/libmnl/libmnl.h | 10 +++++++ src/libmnl.map | 3 +++ src/mmap.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+)