diff options
Diffstat (limited to 'src/netlink.c')
-rw-r--r-- | src/netlink.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/netlink.c b/src/netlink.c index 9fadccd0..5b2d5e16 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1489,6 +1489,64 @@ static struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx, return obj; } +static struct nftnl_flowtable *alloc_nftnl_flowtable(const struct handle *h, + const struct flowtable *ft) +{ + struct nftnl_flowtable *flo; + + flo = nftnl_flowtable_alloc(); + if (flo == NULL) + memory_allocation_error(); + + nftnl_flowtable_set_u32(flo, NFTNL_FLOWTABLE_FAMILY, h->family); + nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_TABLE, h->table); + if (h->flowtable != NULL) + nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_NAME, h->flowtable); + + return flo; +} + +static void netlink_dump_flowtable(struct nftnl_flowtable *flo, + struct netlink_ctx *ctx) +{ + FILE *fp = ctx->octx->output_fp; + + if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) + return; + + nftnl_flowtable_fprintf(fp, flo, 0, 0); + fprintf(fp, "\n"); +} + +int netlink_add_flowtable(struct netlink_ctx *ctx, const struct handle *h, + struct flowtable *ft, uint32_t flags) +{ + struct nftnl_flowtable *flo; + const char *dev_array[8]; + struct expr *expr; + int i = 0, err; + + flo = alloc_nftnl_flowtable(h, ft); + nftnl_flowtable_set_u32(flo, NFTNL_FLOWTABLE_HOOKNUM, ft->hooknum); + nftnl_flowtable_set_u32(flo, NFTNL_FLOWTABLE_PRIO, ft->priority); + + list_for_each_entry(expr, &ft->dev_expr->expressions, list) + dev_array[i++] = expr->identifier; + + dev_array[i] = NULL; + nftnl_flowtable_set_array(flo, NFTNL_FLOWTABLE_DEVICES, dev_array); + + netlink_dump_flowtable(flo, ctx); + + err = mnl_nft_flowtable_batch_add(flo, ctx->batch, flags, ctx->seqnum); + if (err < 0) + netlink_io_error(ctx, &ft->location, "Could not add flowtable: %s", + strerror(errno)); + nftnl_flowtable_free(flo); + + return err; +} + static int list_obj_cb(struct nftnl_obj *nls, void *arg) { struct netlink_ctx *ctx = arg; |