diff --git a/lb/datapath.go b/lb/datapath.go index 5dd6c751..4c9a7982 100644 --- a/lb/datapath.go +++ b/lb/datapath.go @@ -295,8 +295,7 @@ func (dp *Datapath) routes(holders []Holder) error { return err } for _, rt := range routes { - rt := rt - if err := netlink.RouteDel(&rt); err != nil { + if err := delRoute(rt); err != nil { return fmt.Errorf("removing stale route in table %d: %v", table, err) } } @@ -324,3 +323,11 @@ func (dp *Datapath) routes(holders []Holder) error { } return nil } + +// delRoute deletes a route as RouteList returned it: a default route lists without Dst, which RouteDel refuses. +func delRoute(rt netlink.Route) error { + if rt.Dst == nil { + rt.Dst = &net.IPNet{IP: net.IPv4zero, Mask: net.CIDRMask(0, 32)} + } + return netlink.RouteDel(&rt) +} diff --git a/lb/egress_datapath.go b/lb/egress_datapath.go index baf6f92d..efdcfe70 100644 --- a/lb/egress_datapath.go +++ b/lb/egress_datapath.go @@ -213,11 +213,11 @@ func egressNet(e EgressDesired, self string, local Local) error { return err } for _, rt := range routes { - if want != nil && rt.Type == want.Type && rt.LinkIndex == want.LinkIndex && rt.Gw.Equal(want.Gw) { + if want != nil && rt.Type == want.Type && + (want.Type == unix.RTN_UNREACHABLE || rt.LinkIndex == want.LinkIndex && rt.Gw.Equal(want.Gw)) { continue } - rt := rt - if err := netlink.RouteDel(&rt); err != nil { + if err := delRoute(rt); err != nil { return fmt.Errorf("removing stale route in table %d: %v", table, err) } }