#ifndef __nosy_dump_h__ #define __nosy_dump_h__ #define array_length(array) (sizeof(array) / sizeof(array[0])) #define ACK_NO_ACK 0x0 #define ACK_DONE(a) ((a >> 2) == 0) #define ACK_BUSY(a) ((a >> 2) == 1) #define ACK_ERROR(a) ((a >> 2) == 3) #include struct phy_packet { uint32_t timestamp; union { struct { uint32_t zero:24; uint32_t phy_id:6; uint32_t identifier:2; } common, link_on; struct { uint32_t zero:16; uint32_t gap_count:6; uint32_t set_gap_count:1; uint32_t set_root:1; uint32_t root_id:6; uint32_t identifier:2; } phy_config; struct { uint32_t more_packets:1; uint32_t initiated_reset:1; uint32_t port2:2; uint32_t port1:2; uint32_t port0:2; uint32_t power_class:3; uint32_t contender:1; uint32_t phy_delay:2; uint32_t phy_speed:2; uint32_t gap_count:6; uint32_t link_active:1; uint32_t extended:1; uint32_t phy_id:6; uint32_t identifier:2; } self_id; struct { uint32_t more_packets:1; uint32_t reserved1:1; uint32_t porth:2; uint32_t portg:2; uint32_t portf:2; uint32_t porte:2; uint32_t portd:2; uint32_t portc:2; uint32_t portb:2; uint32_t porta:2; uint32_t reserved0:2; uint32_t sequence:3; uint32_t extended:1; uint32_t phy_id:6; uint32_t identifier:2; } ext_self_id; }; uint32_t inverted; uint32_t ack; }; #define TCODE_PHY_PACKET 0x10 #define PHY_PACKET_CONFIGURATION 0x00 #define PHY_PACKET_LINK_ON 0x01 #define PHY_PACKET_SELF_ID 0x02 struct link_packet { uint32_t timestamp; union { struct { uint32_t priority:4; uint32_t tcode:4; uint32_t rt:2; uint32_t tlabel:6; uint32_t destination:16; uint32_t offset_high:16; uint32_t source:16; uint32_t offset_low; } common; struct { uint32_t common[3]; uint32_t crc; } read_quadlet; struct { uint32_t common[3]; uint32_t data; uint32_t crc; } read_quadlet_response; struct { uint32_t common[3]; uint32_t extended_tcode:16; uint32_t data_length:16; uint32_t crc; } read_block; struct { uint32_t common[3]; uint32_t extended_tcode:16; uint32_t data_length:16; uint32_t crc; uint32_t data[0]; /* crc and ack follows. */ } read_block_response; struct { uint32_t common[3]; uint32_t data; uint32_t crc; } write_quadlet; struct { uint32_t common[3]; uint32_t extended_tcode:16; uint32_t data_length:16; uint32_t crc; uint32_t data[0]; /* crc and ack follows. */ } write_block; struct { uint32_t common[3]; uint32_t crc; } write_response; struct { uint32_t common[3]; uint32_t data; uint32_t crc; } cycle_start; struct { uint32_t sy:4; uint32_t tcode:4; uint32_t channel:6; uint32_t tag:2; uint32_t data_length:16; uint32_t crc; } iso_data; }; }; struct subaction { uint32_t ack; size_t length; struct list link; struct link_packet packet; }; struct link_transaction { int request_node, response_node, tlabel; struct subaction *request, *response; struct list request_list, response_list; struct list link; }; int decode_fcp(struct link_transaction *t); #endif /* __nosy_dump_h__ */ option>space:mode:
authorDimitris Michailidis <dmichail@google.com>2017-01-30 14:09:42 -0800
committerDavid S. Miller <davem@davemloft.net>2017-01-31 13:16:59 -0500
commit90427ef5d2a4b9a24079889bf16afdcdaebc4240 (patch)
tree05a3105bb966ada2f06b1c29dfcaa5e3bbf89223 /include
parentc73e44269369e936165f0f9b61f1f09a11dae01c (diff)
ipv6: fix flow labels when the traffic class is non-0
ip6_make_flowlabel() determines the flow label for IPv6 packets. It's supposed to be passed a flow label, which it returns as is if non-0 and in some other cases, otherwise it calculates a new value. The problem is callers often pass a flowi6.flowlabel, which may also contain traffic class bits. If the traffic class is non-0 ip6_make_flowlabel() mistakes the non-0 it gets as a flow label and returns the whole thing. Thus it can return a 'flow label' longer than 20b and the low 20b of that is typically 0 resulting in packets with 0 label. Moreover, different packets of a flow may be labeled differently. For a TCP flow with ECN non-payload and payload packets get different labels as exemplified by this pair of consecutive packets: (pure ACK) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... = Version: 6 .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0) .... .... .... 0001 1100 1110 0100 1001 = Flow Label: 0x1ce49 Payload Length: 32 Next Header: TCP (6) (payload) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... = Version: 6 .... 0000 0010 .... .... .... .... .... = Traffic Class: 0x02 (DSCP: CS0, ECN: ECT(0)) .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) .... .... ..10 .... .... .... .... .... = Explicit Congestion Notification: ECN-Capable Transport codepoint '10' (2) .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 Payload Length: 688 Next Header: TCP (6) This patch allows ip6_make_flowlabel() to be passed more than just a flow label and has it extract the part it really wants. This was simpler than modifying the callers. With this patch packets like the above become Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... = Version: 6 .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0) .... .... .... 1010 1111 1010 0101 1110 = Flow Label: 0xafa5e Payload Length: 32 Next Header: TCP (6) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... = Version: 6 .... 0000 0010 .... .... .... .... .... = Traffic Class: 0x02 (DSCP: CS0, ECN: ECT(0)) .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) .... .... ..10 .... .... .... .... .... = Explicit Congestion Notification: ECN-Capable Transport codepoint '10' (2) .... .... .... 1010 1111 1010 0101 1110 = Flow Label: 0xafa5e Payload Length: 688 Next Header: TCP (6) Signed-off-by: Dimitris Michailidis <dmichail@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/ipv6.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h