Annotation of embedaddon/bird2/conf/flowspec.Y, revision 1.1
1.1 ! misho 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>