Re: [PATCH] udhcpc6 source address is null, should be link-local address

2013-08-21 Thread Ralf Friedl

Denys Vlasenko wrote:

But what if interface has no IPv6 addresses?
Isn't the whole purpose of DHCP is to *acquire an address*?

For example, I don't use or need IPv6 for now.
I just checked, and as expected, none of my interfaces have
any IPv6 addresses.

What should happen in this case?
Does an iface absolutely need a link-local address (and how
to acquire one?).
If not, what dhcp client should fill in - all zeros?
If yes, why can't it just always do that?

From RFC 4862:

link-local address -  an address having link-only scope that can be used to 
reach neighboring nodes attached to the same link.  All interfaces have a 
link-local unicast address.


From RFC 4291:

  Links or Nodes with IEEE 802 48-bit MACs

EUI64  defines a method to create an IEEE EUI-64 identifier from an
   IEEE 48-bit MAC identifier.  This is to insert two octets, with
   hexadecimal values of 0xFF and 0xFE (see the Note at the end of
   appendix), in the middle of the 48-bit MAC (between the company_id
   and vendor-supplied id).  An example is the 48-bit IEEE MAC with
   Global scope:

   |0  1|1  3|3  4|
   |0  5|6  1|2  7|
   ++++
   |cc0g|||
   ++++


   where c is the bits of the assigned company_id, 0 is the value of
   the universal/local bit to indicate Global scope, g is
   individual/group bit, and m is the bits of the manufacturer-
   selected extension identifier.  The interface identifier would be of
   the form:

   |0  1|1  3|3  4|4  6|
   |0  5|6  1|2  7|8  3|
   +++++
   |cc1g||1110||
   +++++

   When IEEE 802 48-bit MAC addresses are available (on an interface or
   a node), an implementation may use them to create interface
   identifiers due to their availability and uniqueness properties.


___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] udhcpc6 source address is null, should be link-local address

2013-08-20 Thread Denys Vlasenko
On Monday 19 August 2013 09:32, Mathias Krüger wrote:
 Okay, then here is the second try ;)

$ patch -p1 /tmp/z.patch --dry-run
patching file networking/udhcp/d6_common.h
Hunk #1 FAILED at 91.
1 out of 1 hunk FAILED -- saving rejects to file 
networking/udhcp/d6_common.h.rej
patching file networking/udhcp/d6_dhcpc.c
patch:  malformed patch at line 118: code)

With some obvious line wrap fixes:

$ patch -p1 /tmp/z.patch --dry-run
patching file networking/udhcp/d6_common.h
Hunk #1 FAILED at 91.
1 out of 1 hunk FAILED -- saving rejects to file 
networking/udhcp/d6_common.h.rej
patching file networking/udhcp/d6_dhcpc.c
Hunk #2 succeeded at 91 with fuzz 1.
Hunk #3 FAILED at 344.
Hunk #4 FAILED at 1034.
Hunk #5 FAILED at 1142.
3 out of 5 hunks FAILED -- saving rejects to file 
networking/udhcp/d6_dhcpc.c.rej

Usually people send patches as attachments if there are doubts
whether their mail clients are able to not mangle patches.
-- 
vda
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH] udhcpc6 source address is null, should be link-local address

2013-08-20 Thread Denys Vlasenko
On Monday 19 August 2013 09:32, Mathias Krüger wrote:
 Okay, then here is the second try ;)

Here is a cleaned-up version of the patch (attached).

But what if interface has no IPv6 addresses?
Isn't the whole purpose of DHCP is to *acquire an address*?

For example, I don't use or need IPv6 for now.
I just checked, and as expected, none of my interfaces have
any IPv6 addresses.

What should happen in this case?
Does an iface absolutely need a link-local address (and how
to acquire one?).
If not, what dhcp client should fill in - all zeros?
If yes, why can't it just always do that?

I'm happy to see some people actually using udhcpc6
- it definitely needs to be finished and debugged,
which can be done only in real ipv6 environment.

-- 
vda
diff -ad -urpN busybox.0/networking/udhcp/d6_common.h busybox.1/networking/udhcp/d6_common.h
--- busybox.0/networking/udhcp/d6_common.h	2013-07-25 03:48:31.0 +0200
+++ busybox.1/networking/udhcp/d6_common.h	2013-08-20 22:54:29.0 +0200
@@ -91,6 +91,7 @@ struct client6_data_t {
 	struct d6_option *ia_na;
 	char **env_ptr;
 	unsigned env_idx;
+	struct in6_addr lladdr;
 };
 
 #define client6_data (*(struct client6_data_t*)(bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)]))
diff -ad -urpN busybox.0/networking/udhcp/d6_dhcpc.c busybox.1/networking/udhcp/d6_dhcpc.c
--- busybox.0/networking/udhcp/d6_dhcpc.c	2013-07-25 03:48:31.0 +0200
+++ busybox.1/networking/udhcp/d6_dhcpc.c	2013-08-20 22:58:29.0 +0200
@@ -34,6 +34,8 @@
 #include netinet/if_ether.h
 #include netpacket/packet.h
 #include linux/filter.h
+#include net/if.h
+#include ifaddrs.h
 
 /* struct client_config_t client_config is in bb_common_bufsiz1 */
 
