libnftnl 1.2.9
obj/counter.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2012-2016 by Pablo Neira Ayuso <pablo@netfilter.org>
4 */
5
6#include <stdio.h>
7#include <stdint.h>
8#include <arpa/inet.h>
9#include <errno.h>
10#include <inttypes.h>
11
12#include <linux/netfilter/nf_tables.h>
13
14#include <libmnl/libmnl.h>
15#include <libnftnl/object.h>
16
17#include "internal.h"
18#include "obj.h"
19
20static int
21nftnl_obj_counter_set(struct nftnl_obj *e, uint16_t type,
22 const void *data, uint32_t data_len)
23{
24 struct nftnl_obj_counter *ctr = nftnl_obj_data(e);
25
26 switch(type) {
27 case NFTNL_OBJ_CTR_BYTES:
28 memcpy(&ctr->bytes, data, data_len);
29 break;
30 case NFTNL_OBJ_CTR_PKTS:
31 memcpy(&ctr->pkts, data, data_len);
32 break;
33 }
34 return 0;
35}
36
37static const void *
38nftnl_obj_counter_get(const struct nftnl_obj *e, uint16_t type,
39 uint32_t *data_len)
40{
41 struct nftnl_obj_counter *ctr = nftnl_obj_data(e);
42
43 switch(type) {
44 case NFTNL_OBJ_CTR_BYTES:
45 *data_len = sizeof(ctr->bytes);
46 return &ctr->bytes;
47 case NFTNL_OBJ_CTR_PKTS:
48 *data_len = sizeof(ctr->pkts);
49 return &ctr->pkts;
50 }
51 return NULL;
52}
53
54static int nftnl_obj_counter_cb(const struct nlattr *attr, void *data)
55{
56 const struct nlattr **tb = data;
57 int type = mnl_attr_get_type(attr);
58
59 if (mnl_attr_type_valid(attr, NFTA_COUNTER_MAX) < 0)
60 return MNL_CB_OK;
61
62 switch(type) {
63 case NFTA_COUNTER_BYTES:
64 case NFTA_COUNTER_PACKETS:
65 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
66 abi_breakage();
67 break;
68 }
69
70 tb[type] = attr;
71 return MNL_CB_OK;
72}
73
74static void
75nftnl_obj_counter_build(struct nlmsghdr *nlh, const struct nftnl_obj *e)
76{
77 struct nftnl_obj_counter *ctr = nftnl_obj_data(e);
78
79 if (e->flags & (1 << NFTNL_OBJ_CTR_BYTES))
80 mnl_attr_put_u64(nlh, NFTA_COUNTER_BYTES, htobe64(ctr->bytes));
81 if (e->flags & (1 << NFTNL_OBJ_CTR_PKTS))
82 mnl_attr_put_u64(nlh, NFTA_COUNTER_PACKETS, htobe64(ctr->pkts));
83}
84
85static int
86nftnl_obj_counter_parse(struct nftnl_obj *e, struct nlattr *attr)
87{
88 struct nftnl_obj_counter *ctr = nftnl_obj_data(e);
89 struct nlattr *tb[NFTA_COUNTER_MAX+1] = {};
90
91 if (mnl_attr_parse_nested(attr, nftnl_obj_counter_cb, tb) < 0)
92 return -1;
93
94 if (tb[NFTA_COUNTER_BYTES]) {
95 ctr->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_BYTES]));
96 e->flags |= (1 << NFTNL_OBJ_CTR_BYTES);
97 }
98 if (tb[NFTA_COUNTER_PACKETS]) {
99 ctr->pkts = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_PACKETS]));
100 e->flags |= (1 << NFTNL_OBJ_CTR_PKTS);
101 }
102
103 return 0;
104}
105
106static int nftnl_obj_counter_snprintf(char *buf, size_t len, uint32_t flags,
107 const struct nftnl_obj *e)
108{
109 struct nftnl_obj_counter *ctr = nftnl_obj_data(e);
110
111 return snprintf(buf, len, "pkts %"PRIu64" bytes %"PRIu64" ",
112 ctr->pkts, ctr->bytes);
113}
114
115static struct attr_policy obj_ctr_attr_policy[__NFTNL_OBJ_CTR_MAX] = {
116 [NFTNL_OBJ_CTR_BYTES] = { .maxlen = sizeof(uint64_t) },
117 [NFTNL_OBJ_CTR_PKTS] = { .maxlen = sizeof(uint64_t) },
118};
119
120struct obj_ops obj_ops_counter = {
121 .name = "counter",
122 .type = NFT_OBJECT_COUNTER,
123 .alloc_len = sizeof(struct nftnl_obj_counter),
124 .nftnl_max_attr = __NFTNL_OBJ_CTR_MAX - 1,
125 .attr_policy = obj_ctr_attr_policy,
126 .set = nftnl_obj_counter_set,
127 .get = nftnl_obj_counter_get,
128 .parse = nftnl_obj_counter_parse,
129 .build = nftnl_obj_counter_build,
130 .output = nftnl_obj_counter_snprintf,
131};