解读gobgp(四)

2023-05-04 17:24:09 浏览数 (1)

声明

本章主要讲解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

留个坑

点评

长函数太多,需要跳着读,很多重要的细节在函数中又不怎么突出。

0 人点赞