@@ -89,6 +91,44 @@ enum {
 
 /*** Utility functions ***/
 
+/* RFC 3315, section 16, says:
+ * The client MUST use a link-local address assigned to the interface for which
+ *  it is requesting configuration information as the source address in the header
+ *  of the IP datagram.
+ * - unlike DHCP for IPv4, where source ip if 0.0.0.0 is happily used.
+ * This helper reads link-local address for client_config.interface.
+ *
+ * TODO: what if interface has no IPv6 link-local address??
+ * For one, my ifaces definitely don't have any such addresses.
+ */
+static int d6_get_lladdr(void)
+{
+	struct sockaddr_in6 *our_ip6;
+	struct ifaddrs *ifap, *ife;
+
+	if (getifaddrs(ifap)  0)
+		goto err;
+
+	for (ife = ifap; ife; ife = ife-ifa_next) {
+		if (strcmp(client_config.interface, ife-ifa_name) != 0)
+			continue;
+		if (!ife-ifa_addr)
+			continue;
+		if (ife-ifa_addr-sa_family != AF_INET6)
+			continue;
+		our_ip6 = ((struct sockaddr_in6 *)ife-ifa_addr);
+		if (IN6_IS_ADDR_LINKLOCAL(our_ip6-sin6_addr)) {
+			client6_data.lladdr = our_ip6-sin6_addr;
+			freeifaddrs(ifap);
+			return 0;
+		}
+	}
+
+ err:
+	bb_error_msg(%s has no link-local address, client_config.interface);
+	return -1;
+}
+
 static void *d6_find_option(uint8_t *option, uint8_t *option_end, unsigned code)
 {
 	/* length minus 4 */
@@ -311,7 +351,7 @@ static int d6_mcast_from_client_config_i
 
 	return d6_send_raw_packet(
 		packet, (end - (uint8_t*) packet),
-		/*src*/ NULL, CLIENT_PORT6,
+		/*src*/ client6_data.lladdr, CLIENT_PORT6,
 		/*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR,
 		client_config.ifindex
 	);
@@ -1001,6 +1041,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, 
 	) {
 		return 1;
 	}
+	if (d6_get_lladdr())
+		return 1;
 
 	/* Create client ID based on mac, set clientid_mac_ptr */
 	{
@@ -1104,6 +1146,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, 
 			) {
 goto ret0; /* iface is gone? */
 			}
+			if (d6_get_lladdr())
+goto ret0; /* no link local address */
 			memcpy(clientid_mac_ptr, client_config.client_mac, 6);
 
 			/* We will restart the wait in any case */
diff -ad -urpN busybox.0/networking/udhcp/d6_packet.c busybox.1/networking/udhcp/d6_packet.c
--- busybox.0/networking/udhcp/d6_packet.c	2013-07-25 03:48:31.0 +0200
+++ busybox.1/networking/udhcp/d6_packet.c	2013-08-20 22:54:01.0 +0200
@@ -84,7 +84,7 @@ int FAST_FUNC d6_send_raw_packet(
 	}
 
 	packet.ip6.ip6_vfc = (6  4); /* 4 bits version, top 4 bits of tclass */
-	if (src_ipv6)
+	/*if (src_ipv6) - always non-NULL*/
 		packet.ip6.ip6_src = *src_ipv6; /* struct copy */
 	packet.ip6.ip6_dst = *dst_ipv6; /* struct copy */
 	packet.udp.source = htons(source_port);
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH] udhcpc6 source address is null, should be link-local address

2013-08-20 Thread Denys Vlasenko
On Tuesday 20 August 2013 23:12, Matt Whitlock wrote:
 On Tuesday, 20 August 2013, at 11:10 pm, Denys Vlasenko wrote:
  But what if interface has no IPv6 addresses?
  Isn't the whole purpose of DHCP is to *acquire an address*?
 
 Interfaces that support IPv6 addressing should automatically
 have IPv6 link-local addresses assigned by the kernel.
 This happens on every modern system I've ever used.
 If you're not seeing IPv6 link-local addresses on your interfaces,
 it's probably because your kernel does not support IPv6.
 If you have a modular kernel, try loading the ipv6 module. 

I manually configured one IPv6 address, on loopback:

# ip a
1: lo: LOOPBACK,UP,1 mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope hostTHIS ONE
   valid_lft forever preferred_lft forever
2: if: NO-CARRIER,BROADCAST,MULTICAST,UP mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:1d:7d:c2:ec:70 brd ff:ff:ff:ff:ff:ff
inet 169.254.0.1/16 brd 169.254.255.255 scope global if
inet 192.168.0.1/24 brd 192.168.0.255 scope global if
3: wifi0: BROADCAST,MULTICAST,UP,1 mtu 1500 qdisc pfifo_fast qlen 1000
link/ieee802.11 00:09:5b:69:17:c8 brd ff:ff:ff:ff:ff:ff
4: wlan0: BROADCAST,MULTICAST,UP,1 mtu 1500 qdisc noqueue
link/ether 00:09:5b:69:17:c8 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.7/24 brd 10.0.0.255 scope global wlan0

As you see, other ifaces are up too but have no IPv6 addresses whatsoever.

My kernel definitely has IPv6 enabled (non-modular):
 
# grep IPV6 .config
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
CONFIG_IPV6_MIP6=m
CONFIG_IPV6_SIT=m
# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_GRE is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_IPV6_MROUTE is not set
CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_NF_NAT_IPV6=m

Anyway, from the kernel sources I see that IPv6 autoconfiguration
can be disabled. Therefore, reradles of why my system doesn't do
autoconfiguraion the question remains:
what udhcpc6 should do in this case?

-- 
vda
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox