Support skip_hw/skip_sw flags

This feature could not be tested with virtual interfaces that's why
unit-tests aren't added into this change.
This commit is contained in:
Ivan Kolodyazhny
2022-08-19 16:50:55 +03:00
committed by Alessandro Boch
parent 7f2b136d34
commit e20cb98f77
4 changed files with 44 additions and 2 deletions

View File

@@ -64,6 +64,8 @@ type Flower struct {
EncSrcIPMask net.IPMask
EncDestPort uint16
EncKeyId uint32
SkipHw bool
SkipSw bool
Actions []Action
}
@@ -130,6 +132,15 @@ func (filter *Flower) encode(parent *nl.RtAttr) error {
parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_KEY_ID, htonl(filter.EncKeyId))
}
var flags uint32 = 0
if filter.SkipHw {
flags |= nl.TCA_CLS_FLAGS_SKIP_HW
}
if filter.SkipSw {
flags |= nl.TCA_CLS_FLAGS_SKIP_SW
}
parent.AddRtAttr(nl.TCA_FLOWER_FLAGS, htonl(flags))
actionsAttr := parent.AddRtAttr(nl.TCA_FLOWER_ACT, nil)
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
return err
@@ -171,6 +182,16 @@ func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error {
if err != nil {
return err
}
case nl.TCA_FLOWER_FLAGS:
attr := nl.DeserializeUint32Bitfield(datum.Value)
skipSw := attr.Value & nl.TCA_CLS_FLAGS_SKIP_HW
skipHw := attr.Value & nl.TCA_CLS_FLAGS_SKIP_SW
if skipSw != 0 {
filter.SkipSw = true
}
if skipHw != 0 {
filter.SkipHw = true
}
}
}
return nil
@@ -344,7 +365,6 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
return err
}
}
req.AddData(options)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err

View File

@@ -1850,7 +1850,6 @@ func TestFilterFlowerAddDel(t *testing.T) {
if filter.EncDestPort != flower.EncDestPort {
t.Fatalf("Flower EncDestPort doesn't match")
}
mia, ok := flower.Actions[0].(*MirredAction)
if !ok {
t.Fatal("Unable to find mirred action")

View File

@@ -330,6 +330,19 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
return msg
}
type Uint32Bitfield struct {
Value uint32
Selector uint32
}
func (a *Uint32Bitfield) Serialize() []byte {
return (*(*[SizeofUint32Bitfield]byte)(unsafe.Pointer(a)))[:]
}
func DeserializeUint32Bitfield(data []byte) *Uint32Bitfield {
return (*Uint32Bitfield)(unsafe.Pointer(&data[0:SizeofUint32Bitfield][0]))
}
type Uint32Attribute struct {
Type uint16
Value uint32

View File

@@ -63,6 +63,12 @@ const (
TCA_ACT_OPTIONS
TCA_ACT_INDEX
TCA_ACT_STATS
TCA_ACT_PAD
TCA_ACT_COOKIE
TCA_ACT_FLAGS
TCA_ACT_HW_STATS
TCA_ACT_USED_HW_STATS
TCA_ACT_IN_HW_COUNT
TCA_ACT_MAX
)
@@ -105,6 +111,7 @@ const (
SizeofTcSfqQopt = 0x0b
SizeofTcSfqRedStats = 0x18
SizeofTcSfqQoptV1 = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c
SizeofUint32Bitfield = 0x8
)
// struct tcmsg {
@@ -1030,6 +1037,9 @@ const (
__TCA_FLOWER_MAX
)
const TCA_CLS_FLAGS_SKIP_HW = 1 << 0 /* don't offload filter to HW */
const TCA_CLS_FLAGS_SKIP_SW = 1 << 1 /* don't use filter in SW */
// struct tc_sfq_qopt {
// unsigned quantum; /* Bytes per round allocated to flow */
// int perturb_period; /* Period of hash perturbation */