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
This commit is contained in:
Thomas Graf 2010-10-29 00:14:34 +02:00
parent 65e386c8ba
commit 0fe5b29423
5 changed files with 59 additions and 11 deletions

View file

@ -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)

View file

@ -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 *),

View file

@ -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);

View file

@ -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; }

View file

@ -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)