libnl 2.0
|
00001 /* 00002 * lib/route/cls/basic.c Basic 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) 2008-2009 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup cls 00014 * @defgroup basic Basic Classifier 00015 * 00016 * @par Introduction 00017 * The basic classifier is the simplest form of a classifier. It does 00018 * not have any special classification capabilities, instead it can be 00019 * used to classify exclusively based on extended matches or to 00020 * create a "catch-all" filter. 00021 * 00022 * @{ 00023 */ 00024 00025 #include <netlink-local.h> 00026 #include <netlink-tc.h> 00027 #include <netlink/netlink.h> 00028 #include <netlink/route/classifier.h> 00029 #include <netlink/route/classifier-modules.h> 00030 #include <netlink/route/cls/basic.h> 00031 #include <netlink/route/cls/ematch.h> 00032 00033 struct rtnl_basic 00034 { 00035 uint32_t b_classid; 00036 struct rtnl_ematch_tree * b_ematch; 00037 int b_mask; 00038 }; 00039 00040 /** @cond SKIP */ 00041 #define BASIC_ATTR_CLASSID 0x001 00042 #define BASIC_ATTR_EMATCH 0x002 00043 /** @endcond */ 00044 00045 static struct nla_policy basic_policy[TCA_FW_MAX+1] = { 00046 [TCA_BASIC_CLASSID] = { .type = NLA_U32 }, 00047 [TCA_BASIC_EMATCHES] = { .type = NLA_NESTED }, 00048 [TCA_BASIC_ACT] = { .type = NLA_NESTED }, 00049 [TCA_BASIC_POLICE] = { .type = NLA_NESTED }, 00050 }; 00051 00052 static int basic_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src) 00053 { 00054 return -NLE_OPNOTSUPP; 00055 } 00056 00057 static void basic_free_data(struct rtnl_cls *cls) 00058 { 00059 struct rtnl_basic *basic = rtnl_cls_data(cls); 00060 00061 rtnl_ematch_tree_free(basic->b_ematch); 00062 } 00063 00064 static int basic_msg_parser(struct rtnl_cls *cls) 00065 { 00066 struct nlattr *tb[TCA_BASIC_MAX + 1]; 00067 struct rtnl_basic *basic = rtnl_cls_data(cls); 00068 int err; 00069 00070 err = tca_parse(tb, TCA_BASIC_MAX, (struct rtnl_tca *) cls, basic_policy); 00071 if (err < 0) 00072 return err; 00073 00074 if (tb[TCA_BASIC_CLASSID]) { 00075 basic->b_classid = nla_get_u32(tb[TCA_BASIC_CLASSID]); 00076 basic->b_mask |= BASIC_ATTR_CLASSID; 00077 } 00078 00079 if (tb[TCA_BASIC_EMATCHES]) { 00080 if ((err = rtnl_ematch_parse(tb[TCA_BASIC_EMATCHES], 00081 &basic->b_ematch)) < 0) 00082 return err; 00083 00084 if (basic->b_ematch) 00085 basic->b_mask |= BASIC_ATTR_EMATCH; 00086 } 00087 00088 if (tb[TCA_BASIC_ACT]) { 00089 /* XXX */ 00090 } 00091 00092 if (tb[TCA_BASIC_POLICE]) { 00093 /* XXX */ 00094 } 00095 00096 return 0; 00097 } 00098 00099 static void basic_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p) 00100 { 00101 struct rtnl_basic *b = rtnl_cls_data(cls); 00102 char buf[32]; 00103 00104 if (b->b_mask & BASIC_ATTR_EMATCH) 00105 nl_dump(p, " ematch"); 00106 else 00107 nl_dump(p, " match-all"); 00108 00109 if (b->b_mask & BASIC_ATTR_CLASSID) 00110 nl_dump(p, " classify-to %s", 00111 rtnl_tc_handle2str(b->b_classid, buf, sizeof(buf))); 00112 } 00113 00114 static void basic_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p) 00115 { 00116 struct rtnl_basic *b = rtnl_cls_data(cls); 00117 00118 if (b->b_mask & BASIC_ATTR_EMATCH) { 00119 nl_dump(p, "\n"); 00120 nl_dump_line(p, " ematch "); 00121 rtnl_ematch_tree_dump(b->b_ematch, p); 00122 } else 00123 nl_dump(p, "no options.\n"); 00124 } 00125 00126 static int basic_get_opts(struct rtnl_cls *cls, struct nl_msg *msg) 00127 { 00128 struct rtnl_basic *b = rtnl_cls_data(cls); 00129 00130 if (!(b->b_mask & BASIC_ATTR_CLASSID)) 00131 return -NLE_MISSING_ATTR; 00132 00133 NLA_PUT_U32(msg, TCA_BASIC_CLASSID, b->b_classid); 00134 00135 return 0; 00136 00137 nla_put_failure: 00138 return -NLE_NOMEM; 00139 } 00140 00141 /** 00142 * @name Attribute Modifications 00143 * @{ 00144 */ 00145 00146 int rtnl_basic_set_classid(struct rtnl_cls *cls, uint32_t classid) 00147 { 00148 struct rtnl_basic *b = rtnl_cls_data(cls); 00149 00150 b->b_classid = classid; 00151 b->b_mask |= BASIC_ATTR_CLASSID; 00152 00153 return 0; 00154 } 00155 00156 uint32_t rtnl_basic_get_classid(struct rtnl_cls *cls) 00157 { 00158 struct rtnl_basic *b = rtnl_cls_data(cls); 00159 00160 return b->b_classid; 00161 } 00162 00163 int rtnl_basic_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) 00164 { 00165 struct rtnl_basic *b = rtnl_cls_data(cls); 00166 00167 if (b->b_ematch) { 00168 rtnl_ematch_tree_free(b->b_ematch); 00169 b->b_mask &= ~BASIC_ATTR_EMATCH; 00170 } 00171 00172 b->b_ematch = tree; 00173 00174 if (tree) 00175 b->b_mask |= BASIC_ATTR_EMATCH; 00176 00177 return 0; 00178 } 00179 00180 struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls) 00181 { 00182 struct rtnl_basic *b = rtnl_cls_data(cls); 00183 return b->b_ematch; 00184 } 00185 00186 /** @} */ 00187 00188 static struct rtnl_cls_ops basic_ops = { 00189 .co_kind = "basic", 00190 .co_size = sizeof(struct rtnl_basic), 00191 .co_msg_parser = basic_msg_parser, 00192 .co_clone = basic_clone, 00193 .co_free_data = basic_free_data, 00194 .co_get_opts = basic_get_opts, 00195 .co_dump = { 00196 [NL_DUMP_LINE] = basic_dump_line, 00197 [NL_DUMP_DETAILS] = basic_dump_details, 00198 }, 00199 }; 00200 00201 static void __init basic_init(void) 00202 { 00203 rtnl_cls_register(&basic_ops); 00204 } 00205 00206 static void __exit basic_exit(void) 00207 { 00208 rtnl_cls_unregister(&basic_ops); 00209 } 00210 00211 /** @} */