Stuart Henderson <s...@spacehopper.org> writes:

> On 2017/01/20 11:40, Marc Peters wrote:
>> Hi,
>> 
>> the attached patch fixes the interface index for dhcpv6 answers on
>> OpenBSD. It is based on the patch from
>> https://marc.info/?l=openbsd-misc&m=144067760416819&w=2
>> 
>> Without the patch, every request will create a log entry with no route
>> to host:
>> Jan 20 11:05:50 infra1-DG dhcpd: send_packet6: No route to host
>> Jan 20 11:05:50 infra1-DG dhcpd: dhcpv6: send_packet6() sent -1 of 133 bytes

I hit this bug some months/years ago but forgot to fix it. :-/

>> Comments, oks?
>
>> Index: patches/patch-common_socket_c
>> ===================================================================
>> RCS file: patches/patch-common_socket_c
>> diff -N patches/patch-common_socket_c
>> --- /dev/null        1 Jan 1970 00:00:00 -0000
>> +++ patches/patch-common_socket_c    20 Jan 2017 09:39:19 -0000
>> @@ -0,0 +1,21 @@
>> +--- common/socket.c.orig    Thu Jan 19 15:55:02 2017
>> ++++ common/socket.c Thu Jan 19 15:58:34 2017
>> +@@ -793,9 +793,18 @@
>> +    memcpy(&dst, to, sizeof(dst));
>> +    m.msg_name = &dst;
>> +    m.msg_namelen = sizeof(dst);
>> ++
>> ++   /*
>> ++    * For OpenBSD, needing interface index.
>> ++    * The preprocessor test is added . . .
>> ++    */
>> ++   #if defined(__OpenBSD__)
>> ++           dst.sin6_scope_id = ifindex = if_nametoindex(interface->name);
>> ++   #else  /* ! defined(__OpenBSD__) */
>> +    ifindex = if_nametoindex(interface->name);
>> +    if (no_global_v6_socket)
>> +            dst.sin6_scope_id = ifindex;
>> ++   #endif /* ! defined(__OpenBSD__) */
>> + 
>> +    /*
>> +     * Set the data buffer we're sending. (Using this wacky 
>
> Here is the upstream code with more context.
>
>  789         /*
>  790          * Set the target address we're sending to.
>  791          * Enforce the scope ID for bogus BSDs.
>  792          */
>  793         memcpy(&dst, to, sizeof(dst));
>  794         m.msg_name = &dst;
>  795         m.msg_namelen = sizeof(dst);
>  796         ifindex = if_nametoindex(interface->name);
>  797         if (no_global_v6_socket)
>  798                 dst.sin6_scope_id = ifindex;
>
> So, setting the scope ID is exactly what they are already trying to do.
> I don't really want to spend much time understanding code which they
> have marked as "XXX: this is gross. we need to go back and overhaul the
> API for socket handling". But it looks like they'd be expecting
> no_global_v6_socket to be set on a BSD which needs the scope id.

Whether no_global_v6_socket is true doesn't seem to depend on the OS: it
appears true when running dhclient, false when running dhcpd/dhcrelay;
see if_register_linklocal6().  This looks more like a lack of testing,
as it appears safe to set sin6_scope_id everywhere.

> Better if someone who already knows the code looks at it - can you
> bring this up on dhcp-users or somewhere similar?

I don't volunteer to move this to dhcp-users... yet.  Maybe the actual
fix is in our base system.  It *looks like* our kernel has indeed a bug,
it should use the ifindex in the cmsg.

> (Also preprocessor directives should start in column 1 so they're
> obvious..but this won't be an acceptable fix upstream anyway).

Indeed.

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to