Skip to content

Commit f4e6e3d

Browse files
Christian Worm Mortensenaboch
authored andcommitted
Allow a Police to be specified directly on a U32 filter
1 parent 99ce943 commit f4e6e3d

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

filter_linux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type U32 struct {
4141
RedirIndex int
4242
Sel *TcU32Sel
4343
Actions []Action
44+
Police *PoliceAction
4445
}
4546

4647
func (filter *U32) Attrs() *FilterAttrs {
@@ -331,6 +332,12 @@ func (h *Handle) filterModify(filter Filter, proto, flags int) error {
331332
if filter.Link != 0 {
332333
options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link))
333334
}
335+
if filter.Police != nil {
336+
police := options.AddRtAttr(nl.TCA_U32_POLICE, nil)
337+
if err := encodePolice(police, filter.Police); err != nil {
338+
return err
339+
}
340+
}
334341
actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
335342
// backwards compatibility
336343
if filter.RedirIndex != 0 {
@@ -952,6 +959,13 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
952959
u32.RedirIndex = int(action.Ifindex)
953960
}
954961
}
962+
case nl.TCA_U32_POLICE:
963+
var police PoliceAction
964+
adata, _ := nl.ParseRouteAttr(datum.Value)
965+
for _, aattr := range adata {
966+
parsePolice(aattr, &police)
967+
}
968+
u32.Police = &police
955969
case nl.TCA_U32_CLASSID:
956970
u32.ClassId = native.Uint32(datum.Value)
957971
case nl.TCA_U32_DIVISOR:

filter_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,6 +2276,108 @@ func TestFilterU32PoliceAddDel(t *testing.T) {
22762276
}
22772277
}
22782278

2279+
func TestFilterU32DirectPoliceAddDel(t *testing.T) {
2280+
tearDown := setUpNetlinkTest(t)
2281+
defer tearDown()
2282+
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
2283+
t.Fatal(err)
2284+
}
2285+
link, err := LinkByName("foo")
2286+
if err != nil {
2287+
t.Fatal(err)
2288+
}
2289+
if err := LinkSetUp(link); err != nil {
2290+
t.Fatal(err)
2291+
}
2292+
2293+
qdisc := &Ingress{
2294+
QdiscAttrs: QdiscAttrs{
2295+
LinkIndex: link.Attrs().Index,
2296+
Handle: MakeHandle(0xffff, 0),
2297+
Parent: HANDLE_INGRESS,
2298+
},
2299+
}
2300+
if err := QdiscAdd(qdisc); err != nil {
2301+
t.Fatal(err)
2302+
}
2303+
2304+
const (
2305+
policeRate = 0x40000000 // 1 Gbps
2306+
policeBurst = 0x19000 // 100 KB
2307+
policePeakRate = 0x4000 // 16 Kbps
2308+
)
2309+
2310+
police := NewPoliceAction()
2311+
police.Rate = policeRate
2312+
police.PeakRate = policePeakRate
2313+
police.Burst = policeBurst
2314+
police.ExceedAction = TC_POLICE_SHOT
2315+
police.NotExceedAction = TC_POLICE_UNSPEC
2316+
2317+
classId := MakeHandle(1, 1)
2318+
filter := &U32{
2319+
FilterAttrs: FilterAttrs{
2320+
LinkIndex: link.Attrs().Index,
2321+
Parent: MakeHandle(0xffff, 0),
2322+
Priority: 1,
2323+
Protocol: unix.ETH_P_ALL,
2324+
},
2325+
ClassId: classId,
2326+
Police: police,
2327+
}
2328+
2329+
if err := FilterAdd(filter); err != nil {
2330+
t.Fatal(err)
2331+
}
2332+
2333+
filters, err := FilterList(link, MakeHandle(0xffff, 0))
2334+
if err != nil {
2335+
t.Fatal(err)
2336+
}
2337+
if len(filters) != 1 {
2338+
t.Fatal("Failed to add filter")
2339+
}
2340+
u32, ok := filters[0].(*U32)
2341+
if !ok {
2342+
t.Fatal("Filter is the wrong type")
2343+
}
2344+
2345+
if u32.Police == nil {
2346+
t.Fatalf("No police in filter")
2347+
}
2348+
2349+
if u32.Police.Rate != policeRate {
2350+
t.Fatal("Filter Rate doesn't match")
2351+
}
2352+
2353+
if u32.Police.PeakRate != policePeakRate {
2354+
t.Fatal("Filter PeakRate doesn't match")
2355+
}
2356+
2357+
if u32.Police.LinkLayer != nl.LINKLAYER_ETHERNET {
2358+
t.Fatal("Filter LinkLayer doesn't match")
2359+
}
2360+
2361+
if err := QdiscDel(qdisc); err != nil {
2362+
t.Fatal(err)
2363+
}
2364+
qdiscs, err := SafeQdiscList(link)
2365+
if err != nil {
2366+
t.Fatal(err)
2367+
}
2368+
2369+
found := false
2370+
for _, v := range qdiscs {
2371+
if _, ok := v.(*Ingress); ok {
2372+
found = true
2373+
break
2374+
}
2375+
}
2376+
if found {
2377+
t.Fatal("Failed to remove qdisc")
2378+
}
2379+
}
2380+
22792381
func TestFilterChainAddDel(t *testing.T) {
22802382
tearDown := setUpNetlinkTest(t)
22812383
defer tearDown()

0 commit comments

Comments
 (0)