From 0fe5b29423c1ad97012a865f1cd8b4f7ff37f143 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 29 Oct 2010 00:14:34 +0200 Subject: Extended pktloc to support nbyte locations for ipv6, etc. The alignment column/field now also takes a number, specifying the length in bytes of the field described by the location --- etc/pktloc | 12 ++++++++++++ include/netlink/route/pktloc.h | 3 ++- lib/route/pktloc.c | 18 ++++++++++++++++-- lib/route/pktloc_syntax.y | 13 ++++++++++--- src/nl-pktloc-lookup.c | 24 +++++++++++++++++++----- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/etc/pktloc b/etc/pktloc index db36d401..96f5a412 100644 --- a/etc/pktloc +++ b/etc/pktloc @@ -17,6 +17,18 @@ ip.chksum u16 net+10 ip.src u32 net+12 ip.dst u32 net+16 +# +# IP version 6 +# +# name alignment offset mask +ip6.version u8 net+0 0xF0 +ip6.tc u16 net+0 0xFF0 +ip6.flowlabel u32 net+0 0xFFFFF +ip6.length u16 net+4 +ip6.nexthdr u8 net+6 +ip6.hoplimit u8 net+7 +ip6.src 16 net+8 +ip6.dst 16 net+24 # # Transmission Control Protocol (TCP) diff --git a/include/netlink/route/pktloc.h b/include/netlink/route/pktloc.h index dbca8dc3..ad8c66c7 100644 --- a/include/netlink/route/pktloc.h +++ b/include/netlink/route/pktloc.h @@ -25,9 +25,9 @@ extern "C" { struct rtnl_pktloc { char * name; - uint8_t align; uint8_t layer; uint16_t offset; + uint16_t align; uint32_t mask; uint32_t refcnt; @@ -35,6 +35,7 @@ struct rtnl_pktloc }; extern int rtnl_pktloc_lookup(const char *, struct rtnl_pktloc **); +extern struct rtnl_pktloc *rtnl_pktloc_alloc(void); extern void rtnl_pktloc_put(struct rtnl_pktloc *); extern int rtnl_pktloc_add(struct rtnl_pktloc *); extern void rtnl_pktloc_foreach(void (*cb)(struct rtnl_pktloc *, void *), diff --git a/lib/route/pktloc.c b/lib/route/pktloc.c index faf4bf5b..b5e5b771 100644 --- a/lib/route/pktloc.c +++ b/lib/route/pktloc.c @@ -176,6 +176,22 @@ int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result) return __pktloc_lookup(name, result); } +/** + * Allocate packet location object + */ +struct rtnl_pktloc *rtnl_pktloc_alloc(void) +{ + struct rtnl_pktloc *loc; + + if (!(loc = calloc(1, sizeof(*loc)))) + return NULL; + + loc->refcnt = 1; + nl_init_list_head(&loc->list); + + return loc; +} + /** * Return reference of a packet location * @arg loc packet location object. @@ -205,8 +221,6 @@ int rtnl_pktloc_add(struct rtnl_pktloc *loc) return -NLE_EXIST; } - loc->refcnt++; - NL_DBG(2, "New packet location entry \"%s\" align=%u layer=%u " "offset=%u mask=%#x refnt=%u\n", loc->name, loc->align, loc->layer, loc->offset, loc->mask, loc->refcnt); diff --git a/lib/route/pktloc_syntax.y b/lib/route/pktloc_syntax.y index bf00549e..95cd6f43 100644 --- a/lib/route/pktloc_syntax.y +++ b/lib/route/pktloc_syntax.y @@ -32,7 +32,7 @@ static void yyerror(YYLTYPE *locp, void *scanner, const char *msg) %token ERROR NUMBER LAYER ALIGN %token NAME -%type mask layer +%type mask layer align %type location %destructor { free($$); } NAME @@ -47,11 +47,11 @@ input: ; location: - NAME ALIGN layer NUMBER mask + NAME align layer NUMBER mask { struct rtnl_pktloc *loc; - if (!(loc = calloc(1, sizeof(*loc)))) { + if (!(loc = rtnl_pktloc_alloc())) { NL_DBG(1, "Allocating a packet location " "object failed.\n"); YYABORT; @@ -72,6 +72,13 @@ location: } ; +align: + ALIGN + { $$ = $1; } + | NUMBER + { $$ = $1; } + ; + layer: /* empty */ { $$ = TCF_LAYER_NETWORK; } diff --git a/src/nl-pktloc-lookup.c b/src/nl-pktloc-lookup.c index dc6154fc..0f9831ad 100644 --- a/src/nl-pktloc-lookup.c +++ b/src/nl-pktloc-lookup.c @@ -52,6 +52,9 @@ static const char *layer_txt[] = { static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value) { + if (loc->align > 4) + nl_cli_fatal(EINVAL, "u32 only supports alignments u8|u16|u32."); + if (loc->layer == TCF_LAYER_LINK) nl_cli_fatal(EINVAL, "u32 does not support link " "layer locations."); @@ -63,19 +66,30 @@ static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value) loc->offset); } +static char *get_align_txt(struct rtnl_pktloc *loc) +{ + static char buf[16]; + + if (loc->align <= 4) + strcpy(buf, align_txt[loc->align]); + else + snprintf(buf, sizeof(buf), "%u", loc->align); + + return buf; +} + static void dump_loc(struct rtnl_pktloc *loc) { printf("%s = %s at %s+%u %#x\n", - loc->name, align_txt[loc->align], - layer_txt[loc->layer], loc->offset, loc->mask); + loc->name, get_align_txt(loc), layer_txt[loc->layer], + loc->offset, loc->mask); } static void list_cb(struct rtnl_pktloc *loc, void *arg) { printf("%-26s %-5s %3s+%-4u %#-10x %u\n", - loc->name, align_txt[loc->align], - layer_txt[loc->layer], loc->offset, - loc->mask, loc->refcnt); + loc->name, get_align_txt(loc), layer_txt[loc->layer], + loc->offset, loc->mask, loc->refcnt); } static void do_list(void) -- cgit v1.2.3