diff --git a/node/Network.cpp b/node/Network.cpp index 2488bea20..45ffc993b 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -178,6 +178,9 @@ static _doZtFilterResult _doZtFilter( std::vector dlog; #endif // ZT_RULES_ENGINE_DEBUGGING + // Set to true if we are a TEE/REDIRECT/WATCH target + bool superAccept = false; + // The default match state for each set of entries starts as 'true' since an // ACTION with no MATCH entries preceding it is always taken. uint8_t thisSetMatches = 1; @@ -199,7 +202,7 @@ static _doZtFilterResult _doZtFilter( #ifdef ZT_RULES_ENGINE_DEBUGGING _dumpFilterTrace("ACTION_ACCEPT",thisSetMatches,inbound,ztSource,ztDest,macSource,macDest,dlog,frameLen,etherType,(const char *)0); #endif // ZT_RULES_ENGINE_DEBUGGING - return DOZTFILTER_ACCEPT; // match, accept packet + return (superAccept ? DOZTFILTER_SUPER_ACCEPT : DOZTFILTER_ACCEPT); // match, accept packet // These are initially handled together since preliminary logic is common case ZT_NETWORK_RULE_ACTION_TEE: @@ -264,6 +267,22 @@ static _doZtFilterResult _doZtFilter( continue; } } else { + // If this is an incoming packet and we are a TEE or REDIRECT target, we should + // super-accept if we accept at all. This will cause us to accept redirected or + // tee'd packets in spite of MAC and ZT addressing checks. + if (inbound) { + switch(rt) { + case ZT_NETWORK_RULE_ACTION_TEE: + case ZT_NETWORK_RULE_ACTION_WATCH: + case ZT_NETWORK_RULE_ACTION_REDIRECT: + if (RR->identity.address() == rules[rn].v.fwd.address) + superAccept = true; + break; + default: + break; + } + } + #ifdef ZT_RULES_ENGINE_DEBUGGING _dumpFilterTrace(_rtn(rt),thisSetMatches,inbound,ztSource,ztDest,macSource,macDest,dlog,frameLen,etherType,(const char *)0); dlog.clear(); @@ -541,12 +560,12 @@ static _doZtFilterResult _doZtFilter( thisRuleMatches = 0; } } else { - if (inbound) { + if ((inbound)&&(!superAccept)) { thisRuleMatches = 0; FILTER_TRACE("%u %s %c remote tag %u not found -> 0 (inbound side is strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id); } else { thisRuleMatches = 1; - FILTER_TRACE("%u %s %c remote tag %u not found -> 1 (outbound side is not strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id); + FILTER_TRACE("%u %s %c remote tag %u not found -> 1 (outbound side and TEE/REDIRECT targets are not strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id); } } } else {