Add the ability to only advertise local routes or don't advertise at all (#932)

* Add the ability to only advertise local routes or don't advertise at all

* Reorder processing to shortcircuit no advertising
This commit is contained in:
Asim Aslam 2019-11-11 15:28:37 +00:00 committed by GitHub
parent 65b1283459
commit fd5c29addc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 5 deletions

View File

@ -413,7 +413,13 @@ func (r *router) advertiseEvents() error {
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
// If we're not advertising any events then sip processing them entirely
if r.options.Advertise == AdvertiseNone {
continue
}
var events []*Event var events []*Event
// collect all events which are not flapping // collect all events which are not flapping
for key, advert := range adverts { for key, advert := range adverts {
// process the advert // process the advert
@ -426,6 +432,11 @@ func (r *router) advertiseEvents() error {
continue 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 // copy the event and append
e := new(Event) e := new(Event)
// this is ok, because router.Event only contains builtin types // this is ok, because router.Event only contains builtin types
@ -450,6 +461,17 @@ func (r *router) advertiseEvents() error {
if e == nil { if e == nil {
continue 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() now := time.Now()
log.Debugf("Router processing table event %s for service %s %s", e.Type, e.Route.Service, e.Route.Address) 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 // flushRouteEvents returns a slice of events, one per each route in the routing table
func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) { func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) {
// Do not advertise anything
if r.options.Advertise == AdvertiseNone {
return []*Event{}, nil
}
// list all routes // list all routes
routes, err := r.table.List() routes, err := r.table.List()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed listing routes: %s", err) return nil, fmt.Errorf("failed listing routes: %s", err)
} }
// Return all the routes
if r.options.Advertise == AdvertiseAll { if r.options.Advertise == AdvertiseAll {
// build a list of events to advertise // build a list of events to advertise
events := make([]*Event, len(routes)) events := make([]*Event, len(routes))
@ -728,24 +756,34 @@ func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) {
return events, nil return events, nil
} }
// routeMap stores optimal routes per service // routeMap stores the routes we're going to advertise
bestRoutes := make(map[string]Route) 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 // go through all routes found in the routing table and collapse them to optimal routes
for _, route := range 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 routeKey := route.Service + "@" + route.Network
optimal, ok := bestRoutes[routeKey] current, ok := bestRoutes[routeKey]
if !ok { if !ok {
bestRoutes[routeKey] = route bestRoutes[routeKey] = route
continue continue
} }
// if the current optimal route metric is higher than routing table route, replace it // 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 bestRoutes[routeKey] = route
continue continue
} }
// if the metrics are the same, prefer advertising your own route // 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 { if route.Router == r.options.Id {
bestRoutes[routeKey] = route bestRoutes[routeKey] = route
continue 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 // build a list of events to advertise
events := make([]*Event, len(bestRoutes)) events := make([]*Event, len(bestRoutes))

View File

@ -147,6 +147,10 @@ const (
AdvertiseAll Strategy = iota AdvertiseAll Strategy = iota
// AdvertiseBest advertises optimal routes to the network // AdvertiseBest advertises optimal routes to the network
AdvertiseBest AdvertiseBest
// AdvertiseLocal will only advertise the local routes
AdvertiseLocal
// AdvertiseNone will not advertise any routes
AdvertiseNone
) )
// String returns human readable Strategy // String returns human readable Strategy
@ -156,6 +160,10 @@ func (s Strategy) String() string {
return "all" return "all"
case AdvertiseBest: case AdvertiseBest:
return "best" return "best"
case AdvertiseLocal:
return "local"
case AdvertiseNone:
return "none"
default: default:
return "unknown" return "unknown"
} }