Newer
Older
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)
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}
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
}
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
}