wgengine/router: also accept exit code 254 from `ip rule del`.
iproute2 3.16.0-2 from Debian Jessie (oldoldstable) doesn't return exit code 2 when deleting a non-existent IP rule. Fixes #434 Signed-off-by: David Anderson <danderson@tailscale.com>reviewable/pr438/r1
parent
484b7fc9a3
commit
5a32f8e181
|
@ -519,7 +519,7 @@ func (r *linuxRouter) addIPRules() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rg := newRunGroup(0, r.cmd)
|
rg := newRunGroup(nil, r.cmd)
|
||||||
|
|
||||||
// NOTE(apenwarr): We leave spaces between each pref number.
|
// NOTE(apenwarr): We leave spaces between each pref number.
|
||||||
// This is so the sysadmin can override by inserting rules in
|
// This is so the sysadmin can override by inserting rules in
|
||||||
|
@ -588,7 +588,10 @@ func (r *linuxRouter) delIPRules() error {
|
||||||
// Error codes: 'ip rule' returns error code 2 if the rule is a
|
// Error codes: 'ip rule' returns error code 2 if the rule is a
|
||||||
// duplicate (add) or not found (del). It returns a different code
|
// duplicate (add) or not found (del). It returns a different code
|
||||||
// for syntax errors. This is also true of busybox.
|
// for syntax errors. This is also true of busybox.
|
||||||
rg := newRunGroup(2, r.cmd)
|
//
|
||||||
|
// Some older versions of iproute2 also return error code 254 for
|
||||||
|
// unknown rules during deletion.
|
||||||
|
rg := newRunGroup([]int{2, 254}, r.cmd)
|
||||||
|
|
||||||
// When deleting rules, we want to be a bit specific (mention which
|
// When deleting rules, we want to be a bit specific (mention which
|
||||||
// table we were routing to) but not *too* specific (fwmarks, etc).
|
// table we were routing to) but not *too* specific (fwmarks, etc).
|
||||||
|
|
|
@ -61,21 +61,31 @@ func (o osCommandRunner) output(args ...string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type runGroup struct {
|
type runGroup struct {
|
||||||
OkCode int // an error code that is acceptable, other than 0, if any
|
OkCode []int // error codes that are acceptable, other than 0, if any
|
||||||
Runner commandRunner // the runner that actually runs our commands
|
Runner commandRunner // the runner that actually runs our commands
|
||||||
ErrAcc error // first error encountered, if any
|
ErrAcc error // first error encountered, if any
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRunGroup(okCode int, runner commandRunner) *runGroup {
|
func newRunGroup(okCode []int, runner commandRunner) *runGroup {
|
||||||
return &runGroup{
|
return &runGroup{
|
||||||
OkCode: okCode,
|
OkCode: okCode,
|
||||||
Runner: runner,
|
Runner: runner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rg *runGroup) okCode(err error) bool {
|
||||||
|
got := errCode(err)
|
||||||
|
for _, want := range rg.OkCode {
|
||||||
|
if got == want {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (rg *runGroup) Output(args ...string) []byte {
|
func (rg *runGroup) Output(args ...string) []byte {
|
||||||
b, err := rg.Runner.output(args...)
|
b, err := rg.Runner.output(args...)
|
||||||
if rg.ErrAcc == nil && err != nil && errCode(err) != rg.OkCode {
|
if rg.ErrAcc == nil && err != nil && !rg.okCode(err) {
|
||||||
rg.ErrAcc = err
|
rg.ErrAcc = err
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
|
@ -83,7 +93,7 @@ func (rg *runGroup) Output(args ...string) []byte {
|
||||||
|
|
||||||
func (rg *runGroup) Run(args ...string) {
|
func (rg *runGroup) Run(args ...string) {
|
||||||
err := rg.Runner.run(args...)
|
err := rg.Runner.run(args...)
|
||||||
if rg.ErrAcc == nil && err != nil && errCode(err) != rg.OkCode {
|
if rg.ErrAcc == nil && err != nil && !rg.okCode(err) {
|
||||||
rg.ErrAcc = err
|
rg.ErrAcc = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue