On Thu, Sep 17, 2026 at 6:28 AM Jerome Forissier <[email protected]>
wrote:

> Hi Yuxiao,
>
> On 11/09/2026 00:32, Yuxiao Zhang wrote:
> > dhcpv6 is a special UDP traffic and should always use link local
> > addresses. Only pick net_ip6 if it is not empty and if it is not dhcp6.
> >
> > Signed-off-by: Yuxiao Zhang <[email protected]>
> > ---
> >
> >  net/net6.c | 13 ++++++++-----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> >
> > diff --git a/net/net6.c b/net/net6.c
> > index 4cff98df15c..18072bd9f49 100644
> > --- a/net/net6.c
> > +++ b/net/net6.c
> > @@ -330,6 +330,10 @@ int net_send_udp_packet6(uchar *ether, struct
> in6_addr *dest, int dport,
> >       uchar *pkt;
> >       struct udp_hdr *udp;
> >       u16 csum_p;
> > +     struct in6_addr *src =
> > +             (dport == 547 || ip6_is_unspecified_addr(&net_ip6)) ?
> > +                     &net_link_local_ip6 :
> > +                     &net_ip6;
>
> Rather than special-casing DHCPv6 based on dport == 547, I think this
> should be based on the destination address scope.
>
> For a link-local multicast destination, RFC 6724 source-address selection
> prefers a link-local source address, so something like:
>
> struct in6_addr *src =
>         (ip6_is_unspecified_addr(&net_ip6) ||
>          ip6_is_link_local_multicast(dest)) ?
>         &net_link_local_ip6 : &net_ip6;
>
> with:
>
> static bool ip6_is_link_local_multicast(const struct in6_addr *addr)
> {
>         return addr->s6_addr[0] == 0xff &&
>                (addr->s6_addr[1] & 0xf) == 0x2;
> }
>
> This should fix DHCPv6 while keeping the source-address selection in the
> IPv6 layer rather than making generic UDP code aware of DHCP port numbers.
>
> What do you think?
>
> >       udp = (struct udp_hdr *)((uchar *)net_tx_packet +
> net_eth_hdr_size() +
> >                       IP6_HDR_SIZE);
> > @@ -341,7 +345,7 @@ int net_send_udp_packet6(uchar *ether, struct
> in6_addr *dest, int dport,
> >       /* checksum */
> >       udp->udp_xsum = 0;
> >       csum_p = csum_partial((u8 *)udp, len + UDP_HDR_SIZE, 0);
> > -     udp->udp_xsum = csum_ipv6_magic(&net_ip6, dest, len + UDP_HDR_SIZE,
> > +     udp->udp_xsum = csum_ipv6_magic(src, dest, len + UDP_HDR_SIZE,
> >                                       IPPROTO_UDP, csum_p);
> >
> >       /* if MAC address was not discovered yet, save the packet and do
> > @@ -353,8 +357,8 @@ int net_send_udp_packet6(uchar *ether, struct
> in6_addr *dest, int dport,
> >
> >               pkt = net_nd_tx_packet;
> >               pkt += net_set_ether(pkt, net_nd_packet_mac, PROT_IP6);
> > -             pkt += ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_UDP, 64,
> > -                             len + UDP_HDR_SIZE);
> > +             pkt += ip6_add_hdr(pkt, src, dest, IPPROTO_UDP, 64,
> > +                                len + UDP_HDR_SIZE);
> >               memcpy(pkt, (uchar *)udp, len + UDP_HDR_SIZE);
> >
> >               /* size of the waiting packet */
> > @@ -370,8 +374,7 @@ int net_send_udp_packet6(uchar *ether, struct
> in6_addr *dest, int dport,
> >
> >       pkt = (uchar *)net_tx_packet;
> >       pkt += net_set_ether(pkt, ether, PROT_IP6);
> > -     pkt += ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_UDP, 64,
> > -                     len + UDP_HDR_SIZE);
> > +     pkt += ip6_add_hdr(pkt, src, dest, IPPROTO_UDP, 64, len +
> UDP_HDR_SIZE);
> >       (void)eth_send(net_tx_packet, pkt - net_tx_packet + UDP_HDR_SIZE +
> len);
> >
> >       return 0;       /* transmitted */
> > ---
> > base-commit: b4ac71db13a33c4e6532c60a781ddf34b7f4375a
> > branch: main
> >
>
> Thanks,
> --
> Jerome
>

Yes this makes sense and it is a more generic fix. I will send another
version.

Thanks,
Yuxiao

Reply via email to