diff options
Diffstat (limited to 'misc.go')
-rw-r--r-- | misc.go | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -46,3 +46,62 @@ func min(a, b uint) uint { } return a } + +// called from receive +func ecn_rfc6040_egress(inner byte, outer byte) (byte, bool) { + /* + +---------+------------------------------------------------+ + |Arriving | Arriving Outer Header | + | Inner +---------+------------+------------+------------+ + | Header | Not-ECT | ECT(0) | ECT(1) | CE | + +---------+---------+------------+------------+------------+ + | Not-ECT | Not-ECT |Not-ECT(!!!)|Not-ECT(!!!)| <drop>(!!!)| + | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE | + | ECT(1) | ECT(1) | ECT(1) (!) | ECT(1) | CE | + | CE | CE | CE | CE(!!!)| CE | + +---------+---------+------------+------------+------------+ + */ + innerECN := CongestionExperienced & inner + outerECN := CongestionExperienced & outer + + switch outerECN { + case CongestionExperienced: + switch innerECN { + case NotECNTransport: + return 0, true + } + return (inner & (CongestionExperienced ^ 255)) | CongestionExperienced, false + case ECNTransport1: + switch innerECN { + case ECNTransport0: + return (inner & (CongestionExperienced ^ 255)) | ECNTransport1, false + } + } + return inner, false +} + +// called from send +func ecn_rfc6040_ingress(inner byte, useNormalMode bool) byte { + /* + +-----------------+-------------------------------+ + | Incoming Header | Departing Outer Header | + | (also equal to +---------------+---------------+ + | departing Inner | Compatibility | Normal | + | Header) | Mode | Mode | + +-----------------+---------------+---------------+ + | Not-ECT | Not-ECT | Not-ECT | + | ECT(0) | Not-ECT | ECT(0) | + | ECT(1) | Not-ECT | ECT(1) | + | CE | Not-ECT | CE | + +-----------------+---------------+---------------+ + */ + if !useNormalMode { + inner &= (CongestionExperienced ^ 255) + } + + return inner +} + +func ecn_rfc6040_enabled(tos byte) bool { + return (CongestionExperienced & tos) == ECNTransport0 +} |