diff -urp v5.3/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
--- v5.3/linux/Documentation/networking/ip-sysctl.txt	2019-11-30 19:20:51.000000000 +0200
+++ linux/Documentation/networking/ip-sysctl.txt	2019-11-30 19:21:22.927077243 +0200
@@ -1374,6 +1374,14 @@ drop_gratuitous_arp - BOOLEAN
 	Default: off (0)
 
 
+hidden - BOOLEAN
+	Hide addresses attached to this device from other devices.
+	Such addresses will never be selected by source address autoselection
+	mechanism, host does not answer broadcast ARP requests for them,
+	does not announce them as source address of ARP requests, but they
+	are still reachable via IP. This flag is activated only if it is
+	enabled both in specific device section and in "all" section.
+
 tag - INTEGER
 	Allows you to write a number, which can be used as required.
 	Default value is 0.
diff -urp v5.3/linux/include/linux/inetdevice.h linux/include/linux/inetdevice.h
--- v5.3/linux/include/linux/inetdevice.h	2019-11-30 19:20:51.000000000 +0200
+++ linux/include/linux/inetdevice.h	2019-11-30 19:21:22.928077230 +0200
@@ -112,6 +112,7 @@ static inline void ipv4_devconf_setall(s
 						      SECURE_REDIRECTS)
 #define IN_DEV_IDTAG(in_dev)		IN_DEV_CONF_GET(in_dev, TAG)
 #define IN_DEV_MEDIUM_ID(in_dev)	IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
+#define IN_DEV_HIDDEN(in_dev)		IN_DEV_ANDCONF((in_dev), HIDDEN)
 #define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
 					IN_DEV_ORCONF((in_dev), \
 						      PROMOTE_SECONDARIES)
diff -urp v5.3/linux/include/uapi/linux/ip.h linux/include/uapi/linux/ip.h
--- v5.3/linux/include/uapi/linux/ip.h	2019-11-30 19:20:51.000000000 +0200
+++ linux/include/uapi/linux/ip.h	2019-11-30 19:21:22.928077230 +0200
@@ -169,6 +169,7 @@ enum
 	IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
 	IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
 	IPV4_DEVCONF_BC_FORWARDING,
+	IPV4_DEVCONF_HIDDEN,
 	__IPV4_DEVCONF_MAX
 };
 
diff -urp v5.3/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v5.3/linux/net/ipv4/arp.c	2019-11-30 19:20:51.000000000 +0200
+++ linux/net/ipv4/arp.c	2019-11-30 19:21:22.929077217 +0200
@@ -67,6 +67,8 @@
  *					sending (e.g. insert 8021q tag).
  *		Harald Welte	:	convert to make use of jenkins hash
  *		Jesper D. Brouer:       Proxy ARP PVLAN RFC 3069 support.
