/build/buildd/libnl-1.0~pre6/lib/route/cls/fw.c

00001 /*
00002  * lib/route/cls/fw.c           fw classifier
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
00010  * Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com>
00011  * Copyright (c) 2006 Siemens AG Oesterreich
00012  */
00013 
00014 /**
00015  * @ingroup cls
00016  * @defgroup fw Firewall Classifier
00017  *
00018  * @{
00019  */
00020 
00021 #include <netlink-local.h>
00022 #include <netlink-tc.h>
00023 #include <netlink/netlink.h>
00024 #include <netlink/route/classifier.h>
00025 #include <netlink/route/classifier-modules.h>
00026 #include <netlink/route/cls/fw.h>
00027 
00028 /** @cond SKIP */
00029 #define FW_ATTR_CLASSID      0x001
00030 #define FW_ATTR_ACTION       0x002
00031 #define FW_ATTR_POLICE       0x004
00032 #define FW_ATTR_INDEV        0x008
00033 /** @endcond */
00034 
00035 static inline struct rtnl_fw *fw_cls(struct rtnl_cls *cls)
00036 {
00037         return (struct rtnl_fw *) cls->c_subdata;
00038 }
00039 
00040 static inline struct rtnl_fw *fw_alloc(struct rtnl_cls *cls)
00041 {
00042         if (!cls->c_subdata)
00043                 cls->c_subdata = calloc(1, sizeof(struct rtnl_fw));
00044 
00045         return fw_cls(cls);
00046 }
00047 
00048 static struct nla_policy fw_policy[TCA_FW_MAX+1] = {
00049         [TCA_FW_CLASSID]        = { .type = NLA_U32 },
00050         [TCA_FW_INDEV]          = { .type = NLA_STRING,
00051                                     .maxlen = IFNAMSIZ },
00052 };
00053 
00054 static int fw_msg_parser(struct rtnl_cls *cls)
00055 {
00056         int err;
00057         struct nlattr *tb[TCA_FW_MAX + 1];
00058         struct rtnl_fw *f;
00059 
00060         err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy);
00061         if (err < 0)
00062                 return err;
00063 
00064         f = fw_alloc(cls);
00065         if (!f)
00066                 goto errout_nomem;
00067 
00068         if (tb[TCA_FW_CLASSID]) {
00069                 f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
00070                 f->cf_mask |= FW_ATTR_CLASSID;
00071         }
00072 
00073         if (tb[TCA_FW_ACT]) {
00074                 f->cf_act = nla_get_data(tb[TCA_FW_ACT]);
00075                 if (!f->cf_act)
00076                         goto errout_nomem;
00077                 f->cf_mask |= FW_ATTR_ACTION;
00078         }
00079 
00080         if (tb[TCA_FW_POLICE]) {
00081                 f->cf_police = nla_get_data(tb[TCA_FW_POLICE]);
00082                 if (!f->cf_police)
00083                         goto errout_nomem;
00084                 f->cf_mask |= FW_ATTR_POLICE;
00085         }
00086 
00087         if (tb[TCA_FW_INDEV]) {
00088                 nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
00089                 f->cf_mask |= FW_ATTR_INDEV;
00090         }
00091 
00092         return 0;
00093 
00094 errout_nomem:
00095         err = nl_errno(ENOMEM);
00096 
00097         return err;
00098 }
00099 
00100 static void fw_free_data(struct rtnl_cls *cls)
00101 {
00102         struct rtnl_fw *f = fw_cls(cls);
00103 
00104         if (!f)
00105                 return;
00106 
00107         nl_data_free(f->cf_act);
00108         nl_data_free(f->cf_police);
00109 
00110         free(cls->c_subdata);
00111 }
00112 
00113 static int fw_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p,
00114                           int line)
00115 {
00116         struct rtnl_fw *f = fw_cls(cls);
00117         char buf[32];
00118 
00119         if (!f)
00120                 goto ignore;
00121 
00122         if (f->cf_mask & FW_ATTR_CLASSID)
00123                 dp_dump(p, " target %s",
00124                         rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
00125 
00126 ignore:
00127         return line;
00128 }
00129 
00130 static int fw_dump_full(struct rtnl_cls *cls, struct nl_dump_params *p,
00131                          int line)
00132 {
00133         struct rtnl_fw *f = fw_cls(cls);
00134 
00135         if (!f)
00136                 goto ignore;
00137 
00138         if (f->cf_mask & FW_ATTR_INDEV)
00139                 dp_dump(p, "indev %s ", f->cf_indev);
00140 
00141 ignore:
00142         return line;
00143 }
00144 
00145 static int fw_dump_stats(struct rtnl_cls *cls, struct nl_dump_params *p,
00146                           int line)
00147 {
00148         struct rtnl_fw *f = fw_cls(cls);
00149 
00150         if (!f)
00151                 goto ignore;
00152 
00153 ignore:
00154         return line;
00155 }
00156 
00157 static struct nl_msg *fw_get_opts(struct rtnl_cls *cls)
00158 {
00159         struct rtnl_fw *f;
00160         struct nl_msg *msg;
00161         
00162         f = fw_cls(cls);
00163         if (!f)
00164                 return NULL;
00165 
00166         msg = nlmsg_build_no_hdr();
00167         if (!msg)
00168                 return NULL;
00169 
00170         if (f->cf_mask & FW_ATTR_CLASSID)
00171                 nla_put_u32(msg, TCA_FW_CLASSID, f->cf_classid);
00172 
00173         if (f->cf_mask & FW_ATTR_ACTION)
00174                 nla_put_data(msg, TCA_FW_ACT, f->cf_act);
00175 
00176         if (f->cf_mask & FW_ATTR_POLICE)
00177                 nla_put_data(msg, TCA_FW_POLICE, f->cf_police);
00178 
00179         if (f->cf_mask & FW_ATTR_INDEV)
00180                 nla_put_string(msg, TCA_FW_INDEV, f->cf_indev);
00181 
00182         return msg;
00183 }
00184 
00185 /**
00186  * @name Attribute Modifications
00187  * @{
00188  */
00189 
00190 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
00191 {
00192         struct rtnl_fw *f;
00193         
00194         f = fw_alloc(cls);
00195         if (!f)
00196                 return nl_errno(ENOMEM);
00197 
00198         f->cf_classid = classid;
00199         f->cf_mask |= FW_ATTR_CLASSID;
00200 
00201         return 0;
00202 }
00203 
00204 /** @} */
00205 
00206 static struct rtnl_cls_ops fw_ops = {
00207         .co_kind                = "fw",
00208         .co_msg_parser          = fw_msg_parser,
00209         .co_free_data           = fw_free_data,
00210         .co_get_opts            = fw_get_opts,
00211         .co_dump[NL_DUMP_BRIEF] = fw_dump_brief,
00212         .co_dump[NL_DUMP_FULL]  = fw_dump_full,
00213         .co_dump[NL_DUMP_STATS] = fw_dump_stats,
00214 };
00215 
00216 static void __init fw_init(void)
00217 {
00218         rtnl_cls_register(&fw_ops);
00219 }
00220 
00221 static void __exit fw_exit(void)
00222 {
00223         rtnl_cls_unregister(&fw_ops);
00224 }
00225 
00226 /** @} */

Generated on Fri Apr 27 14:14:07 2007 for libnl by  doxygen 1.5.1