libnl  1.1.4
fw.c
1 /*
2  * lib/route/cls/fw.c fw classifier
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) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  * Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com>
11  * Copyright (c) 2006 Siemens AG Oesterreich
12  */
13 
14 /**
15  * @ingroup cls_api
16  * @defgroup fw Firewall Classifier
17  *
18  * @{
19  */
20 
21 #include <netlink-local.h>
22 #include <netlink-tc.h>
23 #include <netlink/netlink.h>
24 #include <netlink/route/classifier.h>
25 #include <netlink/route/classifier-modules.h>
26 #include <netlink/route/cls/fw.h>
27 
28 /** @cond SKIP */
29 #define FW_ATTR_CLASSID 0x001
30 #define FW_ATTR_ACTION 0x002
31 #define FW_ATTR_POLICE 0x004
32 #define FW_ATTR_INDEV 0x008
33 /** @endcond */
34 
35 static inline struct rtnl_fw *fw_cls(struct rtnl_cls *cls)
36 {
37  return (struct rtnl_fw *) cls->c_subdata;
38 }
39 
40 static inline struct rtnl_fw *fw_alloc(struct rtnl_cls *cls)
41 {
42  if (!cls->c_subdata)
43  cls->c_subdata = calloc(1, sizeof(struct rtnl_fw));
44 
45  return fw_cls(cls);
46 }
47 
48 static struct nla_policy fw_policy[TCA_FW_MAX+1] = {
49  [TCA_FW_CLASSID] = { .type = NLA_U32 },
50  [TCA_FW_INDEV] = { .type = NLA_STRING,
51  .maxlen = IFNAMSIZ },
52 };
53 
54 static int fw_msg_parser(struct rtnl_cls *cls)
55 {
56  int err;
57  struct nlattr *tb[TCA_FW_MAX + 1];
58  struct rtnl_fw *f;
59 
60  err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy);
61  if (err < 0)
62  return err;
63 
64  f = fw_alloc(cls);
65  if (!f)
66  goto errout_nomem;
67 
68  if (tb[TCA_FW_CLASSID]) {
69  f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
70  f->cf_mask |= FW_ATTR_CLASSID;
71  }
72 
73  if (tb[TCA_FW_ACT]) {
74  f->cf_act = nla_get_data(tb[TCA_FW_ACT]);
75  if (!f->cf_act)
76  goto errout_nomem;
77  f->cf_mask |= FW_ATTR_ACTION;
78  }
79 
80  if (tb[TCA_FW_POLICE]) {
81  f->cf_police = nla_get_data(tb[TCA_FW_POLICE]);
82  if (!f->cf_police)
83  goto errout_nomem;
84  f->cf_mask |= FW_ATTR_POLICE;
85  }
86 
87  if (tb[TCA_FW_INDEV]) {
88  nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
89  f->cf_mask |= FW_ATTR_INDEV;
90  }
91 
92  return 0;
93 
94 errout_nomem:
95  err = nl_errno(ENOMEM);
96 
97  return err;
98 }
99 
100 static void fw_free_data(struct rtnl_cls *cls)
101 {
102  struct rtnl_fw *f = fw_cls(cls);
103 
104  if (!f)
105  return;
106 
107  nl_data_free(f->cf_act);
108  nl_data_free(f->cf_police);
109 
110  free(cls->c_subdata);
111 }
112 
113 static int fw_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src)
114 {
115  struct rtnl_fw *dst, *src = fw_cls(_src);
116 
117  if (!src)
118  return 0;
119 
120  dst = fw_alloc(_dst);
121  if (!dst)
122  return nl_errno(ENOMEM);
123 
124  if (src->cf_act)
125  if (!(dst->cf_act = nl_data_clone(src->cf_act)))
126  goto errout;
127 
128  if (src->cf_police)
129  if (!(dst->cf_police = nl_data_clone(src->cf_police)))
130  goto errout;
131 
132  return 0;
133 errout:
134  return nl_get_errno();
135 }
136 
137 static int fw_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p,
138  int line)
139 {
140  struct rtnl_fw *f = fw_cls(cls);
141  char buf[32];
142 
143  if (!f)
144  goto ignore;
145 
146  if (f->cf_mask & FW_ATTR_CLASSID)
147  dp_dump(p, " target %s",
148  rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
149 
150 ignore:
151  return line;
152 }
153 
154 static int fw_dump_full(struct rtnl_cls *cls, struct nl_dump_params *p,
155  int line)
156 {
157  struct rtnl_fw *f = fw_cls(cls);
158 
159  if (!f)
160  goto ignore;
161 
162  if (f->cf_mask & FW_ATTR_INDEV)
163  dp_dump(p, "indev %s ", f->cf_indev);
164 
165 ignore:
166  return line;
167 }
168 
169 static int fw_dump_stats(struct rtnl_cls *cls, struct nl_dump_params *p,
170  int line)
171 {
172  struct rtnl_fw *f = fw_cls(cls);
173 
174  if (!f)
175  goto ignore;
176 
177 ignore:
178  return line;
179 }
180 
181 static struct nl_msg *fw_get_opts(struct rtnl_cls *cls)
182 {
183  struct rtnl_fw *f;
184  struct nl_msg *msg;
185 
186  f = fw_cls(cls);
187  if (!f)
188  return NULL;
189 
190  msg = nlmsg_alloc();
191  if (!msg)
192  return NULL;
193 
194  if (f->cf_mask & FW_ATTR_CLASSID)
195  nla_put_u32(msg, TCA_FW_CLASSID, f->cf_classid);
196 
197  if (f->cf_mask & FW_ATTR_ACTION)
198  nla_put_data(msg, TCA_FW_ACT, f->cf_act);
199 
200  if (f->cf_mask & FW_ATTR_POLICE)
201  nla_put_data(msg, TCA_FW_POLICE, f->cf_police);
202 
203  if (f->cf_mask & FW_ATTR_INDEV)
204  nla_put_string(msg, TCA_FW_INDEV, f->cf_indev);
205 
206  return msg;
207 }
208 
209 /**
210  * @name Attribute Modifications
211  * @{
212  */
213 
214 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
215 {
216  struct rtnl_fw *f;
217 
218  f = fw_alloc(cls);
219  if (!f)
220  return nl_errno(ENOMEM);
221 
222  f->cf_classid = classid;
223  f->cf_mask |= FW_ATTR_CLASSID;
224 
225  return 0;
226 }
227 
228 /** @} */
229 
230 static struct rtnl_cls_ops fw_ops = {
231  .co_kind = "fw",
232  .co_msg_parser = fw_msg_parser,
233  .co_free_data = fw_free_data,
234  .co_clone = fw_clone,
235  .co_get_opts = fw_get_opts,
236  .co_dump[NL_DUMP_BRIEF] = fw_dump_brief,
237  .co_dump[NL_DUMP_FULL] = fw_dump_full,
238  .co_dump[NL_DUMP_STATS] = fw_dump_stats,
239 };
240 
241 static void __init fw_init(void)
242 {
243  rtnl_cls_register(&fw_ops);
244 }
245 
246 static void __exit fw_exit(void)
247 {
248  rtnl_cls_unregister(&fw_ops);
249 }
250 
251 /** @} */
32bit integer
Definition: attr.h:39
Dump object in a brief one-liner.
Definition: types.h:22
char co_kind[32]
Kind/Name of classifier.
int rtnl_cls_unregister(struct rtnl_cls_ops *cops)
Unregister a classifier module.
Definition: cls_api.c:59
struct nl_data * nl_data_clone(struct nl_data *src)
Clone an abstract data object.
Definition: data.c:69
attribute validation policy
Definition: attr.h:73
struct nl_msg * nlmsg_alloc(void)
Allocate a new netlink message with the default maximum payload size.
Definition: msg.c:401
character string
Definition: attr.h:41
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition: tc.c:493
int nla_put_data(struct nl_msg *n, int attrtype, struct nl_data *data)
Add an abstract data netlink attribute to a netlink message.
Definition: attr.c:623
int nla_put_string(struct nl_msg *n, int attrtype, const char *str)
Add a string netlink attribute to a netlink message.
Definition: attr.c:591
int rtnl_cls_register(struct rtnl_cls_ops *cops)
Register a classifier module.
Definition: cls_api.c:38
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:75
Classifier operations.
Dumping parameters.
Definition: types.h:36
struct nl_data * nla_get_data(struct nlattr *nla)
Return payload of abstract data attribute.
Definition: attr.c:776
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of u32 attribute.
Definition: attr.c:693
int nla_put_u32(struct nl_msg *n, int attrtype, uint32_t value)
Add a u32 netlink attribute to a netlink message.
Definition: attr.c:569
Dump all attributes but no statistics.
Definition: types.h:23
Dump all attributes including statistics.
Definition: types.h:24
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload into a sized buffer.
Definition: attr.c:407
void nl_data_free(struct nl_data *data)
Free an abstract data object.
Definition: data.c:110