## iof-bird / bird-2.0.1 / conf / flowspec.Y @ 6b3f1a54

History | View | Annotate | Download (5.22 KB)

1 |
/* |
---|---|

2 |
* BIRD -- Flow specification (RFC 5575) grammar |

3 |
* |

4 |
* (c) 2016 CZ.NIC z.s.p.o. |

5 |
* |

6 |
* Can be freely distributed and used under the terms of the GNU GPL. |

7 |
*/ |

8 | |

9 |
CF_HDR |

10 | |

11 |
#define PARSER 1 |

12 | |

13 |
#include "nest/bird.h" |

14 |
#include "lib/flowspec.h" |

15 | |

16 | |

17 |
CF_DEFINES |

18 | |

19 |
struct flow_builder *this_flow; |

20 | |

21 | |

22 |
CF_DECLS |

23 | |

24 |
%type <i32> flow_num_op flow_srcdst flow_logic_op flow_num_type_ flow_frag_val flow_neg |

25 |
%type <net_ptr> net_flow4_ net_flow6_ net_flow_ |

26 | |

27 |
CF_KEYWORDS(FLOW4, FLOW6, DST, SRC, PROTO, NEXT, HEADER, DPORT, SPORT, ICMP, |

28 |
TYPE, CODE, TCP, FLAGS, LENGTH, DSCP, DONT_FRAGMENT, IS_FRAGMENT, |

29 |
FIRST_FRAGMENT, LAST_FRAGMENT, FRAGMENT, LABEL, OFFSET) |

30 | |

31 | |

32 |
CF_GRAMMAR |

33 | |

34 |
/* Network Flow Specification */ |

35 | |

36 |
flow_num_op: |

37 |
TRUE { $$ = FLOW_OP_TRUE; } |

38 |
| '=' { $$ = FLOW_OP_EQ; } |

39 |
| NEQ { $$ = FLOW_OP_NEQ; } |

40 |
| '<' { $$ = FLOW_OP_LT; } |

41 |
| LEQ { $$ = FLOW_OP_LEQ; } |

42 |
| '>' { $$ = FLOW_OP_GT; } |

43 |
| GEQ { $$ = FLOW_OP_GEQ; } |

44 |
| FALSE { $$ = FLOW_OP_FALSE; } |

45 |
; |

46 | |

47 |
flow_logic_op: |

48 |
OR { $$ = FLOW_OP_OR; } |

49 |
| AND { $$ = FLOW_OP_AND; } |

50 |
; |

51 | |

52 |
flow_num_type_: |

53 |
PROTO { $$ = FLOW_TYPE_IP_PROTOCOL; } |

54 |
| NEXT HEADER { $$ = FLOW_TYPE_NEXT_HEADER; } |

55 |
| PORT { $$ = FLOW_TYPE_PORT; } |

56 |
| DPORT { $$ = FLOW_TYPE_DST_PORT; } |

57 |
| SPORT { $$ = FLOW_TYPE_SRC_PORT; } |

58 |
| ICMP TYPE { $$ = FLOW_TYPE_ICMP_TYPE; } |

59 |
| ICMP CODE { $$ = FLOW_TYPE_ICMP_CODE; } |

60 |
| LENGTH { $$ = FLOW_TYPE_PACKET_LENGTH; } |

61 |
| DSCP { $$ = FLOW_TYPE_DSCP; } |

62 |
; |

63 | |

64 |
flow_num_type: flow_num_type_{ flow_builder_set_type(this_flow, $1); }; |

65 |
flow_flag_type: TCP FLAGS { flow_builder_set_type(this_flow, FLOW_TYPE_TCP_FLAGS); }; |

66 |
flow_frag_type: FRAGMENT { flow_builder_set_type(this_flow, FLOW_TYPE_FRAGMENT); }; |

67 |
flow_label_type: LABEL { flow_builder_set_type(this_flow, FLOW_TYPE_LABEL); }; |

68 | |

69 |
flow_srcdst: |

70 |
DST { $$ = FLOW_TYPE_DST_PREFIX; } |

71 |
| SRC { $$ = FLOW_TYPE_SRC_PREFIX; } |

72 |
; |

73 | |

74 |
flow_num_opts: |

75 |
flow_num_op expr { |

76 |
flow_check_cf_value_length(this_flow, $2); |

77 |
flow_builder_add_op_val(this_flow, $1, $2); |

78 |
} |

79 |
| flow_num_opts flow_logic_op flow_num_op expr { |

80 |
flow_check_cf_value_length(this_flow, $4); |

81 |
flow_builder_add_op_val(this_flow, $2 | $3, $4); |

82 |
} |

83 |
| flow_num_opt_ext |

84 |
| flow_num_opts OR flow_num_opt_ext |

85 |
; |

86 | |

87 |
flow_num_opt_ext_expr: |

88 |
expr { |

89 |
flow_check_cf_value_length(this_flow, $1); |

90 |
flow_builder_add_op_val(this_flow, FLOW_OP_EQ, $1); |

91 |
} |

92 |
| expr DDOT expr { |

93 |
flow_check_cf_value_length(this_flow, $1); |

94 |
flow_check_cf_value_length(this_flow, $3); |

95 |
flow_builder_add_op_val(this_flow, FLOW_OP_GEQ, $1); |

96 |
flow_builder_add_op_val(this_flow, FLOW_OP_AND | FLOW_OP_LEQ, $3); |

97 |
} |

