package route // BGPPath represents a set of BGP path attributes type BGPPath struct { PathIdentifier uint32 NextHop uint32 LocalPref uint32 ASPath string ASPathLen uint16 Origin uint8 MED uint32 EBGP bool BGPIdentifier uint32 Source uint32 } func (r *Route) bgpPathSelection() (best *Path, active []*Path) { // TODO: Implement next hop lookup and compare IGP metrics for _, p := range r.paths { if p.Type != BGPPathType { continue } if len(active) == 0 { active = append(active, p) best = p continue } if active[0].BGPPath.ecmp(p.BGPPath) { active = append(active, p) if !r.bestPath.BGPPath.better(p.BGPPath) { continue } best = p continue } if !active[0].BGPPath.betterECMP(p.BGPPath) { continue } active = []*Path{p} best = p } return best, active } func (b *BGPPath) betterECMP(c *BGPPath) bool { if c.LocalPref < b.LocalPref { return false } if c.LocalPref > b.LocalPref { return true } if c.ASPathLen > b.ASPathLen { return false } if c.ASPathLen < b.ASPathLen { return true } if c.Origin > b.Origin { return false } if c.Origin < b.Origin { return true } if c.MED > b.MED { return false } if c.MED < b.MED { return true } return false } func (b *BGPPath) better(c *BGPPath) bool { if b.betterECMP(c) { return true } if c.BGPIdentifier < b.BGPIdentifier { return true } if c.Source < b.Source { return true } return false } func (b *BGPPath) ecmp(c *BGPPath) bool { return b.LocalPref == c.LocalPref && b.ASPathLen == c.ASPathLen && b.Origin == c.Origin && b.MED == c.MED }