libnftnl  1.2.3
ruleset.c
1 /*
2  * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
3  * (C) 2013 by Arturo Borrero Gonzalez <arturo@debian.org>
4  * (C) 2013 by Alvaro Neira Ayuso <alvaroneay@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
12  */
13 
14 #include <errno.h>
15 
16 #include "internal.h"
17 #include <stdlib.h>
18 
19 #include <libmnl/libmnl.h>
20 #include <libnftnl/ruleset.h>
21 #include <libnftnl/table.h>
22 #include <libnftnl/chain.h>
23 #include <libnftnl/set.h>
24 #include <libnftnl/rule.h>
25 
26 struct nftnl_ruleset {
27  struct nftnl_table_list *table_list;
28  struct nftnl_chain_list *chain_list;
29  struct nftnl_set_list *set_list;
30  struct nftnl_rule_list *rule_list;
31 
32  uint16_t flags;
33 };
34 
36  enum nftnl_cmd_type cmd;
37  enum nftnl_ruleset_type type;
38  union {
39  struct nftnl_table *table;
40  struct nftnl_chain *chain;
41  struct nftnl_rule *rule;
42  struct nftnl_set *set;
43  struct nftnl_set_elem *set_elem;
44  };
45  void *data;
46 
47  /* These fields below are not exposed to the user */
48  uint32_t format;
49  uint32_t set_id;
50  struct nftnl_set_list *set_list;
51 
52  int (*cb)(const struct nftnl_parse_ctx *ctx);
53  uint16_t flags;
54 };
55 
56 EXPORT_SYMBOL(nftnl_ruleset_alloc);
57 struct nftnl_ruleset *nftnl_ruleset_alloc(void)
58 {
59  return calloc(1, sizeof(struct nftnl_ruleset));
60 }
61 
62 EXPORT_SYMBOL(nftnl_ruleset_free);
63 void nftnl_ruleset_free(const struct nftnl_ruleset *r)
64 {
65  if (r->flags & (1 << NFTNL_RULESET_TABLELIST))
66  nftnl_table_list_free(r->table_list);
67  if (r->flags & (1 << NFTNL_RULESET_CHAINLIST))
68  nftnl_chain_list_free(r->chain_list);
69  if (r->flags & (1 << NFTNL_RULESET_SETLIST))
70  nftnl_set_list_free(r->set_list);
71  if (r->flags & (1 << NFTNL_RULESET_RULELIST))
72  nftnl_rule_list_free(r->rule_list);
73  xfree(r);
74 }
75 
76 EXPORT_SYMBOL(nftnl_ruleset_is_set);
77 bool nftnl_ruleset_is_set(const struct nftnl_ruleset *r, uint16_t attr)
78 {
79  return r->flags & (1 << attr);
80 }
81 
82 EXPORT_SYMBOL(nftnl_ruleset_unset);
83 void nftnl_ruleset_unset(struct nftnl_ruleset *r, uint16_t attr)
84 {
85  if (!(r->flags & (1 << attr)))
86  return;
87 
88  switch (attr) {
89  case NFTNL_RULESET_TABLELIST:
90  nftnl_table_list_free(r->table_list);
91  break;
92  case NFTNL_RULESET_CHAINLIST:
93  nftnl_chain_list_free(r->chain_list);
94  break;
95  case NFTNL_RULESET_SETLIST:
96  nftnl_set_list_free(r->set_list);
97  break;
98  case NFTNL_RULESET_RULELIST:
99  nftnl_rule_list_free(r->rule_list);
100  break;
101  }
102  r->flags &= ~(1 << attr);
103 }
104 
105 EXPORT_SYMBOL(nftnl_ruleset_set);
106 void nftnl_ruleset_set(struct nftnl_ruleset *r, uint16_t attr, void *data)
107 {
108  switch (attr) {
109  case NFTNL_RULESET_TABLELIST:
110  nftnl_ruleset_unset(r, NFTNL_RULESET_TABLELIST);
111  r->table_list = data;
112  break;
113  case NFTNL_RULESET_CHAINLIST:
114  nftnl_ruleset_unset(r, NFTNL_RULESET_CHAINLIST);
115  r->chain_list = data;
116  break;
117  case NFTNL_RULESET_SETLIST:
118  nftnl_ruleset_unset(r, NFTNL_RULESET_SETLIST);
119  r->set_list = data;
120  break;
121  case NFTNL_RULESET_RULELIST:
122  nftnl_ruleset_unset(r, NFTNL_RULESET_RULELIST);
123  r->rule_list = data;
124  break;
125  default:
126  return;
127  }
128  r->flags |= (1 << attr);
129 }
130 
131 EXPORT_SYMBOL(nftnl_ruleset_get);
132 void *nftnl_ruleset_get(const struct nftnl_ruleset *r, uint16_t attr)
133 {
134  if (!(r->flags & (1 << attr)))
135  return NULL;
136 
137  switch (attr) {
138  case NFTNL_RULESET_TABLELIST:
139  return r->table_list;
140  case NFTNL_RULESET_CHAINLIST:
141  return r->chain_list;
142  case NFTNL_RULESET_SETLIST:
143  return r->set_list;
144  case NFTNL_RULESET_RULELIST:
145  return r->rule_list;
146  default:
147  return NULL;
148  }
149 }
150 
151 EXPORT_SYMBOL(nftnl_ruleset_ctx_free);
152 void nftnl_ruleset_ctx_free(const struct nftnl_parse_ctx *ctx)
153 {
154  switch (ctx->type) {
155  case NFTNL_RULESET_TABLE:
156  nftnl_table_free(ctx->table);
157  break;
158  case NFTNL_RULESET_CHAIN:
159  nftnl_chain_free(ctx->chain);
160  break;
161  case NFTNL_RULESET_RULE:
162  nftnl_rule_free(ctx->rule);
163  break;
164  case NFTNL_RULESET_SET:
165  case NFTNL_RULESET_SET_ELEMS:
166  nftnl_set_free(ctx->set);
167  break;
168  case NFTNL_RULESET_RULESET:
169  case NFTNL_RULESET_UNSPEC:
170  break;
171  }
172 }
173 
174 EXPORT_SYMBOL(nftnl_ruleset_ctx_is_set);
175 bool nftnl_ruleset_ctx_is_set(const struct nftnl_parse_ctx *ctx, uint16_t attr)
176 {
177  return ctx->flags & (1 << attr);
178 }
179 
180 EXPORT_SYMBOL(nftnl_ruleset_ctx_get);
181 void *nftnl_ruleset_ctx_get(const struct nftnl_parse_ctx *ctx, uint16_t attr)
182 {
183  if (!(ctx->flags & (1 << attr)))
184  return NULL;
185 
186  switch (attr) {
187  case NFTNL_RULESET_CTX_CMD:
188  return (void *)&ctx->cmd;
189  case NFTNL_RULESET_CTX_TYPE:
190  return (void *)&ctx->type;
191  case NFTNL_RULESET_CTX_TABLE:
192  return ctx->table;
193  case NFTNL_RULESET_CTX_CHAIN:
194  return ctx->chain;
195  case NFTNL_RULESET_CTX_RULE:
196  return ctx->rule;
197  case NFTNL_RULESET_CTX_SET:
198  return ctx->set;
199  case NFTNL_RULESET_CTX_DATA:
200  return ctx->data;
201  default:
202  return NULL;
203  }
204 }
205 
206 EXPORT_SYMBOL(nftnl_ruleset_ctx_get_u32);
207 uint32_t nftnl_ruleset_ctx_get_u32(const struct nftnl_parse_ctx *ctx, uint16_t attr)
208 {
209  const void *ret = nftnl_ruleset_ctx_get(ctx, attr);
210  return ret == NULL ? 0 : *((uint32_t *)ret);
211 }
212 
213 
214 EXPORT_SYMBOL(nftnl_ruleset_parse_file_cb);
215 int nftnl_ruleset_parse_file_cb(enum nftnl_parse_type type, FILE *fp,
216  struct nftnl_parse_err *err, void *data,
217  int (*cb)(const struct nftnl_parse_ctx *ctx))
218 {
219  errno = EOPNOTSUPP;
220  return -1;
221 }
222 
223 EXPORT_SYMBOL(nftnl_ruleset_parse_buffer_cb);
224 int nftnl_ruleset_parse_buffer_cb(enum nftnl_parse_type type, const char *buffer,
225  struct nftnl_parse_err *err, void *data,
226  int (*cb)(const struct nftnl_parse_ctx *ctx))
227 {
228  errno = EOPNOTSUPP;
229  return -1;
230 }
231 
232 static int nftnl_ruleset_cb(const struct nftnl_parse_ctx *ctx)
233 {
234  struct nftnl_ruleset *r = ctx->data;
235 
236  if (ctx->cmd != NFTNL_CMD_ADD)
237  return -1;
238 
239  switch (ctx->type) {
240  case NFTNL_RULESET_TABLE:
241  if (r->table_list == NULL) {
242  r->table_list = nftnl_table_list_alloc();
243  if (r->table_list == NULL)
244  return -1;
245 
246  nftnl_ruleset_set(r, NFTNL_RULESET_TABLELIST,
247  r->table_list);
248  }
249  nftnl_table_list_add_tail(ctx->table, r->table_list);
250  break;
251  case NFTNL_RULESET_CHAIN:
252  if (r->chain_list == NULL) {
253  r->chain_list = nftnl_chain_list_alloc();
254  if (r->chain_list == NULL)
255  return -1;
256 
257  nftnl_ruleset_set(r, NFTNL_RULESET_CHAINLIST,
258  r->chain_list);
259  }
260  nftnl_chain_list_add_tail(ctx->chain, r->chain_list);
261  break;
262  case NFTNL_RULESET_SET:
263  if (r->set_list == NULL) {
264  r->set_list = nftnl_set_list_alloc();
265  if (r->set_list == NULL)
266  return -1;
267 
268  nftnl_ruleset_set(r, NFTNL_RULESET_SETLIST,
269  r->set_list);
270  }
271  nftnl_set_list_add_tail(ctx->set, r->set_list);
272  break;
273  case NFTNL_RULESET_RULE:
274  if (r->rule_list == NULL) {
275  r->rule_list = nftnl_rule_list_alloc();
276  if (r->rule_list == NULL)
277  return -1;
278 
279  nftnl_ruleset_set(r, NFTNL_RULESET_RULELIST,
280  r->rule_list);
281  }
282  nftnl_rule_list_add_tail(ctx->rule, r->rule_list);
283  break;
284  case NFTNL_RULESET_RULESET:
285  break;
286  default:
287  return -1;
288  }
289 
290  return 0;
291 }
292 
293 EXPORT_SYMBOL(nftnl_ruleset_parse);
294 int nftnl_ruleset_parse(struct nftnl_ruleset *r, enum nftnl_parse_type type,
295  const char *data, struct nftnl_parse_err *err)
296 {
297  errno = EOPNOTSUPP;
298  return -1;
299 }
300 
301 EXPORT_SYMBOL(nftnl_ruleset_parse_file);
302 int nftnl_ruleset_parse_file(struct nftnl_ruleset *rs, enum nftnl_parse_type type,
303  FILE *fp, struct nftnl_parse_err *err)
304 {
305  return nftnl_ruleset_parse_file_cb(type, fp, err, rs, nftnl_ruleset_cb);
306 }
307 
308 static int
309 nftnl_ruleset_snprintf_table(char *buf, size_t remain,
310  const struct nftnl_ruleset *rs, uint32_t type,
311  uint32_t flags)
312 {
313  struct nftnl_table *t;
314  struct nftnl_table_list_iter *ti;
315  const char *sep = "";
316  int ret, offset = 0;
317 
318  ti = nftnl_table_list_iter_create(rs->table_list);
319  if (ti == NULL)
320  return 0;
321 
322  t = nftnl_table_list_iter_next(ti);
323  while (t != NULL) {
324  ret = snprintf(buf + offset, remain, "%s", sep);
325  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
326 
327  ret = nftnl_table_snprintf(buf + offset, remain, t, type, flags);
328  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
329 
330  t = nftnl_table_list_iter_next(ti);
331  sep = "\n";
332  }
333  nftnl_table_list_iter_destroy(ti);
334 
335  return offset;
336 }
337 
338 static int
339 nftnl_ruleset_snprintf_chain(char *buf, size_t remain,
340  const struct nftnl_ruleset *rs, uint32_t type,
341  uint32_t flags)
342 {
343  struct nftnl_chain *c;
344  struct nftnl_chain_list_iter *ci;
345  const char *sep = "";
346  int ret, offset = 0;
347 
348  ci = nftnl_chain_list_iter_create(rs->chain_list);
349  if (ci == NULL)
350  return 0;
351 
352  c = nftnl_chain_list_iter_next(ci);
353  while (c != NULL) {
354  ret = snprintf(buf + offset, remain, "%s", sep);
355  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
356 
357  ret = nftnl_chain_snprintf(buf + offset, remain, c, type, flags);
358  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
359 
360  c = nftnl_chain_list_iter_next(ci);
361  sep = "\n";
362  }
363  nftnl_chain_list_iter_destroy(ci);
364 
365  return offset;
366 }
367 
368 static int
369 nftnl_ruleset_snprintf_set(char *buf, size_t remain,
370  const struct nftnl_ruleset *rs, uint32_t type,
371  uint32_t flags)
372 {
373  struct nftnl_set *s;
374  struct nftnl_set_list_iter *si;
375  const char *sep = "";
376  int ret, offset = 0;
377 
378  si = nftnl_set_list_iter_create(rs->set_list);
379  if (si == NULL)
380  return 0;
381 
382  s = nftnl_set_list_iter_next(si);
383  while (s != NULL) {
384  ret = snprintf(buf + offset, remain, "%s", sep);
385  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
386 
387  ret = nftnl_set_snprintf(buf + offset, remain, s, type, flags);
388  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
389 
390  s = nftnl_set_list_iter_next(si);
391  sep = "\n";
392  }
393  nftnl_set_list_iter_destroy(si);
394 
395  return offset;
396 }
397 
398 static int
399 nftnl_ruleset_snprintf_rule(char *buf, size_t remain,
400  const struct nftnl_ruleset *rs, uint32_t type,
401  uint32_t flags)
402 {
403  struct nftnl_rule *r;
404  struct nftnl_rule_list_iter *ri;
405  const char *sep = "";
406  int ret, offset = 0;
407 
408  ri = nftnl_rule_list_iter_create(rs->rule_list);
409  if (ri == NULL)
410  return 0;
411 
412  r = nftnl_rule_list_iter_next(ri);
413  while (r != NULL) {
414  ret = snprintf(buf + offset, remain, "%s", sep);
415  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
416 
417  ret = nftnl_rule_snprintf(buf + offset, remain, r, type, flags);
418  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
419 
420  r = nftnl_rule_list_iter_next(ri);
421  sep = "\n";
422  }
423  nftnl_rule_list_iter_destroy(ri);
424 
425  return offset;
426 }
427 
428 static int
429 nftnl_ruleset_do_snprintf(char *buf, size_t remain,
430  const struct nftnl_ruleset *rs,
431  uint32_t cmd, uint32_t type, uint32_t flags)
432 {
433  uint32_t inner_flags = flags;
434  const char *sep = "";
435  int ret, offset = 0;
436 
437  /* dont pass events flags to child calls of _snprintf() */
438  inner_flags &= ~NFTNL_OF_EVENT_ANY;
439 
440  if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_TABLELIST) &&
441  (!nftnl_table_list_is_empty(rs->table_list))) {
442  ret = nftnl_ruleset_snprintf_table(buf + offset, remain, rs,
443  type, inner_flags);
444  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
445 
446  if (ret > 0)
447  sep = "\n";
448  }
449 
450  if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_CHAINLIST) &&
451  (!nftnl_chain_list_is_empty(rs->chain_list))) {
452  ret = snprintf(buf + offset, remain, "%s", sep);
453  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
454 
455  ret = nftnl_ruleset_snprintf_chain(buf + offset, remain, rs,
456  type, inner_flags);
457  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
458 
459  if (ret > 0)
460  sep = "\n";
461  }
462 
463  if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_SETLIST) &&
464  (!nftnl_set_list_is_empty(rs->set_list))) {
465  ret = snprintf(buf + offset, remain, "%s", sep);
466  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
467 
468  ret = nftnl_ruleset_snprintf_set(buf + offset, remain, rs,
469  type, inner_flags);
470  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
471 
472  if (ret > 0)
473  sep = "\n";
474  }
475 
476  if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_RULELIST) &&
477  (!nftnl_rule_list_is_empty(rs->rule_list))) {
478  ret = snprintf(buf + offset, remain, "%s", sep);
479  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
480 
481  ret = nftnl_ruleset_snprintf_rule(buf + offset, remain, rs,
482  type, inner_flags);
483  SNPRINTF_BUFFER_SIZE(ret, remain, offset);
484  }
485 
486  return offset;
487 }
488 
489 EXPORT_SYMBOL(nftnl_ruleset_snprintf);
490 int nftnl_ruleset_snprintf(char *buf, size_t size, const struct nftnl_ruleset *r,
491  uint32_t type, uint32_t flags)
492 {
493  if (size)
494  buf[0] = '\0';
495 
496  if (type != NFTNL_OUTPUT_DEFAULT) {
497  errno = EOPNOTSUPP;
498  return -1;
499  }
500  return nftnl_ruleset_do_snprintf(buf, size, r, nftnl_flag2cmd(flags),
501  type, flags);
502 }
503 
504 static int nftnl_ruleset_fprintf_tables(FILE *fp, const struct nftnl_ruleset *rs,
505  uint32_t type, uint32_t flags)
506 {
507  int len = 0, ret = 0;
508  struct nftnl_table *t;
509  struct nftnl_table_list_iter *ti;
510  const char *sep = "";
511 
512  ti = nftnl_table_list_iter_create(rs->table_list);
513  if (ti == NULL)
514  return -1;
515 
516  t = nftnl_table_list_iter_next(ti);
517  while (t != NULL) {
518  ret = fprintf(fp, "%s", sep);
519  if (ret < 0)
520  goto err;
521 
522  len += ret;
523 
524  ret = nftnl_table_fprintf(fp, t, type, flags);
525  if (ret < 0)
526  goto err;
527 
528  len += ret;
529 
530  t = nftnl_table_list_iter_next(ti);
531  sep = "\n";
532 
533  }
534  nftnl_table_list_iter_destroy(ti);
535 
536  return len;
537 err:
538  nftnl_table_list_iter_destroy(ti);
539  return -1;
540 }
541 
542 static int nftnl_ruleset_fprintf_chains(FILE *fp, const struct nftnl_ruleset *rs,
543  uint32_t type, uint32_t flags)
544 {
545  int len = 0, ret = 0;
546  struct nftnl_chain *o;
547  struct nftnl_chain_list_iter *i;
548  const char *sep = "";
549 
550  i = nftnl_chain_list_iter_create(rs->chain_list);
551  if (i == NULL)
552  return -1;
553 
554  o = nftnl_chain_list_iter_next(i);
555  while (o != NULL) {
556  ret = fprintf(fp, "%s", sep);
557  if (ret < 0)
558  goto err;
559 
560  len += ret;
561 
562  ret = nftnl_chain_fprintf(fp, o, type, flags);
563  if (ret < 0)
564  goto err;
565 
566  len += ret;
567 
568  o = nftnl_chain_list_iter_next(i);
569  sep = "\n";
570  }
571  nftnl_chain_list_iter_destroy(i);
572 
573  return len;
574 err:
575  nftnl_chain_list_iter_destroy(i);
576  return -1;
577 }
578 
579 static int nftnl_ruleset_fprintf_sets(FILE *fp, const struct nftnl_ruleset *rs,
580  uint32_t type, uint32_t flags)
581 {
582  int len = 0, ret = 0;
583  struct nftnl_set *o;
584  struct nftnl_set_list_iter *i;
585  const char *sep = "";
586 
587  i = nftnl_set_list_iter_create(rs->set_list);
588  if (i == NULL)
589  return -1;
590 
591  o = nftnl_set_list_iter_next(i);
592  while (o != NULL) {
593  ret = fprintf(fp, "%s", sep);
594  if (ret < 0)
595  goto err;
596 
597  len += ret;
598 
599  ret = nftnl_set_fprintf(fp, o, type, flags);
600  if (ret < 0)
601  goto err;
602 
603  len += ret;
604 
605  o = nftnl_set_list_iter_next(i);
606  sep = "\n";
607  }
608  nftnl_set_list_iter_destroy(i);
609 
610  return len;
611 err:
612  nftnl_set_list_iter_destroy(i);
613  return -1;
614 }
615 
616 static int nftnl_ruleset_fprintf_rules(FILE *fp, const struct nftnl_ruleset *rs,
617  uint32_t type, uint32_t flags)
618 {
619  int len = 0, ret = 0;
620  struct nftnl_rule *o;
621  struct nftnl_rule_list_iter *i;
622  const char *sep = "";
623 
624  i = nftnl_rule_list_iter_create(rs->rule_list);
625  if (i == NULL)
626  return -1;
627 
628  o = nftnl_rule_list_iter_next(i);
629  while (o != NULL) {
630  ret = fprintf(fp, "%s", sep);
631  if (ret < 0)
632  goto err;
633 
634  len += ret;
635 
636  ret = nftnl_rule_fprintf(fp, o, type, flags);
637  if (ret < 0)
638  goto err;
639 
640  len += ret;
641 
642  o = nftnl_rule_list_iter_next(i);
643  sep = "\n";
644  }
645  nftnl_rule_list_iter_destroy(i);
646 
647  return len;
648 err:
649  nftnl_rule_list_iter_destroy(i);
650  return -1;
651 }
652 
653 #define NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len) \
654  if (ret < 0) \
655  return -1; \
656  len += ret;
657 
658 static int nftnl_ruleset_cmd_fprintf(FILE *fp, const struct nftnl_ruleset *rs,
659  uint32_t cmd, uint32_t type, uint32_t flags)
660 {
661  int len = 0, ret = 0;
662  uint32_t inner_flags = flags;
663  const char *sep = "";
664 
665  /* dont pass events flags to child calls of _snprintf() */
666  inner_flags &= ~NFTNL_OF_EVENT_ANY;
667 
668  if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_TABLELIST)) &&
669  (!nftnl_table_list_is_empty(rs->table_list))) {
670  ret = nftnl_ruleset_fprintf_tables(fp, rs, type, inner_flags);
671  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
672 
673  if (ret > 0)
674  sep = "\n";
675  }
676 
677  if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_CHAINLIST)) &&
678  (!nftnl_chain_list_is_empty(rs->chain_list))) {
679  ret = fprintf(fp, "%s", sep);
680  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
681 
682  ret = nftnl_ruleset_fprintf_chains(fp, rs, type, inner_flags);
683  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
684 
685  if (ret > 0)
686  sep = "\n";
687  }
688 
689  if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_SETLIST)) &&
690  (!nftnl_set_list_is_empty(rs->set_list))) {
691  ret = fprintf(fp, "%s", sep);
692  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
693 
694  ret = nftnl_ruleset_fprintf_sets(fp, rs, type, inner_flags);
695  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
696 
697  if (ret > 0)
698  sep = "\n";
699  }
700 
701  if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_RULELIST)) &&
702  (!nftnl_rule_list_is_empty(rs->rule_list))) {
703  ret = fprintf(fp, "%s", sep);
704  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
705 
706  ret = nftnl_ruleset_fprintf_rules(fp, rs, type, inner_flags);
707  NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
708  }
709 
710  return len;
711 }
712 
713 EXPORT_SYMBOL(nftnl_ruleset_fprintf);
714 int nftnl_ruleset_fprintf(FILE *fp, const struct nftnl_ruleset *rs, uint32_t type,
715  uint32_t flags)
716 {
717  return nftnl_ruleset_cmd_fprintf(fp, rs, nftnl_flag2cmd(flags), type,
718  flags);
719 }
nftnl_chain
Definition: chain.c:32
nftnl_parse_ctx
Definition: ruleset.c:35
nftnl_rule_list_iter
Definition: rule.c:825
nftnl_rule_list
Definition: rule.c:749
nftnl_table
Definition: table.c:28
nftnl_chain_list_iter
Definition: chain.c:1119
nftnl_set_list_iter
Definition: set.c:982
nftnl_table_list
Definition: table.c:409
nftnl_chain_list
Definition: chain.c:1010
nftnl_ruleset
Definition: ruleset.c:26
nftnl_table_list_iter
Definition: table.c:479
nftnl_set_list
Definition: set.c:891