%type <expr> expr initializer_expr
%destructor { expr_free($$); } expr initializer_expr
+%type <expr> rhs_expr concat_rhs_expr basic_rhs_expr
+%destructor { expr_free($$); } rhs_expr concat_rhs_expr basic_rhs_expr
+%type <expr> primary_rhs_expr list_rhs_expr
+%destructor { expr_free($$); } primary_rhs_expr list_rhs_expr
+
%type <expr> relational_expr
%destructor { expr_free($$); } relational_expr
%type <val> relational_op
}
;
-prefix_expr : basic_expr SLASH NUM
+prefix_expr : basic_rhs_expr SLASH NUM
{
$$ = prefix_expr_alloc(&@$, $1, $3);
}
;
-range_expr : basic_expr DASH basic_expr
+range_expr : basic_rhs_expr DASH basic_rhs_expr
{
$$ = range_expr_alloc(&@$, $1, $3);
}
| wildcard_expr
;
-map_expr : concat_expr MAP expr
+map_expr : concat_expr MAP rhs_expr
{
$$ = map_expr_alloc(&@$, $1, $3);
}
}
;
-set_lhs_expr : concat_expr
+set_lhs_expr : concat_rhs_expr
| multiton_expr
;
-set_rhs_expr : concat_expr
+set_rhs_expr : concat_rhs_expr
| verdict_expr
;
| list_expr
;
-relational_expr : expr /* implicit */ expr
+relational_expr : expr /* implicit */ rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
}
- | expr /* implicit */ list_expr
+ | expr /* implicit */ list_rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_FLAGCMP, $1, $2);
}
- | expr relational_op expr
+ | expr relational_op rhs_expr
{
$$ = relational_expr_alloc(&@2, $2, $1, $3);
}
;
+list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr
+ {
+ $$ = list_expr_alloc(&@$);
+ compound_expr_add($$, $1);
+ compound_expr_add($$, $3);
+ }
+ | list_rhs_expr COMMA basic_rhs_expr
+ {
+ $1->location = @$;
+ compound_expr_add($1, $3);
+ $$ = $1;
+ }
+ ;
+
+rhs_expr : concat_rhs_expr { $$ = $1; }
+ | multiton_expr { $$ = $1; }
+ | set_expr { $$ = $1; }
+ ;
+
+concat_rhs_expr : basic_rhs_expr { $$ = $1; }
+ | concat_rhs_expr DOT basic_rhs_expr
+ {
+ if ($$->ops->type != EXPR_CONCAT) {
+ $$ = concat_expr_alloc(&@$);
+ compound_expr_add($$, $1);
+ } else {
+ struct location rhs[] = {
+ [1] = @2,
+ [2] = @3,
+ };
+ location_update(&$3->location, rhs, 2);
+
+ $$ = $1;
+ $$->location = @$;
+ }
+ compound_expr_add($$, $3);
+ }
+ ;
+
+basic_rhs_expr : primary_rhs_expr { $$ = $1; }
+ ;
+
+primary_rhs_expr : symbol_expr { $$ = $1; }
+ | integer_expr { $$ = $1; }
+ | ETHER
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ether");
+ }
+ | IP
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ip");
+ }
+ | IP6
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ip6");
+ }
+ | VLAN
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "vlan");
+ }
+ | ARP
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "arp");
+ }
+ | TCP
+ {
+ uint8_t data = IPPROTO_TCP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | UDP
+ {
+ uint8_t data = IPPROTO_UDP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | UDPLITE
+ {
+ uint8_t data = IPPROTO_UDPLITE;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ESP
+ {
+ uint8_t data = IPPROTO_ESP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | AH
+ {
+ uint8_t data = IPPROTO_AH;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ICMP
+ {
+ uint8_t data = IPPROTO_ICMP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ICMP6
+ {
+ uint8_t data = IPPROTO_ICMPV6;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | COMP
+ {
+ uint8_t data = IPPROTO_COMP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | DCCP
+ {
+ uint8_t data = IPPROTO_DCCP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | SCTP
+ {
+ uint8_t data = IPPROTO_SCTP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ ;
+
relational_op : EQ { $$ = OP_EQ; }
| NEQ { $$ = OP_NEQ; }
| LT { $$ = OP_LT; }
{
$$ = payload_expr_alloc(&@$, &proto_eth, $2);
}
- | ETHER
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ether");
- }
;
eth_hdr_field : SADDR { $$ = ETHHDR_SADDR; }
{
$$ = payload_expr_alloc(&@$, &proto_vlan, $2);
}
- | VLAN
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "vlan");
- }
;
vlan_hdr_field : ID { $$ = VLANHDR_VID; }
{
$$ = payload_expr_alloc(&@$, &proto_arp, $2);
}
- | ARP
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "arp");
- }
;
arp_hdr_field : HTYPE { $$ = ARPHDR_HRD; }
{
$$ = payload_expr_alloc(&@$, &proto_ip, $2);
}
- | IP
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ip");
- }
;
ip_hdr_field : HDRVERSION { $$ = IPHDR_VERSION; }
{
$$ = payload_expr_alloc(&@$, &proto_icmp, $2);
}
- | ICMP
- {
- uint8_t data = IPPROTO_ICMP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
icmp_hdr_field : TYPE { $$ = ICMPHDR_TYPE; }
{
$$ = payload_expr_alloc(&@$, &proto_ip6, $2);
}
- | IP6
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ip6");
- }
;
ip6_hdr_field : HDRVERSION { $$ = IP6HDR_VERSION; }
{
$$ = payload_expr_alloc(&@$, &proto_icmp6, $2);
}
- | ICMP6
- {
- uint8_t data = IPPROTO_ICMPV6;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
icmp6_hdr_field : TYPE { $$ = ICMP6HDR_TYPE; }
{
$$ = payload_expr_alloc(&@$, &proto_ah, $2);
}
- | AH
- {
- uint8_t data = IPPROTO_AH;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
auth_hdr_field : NEXTHDR { $$ = AHHDR_NEXTHDR; }
{
$$ = payload_expr_alloc(&@$, &proto_esp, $2);
}
- | ESP
- {
- uint8_t data = IPPROTO_ESP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
esp_hdr_field : SPI { $$ = ESPHDR_SPI; }
{
$$ = payload_expr_alloc(&@$, &proto_comp, $2);
}
- | COMP
- {
- uint8_t data = IPPROTO_COMP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
comp_hdr_field : NEXTHDR { $$ = COMPHDR_NEXTHDR; }
{
$$ = payload_expr_alloc(&@$, &proto_udp, $2);
}
- | UDP
- {
- uint8_t data = IPPROTO_UDP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
udp_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
{
$$ = payload_expr_alloc(&@$, &proto_udplite, $2);
}
- | UDPLITE
- {
- uint8_t data = IPPROTO_UDPLITE;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
udplite_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
{
$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
}
- | TCP
- {
- uint8_t data = IPPROTO_TCP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
{
$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
}
- | DCCP
- {
- uint8_t data = IPPROTO_DCCP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
dccp_hdr_field : SPORT { $$ = DCCPHDR_SPORT; }
{
$$ = payload_expr_alloc(&@$, &proto_sctp, $2);
}
- | SCTP
- {
- uint8_t data = IPPROTO_SCTP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
sctp_hdr_field : SPORT { $$ = SCTPHDR_SPORT; }