@@ -762,6 +762,79 @@ static void test_ip_tos_sockopt(int fd)
762762 xerror ("expect socklen_t == -1" );
763763}
764764
765+ static void test_so_max_pacing_rate (int fd )
766+ {
767+ /* SO_MAX_PACING_RATE is a unsigned long value in bytes/sec. Validate basic
768+ * set/get semantics and a few edge cases for getsockopt() lengths.
769+ */
770+ unsigned long in , out ;
771+ socklen_t s ;
772+ int r ;
773+
774+ /* Try a few representative values, including 0 (unlimited),
775+ * small, medium and a large one.
776+ */
777+ unsigned long tests [] = {
778+ 0U ,
779+ 1U ,
780+ 10U * 1000U * 1000U , /* 10 MB/s */
781+ 5U * 1024 * 1024 * 1024 /* 5 GB/s - tests that 64-bit unsigned long correctly works */
782+ };
783+
784+ for (size_t i = 0 ; i < sizeof (tests ) / sizeof (unsigned long ); i ++ ) {
785+ in = tests [i ];
786+
787+ r = setsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & in , sizeof (in ));
788+ if (r != 0 ) {
789+ char * msg ;
790+ (void )asprintf (& msg , "setsockopt SO_MAX_PACING_RATE to %lu" , in );
791+ die_perror (msg );
792+ }
793+
794+ out = ~in ; /* poison */
795+ s = sizeof (out );
796+ r = getsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & out , & s );
797+ if (r != 0 ) {
798+ char * msg ;
799+ (void )asprintf (& msg , "getsockopt SO_MAX_PACING_RATE expected %lu" , in );
800+ die_perror (msg );
801+ }
802+
803+ if (s != sizeof (out ))
804+ xerror ("SO_MAX_PACING_RATE length %d != %zu" , s , sizeof (out ));
805+
806+ if (out != in )
807+ xerror ("SO_MAX_PACING_RATE %u != %u" , out , in );
808+
809+ /* Query with zero-length buffer. Kernel should succeed and not write. */
810+ s = 0 ;
811+ r = getsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & out , & s );
812+ if (r != 0 )
813+ die_perror ("getsockopt SO_MAX_PACING_RATE len=0" );
814+ if (s != 0 )
815+ xerror ("expect socklen_t == 0 for SO_MAX_PACING_RATE" );
816+
817+ /* Query with negative length should fail with -EINVAL and leave s unchanged. */
818+ s = -1 ;
819+ r = getsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & out , & s );
820+ if (r != -1 && errno != EINVAL )
821+ die_perror ("getsockopt SO_MAX_PACING_RATE did not indicate -EINVAL" );
822+ if (s != -1 )
823+ xerror ("expect socklen_t == -1 for SO_MAX_PACING_RATE" );
824+ }
825+
826+ /* Invalid set: zero length should fail. */
827+ in = 1234U ;
828+ r = setsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & in , 0 );
829+ if (r != -1 && errno != EINVAL )
830+ die_perror ("setsockopt SO_MAX_PACING_RATE len=0 did not indicate -EINVAL" );
831+
832+ /* Invalid set: too short length should fail. */
833+ r = setsockopt (fd , SOL_SOCKET , SO_MAX_PACING_RATE , & in , 1 );
834+ if (r != -1 && errno != EINVAL )
835+ die_perror ("setsockopt SO_MAX_PACING_RATE short len did not indicate -EINVAL" );
836+ }
837+
765838static int client (int pipefd )
766839{
767840 int fd = -1 ;
@@ -780,6 +853,7 @@ static int client(int pipefd)
780853 }
781854
782855 test_ip_tos_sockopt (fd );
856+ test_so_max_pacing_rate (fd );
783857
784858 connect_one_server (fd , pipefd );
785859
0 commit comments