libnftnl  1.1.9
batch.c
1 /*
2  * Copyright (c) 2013-2015 Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 
9 #include "internal.h"
10 #include <errno.h>
11 #include <libmnl/libmnl.h>
12 #include <libnftnl/batch.h>
13 
14 struct nftnl_batch {
15  uint32_t num_pages;
16  struct nftnl_batch_page *current_page;
17  uint32_t page_size;
18  uint32_t page_overrun_size;
19  struct list_head page_list;
20 };
21 
23  struct list_head head;
24  struct mnl_nlmsg_batch *batch;
25 };
26 
27 static struct nftnl_batch_page *nftnl_batch_page_alloc(struct nftnl_batch *batch)
28 {
29  struct nftnl_batch_page *page;
30  char *buf;
31 
32  page = malloc(sizeof(struct nftnl_batch_page));
33  if (page == NULL)
34  return NULL;
35 
36  buf = malloc(batch->page_size + batch->page_overrun_size);
37  if (buf == NULL)
38  goto err1;
39 
40  page->batch = mnl_nlmsg_batch_start(buf, batch->page_size);
41  if (page->batch == NULL)
42  goto err2;
43 
44  return page;
45 err2:
46  free(buf);
47 err1:
48  free(page);
49  return NULL;
50 }
51 
52 static void nftnl_batch_add_page(struct nftnl_batch_page *page,
53  struct nftnl_batch *batch)
54 {
55  batch->current_page = page;
56  batch->num_pages++;
57  list_add_tail(&page->head, &batch->page_list);
58 }
59 
60 EXPORT_SYMBOL(nftnl_batch_alloc);
61 struct nftnl_batch *nftnl_batch_alloc(uint32_t pg_size, uint32_t pg_overrun_size)
62 {
63  struct nftnl_batch *batch;
64  struct nftnl_batch_page *page;
65 
66  batch = calloc(1, sizeof(struct nftnl_batch));
67  if (batch == NULL)
68  return NULL;
69 
70  batch->page_size = pg_size;
71  batch->page_overrun_size = pg_overrun_size;
72  INIT_LIST_HEAD(&batch->page_list);
73 
74  page = nftnl_batch_page_alloc(batch);
75  if (page == NULL)
76  goto err1;
77 
78  nftnl_batch_add_page(page, batch);
79  return batch;
80 err1:
81  free(batch);
82  return NULL;
83 }
84 
85 EXPORT_SYMBOL(nftnl_batch_free);
86 void nftnl_batch_free(struct nftnl_batch *batch)
87 {
88  struct nftnl_batch_page *page, *next;
89 
90  list_for_each_entry_safe(page, next, &batch->page_list, head) {
91  free(mnl_nlmsg_batch_head(page->batch));
92  mnl_nlmsg_batch_stop(page->batch);
93  free(page);
94  }
95 
96  free(batch);
97 }
98 
99 EXPORT_SYMBOL(nftnl_batch_update);
100 int nftnl_batch_update(struct nftnl_batch *batch)
101 {
102  struct nftnl_batch_page *page;
103  struct nlmsghdr *last_nlh;
104 
105  if (mnl_nlmsg_batch_next(batch->current_page->batch))
106  return 0;
107 
108  last_nlh = nftnl_batch_buffer(batch);
109 
110  page = nftnl_batch_page_alloc(batch);
111  if (page == NULL)
112  goto err1;
113 
114  nftnl_batch_add_page(page, batch);
115 
116  memcpy(nftnl_batch_buffer(batch), last_nlh, last_nlh->nlmsg_len);
117  mnl_nlmsg_batch_next(batch->current_page->batch);
118 
119  return 0;
120 err1:
121  return -1;
122 }
123 
124 EXPORT_SYMBOL(nftnl_batch_buffer);
125 void *nftnl_batch_buffer(struct nftnl_batch *batch)
126 {
127  return mnl_nlmsg_batch_current(batch->current_page->batch);
128 }
129 
130 EXPORT_SYMBOL(nftnl_batch_buffer_len);
131 uint32_t nftnl_batch_buffer_len(struct nftnl_batch *batch)
132 {
133  return mnl_nlmsg_batch_size(batch->current_page->batch);
134 }
135 
136 EXPORT_SYMBOL(nftnl_batch_iovec_len);
137 int nftnl_batch_iovec_len(struct nftnl_batch *batch)
138 {
139  int num_pages = batch->num_pages;
140 
141  /* Skip last page if it's empty */
142  if (mnl_nlmsg_batch_is_empty(batch->current_page->batch))
143  num_pages--;
144 
145  return num_pages;
146 }
147 
148 EXPORT_SYMBOL(nftnl_batch_iovec);
149 void nftnl_batch_iovec(struct nftnl_batch *batch, struct iovec *iov,
150  uint32_t iovlen)
151 {
152  struct nftnl_batch_page *page;
153  int i = 0;
154 
155  list_for_each_entry(page, &batch->page_list, head) {
156  if (i >= iovlen)
157  break;
158 
159  iov[i].iov_base = mnl_nlmsg_batch_head(page->batch);
160  iov[i].iov_len = mnl_nlmsg_batch_size(page->batch);
161  i++;
162  }
163 }