@@ -5,12 +5,17 @@ package netlink
55
66import (
77 "flag"
8+ "fmt"
89 "math/rand"
910 "net"
1011 "os"
1112 "strconv"
13+ "strings"
14+ "syscall"
1215 "testing"
1316
17+ "github.com/stretchr/testify/assert"
18+
1419 "github.com/vishvananda/netlink/nl"
1520)
1621
@@ -49,6 +54,61 @@ func TestDevLinkSetEswitchMode(t *testing.T) {
4954 }
5055}
5156
57+ func logPort (t * testing.T , port * DevlinkPort ) {
58+ type field struct {
59+ key string
60+ value string
61+ }
62+
63+ fields := []field {}
64+
65+ fields = append (fields , field {key : "bus" , value : port .BusName })
66+ fields = append (fields , field {key : "device" , value : port .DeviceName })
67+ fields = append (fields , field {key : "port_index" , value : strconv .Itoa (int (port .PortIndex ))})
68+ fields = append (fields , field {key : "port_type" , value : strconv .Itoa (int (port .PortType ))})
69+ fields = append (fields , field {key : "port_flavour" , value : strconv .Itoa (int (port .PortFlavour ))})
70+ fields = append (fields , field {key : "netdev_name" , value : port .NetdeviceName })
71+ fields = append (fields , field {key : "netdev_index" , value : strconv .Itoa (int (port .NetdevIfIndex ))})
72+ fields = append (fields , field {key : "rdma_dev_name" , value : port .RdmaDeviceName })
73+
74+ if port .Fn != nil {
75+ fields = append (fields , field {key : "hw_addr" , value : port .Fn .HwAddr .String ()})
76+ fields = append (fields , field {key : "state" , value : strconv .Itoa (int (port .Fn .State ))})
77+ fields = append (fields , field {key : "op_state" , value : strconv .Itoa (int (port .Fn .OpState ))})
78+ }
79+
80+ if port .PortNumber != nil {
81+ fields = append (fields , field {key : "port_number" , value : strconv .Itoa (int (* port .PortNumber ))})
82+ }
83+
84+ if port .PfNumber != nil {
85+ fields = append (fields , field {key : "pf_number" , value : strconv .Itoa (int (* port .PfNumber ))})
86+ }
87+
88+ if port .VfNumber != nil {
89+ fields = append (fields , field {key : "vf_number" , value : strconv .Itoa (int (* port .VfNumber ))})
90+ }
91+
92+ if port .SfNumber != nil {
93+ fields = append (fields , field {key : "sf_number" , value : strconv .Itoa (int (* port .SfNumber ))})
94+ }
95+
96+ if port .ControllerNumber != nil {
97+ fields = append (fields , field {key : "controller_number" , value : strconv .Itoa (int (* port .ControllerNumber ))})
98+ }
99+
100+ if port .External != nil {
101+ fields = append (fields , field {key : "external" , value : strconv .FormatBool (* port .External )})
102+ }
103+
104+ fieldsStr := []string {}
105+ for _ , field := range fields {
106+ fieldsStr = append (fieldsStr , fmt .Sprintf ("%s=%s" , field .key , field .value ))
107+ }
108+
109+ t .Log (strings .Join (fieldsStr , " " ))
110+ }
111+
52112func TestDevLinkGetAllPortList (t * testing.T ) {
53113 minKernelRequired (t , 5 , 4 )
54114 ports , err := DevLinkGetAllPortList ()
@@ -57,7 +117,7 @@ func TestDevLinkGetAllPortList(t *testing.T) {
57117 }
58118 t .Log ("devlink port count = " , len (ports ))
59119 for _ , port := range ports {
60- t . Log ( * port )
120+ logPort ( t , port )
61121 }
62122}
63123
@@ -401,3 +461,211 @@ func validateDeviceParams(t *testing.T, p *DevlinkParam) {
401461 }
402462 }
403463}
464+
465+ func testGetDevlinkPortCommonAttrs () []* nl.RtAttr {
466+ nlAttrs := []* nl.RtAttr {}
467+ nlAttrs = append (nlAttrs ,
468+ nl .NewRtAttr (nl .DEVLINK_ATTR_BUS_NAME , nl .ZeroTerminated ("pci" )),
469+ nl .NewRtAttr (nl .DEVLINK_ATTR_DEV_NAME , nl .ZeroTerminated ("0000:08:00.0" )),
470+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_INDEX , nl .Uint32Attr (131071 )),
471+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_TYPE , nl .Uint16Attr (nl .DEVLINK_PORT_TYPE_ETH )),
472+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_NETDEV_NAME , nl .ZeroTerminated ("eth0" )),
473+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_NETDEV_IFINDEX , nl .Uint32Attr (5 )),
474+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_IBDEV_NAME , nl .ZeroTerminated ("rdma0" )),
475+ )
476+
477+ return nlAttrs
478+ }
479+
480+ func testAddDevlinkPortPhysicalAttrs (nlAttrs []* nl.RtAttr ) []* nl.RtAttr {
481+ nlAttrs = append (nlAttrs ,
482+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_FLAVOUR , nl .Uint16Attr (nl .DEVLINK_PORT_FLAVOUR_PHYSICAL )),
483+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_NUMBER , nl .Uint32Attr (1 )),
484+ )
485+
486+ return nlAttrs
487+ }
488+
489+ func testAddDevlinkPortPfAttrs (nlAttrs []* nl.RtAttr ) []* nl.RtAttr {
490+ nlAttrs = append (nlAttrs ,
491+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_FLAVOUR , nl .Uint16Attr (nl .DEVLINK_PORT_FLAVOUR_PCI_PF )),
492+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_PCI_PF_NUMBER , nl .Uint16Attr (1 )),
493+ )
494+
495+ return nlAttrs
496+ }
497+
498+ func testAddDevlinkPortVfAttrs (nlAttrs []* nl.RtAttr ) []* nl.RtAttr {
499+ nlAttrs = append (nlAttrs ,
500+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_FLAVOUR , nl .Uint16Attr (nl .DEVLINK_PORT_FLAVOUR_PCI_VF )),
501+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_PCI_PF_NUMBER , nl .Uint16Attr (0 )),
502+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_PCI_VF_NUMBER , nl .Uint16Attr (4 )),
503+ )
504+
505+ nlAttrs = testAddDevlinkPortFnAttrs (nlAttrs )
506+ return nlAttrs
507+ }
508+
509+ func testAddDevlinkPortSfAttrs (nlAttrs []* nl.RtAttr ) []* nl.RtAttr {
510+ nlAttrs = append (nlAttrs ,
511+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_FLAVOUR , nl .Uint16Attr (nl .DEVLINK_PORT_FLAVOUR_PCI_SF )),
512+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_PCI_PF_NUMBER , nl .Uint16Attr (0 )),
513+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_PCI_SF_NUMBER , nl .Uint32Attr (123 )),
514+ )
515+
516+ nlAttrs = testAddDevlinkPortFnAttrs (nlAttrs )
517+ return nlAttrs
518+ }
519+
520+ func testNlAttrsToNetlinkRouteAttrs (nlAttrs []* nl.RtAttr ) []syscall.NetlinkRouteAttr {
521+ attrs := []syscall.NetlinkRouteAttr {}
522+ for _ , attr := range nlAttrs {
523+ attrs = append (attrs , syscall.NetlinkRouteAttr {Attr : syscall .RtAttr (attr .RtAttr ), Value : attr .Data })
524+ }
525+ return attrs
526+ }
527+
528+ func testAddDevlinkPortFnAttrs (nlAttrs []* nl.RtAttr ) []* nl.RtAttr {
529+ hwAddr , _ := net .ParseMAC ("00:11:22:33:44:55" )
530+ hwAddrAttr := nl .NewRtAttr (nl .DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR , []byte (hwAddr ))
531+ raw := hwAddrAttr .Serialize ()
532+
533+ nlAttr := nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_FUNCTION , raw )
534+ return append (nlAttrs , nlAttr )
535+ }
536+
537+ func testAddDevlinkPortControllerAttrs (nlAttrs []* nl.RtAttr , controllerNumber uint32 , external bool ) []* nl.RtAttr {
538+ extVal := uint8 (0 )
539+ if external {
540+ extVal = 1
541+ }
542+
543+ nlAttrs = append (nlAttrs ,
544+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_CONTROLLER_NUMBER , nl .Uint32Attr (controllerNumber )),
545+ nl .NewRtAttr (nl .DEVLINK_ATTR_PORT_EXTERNAL , nl .Uint8Attr (extVal )),
546+ )
547+
548+ return nlAttrs
549+ }
550+ func testAssertCommonAttrs (t * testing.T , port * DevlinkPort ) {
551+ assert .Equal (t , "pci" , port .BusName )
552+ assert .Equal (t , "0000:08:00.0" , port .DeviceName )
553+ assert .Equal (t , uint32 (131071 ), port .PortIndex )
554+ assert .Equal (t , uint16 (nl .DEVLINK_PORT_TYPE_ETH ), port .PortType )
555+ assert .Equal (t , "eth0" , port .NetdeviceName )
556+ assert .Equal (t , uint32 (5 ), port .NetdevIfIndex )
557+ assert .Equal (t , "rdma0" , port .RdmaDeviceName )
558+ }
559+
560+ func TestDevlinkPortParseAttributes (t * testing.T ) {
561+ t .Run ("flavor physical" , func (t * testing.T ) {
562+ nlAttrs := testGetDevlinkPortCommonAttrs ()
563+ nlAttrs = testAddDevlinkPortPhysicalAttrs (nlAttrs )
564+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
565+
566+ port := & DevlinkPort {}
567+ err := port .parseAttributes (attrs )
568+ assert .NoError (t , err )
569+
570+ testAssertCommonAttrs (t , port )
571+ assert .Equal (t , uint16 (nl .DEVLINK_PORT_FLAVOUR_PHYSICAL ), port .PortFlavour )
572+ assert .Equal (t , uint32 (1 ), * port .PortNumber )
573+
574+ assert .Nil (t , port .Fn )
575+ assert .Nil (t , port .PfNumber )
576+ assert .Nil (t , port .VfNumber )
577+ assert .Nil (t , port .SfNumber )
578+ assert .Nil (t , port .ControllerNumber )
579+ assert .Nil (t , port .External )
580+ })
581+
582+ t .Run ("flavor pcipf" , func (t * testing.T ) {
583+ nlAttrs := testGetDevlinkPortCommonAttrs ()
584+ nlAttrs = testAddDevlinkPortPfAttrs (nlAttrs )
585+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
586+
587+ port := & DevlinkPort {}
588+ err := port .parseAttributes (attrs )
589+ assert .NoError (t , err )
590+
591+ testAssertCommonAttrs (t , port )
592+ assert .Equal (t , uint16 (nl .DEVLINK_PORT_FLAVOUR_PCI_PF ), port .PortFlavour )
593+ assert .Equal (t , uint16 (1 ), * port .PfNumber )
594+
595+ assert .Nil (t , port .Fn )
596+ assert .Nil (t , port .PortNumber )
597+ assert .Nil (t , port .VfNumber )
598+ assert .Nil (t , port .SfNumber )
599+ assert .Nil (t , port .ControllerNumber )
600+ assert .Nil (t , port .External )
601+ })
602+ t .Run ("flavor pcivf" , func (t * testing.T ) {
603+ nlAttrs := testGetDevlinkPortCommonAttrs ()
604+ nlAttrs = testAddDevlinkPortVfAttrs (nlAttrs )
605+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
606+
607+ port := & DevlinkPort {}
608+ err := port .parseAttributes (attrs )
609+ assert .NoError (t , err )
610+
611+ testAssertCommonAttrs (t , port )
612+ assert .Equal (t , uint16 (nl .DEVLINK_PORT_FLAVOUR_PCI_VF ), port .PortFlavour )
613+ assert .Equal (t , uint16 (0 ), * port .PfNumber )
614+ assert .Equal (t , uint16 (4 ), * port .VfNumber )
615+ assert .Equal (t , "00:11:22:33:44:55" , port .Fn .HwAddr .String ())
616+
617+ assert .Nil (t , port .PortNumber )
618+ assert .Nil (t , port .SfNumber )
619+ assert .Nil (t , port .ControllerNumber )
620+ assert .Nil (t , port .External )
621+ })
622+
623+ t .Run ("flavor pcisf" , func (t * testing.T ) {
624+ nlAttrs := testGetDevlinkPortCommonAttrs ()
625+ nlAttrs = testAddDevlinkPortSfAttrs (nlAttrs )
626+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
627+
628+ port := & DevlinkPort {}
629+ err := port .parseAttributes (attrs )
630+ assert .NoError (t , err )
631+
632+ testAssertCommonAttrs (t , port )
633+ assert .Equal (t , uint16 (nl .DEVLINK_PORT_FLAVOUR_PCI_SF ), port .PortFlavour )
634+ assert .Equal (t , uint16 (0 ), * port .PfNumber )
635+ assert .Equal (t , uint32 (123 ), * port .SfNumber )
636+ assert .Equal (t , "00:11:22:33:44:55" , port .Fn .HwAddr .String ())
637+
638+ assert .Nil (t , port .PortNumber )
639+ assert .Nil (t , port .VfNumber )
640+ assert .Nil (t , port .ControllerNumber )
641+ assert .Nil (t , port .External )
642+ })
643+
644+ t .Run ("port with controller - external false" , func (t * testing.T ) {
645+ nlAttrs := testGetDevlinkPortCommonAttrs ()
646+ nlAttrs = testAddDevlinkPortVfAttrs (nlAttrs )
647+ nlAttrs = testAddDevlinkPortControllerAttrs (nlAttrs , 0 , false )
648+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
649+
650+ port := & DevlinkPort {}
651+ err := port .parseAttributes (attrs )
652+ assert .NoError (t , err )
653+
654+ assert .Equal (t , uint32 (0 ), * port .ControllerNumber )
655+ assert .Equal (t , false , * port .External )
656+ })
657+
658+ t .Run ("port with controller - external true" , func (t * testing.T ) {
659+ nlAttrs := testGetDevlinkPortCommonAttrs ()
660+ nlAttrs = testAddDevlinkPortVfAttrs (nlAttrs )
661+ nlAttrs = testAddDevlinkPortControllerAttrs (nlAttrs , 1 , true )
662+ attrs := testNlAttrsToNetlinkRouteAttrs (nlAttrs )
663+
664+ port := & DevlinkPort {}
665+ err := port .parseAttributes (attrs )
666+ assert .NoError (t , err )
667+
668+ assert .Equal (t , uint32 (1 ), * port .ControllerNumber )
669+ assert .Equal (t , true , * port .External )
670+ })
671+ }
0 commit comments