Commit b1d95ae5 authored by Ray Bellis's avatar Ray Bellis Committed by David S. Miller
Browse files

tools, bpf_asm: simplify parser rule for BPF extensions



We can already use yylval in the lexer for encoding the BPF extension
number, so that the parser rules can be further reduced to a single one
for each B/H/W case.

Signed-off-by: default avatarRay Bellis <ray@isc.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0c71de66
Loading
Loading
Loading
Loading
+68 −16
Original line number Original line Diff line number Diff line
@@ -23,6 +23,9 @@
#include <stdio.h>
#include <stdio.h>
#include <stdint.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>

#include <linux/filter.h>


#include "bpf_exp.yacc.h"
#include "bpf_exp.yacc.h"


@@ -79,22 +82,71 @@ extern void yyerror(const char *str);
"txa"		{ return OP_TXA; }
"txa"		{ return OP_TXA; }


"#"?("len")	{ return K_PKT_LEN; }
"#"?("len")	{ return K_PKT_LEN; }
"#"?("proto")	{ return K_PROTO; }

"#"?("type")	{ return K_TYPE; }
"#"?("proto")	{
"#"?("poff")	{ return K_POFF; }
		yylval.number = SKF_AD_PROTOCOL;
"#"?("ifidx")	{ return K_IFIDX; }
		return extension;
"#"?("nla")	{ return K_NLATTR; }
	}
"#"?("nlan")	{ return K_NLATTR_NEST; }
"#"?("type")	{
"#"?("mark")	{ return K_MARK; }
		yylval.number = SKF_AD_PKTTYPE;
"#"?("queue")	{ return K_QUEUE; }
		return extension;
"#"?("hatype")	{ return K_HATYPE; }
	}
"#"?("rxhash")	{ return K_RXHASH; }
"#"?("poff")	{
"#"?("cpu")	{ return K_CPU; }
		yylval.number = SKF_AD_PAY_OFFSET;
"#"?("vlan_tci")	{ return K_VLAN_TCI; }
		return extension;
"#"?("vlan_pr")		{ return K_VLAN_AVAIL; }
	}
"#"?("vlan_avail")	{ return K_VLAN_AVAIL; }
"#"?("ifidx")	{
"#"?("vlan_tpid")	{ return K_VLAN_TPID; }
		yylval.number = SKF_AD_IFINDEX;
"#"?("rand")	{ return K_RAND; }
		return extension;
	}
"#"?("nla")	{
		yylval.number = SKF_AD_NLATTR;
		return extension;
	}
"#"?("nlan")	{
		yylval.number = SKF_AD_NLATTR_NEST;
		return extension;
	}
"#"?("mark")	{
		yylval.number = SKF_AD_MARK;
		return extension;
	}
"#"?("queue")	{
		yylval.number = SKF_AD_QUEUE;
		return extension;
	}
"#"?("hatype")	{
		yylval.number = SKF_AD_HATYPE;
		return extension;
	}
"#"?("rxhash")	{
		yylval.number = SKF_AD_RXHASH;
		return extension;
	}
"#"?("cpu")	{
		yylval.number = SKF_AD_CPU;
		return extension;
	}
"#"?("vlan_tci") {
		yylval.number = SKF_AD_VLAN_TAG;
		return extension;
	}
"#"?("vlan_pr")	{
		yylval.number = SKF_AD_VLAN_TAG_PRESENT;
		return extension;
	}
"#"?("vlan_avail") {
		yylval.number = SKF_AD_VLAN_TAG_PRESENT;
		return extension;
	}
"#"?("vlan_tpid") {
		yylval.number = SKF_AD_VLAN_TPID;
		return extension;
	}
"#"?("rand")	{
		yylval.number = SKF_AD_RANDOM;
		return extension;
	}


":"		{ return ':'; }
":"		{ return ':'; }
","		{ return ','; }
","		{ return ','; }
+11 −135
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
enum jmp_type { JTL, JFL, JKL };
enum jmp_type { JTL, JFL, JKL };


extern FILE *yyin;
extern FILE *yyin;
extern int yylineno;
extern int yylex(void);
extern int yylex(void);
extern void yyerror(const char *str);
extern void yyerror(const char *str);


@@ -55,14 +56,14 @@ static void bpf_set_jmp_label(char *label, enum jmp_type type);
%token OP_RET OP_TAX OP_TXA OP_LDXB OP_MOD OP_NEG OP_JNEQ OP_JLT OP_JLE OP_LDI
%token OP_RET OP_TAX OP_TXA OP_LDXB OP_MOD OP_NEG OP_JNEQ OP_JLT OP_JLE OP_LDI
%token OP_LDXI
%token OP_LDXI


