mirror of
https://github.com/netbirdio/go-netroute.git
synced 2026-05-22 17:11:07 -07:00
compare priority if route rule's dst mask is same size
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user