An application that joins an IPv6 multicast group without performing an IPV6_MULTICAST_IF setsockopt() will see packets sent to the wrong MAC address. According to RFC2464 section 7 [1], the MAC should be 33:33:DST[13]:DST[14]:DST[15]:DST[16], but FreeBSD is sending to 33:33:last:four:of:gateway. Setting IPV6_MULTICAST_IF results in the expected destination MAC. My uneducated analysis - It looks to me like this is because setting IPV6_MULTICAST_IF bypasses (sys/netinet6/ip6_output.c:753) the routing code that would otherwise modify the destination IP to be the gateway. I expect what's missing is the equivalent of sys/netinet/ip_output.c:551 where the destination is restored to be the multicast address after the routing decision is made: /* * IP destination address is multicast. Make sure "gw" * still points to the address in "ro". (It may have been * changed to point to a gateway address, above.) */ gw = (const struct sockaddr *)dst; [1] https://datatracker.ietf.org/doc/html/rfc2464#section-7
I have a test program which shows 13.3 multicast reaching 14.1 but the 14.1 packets do not reach 13.3 The program tests ipv4 or ipv6. It was working fine when written for 13.1 years ago. So, anyhow, I think I've hit this problem.
(In reply to antonfb from comment #1) Is it possible to share the test program?
Created attachment 253704 [details] test case program My test program attached. NOTE: You need to modify it with your /64 address in the location with a comment. Here's some of my truss output with concurrent runs on 13.4 and 14.1 the 14.1 machine... (command "hive foo" i.e. one argument to cause ipv6 case...) NOTE this receives the multicast messages... socket(PF_INET6,SOCK_DGRAM,0) = 3 (0x3) bind(3,{ AF_INET6 [::]:3412 },28) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,0x8209f444c,4) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_MULTICAST_LOOP,0x8209f444c,4) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_JOIN_GROUP,0x8209f4438,20) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 4.999998 }) = 1 (0x1) recvfrom(3,"This is a test",200,0,{ AF_INET6 [2001:5a8:60c8:1e00:8647:9ff:fe2e:141a]:3412 },0x8209f433c) = 14 (0xe) fstat(1,{ mode=crw--w---- ,inode=379,size=0,blksize=4096 }) = 0 (0x0) ioctl(1,TIOCGETA,0x8209f3ac4) = 0 (0x0) 2001:5a8:60c8:1e00:8647:9ff:fe2e:141a 3412 This is a test write(1,"2001:5a8:60c8:1e00:8647:9ff:fe2e"...,58) = 58 (0x3a) select(4,{ 3 },0x0,0x0,{ 4.678515 }) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) The 13.4 machine... same command run, one argument to cause ipv6 NOTE this does not receive messages from the 14.1 machine socket(PF_INET6,SOCK_DGRAM,0) = 3 (0x3) bind(3,{ AF_INET6 [::]:3412 },28) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,0x820ada4dc,4) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_MULTICAST_LOOP,0x820ada4dc,4) = 0 (0x0) setsockopt(3,IPPROTO_IPV6,IPV6_JOIN_GROUP,0x820ada4c8,20) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 4.999999 }) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 4.999999 }) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 4.999999 }) = 0 (0x0) sendmsg(3,{{ AF_INET6 [ff34:40:2001:5a8:60c8:1e00:2:1]:3412 },28,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 4.999999 }) = 0 (0x0) For completeness... the ipv4 runs work. 14.1 machine... socket(PF_INET,SOCK_DGRAM,0) = 3 (0x3) bind(3,{ AF_INET 0.0.0.0:3412 },16) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_MULTICAST_TTL,0x821026d5c,4) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_MULTICAST_LOOP,0x821026d5c,4) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_ADD_MEMBERSHIP,0x821026d48,8) = 0 (0x0) sendmsg(3,{{ AF_INET 239.1.0.1:3412 },16,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 1 (0x1) recvfrom(3,"This is a test",200,0,{ AF_INET 192.168.2.5:3412 },0x821026c4c) = 14 (0xe) fstat(1,{ mode=crw--w---- ,inode=379,size=0,blksize=4096 }) = 0 (0x0) ioctl(1,TIOCGETA,0x8210263d4) = 0 (0x0) 192.168.2.5 3412 This is a test write(1,"192.168.2.5 3412 This is a test"...,32) = 32 (0x20) select(4,{ 3 },0x0,0x0,{ 4.998028 }) = 0 (0x0) sendmsg(3,{{ AF_INET 239.1.0.1:3412 },16,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 1 (0x1) recvfrom(3,"This is a test",200,0,{ AF_INET 192.168.2.5:3412 },0x821026c4c) = 14 (0xe) 192.168.2.5 3412 This is a test 13.2 machine... socket(PF_INET,SOCK_DGRAM,0) = 3 (0x3) bind(3,{ AF_INET 0.0.0.0:3412 },16) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_MULTICAST_TTL,0x8205725ec,4) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_MULTICAST_LOOP,0x8205725ec,4) = 0 (0x0) setsockopt(3,IPPROTO_IP,IP_ADD_MEMBERSHIP,0x8205725d8,8) = 0 (0x0) sendmsg(3,{{ AF_INET 239.1.0.1:3412 },16,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 0 (0x0) sendmsg(3,{{ AF_INET 239.1.0.1:3412 },16,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 0 (0x0) sendmsg(3,{{ AF_INET 239.1.0.1:3412 },16,[{"This is a test",14}],1,{},0,0},0) = 14 (0xe) select(4,{ 3 },0x0,0x0,{ 5.000000 }) = 1 (0x1) recvfrom(3,"This is a test",200,0,{ AF_INET 192.168.2.3:3412 },0x8205724dc) = 14 (0xe) fstat(1,{ mode=crw--w---- ,inode=381,size=0,blksize=4096 }) = 0 (0x0) ioctl(1,TIOCGETA,0x820571c64) = 0 (0x0) 192.168.2.3 3412 This is a test