Simmplified RT Lookup. No more Metric in Query.
This commit is contained in:
parent
d3e200575c
commit
da299ea26b
@ -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()
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user