lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1383958474-6255-2-git-send-email-nicolas.dichtel@6wind.com>
Date:	Sat,  9 Nov 2013 01:54:34 +0100
From:	Nicolas Dichtel <nicolas.dichtel@...nd.com>
To:	hannes@...essinduktion.org
Cc:	netdev@...r.kernel.org, davem@...emloft.net,
	David.Laight@...LAB.COM, jiri@...nulli.us, vyasevich@...il.com,
	kuznet@....inr.ac.ru, jmorris@...ei.org, yoshfuji@...ux-ipv6.org,
	kaber@...sh.net, thaller@...hat.com, stephen@...workplumber.org,
	Nicolas Dichtel <nicolas.dichtel@...nd.com>
Subject: [RFC PATCH net-next 2/2] udp: add sk opt to allow sending pkt with src 0.0.0.0

This feature allows to a send packets with address source set to 0.0.0.0 even if
an ip address is available on another interface.

It's useful for DHCP client, to allow them to use UDP sockets and be compliant
with the RFC2131, Section 4.1:

4.1 Constructing and sending DHCP messages
...
   DHCP messages broadcast by a client prior to that client obtaining
   its IP address must have the source address field in the IP header
   set to 0.

Based on a previous work from
Guillaume Gaudonville <guillaume.gaudonville@...nd.com>.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@...nd.com>
---
 include/linux/udp.h      |  3 ++-
 include/uapi/linux/udp.h |  1 +
 net/ipv4/udp.c           | 21 +++++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/include/linux/udp.h b/include/linux/udp.h
index 42278bbf7a88..ca947206f0fe 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -63,7 +63,8 @@ struct udp_sock {
 #define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
 #define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
 	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
-	__u8		 unused[3];
+	__u8		 src_any:1;	/* saddr to 0 when no IP is available */
+	__u8		 unused[2];
 	/*
 	 * For encapsulation sockets.
 	 */
diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
index e2bcfd75a30d..daf4a48face1 100644
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -29,6 +29,7 @@ struct udphdr {
 /* UDP socket options */
 #define UDP_CORK	1	/* Never send partially complete segments */
 #define UDP_ENCAP	100	/* Set the socket to accept encapsulated packets */
+#define UDP_SRC_ANY	101	/* Set src addr to 0 when no IP is available */
 
 /* UDP encapsulation types */
 #define UDP_ENCAP_ESPINUDP_NON_IKE	1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 89909dd730dd..f58945187dbd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -111,6 +111,7 @@
 #include <linux/static_key.h>
 #include <trace/events/skb.h>
 #include <net/busy_poll.h>
+#include <linux/inetdevice.h>
 #include "udp_impl.h"
 
 struct udp_table udp_table __read_mostly;
@@ -1015,6 +1016,18 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		goto do_confirm;
 back_from_confirm:
 
+	if (up->src_any && sk->sk_bound_dev_if) {
+		struct net_device *dev;
+		struct in_device *in_dev;
+
+		rcu_read_lock();
+		dev = dev_get_by_index_rcu(sock_net(sk), sk->sk_bound_dev_if);
+		in_dev = dev ? __in_dev_get_rcu(dev) : NULL;
+		if (!inet_confirm_addr(sock_net(sk), in_dev, 0, 0,
+				       RT_SCOPE_HOST))
+			fl4->saddr = 0;
+		rcu_read_unlock();
+	}
 	saddr = fl4->saddr;
 	if (!ipc.addr)
 		daddr = ipc.addr = fl4->daddr;
@@ -2045,6 +2058,10 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		up->pcflag |= UDPLITE_RECV_CC;
 		break;
 
+	case UDP_SRC_ANY:
+		up->src_any = val ? 1 : 0;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -2107,6 +2124,10 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		val = up->pcrlen;
 		break;
 
+	case UDP_SRC_ANY:
+		val = up->src_any;
+		break;
+
 	default:
 		return -ENOPROTOOPT;
 	}
-- 
1.8.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