//export get_route_family func get_route_family(input *C.char) C.int { rf, err := bgp.GetRouteFamily(C.GoString(input)) if err != nil { return C.int(-1) } return C.int(rf) }
func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInterface { caps := make([]bgp.ParameterCapabilityInterface, 0, 4) caps = append(caps, bgp.NewCapRouteRefresh()) for _, rf := range pConf.AfiSafis { family, _ := bgp.GetRouteFamily(string(rf.Config.AfiSafiName)) caps = append(caps, bgp.NewCapMultiProtocol(family)) } caps = append(caps, bgp.NewCapFourOctetASNumber(pConf.Config.LocalAs)) if c := pConf.GracefulRestart.Config; c.Enabled { tuples := []*bgp.CapGracefulRestartTuple{} ltuples := []*bgp.CapLongLivedGracefulRestartTuple{} // RFC 4724 4.1 // To re-establish the session with its peer, the Restarting Speaker // MUST set the "Restart State" bit in the Graceful Restart Capability // of the OPEN message. restarting := pConf.GracefulRestart.State.LocalRestarting if !c.HelperOnly { for i, rf := range pConf.AfiSafis { k, _ := bgp.GetRouteFamily(string(rf.Config.AfiSafiName)) if m := rf.MpGracefulRestart.Config; m.Enabled { // When restarting, always flag forwaring bit. // This can be a lie, depending on how gobgpd is used. // For a route-server use-case, since a route-server // itself doesn't forward packets, and the dataplane // is a l2 switch which continues to work with no // relation to bgpd, this behavior is ok. // TODO consideration of other use-cases tuples = append(tuples, bgp.NewCapGracefulRestartTuple(k, restarting)) pConf.AfiSafis[i].MpGracefulRestart.State.Advertised = true } if m := rf.LongLivedGracefulRestart.Config; m.Enabled { ltuples = append(ltuples, bgp.NewCapLongLivedGracefulRestartTuple(k, restarting, m.RestartTime)) } } } time := c.RestartTime notification := c.NotificationEnabled caps = append(caps, bgp.NewCapGracefulRestart(restarting, notification, time, tuples)) if c.LongLivedEnabled { caps = append(caps, bgp.NewCapLongLivedGracefulRestart(ltuples)) } } return caps }
func (peer *Peer) llgrRestartTime(family bgp.RouteFamily) uint32 { for _, a := range peer.fsm.pConf.AfiSafis { if f, _ := bgp.GetRouteFamily(string(a.Config.AfiSafiName)); f == family { return a.LongLivedGracefulRestart.State.PeerRestartTime } } return 0 }
func (peer *Peer) llgrFamilies() ([]bgp.RouteFamily, []bgp.RouteFamily) { list := []bgp.RouteFamily{} for _, a := range peer.fsm.pConf.AfiSafis { if a.LongLivedGracefulRestart.State.Enabled { f, _ := bgp.GetRouteFamily(string(a.Config.AfiSafiName)) list = append(list, f) } } return classifyFamilies(peer.configuredRFlist(), list) }
func (peer *Peer) forwardingPreservedFamilies() ([]bgp.RouteFamily, []bgp.RouteFamily) { list := []bgp.RouteFamily{} for _, a := range peer.fsm.pConf.AfiSafis { if s := a.MpGracefulRestart.State; s.Enabled && s.Received { f, _ := bgp.GetRouteFamily(string(a.Config.AfiSafiName)) list = append(list, f) } } return classifyFamilies(peer.configuredRFlist(), list) }
func (c AfiSafis) ToRfList() ([]bgp.RouteFamily, error) { rfs := make([]bgp.RouteFamily, 0, len(c)) for _, rf := range c { k, err := bgp.GetRouteFamily(string(rf.Config.AfiSafiName)) if err != nil { return nil, fmt.Errorf("invalid address family: %s", rf.Config.AfiSafiName) } rfs = append(rfs, k) } return rfs, nil }
func (peer *Peer) updatePrefixLimitConfig(c []config.AfiSafi) ([]*SenderMsg, error) { x := peer.fsm.pConf.AfiSafis y := c if len(x) != len(y) { return nil, fmt.Errorf("changing supported afi-safi is not allowed") } m := make(map[bgp.RouteFamily]config.PrefixLimitConfig) for _, e := range x { k, err := bgp.GetRouteFamily(string(e.Config.AfiSafiName)) if err != nil { return nil, err } m[k] = e.PrefixLimit.Config } msgs := make([]*SenderMsg, 0, len(y)) for _, e := range y { k, err := bgp.GetRouteFamily(string(e.Config.AfiSafiName)) if err != nil { return nil, err } if p, ok := m[k]; !ok { return nil, fmt.Errorf("changing supported afi-safi is not allowed") } else if !p.Equal(&e.PrefixLimit.Config) { log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.ID(), "AddressFamily": e.Config.AfiSafiName, "OldMaxPrefixes": p.MaxPrefixes, "NewMaxPrefixes": e.PrefixLimit.Config.MaxPrefixes, "OldShutdownThresholdPct": p.ShutdownThresholdPct, "NewShutdownThresholdPct": e.PrefixLimit.Config.ShutdownThresholdPct, }).Warnf("update prefix limit configuration") peer.prefixLimitWarned[k] = false if msg := peer.doPrefixLimit(k, &e.PrefixLimit.Config); msg != nil { msgs = append(msgs, newSenderMsg(peer, nil, msg, true)) } } } peer.fsm.pConf.AfiSafis = c return msgs, nil }
func (peer *Peer) llgrRestartTimerExpired(family bgp.RouteFamily) bool { all := true for _, a := range peer.fsm.pConf.AfiSafis { if f, _ := bgp.GetRouteFamily(string(a.Config.AfiSafiName)); f == family { a.LongLivedGracefulRestart.State.PeerRestartTimerExpired = true } s := a.LongLivedGracefulRestart.State if s.Received && !s.PeerRestartTimerExpired { all = false } } return all }
func (peer *Peer) handleUpdate(e *FsmMsg) ([]*table.Path, []bgp.RouteFamily, *bgp.BGPMessage) { m := e.MsgData.(*bgp.BGPMessage) update := m.Body.(*bgp.BGPUpdate) log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.fsm.pConf.Config.NeighborAddress, "nlri": update.NLRI, "withdrawals": update.WithdrawnRoutes, "attributes": update.PathAttributes, }).Debug("received update") peer.fsm.pConf.Timers.State.UpdateRecvTime = time.Now().Unix() if len(e.PathList) > 0 { peer.adjRibIn.Update(e.PathList) for _, family := range peer.fsm.pConf.AfiSafis { k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName)) if msg := peer.doPrefixLimit(k, &family.PrefixLimit.Config); msg != nil { return nil, nil, msg } } paths := make([]*table.Path, 0, len(e.PathList)) eor := []bgp.RouteFamily{} for _, path := range e.PathList { if path.IsEOR() { family := path.GetRouteFamily() log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.ID(), "AddressFamily": family, }).Debug("EOR received") eor = append(eor, family) continue } if path.Filtered(peer.ID()) != table.POLICY_DIRECTION_IN { paths = append(paths, path) } } return paths, eor, nil } return nil, nil, nil }
func (peer *Peer) forwardingPreservedFamilies() ([]bgp.RouteFamily, []bgp.RouteFamily) { list := []bgp.RouteFamily{} for _, a := range peer.fsm.pConf.AfiSafis { if s := a.MpGracefulRestart.State; s.Enabled && s.Received { f, _ := bgp.GetRouteFamily(string(a.Config.AfiSafiName)) list = append(list, f) } } preserved := []bgp.RouteFamily{} notPreserved := []bgp.RouteFamily{} for _, f := range peer.configuredRFlist() { p := true for _, g := range list { if f == g { p = false preserved = append(preserved, f) } } if p { notPreserved = append(notPreserved, f) } } return preserved, notPreserved }
func (peer *Peer) ToApiStruct() *api.Peer { f := peer.fsm c := f.pConf remoteCap := make([][]byte, 0, len(peer.fsm.capMap)) for _, c := range peer.fsm.capMap { for _, m := range c { buf, _ := m.Serialize() remoteCap = append(remoteCap, buf) } } caps := capabilitiesFromConfig(peer.fsm.pConf) localCap := make([][]byte, 0, len(caps)) for _, c := range caps { buf, _ := c.Serialize() localCap = append(localCap, buf) } prefixLimits := make([]*api.PrefixLimit, 0, len(peer.fsm.pConf.AfiSafis)) for _, family := range peer.fsm.pConf.AfiSafis { if c := family.PrefixLimit.Config; c.MaxPrefixes > 0 { k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName)) prefixLimits = append(prefixLimits, &api.PrefixLimit{ Family: uint32(k), MaxPrefixes: c.MaxPrefixes, ShutdownThresholdPct: uint32(c.ShutdownThresholdPct), }) } } conf := &api.PeerConf{ NeighborAddress: c.Config.NeighborAddress, Id: peer.fsm.peerInfo.ID.To4().String(), PeerAs: c.Config.PeerAs, LocalAs: c.Config.LocalAs, PeerType: uint32(c.Config.PeerType.ToInt()), AuthPassword: c.Config.AuthPassword, RemovePrivateAs: uint32(c.Config.RemovePrivateAs.ToInt()), RouteFlapDamping: c.Config.RouteFlapDamping, SendCommunity: uint32(c.Config.SendCommunity.ToInt()), Description: c.Config.Description, PeerGroup: c.Config.PeerGroup, RemoteCap: remoteCap, LocalCap: localCap, PrefixLimits: prefixLimits, } timer := c.Timers s := c.State advertised := uint32(0) received := uint32(0) accepted := uint32(0) if f.state == bgp.BGP_FSM_ESTABLISHED { rfList := peer.configuredRFlist() advertised = uint32(peer.adjRibOut.Count(rfList)) received = uint32(peer.adjRibIn.Count(rfList)) accepted = uint32(peer.adjRibIn.Accepted(rfList)) } uptime := int64(0) if timer.State.Uptime != 0 { uptime = timer.State.Uptime } downtime := int64(0) if timer.State.Downtime != 0 { downtime = timer.State.Downtime } timerconf := &api.TimersConfig{ ConnectRetry: uint64(timer.Config.ConnectRetry), HoldTime: uint64(timer.Config.HoldTime), KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), } timerstate := &api.TimersState{ KeepaliveInterval: uint64(timer.State.KeepaliveInterval), NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), Uptime: uint64(uptime), Downtime: uint64(downtime), } apitimer := &api.Timers{ Config: timerconf, State: timerstate, } msgrcv := &api.Message{ NOTIFICATION: s.Messages.Received.Notification, UPDATE: s.Messages.Received.Update, OPEN: s.Messages.Received.Open, KEEPALIVE: s.Messages.Received.Keepalive, REFRESH: s.Messages.Received.Refresh, DISCARDED: s.Messages.Received.Discarded, TOTAL: s.Messages.Received.Total, } msgsnt := &api.Message{ NOTIFICATION: s.Messages.Sent.Notification, UPDATE: s.Messages.Sent.Update, OPEN: s.Messages.Sent.Open, KEEPALIVE: s.Messages.Sent.Keepalive, REFRESH: s.Messages.Sent.Refresh, DISCARDED: s.Messages.Sent.Discarded, TOTAL: s.Messages.Sent.Total, } msg := &api.Messages{ Received: msgrcv, Sent: msgsnt, } info := &api.PeerState{ BgpState: f.state.String(), AdminState: f.adminState.String(), Messages: msg, Received: received, Accepted: accepted, Advertised: advertised, } rr := &api.RouteReflector{ RouteReflectorClient: peer.fsm.pConf.RouteReflector.Config.RouteReflectorClient, RouteReflectorClusterId: string(peer.fsm.pConf.RouteReflector.Config.RouteReflectorClusterId), } rs := &api.RouteServer{ RouteServerClient: peer.fsm.pConf.RouteServer.Config.RouteServerClient, } return &api.Peer{ Conf: conf, Info: info, Timers: apitimer, RouteReflector: rr, RouteServer: rs, } }
func (s *Server) GetNeighbor(ctx context.Context, arg *GetNeighborRequest) (*GetNeighborResponse, error) { toApi := func(pconf *config.Neighbor) *Peer { prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis)) for _, family := range pconf.AfiSafis { if c := family.PrefixLimit.Config; c.MaxPrefixes > 0 { k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName)) prefixLimits = append(prefixLimits, &PrefixLimit{ Family: uint32(k), MaxPrefixes: c.MaxPrefixes, ShutdownThresholdPct: uint32(c.ShutdownThresholdPct), }) } } timer := pconf.Timers s := pconf.State localAddress := pconf.Transport.Config.LocalAddress if pconf.Transport.State.LocalAddress != "" { localAddress = pconf.Transport.State.LocalAddress } return &Peer{ Conf: &PeerConf{ NeighborAddress: pconf.Config.NeighborAddress, Id: s.RemoteRouterId, PeerAs: pconf.Config.PeerAs, LocalAs: pconf.Config.LocalAs, PeerType: uint32(pconf.Config.PeerType.ToInt()), AuthPassword: pconf.Config.AuthPassword, RemovePrivateAs: uint32(pconf.Config.RemovePrivateAs.ToInt()), RouteFlapDamping: pconf.Config.RouteFlapDamping, SendCommunity: uint32(pconf.Config.SendCommunity.ToInt()), Description: pconf.Config.Description, PeerGroup: pconf.Config.PeerGroup, RemoteCap: s.Capabilities.RemoteList, LocalCap: s.Capabilities.LocalList, PrefixLimits: prefixLimits, LocalAddress: localAddress, NeighborInterface: pconf.Config.NeighborInterface, }, Info: &PeerState{ BgpState: bgp.FSMState(s.SessionState.ToInt()).String(), AdminState: s.AdminState, Messages: &Messages{ Received: &Message{ NOTIFICATION: s.Messages.Received.Notification, UPDATE: s.Messages.Received.Update, OPEN: s.Messages.Received.Open, KEEPALIVE: s.Messages.Received.Keepalive, REFRESH: s.Messages.Received.Refresh, DISCARDED: s.Messages.Received.Discarded, TOTAL: s.Messages.Received.Total, }, Sent: &Message{ NOTIFICATION: s.Messages.Sent.Notification, UPDATE: s.Messages.Sent.Update, OPEN: s.Messages.Sent.Open, KEEPALIVE: s.Messages.Sent.Keepalive, REFRESH: s.Messages.Sent.Refresh, DISCARDED: s.Messages.Sent.Discarded, TOTAL: s.Messages.Sent.Total, }, }, Received: s.AdjTable.Received, Accepted: s.AdjTable.Accepted, Advertised: s.AdjTable.Advertised, }, Timers: &Timers{ Config: &TimersConfig{ ConnectRetry: uint64(timer.Config.ConnectRetry), HoldTime: uint64(timer.Config.HoldTime), KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), }, State: &TimersState{ KeepaliveInterval: uint64(timer.State.KeepaliveInterval), NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), Uptime: uint64(timer.State.Uptime), Downtime: uint64(timer.State.Downtime), }, }, RouteReflector: &RouteReflector{ RouteReflectorClient: pconf.RouteReflector.Config.RouteReflectorClient, RouteReflectorClusterId: string(pconf.RouteReflector.Config.RouteReflectorClusterId), }, RouteServer: &RouteServer{ RouteServerClient: pconf.RouteServer.Config.RouteServerClient, }, } } p := []*Peer{} for _, e := range s.bgpServer.GetNeighbor() { p = append(p, toApi(e)) } return &GetNeighborResponse{Peers: p}, nil }