[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH] udhcp: DHCPv6 and setting the link-local address
From:       Jackmcbarn <jackmcbarn+bb () gmail ! com>
Date:       2016-07-21 18:39:05
Message-ID: CAOx5P=Ks0cOP4eJBCnmMsuMvoy1_gdh-tej1k4C_+ua10Kq+Qg () mail ! gmail ! com
[Download RAW message or body]

I brought this issue up a while ago. I noticed that it isn't just not
setting these addresses, but also removing any that were already
present when it started. (This also affects "real" SLAAC addresses.)

On Tue, Jul 19, 2016 at 10:01 AM, Marc Seeger <mseeger@fb.com> wrote:
> Hey!
> 
> We noticed that the DHCPv6 client included with busybox does not set the IPv6 \
> link-local address of the interface as the source IP in \
> d6_mcast_from_client_config_ifindex(). RFC3315 mentions that:
> 
> a) In "4.1. IPv6 Terminology":
> "Every interface has a link-local address."
> 
> and
> 
> b) In "16. Client Source Address and Interface Selection":
> "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. 
> In the current codebase, udhcp sets the source address to NULL when it's calling \
> d6_send_raw_packet (--> \
> https://git.busybox.net/busybox/tree/networking/udhcp/d6_dhcpc.c#n314). While this \
> isn't quite RFC conform as far as I can tell, it seems to work fine with most \
> switches. We did however see some cases where the switch doesn't correctly forward \
> DHCP responses back to the client if the link local address is missing. 
> I created a patch that parses the address from /proc/net/if_inet6 and we've been \
> running it in production successfully for a few weeks. A lot of the code is taken \
> from ife_print6() in interface.c and could probably be abstracted and reused. 
> I don't think it's quite ready to be merged yet, but I just wanted to gather some \
> initial feedback/concerns. Things like: Do we want to fall back to the old "just \
> use NULL" approach if we fail to discover a link local address for whatever reason? \
>  Cheers,
> Marc
> 
> 
> 
> diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
> index 345ca5e..eda474a 100644
> --- a/networking/udhcp/d6_dhcpc.c
> +++ b/networking/udhcp/d6_dhcpc.c
> @@ -434,9 +434,65 @@ static int d6_mcast_from_client_config_ifindex(struct \
> d6_packet *packet, uint8_t 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
> };
> 
> +       #define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
> +       #define IPV6_ADDR_LINKLOCAL             0x0020U
> +       #define IPV6_ADDR_SCOPE_MASK            0x00f0U
> +
> +       FILE *f;
> +       char addr6[40], devname[21];
> +       struct sockaddr_in6 sap;
> +       int plen, scope, dad_status, if_idx;
> +       char addr6p[8][5];
> +       int link_local_parsing_success = 0;
> +
> +       f = fopen_for_read(_PATH_PROCNET_IFINET6);
> +       if (f == NULL){
> +               log1("Could not find /proc/net/if_inet6, can't set link local addr, \
> not sending package."); +               return;
> +       }
> +       // cat /proc/net/if_inet6
> +       // 00000000000000000000000000000001 01 80 10 80       lo
> +       // 2401db000020a01eface000000230000 02 40 00 80     eth0
> +       // fe8000000000000062eb69fffe9bb5c2 02 40 20 80     eth0
> +       // Iterate over every one of those lines and extract the parts into \
> variables +       while (fscanf
> +                          (f,"%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x \
> %20s\n", +                       addr6p[0], addr6p[1], addr6p[2], addr6p[3], \
> addr6p[4], +                       addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, \
> &scope, +                       &dad_status, devname) != EOF
> +       ) {
> +               // check that it's the interface we're currently listening on
> +               if (!strcmp(devname, client_config.interface)) {
> +                       // See if it's link-local. if not we don't care
> +                       // about it at this point
> +                       if ((scope & IPV6_ADDR_SCOPE_MASK) == IPV6_ADDR_LINKLOCAL) \
> { +                               // Re-assemble the readable v6 address into addr6
> +                               sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
> +                                               addr6p[0], addr6p[1], addr6p[2], \
> addr6p[3], +                                               addr6p[4], addr6p[5], \
> addr6p[6], addr6p[7]); +                               log1("Found Link Local \
> address for %s: %s", devname, addr6); +                               // Set the \
> socket address to all zeros +                               memset(&sap, 0, \
> sizeof(sap)); +                               // Convert the printable v6 address \
> to the binary equivalent +                               // and write it to the \
> sockaddr_in6 struct into &sap.sin6_addr +                               \
> inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr); +                   \
> // Set the family to v6 just to have a proper data structure +                      \
> sap.sin6_family = AF_INET6; +                               // Cool, we found what \
> we're looking for. Our work here is done! +                               \
> link_local_parsing_success = 1; +                               break;
> +                       }
> +               }
> +       }
> +       fclose(f);
> +
> +       if (link_local_parsing_success == 0) {
> +               log1("Could not find link local addr among interfaces, not sending \
> package."); +               return;
> +       }
> return d6_send_raw_packet(
> packet, (end - (uint8_t*) packet),
> -               /*src*/ NULL, CLIENT_PORT6,
> +               /*src*/ (struct in6_addr*)&sap.sin6_addr, CLIENT_PORT6,
> /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR,
> client_config.ifindex
> );
> _______________________________________________
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic