All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Greear <greearb@candelatech.com>
To: "'netdev@oss.sgi.com'" <netdev@oss.sgi.com>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH]  Networking:  send-to-self
Date: Tue, 17 Sep 2002 23:47:22 -0700	[thread overview]
Message-ID: <3D88217A.6070702@candelatech.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 676 bytes --]

This patch allows one to use the SO_BINDTODEVICE and a new ioctl against
net_device objects to send and receive regular routed traffic between two
interfaces on the same machine.  It also fixes a problem when using BINDTODEVICE:
the old code does not set the bound_if correctly when sending back the
syn-ack during TCP connection initialization.

I'm not sure how useful others will find it, but it amuses me ;)

Comments and suggestions welcome.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear


[-- Attachment #2: sts_2.4.19.patch --]
[-- Type: text/plain, Size: 9264 bytes --]

--- linux-2.4.19/include/linux/sockios.h	Wed Nov  7 15:39:36 2001
+++ linux-2.4.19.dev/include/linux/sockios.h	Sun Sep 15 21:10:00 2002
@@ -114,6 +114,16 @@
 #define SIOCBONDINFOQUERY      0x8994	/* rtn info about bond state    */
 #define SIOCBONDCHANGEACTIVE   0x8995   /* update to a new active slave */
 			
+
+/* Ben's little hack land */
+#define SIOCSACCEPTLOCALADDRS  0x89a0   /*  Allow interfaces to accept pkts from
+                                         * local interfaces...use with SO_BINDTODEVICE
+                                         */
+#define SIOCGACCEPTLOCALADDRS  0x89a1   /*  Allow interfaces to accept pkts from
+                                         * local interfaces...use with SO_BINDTODEVICE
+                                         */
+
+
 /* Device private ioctl calls */
 
 /*
--- linux-2.4.19/net/Config.in	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/net/Config.in	Sun Sep 15 21:27:08 2002
@@ -97,6 +97,7 @@
 mainmenu_option next_comment
 comment 'Network testing'
 tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
+bool 'Send-to-Self' CONFIG_NET_SENDTOSELF
 endmenu
 
 endmenu
--- linux-2.4.19/include/net/tcp.h	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/include/net/tcp.h	Sun Sep 15 21:57:07 2002
@@ -27,6 +27,7 @@
 #include <linux/config.h>
 #include <linux/tcp.h>
 #include <linux/slab.h>
+#include <linux/cache.h>
 #include <net/checksum.h>
 #include <net/sock.h>
 
@@ -117,8 +118,7 @@
 	 * Now align to a new cache line as all the following members
 	 * are often dirty.
 	 */
-	rwlock_t __tcp_lhash_lock
-		__attribute__((__aligned__(SMP_CACHE_BYTES)));
+	rwlock_t __tcp_lhash_lock ____cacheline_aligned;
 	atomic_t __tcp_lhash_users;
 	wait_queue_head_t __tcp_lhash_wait;
 	spinlock_t __tcp_portalloc_lock;
@@ -447,7 +447,6 @@
 extern int sysctl_tcp_retrans_collapse;
 extern int sysctl_tcp_stdurg;
 extern int sysctl_tcp_rfc1337;
-extern int sysctl_tcp_tw_recycle;
 extern int sysctl_tcp_abort_on_overflow;
 extern int sysctl_tcp_max_orphans;
 extern int sysctl_tcp_max_tw_buckets;
@@ -520,6 +519,14 @@
 		struct tcp_v6_open_req v6_req;
 #endif
 	} af;
+#ifdef CONFIG_NET_SENDTOSELF
+        int bound_dev_if; /* This is so we can connect to ourselves and not collide
+                           * in the open-request hash (the addresses and ports are the
+                           * same, but we need two ends, so use the interface to determine
+                           * one from the other.  Active when SO_BINDTODEVICE is used.
+                           * --Ben
+                           */
+#endif
 };
 
 /* SLAB cache for open requests. */
--- linux-2.4.19/net/ipv4/arp.c	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/net/ipv4/arp.c	Sun Sep 15 21:14:43 2002
@@ -1,4 +1,4 @@
-/* linux/net/inet/arp.c
+/* linux/net/inet/arp.c  -*-linux-c-*-
  *
  * Version:	$Id: sts_2.4.19.patch,v 1.3 2002/09/17 07:01:55 greear Exp $
  *
@@ -351,12 +351,26 @@
 	int flag = 0; 
 	/*unsigned long now; */
 
