summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2010-10-28 22:14:34 (GMT)
committerThomas Graf <tgraf@suug.ch>2010-10-28 22:14:34 (GMT)
commit0fe5b29423c1ad97012a865f1cd8b4f7ff37f143 (patch)
tree2776ab0e83cea83f4582b0f2313901a7c4c918be
parent65e386c8ba490d405f539322a12e1f1c7ea2eb5c (diff)
downloadlibnl-0fe5b29423c1ad97012a865f1cd8b4f7ff37f143.zip
libnl-0fe5b29423c1ad97012a865f1cd8b4f7ff37f143.tar.gz
libnl-0fe5b29423c1ad97012a865f1cd8b4f7ff37f143.tar.bz2
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
-rw-r--r--etc/pktloc12
-rw-r--r--include/netlink/route/pktloc.h3
-rw-r--r--lib/route/pktloc.c18
-rw-r--r--lib/route/pktloc_syntax.y13
-rw-r--r--src/nl-pktloc-lookup.c24
5 files changed, 59 insertions, 11 deletions
diff --git a/etc/pktloc b/etc/pktloc
index db36d40..96f5a41 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 dbca8dc..ad8c66c 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 faf4bf5..b5e5b77 100644
--- a/lib/route/pktloc.c
+++ b/lib/route/pktloc.c
@@ -177,6 +177,22 @@ int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **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 bf00549..95cd6f4 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 <i> ERROR NUMBER LAYER ALIGN
%token <s> NAME
-%type <i> mask layer
+%type <i> mask layer align
%type <l> 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 dc6154f..0f9831a 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)