diff options
| author | Joseph Henry <[email protected]> | 2019-08-20 18:50:38 -0700 |
|---|---|---|
| committer | Joseph Henry <[email protected]> | 2019-08-20 18:50:38 -0700 |
| commit | 5453cab22b26b4caa38457dadf64e5f53920cb2d (patch) | |
| tree | 3018578b5eea4e92c16c0c67aa67f9ddb55e4869 /node/Switch.cpp | |
| parent | b0a91c018727f20789ac10b70b766f7b6041feb5 (diff) | |
Added flow-awareness check for policies, more work on ZT_MULTIPATH_ACTIVE_BACKUP
Diffstat (limited to 'node/Switch.cpp')
| -rw-r--r-- | node/Switch.cpp | 113 |
1 files changed, 62 insertions, 51 deletions
diff --git a/node/Switch.cpp b/node/Switch.cpp index c2251f23..51f23f67 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -284,6 +284,14 @@ static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsig return false; // overflow == invalid } +bool Switch::isFlowAware() +{ + int mode = RR->node->getMultipathMode(); + return (( mode == ZT_MULTIPATH_BALANCE_RR_FLOW) + || (mode == ZT_MULTIPATH_BALANCE_XOR_FLOW) + || (mode == ZT_MULTIPATH_BALANCE_DYNAMIC_FLOW)); +} + void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { if (!network->hasConfig()) @@ -309,61 +317,64 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const * preferred virtual path and will be sent out according to what the multipath logic * deems appropriate. An example of this would be an ICMP packet. */ + int64_t flowId = -1; - if (etherType == ZT_ETHERTYPE_IPV4 && (len >= 20)) { - uint16_t srcPort = 0; - uint16_t dstPort = 0; - int8_t proto = (reinterpret_cast<const uint8_t *>(data)[9]); - const unsigned int headerLen = 4 * (reinterpret_cast<const uint8_t *>(data)[0] & 0xf); - switch(proto) { - case 0x01: // ICMP - flowId = 0x01; - break; - // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite - if (len > (headerLen + 4)) { - unsigned int pos = headerLen + 0; - srcPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; - srcPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); - pos++; - dstPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; - dstPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); - flowId = ((int64_t)srcPort << 48) | ((int64_t)dstPort << 32) | proto; - } - break; + if (isFlowAware()) { + if (etherType == ZT_ETHERTYPE_IPV4 && (len >= 20)) { + uint16_t srcPort = 0; + uint16_t dstPort = 0; + int8_t proto = (reinterpret_cast<const uint8_t *>(data)[9]); + const unsigned int headerLen = 4 * (reinterpret_cast<const uint8_t *>(data)[0] & 0xf); + switch(proto) { + case 0x01: // ICMP + flowId = 0x01; + break; + // All these start with 16-bit source and destination port in that order + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite + if (len > (headerLen + 4)) { + unsigned int pos = headerLen + 0; + srcPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; + srcPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); + pos++; + dstPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; + dstPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); + flowId = ((int64_t)srcPort << 48) | ((int64_t)dstPort << 32) | proto; + } + break; + } } - } - if (etherType == ZT_ETHERTYPE_IPV6 && (len >= 40)) { - uint16_t srcPort = 0; - uint16_t dstPort = 0; - unsigned int pos; - unsigned int proto; - _ipv6GetPayload((const uint8_t *)data, len, pos, proto); - switch(proto) { - case 0x3A: // ICMPv6 - flowId = 0x3A; - break; - // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite - if (len > (pos + 4)) { - srcPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; - srcPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); - pos++; - dstPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; - dstPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); - flowId = ((int64_t)srcPort << 48) | ((int64_t)dstPort << 32) | proto; - } - break; - default: - break; + if (etherType == ZT_ETHERTYPE_IPV6 && (len >= 40)) { + uint16_t srcPort = 0; + uint16_t dstPort = 0; + unsigned int pos; + unsigned int proto; + _ipv6GetPayload((const uint8_t *)data, len, pos, proto); + switch(proto) { + case 0x3A: // ICMPv6 + flowId = 0x3A; + break; + // All these start with 16-bit source and destination port in that order + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite + if (len > (pos + 4)) { + srcPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; + srcPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); + pos++; + dstPort = (reinterpret_cast<const uint8_t *>(data)[pos++]) << 8; + dstPort |= (reinterpret_cast<const uint8_t *>(data)[pos]); + flowId = ((int64_t)srcPort << 48) | ((int64_t)dstPort << 32) | proto; + } + break; + default: + break; + } } } |
