Skip to content

Commit

Permalink
Don't use global state for the BPF compiler.
Browse files Browse the repository at this point in the history
This allows multiple pcap_compile() calls to be in progress on different
pcap_t's in different threads.

(No, you can't count on that behavior in older versions of libpcap, so
only do that if you know you're using a newer version of libpcap.)
  • Loading branch information
guyharris committed Feb 11, 2016
1 parent 36146a8 commit fb20696
Show file tree
Hide file tree
Showing 9 changed files with 2,633 additions and 2,690 deletions.
4,179 changes: 2,045 additions & 2,134 deletions gencode.c

Large diffs are not rendered by default.

151 changes: 89 additions & 62 deletions gencode.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,88 +281,115 @@ struct qual {
unsigned char pad;
};

struct arth *gen_loadi(int);
struct arth *gen_load(int, struct arth *, int);
struct arth *gen_loadlen(void);
struct arth *gen_neg(struct arth *);
struct arth *gen_arth(int, struct arth *, struct arth *);
struct _compiler_state;

typedef struct _compiler_state compiler_state_t;

struct arth *gen_loadi(compiler_state_t *, int);
struct arth *gen_load(compiler_state_t *, int, struct arth *, int);
struct arth *gen_loadlen(compiler_state_t *);
struct arth *gen_neg(compiler_state_t *, struct arth *);
struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *);

void gen_and(struct block *, struct block *);
void gen_or(struct block *, struct block *);
void gen_not(struct block *);

struct block *gen_scode(const char *, struct qual);
struct block *gen_ecode(const u_char *, struct qual);
struct block *gen_acode(const u_char *, struct qual);
struct block *gen_mcode(const char *, const char *, unsigned int, struct qual);
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
unsigned int, struct qual);
#ifdef INET6
struct block *gen_mcode6(const char *, const char *, unsigned int, struct qual);
struct block *gen_mcode6(compiler_state_t *, const char *, const char *,
unsigned int, struct qual);
#endif
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
struct block *gen_proto_abbrev(int);
struct block *gen_relation(int, struct arth *, struct arth *, int);
struct block *gen_less(int);
struct block *gen_greater(int);
struct block *gen_byteop(int, int, int);
struct block *gen_broadcast(int);
struct block *gen_multicast(int);
struct block *gen_inbound(int);

struct block *gen_llc(void);
struct block *gen_llc_i(void);
struct block *gen_llc_s(void);
struct block *gen_llc_u(void);
struct block *gen_llc_s_subtype(bpf_u_int32);
struct block *gen_llc_u_subtype(bpf_u_int32);

struct block *gen_vlan(int);
struct block *gen_mpls(int);

struct block *gen_pppoed(void);
struct block *gen_pppoes(int);

struct block *gen_geneve(int);

struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmtype_abbrev(int type);
struct block *gen_atmmulti_abbrev(int type);

struct block *gen_mtp2type_abbrev(int type);
struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);

struct block *gen_pf_ifname(const char *);
struct block *gen_pf_rnr(int);
struct block *gen_pf_srnr(int);
struct block *gen_pf_ruleset(char *);
struct block *gen_pf_reason(int);
struct block *gen_pf_action(int);
struct block *gen_pf_dir(int);

struct block *gen_p80211_type(int, int);
struct block *gen_p80211_fcdir(int);

void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32,
struct qual);
struct block *gen_proto_abbrev(compiler_state_t *, int);
struct block *gen_relation(compiler_state_t *, int, struct arth *,
struct arth *, int);
struct block *gen_less(compiler_state_t *, int);
struct block *gen_greater(compiler_state_t *, int);
struct block *gen_byteop(compiler_state_t *, int, int, int);
struct block *gen_broadcast(compiler_state_t *, int);
struct block *gen_multicast(compiler_state_t *, int);
struct block *gen_inbound(compiler_state_t *, int);

struct block *gen_llc(compiler_state_t *);
struct block *gen_llc_i(compiler_state_t *);
struct block *gen_llc_s(compiler_state_t *);
struct block *gen_llc_u(compiler_state_t *);
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);

struct block *gen_vlan(compiler_state_t *, int);
struct block *gen_mpls(compiler_state_t *, int);

struct block *gen_pppoed(compiler_state_t *);
struct block *gen_pppoes(compiler_state_t *, int);

struct block *gen_geneve(compiler_state_t *, int);

struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
bpf_u_int32, int);
struct block *gen_atmtype_abbrev(compiler_state_t *, int type);
struct block *gen_atmmulti_abbrev(compiler_state_t *, int type);

struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int);

struct block *gen_pf_ifname(compiler_state_t *, const char *);
struct block *gen_pf_rnr(compiler_state_t *, int);
struct block *gen_pf_srnr(compiler_state_t *, int);
struct block *gen_pf_ruleset(compiler_state_t *, char *);
struct block *gen_pf_reason(compiler_state_t *, int);
struct block *gen_pf_action(compiler_state_t *, int);

struct block *gen_p80211_type(compiler_state_t *, int, int);
struct block *gen_p80211_fcdir(compiler_state_t *, int);

/*
* 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.
* Rather than traverse the code array, marking each item, 'cur_mark'
* is incremented. This automatically makes each element unmarked.
*/
#define isMarked(icp, p) ((p)->mark == (icp)->cur_mark)
#define unMarkAll(icp) (icp)->cur_mark += 1
#define Mark(icp, p) ((p)->mark = (icp)->cur_mark)

struct icode {
struct block *root;
int cur_mark;
};

void bpf_optimize(compiler_state_t *, struct icode *ic);
void bpf_syntax_error(compiler_state_t *, const char *);
void bpf_error(compiler_state_t *, const char *, ...)
__attribute__((noreturn))
#ifdef __ATTRIBUTE___FORMAT_OK
__attribute__((format (printf, 1, 2)))
__attribute__((format (printf, 2, 3)))
#endif /* __ATTRIBUTE___FORMAT_OK */
;

void finish_parse(struct block *);
char *sdup(const char *);
void finish_parse(compiler_state_t *, struct block *);
char *sdup(compiler_state_t *, const char *);

struct bpf_insn *icode_to_fcode(struct block *, u_int *);
struct _opt_state;
typedef struct _opt_state opt_state_t;

struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
struct block *, u_int *);
void sappend(struct slist *, struct slist *);

/*
* Older versions of Bison don't put this declaration in
* grammar.h.
*/
int pcap_parse(void *);
int pcap_parse(void *, compiler_state_t *);

/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)

extern int no_optimize;
Loading

2 comments on commit fb20696

@fxlb
Copy link
Member

@fxlb fxlb commented on fb20696 Feb 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When SKF_AD_VLAN_TAG and SKF_AD_VLAN_TAG_PRESENT are defined in /usr/include/linux/filter.h (f.e. Debian Jessie, Linux 3.16.0), the build is broken:

/usr/include/linux/filter.h:#define SKF_AD_VLAN_TAG     44
/usr/include/linux/filter.h:#define SKF_AD_VLAN_TAG_PRESENT 48

Errors:

./gencode.c: In function 'gen_vlan_bpf_extensions':
./gencode.c:7902:22: error: 'cstate' undeclared (first use in this function)
         s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
                      ^
./gencode.c:7902:22: note: each undeclared identifier is reported only once for each function it appears in
./gencode.c: In function 'gen_vlan':
./gencode.c:8015:7: error: 'off_outermostlinkhdr' undeclared (first use in this function)
       off_outermostlinkhdr.constant_part) {
       ^
Makefile:460: recipe for target 'gencode.o' failed

@guyharris
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by Denis in 3f0a659. Thanks.

Please sign in to comment.