From 958149795f680f77f73ca44f78279f55265728c0 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Sat, 13 Aug 2016 02:11:21 +0300 Subject: trafgen: parser: Add support of 'dinc' function for proto fields Add 'dinc()' function in 'field_expr' rules to be used for dynamically incrementing of any specified field: SYNTAX := dinc() | dinc(step) | dinc(min, max) | dinc(min, max, step) EXAMPLES: { udp(sport=dinc() } { udp(sport=dinc(1) } { udp(sport=dinc(100, 125, 5) } Signed-off-by: Vadim Kochan Signed-off-by: Tobias Klauser --- trafgen_parser.y | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/trafgen_parser.y b/trafgen_parser.y index 1e7bd5c..9b313d1 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -75,6 +75,7 @@ enum field_expr_type_t { FIELD_EXPR_MAC, FIELD_EXPR_IP4_ADDR, FIELD_EXPR_IP6_ADDR, + FIELD_EXPR_INC, }; struct proto_field_expr { @@ -86,6 +87,7 @@ struct proto_field_expr { struct in6_addr ip6_addr; long long int number; uint8_t bytes[256]; + struct proto_field_func func; } val; }; @@ -126,6 +128,12 @@ static inline void __init_new_csum_slot(struct packet_dyn *slot) slot->slen = 0; } +static inline void __init_new_fields_slot(struct packet_dyn *slot) +{ + slot->fields = NULL; + slot->flen = 0; +} + static inline void __setup_new_counter(struct counter *c, uint8_t start, uint8_t stop, uint8_t stepping, int type) @@ -168,6 +176,7 @@ static void realloc_packet(void) __init_new_counter_slot(&packet_dyn[packetd_last]); __init_new_randomizer_slot(&packet_dyn[packetd_last]); __init_new_csum_slot(&packet_dyn[packetd_last]); + __init_new_fields_slot(&packet_dyn[packetd_last]); } struct packet *current_packet(void) @@ -377,6 +386,19 @@ static void proto_field_set(uint32_t fid) field_expr.field = proto_field_by_id(hdr, fid); } +static void proto_field_func_setup(struct proto_field *field, struct proto_field_func *func) +{ + struct packet_dyn *pkt_dyn; + + proto_field_func_add(field->hdr, field->id, func); + + pkt_dyn = &packet_dyn[packetd_last]; + pkt_dyn->flen++; + pkt_dyn->fields = xrealloc(pkt_dyn->fields, pkt_dyn->flen * + sizeof(struct proto_field *)); + pkt_dyn->fields[pkt_dyn->flen - 1] = field; +} + static void proto_field_expr_eval(void) { struct proto_field *field = field_expr.field; @@ -406,6 +428,15 @@ static void proto_field_expr_eval(void) (uint8_t *)&field_expr.val.ip6_addr.s6_addr); break; + case FIELD_EXPR_INC: + if (field_expr.val.func.min + && field_expr.val.func.min >= field_expr.val.func.max) + panic("dinc(): min(%u) can't be >= max(%u)\n", + field_expr.val.func.min, field_expr.val.func.max); + + proto_field_func_setup(field, &field_expr.val.func); + break; + case FIELD_EXPR_UNKNOWN: default: bug(); @@ -686,6 +717,27 @@ field_expr field_expr.val.ip4_addr = $1; } | ip6_addr { field_expr.type = FIELD_EXPR_IP6_ADDR; field_expr.val.ip6_addr = $1; } + | K_DINC '(' ')' { field_expr.type = FIELD_EXPR_INC; + field_expr.val.func.type = PROTO_FIELD_FUNC_INC; + field_expr.val.func.inc = 1; } + | K_DINC '(' number ')' + { field_expr.type = FIELD_EXPR_INC; + field_expr.val.func.type = PROTO_FIELD_FUNC_INC; + field_expr.val.func.inc = $3; } + | K_DINC '(' number delimiter number ')' + { field_expr.type = FIELD_EXPR_INC; + field_expr.val.func.type = PROTO_FIELD_FUNC_INC; + field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN; + field_expr.val.func.min = $3; + field_expr.val.func.max = $5; + field_expr.val.func.inc = 1; } + | K_DINC '(' number delimiter number delimiter number ')' + { field_expr.type = FIELD_EXPR_INC; + field_expr.val.func.type = PROTO_FIELD_FUNC_INC; + field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN; + field_expr.val.func.min = $3; + field_expr.val.func.max = $5; + field_expr.val.func.inc = $7; } ; eth_proto @@ -1096,6 +1148,7 @@ void cleanup_packets(void) for (i = 0; i < dlen; ++i) { free(packet_dyn[i].cnt); free(packet_dyn[i].rnd); + free(packet_dyn[i].fields); } free(packet_dyn); -- cgit v1.2.3-54-g00ecf