1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2003-2013 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2006 Petr Gotthard <[email protected]>
5*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2006 Siemens AG Oesterreich
6*4dc78e53SAndroid Build Coastguard Worker */
7*4dc78e53SAndroid Build Coastguard Worker
8*4dc78e53SAndroid Build Coastguard Worker /**
9*4dc78e53SAndroid Build Coastguard Worker * @ingroup cls
10*4dc78e53SAndroid Build Coastguard Worker * @defgroup cls_fw Firewall Classifier
11*4dc78e53SAndroid Build Coastguard Worker *
12*4dc78e53SAndroid Build Coastguard Worker * @{
13*4dc78e53SAndroid Build Coastguard Worker */
14*4dc78e53SAndroid Build Coastguard Worker
15*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/classifier.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/fw.h>
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
22*4dc78e53SAndroid Build Coastguard Worker
23*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
24*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw {
25*4dc78e53SAndroid Build Coastguard Worker uint32_t cf_classid;
26*4dc78e53SAndroid Build Coastguard Worker struct nl_data *cf_act;
27*4dc78e53SAndroid Build Coastguard Worker struct nl_data *cf_police;
28*4dc78e53SAndroid Build Coastguard Worker char cf_indev[IFNAMSIZ];
29*4dc78e53SAndroid Build Coastguard Worker uint32_t cf_fwmask;
30*4dc78e53SAndroid Build Coastguard Worker int cf_mask;
31*4dc78e53SAndroid Build Coastguard Worker };
32*4dc78e53SAndroid Build Coastguard Worker
33*4dc78e53SAndroid Build Coastguard Worker #define FW_ATTR_CLASSID 0x001
34*4dc78e53SAndroid Build Coastguard Worker #define FW_ATTR_ACTION 0x002
35*4dc78e53SAndroid Build Coastguard Worker #define FW_ATTR_POLICE 0x004
36*4dc78e53SAndroid Build Coastguard Worker #define FW_ATTR_INDEV 0x008
37*4dc78e53SAndroid Build Coastguard Worker #define FW_ATTR_MASK 0x010
38*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
39*4dc78e53SAndroid Build Coastguard Worker
40*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy fw_policy[TCA_FW_MAX+1] = {
41*4dc78e53SAndroid Build Coastguard Worker [TCA_FW_CLASSID] = { .type = NLA_U32 },
42*4dc78e53SAndroid Build Coastguard Worker [TCA_FW_INDEV] = { .type = NLA_STRING,
43*4dc78e53SAndroid Build Coastguard Worker .maxlen = IFNAMSIZ },
44*4dc78e53SAndroid Build Coastguard Worker [TCA_FW_MASK] = { .type = NLA_U32 },
45*4dc78e53SAndroid Build Coastguard Worker };
46*4dc78e53SAndroid Build Coastguard Worker
fw_msg_parser(struct rtnl_tc * tc,void * data)47*4dc78e53SAndroid Build Coastguard Worker static int fw_msg_parser(struct rtnl_tc *tc, void *data)
48*4dc78e53SAndroid Build Coastguard Worker {
49*4dc78e53SAndroid Build Coastguard Worker struct nlattr *tb[TCA_FW_MAX + 1];
50*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f = data;
51*4dc78e53SAndroid Build Coastguard Worker int err;
52*4dc78e53SAndroid Build Coastguard Worker
53*4dc78e53SAndroid Build Coastguard Worker err = tca_parse(tb, TCA_FW_MAX, tc, fw_policy);
54*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
55*4dc78e53SAndroid Build Coastguard Worker return err;
56*4dc78e53SAndroid Build Coastguard Worker
57*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FW_CLASSID]) {
58*4dc78e53SAndroid Build Coastguard Worker f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
59*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_CLASSID;
60*4dc78e53SAndroid Build Coastguard Worker }
61*4dc78e53SAndroid Build Coastguard Worker
62*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FW_ACT]) {
63*4dc78e53SAndroid Build Coastguard Worker f->cf_act = nl_data_alloc_attr(tb[TCA_FW_ACT]);
64*4dc78e53SAndroid Build Coastguard Worker if (!f->cf_act)
65*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
66*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_ACTION;
67*4dc78e53SAndroid Build Coastguard Worker }
68*4dc78e53SAndroid Build Coastguard Worker
69*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FW_POLICE]) {
70*4dc78e53SAndroid Build Coastguard Worker f->cf_police = nl_data_alloc_attr(tb[TCA_FW_POLICE]);
71*4dc78e53SAndroid Build Coastguard Worker if (!f->cf_police)
72*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
73*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_POLICE;
74*4dc78e53SAndroid Build Coastguard Worker }
75*4dc78e53SAndroid Build Coastguard Worker
76*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FW_INDEV]) {
77*4dc78e53SAndroid Build Coastguard Worker nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
78*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_INDEV;
79*4dc78e53SAndroid Build Coastguard Worker }
80*4dc78e53SAndroid Build Coastguard Worker
81*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FW_MASK]) {
82*4dc78e53SAndroid Build Coastguard Worker f->cf_fwmask = nla_get_u32(tb[TCA_FW_MASK]);
83*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_MASK;
84*4dc78e53SAndroid Build Coastguard Worker }
85*4dc78e53SAndroid Build Coastguard Worker
86*4dc78e53SAndroid Build Coastguard Worker return 0;
87*4dc78e53SAndroid Build Coastguard Worker }
88*4dc78e53SAndroid Build Coastguard Worker
fw_free_data(struct rtnl_tc * tc,void * data)89*4dc78e53SAndroid Build Coastguard Worker static void fw_free_data(struct rtnl_tc *tc, void *data)
90*4dc78e53SAndroid Build Coastguard Worker {
91*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f = data;
92*4dc78e53SAndroid Build Coastguard Worker
93*4dc78e53SAndroid Build Coastguard Worker nl_data_free(f->cf_act);
94*4dc78e53SAndroid Build Coastguard Worker nl_data_free(f->cf_police);
95*4dc78e53SAndroid Build Coastguard Worker }
96*4dc78e53SAndroid Build Coastguard Worker
fw_clone(void * _dst,void * _src)97*4dc78e53SAndroid Build Coastguard Worker static int fw_clone(void *_dst, void *_src)
98*4dc78e53SAndroid Build Coastguard Worker {
99*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *dst = _dst, *src = _src;
100*4dc78e53SAndroid Build Coastguard Worker
101*4dc78e53SAndroid Build Coastguard Worker dst->cf_act = NULL;
102*4dc78e53SAndroid Build Coastguard Worker dst->cf_police = NULL;
103*4dc78e53SAndroid Build Coastguard Worker
104*4dc78e53SAndroid Build Coastguard Worker if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act)))
105*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
106*4dc78e53SAndroid Build Coastguard Worker
107*4dc78e53SAndroid Build Coastguard Worker if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police)))
108*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
109*4dc78e53SAndroid Build Coastguard Worker
110*4dc78e53SAndroid Build Coastguard Worker return 0;
111*4dc78e53SAndroid Build Coastguard Worker }
112*4dc78e53SAndroid Build Coastguard Worker
fw_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)113*4dc78e53SAndroid Build Coastguard Worker static void fw_dump_line(struct rtnl_tc *tc, void *data,
114*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p)
115*4dc78e53SAndroid Build Coastguard Worker {
116*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f = data;
117*4dc78e53SAndroid Build Coastguard Worker
118*4dc78e53SAndroid Build Coastguard Worker if (!f)
119*4dc78e53SAndroid Build Coastguard Worker return;
120*4dc78e53SAndroid Build Coastguard Worker
121*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_CLASSID) {
122*4dc78e53SAndroid Build Coastguard Worker char buf[32];
123*4dc78e53SAndroid Build Coastguard Worker
124*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " target %s",
125*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
126*4dc78e53SAndroid Build Coastguard Worker }
127*4dc78e53SAndroid Build Coastguard Worker
128*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_MASK)
129*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " mask 0x%x", f->cf_fwmask);
130*4dc78e53SAndroid Build Coastguard Worker }
131*4dc78e53SAndroid Build Coastguard Worker
fw_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)132*4dc78e53SAndroid Build Coastguard Worker static void fw_dump_details(struct rtnl_tc *tc, void *data,
133*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p)
134*4dc78e53SAndroid Build Coastguard Worker {
135*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f = data;
136*4dc78e53SAndroid Build Coastguard Worker
137*4dc78e53SAndroid Build Coastguard Worker if (f && f->cf_mask & FW_ATTR_INDEV)
138*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "indev %s ", f->cf_indev);
139*4dc78e53SAndroid Build Coastguard Worker }
140*4dc78e53SAndroid Build Coastguard Worker
fw_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)141*4dc78e53SAndroid Build Coastguard Worker static int fw_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
142*4dc78e53SAndroid Build Coastguard Worker {
143*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f = data;
144*4dc78e53SAndroid Build Coastguard Worker
145*4dc78e53SAndroid Build Coastguard Worker if (!f)
146*4dc78e53SAndroid Build Coastguard Worker return 0;
147*4dc78e53SAndroid Build Coastguard Worker
148*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_CLASSID)
149*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid);
150*4dc78e53SAndroid Build Coastguard Worker
151*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_ACTION)
152*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act);
153*4dc78e53SAndroid Build Coastguard Worker
154*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_POLICE)
155*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police);
156*4dc78e53SAndroid Build Coastguard Worker
157*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_INDEV)
158*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev);
159*4dc78e53SAndroid Build Coastguard Worker
160*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FW_ATTR_MASK)
161*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FW_MASK, f->cf_fwmask);
162*4dc78e53SAndroid Build Coastguard Worker
163*4dc78e53SAndroid Build Coastguard Worker return 0;
164*4dc78e53SAndroid Build Coastguard Worker
165*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
166*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
167*4dc78e53SAndroid Build Coastguard Worker }
168*4dc78e53SAndroid Build Coastguard Worker
169*4dc78e53SAndroid Build Coastguard Worker /**
170*4dc78e53SAndroid Build Coastguard Worker * @name Attribute Modifications
171*4dc78e53SAndroid Build Coastguard Worker * @{
172*4dc78e53SAndroid Build Coastguard Worker */
173*4dc78e53SAndroid Build Coastguard Worker
rtnl_fw_set_classid(struct rtnl_cls * cls,uint32_t classid)174*4dc78e53SAndroid Build Coastguard Worker int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
175*4dc78e53SAndroid Build Coastguard Worker {
176*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f;
177*4dc78e53SAndroid Build Coastguard Worker
178*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
179*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
180*4dc78e53SAndroid Build Coastguard Worker
181*4dc78e53SAndroid Build Coastguard Worker f->cf_classid = classid;
182*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_CLASSID;
183*4dc78e53SAndroid Build Coastguard Worker
184*4dc78e53SAndroid Build Coastguard Worker return 0;
185*4dc78e53SAndroid Build Coastguard Worker }
186*4dc78e53SAndroid Build Coastguard Worker
rtnl_fw_set_mask(struct rtnl_cls * cls,uint32_t mask)187*4dc78e53SAndroid Build Coastguard Worker int rtnl_fw_set_mask(struct rtnl_cls *cls, uint32_t mask)
188*4dc78e53SAndroid Build Coastguard Worker {
189*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fw *f;
190*4dc78e53SAndroid Build Coastguard Worker
191*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
192*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
193*4dc78e53SAndroid Build Coastguard Worker
194*4dc78e53SAndroid Build Coastguard Worker f->cf_fwmask = mask;
195*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FW_ATTR_MASK;
196*4dc78e53SAndroid Build Coastguard Worker
197*4dc78e53SAndroid Build Coastguard Worker return 0;
198*4dc78e53SAndroid Build Coastguard Worker }
199*4dc78e53SAndroid Build Coastguard Worker
200*4dc78e53SAndroid Build Coastguard Worker /** @} */
201*4dc78e53SAndroid Build Coastguard Worker
202*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops fw_ops = {
203*4dc78e53SAndroid Build Coastguard Worker .to_kind = "fw",
204*4dc78e53SAndroid Build Coastguard Worker .to_type = RTNL_TC_TYPE_CLS,
205*4dc78e53SAndroid Build Coastguard Worker .to_size = sizeof(struct rtnl_fw),
206*4dc78e53SAndroid Build Coastguard Worker .to_msg_parser = fw_msg_parser,
207*4dc78e53SAndroid Build Coastguard Worker .to_msg_fill = fw_msg_fill,
208*4dc78e53SAndroid Build Coastguard Worker .to_free_data = fw_free_data,
209*4dc78e53SAndroid Build Coastguard Worker .to_clone = fw_clone,
210*4dc78e53SAndroid Build Coastguard Worker .to_dump = {
211*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_LINE] = fw_dump_line,
212*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_DETAILS] = fw_dump_details,
213*4dc78e53SAndroid Build Coastguard Worker },
214*4dc78e53SAndroid Build Coastguard Worker };
215*4dc78e53SAndroid Build Coastguard Worker
fw_init(void)216*4dc78e53SAndroid Build Coastguard Worker static void _nl_init fw_init(void)
217*4dc78e53SAndroid Build Coastguard Worker {
218*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_register(&fw_ops);
219*4dc78e53SAndroid Build Coastguard Worker }
220*4dc78e53SAndroid Build Coastguard Worker
fw_exit(void)221*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit fw_exit(void)
222*4dc78e53SAndroid Build Coastguard Worker {
223*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_unregister(&fw_ops);
224*4dc78e53SAndroid Build Coastguard Worker }
225*4dc78e53SAndroid Build Coastguard Worker
226*4dc78e53SAndroid Build Coastguard Worker /** @} */
227