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-2009 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 struct nla_policy fw_policy[TCA_FW_MAX+1] = {
36 [TCA_FW_CLASSID] = { .type = NLA_U32 },
37 [TCA_FW_INDEV] = { .type = NLA_STRING,
41 static int fw_msg_parser(struct rtnl_cls *cls)
43 struct rtnl_fw *f = rtnl_cls_data(cls);
44 struct nlattr *tb[TCA_FW_MAX + 1];
47 err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy);
51 if (tb[TCA_FW_CLASSID]) {
52 f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
53 f->cf_mask |= FW_ATTR_CLASSID;
57 f->cf_act = nl_data_alloc_attr(tb[TCA_FW_ACT]);
60 f->cf_mask |= FW_ATTR_ACTION;
63 if (tb[TCA_FW_POLICE]) {
64 f->cf_police = nl_data_alloc_attr(tb[TCA_FW_POLICE]);
67 f->cf_mask |= FW_ATTR_POLICE;
70 if (tb[TCA_FW_INDEV]) {
71 nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
72 f->cf_mask |= FW_ATTR_INDEV;
78 static void fw_free_data(struct rtnl_cls *cls)
80 struct rtnl_fw *f = rtnl_cls_data(cls);
82 nl_data_free(f->cf_act);
83 nl_data_free(f->cf_police);
86 static int fw_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src)
88 struct rtnl_fw *dst = rtnl_cls_data(_dst);
89 struct rtnl_fw *src = rtnl_cls_data(_src);
91 if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act)))
94 if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police)))
100 static void fw_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p)
102 struct rtnl_fw *f = rtnl_cls_data(cls);
105 if (f->cf_mask & FW_ATTR_CLASSID)
106 nl_dump(p, " target %s",
107 rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
110 static void fw_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p)
112 struct rtnl_fw *f = rtnl_cls_data(cls);
114 if (f->cf_mask & FW_ATTR_INDEV)
115 nl_dump(p, "indev %s ", f->cf_indev);
118 static int fw_get_opts(struct rtnl_cls *cls, struct nl_msg *msg)
120 struct rtnl_fw *f = rtnl_cls_data(cls);
122 if (f->cf_mask & FW_ATTR_CLASSID)
123 NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid);
125 if (f->cf_mask & FW_ATTR_ACTION)
126 NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act);
128 if (f->cf_mask & FW_ATTR_POLICE)
129 NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police);
131 if (f->cf_mask & FW_ATTR_INDEV)
132 NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev);
141 * @name Attribute Modifications
145 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
147 struct rtnl_fw *f = rtnl_cls_data(cls);
149 f->cf_classid = classid;
150 f->cf_mask |= FW_ATTR_CLASSID;
157 static struct rtnl_cls_ops fw_ops = {
159 .co_size = sizeof(struct rtnl_fw),
160 .co_msg_parser = fw_msg_parser,
161 .co_free_data = fw_free_data,
162 .co_clone = fw_clone,
163 .co_get_opts = fw_get_opts,
165 [NL_DUMP_LINE] = fw_dump_line,
166 [NL_DUMP_DETAILS] = fw_dump_details,
170 static void __init fw_init(void)
172 rtnl_cls_register(&fw_ops);
175 static void __exit fw_exit(void)
177 rtnl_cls_unregister(&fw_ops);