Refuse a filter location something else holds, and the driver's word on how many it wrote

This commit is contained in:
flamingcow
2026-08-04 22:12:03 -07:00
parent f5d05d1fc5
commit 19b0f1d2ea
+14 -3
View File
@@ -83,6 +83,11 @@ func allRuleLocations(fd int, ifname string) ([]uint32, uint32, error) {
return nil, 0, err
}
if all.ruleCnt > cnt.ruleCnt {
return nil, 0, fmt.Errorf("%s reported %d filter locations into room for %d",
ifname, all.ruleCnt, cnt.ruleCnt)
}
raw := buf[locOff:]
locs := make([]uint32, 0, all.ruleCnt)
for i := 0; i < int(all.ruleCnt); i++ {
@@ -171,9 +176,16 @@ func checkFlowRules(fd int, ifname string, ethertypes []uint16) checkResult {
taken[loc] = true
}
// Inserting at a taken location would evict it, and would then leave every
// later ethertype evicting the one before it at that same location.
next := capacity - 1
for i, et := range ethertypes {
for taken[next] && next > 0 {
for taken[next] {
if next == 0 {
res.err = fmt.Errorf("no free filter location below %d for ethertype 0x%04x",
capacity, et)
return res
}
next--
}
if err := insertEtherRule(fd, ifname, et, uint64(i), next); err != nil {
@@ -586,8 +598,7 @@ func withIoctlSocket(fn func(fd int) []checkResult) []checkResult {
}
// Nothing here waits for a carrier: the two ports are the two ends of the cable
// under test, so with no cable there will never be one, and a dead wire is a
// result to report rather than a reason to refuse to start.
// under test, so with no cable there is never going to be one.
func configureSystem(ifnames []string, ethertypes []uint16) []checkResult {
return withIoctlSocket(func(fd int) []checkResult {
out := []checkResult{checkGovernor(wantGovernor)}