11 #include <libmnl/libmnl.h> 
   14 static int mnl_cb_noop(
const struct nlmsghdr *nlh, 
void *data)
 
   19 static int mnl_cb_error(
const struct nlmsghdr *nlh, 
void *data)
 
   21         const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
 
   23         if (nlh->nlmsg_len < mnl_nlmsg_size(
sizeof(
struct nlmsgerr))) {
 
   33         return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
 
   36 static int mnl_cb_stop(
const struct nlmsghdr *nlh, 
void *data)
 
   41 static const mnl_cb_t default_cb_array[NLMSG_MIN_TYPE] = {
 
   42         [NLMSG_NOOP]    = mnl_cb_noop,
 
   43         [NLMSG_ERROR]   = mnl_cb_error,
 
   44         [NLMSG_DONE]    = mnl_cb_stop,
 
   45         [NLMSG_OVERRUN] = mnl_cb_noop,
 
   48 static inline int __mnl_cb_run(
const void *buf, 
size_t numbytes,
 
   49                                unsigned int seq, 
unsigned int portid,
 
   50                                mnl_cb_t cb_data, 
void *data,
 
   51                                const mnl_cb_t *cb_ctl_array,
 
   52                                unsigned int cb_ctl_array_len)
 
   54         int ret = MNL_CB_OK, len = numbytes;
 
   55         const struct nlmsghdr *nlh = buf;
 
   57         while (mnl_nlmsg_ok(nlh, len)) {
 
   59                 if (!mnl_nlmsg_portid_ok(nlh, portid)) {
 
   64                 if (!mnl_nlmsg_seq_ok(nlh, seq)) {
 
   70                 if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
 
   76                 if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { 
 
   78                                 ret = cb_data(nlh, data);
 
   79                                 if (ret <= MNL_CB_STOP)
 
   82                 } 
else if (nlh->nlmsg_type < cb_ctl_array_len) {
 
   83                         if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type]) {
 
   84                                 ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
 
   85                                 if (ret <= MNL_CB_STOP)
 
   88                 } 
else if (default_cb_array[nlh->nlmsg_type]) {
 
   89                         ret = default_cb_array[nlh->nlmsg_type](nlh, data);
 
   90                         if (ret <= MNL_CB_STOP)
 
   93                 nlh = mnl_nlmsg_next(nlh, &len);
 
  130 EXPORT_SYMBOL(mnl_cb_run2);
 
  131 int mnl_cb_run2(
const void *buf, 
size_t numbytes, 
unsigned int seq,
 
  132                 unsigned int portid, mnl_cb_t cb_data, 
void *data,
 
  133                 const mnl_cb_t *cb_ctl_array, 
unsigned int cb_ctl_array_len)
 
  135         return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data,
 
  136                             cb_ctl_array, cb_ctl_array_len);
 
  158 EXPORT_SYMBOL(mnl_cb_run);
 
  159 int mnl_cb_run(
const void *buf, 
size_t numbytes, 
unsigned int seq,
 
  160                unsigned int portid, mnl_cb_t cb_data, 
void *data)
 
  162         return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);