Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions gencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10712,3 +10712,52 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
}
return b1;
}

struct block*
gen_offset(compiler_state_t *cstate, struct arth *a_arg)
{
struct arth *a = a_arg;
struct block *b;
struct slist *s, *s1;
bpf_abs_offset *offsets[2];
int i;
offsets[0] = &(cstate->off_linkpl);
offsets[1] = &(cstate->off_linktype)};

/*
* Catch errors reported by us and routines below us, and return NULL
* on an error.
*/
if (setjmp(cstate->top_ctx))
return (NULL);

s = NULL;
b = gen_true(cstate);
for (i = 0; i < 2; ++i) {
bpf_abs_offset *off = offsets[i];
// Make sure the offset being adjusted is variable
if (!off->is_variable)
off->is_variable = 1;
if (off->reg == -1)
off->reg = alloc_reg(cstate);

// Put the current offset into the accumulator
s = new_stmt(cstate, BPF_LD|BPF_MEM);
s->s.k = off->reg;

// Put the computed offset into the extra register
s1 = xfer_to_x(cstate, a);
sappend(s, s1);

// Add to the accumulator from the computed offset in the extra register
s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X);
sappend(s, s1);

s1 = new_stmt(cstate, BPF_ST);
s1->s.k = off->reg;
sappend(s, s1);
}
sappend(a->s, s);
b->stmts = a->s;
return b;
}
2 changes: 2 additions & 0 deletions gencode.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ struct block *gen_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, bpf_u_int32, bpf_u_int32);
struct block *gen_p80211_fcdir(compiler_state_t *, bpf_u_int32);

struct block *gen_offset(compiler_state_t *, struct arth *);

/*
* Representation of a program as a tree of blocks, plus current mark.
* A block is marked if only if its mark equals the current mark.
Expand Down
2 changes: 2 additions & 0 deletions grammar.y.in
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ DIAG_OFF_BISON_BYACC
%token RADIO
%token FISU LSSU MSU HFISU HLSSU HMSU
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
%token OFFSET
%token LEX_ERROR

%type <s> ID EID AID
Expand Down Expand Up @@ -689,6 +690,7 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| VXLAN pnum { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, $2, 1))); }
| VXLAN { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, 0, 0))); }
| OFFSET arth { CHECK_PTR_VAL(($$ = gen_offset(cstate, $2))); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
| pllc { $$ = $1; }
Expand Down
2 changes: 2 additions & 0 deletions scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ tcp-ack { yylval->h = 0x10; return NUM; }
tcp-urg { yylval->h = 0x20; return NUM; }
tcp-ece { yylval->h = 0x40; return NUM; }
tcp-cwr { yylval->h = 0x80; return NUM; }

offset return OFFSET;
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
Expand Down