Skip to content

Commit

Permalink
flower: implement more attributes
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Lehner <dev@der-flo.net>
  • Loading branch information
florianl authored and dennisafa committed Mar 29, 2021
1 parent c42e5eb commit 277fae9
Showing 5 changed files with 78 additions and 17 deletions.
11 changes: 11 additions & 0 deletions converter.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,17 @@ package tc

import "net"

func netIPMaskPtr(v net.IPMask) *net.IPMask {
return &v
}

func netIPMaskValue(v *net.IPMask) net.IPMask {
if v != nil {
return *v
}
return net.IPMask{}
}

func netIPPtr(v net.IP) *net.IP {
return &v
}
19 changes: 19 additions & 0 deletions converter_test.go
Original file line number Diff line number Diff line change
@@ -27,6 +27,25 @@ func TestConvertNetIP(t *testing.T) {
}
}

func TestConvertNetIPMask(t *testing.T) {
tests := map[string]struct {
value net.IPMask
}{
"broadcast": {value: net.IPv4Mask(255, 255, 255, 255)},
"default mask": {value: net.ParseIP("127.0.0.1").DefaultMask()},
}

for name, testcase := range tests {
t.Run(name, func(t *testing.T) {
ptr := netIPMaskPtr(testcase.value)
value := netIPMaskValue(ptr)
if diff := cmp.Diff(value, testcase.value); diff != "" {
t.Fatalf("Missmatch (-want +got):\n%s", diff)
}
})
}
}

