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