1 /*
2 * lib/route/act/gact.c gact action
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
7 * of the License.
8 *
9 * Copyright (c) 2016 Sushma Sitaram <sushma.sitaram@intel.com>
10 */
11
12 /**
13 * @ingroup act
14 * @defgroup act_gact GACT Editing
15 *
16 * @{
17 */
18
19 #include <netlink-private/netlink.h>
20 #include <netlink-private/tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/attr.h>
23 #include <netlink/utils.h>
24 #include <netlink-private/route/tc-api.h>
25 #include <netlink/route/act/gact.h>
26
27 static struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
28 [TCA_GACT_PARMS] = { .minlen = sizeof(struct tc_gact) },
29 };
30
gact_msg_parser(struct rtnl_tc * tc,void * data)31 static int gact_msg_parser(struct rtnl_tc *tc, void *data)
32 {
33 struct rtnl_gact *u = data;
34 struct nlattr *tb[TCA_GACT_MAX + 1];
35 int err;
36
37 err = tca_parse(tb, TCA_GACT_MAX, tc, gact_policy);
38 if (err < 0)
39 return err;
40
41 if (!tb[TCA_GACT_PARMS])
42 return -NLE_MISSING_ATTR;
43
44 nla_memcpy(&u->g_parm, tb[TCA_GACT_PARMS], sizeof(u->g_parm));
45
46 return 0;
47 }
48
gact_free_data(struct rtnl_tc * tc,void * data)49 static void gact_free_data(struct rtnl_tc *tc, void *data)
50 {
51 }
52
gact_clone(void * _dst,void * _src)53 static int gact_clone(void *_dst, void *_src)
54 {
55 struct rtnl_gact *dst = _dst, *src = _src;
56
57 memcpy(&dst->g_parm, &src->g_parm, sizeof(src->g_parm));
58 return 0;
59 }
60
gact_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)61 static void gact_dump_line(struct rtnl_tc *tc, void *data,
62 struct nl_dump_params *p)
63 {
64 struct rtnl_gact *u = data;
65
66 if (!u)
67 return;
68
69 switch(u->g_parm.action){
70 case TC_ACT_UNSPEC:
71 nl_dump(p, " continue");
72 break;
73 case TC_ACT_SHOT:
74 nl_dump(p, " drop");
75 break;
76 case TC_ACT_RECLASSIFY:
77 nl_dump(p, " reclassify");
78 break;
79 case TC_ACT_OK:
80 nl_dump(p, " pass");
81 break;
82 }
83
84 }
85
gact_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)86 static void gact_dump_details(struct rtnl_tc *tc, void *data,
87 struct nl_dump_params *p)
88 {
89 }
90
gact_dump_stats(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)91 static void gact_dump_stats(struct rtnl_tc *tc, void *data,
92 struct nl_dump_params *p)
93 {
94 struct rtnl_gact *u = data;
95
96 if (!u)
97 return;
98 /* TODO */
99 }
100
101
gact_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)102 static int gact_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
103 {
104 struct rtnl_gact *u = data;
105
106 if (!u)
107 return 0;
108
109 NLA_PUT(msg, TCA_GACT_PARMS, sizeof(u->g_parm), &u->g_parm);
110
111 return 0;
112
113 nla_put_failure:
114 return -NLE_NOMEM;
115 }
116
117 /**
118 * @name Attribute Modifications
119 * @{
120 */
121
rtnl_gact_set_action(struct rtnl_act * act,int action)122 int rtnl_gact_set_action(struct rtnl_act *act, int action)
123 {
124 struct rtnl_gact *u;
125
126 if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act))))
127 return -NLE_NOMEM;
128
129 if (action > TC_ACT_SHOT || action < TC_ACT_UNSPEC)
130 return -NLE_INVAL;
131
132 switch (action) {
133 case TC_ACT_UNSPEC:
134 case TC_ACT_SHOT:
135 u->g_parm.action = action;
136 break;
137 case TC_ACT_OK:
138 case TC_ACT_RECLASSIFY:
139 default:
140 return NLE_OPNOTSUPP;
141 }
142
143 return 0;
144 }
145
rtnl_gact_get_action(struct rtnl_act * act)146 int rtnl_gact_get_action(struct rtnl_act *act)
147 {
148 struct rtnl_gact *u;
149
150 if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act))))
151 return -NLE_NOMEM;
152 return u->g_parm.action;
153 }
154
155
156 /** @} */
157
158 static struct rtnl_tc_ops gact_ops = {
159 .to_kind = "gact",
160 .to_type = RTNL_TC_TYPE_ACT,
161 .to_size = sizeof(struct rtnl_gact),
162 .to_msg_parser = gact_msg_parser,
163 .to_free_data = gact_free_data,
164 .to_clone = gact_clone,
165 .to_msg_fill = gact_msg_fill,
166 .to_dump = {
167 [NL_DUMP_LINE] = gact_dump_line,
168 [NL_DUMP_DETAILS] = gact_dump_details,
169 [NL_DUMP_STATS] = gact_dump_stats,
170 },
171 };
172
gact_init(void)173 static void __init gact_init(void)
174 {
175 rtnl_tc_register(&gact_ops);
176 }
177
gact_exit(void)178 static void __exit gact_exit(void)
179 {
180 rtnl_tc_unregister(&gact_ops);
181 }
182
183 /** @} */
184