98 |
; |

99 | |

100 |
flow_num_opt_ext: |

101 |
flow_num_opt_ext_expr |

102 |
| flow_num_opt_ext ',' flow_num_opt_ext_expr |

103 |
; |

104 | |

105 |
flow_bmk_opts: |

106 |
flow_neg expr '/' expr { |

107 |
flow_check_cf_bmk_values(this_flow, $1, $2, $4); |

108 |
flow_builder_add_val_mask(this_flow, $1, $2, $4); |

109 |
} |

110 |
| flow_bmk_opts flow_logic_op flow_neg expr '/' expr { |

111 |
flow_check_cf_bmk_values(this_flow, $3, $4, $6); |

112 |
flow_builder_add_val_mask(this_flow, $2 | $3, $4, $6); |

113 |
} |

114 |
| flow_bmk_opts ',' flow_neg expr '/' expr { |

115 |
flow_check_cf_bmk_values(this_flow, $3, $4, $6); |

116 |
flow_builder_add_val_mask(this_flow, 0x40 | $3, $4, $6); /* AND */ |

117 |
} |

118 |
; |

119 | |

120 |
flow_neg: |

121 |
/* empty */ { $$ = 0x00; } |

122 |
| '!' { $$ = 0x02; } |

123 |
; |

124 | |

125 |
flow_frag_val: |

126 |
DONT_FRAGMENT { $$ = 1; } |

127 |
| IS_FRAGMENT { $$ = 2; } |

128 |
| FIRST_FRAGMENT { $$ = 4; } |

129 |
| LAST_FRAGMENT { $$ = 8; } |

130 |
; |

131 | |

132 |
flow_frag_opts: |

133 |
flow_neg flow_frag_val { |

134 |
flow_builder_add_val_mask(this_flow, 0, ($1 ? 0 : $2), $2); |

135 |
} |

136 |
| flow_frag_opts flow_logic_op flow_neg flow_frag_val { |

137 |
flow_builder_add_val_mask(this_flow, $2, ($3 ? 0 : $4), $4); |

138 |
} |

139 |
| flow_frag_opts ',' flow_neg flow_frag_val { |

140 |
flow_builder_add_val_mask(this_flow, 0x40, ($3 ? 0 : $4), $4); /* AND */ |

141 |
} |

142 |
; |

143 | |

144 |
flow4_item: |

145 |
flow_srcdst net_ip { |

146 |
flow_builder_set_type(this_flow, $1); |

147 |
flow_builder4_add_pfx(this_flow, (net_addr_ip4 *) &($2)); |

148 |
} |

149 |
| flow_num_type flow_num_opts |

150 |
| flow_flag_type flow_bmk_opts |

151 |
| flow_frag_type flow_frag_opts |

152 |
; |

153 | |

154 |
flow6_item: |

155 |
flow_srcdst net_ip6 { |

156 |
flow_builder_set_type(this_flow, $1); |

157 |
flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), 0); |

158 |
} |

159 |
| flow_srcdst net_ip6 OFFSET NUM { |

160 |
if ($4 > $2.pxlen) |

161 |
cf_error("Prefix offset is higher than prefix length"); |

162 |
flow_builder_set_type(this_flow, $1); |

163 |
flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), $4); |

164 |
} |

165 |
| flow_num_type flow_num_opts |

166 |
| flow_flag_type flow_bmk_opts |

167 |
| flow_frag_type flow_frag_opts |

168 |
| flow_label_type flow_bmk_opts |

169 |
; |

170 | |

171 |
flow4_opts: |

172 |
/* empty */ |

173 |
| flow4_opts flow4_item ';' |

174 |
; |

175 | |

176 |
flow6_opts: |

177 |
/* empty */ |

178 |
| flow6_opts flow6_item ';' |

179 |
; |

180 | |

181 |
flow_builder_init: |

182 |
{ |

183 |
if (this_flow == NULL) |

184 |
this_flow = flow_builder_init(&root_pool); |

185 |
else |

186 |
flow_builder_clear(this_flow); |

187 |
}; |

188 | |

189 |
flow_builder_set_ipv4: { this_flow->ipv6 = 0; }; |

190 |
flow_builder_set_ipv6: { this_flow->ipv6 = 1; }; |

191 | |

192 |
net_flow4_: FLOW4 '{' flow_builder_init flow_builder_set_ipv4 flow4_opts '}' |

193 |
{ |

194 |
$$ = (net_addr *) flow_builder4_finalize(this_flow, cfg_mem); |

195 |
flow4_validate_cf((net_addr_flow4 *) $$); |

196 |
}; |

197 | |

198 |
net_flow6_: FLOW6 '{' flow_builder_init flow_builder_set_ipv6 flow6_opts '}' |

199 |
{ |

200 |
$$ = (net_addr *) flow_builder6_finalize(this_flow, cfg_mem); |

201 |
flow6_validate_cf((net_addr_flow6 *) $$); |

202 |
}; |

203 | |

204 |
net_flow_: net_flow4_ | net_flow6_ ; |

205 | |

206 | |

207 |
CF_CODE |

208 | |

209 |
CF_END |