xref: /aosp_15_r20/external/libnl/lib/route/act/gact.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2016 Sushma Sitaram <[email protected]>
4  */
5 
6 /**
7  * @ingroup act
8  * @defgroup act_gact GACT Editing
9  *
10  * @{
11  */
12 
13 #include "nl-default.h"
14 
15 #include <netlink/netlink.h>
16 #include <netlink/attr.h>
17 #include <netlink/utils.h>
18 #include <netlink/route/act/gact.h>
19 
20 #include "tc-api.h"
21 
22 struct rtnl_gact {
23 	struct tc_gact g_parm;
24 };
25 
26 static struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
27 	[TCA_GACT_PARMS]             = { .minlen = sizeof(struct tc_gact) },
28 };
29 
gact_msg_parser(struct rtnl_tc * tc,void * data)30 static int gact_msg_parser(struct rtnl_tc *tc, void *data)
31 {
32 	struct rtnl_gact *u = data;
33 	struct nlattr *tb[TCA_GACT_MAX + 1];
34 	int err;
35 
36 	err = tca_parse(tb, TCA_GACT_MAX, tc, gact_policy);
37 	if (err < 0)
38 		return err;
39 
40 	if (!tb[TCA_GACT_PARMS])
41 		return -NLE_MISSING_ATTR;
42 
43 	nla_memcpy(&u->g_parm, tb[TCA_GACT_PARMS], sizeof(u->g_parm));
44 
45 	return 0;
46 }
47 
gact_free_data(struct rtnl_tc * tc,void * data)48 static void gact_free_data(struct rtnl_tc *tc, void *data)
49 {
50 }
51 
gact_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)52 static void gact_dump_line(struct rtnl_tc *tc, void *data,
53 			  struct nl_dump_params *p)
54 {
55 	struct rtnl_gact *u = data;
56 
57 	if (!u)
58 		return;
59 
60 	switch(u->g_parm.action){
61 	case TC_ACT_UNSPEC:
62 		nl_dump(p, " continue");
63 		break;
64 	case TC_ACT_SHOT:
65 		nl_dump(p, " drop");
66 		break;
67 	case TC_ACT_RECLASSIFY:
68 		nl_dump(p, " reclassify");
69 		break;
70 	case TC_ACT_OK:
71 		nl_dump(p, " pass");
72 		break;
73 	}
74 
75 }
76 
gact_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)77 static void gact_dump_details(struct rtnl_tc *tc, void *data,
78 			     struct nl_dump_params *p)
79 {
80 }
81 
gact_dump_stats(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)82 static void gact_dump_stats(struct rtnl_tc *tc, void *data,
83 			   struct nl_dump_params *p)
84 {
85 	struct rtnl_gact *u = data;
86 
87 	if (!u)
88 		return;
89 	/* TODO */
90 }
91 
92 
gact_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)93 static int gact_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
94 {
95 	struct rtnl_gact *u = data;
96 
97 	if (!u)
98 		return 0;
99 
100 	NLA_PUT(msg, TCA_GACT_PARMS, sizeof(u->g_parm), &u->g_parm);
101 
102 	return 0;
103 
104 nla_put_failure:
105 	return -NLE_NOMEM;
106 }
107 
108 /**
109  * @name Attribute Modifications
110  * @{
111  */
112 
rtnl_gact_set_action(struct rtnl_act * act,int action)113 int rtnl_gact_set_action(struct rtnl_act *act, int action)
114 {
115 	struct rtnl_gact *u;
116 
117 	if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act))))
118 		return -NLE_NOMEM;
119 
120 	u->g_parm.action = action;
121 
122 	return 0;
123 }
124 
rtnl_gact_get_action(struct rtnl_act * act)125 int rtnl_gact_get_action(struct rtnl_act *act)
126 {
127 	struct rtnl_gact *u;
128 
129 	if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act))))
130 		return -NLE_NOMEM;
131 	return u->g_parm.action;
132 }
133 
134 
135 /** @} */
136 
137 static struct rtnl_tc_ops gact_ops = {
138 	.to_kind		= "gact",
139 	.to_type		= RTNL_TC_TYPE_ACT,
140 	.to_size		= sizeof(struct rtnl_gact),
141 	.to_msg_parser		= gact_msg_parser,
142 	.to_free_data		= gact_free_data,
143 	.to_clone		= NULL,
144 	.to_msg_fill		= gact_msg_fill,
145 	.to_dump = {
146 	    [NL_DUMP_LINE]	= gact_dump_line,
147 	    [NL_DUMP_DETAILS]	= gact_dump_details,
148 	    [NL_DUMP_STATS]	= gact_dump_stats,
149 	},
150 };
151 
gact_init(void)152 static void _nl_init gact_init(void)
153 {
154 	rtnl_tc_register(&gact_ops);
155 }
156 
gact_exit(void)157 static void _nl_exit gact_exit(void)
158 {
159 	rtnl_tc_unregister(&gact_ops);
160 }
161 
162 /** @} */
163