+ *		Julian Anastasov:	"hidden" flag: hide the
+ *					interface and don't reply for it
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -334,7 +336,9 @@ static void arp_solicit(struct neighbour
 	struct net_device *dev = neigh->dev;
 	__be32 target = *(__be32 *)neigh->primary_key;
 	int probes = atomic_read(&neigh->probes);
-	struct in_device *in_dev;
+	struct in_device *in_dev, *in_dev2;
+	struct net_device *dev2;
+	int mode;
 	struct dst_entry *dst = NULL;
 
 	rcu_read_lock();
@@ -343,9 +347,22 @@ static void arp_solicit(struct neighbour
 		rcu_read_unlock();
 		return;
 	}
-	switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
+	mode = IN_DEV_ARP_ANNOUNCE(in_dev);
+	if (mode != 2 && skb &&
+	    (dev2 = __ip_dev_find(dev_net(dev), ip_hdr(skb)->saddr,
+				  false)) != NULL &&
+	    (saddr = ip_hdr(skb)->saddr,
+	     in_dev2 = __in_dev_get_rcu(dev2)) != NULL &&
+	    IN_DEV_HIDDEN(in_dev2)) {
+		saddr = 0;
+		goto get;
+	}
+
+	switch (mode) {
 	default:
 	case 0:		/* By default announce any local IP */
+		if (saddr)
+			break;
 		if (skb && inet_addr_type_dev_table(dev_net(dev), dev,
 					  ip_hdr(skb)->saddr) == RTN_LOCAL)
 			saddr = ip_hdr(skb)->saddr;
@@ -353,9 +370,10 @@ static void arp_solicit(struct neighbour
 	case 1:		/* Restrict announcements of saddr in same subnet */
 		if (!skb)
 			break;
-		saddr = ip_hdr(skb)->saddr;
-		if (inet_addr_type_dev_table(dev_net(dev), dev,
-					     saddr) == RTN_LOCAL) {
+		if (saddr ||
+		    (saddr = ip_hdr(skb)->saddr,
+		     inet_addr_type_dev_table(dev_net(dev), dev,
+					     saddr) == RTN_LOCAL)) {
 			/* saddr should be known to target */
 			if (inet_addr_onlink(in_dev, target, saddr))
 				break;
@@ -365,6 +383,8 @@ static void arp_solicit(struct neighbour
 	case 2:		/* Avoid secondary IPs, get a primary/preferred one */
 		break;
 	}
+
+get:
 	rcu_read_unlock();
 
 	if (!saddr)
@@ -444,6 +464,21 @@ static int arp_filter(__be32 sip, __be32
 	return flag;
 }
 
+static int arp_hidden(u32 tip, struct net_device *dev)
+{
+	struct net_device *dev2;
+	struct in_device *in_dev2;
+	int ret = 0;
+
+	if (!IPV4_DEVCONF_ALL(dev_net(dev), HIDDEN))
+		return 0;
+
+	if ((dev2 = __ip_dev_find(dev_net(dev), tip, false)) && dev2 != dev &&
+	    (in_dev2 = __in_dev_get_rcu(dev2)) && IN_DEV_HIDDEN(in_dev2))
+		ret = 1;
+	return ret;
+}
+
 /*
  * Check if we can use proxy ARP for this path
  */
@@ -804,6 +839,7 @@ static int arp_process(struct net *net,
 	if (sip == 0) {
 		if (arp->ar_op == htons(ARPOP_REQUEST) &&
 		    inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL &&
+		    !arp_hidden(tip, dev) &&
 		    !arp_ignore(in_dev, sip, tip))
 			arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
 				     sha, dev->dev_addr, sha, reply_dst);
@@ -822,6 +858,8 @@ static int arp_process(struct net *net,
 			dont_send = arp_ignore(in_dev, sip, tip);
 			if (!dont_send && IN_DEV_ARPFILTER(in_dev))
 				dont_send = arp_filter(sip, tip, dev);
+			if (!dont_send && skb->pkt_type != PACKET_HOST)
+				dont_send = arp_hidden(tip,dev); 
 			if (!dont_send) {
 				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
 				if (n) {
diff -urp v5.3/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- v5.3/linux/net/ipv4/devinet.c	2019-11-30 19:20:51.000000000 +0200
+++ linux/net/ipv4/devinet.c	2019-11-30 19:30:02.004229373 +0200
@@ -1352,9 +1352,16 @@ no_in_dev:
 		if (!in_dev)
 			continue;
 
-		addr = in_dev_select_addr(in_dev, scope);
-		if (addr)
-			goto out_unlock;
+		in_dev_for_each_ifa_rcu(ifa, in_dev) {
+			if (ifa->ifa_flags & IFA_F_SECONDARY)
+				break;
+			if (!IN_DEV_HIDDEN(in_dev) &&
+			    ifa->ifa_scope != RT_SCOPE_LINK &&
+			    ifa->ifa_scope <= scope) {
+				addr = ifa->ifa_local;
+				goto out_unlock;
+			}
+		}
 	}
 out_unlock:
 	rcu_read_unlock();
@@ -2524,6 +2531,7 @@ static struct devinet_sysctl_table {
 		DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
 		DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
 		DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
+		DEVINET_SYSCTL_RW_ENTRY(HIDDEN, "hidden"),
 		DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
 		DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
 		DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
