@@ -2529,6 +2529,101 @@ func TestRouteViaAddDel(t *testing.T) {
25292529 }
25302530}
25312531
2532+ // TestRouteMultiPathViaIPv4Mapped verifies that adding a Multipath route
2533+ // with a 16-byte IPv4-mapped address is correctly normalized to 4 bytes
2534+ // during encoding, preventing kernel invalid gateway rejections.
2535+ func TestRouteMultiPathViaIPv4Mapped (t * testing.T ) {
2536+ minKernelRequired (t , 5 , 4 )
2537+ t .Cleanup (setUpNetlinkTest (t ))
2538+
2539+ link , err := LinkByName ("lo" )
2540+ if err != nil {
2541+ t .Fatal (err )
2542+ }
2543+ if err := LinkSetUp (link ); err != nil {
2544+ t .Fatal (err )
2545+ }
2546+
2547+ buggyViaIP := net .ParseIP ("1.1.1.1" )
2548+ if len (buggyViaIP ) != 16 {
2549+ t .Fatalf ("expected a 16-byte IP object for the test, but got %d bytes" , len (buggyViaIP ))
2550+ }
2551+
2552+ dst := & net.IPNet {
2553+ IP : net .IPv4 (192 , 168 , 99 , 0 ),
2554+ Mask : net .CIDRMask (24 , 32 ),
2555+ }
2556+
2557+ route := & Route {
2558+ LinkIndex : link .Attrs ().Index ,
2559+ Dst : dst ,
2560+ MultiPath : []* NexthopInfo {
2561+ {
2562+ LinkIndex : link .Attrs ().Index ,
2563+ Flags : int (FLAG_ONLINK ),
2564+ Via : & Via {
2565+ AddrFamily : FAMILY_V4 ,
2566+ Addr : buggyViaIP , // intentionally trying to send the 16-byte IP to the Kernel
2567+ },
2568+ },
2569+ },
2570+ }
2571+
2572+ if err := RouteAdd (route ); err != nil {
2573+ t .Fatalf ("RouteAdd should handle 16-byte IPv4 Via addresses: %v" , err )
2574+ }
2575+
2576+ routes , err := RouteListFiltered (FAMILY_V4 , & Route {Dst : dst }, RT_FILTER_DST )
2577+ if err != nil {
2578+ t .Fatal (err )
2579+ }
2580+ if len (routes ) != 1 {
2581+ t .Fatal ("Route was not added to the kernel properly" )
2582+ }
2583+
2584+ if err := RouteDel (route ); err != nil {
2585+ t .Fatal (err )
2586+ }
2587+
2588+ routesAfterDel , err := RouteListFiltered (FAMILY_V4 , & Route {Dst : dst }, RT_FILTER_DST )
2589+ if err != nil {
2590+ t .Fatal (err )
2591+ }
2592+ if len (routesAfterDel ) != 0 {
2593+ t .Fatal ("Route was not deleted from the kernel properly" )
2594+ }
2595+ }
2596+
2597+ // TestViaEncodeIPv4Mapped verifies that a 16-byte IPv4-mapped address
2598+ // is correctly compressed and encoded into a strictly 6-byte slice
2599+ // (2 bytes for AddrFamily + 4 bytes for the IPv4 address).
2600+ func TestViaEncodeIPv4Mapped (t * testing.T ) {
2601+ via := & Via {
2602+ AddrFamily : FAMILY_V4 ,
2603+ Addr : net .ParseIP ("1.1.1.1" ),
2604+ }
2605+
2606+ b , err := via .Encode ()
2607+ if err != nil {
2608+ t .Fatal (err )
2609+ }
2610+
2611+ if len (b ) != 6 {
2612+ t .Fatalf ("expected encoded Via length to be 6 bytes, got %d" , len (b ))
2613+ }
2614+
2615+ gotFamily := int (native .Uint16 (b [0 :2 ]))
2616+ if gotFamily != FAMILY_V4 {
2617+ t .Fatalf ("unexpected address family; got %d, want %d" , gotFamily , FAMILY_V4 )
2618+ }
2619+
2620+ gotAddr := net .IP (b [2 :6 ])
2621+ wantAddr := net .IPv4 (1 , 1 , 1 , 1 )
2622+ if ! gotAddr .Equal (wantAddr ) {
2623+ t .Fatalf ("unexpected IPv4 address; got %s, want %s" , gotAddr , wantAddr )
2624+ }
2625+ }
2626+
25322627func TestRouteUIDOption (t * testing.T ) {
25332628 t .Cleanup (setUpNetlinkTest (t ))
25342629
0 commit comments