summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/grpc_server.go15
-rw-r--r--config/default.go2
-rw-r--r--gobgp/cmd/monitor.go12
-rw-r--r--gobgp/cmd/neighbor.go32
-rw-r--r--packet/bgp/validate.go12
-rw-r--r--server/fsm.go24
-rw-r--r--server/peer.go2
-rw-r--r--server/server.go58
-rw-r--r--server/server_test.go4
-rw-r--r--table/path.go6
10 files changed, 105 insertions, 62 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go
index 9fc66bde..33ee13c5 100644
--- a/api/grpc_server.go
+++ b/api/grpc_server.go
@@ -195,6 +195,8 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
Received: s.AdjTable.Received,
Accepted: s.AdjTable.Accepted,
Advertised: s.AdjTable.Advertised,
+ PeerAs: s.PeerAs,
+ PeerType: uint32(s.PeerType.ToInt()),
},
Timers: &Timers{
Config: &TimersConfig{
@@ -429,15 +431,16 @@ func (s *Server) MonitorPeerState(arg *Arguments, stream GobgpApi_MonitorPeerSta
case ev := <-w.Event():
switch msg := ev.(type) {
case *server.WatchEventPeerState:
- if len(arg.Name) > 0 && arg.Name != msg.PeerAddress.String() {
+ if len(arg.Name) > 0 && arg.Name != msg.PeerAddress.String() && arg.Name != msg.PeerInterface {
continue
}
if err := stream.Send(&Peer{
Conf: &PeerConf{
- PeerAs: msg.PeerAS,
- LocalAs: msg.LocalAS,
- NeighborAddress: msg.PeerAddress.String(),
- Id: msg.PeerID.String(),
+ PeerAs: msg.PeerAS,
+ LocalAs: msg.LocalAS,
+ NeighborAddress: msg.PeerAddress.String(),
+ Id: msg.PeerID.String(),
+ NeighborInterface: msg.PeerInterface,
},
Info: &PeerState{
PeerAs: msg.PeerAS,
@@ -961,6 +964,8 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
pconf.State.AdjTable.Received = a.Info.Received
pconf.State.AdjTable.Accepted = a.Info.Accepted
pconf.State.AdjTable.Advertised = a.Info.Advertised
+ pconf.State.PeerAs = a.Info.PeerAs
+ pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)]
if a.Info.Messages != nil {
if a.Info.Messages.Sent != nil {
diff --git a/config/default.go b/config/default.go
index 92c743dd..094afb2b 100644
--- a/config/default.go
+++ b/config/default.go
@@ -105,6 +105,8 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
n.Config.PeerType = PEER_TYPE_INTERNAL
}
+ n.State.PeerAs = n.Config.PeerAs
+
if !v.IsSet("neighbor.timers.config.connect-retry") && n.Timers.Config.ConnectRetry == 0 {
n.Timers.Config.ConnectRetry = float64(DEFAULT_CONNECT_RETRY)
}
diff --git a/gobgp/cmd/monitor.go b/gobgp/cmd/monitor.go
index 8a7866b1..661b6c24 100644
--- a/gobgp/cmd/monitor.go
+++ b/gobgp/cmd/monitor.go
@@ -74,11 +74,7 @@ func NewMonitorCmd() *cobra.Command {
neighborCmd := &cobra.Command{
Use: CMD_NEIGHBOR,
Run: func(cmd *cobra.Command, args []string) {
- var names []string
- if len(args) > 0 {
- names = []string{args[0]}
- }
- stream, err := client.MonitorNeighborState(names...)
+ stream, err := client.MonitorNeighborState(args...)
if err != nil {
exitWithError(err)
}
@@ -93,7 +89,11 @@ func NewMonitorCmd() *cobra.Command {
j, _ := json.Marshal(s)
fmt.Println(string(j))
} else {
- fmt.Printf("[NEIGH] %s fsm: %s admin: %s\n", s.Config.NeighborAddress, s.State.SessionState, s.State.AdminState)
+ addr := s.Config.NeighborAddress
+ if s.Config.NeighborInterface != "" {
+ addr = fmt.Sprintf("%s(%s)", addr, s.Config.NeighborInterface)
+ }
+ fmt.Printf("[NEIGH] %s fsm: %s admin: %s\n", addr, s.State.SessionState, s.State.AdminState)
}
}
},
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index 5ab7e32c..b39c1a56 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -53,6 +53,14 @@ func getNeighbor(name string, enableAdvertised bool) (*config.Neighbor, error) {
return client.GetNeighbor(name, enableAdvertised)
}
+func getASN(p *config.Neighbor) string {
+ asn := "*"
+ if p.State.PeerAs > 0 {
+ asn = fmt.Sprint(p.State.PeerAs)
+ }
+ return asn
+}
+
func showNeighbors(vrf string) error {
m, err := getNeighbors(vrf)
if err != nil {
@@ -71,7 +79,7 @@ func showNeighbors(vrf string) error {
return nil
}
maxaddrlen := 0
- maxaslen := 0
+ maxaslen := 2
maxtimelen := len("Up/Down")
timedelta := []string{}
@@ -84,8 +92,8 @@ func showNeighbors(vrf string) error {
} else if j := len(n.Config.NeighborAddress); j > maxaddrlen {
maxaddrlen = j
}
- if len(fmt.Sprint(n.Config.PeerAs)) > maxaslen {
- maxaslen = len(fmt.Sprint(n.Config.PeerAs))
+ if l := len(getASN(n)); l > maxaslen {
+ maxaslen = l
}
timeStr := "never"
if n.Timers.State.Uptime != 0 {
@@ -135,7 +143,7 @@ func showNeighbors(vrf string) error {
if n.Config.NeighborInterface != "" {
neigh = n.Config.NeighborInterface
}
- fmt.Printf(format, neigh, fmt.Sprint(n.Config.PeerAs), timedelta[i], format_fsm(n.State.AdminState, n.State.SessionState), fmt.Sprint(n.State.AdjTable.Received), fmt.Sprint(n.State.AdjTable.Accepted))
+ fmt.Printf(format, neigh, getASN(n), timedelta[i], format_fsm(n.State.AdminState, n.State.SessionState), fmt.Sprint(n.State.AdjTable.Received), fmt.Sprint(n.State.AdjTable.Accepted))
}
return nil
@@ -152,7 +160,7 @@ func showNeighbor(args []string) error {
return nil
}
- fmt.Printf("BGP neighbor is %s, remote AS %d", p.Config.NeighborAddress, p.Config.PeerAs)
+ fmt.Printf("BGP neighbor is %s, remote AS %s", p.Config.NeighborAddress, getASN(p))
if p.RouteReflector.Config.RouteReflectorClient {
fmt.Printf(", route-reflector-client\n")
@@ -311,13 +319,13 @@ func showNeighbor(args []string) error {
}
return strings.Join(lines, "\n")
}
- if m := lookup(c, p.Conf.LocalCap); m != nil {
+ if m := lookup(c, p.State.LocalCapabilityList); m != nil {
e := m.(*bgp.CapExtendedNexthop)
if s := exnhStr(e); len(s) > 0 {
fmt.Printf(" Local: %s\n", s)
}
}
- if m := lookup(c, p.Conf.RemoteCap); m != nil {
+ if m := lookup(c, p.State.LocalCapabilityList); m != nil {
e := m.(*bgp.CapExtendedNexthop)
if s := exnhStr(e); len(s) > 0 {
fmt.Printf(" Remote: %s\n", s)
@@ -849,13 +857,15 @@ func modNeighbor(cmdType string, args []string) error {
var err error
switch cmdType {
case CMD_ADD:
- if len(m["as"]) != 1 {
+ if len(m[""]) > 0 && len(m["as"]) != 1 {
return fmt.Errorf("%s", usage)
}
var as int
- as, err = strconv.Atoi(m["as"][0])
- if err != nil {
- return err
+ if len(m["as"]) > 0 {
+ as, err = strconv.Atoi(m["as"][0])
+ if err != nil {
+ return err
+ }
}
err = client.AddNeighbor(getConf(as))
case CMD_DEL:
diff --git a/packet/bgp/validate.go b/packet/bgp/validate.go
index 5cf2afbb..13c66a77 100644
--- a/packet/bgp/validate.go
+++ b/packet/bgp/validate.go
@@ -230,9 +230,9 @@ func ValidateBGPMessage(m *BGPMessage) error {
return nil
}
-func ValidateOpenMsg(m *BGPOpen, expectedAS uint32) error {
+func ValidateOpenMsg(m *BGPOpen, expectedAS uint32) (uint32, error) {
if m.Version != 4 {
- return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER, nil, fmt.Sprintf("upsuppored version %d", m.Version))
+ return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER, nil, fmt.Sprintf("upsuppored version %d", m.Version))
}
as := uint32(m.MyAS)
@@ -248,12 +248,12 @@ func ValidateOpenMsg(m *BGPOpen, expectedAS uint32) error {
}
}
}
- if as != expectedAS {
- return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_BAD_PEER_AS, nil, fmt.Sprintf("as number mismatch expected %d, received %d", expectedAS, as))
+ if expectedAS != 0 && as != expectedAS {
+ return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_BAD_PEER_AS, nil, fmt.Sprintf("as number mismatch expected %d, received %d", expectedAS, as))
}
if m.HoldTime < 3 && m.HoldTime != 0 {
- return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNACCEPTABLE_HOLD_TIME, nil, fmt.Sprintf("unacceptable hold time %d", m.HoldTime))
+ return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNACCEPTABLE_HOLD_TIME, nil, fmt.Sprintf("unacceptable hold time %d", m.HoldTime))
}
- return nil
+ return as, nil
}
diff --git a/server/fsm.go b/server/fsm.go
index e680f8ec..f623f399 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -474,9 +474,9 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
break
}
fsm.conn = conn
- if fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
+ if fsm.pConf.Config.PeerAs != 0 && fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
ttl := 1
- if fsm.pConf.EbgpMultihop.Config.Enabled == true {
+ if fsm.pConf.EbgpMultihop.Config.Enabled {
ttl = int(fsm.pConf.EbgpMultihop.Config.MultihopTtl)
}
if ttl != 0 {
@@ -844,11 +844,29 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
if m.Header.Type == bgp.BGP_MSG_OPEN {
fsm.recvOpen = m
body := m.Body.(*bgp.BGPOpen)
- err := bgp.ValidateOpenMsg(body, fsm.pConf.Config.PeerAs)
+ peerAs, err := bgp.ValidateOpenMsg(body, fsm.pConf.Config.PeerAs)
if err != nil {
fsm.sendNotificationFromErrorMsg(err.(*bgp.MessageError))
return bgp.BGP_FSM_IDLE, FSM_INVALID_MSG
}
+
+ // ASN negotiation was skipped
+ if fsm.pConf.Config.PeerAs == 0 {
+ typ := config.PEER_TYPE_EXTERNAL
+ if fsm.peerInfo.LocalAS == peerAs {
+ typ = config.PEER_TYPE_INTERNAL
+ }
+ fsm.pConf.State.PeerType = typ
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": fsm.pConf.Config.NeighborAddress,
+ "State": fsm.state.String(),
+ }).Infof("skiped asn negotiation: peer-as: %d, peer-type: %s", peerAs, typ)
+ } else {
+ fsm.pConf.State.PeerType = fsm.pConf.Config.PeerType
+ }
+ fsm.pConf.State.PeerAs = peerAs
+ fsm.peerInfo.AS = peerAs
fsm.peerInfo.ID = body.ID
fsm.capMap, fsm.rfMap = open2Cap(body, fsm.pConf)
diff --git a/server/peer.go b/server/peer.go
index 96e014db..15029bd6 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -69,7 +69,7 @@ func (peer *Peer) TableID() string {
}
func (peer *Peer) isIBGPPeer() bool {
- return peer.fsm.pConf.Config.PeerAs == peer.fsm.gConf.Config.As
+ return peer.fsm.pConf.State.PeerAs == peer.fsm.gConf.Config.As
}
func (peer *Peer) isRouteServerClient() bool {
diff --git a/server/server.go b/server/server.go
index 8260e566..5238c33b 100644
--- a/server/server.go
+++ b/server/server.go
@@ -288,7 +288,7 @@ func sendFsmOutgoingMsg(peer *Peer, paths []*table.Path, notification *bgp.BGPMe
func isASLoop(peer *Peer, path *table.Path) bool {
for _, as := range path.GetAsList() {
- if as == peer.fsm.pConf.Config.PeerAs {
+ if as == peer.fsm.pConf.State.PeerAs {
return true
}
}
@@ -329,7 +329,7 @@ func filterpath(peer *Peer, path, old *table.Path) *table.Path {
ignore = true
info := path.GetSource()
//if the path comes from eBGP peer
- if info.AS != peer.fsm.pConf.Config.PeerAs {
+ if info.AS != peer.fsm.pConf.State.PeerAs {
ignore = false
}
// RFC4456 8. Avoiding Routing Information Loops
@@ -509,18 +509,19 @@ func createWatchEventPeerState(peer *Peer) *WatchEventPeerState {
sentOpen := buildopen(peer.fsm.gConf, peer.fsm.pConf)
recvOpen := peer.fsm.recvOpen
return &WatchEventPeerState{
- PeerAS: peer.fsm.peerInfo.AS,
- LocalAS: peer.fsm.peerInfo.LocalAS,
- PeerAddress: peer.fsm.peerInfo.Address,
- LocalAddress: net.ParseIP(laddr),
- PeerPort: rport,
- LocalPort: lport,
- PeerID: peer.fsm.peerInfo.ID,
- SentOpen: sentOpen,
- RecvOpen: recvOpen,
- State: peer.fsm.state,
- AdminState: peer.fsm.adminState,
- Timestamp: time.Now(),
+ PeerAS: peer.fsm.peerInfo.AS,
+ LocalAS: peer.fsm.peerInfo.LocalAS,
+ PeerAddress: peer.fsm.peerInfo.Address,
+ LocalAddress: net.ParseIP(laddr),
+ PeerPort: rport,
+ LocalPort: lport,
+ PeerID: peer.fsm.peerInfo.ID,
+ SentOpen: sentOpen,
+ RecvOpen: recvOpen,
+ State: peer.fsm.state,
+ AdminState: peer.fsm.adminState,
+ Timestamp: time.Now(),
+ PeerInterface: peer.fsm.pConf.Config.NeighborInterface,
}
}
@@ -687,6 +688,10 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
peer.prefixLimitWarned = make(map[bgp.RouteFamily]bool)
peer.DropAll(drop)
server.dropPeerAllRoutes(peer, drop)
+ if peer.fsm.pConf.Config.PeerAs == 0 {
+ peer.fsm.pConf.State.PeerAs = 0
+ peer.fsm.peerInfo.AS = 0
+ }
} else if peer.fsm.pConf.GracefulRestart.State.PeerRestarting && nextState == bgp.BGP_FSM_IDLE {
if peer.fsm.pConf.GracefulRestart.State.LongLivedEnabled {
llgr, no_llgr := peer.llgrFamilies()
@@ -2114,18 +2119,19 @@ type WatchEventUpdate struct {
}
type WatchEventPeerState struct {
- PeerAS uint32
- LocalAS uint32
- PeerAddress net.IP
- LocalAddress net.IP
- PeerPort uint16
- LocalPort uint16
- PeerID net.IP
- SentOpen *bgp.BGPMessage
- RecvOpen *bgp.BGPMessage
- State bgp.FSMState
- AdminState AdminState
- Timestamp time.Time
+ PeerAS uint32
+ LocalAS uint32
+ PeerAddress net.IP
+ LocalAddress net.IP
+ PeerPort uint16
+ LocalPort uint16
+ PeerID net.IP
+ SentOpen *bgp.BGPMessage
+ RecvOpen *bgp.BGPMessage
+ State bgp.FSMState
+ AdminState AdminState
+ Timestamp time.Time
+ PeerInterface string
}
type WatchEventAdjIn struct {
diff --git a/server/server_test.go b/server/server_test.go
index 3c343b9e..8f5fcc4d 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -185,9 +185,11 @@ func TestNumGoroutineWithAddDeleteNeighbor(t *testing.T) {
}
func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (*Peer, *table.PeerInfo) {
+ nConf := &config.Neighbor{Config: config.NeighborConfig{PeerAs: as, NeighborAddress: address}}
+ config.SetDefaultNeighborConfigValues(nConf, myAs)
p := NewPeer(
&config.Global{Config: config.GlobalConfig{As: myAs}},
- &config.Neighbor{Config: config.NeighborConfig{PeerAs: as, NeighborAddress: address}},
+ nConf,
rib,
&table.RoutingPolicy{})
for _, f := range rib.GetRFlist() {
diff --git a/table/path.go b/table/path.go
index c31d6cc6..b8db56a7 100644
--- a/table/path.go
+++ b/table/path.go
@@ -181,7 +181,7 @@ func (path *Path) UpdatePathAttrs(global *config.Global, peer *config.Neighbor,
return ip.Equal(net.ParseIP("0.0.0.0")) || ip.Equal(net.ParseIP("::"))
}
nexthop := path.GetNexthop()
- if peer.Config.PeerType == config.PEER_TYPE_EXTERNAL {
+ if peer.State.PeerType == config.PEER_TYPE_EXTERNAL {
// NEXTHOP handling
if !path.IsLocal() || isZero(nexthop) {
path.SetNexthop(localAddress)
@@ -195,7 +195,7 @@ func (path *Path) UpdatePathAttrs(global *config.Global, peer *config.Neighbor,
path.delPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
}
- } else if peer.Config.PeerType == config.PEER_TYPE_INTERNAL {
+ } else if peer.State.PeerType == config.PEER_TYPE_INTERNAL {
// NEXTHOP handling for iBGP
// if the path generated locally set local address as nexthop.
// if not, don't modify it.
@@ -255,7 +255,7 @@ func (path *Path) UpdatePathAttrs(global *config.Global, peer *config.Neighbor,
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": peer.Config.NeighborAddress,
- }).Warnf("invalid peer type: %d", peer.Config.PeerType)
+ }).Warnf("invalid peer type: %d", peer.State.PeerType)
}
}