xref: /aosp_15_r20/external/libnl/lib/route/cls/fw.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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