diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index f0235b9d5..f75638f80 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -406,16 +406,6 @@ enum ZT_Event
 	ZT_EVENT_USER_MESSAGE = 6
 };
 
-/**
- * Node relay policy
- */
-enum ZT_RelayPolicy
-{
-	ZT_RELAY_POLICY_NEVER = 0,
-	ZT_RELAY_POLICY_TRUSTED = 1,
-	ZT_RELAY_POLICY_ALWAYS = 2
-};
-
 /**
  * User message used with ZT_EVENT_USER_MESSAGE
  */
@@ -476,11 +466,6 @@ typedef struct
 	 */
 	const char *secretIdentity;
 
-	/**
-	 * Node relay policy
-	 */
-	enum ZT_RelayPolicy relayPolicy;
-
 	/**
 	 * True if some kind of connectivity appears available
 	 */
@@ -1718,15 +1703,6 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
  */
 enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
 
-/**
- * Set node's relay policy
- *
- * @param node Node instance
- * @param rp New relay policy
- * @return OK(0) or error code
- */
-enum ZT_ResultCode ZT_Node_setRelayPolicy(ZT_Node *node,enum ZT_RelayPolicy rp);
-
 /**
  * Join a network
  *
diff --git a/node/Network.cpp b/node/Network.cpp
index 8b0f20559..ec1bcb337 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -1102,7 +1102,6 @@ void Network::requestConfiguration()
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
-	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_RELAY_POLICY,(uint64_t)RR->node->relayPolicy());
 
 	if (ctrl == RR->identity.address()) {
 		if (RR->localNetworkController) {
diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp
index a548e8667..390873952 100644
--- a/node/NetworkConfig.hpp
+++ b/node/NetworkConfig.hpp
@@ -135,8 +135,6 @@ namespace ZeroTier {
 #define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH "a"
 // Network configuration meta-data flags
 #define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS "f"
-// Relay policy for this node
-#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_RELAY_POLICY "rp"
 
 // These dictionary keys are short so they don't take up much room.
 // By convention we use upper case for binary blobs, but it doesn't really matter.
diff --git a/node/Node.cpp b/node/Node.cpp
index df22e3f25..23271ccab 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -53,8 +53,7 @@ Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
 	_prngStreamPtr(0),
 	_now(now),
 	_lastPingCheck(0),
-	_lastHousekeepingRun(0),
-	_relayPolicy(ZT_RELAY_POLICY_TRUSTED)
+	_lastHousekeepingRun(0)
 {
 	if (callbacks->version != 0)
 		throw std::runtime_error("callbacks struct version mismatch");
@@ -102,9 +101,6 @@ Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
 		throw;
 	}
 
-	if (RR->topology->amRoot())
-		_relayPolicy = ZT_RELAY_POLICY_ALWAYS;
-
 	postEvent(ZT_EVENT_UP);
 }
 
@@ -282,12 +278,6 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
 	return ZT_RESULT_OK;
 }
 
-ZT_ResultCode Node::setRelayPolicy(enum ZT_RelayPolicy rp)
-{
-	_relayPolicy = rp;
-	return ZT_RESULT_OK;
-}
-
 ZT_ResultCode Node::join(uint64_t nwid,void *uptr)
 {
 	Mutex::Lock _l(_networks_m);
@@ -345,7 +335,6 @@ void Node::status(ZT_NodeStatus *status) const
 	status->worldTimestamp = RR->topology->planetWorldTimestamp();
 	status->publicIdentity = RR->publicIdentityStr.c_str();
 	status->secretIdentity = RR->secretIdentityStr.c_str();
-	status->relayPolicy = _relayPolicy;
 	status->online = _online ? 1 : 0;
 }
 
@@ -860,15 +849,6 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol
 	}
 }
 
-enum ZT_ResultCode ZT_Node_setRelayPolicy(ZT_Node *node,enum ZT_RelayPolicy rp)
-{
-	try {
-		return reinterpret_cast<ZeroTier::Node *>(node)->setRelayPolicy(rp);
-	} catch ( ... ) {
-		return ZT_RESULT_FATAL_ERROR_INTERNAL;
-	}
-}
-
 enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr)
 {
 	try {
diff --git a/node/Node.hpp b/node/Node.hpp
index 4c070014d..662abcb40 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -91,7 +91,6 @@ public:
 		unsigned int frameLength,
 		volatile uint64_t *nextBackgroundTaskDeadline);
 	ZT_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
-	ZT_ResultCode setRelayPolicy(enum ZT_RelayPolicy rp);
 	ZT_ResultCode join(uint64_t nwid,void *uptr);
 	ZT_ResultCode leave(uint64_t nwid,void **uptr);
 	ZT_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
@@ -197,7 +196,6 @@ public:
 	inline int configureVirtualNetworkPort(uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,nwid,nuptr,op,nc); }
 
 	inline bool online() const throw() { return _online; }
-	inline ZT_RelayPolicy relayPolicy() const { return _relayPolicy; }
 
 #ifdef ZT_TRACE
 	void postTrace(const char *module,unsigned int line,const char *fmt,...);
@@ -298,7 +296,6 @@ private:
 	uint64_t _now;
 	uint64_t _lastPingCheck;
 	uint64_t _lastHousekeepingRun;
-	ZT_RelayPolicy _relayPolicy;
 	bool _online;
 };
 
diff --git a/node/Switch.cpp b/node/Switch.cpp
index 04624f03b..f935b7aae 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -105,17 +105,8 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
 				const Address destination(fragment.destination());
 
 				if (destination != RR->identity.address()) {
-					switch(RR->node->relayPolicy()) {
-						case ZT_RELAY_POLICY_ALWAYS:
-							break;
-						case ZT_RELAY_POLICY_TRUSTED:
-							if (!path->trustEstablished(now))
-								return;
-							break;
-						// case ZT_RELAY_POLICY_NEVER:
-						default:
-							return;
-					}
+					if ( (!RR->topology->amRoot()) && (!path->trustEstablished(now)) )
+						return;
 
 					if (fragment.hops() < ZT_RELAY_MAX_HOPS) {
 						fragment.incrementHops();
@@ -213,18 +204,10 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
 
 				//TRACE("<< %.16llx %s -> %s (size: %u)",(unsigned long long)packet->packetId(),source.toString().c_str(),destination.toString().c_str(),packet->size());
 
+
 				if (destination != RR->identity.address()) {
-					switch(RR->node->relayPolicy()) {
-						case ZT_RELAY_POLICY_ALWAYS:
-							break;
-						case ZT_RELAY_POLICY_TRUSTED:
-							if (!path->trustEstablished(now))
-								return;
-							break;
-						// case ZT_RELAY_POLICY_NEVER:
-						default:
-							return;
-					}
+					if ( (!RR->topology->amRoot()) && (!path->trustEstablished(now)) )
+						return;
 
 					Packet packet(data,len);
 
diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp
index 86158a91d..e5142f3e7 100644
--- a/service/ControlPlane.cpp
+++ b/service/ControlPlane.cpp
@@ -391,7 +391,6 @@ unsigned int ControlPlane::handleRequest(
 					"\t\"worldId\": %llu,\n"
 					"\t\"worldTimestamp\": %llu,\n"
 					"\t\"online\": %s,\n"
-					"\t\"relayPolicy\": \"%s\",\n"
 					"\t\"tcpFallbackActive\": %s,\n"
 					"\t\"versionMajor\": %d,\n"
 					"\t\"versionMinor\": %d,\n"
@@ -405,7 +404,6 @@ unsigned int ControlPlane::handleRequest(
 					status.worldId,
 					status.worldTimestamp,
 					(status.online) ? "true" : "false",
-					((status.relayPolicy == ZT_RELAY_POLICY_ALWAYS) ? "always" : ((status.relayPolicy == ZT_RELAY_POLICY_NEVER) ? "never" : "trusted")),
 					(_svc->tcpFallbackActive()) ? "true" : "false",
 					ZEROTIER_ONE_VERSION_MAJOR,
 					ZEROTIER_ONE_VERSION_MINOR,
diff --git a/service/OneService.cpp b/service/OneService.cpp
index 6d9effa13..f6174d423 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -694,7 +694,7 @@ public:
 			_controlPlane->addAuthToken(authToken.c_str());
 			_controlPlane->setController(_controller);
 
-			{	// Remember networks from previous session
+			{	// Load existing networks
 				std::vector<std::string> networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S "networks.d").c_str()));
 				for(std::vector<std::string>::iterator f(networksDotD.begin());f!=networksDotD.end();++f) {
 					std::size_t dot = f->find_last_of('.');
@@ -981,13 +981,6 @@ public:
 		if (settings.is_object()) {
 			_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
 
-			const std::string rp(OSUtils::jsonString(settings["relayPolicy"],""));
-			if ((rp == "always")||(rp == "ALWAYS"))
-				_node->setRelayPolicy(ZT_RELAY_POLICY_ALWAYS);
-			else if ((rp == "never")||(rp == "NEVER"))
-				_node->setRelayPolicy(ZT_RELAY_POLICY_NEVER);
-			else _node->setRelayPolicy(ZT_RELAY_POLICY_TRUSTED);
-
 			const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
 			const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"],false);
 			if (((up == "apply")||(up == "download"))||(udist)) {
diff --git a/service/README.md b/service/README.md
index 5d54b9233..d3bc5338a 100644
--- a/service/README.md
+++ b/service/README.md
@@ -24,7 +24,6 @@ Settings available in `local.conf` (this is not valid JSON, and JSON does not al
 		}
 	},
 	"settings": { /* Other global settings */
-		"relayPolicy": "trusted"|"always"|"never", /* Policy for relaying others' traffic (see below) */
 		"portMappingEnabled": true|false, /* If true (the default), try to use uPnP or NAT-PMP to map ports */
 		"softwareUpdate": "apply"|"download"|"disable", /* Automatically apply updates, just download, or disable built-in software updates */
 		"softwareUpdateDist": true|false, /* If true, distribute software updates (only really useful to ZeroTier, Inc. itself, default is false) */