libnl  3.2.3
/build/buildd/libnl3-3.2.3/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-2011 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 cls_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/tc-api.h>
00025 #include <netlink/route/classifier.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_tc *tc, void *data)
00042 {
00043         struct nlattr *tb[TCA_FW_MAX + 1];
00044         struct rtnl_fw *f = data;
00045         int err;
00046 
00047         err = tca_parse(tb, TCA_FW_MAX, tc, 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_tc *tc, void *data)
00079 {
00080         struct rtnl_fw *f = data;
00081 
00082         nl_data_free(f->cf_act);
00083         nl_data_free(f->cf_police);
00084 }
00085 
00086 static int fw_clone(void *_dst, void *_src)
00087 {
00088         struct rtnl_fw *dst = _dst, *src = _src;
00089 
00090         if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act)))
00091                 return -NLE_NOMEM;
00092         
00093         if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police)))
00094                 return -NLE_NOMEM;
00095 
00096         return 0;
00097 }
00098 
00099 static void fw_dump_line(struct rtnl_tc *tc, void *data,
00100                          struct nl_dump_params *p)
00101 {
00102         struct rtnl_fw *f = data;
00103 
00104         if (f && f->cf_mask & FW_ATTR_CLASSID) {
00105                 char buf[32];
00106 
00107                 nl_dump(p, " target %s",
00108                         rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf)));
00109         }
00110 }
00111 
00112 static void fw_dump_details(struct rtnl_tc *tc, void *data,
00113                             struct nl_dump_params *p)
00114 {
00115         struct rtnl_fw *f = data;
00116 
00117         if (f && f->cf_mask & FW_ATTR_INDEV)
00118                 nl_dump(p, "indev %s ", f->cf_indev);
00119 }
00120 
00121 static int fw_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
00122 {
00123         struct rtnl_fw *f = data;
00124 
00125         if (!f)
00126                 return 0;
00127 
00128         if (f->cf_mask & FW_ATTR_CLASSID)
00129                 NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid);
00130 
00131         if (f->cf_mask & FW_ATTR_ACTION)
00132                 NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act);
00133 
00134         if (f->cf_mask & FW_ATTR_POLICE)
00135                 NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police);
00136 
00137         if (f->cf_mask & FW_ATTR_INDEV)
00138                 NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev);
00139 
00140         return 0;
00141 
00142 nla_put_failure:
00143         return -NLE_MSGSIZE;
00144 }
00145 
00146 /**
00147  * @name Attribute Modifications
00148  * @{
00149  */
00150 
00151 int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid)
00152 {
00153         struct rtnl_fw *f;
00154 
00155         if (!(f = rtnl_tc_data(TC_CAST(cls))))
00156                 return -NLE_NOMEM;
00157         
00158         f->cf_classid = classid;
00159         f->cf_mask |= FW_ATTR_CLASSID;
00160 
00161         return 0;
00162 }
00163 
00164 /** @} */
00165 
00166 static struct rtnl_tc_ops fw_ops = {
00167         .to_kind                = "fw",
00168         .to_type                = RTNL_TC_TYPE_CLS,
00169         .to_size                = sizeof(struct rtnl_fw),
00170         .to_msg_parser          = fw_msg_parser,
00171         .to_msg_fill            = fw_msg_fill,
00172         .to_free_data           = fw_free_data,
00173         .to_clone               = fw_clone,
00174         .to_dump = {
00175             [NL_DUMP_LINE]      = fw_dump_line,
00176             [NL_DUMP_DETAILS]   = fw_dump_details,
00177         },
00178 };
00179 
00180 static void __init fw_init(void)
00181 {
00182         rtnl_tc_register(&fw_ops);
00183 }
00184 
00185 static void __exit fw_exit(void)
00186 {
00187         rtnl_tc_unregister(&fw_ops);
00188 }
00189 
00190 /** @} */