filter: add classid and port range support for flower

This commit is contained in:
lwintermelon
2025-05-08 03:06:58 +00:00
committed by Alessandro Boch
parent 06c2c01f6a
commit b929916209
3 changed files with 106 additions and 19 deletions

View File

@@ -54,6 +54,7 @@ func (filter *U32) Type() string {
type Flower struct { type Flower struct {
FilterAttrs FilterAttrs
ClassId uint32
DestIP net.IP DestIP net.IP
DestIPMask net.IPMask DestIPMask net.IPMask
SrcIP net.IP SrcIP net.IP
@@ -73,6 +74,10 @@ type Flower struct {
IPProto *nl.IPProto IPProto *nl.IPProto
DestPort uint16 DestPort uint16
SrcPort uint16 SrcPort uint16
SrcPortRangeMin uint16
SrcPortRangeMax uint16
DstPortRangeMin uint16
DstPortRangeMax uint16
Actions []Action Actions []Action
} }
@@ -171,6 +176,19 @@ func (filter *Flower) encode(parent *nl.RtAttr) error {
} }
} }
} }
if filter.SrcPortRangeMin != 0 && filter.SrcPortRangeMax != 0 {
parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_SRC_MIN, htons(filter.SrcPortRangeMin))
parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_SRC_MAX, htons(filter.SrcPortRangeMax))
}
if filter.DstPortRangeMin != 0 && filter.DstPortRangeMax != 0 {
parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_DST_MIN, htons(filter.DstPortRangeMin))
parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_DST_MAX, htons(filter.DstPortRangeMax))
}
if filter.ClassId != 0 {
parent.AddRtAttr(nl.TCA_FLOWER_CLASSID, nl.Uint32Attr(filter.ClassId))
}
var flags uint32 = 0 var flags uint32 = 0
if filter.SkipHw { if filter.SkipHw {
@@ -247,6 +265,16 @@ func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error {
if skipHw != 0 { if skipHw != 0 {
filter.SkipHw = true filter.SkipHw = true
} }
case nl.TCA_FLOWER_KEY_PORT_SRC_MIN:
filter.SrcPortRangeMin = ntohs(datum.Value)
case nl.TCA_FLOWER_KEY_PORT_SRC_MAX:
filter.SrcPortRangeMax = ntohs(datum.Value)
case nl.TCA_FLOWER_KEY_PORT_DST_MIN:
filter.DstPortRangeMin = ntohs(datum.Value)
case nl.TCA_FLOWER_KEY_PORT_DST_MAX:
filter.DstPortRangeMax = ntohs(datum.Value)
case nl.TCA_FLOWER_CLASSID:
filter.ClassId = native.Uint32(datum.Value)
} }
} }
return nil return nil

View File

@@ -2045,6 +2045,58 @@ func TestFilterFlowerAddDel(t *testing.T) {
t.Fatal("Failed to remove filter") t.Fatal("Failed to remove filter")
} }
classId := MakeHandle(1, 101)
filter = &Flower{
FilterAttrs: FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: MakeHandle(0xffff, 0),
Priority: 1,
Protocol: unix.ETH_P_ALL,
},
EthType: unix.ETH_P_IP,
IPProto: ipproto,
ClassId: classId,
SrcPortRangeMin: 1000,
SrcPortRangeMax: 2000,
}
if err := FilterAdd(filter); err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
filters, err = FilterList(link, MakeHandle(0xffff, 0))
if err != nil {
t.Fatal(err)
}
if len(filters) != 1 {
t.Fatal("Failed to add filter")
}
flower, ok = filters[0].(*Flower)
if !ok {
t.Fatal("Filter is the wrong type")
}
if filter.ClassId != flower.ClassId {
t.Fatalf("Flower ClassId doesn't match")
}
if filter.SrcPortRangeMin != flower.SrcPortRangeMin {
t.Fatalf("Flower SrcPortRangeMin doesn't match")
}
if filter.SrcPortRangeMax != flower.SrcPortRangeMax {
t.Fatalf("Flower SrcPortRangeMax doesn't match")
}
if err := FilterDel(filter); err != nil {
t.Fatal(err)
}
filters, err = FilterList(link, MakeHandle(0xffff, 0))
if err != nil {
t.Fatal(err)
}
if len(filters) != 0 {
t.Fatal("Failed to remove filter")
}
if err := QdiscDel(qdisc); err != nil { if err := QdiscDel(qdisc); err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -1123,6 +1123,13 @@ const (
TCA_FLOWER_KEY_ENC_OPTS TCA_FLOWER_KEY_ENC_OPTS
TCA_FLOWER_KEY_ENC_OPTS_MASK TCA_FLOWER_KEY_ENC_OPTS_MASK
TCA_FLOWER_IN_HW_COUNT
TCA_FLOWER_KEY_PORT_SRC_MIN /* be16 */
TCA_FLOWER_KEY_PORT_SRC_MAX /* be16 */
TCA_FLOWER_KEY_PORT_DST_MIN /* be16 */
TCA_FLOWER_KEY_PORT_DST_MAX /* be16 */
__TCA_FLOWER_MAX __TCA_FLOWER_MAX
) )