libnl 2.0

/tmp/buildd/libnl2-2.0/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-2009 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_api
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 struct nla_policy fw_policy[TCA_FW_MAX+1] = {
00036         [TCA_FW_CLASSID]        = { .type = NLA_U32 },
00037         [TCA_FW_INDEV]          = { .type = NLA_STRING,
00038                                     .maxlen = IFNAMSIZ },
00039 };
00040 
00041 static int fw_msg_parser(struct rtnl_cls *cls)
00042 {
00043         struct rtnl_fw *f = rtnl_cls_data(cls);
00044         struct nlattr *tb[TCA_FW_MAX + 1];
00045         int err;
00046 
00047         err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy);
00048         if (err < 0)
00049                 return err;
00050 
00051         if (tb[TCA_FW_CLASSID]) {
00052                 f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
00053                 f->cf_mask |= FW_ATTR_CLASSID;
00054         }
00055 
00056         if (tb[TCA_FW_ACT]) {
00057                 f->cf_act = nl_data_alloc_attr(tb[TCA_FW_ACT]);
00058                 if (!f->cf_act)
00059                         return -NLE_NOMEM;
00060                 f->cf_mask |= FW_ATTR_ACTION;
00061         }
00062 
00063         if (tb[TCA_FW_POLICE]) {
00064                 f->cf_police = nl_data_alloc_attr(tb[TCA_FW_POLICE]);
00065                 if (!f->cf_police)
00066                         return -NLE_NOMEM;
00067                 f->cf_mask |= FW_ATTR_POLICE;
00068         }
00069 
00070         if (tb[TCA_FW_INDEV]) {
00071                 nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ);
00072                 f->cf_mask |= FW_ATTR_INDEV;
00073         }
00074 
00075         return 0;
00076 }
00077 
00078 static void fw_free_data(struct rtnl_cls *cls)
00079 {
00080         struct rtnl_fw *f = rtnl_cls_data(cls);
00081 
00082         nl_data_free(f->cf_act);
00083         nl_data_free(f->cf_police);
00084 }
00085 
00086 static int fw_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src)
00087 {
00088         struct rtnl_fw *dst = rtnl_cls_data(_dst);
00089         struct rtnl_fw *src = rtnl_cls_data(_src);
00090 
00091         if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act)))
00092                 return -NLE_NOMEM;
00093         
00094         if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police)))
00095                 return -NLE_NOMEM;
00096 
00097         return 0;
00098 }
00099 
00100 static void fw_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p)
00101 {
00102         struct rtnl_fw *f = rtnl_cls_data(cls);
00103         char buf[32];
00104 
00105         if (f->cf_mask & FW_ATTR_CLASSID)
00106                 nl_dump(p, " target %s",
00107                         rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
00108 }
00109 
00110 static void fw_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p)
00111 {
00112         struct rtnl_fw *f = rtnl_cls_data(cls);
00113 
00114         if (f->cf_mask & FW_ATTR_INDEV)
00115                 nl_dump(p, "indev %s ", f->cf_indev);
00116 }
00117 
00118 static int fw_get_opts(struct rtnl_cls *cls, struct nl_msg *msg)
00119 {
00120         struct rtnl_fw *f = rtnl_cls_data(cls);
00121         
00122         if (f->cf_mask & FW_ATTR_CLASSID)
00123                 NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid);
00124 
00125         if (f->cf_mask & FW_ATTR_ACTION)
00126                 NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act);
00127 
00128         if (f->cf_mask & FW_ATTR_POLICE)
00129                 NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police);
00130 
00131         if (f->cf_mask & FW_ATTR_INDEV)
00132                 NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev);
00133 
00134         return 0;
00135 
00136 nla_put_failure:
00137         return -NLE_NOMEM;
00138 }
00139 
00140 /**
00141  * @name Attribute Modifications
00142  * @{
00143  */
00144 
00145 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
00146 {
00147         struct rtnl_fw *f = rtnl_cls_data(cls);
00148         
00149         f->cf_classid = classid;
00150         f->cf_mask |= FW_ATTR_CLASSID;
00151 
00152         return 0;
00153 }
00154 
00155 /** @} */
00156 
00157 static struct rtnl_cls_ops fw_ops = {
00158         .co_kind                = "fw",
00159         .co_size                = sizeof(struct rtnl_fw),
00160         .co_msg_parser          = fw_msg_parser,
00161         .co_free_data           = fw_free_data,
00162         .co_clone               = fw_clone,
00163         .co_get_opts            = fw_get_opts,
00164         .co_dump = {
00165             [NL_DUMP_LINE]      = fw_dump_line,
00166             [NL_DUMP_DETAILS]   = fw_dump_details,
00167         },
00168 };
00169 
00170 static void __init fw_init(void)
00171 {
00172         rtnl_cls_register(&fw_ops);
00173 }
00174 
00175 static void __exit fw_exit(void)
00176 {
00177         rtnl_cls_unregister(&fw_ops);
00178 }
00179 
00180 /** @} */