2 * lib/route/cls/fw.c fw classifier
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
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
16 * @defgroup fw Firewall Classifier
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>
29 #define FW_ATTR_CLASSID 0x001
30 #define FW_ATTR_ACTION 0x002
31 #define FW_ATTR_POLICE 0x004
32 #define FW_ATTR_INDEV 0x008
35 static inline struct rtnl_fw *fw_cls(struct rtnl_cls *cls)
37 return (struct rtnl_fw *) cls->c_subdata;
40 static inline struct rtnl_fw *fw_alloc(struct rtnl_cls *cls)
43 cls->c_subdata = calloc(1, sizeof(struct rtnl_fw));
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,
54 static int fw_msg_parser(struct rtnl_cls *cls)
57 struct nlattr *tb[TCA_FW_MAX + 1];
60 err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy);
68 if (tb[TCA_FW_CLASSID]) {
69 f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
70 f->cf_mask |= FW_ATTR_CLASSID;
74 f->cf_act = nla_get_data(tb[TCA_FW_ACT]);
77 f->cf_mask |= FW_ATTR_ACTION;
80 if (tb[TCA_FW_POLICE]) {
81 f->cf_police = nla_get_data(tb[TCA_FW_POLICE]);
84 f->cf_mask |= FW_ATTR_POLICE;
87 if (tb[TCA_FW_INDEV]) {
88 nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
89 f->cf_mask |= FW_ATTR_INDEV;
95 err = nl_errno(ENOMEM);
100 static void fw_free_data(struct rtnl_cls *cls)
102 struct rtnl_fw *f = fw_cls(cls);
107 nl_data_free(f->cf_act);
108 nl_data_free(f->cf_police);
110 free(cls->c_subdata);
113 static int fw_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p,
116 struct rtnl_fw *f = fw_cls(cls);
122 if (f->cf_mask & FW_ATTR_CLASSID)
123 dp_dump(p, " target %s",
124 rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
130 static int fw_dump_full(struct rtnl_cls *cls, struct nl_dump_params *p,
133 struct rtnl_fw *f = fw_cls(cls);
138 if (f->cf_mask & FW_ATTR_INDEV)
139 dp_dump(p, "indev %s ", f->cf_indev);
145 static int fw_dump_stats(struct rtnl_cls *cls, struct nl_dump_params *p,
148 struct rtnl_fw *f = fw_cls(cls);
157 static struct nl_msg *fw_get_opts(struct rtnl_cls *cls)
166 msg = nlmsg_build_no_hdr();
170 if (f->cf_mask & FW_ATTR_CLASSID)
171 nla_put_u32(msg, TCA_FW_CLASSID, f->cf_classid);
173 if (f->cf_mask & FW_ATTR_ACTION)
174 nla_put_data(msg, TCA_FW_ACT, f->cf_act);
176 if (f->cf_mask & FW_ATTR_POLICE)
177 nla_put_data(msg, TCA_FW_POLICE, f->cf_police);
179 if (f->cf_mask & FW_ATTR_INDEV)
180 nla_put_string(msg, TCA_FW_INDEV, f->cf_indev);
186 * @name Attribute Modifications
190 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
196 return nl_errno(ENOMEM);
198 f->cf_classid = classid;
199 f->cf_mask |= FW_ATTR_CLASSID;
206 static struct rtnl_cls_ops fw_ops = {
208 .co_msg_parser = fw_msg_parser,
209 .co_free_data = fw_free_data,
210 .co_get_opts = fw_get_opts,
211 .co_dump[NL_DUMP_BRIEF] = fw_dump_brief,
212 .co_dump[NL_DUMP_FULL] = fw_dump_full,
213 .co_dump[NL_DUMP_STATS] = fw_dump_stats,
216 static void __init fw_init(void)
218 rtnl_cls_register(&fw_ops);
221 static void __exit fw_exit(void)
223 rtnl_cls_unregister(&fw_ops);