summaryrefslogtreecommitdiffstats
path: root/lib/route/cls/ematch/nbyte.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2010-10-28 22:20:42 (GMT)
committerThomas Graf <tgraf@suug.ch>2010-10-28 22:20:42 (GMT)
commitd7a561a1372f819efc8cede30dc550d8e3afcc28 (patch)
treeda9fefa62f5ffdca82fa374ebe0b207202719410 /lib/route/cls/ematch/nbyte.c
parente1eacd6b16b014eb42bcf6683ebe2334c3a35c68 (diff)
downloadlibnl-d7a561a1372f819efc8cede30dc550d8e3afcc28.zip
libnl-d7a561a1372f819efc8cede30dc550d8e3afcc28.tar.gz
libnl-d7a561a1372f819efc8cede30dc550d8e3afcc28.tar.bz2
Tons of ematch work
- Fixes a bunch of bugs related to ematches - Adds support for the nbyte ematch - Adds a bison/flex parser for ematch expressions, expressions may look like this: ip.length > 256 && pattern(ip6.src = 3ffe::/16) documenation on syntax follows - adds ematch support to the basic classifier (--ematch EXPR)
Diffstat (limited to 'lib/route/cls/ematch/nbyte.c')
-rw-r--r--lib/route/cls/ematch/nbyte.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/route/cls/ematch/nbyte.c b/lib/route/cls/ematch/nbyte.c
new file mode 100644
index 0000000..25a9866
--- /dev/null
+++ b/lib/route/cls/ematch/nbyte.c
@@ -0,0 +1,139 @@
+/*
+ * lib/route/cls/ematch/nbyte.c Nbyte comparison
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
+ */
+
+/**
+ * @ingroup ematch
+ * @defgroup em_nbyte N-Byte Comparison
+ *
+ * @{
+ */
+
+#include <netlink-local.h>
+#include <netlink-tc.h>
+#include <netlink/netlink.h>
+#include <netlink/route/cls/ematch.h>
+#include <netlink/route/cls/ematch/nbyte.h>
+
+struct nbyte_data
+{
+ struct tcf_em_nbyte cfg;
+ uint8_t * pattern;
+};
+
+void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *e, uint8_t layer,
+ uint16_t offset)
+{
+ struct nbyte_data *n = rtnl_ematch_data(e);
+ n->cfg.off = offset;
+ n->cfg.layer = layer;
+}
+
+uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *e)
+{
+ return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.off;
+}
+
+uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *e)
+{
+ return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.layer;
+}
+
+void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *e,
+ uint8_t *pattern, size_t len)
+{
+ struct nbyte_data *n = rtnl_ematch_data(e);
+
+ if (n->pattern)
+ free(n->pattern);
+
+ n->pattern = pattern;
+ n->cfg.len = len;
+}
+
+uint8_t *rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *e)
+{
+ return ((struct nbyte_data *) rtnl_ematch_data(e))->pattern;
+}
+
+size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *e)
+{
+ return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.len;
+}
+
+static const char *layer_txt(struct tcf_em_nbyte *nbyte)
+{
+ switch (nbyte->layer) {
+ case TCF_LAYER_LINK:
+ return "link";
+ case TCF_LAYER_NETWORK:
+ return "net";
+ case TCF_LAYER_TRANSPORT:
+ return "trans";
+ default:
+ return "?";
+ }
+}
+
+static int nbyte_parse(struct rtnl_ematch *e, void *data, size_t len)
+{
+ struct nbyte_data *n = rtnl_ematch_data(e);
+ size_t hdrlen = sizeof(struct tcf_em_nbyte);
+ size_t plen = len - hdrlen;
+
+ memcpy(&n->cfg, data, hdrlen);
+ if (plen > 0) {
+ if (!(n->pattern = calloc(1, plen)))
+ return -NLE_NOMEM;
+
+ memcpy(n->pattern, data + hdrlen, plen);
+ }
+
+ return 0;
+}
+
+static void nbyte_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
+{
+ struct nbyte_data *n = rtnl_ematch_data(e);
+ int i;
+
+ nl_dump(p, "pattern(%u:[", n->cfg.len);
+
+ for (i = 0; i < n->cfg.len; i++) {
+ nl_dump(p, "%02x", n->pattern[i]);
+ if (i+1 < n->cfg.len)
+ nl_dump(p, " ");
+ }
+
+ nl_dump(p, "] at %s+%u)", layer_txt(&n->cfg), n->cfg.off);
+}
+
+static void nbyte_free(struct rtnl_ematch *e)
+{
+ struct nbyte_data *n = rtnl_ematch_data(e);
+ free(n->pattern);
+}
+
+static struct rtnl_ematch_ops nbyte_ops = {
+ .eo_kind = TCF_EM_NBYTE,
+ .eo_name = "nbyte",
+ .eo_minlen = sizeof(struct tcf_em_nbyte),
+ .eo_datalen = sizeof(struct nbyte_data),
+ .eo_parse = nbyte_parse,
+ .eo_dump = nbyte_dump,
+ .eo_free = nbyte_free,
+};
+
+static void __init nbyte_init(void)
+{
+ rtnl_ematch_register(&nbyte_ops);
+}
+
+/** @} */