Skip to content
Snippets Groups Projects
bgp.go 1.64 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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
    }