-	if (ip_route_output(&rt, sip, tip, 0, 0) < 0) 
+	if (ip_route_output(&rt, sip, tip, 0, 0) < 0)
 		return 1;
-	if (rt->u.dst.dev != dev) { 
-		NET_INC_STATS_BH(ArpFilter);
-		flag = 1;
-	} 
+        
+	if (rt->u.dst.dev != dev) {
+#ifdef CONFIG_NET_SENDTOSELF
+                if ((dev->priv_flags & IFF_ACCEPT_LOCAL_ADDRS) &&
+                    (rt->u.dst.dev == &loopback_dev))  {
+                        /* OK, we'll let this special case slide, so that we can arp from one
+                         * local interface to another.  This seems to work, but could use some
+                         * review. --Ben
+                         */
+                }
+                else {
+#endif
+                        NET_INC_STATS_BH(ArpFilter);
+                        flag = 1;
+#ifdef CONFIG_NET_SENDTOSELF
+                }
+#endif
+        }
 	ip_rt_put(rt); 
 	return flag; 
 } 
--- linux-2.4.19/net/ipv4/fib_frontend.c	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/net/ipv4/fib_frontend.c	Sun Sep 15 21:16:44 2002
@@ -233,8 +233,19 @@
 
 	if (fib_lookup(&key, &res))
 		goto last_resort;
-	if (res.type != RTN_UNICAST)
-		goto e_inval_res;
+        
+	if (res.type != RTN_UNICAST) {
+#ifdef CONFIG_NET_SENDTOSELF
+           if ((res.type == RTN_LOCAL) &&
+                    (dev->priv_flags & IFF_ACCEPT_LOCAL_ADDRS)) {
+                     /* All is OK */
+           }
+           else
+#endif
+              goto e_inval_res;
+                
+        }
+        
 	*spec_dst = FIB_RES_PREFSRC(res);
 	fib_combine_itag(itag, &res);
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
--- linux-2.4.19/net/ipv4/ip_output.c	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/net/ipv4/ip_output.c	Sun Sep 15 21:19:45 2002
@@ -520,8 +520,18 @@
 		/*
 		 *	Get the memory we require with some space left for alignment.
 		 */
-
-		skb = sock_alloc_send_skb(sk, fraglen+hh_len+15, flags&MSG_DONTWAIT, &err);
+		if (!(flags & MSG_DONTWAIT) || nfrags == 0) {
+			skb = sock_alloc_send_skb(sk, fraglen + hh_len + 15,
+						  (flags & MSG_DONTWAIT), &err);
+		} else {
+			/* On a non-blocking write, we check for send buffer
+			 * usage on the first fragment only.
+			 */
+			skb = sock_wmalloc(sk, fraglen + hh_len + 15, 1,
+					   sk->allocation);
+			if (!skb)
+				err = -ENOBUFS;
+		}
 		if (skb == NULL)
 			goto error;
 
@@ -965,7 +975,11 @@
 			daddr = replyopts.opt.faddr;
 	}
 
+#ifdef CONFIG_NET_SENDTOSELF
+	if (ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->nh.iph->tos), sk->bound_dev_if))
+#else
 	if (ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->nh.iph->tos), 0))
+#endif
 		return;
 
 	/* And let IP do all the hard work.
--- linux-2.4.19/net/ipv4/tcp_ipv4.c	Fri Aug  2 17:39:46 2002
+++ linux-2.4.19.dev/net/ipv4/tcp_ipv4.c	Sun Sep 15 21:25:42 2002
@@ -865,21 +865,36 @@
 	return h&(TCP_SYNQ_HSIZE-1);
 }
 
+/** Netdevice ID can be wild-carded by making it zero.
+ */
 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, 
 					      struct open_request ***prevp,
 					      __u16 rport,