%token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE
%token K_PKT_LEN
%token K_RXHASH K_CPU K_IFIDX K_VLAN_TCI K_VLAN_AVAIL K_VLAN_TPID K_POFF K_RAND


%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%'
%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%'


%token number label
%token extension number label


%type <label> label
%type <label> label
%type <number> extension
%type <number> number
%type <number> number


%%
%%
@@ -125,51 +126,9 @@ ldb
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_IND, 0, 0, $6); }
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_IND, 0, 0, $6); }
	| OP_LDB '[' number ']' {
	| OP_LDB '[' number ']' {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0, $3); }
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0, $3); }
	| OP_LDB K_PROTO {
	| OP_LDB extension {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PROTOCOL); }
				   SKF_AD_OFF + $2); }
	| OP_LDB K_TYPE {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PKTTYPE); }
	| OP_LDB K_IFIDX {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_IFINDEX); }
	| OP_LDB K_NLATTR {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR); }
	| OP_LDB K_NLATTR_NEST {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
	| OP_LDB K_MARK {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_MARK); }
	| OP_LDB K_QUEUE {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_QUEUE); }
	| OP_LDB K_HATYPE {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_HATYPE); }
	| OP_LDB K_RXHASH {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RXHASH); }
	| OP_LDB K_CPU {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_CPU); }
	| OP_LDB K_VLAN_TCI {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG); }
	| OP_LDB K_VLAN_AVAIL {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
	| OP_LDB K_POFF {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
	| OP_LDB K_RAND {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RANDOM); }
	| OP_LDB K_VLAN_TPID {
		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TPID); }
	;
	;


ldh
ldh
@@ -179,51 +138,9 @@ ldh
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_IND, 0, 0, $6); }
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_IND, 0, 0, $6); }
	| OP_LDH '[' number ']' {
	| OP_LDH '[' number ']' {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0, $3); }
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0, $3); }
	| OP_LDH K_PROTO {
	| OP_LDH extension {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PROTOCOL); }
	| OP_LDH K_TYPE {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PKTTYPE); }
	| OP_LDH K_IFIDX {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_IFINDEX); }
	| OP_LDH K_NLATTR {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR); }
	| OP_LDH K_NLATTR_NEST {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
	| OP_LDH K_MARK {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_MARK); }
	| OP_LDH K_QUEUE {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_QUEUE); }
	| OP_LDH K_HATYPE {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_HATYPE); }
				   SKF_AD_OFF + $2); }
	| OP_LDH K_RXHASH {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RXHASH); }
	| OP_LDH K_CPU {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_CPU); }
	| OP_LDH K_VLAN_TCI {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG); }
	| OP_LDH K_VLAN_AVAIL {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
	| OP_LDH K_POFF {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
	| OP_LDH K_RAND {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RANDOM); }
	| OP_LDH K_VLAN_TPID {
		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TPID); }
	;
	;


ldi
ldi
@@ -238,51 +155,9 @@ ld
		bpf_set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $3); }
		bpf_set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $3); }
	| OP_LD K_PKT_LEN {
	| OP_LD K_PKT_LEN {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_LEN, 0, 0, 0); }
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_LEN, 0, 0, 0); }
	| OP_LD K_PROTO {
	| OP_LD extension {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PROTOCOL); }
	| OP_LD K_TYPE {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PKTTYPE); }
	| OP_LD K_IFIDX {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_IFINDEX); }
	| OP_LD K_NLATTR {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR); }
	| OP_LD K_NLATTR_NEST {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_NLATTR_NEST); }
	| OP_LD K_MARK {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_MARK); }
	| OP_LD K_QUEUE {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_QUEUE); }
	| OP_LD K_HATYPE {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_HATYPE); }
	| OP_LD K_RXHASH {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RXHASH); }
	| OP_LD K_CPU {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_CPU); }
	| OP_LD K_VLAN_TCI {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG); }
	| OP_LD K_VLAN_AVAIL {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT); }
	| OP_LD K_POFF {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
	| OP_LD K_RAND {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_RANDOM); }
	| OP_LD K_VLAN_TPID {
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
				   SKF_AD_OFF + SKF_AD_VLAN_TPID); }
				   SKF_AD_OFF + $2); }
	| OP_LD 'M' '[' number ']' {
	| OP_LD 'M' '[' number ']' {
		bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
		bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
	| OP_LD '[' 'x' '+' number ']' {
	| OP_LD '[' 'x' '+' number ']' {
@@ -776,5 +651,6 @@ void bpf_asm_compile(FILE *fp, bool cstyle)


void yyerror(const char *str)
void yyerror(const char *str)
{
{
	fprintf(stderr, "error: %s at line %d\n", str, yylineno);
	exit(1);
	exit(1);
}
}