libnl 2.0
|
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 /** @} */