diff options
-rw-r--r-- | trafgen_l2.c | 24 | ||||
-rw-r--r-- | trafgen_l3.c | 8 | ||||
-rw-r--r-- | trafgen_l4.c | 22 | ||||
-rw-r--r-- | trafgen_parser.y | 2 | ||||
-rw-r--r-- | trafgen_proto.c | 65 | ||||
-rw-r--r-- | trafgen_proto.h | 40 |
6 files changed, 83 insertions, 78 deletions
diff --git a/trafgen_l2.c b/trafgen_l2.c index 1863332..f09b2a6 100644 --- a/trafgen_l2.c +++ b/trafgen_l2.c @@ -47,7 +47,7 @@ static void eth_header_init(struct proto_hdr *hdr) proto_field_set_default_dev_mac(hdr, ETH_SRC_ADDR); } -static struct proto_hdr eth_hdr = { +static const struct proto_ops eth_proto_ops = { .id = PROTO_ETH, .layer = PROTO_L2, .header_init = eth_header_init, @@ -74,13 +74,13 @@ static void vlan_header_init(struct proto_hdr *hdr) proto_header_fields_add(hdr, vlan_fields, array_size(vlan_fields)); - if (lower->id == PROTO_ETH) + if (lower->ops->id == PROTO_ETH) lower_etype = proto_field_get_u16(lower, ETH_TYPE); - else if (lower->id == PROTO_VLAN) + else if (lower->ops->id == PROTO_VLAN) lower_etype = proto_field_get_u16(lower, VLAN_ETYPE); proto_field_set_be16(hdr, VLAN_ETYPE, lower_etype); - proto_field_set_default_be16(hdr, VLAN_TPID, pid_to_eth(hdr->id)); + proto_field_set_default_be16(hdr, VLAN_TPID, pid_to_eth(hdr->ops->id)); } static void vlan_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) @@ -89,7 +89,7 @@ static void vlan_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) proto_field_set_be16(hdr, VLAN_ETYPE, pid_to_eth(pid)); } -static struct proto_hdr vlan_hdr = { +static const struct proto_ops vlan_proto_ops = { .id = PROTO_VLAN, .layer = PROTO_L2, .header_init = vlan_header_init, @@ -114,7 +114,7 @@ static void arp_header_init(struct proto_hdr *hdr) lower = proto_lower_default_add(hdr, PROTO_ETH); - if (lower->id == PROTO_ETH) { + if (lower->ops->id == PROTO_ETH) { const uint8_t bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; proto_field_set_default_bytes(lower, ETH_DST_ADDR, bcast); @@ -133,7 +133,7 @@ static void arp_header_init(struct proto_hdr *hdr) proto_field_set_default_dev_ipv4(hdr, ARP_TPA); } -static struct proto_hdr arp_hdr = { +static const struct proto_ops arp_proto_ops = { .id = PROTO_ARP, .layer = PROTO_L2, .header_init = arp_header_init, @@ -161,7 +161,7 @@ static void mpls_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) proto_field_set_default_be32(hdr, MPLS_LAST, 0); } -static struct proto_hdr mpls_hdr = { +static const struct proto_ops mpls_proto_ops = { .id = PROTO_MPLS, .layer = PROTO_L2, .header_init = mpls_header_init, @@ -170,8 +170,8 @@ static struct proto_hdr mpls_hdr = { void protos_l2_init(void) { - proto_header_register(ð_hdr); - proto_header_register(&vlan_hdr); - proto_header_register(&arp_hdr); - proto_header_register(&mpls_hdr); + proto_ops_register(ð_proto_ops); + proto_ops_register(&vlan_proto_ops); + proto_ops_register(&arp_proto_ops); + proto_ops_register(&mpls_proto_ops); } diff --git a/trafgen_l3.c b/trafgen_l3.c index 1cdd041..2eabef1 100644 --- a/trafgen_l3.c +++ b/trafgen_l3.c @@ -86,7 +86,7 @@ static void ipv4_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) proto_field_set_default_u8(hdr, IP4_PROTO, ip_proto); } -static struct proto_hdr ipv4_hdr = { +static const struct proto_ops ipv4_proto_ops = { .id = PROTO_IP4, .layer = PROTO_L3, .header_init = ipv4_header_init, @@ -146,7 +146,7 @@ static void ipv6_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) proto_field_set_default_u8(hdr, IP6_NEXT_HDR, ip_proto); } -static struct proto_hdr ipv6_hdr = { +static const struct proto_ops ipv6_proto_ops = { .id = PROTO_IP6, .layer = PROTO_L3, .header_init = ipv6_header_init, @@ -156,6 +156,6 @@ static struct proto_hdr ipv6_hdr = { void protos_l3_init(void) { - proto_header_register(&ipv4_hdr); - proto_header_register(&ipv6_hdr); + proto_ops_register(&ipv4_proto_ops); + proto_ops_register(&ipv6_proto_ops); } diff --git a/trafgen_l4.c b/trafgen_l4.c index 79c5914..16346db 100644 --- a/trafgen_l4.c +++ b/trafgen_l4.c @@ -44,7 +44,7 @@ static void udp_packet_finish(struct proto_hdr *hdr) if (!lower) return; - switch (lower->id) { + switch (lower->ops->id) { case PROTO_IP4: csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_UDP); @@ -61,7 +61,7 @@ static void udp_packet_finish(struct proto_hdr *hdr) proto_field_set_be16(hdr, UDP_CSUM, bswap_16(csum)); } -static struct proto_hdr udp_hdr = { +static const struct proto_ops udp_proto_ops = { .id = PROTO_UDP, .layer = PROTO_L4, .header_init = udp_header_init, @@ -112,7 +112,7 @@ static void tcp_packet_finish(struct proto_hdr *hdr) total_len = pkt->len - hdr->pkt_offset; - switch (lower->id) { + switch (lower->ops->id) { case PROTO_IP4: csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_TCP); @@ -129,7 +129,7 @@ static void tcp_packet_finish(struct proto_hdr *hdr) proto_field_set_be16(hdr, TCP_CSUM, bswap_16(csum)); } -static struct proto_hdr tcp_hdr = { +static const struct proto_ops tcp_proto_ops = { .id = PROTO_TCP, .layer = PROTO_L4, .header_init = tcp_header_init, @@ -170,7 +170,7 @@ static void icmpv4_packet_finish(struct proto_hdr *hdr) proto_field_set_u16(hdr, ICMPV4_CSUM, bswap_16(csum)); } -static struct proto_hdr icmpv4_hdr = { +static const struct proto_ops icmpv4_proto_ops = { .id = PROTO_ICMP4, .layer = PROTO_L4, .header_init = icmpv4_header_init, @@ -205,7 +205,7 @@ static void icmpv6_packet_finish(struct proto_hdr *hdr) total_len = pkt->len - hdr->pkt_offset; - switch (lower->id) { + switch (lower->ops->id) { case PROTO_IP6: csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_ICMPV6); @@ -218,7 +218,7 @@ static void icmpv6_packet_finish(struct proto_hdr *hdr) proto_field_set_be16(hdr, ICMPV6_CSUM, bswap_16(csum)); } -static struct proto_hdr icmpv6_hdr = { +static struct proto_ops icmpv6_proto_ops = { .id = PROTO_ICMP6, .layer = PROTO_L4, .header_init = icmpv6_header_init, @@ -227,8 +227,8 @@ static struct proto_hdr icmpv6_hdr = { void protos_l4_init(void) { - proto_header_register(&udp_hdr); - proto_header_register(&tcp_hdr); - proto_header_register(&icmpv4_hdr); - proto_header_register(&icmpv6_hdr); + proto_ops_register(&udp_proto_ops); + proto_ops_register(&tcp_proto_ops); + proto_ops_register(&icmpv4_proto_ops); + proto_ops_register(&icmpv6_proto_ops); } diff --git a/trafgen_parser.y b/trafgen_parser.y index cd87c12..d643ad2 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -348,7 +348,7 @@ static void set_dynamic_incdec(uint8_t start, uint8_t stop, uint8_t stepping, static void proto_add(enum proto_id pid) { - hdr = proto_header_init(pid); + hdr = proto_header_push(pid); } %} diff --git a/trafgen_proto.c b/trafgen_proto.c index 4219794..d976c14 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -27,7 +27,7 @@ struct ctx { }; static struct ctx ctx; -static const struct proto_hdr *registered[__PROTO_MAX]; +static const struct proto_ops *registered_ops[__PROTO_MAX]; struct proto_hdr *proto_lower_header(struct proto_hdr *hdr) { @@ -52,19 +52,18 @@ uint8_t *proto_header_ptr(struct proto_hdr *hdr) return &packet_get(hdr->pkt_id)->payload[hdr->pkt_offset]; } -static const struct proto_hdr *proto_header_by_id(enum proto_id id) +static const struct proto_ops *proto_ops_by_id(enum proto_id id) { - bug_on(id >= __PROTO_MAX); - return registered[id]; + const struct proto_ops *ops = registered_ops[id]; + + bug_on(ops->id != id); + return ops; } -void proto_header_register(struct proto_hdr *hdr) +void proto_ops_register(const struct proto_ops *ops) { - bug_on(hdr->id >= __PROTO_MAX); - registered[hdr->id] = hdr; - - hdr->fields = NULL; - hdr->fields_count = 0; + bug_on(ops->id >= __PROTO_MAX); + registered_ops[ops->id] = ops; } static void proto_fields_realloc(struct proto_hdr *hdr, size_t count) @@ -120,52 +119,55 @@ bool proto_field_is_set(struct proto_hdr *hdr, uint32_t fid) return field ? field->is_set : false; } -struct proto_hdr *proto_header_init(enum proto_id pid) +struct proto_hdr *proto_header_push(enum proto_id pid) { struct proto_hdr **headers = current_packet()->headers; - const struct proto_hdr *hdr = proto_header_by_id(pid); - struct proto_hdr *new_hdr; + const struct proto_ops *ops = proto_ops_by_id(pid); + struct proto_hdr *hdr; bug_on(current_packet()->headers_count >= PROTO_MAX_LAYERS); - new_hdr = xmalloc(sizeof(*new_hdr)); - memcpy(new_hdr, hdr, sizeof(*new_hdr)); + hdr = xzmalloc(sizeof(*hdr)); + hdr->ops = ops; + hdr->pkt_id = current_packet_id(); - new_hdr->pkt_id = current_packet_id(); + if (ops && ops->header_init) + ops->header_init(hdr); - if (new_hdr->header_init) - new_hdr->header_init(new_hdr); + headers[current_packet()->headers_count++] = hdr; - headers[current_packet()->headers_count++] = new_hdr; - return new_hdr; + return hdr; } void proto_header_finish(struct proto_hdr *hdr) { - if (hdr && hdr->header_finish) - hdr->header_finish(hdr); + if (hdr && hdr->ops && hdr->ops->header_finish) + hdr->ops->header_finish(hdr); } -struct proto_hdr *proto_lower_default_add(struct proto_hdr *hdr, +struct proto_hdr *proto_lower_default_add(struct proto_hdr *upper, enum proto_id pid) { struct proto_hdr *current; size_t headers_count = current_packet()->headers_count; + const struct proto_ops *ops; if (headers_count > 0) { current = current_packet()->headers[headers_count - 1]; + ops = current->ops; - if (current->layer >= proto_header_by_id(pid)->layer) + if (ops->layer >= proto_ops_by_id(pid)->layer) goto set_proto; - if (current->id == pid) + if (ops->id == pid) goto set_proto; } - current = proto_header_init(pid); + current = proto_header_push(pid); + ops = current->ops; set_proto: - if (current->set_next_proto) - current->set_next_proto(current, hdr->id); + if (ops && ops->set_next_proto) + ops->set_next_proto(current, upper->ops->id); return current; } @@ -415,9 +417,10 @@ void proto_packet_finish(void) /* Go down from upper layers to do last calculations (checksum) */ for (i = headers_count - 1; i >= 0; i--) { - struct proto_hdr *p = headers[i]; + struct proto_hdr *hdr = headers[i]; + const struct proto_ops *ops = hdr->ops; - if (p->packet_finish) - p->packet_finish(p); + if (ops && ops->packet_finish) + ops->packet_finish(hdr); } } diff --git a/trafgen_proto.h b/trafgen_proto.h index dbba700..9716aa2 100644 --- a/trafgen_proto.h +++ b/trafgen_proto.h @@ -29,6 +29,25 @@ enum proto_layer { struct proto_hdr; +struct proto_ops { + enum proto_id id; + enum proto_layer layer; + + void (*header_init)(struct proto_hdr *hdr); + void (*header_finish)(struct proto_hdr *hdr); + void (*packet_finish)(struct proto_hdr *hdr); + void (*set_next_proto)(struct proto_hdr *hdr, enum proto_id pid); +}; + +struct proto_hdr { + const struct proto_ops *ops; + uint16_t pkt_offset; + uint32_t pkt_id; + struct proto_field *fields; + size_t fields_count; + size_t len; +}; + struct proto_field { uint32_t id; size_t len; @@ -42,27 +61,10 @@ struct proto_field { struct proto_hdr *hdr; }; -struct proto_hdr { - enum proto_id id; - enum proto_layer layer; - - struct proto_hdr *next; - uint16_t pkt_offset; - uint32_t pkt_id; - struct proto_field *fields; - size_t fields_count; - size_t len; - - void (*header_init)(struct proto_hdr *hdr); - void (*header_finish)(struct proto_hdr *hdr); - void (*packet_finish)(struct proto_hdr *hdr); - void (*set_next_proto)(struct proto_hdr *hdr, enum proto_id pid); -}; - extern void protos_init(const char *dev); -extern void proto_header_register(struct proto_hdr *hdr); +extern void proto_ops_register(const struct proto_ops *ops); -extern struct proto_hdr *proto_header_init(enum proto_id pid); +extern struct proto_hdr *proto_header_push(enum proto_id pid); extern void proto_header_finish(struct proto_hdr *hdr); extern void proto_packet_finish(void); extern struct proto_hdr *proto_lower_default_add(struct proto_hdr *hdr, |