Re: Question about netinet6/in6.h

Warner Losh <[email protected]>
Newsgroups gmane.os.freebsd.devel.net
Message-ID <CANCZdfqEf-TniYhp0Cyv_DnFeKcHKvxeRBotyLYgzN0Jcw5BcQ@mail.gmail.com>
On Fri, Apr 26, 2024, 9:33 PM Bakul Shah <[email protected]> wrote:

>
>
> > On Apr 26, 2024, at 5:02 PM, Mike Karels <[email protected]> wrote:
> >
> > On 26 Apr 2024, at 18:06, Warner Losh wrote:
> >
> >> On Fri, Apr 26, 2024 at 4:21 PM Mike Karels <[email protected]> wrote:
> >>
> >>> On 26 Apr 2024, at 15:49, Mike Karels wrote:
> >>>
> >>>> On 26 Apr 2024, at 15:01, Warner Losh wrote:
> >>>>
> >>>>> This has to be a FAQ
> >>>>>
> >>>>> I'm porting a program from Linux, I often see an error like:
> >>>>> ./test/mock-ifaddrs.c:95:19: error: no member named 's6_addr32' in
> >>> 'struct
> >>>>> in6_addr'
> >>>>>   95 |                 ipv6->sin6_addr.s6_addr32[3] = 0;
> >>>>>      |                 ~~~~~~~~~~~~~~~ ^
> >>>>> but yet, we kinda define them, but only for the kernel and boot
> loader:
> >>>>> /*
> >>>>> * IPv6 address
> >>>>> */
> >>>>> struct in6_addr {
> >>>>>        union {
> >>>>>                uint8_t         __u6_addr8[16];
> >>>>>                uint16_t        __u6_addr16[8];
> >>>>>                uint32_t        __u6_addr32[4];
> >>>>>        } __u6_addr;                    /* 128-bit IP6 address */
> >>>>> };
> >>>>>
> >>>>> #define s6_addr   __u6_addr.__u6_addr8
> >>>>> #if defined(_KERNEL) || defined(_STANDALONE) /* XXX nonstandard */
> >>>>> #define s6_addr8  __u6_addr.__u6_addr8
> >>>>> #define s6_addr16 __u6_addr.__u6_addr16
> >>>>> #define s6_addr32 __u6_addr.__u6_addr32
> >>>>> #endif
> >>>>>
> >>>>> I'm wondering if anybody why it's like that? git blame suggests we
> >>> imported
> >>>>> that from kame, with
> >>>>> only tweaks by people that are now deceased*.*
> >>>>>
> >>>>> Why not just expose them?
> >>>>
> >>>> Looks like only s6_addr is specified in the RFCs (2553 and 3493).
> Oddly,
> >>>> though, the RFCs give an example implementation using that union with
> >>>> different element names (like _S6_u8), and show the one #define.
> >>>> Similarly, POSIX specifies only s6_addr, but it allows other members
> >>>> of the structure, so I don't see a problem with exposing them all even
> >>>> in a POSIX environment.
> >>>>
> >>>> I would have no objection to exposing all four definitions, especially
> >>>> if Linux apps use them.
> >>>
> >>> I put the change, along with an explanatory comment, in
> >>> https://reviews.freebsd.org/D44979.  Comments welcome.
> >>>
> >>
> >> Thanks! I was testing a similar change, but I like yours better...
> though
> >> maybe
> >> we should just make it visible when __BSD_VISIBLE is true.... I'll have
> to
> >> look
> >> closely at what Linux does here... I think they have it always visible,
> or
> >> at least
> >> musl does that (glibc is harder to track down due to the many layers of
> >> indirection).
> >
> > I thought briefly about __BSD_VISIBLE, but wasn't sure it was necessary.
> > Let me know what you find out.  I think it should work either way; in.h
> > includes cdefs.h, so it's guaranteed to have been included.
>
> If the -ms-extensions option is used with gcc or clang, this ugliness can
> go away as you can have nested anonymous unions or -structs and their
> fields
> can be referenced as if they're directly in the parent struct/union.
>
> [IIRC this was present in Plan9 C from very early on. Also in C11 or later]


True. In fact c11 and newer doesn't need anything on the command line here.
If it were only in the kernel then I'd chamge it like thay while I was
here... but lots of code in ports will specify c99 + POSIX 2001 and to
compile there your only hope is this construct....

Warner
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.