* support for MPLS
*/
struct block *
-gen_mpls(compiler_state_t *cstate, int label_num)
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
{
struct block *b0, *b1;
}
/* If a specific MPLS label is requested, check it */
- if (label_num >= 0) {
+ if (has_label_num) {
+ if (label_num > 0xFFFFF) {
+ bpf_error(cstate, "MPLS label %u greater than maximum %u",
+ label_num, 0xFFFFF);
+ }
label_num = label_num << 12; /* label is shifted 12 bits on the wire */
b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, (bpf_int32)label_num,
0xfffff000); /* only compare the first 20 bits */
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_mpls(compiler_state_t *, bpf_u_int32, int);
struct block *gen_pppoed(compiler_state_t *);
struct block *gen_pppoes(compiler_state_t *, int);
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
| VLAN { $$ = gen_vlan(cstate, -1); }
- | MPLS pnum { $$ = gen_mpls(cstate, $2); }
- | MPLS { $$ = gen_mpls(cstate, -1); }
+ | MPLS pnum { $$ = gen_mpls(cstate, (bpf_u_int32)$2, 1); }
+ | MPLS { $$ = gen_mpls(cstate, 0, 0); }
| PPPOED { $$ = gen_pppoed(cstate); }
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
| PPPOES { $$ = gen_pppoes(cstate, -1); }