-					      __u32 raddr, __u32 laddr)
+					      __u32 raddr, __u32 laddr,
+                                              int netdevice_id)
 {
 	struct tcp_listen_opt *lopt = tp->listen_opt;
 	struct open_request *req, **prev;  
 
+        /* Will only take netdevice_id into the equation if neither are
+         * 0.  This should be backwards compatible with older code, and also
+         * let us connect to ourselves over external ports.  Otherwise, we
+         * get confused about which connection is the originator v/s the
+         * receiver of the open request. --Ben
+         */
 	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)];
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
 		if (req->rmt_port == rport &&
 		    req->af.v4_req.rmt_addr == raddr &&
 		    req->af.v4_req.loc_addr == laddr &&
-		    TCP_INET_FAMILY(req->class->family)) {
+		    TCP_INET_FAMILY(req->class->family)
+#ifdef CONFIG_NET_SENDTOSELF
+                    && ((!netdevice_id) || (!req->bound_dev_if) ||
+                     (req->bound_dev_if == netdevice_id))) {
+#else
+                   ) {
+#endif
 			BUG_TRAP(req->sk == NULL);
 			*prevp = prev;
 			return req; 
@@ -899,7 +914,10 @@
 	req->retrans = 0;
 	req->sk = NULL;
 	req->dl_next = lopt->syn_table[h];
-
+#ifdef CONFIG_NET_SENDTOSELF
+        req->bound_dev_if = sk->bound_dev_if;
+#endif
+        
 	write_lock(&tp->syn_wait_lock);
 	lopt->syn_table[h] = req;
 	write_unlock(&tp->syn_wait_lock);
@@ -979,7 +997,8 @@
 	struct sock *sk;
 	__u32 seq;
 	int err;
-
+        int netdevice_id = 0;
+        
 	if (skb->len < (iph->ihl << 2) + 8) {
 		ICMP_INC_STATS_BH(IcmpInErrors); 
 		return;
@@ -1048,9 +1067,13 @@
 		if (sk->lock.users != 0)
 			goto out;
 
+                if (skb->dev) {
+                        netdevice_id = skb->dev->ifindex;
+                }
+                
 		req = tcp_v4_search_req(tp, &prev,
 					th->dest,
-					iph->daddr, iph->saddr); 
+					iph->daddr, iph->saddr, netdevice_id);
 		if (!req)
 			goto out;
 
@@ -1394,7 +1417,7 @@
 #define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */
 #endif
 
-	/* Never answer to SYNs send to broadcast or multicast */
+	/* Never answer to SYNs sent to broadcast or multicast */
 	if (((struct rtable *)skb->dst)->rt_flags & 
 	    (RTCF_BROADCAST|RTCF_MULTICAST))
 		goto drop; 
@@ -1452,6 +1475,10 @@
 	req->af.v4_req.rmt_addr = saddr;
 	req->af.v4_req.opt = tcp_v4_save_options(sk, skb);
 	req->class = &or_ipv4;
+#ifdef CONFIG_NET_SENDTOSELF
+        req->bound_dev_if = sk->bound_dev_if;
+#endif
+        
 	if (!want_cookie)
 		TCP_ECN_create_request(req, skb->h.th);
 
@@ -1587,11 +1614,12 @@
 	struct iphdr *iph = skb->nh.iph;
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 	struct sock *nsk;
-
+        int device_id = tcp_v4_iif(skb);
+        
 	/* Find possible connection requests. */
 	req = tcp_v4_search_req(tp, &prev,
 				th->source,
-				iph->saddr, iph->daddr);
+				iph->saddr, iph->daddr, device_id);
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
 
@@ -1599,7 +1627,7 @@
 					  th->source,
 					  skb->nh.iph->daddr,
 					  ntohs(th->dest),
-					  tcp_v4_iif(skb));
+					  device_id);
 
 	if (nsk) {
 		if (nsk->state != TCP_TIME_WAIT) {

             reply	other threads:[~2002-09-18  6:42 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-18  6:47 Ben Greear [this message]
2002-09-18  6:44 ` [PATCH] Networking: send-to-self David S. Miller
2002-09-18  6:53 ` Ben Greear
2002-09-18  7:09 ` [PATCH] Networking: send-to-self [link to non-broken patch this time] Ben Greear
2002-09-18 22:55   ` David S. Miller
2002-09-18 23:20     ` Ben Greear
2002-09-19  1:28       ` David S. Miller
2002-09-19  2:07         ` Ben Greear
2002-09-19  2:01           ` David S. Miller
2002-09-19  3:04             ` Ben Greear
2002-09-27  1:00               ` [PATCH] Networking: send-to-self [link to non-broken patch this kuznet
2002-09-27  1:30                 ` Ben Greear
2002-09-27  3:36                   ` kuznet
2002-09-27  6:33                 ` Ben Greear
2002-09-27 15:01                   ` kuznet
2002-09-27 15:40                     ` Ben Greear
2002-09-27 15:46                       ` kuznet
2002-09-27 15:53                         ` Ben Greear
  -- strict thread matches above, loose matches on Subject: below --
2002-09-18 13:49 [PATCH] Networking: send-to-self Joerg Pommnitz
2002-09-18 16:51 ` Ben Greear

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3D88217A.6070702@candelatech.com \
    --to=greearb@candelatech.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.