| %{ |
| #include <netlink-local.h> |
| #include <netlink-tc.h> |
| #include <netlink/netlink.h> |
| #include <netlink/utils.h> |
| #include <netlink/route/pktloc.h> |
| %} |
| |
| %locations |
| %error-verbose |
| %define api.pure |
| %name-prefix "pktloc_" |
| |
| %parse-param {void *scanner} |
| %lex-param {void *scanner} |
| |
| %union { |
| struct rtnl_pktloc *l; |
| uint32_t i; |
| char *s; |
| } |
| |
| %{ |
| extern int pktloc_lex(YYSTYPE *, YYLTYPE *, void *); |
| extern void rtnl_pktloc_add(struct rtnl_pktloc *); |
| |
| static void yyerror(YYLTYPE *locp, void *scanner, const char *msg) |
| { |
| /* FIXME */ |
| } |
| %} |
| |
| %token <i> ERROR NUMBER LAYER |
| %token <s> NAME |
| |
| %type <i> mask layer |
| %type <l> location |
| |
| %destructor { free($$); } NAME |
| |
| %start input |
| |
| %% |
| |
| input: |
| def |
| { } |
| ; |
| |
| def: |
| /* empty */ |
| { } |
| | location def |
| { } |
| ; |
| |
| location: |
| NAME NAME layer NUMBER mask |
| { |
| struct rtnl_pktloc *loc; |
| |
| if (!(loc = calloc(1, sizeof(*loc)))) { |
| /* FIXME */ |
| } |
| |
| if (!strcasecmp($2, "u8")) |
| loc->align = TCF_EM_ALIGN_U8; |
| else if (!strcasecmp($2, "h8")) { |
| loc->align = TCF_EM_ALIGN_U8; |
| loc->flags = TCF_EM_CMP_TRANS; |
| } else if (!strcasecmp($2, "u16")) |
| loc->align = TCF_EM_ALIGN_U16; |
| else if (!strcasecmp($2, "h16")) { |
| loc->align = TCF_EM_ALIGN_U16; |
| loc->flags = TCF_EM_CMP_TRANS; |
| } else if (!strcasecmp($2, "u32")) |
| loc->align = TCF_EM_ALIGN_U32; |
| else if (!strcasecmp($2, "h32")) { |
| loc->align = TCF_EM_ALIGN_U32; |
| loc->flags = TCF_EM_CMP_TRANS; |
| } |
| |
| free($2); |
| |
| loc->name = $1; |
| loc->layer = $3; |
| loc->offset = $4; |
| loc->mask = $5; |
| |
| rtnl_pktloc_add(loc); |
| |
| $$ = loc; |
| } |
| ; |
| |
| layer: |
| /* empty */ |
| { $$ = TCF_LAYER_NETWORK; } |
| | LAYER '+' |
| { $$ = $1; } |
| ; |
| |
| mask: |
| /* empty */ |
| { $$ = 0; } |
| | NUMBER |
| { $$ = $1; } |
| ; |