xref: /aosp_15_r20/external/libnl/lib/route/act/mirred.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) 2013 Cong Wang <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup act
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup act_mirred Mirror and Redirect
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * @{
11*4dc78e53SAndroid Build Coastguard Worker  */
12*4dc78e53SAndroid Build Coastguard Worker 
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/act/mirred.h>
19*4dc78e53SAndroid Build Coastguard Worker 
20*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker struct rtnl_mirred {
23*4dc78e53SAndroid Build Coastguard Worker 	struct tc_mirred m_parm;
24*4dc78e53SAndroid Build Coastguard Worker };
25*4dc78e53SAndroid Build Coastguard Worker 
26*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
27*4dc78e53SAndroid Build Coastguard Worker 	[TCA_MIRRED_PARMS]      = { .minlen = sizeof(struct tc_mirred) },
28*4dc78e53SAndroid Build Coastguard Worker };
29*4dc78e53SAndroid Build Coastguard Worker 
mirred_msg_parser(struct rtnl_tc * tc,void * data)30*4dc78e53SAndroid Build Coastguard Worker static int mirred_msg_parser(struct rtnl_tc *tc, void *data)
31*4dc78e53SAndroid Build Coastguard Worker {
32*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u = data;
33*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[TCA_MIRRED_MAX + 1];
34*4dc78e53SAndroid Build Coastguard Worker 	int err;
35*4dc78e53SAndroid Build Coastguard Worker 
36*4dc78e53SAndroid Build Coastguard Worker 	err = tca_parse(tb, TCA_MIRRED_MAX, tc, mirred_policy);
37*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
38*4dc78e53SAndroid Build Coastguard Worker 		return err;
39*4dc78e53SAndroid Build Coastguard Worker 
40*4dc78e53SAndroid Build Coastguard Worker 	if (!tb[TCA_MIRRED_PARMS])
41*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
42*4dc78e53SAndroid Build Coastguard Worker 
43*4dc78e53SAndroid Build Coastguard Worker 	nla_memcpy(&u->m_parm, tb[TCA_MIRRED_PARMS], sizeof(u->m_parm));
44*4dc78e53SAndroid Build Coastguard Worker 	return 0;
45*4dc78e53SAndroid Build Coastguard Worker }
46*4dc78e53SAndroid Build Coastguard Worker 
mirred_free_data(struct rtnl_tc * tc,void * data)47*4dc78e53SAndroid Build Coastguard Worker static void mirred_free_data(struct rtnl_tc *tc, void *data)
48*4dc78e53SAndroid Build Coastguard Worker {
49*4dc78e53SAndroid Build Coastguard Worker }
50*4dc78e53SAndroid Build Coastguard Worker 
mirred_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)51*4dc78e53SAndroid Build Coastguard Worker static void mirred_dump_line(struct rtnl_tc *tc, void *data,
52*4dc78e53SAndroid Build Coastguard Worker 			  struct nl_dump_params *p)
53*4dc78e53SAndroid Build Coastguard Worker {
54*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u = data;
55*4dc78e53SAndroid Build Coastguard Worker 	if (!u)
56*4dc78e53SAndroid Build Coastguard Worker 		return;
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, " index %u", u->m_parm.ifindex);
59*4dc78e53SAndroid Build Coastguard Worker 
60*4dc78e53SAndroid Build Coastguard Worker 	if (u->m_parm.eaction == TCA_EGRESS_MIRROR)
61*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " egress mirror");
62*4dc78e53SAndroid Build Coastguard Worker 	else if (u->m_parm.eaction == TCA_EGRESS_REDIR)
63*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " egress redirect");
64*4dc78e53SAndroid Build Coastguard Worker 
65*4dc78e53SAndroid Build Coastguard Worker 	switch(u->m_parm.action) {
66*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_UNSPEC:
67*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " unspecified");
68*4dc78e53SAndroid Build Coastguard Worker 		break;
69*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_PIPE:
70*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " pipe");
71*4dc78e53SAndroid Build Coastguard Worker 		break;
72*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_STOLEN:
73*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " stolen");
74*4dc78e53SAndroid Build Coastguard Worker 		break;
75*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_SHOT:
76*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " shot");
77*4dc78e53SAndroid Build Coastguard Worker 		break;
78*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_QUEUED:
79*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " queued");
80*4dc78e53SAndroid Build Coastguard Worker 		break;
81*4dc78e53SAndroid Build Coastguard Worker 	case TC_ACT_REPEAT:
82*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " repeat");
83*4dc78e53SAndroid Build Coastguard Worker 		break;
84*4dc78e53SAndroid Build Coastguard Worker 	}
85*4dc78e53SAndroid Build Coastguard Worker }
86*4dc78e53SAndroid Build Coastguard Worker 
mirred_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)87*4dc78e53SAndroid Build Coastguard Worker static void mirred_dump_details(struct rtnl_tc *tc, void *data,
88*4dc78e53SAndroid Build Coastguard Worker 			     struct nl_dump_params *p)
89*4dc78e53SAndroid Build Coastguard Worker {
90*4dc78e53SAndroid Build Coastguard Worker }
91*4dc78e53SAndroid Build Coastguard Worker 
mirred_dump_stats(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)92*4dc78e53SAndroid Build Coastguard Worker static void mirred_dump_stats(struct rtnl_tc *tc, void *data,
93*4dc78e53SAndroid Build Coastguard Worker 			   struct nl_dump_params *p)
94*4dc78e53SAndroid Build Coastguard Worker {
95*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u = data;
96*4dc78e53SAndroid Build Coastguard Worker 
97*4dc78e53SAndroid Build Coastguard Worker 	if (!u)
98*4dc78e53SAndroid Build Coastguard Worker 		return;
99*4dc78e53SAndroid Build Coastguard Worker 	/* TODO */
100*4dc78e53SAndroid Build Coastguard Worker }
101*4dc78e53SAndroid Build Coastguard Worker 
102*4dc78e53SAndroid Build Coastguard Worker 
mirred_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)103*4dc78e53SAndroid Build Coastguard Worker static int mirred_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
104*4dc78e53SAndroid Build Coastguard Worker {
105*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u = data;
106*4dc78e53SAndroid Build Coastguard Worker 
107*4dc78e53SAndroid Build Coastguard Worker 	if (!u)
108*4dc78e53SAndroid Build Coastguard Worker 		return 0;
109*4dc78e53SAndroid Build Coastguard Worker 
110*4dc78e53SAndroid Build Coastguard Worker 	NLA_PUT(msg, TCA_MIRRED_PARMS, sizeof(u->m_parm), &u->m_parm);
111*4dc78e53SAndroid Build Coastguard Worker 	return 0;
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
114*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_NOMEM;
115*4dc78e53SAndroid Build Coastguard Worker }
116*4dc78e53SAndroid Build Coastguard Worker 
117*4dc78e53SAndroid Build Coastguard Worker /**
118*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modifications
119*4dc78e53SAndroid Build Coastguard Worker  * @{
120*4dc78e53SAndroid Build Coastguard Worker  */
121*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_set_action(struct rtnl_act * act,int action)122*4dc78e53SAndroid Build Coastguard Worker int rtnl_mirred_set_action(struct rtnl_act *act, int action)
123*4dc78e53SAndroid Build Coastguard Worker {
124*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
125*4dc78e53SAndroid Build Coastguard Worker 
126*4dc78e53SAndroid Build Coastguard Worker 	if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
127*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
128*4dc78e53SAndroid Build Coastguard Worker 
129*4dc78e53SAndroid Build Coastguard Worker 	if (action > TCA_INGRESS_MIRROR || action < TCA_EGRESS_REDIR)
130*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
131*4dc78e53SAndroid Build Coastguard Worker 
132*4dc78e53SAndroid Build Coastguard Worker 	switch (action) {
133*4dc78e53SAndroid Build Coastguard Worker 	case TCA_EGRESS_MIRROR:
134*4dc78e53SAndroid Build Coastguard Worker 	case TCA_EGRESS_REDIR:
135*4dc78e53SAndroid Build Coastguard Worker 		u->m_parm.eaction = action;
136*4dc78e53SAndroid Build Coastguard Worker 		break;
137*4dc78e53SAndroid Build Coastguard Worker 	case TCA_INGRESS_REDIR:
138*4dc78e53SAndroid Build Coastguard Worker 	case TCA_INGRESS_MIRROR:
139*4dc78e53SAndroid Build Coastguard Worker 	default:
140*4dc78e53SAndroid Build Coastguard Worker 		return NLE_OPNOTSUPP;
141*4dc78e53SAndroid Build Coastguard Worker 	}
142*4dc78e53SAndroid Build Coastguard Worker 	return 0;
143*4dc78e53SAndroid Build Coastguard Worker }
144*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_get_action(struct rtnl_act * act)145*4dc78e53SAndroid Build Coastguard Worker int rtnl_mirred_get_action(struct rtnl_act *act)
146*4dc78e53SAndroid Build Coastguard Worker {
147*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
148*4dc78e53SAndroid Build Coastguard Worker 
149*4dc78e53SAndroid Build Coastguard Worker 	if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
150*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
151*4dc78e53SAndroid Build Coastguard Worker 	return u->m_parm.eaction;
152*4dc78e53SAndroid Build Coastguard Worker }
153*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_set_ifindex(struct rtnl_act * act,uint32_t ifindex)154*4dc78e53SAndroid Build Coastguard Worker int rtnl_mirred_set_ifindex(struct rtnl_act *act, uint32_t ifindex)
155*4dc78e53SAndroid Build Coastguard Worker {
156*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
157*4dc78e53SAndroid Build Coastguard Worker 
158*4dc78e53SAndroid Build Coastguard Worker 	if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
159*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
160*4dc78e53SAndroid Build Coastguard Worker 
161*4dc78e53SAndroid Build Coastguard Worker 	u->m_parm.ifindex = ifindex;
162*4dc78e53SAndroid Build Coastguard Worker 	return 0;
163*4dc78e53SAndroid Build Coastguard Worker }
164*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_get_ifindex(struct rtnl_act * act)165*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_mirred_get_ifindex(struct rtnl_act *act)
166*4dc78e53SAndroid Build Coastguard Worker {
167*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
168*4dc78e53SAndroid Build Coastguard Worker 
169*4dc78e53SAndroid Build Coastguard Worker 	if ((u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
170*4dc78e53SAndroid Build Coastguard Worker 		return u->m_parm.ifindex;
171*4dc78e53SAndroid Build Coastguard Worker 	return 0;
172*4dc78e53SAndroid Build Coastguard Worker }
173*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_set_policy(struct rtnl_act * act,int policy)174*4dc78e53SAndroid Build Coastguard Worker int rtnl_mirred_set_policy(struct rtnl_act *act, int policy)
175*4dc78e53SAndroid Build Coastguard Worker {
176*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
177*4dc78e53SAndroid Build Coastguard Worker 
178*4dc78e53SAndroid Build Coastguard Worker 	if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
179*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
180*4dc78e53SAndroid Build Coastguard Worker 
181*4dc78e53SAndroid Build Coastguard Worker 	u->m_parm.action = policy;
182*4dc78e53SAndroid Build Coastguard Worker 
183*4dc78e53SAndroid Build Coastguard Worker 	return 0;
184*4dc78e53SAndroid Build Coastguard Worker }
185*4dc78e53SAndroid Build Coastguard Worker 
rtnl_mirred_get_policy(struct rtnl_act * act)186*4dc78e53SAndroid Build Coastguard Worker int rtnl_mirred_get_policy(struct rtnl_act *act)
187*4dc78e53SAndroid Build Coastguard Worker {
188*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mirred *u;
189*4dc78e53SAndroid Build Coastguard Worker 
190*4dc78e53SAndroid Build Coastguard Worker 	if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
191*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
192*4dc78e53SAndroid Build Coastguard Worker 	return u->m_parm.action;
193*4dc78e53SAndroid Build Coastguard Worker }
194*4dc78e53SAndroid Build Coastguard Worker 
195*4dc78e53SAndroid Build Coastguard Worker /** @} */
196*4dc78e53SAndroid Build Coastguard Worker 
197*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops mirred_ops = {
198*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "mirred",
199*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_ACT,
200*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_mirred),
201*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= mirred_msg_parser,
202*4dc78e53SAndroid Build Coastguard Worker 	.to_free_data		= mirred_free_data,
203*4dc78e53SAndroid Build Coastguard Worker 	.to_clone		= NULL,
204*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= mirred_msg_fill,
205*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
206*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= mirred_dump_line,
207*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= mirred_dump_details,
208*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_STATS]	= mirred_dump_stats,
209*4dc78e53SAndroid Build Coastguard Worker 	},
210*4dc78e53SAndroid Build Coastguard Worker };
211*4dc78e53SAndroid Build Coastguard Worker 
mirred_init(void)212*4dc78e53SAndroid Build Coastguard Worker static void _nl_init mirred_init(void)
213*4dc78e53SAndroid Build Coastguard Worker {
214*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&mirred_ops);
215*4dc78e53SAndroid Build Coastguard Worker }
216*4dc78e53SAndroid Build Coastguard Worker 
mirred_exit(void)217*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit mirred_exit(void)
218*4dc78e53SAndroid Build Coastguard Worker {
219*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&mirred_ops);
220*4dc78e53SAndroid Build Coastguard Worker }
221*4dc78e53SAndroid Build Coastguard Worker 
222*4dc78e53SAndroid Build Coastguard Worker /** @} */
223