func TestConvertString(t *testing.T) {
tests := map[string]struct {
value string
38 changes: 26 additions & 12 deletions f_flower.go
Original file line number Diff line number Diff line change
@@ -107,21 +107,22 @@ type Flower struct {
KeyEthType *uint16
KeyIPProto *uint8
KeyIPv4Src *net.IP
KeyIPv4SrcMask *net.IP
KeyIPv4SrcMask *net.IPMask
KeyIPv4Dst *net.IP
KeyIPv4DstMask *net.IP
KeyIPv4DstMask *net.IPMask
KeyTCPSrc *uint16
KeyTCPDst *uint16
KeyUDPSrc *uint16
KeyUDPDst *uint16
Flags *uint32
KeyVlanID *uint16
KeyVlanPrio *uint8
KeyVlanEthType *uint16
KeyEncKeyID *uint32
KeyEncIPv4Src *net.IP
KeyEncIPv4SrcMask *net.IP
KeyEncIPv4SrcMask *net.IPMask
KeyEncIPv4Dst *net.IP
KeyEncIPv4DstMask *net.IP
KeyEncIPv4DstMask *net.IPMask
KeyTCPSrcMask *uint16
KeyTCPDstMask *uint16
KeyUDPSrcMask *uint16
@@ -163,6 +164,7 @@ type Flower struct {
KeyEncIPTOSMask *uint8
KeyEncIPTTL *uint8
KeyEncIPTTLMask *uint8
InHwCount *uint32
}

// unmarshalFlower parses the Flower-encoded data and stores the result in the value pointed to by info.
@@ -202,13 +204,13 @@ func unmarshalFlower(data []byte, info *Flower) error {
tmp := uint32ToIP(ad.Uint32())
info.KeyIPv4Src = &tmp
case tcaFlowerKeyIPv4SrcMask:
tmp := uint32ToIP(ad.Uint32())
tmp := uint32ToIPMask(ad.Uint32())
info.KeyIPv4SrcMask = &tmp
case tcaFlowerKeyIPv4Dst:
tmp := uint32ToIP(ad.Uint32())
info.KeyIPv4Dst = &tmp
case tcaFlowerKeyIPv4DstMask:
tmp := uint32ToIP(ad.Uint32())
tmp := uint32ToIPMask(ad.Uint32())
info.KeyIPv4DstMask = &tmp
case tcaFlowerKeyTCPSrc:
tmp := ad.Uint16()
@@ -222,6 +224,9 @@ func unmarshalFlower(data []byte, info *Flower) error {
case tcaFlowerKeyUDPDst:
tmp := ad.Uint16()
info.KeyUDPDst = &tmp
case tcaFlowerFlags:
tmp := ad.Uint32()
info.Flags = &tmp
case tcaFlowerKeyVlanID:
tmp := ad.Uint16()
info.KeyVlanID = &tmp
@@ -238,13 +243,13 @@ func unmarshalFlower(data []byte, info *Flower) error {
tmp := uint32ToIP(ad.Uint32())
info.KeyEncIPv4Src = &tmp
case tcaFlowerKeyEncIPv4SrcMask:
tmp := uint32ToIP(ad.Uint32())
tmp := uint32ToIPMask(ad.Uint32())
info.KeyEncIPv4SrcMask = &tmp
case tcaFlowerKeyEncIPv4Dst:
tmp := uint32ToIP(ad.Uint32())
info.KeyEncIPv4Dst = &tmp
case tcaFlowerKeyEncIPv4DstMask:
tmp := uint32ToIP(ad.Uint32())
tmp := uint32ToIPMask(ad.Uint32())
info.KeyEncIPv4DstMask = &tmp
case tcaFlowerKeyTCPSrcMask:
tmp := ad.Uint16()
@@ -369,6 +374,9 @@ func unmarshalFlower(data []byte, info *Flower) error {
case tcaFlowerKeyEncIPTTLMask:
tmp := ad.Uint8()
info.KeyEncIPTTLMask = &tmp
case tcaFlowerInHwCount:
tmp := ad.Uint32()
info.InHwCount = &tmp
default:
return fmt.Errorf("unmarshalFlower()\t%d\n\t%v", ad.Type(), ad.Bytes())
}
@@ -426,7 +434,7 @@ func marshalFlower(info *Flower) ([]byte, error) {
options = append(options, tcOption{Interpretation: vtUint32Be, Type: tcaFlowerKeyIPv4Src, Data: tmp})
}
if info.KeyIPv4SrcMask != nil {
tmp, err := ipToUint32(*info.KeyIPv4SrcMask)
tmp, err := ipMaskToUint32(*info.KeyIPv4SrcMask)
if err != nil {
return []byte{}, fmt.Errorf("Flower - KeyIPv4SrcMask: %w", err)
}
@@ -440,7 +448,7 @@ func marshalFlower(info *Flower) ([]byte, error) {
options = append(options, tcOption{Interpretation: vtUint32Be, Type: tcaFlowerKeyIPv4Dst, Data: tmp})
}
if info.KeyIPv4DstMask != nil {
tmp, err := ipToUint32(*info.KeyIPv4DstMask)
tmp, err := ipMaskToUint32(*info.KeyIPv4DstMask)
if err != nil {
return []byte{}, fmt.Errorf("Flower - KeyIPv4DstMask: %w", err)
}
@@ -458,6 +466,9 @@ func marshalFlower(info *Flower) ([]byte, error) {
if info.KeyUDPDst != nil {
options = append(options, tcOption{Interpretation: vtUint16Be, Type: tcaFlowerKeyUDPDst, Data: *info.KeyUDPDst})
}
if info.Flags != nil {
options = append(options, tcOption{Interpretation: vtUint32, Type: tcaFlowerFlags, Data: *info.Flags})
}
if info.KeyVlanID != nil {
options = append(options, tcOption{Interpretation: vtUint16, Type: tcaFlowerKeyVlanID, Data: *info.KeyVlanID})
}
@@ -478,7 +489,7 @@ func marshalFlower(info *Flower) ([]byte, error) {
options = append(options, tcOption{Interpretation: vtUint32Be, Type: tcaFlowerKeyEncIPv4Src, Data: tmp})
}
if info.KeyEncIPv4SrcMask != nil {
tmp, err := ipToUint32(*info.KeyEncIPv4SrcMask)
tmp, err := ipMaskToUint32(*info.KeyEncIPv4SrcMask)
if err != nil {
return []byte{}, fmt.Errorf("Flower - KeyEncIPv4SrcMask: %w", err)
}
@@ -492,7 +503,7 @@ func marshalFlower(info *Flower) ([]byte, error) {
options = append(options, tcOption{Interpretation: vtUint32Be, Type: tcaFlowerKeyEncIPv4Dst, Data: tmp})
}
if info.KeyEncIPv4DstMask != nil {
tmp, err := ipToUint32(*info.KeyEncIPv4DstMask)
tmp, err := ipMaskToUint32(*info.KeyEncIPv4DstMask)
if err != nil {
return []byte{}, fmt.Errorf("Flower - KeyEncIPv4DstMask: %w", err)
}
@@ -621,5 +632,8 @@ func marshalFlower(info *Flower) ([]byte, error) {
if info.KeyEncIPTTLMask != nil {
options = append(options, tcOption{Interpretation: vtUint8, Type: tcaFlowerKeyEncIPTTLMask, Data: *info.KeyEncIPTTLMask})
}
if info.InHwCount != nil {
options = append(options, tcOption{Interpretation: vtUint32, Type: tcaFlowerInHwCount, Data: *info.InHwCount})
}
return marshalAttributes(options)
}
12 changes: 7 additions & 5 deletions f_flower_test.go
Original file line number Diff line number Diff line change
@@ -22,13 +22,13 @@ func TestFlower(t *testing.T) {
"allArguments": {val: Flower{
ClassID: uint32Ptr(1),
Indev: stringPtr("foo"),
Actions: &actions,
Actions: &actions,
KeyEthType: uint16Ptr(2),
KeyIPProto: uint8Ptr(3),
KeyIPv4Src: netIPPtr(net.ParseIP("1.2.3.4")),
KeyIPv4SrcMask: netIPPtr(net.ParseIP("255.255.255.255")),
KeyIPv4SrcMask: netIPMaskPtr(net.CIDRMask(20, 32)),
KeyIPv4Dst: netIPPtr(net.ParseIP("4.3.2.1")),
KeyIPv4DstMask: netIPPtr(net.ParseIP("255.255.255.0")),
KeyIPv4DstMask: netIPMaskPtr(net.CIDRMask(21, 32)),
KeyTCPSrc: uint16Ptr(4),
KeyTCPDst: uint16Ptr(5),
KeyUDPSrc: uint16Ptr(6),
@@ -38,9 +38,9 @@ func TestFlower(t *testing.T) {
KeyVlanEthType: uint16Ptr(10),
KeyEncKeyID: uint32Ptr(11),
KeyEncIPv4Src: netIPPtr(net.ParseIP("3.4.1.2")),
KeyEncIPv4SrcMask: netIPPtr(net.ParseIP("255.255.0.0")),
KeyEncIPv4SrcMask: netIPMaskPtr(net.CIDRMask(22, 32)),
KeyEncIPv4Dst: netIPPtr(net.ParseIP("4.3.2.1")),
KeyEncIPv4DstMask: netIPPtr(net.ParseIP("255.0.0.0")),
KeyEncIPv4DstMask: netIPMaskPtr(net.CIDRMask(23, 32)),
KeyTCPSrcMask: uint16Ptr(12),
KeyTCPDstMask: uint16Ptr(13),
KeyUDPSrcMask: uint16Ptr(14),
@@ -82,6 +82,8 @@ func TestFlower(t *testing.T) {
KeyEncIPTOSMask: uint8Ptr(50),
KeyEncIPTTL: uint8Ptr(51),
KeyEncIPTTLMask: uint8Ptr(52),
InHwCount: uint32Ptr(53),
Flags: uint32Ptr(54),
}},
}

15 changes: 15 additions & 0 deletions helper.go
Original file line number Diff line number Diff line change
@@ -21,6 +21,21 @@ func uint32ToIP(ip uint32) net.IP {
return netIP
}

// ipMaskToUint32 converts a legacy IPMask object to its uint32 representative.
// For IPv6 masks it returns ErrInvalidArg.
func ipMaskToUint32(ipv4 net.IPMask) (uint32, error) {
ones, bits := ipv4.Size()
if bits != 32 {
return 0, ErrInvalidArg
}
return uint32(ones), nil
}

// uint32ToIPMask converts a legacy ip mask to a net.IPMask object.
func uint32ToIPMask(bits uint32) net.IPMask {
return net.CIDRMask(int(bits), 32)
}

// bytesToIP converts a slice of bytes into a net.IP object.
func bytesToIP(ip []byte) (net.IP, error) {
if len(ip) != net.IPv4len && len(ip) != net.IPv6len {

0 comments on commit 277fae9

Please sign in to comment.