diff --git a/router/default.go b/router/default.go index 49f0ff1f..b77a3683 100644 --- a/router/default.go +++ b/router/default.go @@ -413,7 +413,13 @@ func (r *router) advertiseEvents() error { for { select { case <-ticker.C: + // If we're not advertising any events then sip processing them entirely + if r.options.Advertise == AdvertiseNone { + continue + } + var events []*Event + // collect all events which are not flapping for key, advert := range adverts { // process the advert @@ -426,6 +432,11 @@ func (r *router) advertiseEvents() error { continue } + // if we only advertise local routes skip processing anything not link local + if r.options.Advertise == AdvertiseLocal && advert.event.Route.Link != "local" { + continue + } + // copy the event and append e := new(Event) // this is ok, because router.Event only contains builtin types @@ -450,6 +461,17 @@ func (r *router) advertiseEvents() error { if e == nil { continue } + + // If we're not advertising any events then skip processing them entirely + if r.options.Advertise == AdvertiseNone { + continue + } + + // if we only advertise local routes skip processing anything not link local + if r.options.Advertise == AdvertiseLocal && e.Route.Link != "local" { + continue + } + now := time.Now() log.Debugf("Router processing table event %s for service %s %s", e.Type, e.Route.Service, e.Route.Address) @@ -708,12 +730,18 @@ func (r *router) Process(a *Advert) error { // flushRouteEvents returns a slice of events, one per each route in the routing table func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) { + // Do not advertise anything + if r.options.Advertise == AdvertiseNone { + return []*Event{}, nil + } + // list all routes routes, err := r.table.List() if err != nil { return nil, fmt.Errorf("failed listing routes: %s", err) } + // Return all the routes if r.options.Advertise == AdvertiseAll { // build a list of events to advertise events := make([]*Event, len(routes)) @@ -728,24 +756,34 @@ func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) { return events, nil } - // routeMap stores optimal routes per service + // routeMap stores the routes we're going to advertise bestRoutes := make(map[string]Route) + // set whether we're advertising only local + advertiseLocal := r.options.Advertise == AdvertiseLocal + // go through all routes found in the routing table and collapse them to optimal routes for _, route := range routes { + // if we're only advertising local routes + if advertiseLocal && route.Link != "local" { + continue + } + + // now we're going to find the best routes + routeKey := route.Service + "@" + route.Network - optimal, ok := bestRoutes[routeKey] + current, ok := bestRoutes[routeKey] if !ok { bestRoutes[routeKey] = route continue } // if the current optimal route metric is higher than routing table route, replace it - if optimal.Metric > route.Metric { + if current.Metric > route.Metric { bestRoutes[routeKey] = route continue } // if the metrics are the same, prefer advertising your own route - if optimal.Metric == route.Metric { + if current.Metric == route.Metric { if route.Router == r.options.Id { bestRoutes[routeKey] = route continue @@ -753,7 +791,7 @@ func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) { } } - log.Debugf("Router advertising %d best routes out of %d", len(bestRoutes), len(routes)) + log.Debugf("Router advertising %d %s routes out of %d", len(bestRoutes), r.options.Advertise, len(routes)) // build a list of events to advertise events := make([]*Event, len(bestRoutes)) diff --git a/router/router.go b/router/router.go index cd300e7e..e6018766 100644 --- a/router/router.go +++ b/router/router.go @@ -147,6 +147,10 @@ const ( AdvertiseAll Strategy = iota // AdvertiseBest advertises optimal routes to the network AdvertiseBest + // AdvertiseLocal will only advertise the local routes + AdvertiseLocal + // AdvertiseNone will not advertise any routes + AdvertiseNone ) // String returns human readable Strategy @@ -156,6 +160,10 @@ func (s Strategy) String() string { return "all" case AdvertiseBest: return "best" + case AdvertiseLocal: + return "local" + case AdvertiseNone: + return "none" default: return "unknown" }