diff options
author | Thomas Graf <tgraf@suug.ch> | 2010-10-28 22:20:42 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2010-10-28 22:20:42 (GMT) |
commit | d7a561a1372f819efc8cede30dc550d8e3afcc28 (patch) | |
tree | da9fefa62f5ffdca82fa374ebe0b207202719410 /lib/route/cls/ematch/nbyte.c | |
parent | e1eacd6b16b014eb42bcf6683ebe2334c3a35c68 (diff) | |
download | libnl-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.c | 139 |
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); +} + +/** @} */ |