Page MenuHomeFreeBSD

IPv6 redirect doesn't work.
Needs ReviewPublic

Authored by steven_chen3_dell.com on Feb 2 2024, 10:43 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Jun 12, 11:43 AM
Unknown Object (File)
Mon, Jun 3, 7:04 AM
Unknown Object (File)
Tue, May 21, 2:52 AM
Unknown Object (File)
May 8 2024, 10:21 PM
Unknown Object (File)
May 7 2024, 3:00 AM
Unknown Object (File)
May 4 2024, 3:45 AM
Unknown Object (File)
Apr 27 2024, 9:42 AM
Unknown Object (File)
Apr 27 2024, 9:41 AM

Details

Reviewers
melifaro
Summary

If the redirect target isn't link local address, and redirect destination and redirect target address are the same,
the route install for redirect will fail.
In this cause, the type of gateway address is AF_LINK, the size of that address structure is 56 bytes, but the max size of store address of nhop
is only 28 bytes, which cause size check failure.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

steven_chen3_dell.com edited the summary of this revision. (Show Details)

Thank you for submitting the patch. I’m not sure I fully understand the problem and the solution.
Could you please provide some examples?

Thank you for your replying, first of all, I want to say sorry for replying to you so late because I was a bit busy recently. I give a test example here.

ex:

a router send a redirect icmp6:

Frame 8: 110 bytes on wire (880 bits), 110 bytes captured (880 bits) on interface unknown, id 0
Ethernet II, Src: Sytek_10:10:60 (00:00:10:10:10:60), Dst: Dell_10:ba:3a (6c:3c:8c:10:ba:3a)
Internet Protocol Version 6, Src: fe80::200:10ff:fe10:1060, Dst: 2001:2:0:1000:49f1:31ca:b020:fc0a
Internet Control Message Protocol v6

Type: Redirect (137)
Code: 0
Checksum: 0xcf90 [correct]
[Checksum Status: Good]
Reserved: 00000000
Target Address: 2001:2:0:1001:200:10ff:fe10:1180
Destination Address: 2001:2:0:1001:200:10ff:fe10:1180
ICMPv6 Option (Target link-layer address : 00:00:10:10:10:80)
ICMPv6 Option (Source link-layer address : 22:22:22:22:22:22)

after the host receive it, we expect a new redirect route table will be added:
2001:2:0:1001:200:10ff:fe10:1180 #link1

but the route is not added, the adding is prevented by function nhop_set_gw length check

the redirect icmp6 process:
icmp6_redirect_input -> rib_add_redirect -> nhop_set_gw

the param gw and is_gw of nhop_set_gw are transmitted by icmp6_redirect_inpu, the value is set in icmp6.c line 2285, code show below:

is_router = is_onlink = 0;
if (IN6_IS_ADDR_LINKLOCAL(&redtgt6))
        is_router = 1;  /* router case */
if (bcmp(&redtgt6, &reddst6, sizeof(redtgt6)) == 0)
        is_onlink = 1;  /* on-link destination case */

Target Address is 2001:2:0:1001:200:10ff:fe10:1180, is not linklocal, so is_route=0, and is_online = 1.

in icmp6.c line 3448:

if (is_router) {
        bzero(&sgw, sizeof(sgw));
        sgw.sin6_family = AF_INET6;
        sgw.sin6_len = sizeof(struct sockaddr_in6);
        bcopy(&redtgt6, &sgw.sin6_addr,
                sizeof(struct in6_addr));
        gw = (struct sockaddr *)&sgw;
        rt_flags |= RTF_GATEWAY;
} else
        gw = ifp->if_addr->ifa_addr;  //run here
for (fibnum = 0; fibnum < rt_numfibs; fibnum++)
        rib_add_redirect(fibnum, (struct sockaddr *)&sdst, gw,
            (struct sockaddr *)&ssrc, ifp, rt_flags,
            V_icmp6_redirtimeout);

the gw is ifa_addr, which is AF_LINK. so gw->sa_len is sizeof(struct sockaddr_dl_short), but in the nhop_set_gw, the length check compare with gw_buf length of struct nhop:

	 if (gw->sa_len > sizeof(nh->gw_buf)) {
           ...
        }

nh->gw_buf is defined with max size 28 bytes, but gw->sa_len is the size of struct sockaddr_dl_short which is 12 bytes. so the check return error.