diff options
author | Vadim Kochan <vadim4j@gmail.com> | 2016-09-22 23:55:33 +0300 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2016-10-04 17:17:24 +0200 |
commit | f4c1856026c0edcc1e2285cf6ae773057bee51cd (patch) | |
tree | baf5663ef7daf90b5f1cdd4c3e9f31868034238d | |
parent | 7007975949f5177fbf2514633cc44ba0ac4712c5 (diff) |
trafgen: l2: Add support for IEEE 802.3X PAUSE header
Add EEE802.3X Ethernet MAC Control PAUSE frame proto header with two
fields - opcode & time.
By default Ethernet header is pushed on header init.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r-- | trafgen_l2.c | 27 | ||||
-rw-r--r-- | trafgen_l2.h | 5 | ||||
-rw-r--r-- | trafgen_proto.h | 1 |
3 files changed, 33 insertions, 0 deletions
diff --git a/trafgen_l2.c b/trafgen_l2.c index 866559c..8d2d285 100644 --- a/trafgen_l2.c +++ b/trafgen_l2.c @@ -30,6 +30,8 @@ static uint16_t pid_to_eth(enum proto_id pid) return ETH_P_MPLS_UC; case PROTO_VLAN: return ETH_P_8021Q; + case PROTO_PAUSE: + return ETH_P_PAUSE; default: bug(); } @@ -54,6 +56,30 @@ static const struct proto_ops eth_proto_ops = { .set_next_proto = eth_set_next_proto, }; +static struct proto_field pause_fields[] = { + { .id = PAUSE_OPCODE, .len = 2, .offset = 0 }, + { .id = PAUSE_TIME, .len = 2, .offset = 2 }, +}; + +static void pause_header_init(struct proto_hdr *hdr) +{ + uint8_t eth_dst[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 }; + + struct proto_hdr *lower; + + lower = proto_lower_default_add(hdr, PROTO_ETH); + proto_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst); + + proto_header_fields_add(hdr, pause_fields, array_size(pause_fields)); + proto_field_set_default_be16(hdr, PAUSE_OPCODE, 0x1); +} + +static struct proto_ops pause_proto_ops = { + .id = PROTO_PAUSE, + .layer = PROTO_L2, + .header_init = pause_header_init, +}; + static struct proto_field vlan_fields[] = { /* TPID overlaps with Ethernet header and points to ether type */ { .id = VLAN_TPID, .len = 2, .offset = -2 }, @@ -167,6 +193,7 @@ static const struct proto_ops mpls_proto_ops = { void protos_l2_init(void) { proto_ops_register(ð_proto_ops); + proto_ops_register(&pause_proto_ops); proto_ops_register(&vlan_proto_ops); proto_ops_register(&arp_proto_ops); proto_ops_register(&mpls_proto_ops); diff --git a/trafgen_l2.h b/trafgen_l2.h index 14f0e84..7c8ef7d 100644 --- a/trafgen_l2.h +++ b/trafgen_l2.h @@ -7,6 +7,11 @@ enum eth_field { ETH_TYPE, }; +enum pause_field { + PAUSE_OPCODE, + PAUSE_TIME, +}; + enum arp_field { ARP_HTYPE, ARP_PTYPE, diff --git a/trafgen_proto.h b/trafgen_proto.h index a8b97eb..a1f6b66 100644 --- a/trafgen_proto.h +++ b/trafgen_proto.h @@ -8,6 +8,7 @@ enum proto_id { PROTO_NONE = 0, PROTO_ETH, + PROTO_PAUSE, PROTO_VLAN, PROTO_ARP, PROTO_MPLS, |