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 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:] raw := buf[locOff:]
locs := make([]uint32, 0, all.ruleCnt) locs := make([]uint32, 0, all.ruleCnt)
for i := 0; i < int(all.ruleCnt); i++ { for i := 0; i < int(all.ruleCnt); i++ {
@@ -171,9 +176,16 @@ func checkFlowRules(fd int, ifname string, ethertypes []uint16) checkResult {
taken[loc] = true 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 next := capacity - 1
for i, et := range ethertypes { 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-- next--
} }
if err := insertEtherRule(fd, ifname, et, uint64(i), next); err != nil { 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 // 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 // under test, so with no cable there is never going to be one.
// result to report rather than a reason to refuse to start.
func configureSystem(ifnames []string, ethertypes []uint16) []checkResult { func configureSystem(ifnames []string, ethertypes []uint16) []checkResult {
return withIoctlSocket(func(fd int) []checkResult { return withIoctlSocket(func(fd int) []checkResult {
out := []checkResult{checkGovernor(wantGovernor)} out := []checkResult{checkGovernor(wantGovernor)}