Newer
Older
"github.com/bio-routing/bio-rd/config"
bnet "github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/routingtable"
"github.com/bio-routing/bio-rd/routingtable/locRIB"
type PeerInfo struct {
PeerASN uint32
LocalASN uint32
}
type peer struct {
server *bgpServer
peerASN uint32
localASN uint32
// guarded by fsmsMu
fsms []*FSM
fsmsMu sync.Mutex
routerID uint32
addPathSend routingtable.ClientOptions
addPathRecv bool
reconnectInterval time.Duration
keepaliveTime time.Duration
holdTime time.Duration
optOpenParams []packet.OptParam
importFilter *filter.Filter
exportFilter *filter.Filter
func (p *peer) snapshot() PeerInfo {
return PeerInfo{
PeerAddr: p.addr,
PeerASN: p.peerASN,
LocalASN: p.localASN,
}
}
func (p *peer) collisionHandling(callingFSM *FSM) bool {
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
p.fsmsMu.Lock()
defer p.fsmsMu.Unlock()
for _, fsm := range p.fsms {
if callingFSM == fsm {
continue
}
fsm.stateMu.RLock()
isEstablished := isEstablishedState(fsm.state)
isOpenConfirm := isOpenConfirmState(fsm.state)
fsm.stateMu.RUnlock()
if isEstablished {
return true
}
if !isOpenConfirm {
continue
}
if p.routerID < callingFSM.neighborID {
fsm.cease()
} else {
return true
}
}
return false
}
func isOpenConfirmState(s state) bool {
switch s.(type) {
case openConfirmState:
return true
}
return false
}
func isEstablishedState(s state) bool {
switch s.(type) {
case establishedState:
return true
}
return false
// NewPeer creates a new peer with the given config. If an connection is established, the adjRIBIN of the peer is connected
// to the given rib. To actually connect the peer, call Start() on the returned peer.
func newPeer(c config.Peer, rib *locRIB.LocRIB, server *bgpServer) (*peer, error) {
if c.LocalAS == 0 {
c.LocalAS = server.localASN
}
p := &peer{
addr: c.PeerAddress,
rib: rib,
addPathSend: c.AddPathSend,
addPathRecv: c.AddPathRecv,
reconnectInterval: c.ReconnectInterval,
importFilter: filterOrDefault(c.ImportFilter),
exportFilter: filterOrDefault(c.ExportFilter),
addPathEnabled, addPathCap := handleAddPathCapability(c)
if addPathEnabled {
caps = append(caps, addPathCap)
p.optOpenParams = append(p.optOpenParams, packet.OptParam{
Type: packet.CapabilitiesParamType,
Value: caps,
})
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
func asn4Capability(c config.Peer) packet.Capability {
return packet.Capability{
Code: packet.ASN4CapabilityCode,
Value: packet.ASN4Capability{
ASN4: c.LocalAS,
},
}
}
func handleAddPathCapability(c config.Peer) (bool, packet.Capability) {
addPath := uint8(0)
if c.AddPathRecv {
addPath += packet.AddPathReceive
}
if !c.AddPathSend.BestOnly {
addPath += packet.AddPathSend
}
if addPath == 0 {
return false, packet.Capability{}
}
return true, packet.Capability{
Code: packet.AddPathCapabilityCode,
Value: packet.AddPathCapability{
AFI: packet.IPv4AFI,
SAFI: packet.UnicastSAFI,
SendReceive: addPath,
},
}
}
func filterOrDefault(f *filter.Filter) *filter.Filter {
if f != nil {
return f
}
return filter.NewDrainFilter()
}
// GetAddr returns the IP address of the peer
func (p *peer) GetAddr() bnet.IP {
func (p *peer) Start() {