Simmplified RT Lookup. No more Metric in Query.

This commit is contained in:
Milos Gajdos 2019-07-01 20:33:08 +01:00
parent d3e200575c
commit da299ea26b
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F
3 changed files with 47 additions and 56 deletions

View File

@ -232,7 +232,11 @@ func (r *router) watchError(errChan <-chan error) {
// stop the router if some error happened // stop the router if some error happened
if err != nil && code != Stopped { if err != nil && code != Stopped {
// this will stop watchers which will close r.advertChan
close(r.exit) close(r.exit)
// drain the advertise channel
for range r.advertChan {
}
} }
} }
@ -343,12 +347,11 @@ func (r *router) Stop() error {
if r.status.Code == Running { if r.status.Code == Running {
// notify all goroutines to finish // notify all goroutines to finish
close(r.exit) close(r.exit)
}
r.RUnlock()
// drain the advertise channel // drain the advertise channel
for range r.advertChan { for range r.advertChan {
} }
}
r.RUnlock()
// wait for all goroutines to finish // wait for all goroutines to finish
r.wg.Wait() r.wg.Wait()

View File

@ -163,45 +163,45 @@ func (t *table) List() ([]Route, error) {
return routes, nil return routes, nil
} }
// Lookup queries routing table and returns all routes that match it // isMatch checks if the route matches given network and router
func isMatch(route Route, network, router string) bool {
if network == "*" || network == route.Network {
if router == "*" || router == route.Router {
return true
}
}
return false
}
// findRoutes finds all the routes for given network and router and returns them
func findRoutes(routes map[uint64]Route, network, router string) []Route {
var results []Route
for _, route := range routes {
if isMatch(route, network, router) {
results = append(results, route)
}
}
return results
}
// Lookup queries routing table and returns all routes that match the lookup query
func (t *table) Lookup(q Query) ([]Route, error) { func (t *table) Lookup(q Query) ([]Route, error) {
t.RLock() t.RLock()
defer t.RUnlock() defer t.RUnlock()
var results []Route
for destAddr, routes := range t.m {
if q.Options().Destination != "*" { if q.Options().Destination != "*" {
if q.Options().Destination != destAddr { // no routes found for the destination and query policy is not a DiscardIfNone
continue if _, ok := t.m[q.Options().Destination]; !ok && q.Options().Policy != DiscardIfNone {
}
for _, route := range routes {
if q.Options().Network == "*" || q.Options().Network == route.Network {
if q.Options().Router == "*" {
if route.Metric <= q.Options().Metric {
results = append(results, route)
}
}
}
}
}
if q.Options().Destination == "*" {
for _, route := range routes {
if q.Options().Network == "*" || q.Options().Network == route.Network {
if q.Options().Router == "*" {
if route.Metric <= q.Options().Metric {
results = append(results, route)
}
}
}
}
}
}
if len(results) == 0 && q.Options().Policy != DiscardIfNone {
return nil, ErrRouteNotFound return nil, ErrRouteNotFound
} }
return findRoutes(t.m[q.Options().Destination], q.Options().Network, q.Options().Router), nil
}
var results []Route
// search through all destinations
for _, routes := range t.m {
results = append(results, findRoutes(routes, q.Options().Network, q.Options().Router)...)
}
return results, nil return results, nil
} }

View File

@ -36,44 +36,35 @@ type QueryOption func(*QueryOptions)
type QueryOptions struct { type QueryOptions struct {
// Destination is destination address // Destination is destination address
Destination string Destination string
// Router is router address
Router string
// Network is network address // Network is network address
Network string Network string
// Metric is route metric // Router is router address
Metric int Router string
// Policy is query lookup policy // Policy is query lookup policy
Policy LookupPolicy Policy LookupPolicy
} }
// QueryDestination sets query destination address // QueryDestination sets destination address
func QueryDestination(a string) QueryOption { func QueryDestination(d string) QueryOption {
return func(o *QueryOptions) { return func(o *QueryOptions) {
o.Destination = a o.Destination = d
} }
} }
// QueryNetwork sets query network address // QueryNetwork sets route network address
func QueryNetwork(a string) QueryOption { func QueryNetwork(a string) QueryOption {
return func(o *QueryOptions) { return func(o *QueryOptions) {
o.Network = a o.Network = a
} }
} }
// QueryRouter sets query gateway address // QueryRouter sets route router address
func QueryRouter(r string) QueryOption { func QueryRouter(r string) QueryOption {
return func(o *QueryOptions) { return func(o *QueryOptions) {
o.Router = r o.Router = r
} }
} }
// QueryMetric sets query metric
func QueryMetric(m int) QueryOption {
return func(o *QueryOptions) {
o.Metric = m
}
}
// QueryPolicy sets query policy // QueryPolicy sets query policy
// NOTE: this might be renamed to filter or some such // NOTE: this might be renamed to filter or some such
func QueryPolicy(p LookupPolicy) QueryOption { func QueryPolicy(p LookupPolicy) QueryOption {
@ -99,9 +90,7 @@ func NewQuery(opts ...QueryOption) Query {
// NOTE: by default we use DefaultNetworkMetric // NOTE: by default we use DefaultNetworkMetric
qopts := QueryOptions{ qopts := QueryOptions{
Destination: "*", Destination: "*",
Router: "*",
Network: "*", Network: "*",
Metric: DefaultNetworkMetric,
Policy: DiscardIfNone, Policy: DiscardIfNone,
} }
@ -126,13 +115,12 @@ func (q query) String() string {
// create nice table printing structure // create nice table printing structure
table := tablewriter.NewWriter(sb) table := tablewriter.NewWriter(sb)
table.SetHeader([]string{"Destination", "Router", "Network", "Metric", "Policy"}) table.SetHeader([]string{"Destination", "Network", "Router", "Policy"})
strQuery := []string{ strQuery := []string{
q.opts.Destination, q.opts.Destination,
q.opts.Router,
q.opts.Network, q.opts.Network,
fmt.Sprintf("%d", q.opts.Metric), q.opts.Router,
fmt.Sprintf("%s", q.opts.Policy), fmt.Sprintf("%s", q.opts.Policy),
} }
table.Append(strQuery) table.Append(strQuery)