libnftnl 1.3.2
obj/connlimit.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2025 by Fernando Fernandez Mancera <fmancera@suse.de>
4 */
5
6#include <stdio.h>
7#include <stdint.h>
8#include <arpa/inet.h>
9
10#include <linux/netfilter/nf_tables.h>
11
12#include <internal.h>
13#include <libmnl/libmnl.h>
14#include <libnftnl/object.h>
15
16#include "obj.h"
17
18static int nftnl_obj_connlimit_set(struct nftnl_obj *e, uint16_t type,
19 const void *data, uint32_t data_len)
20{
21 struct nftnl_obj_connlimit *connlimit = nftnl_obj_data(e);
22
23 switch(type) {
24 case NFTNL_OBJ_CONNLIMIT_COUNT:
25 memcpy(&connlimit->count, data, data_len);
26 break;
27 case NFTNL_OBJ_CONNLIMIT_FLAGS:
28 memcpy(&connlimit->flags, data, data_len);
29 break;
30 }
31 return 0;
32}
33
34static const void *nftnl_obj_connlimit_get(const struct nftnl_obj *e,
35 uint16_t type, uint32_t *data_len)
36{
37 struct nftnl_obj_connlimit *connlimit = nftnl_obj_data(e);
38
39 switch (type) {
40 case NFTNL_OBJ_CONNLIMIT_COUNT:
41 *data_len = sizeof(connlimit->count);
42 return &connlimit->count;
43 case NFTNL_OBJ_CONNLIMIT_FLAGS:
44 *data_len = sizeof(connlimit->flags);
45 return &connlimit->flags;
46 }
47 return NULL;
48}
49
50static int nftnl_obj_connlimit_cb(const struct nlattr *attr, void *data)
51{
52 int type = mnl_attr_get_type(attr);
53 const struct nlattr **tb = data;
54
55 if (mnl_attr_type_valid(attr, NFTA_CONNLIMIT_MAX) < 0)
56 return MNL_CB_OK;
57
58 switch (type) {
59 case NFTA_CONNLIMIT_COUNT:
60 case NFTA_CONNLIMIT_FLAGS:
61 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
62 abi_breakage();
63 break;
64 }
65
66 tb[type] = attr;
67 return MNL_CB_OK;
68}
69
70static void nftnl_obj_connlimit_build(struct nlmsghdr *nlh,
71 const struct nftnl_obj *e)
72{
73 struct nftnl_obj_connlimit *connlimit = nftnl_obj_data(e);
74
75 if (e->flags & (1 << NFTNL_OBJ_CONNLIMIT_COUNT))
76 mnl_attr_put_u32(nlh, NFTA_CONNLIMIT_COUNT,
77 htonl(connlimit->count));
78 if (e->flags & (1 << NFTNL_OBJ_CONNLIMIT_FLAGS))
79 mnl_attr_put_u32(nlh, NFTA_CONNLIMIT_FLAGS,
80 htonl(connlimit->flags));
81}
82
83static int nftnl_obj_connlimit_parse(struct nftnl_obj *e, struct nlattr *attr)
84{
85 struct nftnl_obj_connlimit *connlimit = nftnl_obj_data(e);
86 struct nlattr *tb[NFTA_CONNLIMIT_MAX + 1] = {};
87
88 if (mnl_attr_parse_nested(attr, nftnl_obj_connlimit_cb, tb) < 0)
89 return -1;
90
91 if (tb[NFTA_CONNLIMIT_COUNT]) {
92 connlimit->count = ntohl(mnl_attr_get_u32(tb[NFTA_CONNLIMIT_COUNT]));
93 e->flags |= (1 << NFTNL_OBJ_CONNLIMIT_COUNT);
94 }
95 if (tb[NFTA_CONNLIMIT_FLAGS]) {
96 connlimit->flags = ntohl(mnl_attr_get_u32(tb[NFTA_CONNLIMIT_FLAGS]));
97 e->flags |= (1 << NFTNL_OBJ_CONNLIMIT_FLAGS);
98 }
99
100 return 0;
101}
102
103static int nftnl_obj_connlimit_snprintf(char *buf, size_t len,
104 uint32_t flags,
105 const struct nftnl_obj *e)
106{
107 struct nftnl_obj_connlimit *connlimit = nftnl_obj_data(e);
108
109 return snprintf(buf, len, "count %u flags %x ",
110 connlimit->count, connlimit->flags);
111}
112
113static struct attr_policy obj_connlimit_attr_policy[__NFTNL_OBJ_CONNLIMIT_MAX] = {
114 [NFTNL_OBJ_CONNLIMIT_COUNT] = { .maxlen = sizeof(uint32_t) },
115 [NFTNL_OBJ_CONNLIMIT_FLAGS] = { .maxlen = sizeof(uint32_t) },
116};
117
118struct obj_ops obj_ops_connlimit = {
119 .name = "connlimit",
120 .type = NFT_OBJECT_CONNLIMIT,
121 .alloc_len = sizeof(struct nftnl_obj_connlimit),
122 .nftnl_max_attr = __NFTNL_OBJ_CONNLIMIT_MAX,
123 .attr_policy = obj_connlimit_attr_policy,
124 .set = nftnl_obj_connlimit_set,
125 .get = nftnl_obj_connlimit_get,
126 .parse = nftnl_obj_connlimit_parse,
127 .build = nftnl_obj_connlimit_build,
128 .output = nftnl_obj_connlimit_snprintf,
129};