00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <netlink-local.h>
00019 #include <netlink-tc.h>
00020 #include <netlink/netlink.h>
00021 #include <netlink/utils.h>
00022 #include <netlink/route/tc.h>
00023 #include <netlink/route/classifier.h>
00024 #include <netlink/route/classifier-modules.h>
00025 #include <netlink/route/link.h>
00026
00027
00028 #define CLS_ATTR_PRIO (TCA_ATTR_MAX << 1)
00029 #define CLS_ATTR_PROTOCOL (TCA_ATTR_MAX << 2)
00030
00031
00032 static void cls_free_data(struct nl_object *obj)
00033 {
00034 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00035 struct rtnl_cls_ops *cops;
00036
00037 tca_free_data((struct rtnl_tca *) cls);
00038
00039 cops = rtnl_cls_lookup_ops(cls);
00040 if (cops && cops->co_free_data)
00041 cops->co_free_data(cls);
00042 }
00043
00044 static int cls_clone(struct nl_object *_dst, struct nl_object *_src)
00045 {
00046 struct rtnl_cls *dst = nl_object_priv(_dst);
00047 struct rtnl_cls *src = nl_object_priv(_src);
00048 struct rtnl_cls_ops *cops;
00049 int err;
00050
00051 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
00052 if (err < 0)
00053 goto errout;
00054
00055 cops = rtnl_cls_lookup_ops(src);
00056 if (cops && cops->co_clone)
00057 err = cops->co_clone(dst, src);
00058 errout:
00059 return err;
00060 }
00061
00062 static int cls_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
00063 {
00064 char buf[32];
00065 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00066 struct rtnl_cls_ops *cops;
00067 int line;
00068
00069 line = tca_dump_brief((struct rtnl_tca *) cls, "cls", p, 0);
00070
00071 dp_dump(p, " prio %u protocol %s", cls->c_prio,
00072 nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf)));
00073
00074 cops = rtnl_cls_lookup_ops(cls);
00075 if (cops && cops->co_dump[NL_DUMP_BRIEF])
00076 line = cops->co_dump[NL_DUMP_BRIEF](cls, p, line);
00077 dp_dump(p, "\n");
00078
00079 return line;
00080 }
00081
00082 static int cls_dump_full(struct nl_object *obj, struct nl_dump_params *p)
00083 {
00084 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00085 struct rtnl_cls_ops *cops;
00086 int line;
00087
00088 line = cls_dump_brief(obj, p);
00089 line = tca_dump_full((struct rtnl_tca *) cls, p, line);
00090
00091 cops = rtnl_cls_lookup_ops(cls);
00092 if (cops && cops->co_dump[NL_DUMP_FULL])
00093 line = cops->co_dump[NL_DUMP_FULL](cls, p, line);
00094 else
00095 dp_dump(p, "no options\n");
00096
00097 return line;
00098 }
00099
00100 static int cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
00101 {
00102 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00103 struct rtnl_cls_ops *cops;
00104 int line;
00105
00106 line = cls_dump_full(obj, p);
00107 line = tca_dump_stats((struct rtnl_tca *) cls, p, line);
00108 dp_dump(p, "\n");
00109
00110 cops = rtnl_cls_lookup_ops(cls);
00111 if (cops && cops->co_dump[NL_DUMP_STATS])
00112 line = cops->co_dump[NL_DUMP_STATS](cls, p, line);
00113
00114 return line;
00115 }
00116
00117
00118
00119
00120
00121
00122 struct rtnl_cls *rtnl_cls_alloc(void)
00123 {
00124 return (struct rtnl_cls *) co_clone)
00057 err = cops->co_clone(dst, src);
00058 errout:
00059 return err;
00060 }
00061
00062 static int cls_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
00063 {
00064 char buf[32];
00065 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00066 struct rtnl_cls_ops *cops;
00067 int line;
00068
00069 line = tca_dump_brief((struct rtnl_tca *) cls, "cls", p, 0);
00070
00071 dp_dump(p, " prio %u protocol %s", cls->c_prio,
00072 nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf)));
00073
00074 cops = rtnl_cls_lookup_ops(cls);
00075 if (cops && cops->co_dump[NL_DUMP_BRIEF])
00076 line = cops->co_dump[NL_DUMP_BRIEF](cls, p, line);
00077 dp_dump(p, "\n");
00078
00079 return line;
00080 }
00081
00082 static int cls_dump_full(struct nl_object *obj, struct nl_dump_params *p)
00083 {
00084 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00085 struct rtnl_cls_ops *cops;
00086 int line;
00087
00088 line = cls_dump_brief(obj, p);
00089 line = tca_dump_full((struct rtnl_tca *) cls, p, line);
00090
00091 cops = rtnl_cls_lookup_ops(cls);
00092 if (cops && cops->co_dump[NL_DUMP_FULL])
00093 line = cops->co_dump[NL_DUMP_FULL](cls, p, line);
00094 else
00095 dp_dump(p, "no options\n");
00096
00097 return line;
00098 }
00099
00100 static int cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
00101 {
00102 struct rtnl_cls *cls = (struct rtnl_cls *) obj;
00103 struct rtnl_cls_ops *cops;
00104 int line;
00105
00106 line = cls_dump_full(obj, p);
00107 line = tca_dump_stats((struct rtnl_tca *) cls, p, line);
00108 dp_dump(p, "\n");
00109
00110 cops = rtnl_cls_lookup_ops(cls);
00111 if (cops && cops->