IPv6 multicast packet size

Hideki Yamamoto hyama99 at gmail.com
Sat Feb 27 06:31:54 UTC 2010


Hi,

I have found the answer to my question.
The following lines resolved my problem.

	sock_optval=0;
	error = setsockopt(send_s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
                         &sock_optval, sizeof(sock_optval));

2010/2/22 Hideki Yamamoto <hyama99 at gmail.com>:
> Hi,
>
> I have encountered IPv6 multicast problem.
> I cannot send UDP packet longer than Shortest MTU.
> It seems the bug of IPv6 multicast kernel.
> I used the same application from FreeBSD 4.11. On that old version,
> any problems happens.  When I would like to change the platform of
> this application from 4.11 to 7.2 or later, I encountered this
> problem.
> Does anyone have any information about this problem?
>
> The followings are OS information I have tested, the result of
> Tshark command, and source code of test program.
>
> Best regards,
>
> Hideki Yamamoto
>
> --------------------------------------------------------------------------
> OS information
> --------------------------------------------------------------------------
> # sysctl -a |grep v6
> net.inet.tcp.v6mssdflt: 1024
> net.inet6.ip6.v6only: 1
> # sysctl -a |grep mtu
> net.inet.tcp.path_mtu_discovery: 1
> net.inet.sctp.pmtu_raise_time: 600
> net.inet6.ip6.mcast_pmtu: 0
> # uname -a
> FreeBSD tulip 9.0-CURRENT FreeBSD 9.0-CURRENT #16: Fri Jan 15 05:25:24
> JST 2010     root at tulip:/usr/obj/usr/src/sys/tulip8  i386
> tulip#
>
> --------------------------------------------------------------------------
> Tshark output that shows the packets are devided into two packtet when
> delivering 1400 byte lenghth packets.
> --------------------------------------------------------------------------
> # ./udp -s 1400 -o &
> # tshark -VV -i fxp1 host ff3e::9800:600 |grep -v aaaaaaaaa
> Capturing on fxp1
> Frame 1 (1294 bytes on wire, 1294 bytes captured)
>   Arrival Time: Feb 21, 2010 17:35:08.560297000
>   [Time delta from previous captured frame: 0.000000000 seconds]
>   [Time delta from previous displayed frame: 0.000000000 seconds]
>   [Time since reference or first frame: 0.000000000 seconds]
>   Frame Number: 1
>   Frame Length: 1294 bytes
>   Capture Length: 1294 bytes
>   [Frame is marked: False]
>   [Protocols in frame: eth:ipv6:data]
> Ethernet II, Src: Intel_89:d6:d9 (00:d0:b7:89:d6:d9), Dst:
> IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>   Destination: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>       Address: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>       .... ...1 .... .... .... .... = IG bit: Group address
> (multicast/broadcast)
>       .... ..1. .... .... .... .... = LG bit: Locally administered
> address (this is NOT the factory default)
>   Source: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
>       Address: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
>       .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
>       .... ..0. .... .... .... .... = LG bit: Globally unique address
> (factory default)
>   Type: IPv6 (0x86dd)
> Internet Protocol Version 6
>   0110 .... = Version: 6
>       [0110 .... = This field makes the filter "ip.version == 6" possible: 6]
>   .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000
>   .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000
>   Payload length: 1240
>   Next header: IPv6 fragment (0x2c)
>   Hop limit: 1
>   Source: 2001:2a0:806:206:2d0:b7ff:fe89:d6d9
> (2001:2a0:806:206:2d0:b7ff:fe89:d6d9)
>   Destination: ff3e::9800:600 (ff3e::9800:600)
>   Fragmentation Header
>       Next header: UDP (0x11)
>       0000 0000 0000 0... = Offset: 0 (0x0000)
>       .... .... .... ...1 = More Fragment: Yes
>       Identification: 0xc31d92fa
> Data (1232 bytes)
>
> 0000  5d 61 46 50 05 80 b0 d6 61 61 61 61 61 61 61 61   ]aFP....aaaaaaaa
>   Data: 5D6146500580B0D661616161616161616161616161616161...
>   [Length: 1232]
>
> Frame 2 (238 bytes on wire, 238 bytes captured)
>   Arrival Time: Feb 21, 2010 17:35:08.560324000
>   [Time delta from previous captured frame: 0.000027000 seconds]
>   [Time delta from previous displayed frame: 0.000027000 seconds]
>   [Time since reference or first frame: 0.000027000 seconds]
>   Frame Number: 2
>   Frame Length: 238 bytes
>   Capture Length: 238 bytes
>   [Frame is marked: False]
>   [Protocols in frame: eth:ipv6:udp:data]
> Ethernet II, Src: Intel_89:d6:d9 (00:d0:b7:89:d6:d9), Dst:
> IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>   Destination: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>       Address: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
>       .... ...1 .... .... .... .... = IG bit: Group address
> (multicast/broadcast)
>       .... ..1. .... .... .... .... = LG bit: Locally administered
> address (this is NOT the factory default)
>   Source: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
>       Address: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
>       .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
>       .... ..0. .... .... .... .... = LG bit: Globally unique address
> (factory default)
>   Type: IPv6 (0x86dd)
>
> ------
> /**********************************************************************
> udp.c (modified for MC Send Support)
> ***********************************************************************/
> #include <sys/param.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <sys/ioctl.h>
> #include <net/if.h>
> #include <netinet/in.h>
> #include <netdb.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <err.h>
> #include <errno.h>
> #include <ifaddrs.h>
>
>  // Modify send_addr to Multicast Address
> char *send_addr="ff3e::9800:600";
> char *send_port="18000";
>
> char *recv_addr="2001:99::1";
> char *recv_port="16000";
> int send_s;
> int only_out=0;
> int only_in=0;
> int out_packet_size;
> struct addrinfo *send_res;
>
> // Add for MC support
> char *out_if="fxp1";
>
> main(ac,av)
> int ac;
> char **av;
> {
>   int c;
>
>   while ((c = getopt(ac, av, "s:oi")) != -1) {
>       switch (c) {
>       case 'o':
>           only_out++;
>           break;
>       case 'i':
>           only_in++;
>           break;
>       case 's':
>           out_packet_size = atoi(optarg);
>           break;
>       default:
>           Usage();
>           exit (1);
>       }
>   }
>   if( only_in && only_out ){
>       Usage();
>       exit (1);
>   }
>
>   if( only_in == 0 ){
>       create_send_socket();
>       send_v6_udp();
>       exit;
>   }
>   recv_v6_udp();
> }
> Usage()
> {
>   printf("Usage: udpgw [-o][-i][-s output_packet_size]\n");
>
> }
> create_send_socket()
> {
>   struct addrinfo hints;
>   int error;
>   struct sockaddr_in6 *sin6;// Add for MC Support
>   int ifindex;// Add for MC Support
>
>
>   memset(&hints, 0, sizeof(hints));
>   hints.ai_family = PF_UNSPEC;
>   hints.ai_socktype = SOCK_DGRAM;
>   error = getaddrinfo(send_addr, send_port, &hints, &send_res);
>   if (error != 0) errx(1, "%s", gai_strerror(error));
>   send_res->ai_family = AF_INET6;
>   send_s = socket(send_res->ai_family, send_res->ai_socktype,
>                   send_res->ai_protocol);
>   if (send_s < 0) err(1, "socket");
>
> // Add for MC support
>   sin6 = (struct sockaddr_in6 *)send_res->ai_addr;
>   if(IN6_IS_ADDR_MULTICAST(&(sin6->sin6_addr))) {
>       if ( (ifindex = if_nametoindex(out_if)) == 0 ){
>           err(1, "socket-MC");
>       }
>       error = setsockopt(send_s, IPPROTO_IPV6, IPV6_MULTICAST_IF,
>                          &ifindex, sizeof(ifindex));
>       if (error < 0){
>           err(1, "socket-MC");
>       }
>   }
>
> }
> send_v6_udp()
> {
>   int len,cc,i;
>   char buf[2000];
>
>   for( i=0; i<2000 ; i++ ){
>       buf[i]='a';
>   }
>   if(  1501 > out_packet_size ){
>       cc = out_packet_size ;
>   }else{
>       cc = 1500;
>   }
>   printf("Let's send %d length packet to %s\n",cc,send_addr);
>   while(1){
>       len = sendto(send_s, buf, cc, 0, send_res->ai_addr,
> send_res->ai_addrlen);
>       sleep(1);
>   }
> }
>
> recv_v6_udp()
> {
>   int recv_s;
>   struct addrinfo hints, *res;
>   int error;
>   int len,cc,ccout;
>   char buf[2000];
>   FILE *outfp=stdout;
>   int fromlen;
>   struct sockaddr_in6 from6;
>
>   memset(&hints, 0, sizeof(hints));
>   hints.ai_family = PF_UNSPEC;
>   hints.ai_socktype = SOCK_DGRAM;
>   error = getaddrinfo(recv_addr, recv_port, &hints, &res);
>   if (error != 0) errx(1, "%s", gai_strerror(error));
>   res->ai_family = AF_INET6;
>   recv_s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
>   if (recv_s < 0) err(1, "socket");
>
>   while(1){
>       cc = recvfrom(recv_s, (void *)buf, sizeof(buf), 0,
>                     (struct sockaddr *)&from6, &fromlen);
>       if (cc < 0) {
>           warn("recvfrom");
>           continue;
>       }
>       if ( only_in == 0 ){
>           len = sendto(send_s, buf, cc, 0, send_res->ai_addr,
>                        send_res->ai_addrlen);
>       } else {
>           if ((ccout = fwrite(buf, cc, 1, outfp)) < 1)
>               close(recv_s);
>       }
>
>   }
> }
> -------------
>


More information about the freebsd-net mailing list