声明
本章主要讲解gobgp中RIB表的流转。
1 RIB_in到local_Rib
gobgp在BgpServer的Serve方法中调用handlefsmMessage,实际是调用了handleFSMMessage(./pkg/server/server.go)处理BGP消息:
代码语言:go复制func (s *BgpServer) handleFSMMessage(peer *peer, e *fsmMsg) {
switch e.MsgType {
case fsmMsgStateChange:
...
case fsmMsgRouteRefresh:
...
case fsmMsgBGPMessage:
switch m := e.MsgData.(type) {
case *bgp.MessageError:
...
case *bgp.BGPMessage:
// 这里会通告给外部消息订阅者
s.notifyRecvMessageWatcher(peer, e.timestamp, m)
peer.fsm.lock.RLock()
notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED
beforeUptime := e.timestamp.Unix() < peer.fsm.pConf.Timers.State.Uptime
peer.fsm.lock.RUnlock()
if notEstablished || beforeUptime {
return
}
// 这里的handleUpdate会把路由写入peer的Rib_in中
pathList, eor, notification := peer.handleUpdate(e)
if notification != nil {
sendfsmOutgoingMsg(peer, nil, notification, true)
return
}
if m.Header.Type == bgp.BGP_MSG_UPDATE {
s.notifyPrePolicyUpdateWatcher(peer, pathList, m, e.timestamp, e.payload)
}
// propagateUpdate会写入local_Rib
if len(pathList) > 0 {
s.propagateUpdate(peer, pathList)
}
...
default:
...
}
}
}
代码语言:go复制func (s *BgpServer) propagateUpdate(peer *peer, pathList []*table.Path) {
...
for _, path := range pathList {
...
// rib.Update是更新local_Rib
if dsts := rib.Update(path); len(dsts) > 0 {
s.propagateUpdateToNeighbors(peer, path, dsts, true)
}
}
}
propagateUpdateToNeighbors➡processOutgoingPaths➡filterpath,这里会判断是否是增量,并且这里会判断是否是IBGP邻居。
2 Rib_out
留个坑
点评
长函数太多,需要跳着读,很多重要的细节在函数中又不怎么突出。