예제 #1
0
파일: path.go 프로젝트: mfeed/gobgp
//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)
}
예제 #2
0
파일: fsm.go 프로젝트: osrg/gobgp
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
}
예제 #3
0
파일: peer.go 프로젝트: osrg/gobgp
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
}
예제 #4
0
파일: peer.go 프로젝트: osrg/gobgp
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)
}
예제 #5
0
파일: peer.go 프로젝트: osrg/gobgp
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)
}
예제 #6
0
파일: util.go 프로젝트: osrg/gobgp
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
}
예제 #7
0
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
}
예제 #8
0
파일: peer.go 프로젝트: osrg/gobgp
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
}
예제 #9
0
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
}
예제 #10
0
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
}
예제 #11
0
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,
	}
}
예제 #12
0
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
}