compare priority if route rule's dst mask is same size

This commit is contained in:
snyh
2022-09-23 18:21:54 +02:00
committed by Will
parent 7efb0a3716
commit 6bd210a0eb
+30 -18
View File
@@ -27,6 +27,34 @@ type rtInfo struct {
Priority uint32
}
func (rt rtInfo) IsMoreSpecThan(mostSpecificRt *rtInfo) bool {
if mostSpecificRt == nil {
return true
}
var candSpec, curSpec int
if rt.Dst != nil {
candSpec, _ = rt.Dst.Mask.Size()
}
if mostSpecificRt.Dst != nil {
curSpec, _ = mostSpecificRt.Dst.Mask.Size()
}
if candSpec > curSpec {
return true
} else if candSpec < curSpec {
return false
}
// Windows and MacOS hasn't metric/priority on rule entry,
// But the interface device has the priority property.
//
// Before we find more correctly way on different OS platform,
// we keep the same rule selecting logical as before which
// is more later more special
return mostSpecificRt.Priority >= rt.Priority
}
// routeSlice implements sort.Interface to sort routes by Priority.
type routeSlice []*rtInfo
@@ -121,25 +149,9 @@ func (r *router) route(routes routeSlice, input net.HardwareAddr, src, dst net.I
if rt.Dst != nil && !rt.Dst.Contains(dst) {
continue
}
if mostSpecificRt != nil {
var candSpec, curSpec int
if rt.Dst != nil {
candSpec, _ = rt.Dst.Mask.Size()
}
if mostSpecificRt.Dst != nil {
curSpec, _ = mostSpecificRt.Dst.Mask.Size()
}
if candSpec < curSpec {
continue
} else if candSpec == curSpec {
// it must use `<=` instead `<` because routes are sort by priority,
// we should treat earlier rtInfo more specific
if mostSpecificRt.Priority <= rt.Priority {
continue
}
}
if rt.IsMoreSpecThan(mostSpecificRt) {
mostSpecificRt = rt
}
mostSpecificRt = rt
}
if mostSpecificRt != nil {
return int(mostSpecificRt.OutputIface), mostSpecificRt.Gateway, mostSpecificRt.PrefSrc, nil