diff --git a/protocols/bgp/server/fake_conn.go b/protocols/bgp/server/fake_conn.go new file mode 100644 index 0000000000000000000000000000000000000000..4537da5a88d1d26e881644c974306130a82d0017 --- /dev/null +++ b/protocols/bgp/server/fake_conn.go @@ -0,0 +1,52 @@ +package server + +import ( + "net" + "time" +) + +type fakeConn struct { +} + +type fakeAddr struct { +} + +func (f fakeAddr) Network() string { + return "" +} + +func (f fakeAddr) String() string { + return "169.254.100.100:179" +} + +func (f fakeConn) Read(b []byte) (n int, err error) { + return 0, nil +} + +func (f fakeConn) Write(b []byte) (n int, err error) { + return len(b), nil +} + +func (f fakeConn) Close() error { + return nil +} + +func (f fakeConn) LocalAddr() net.Addr { + return fakeAddr{} +} + +func (f fakeConn) RemoteAddr() net.Addr { + return fakeAddr{} +} + +func (f fakeConn) SetDeadline(t time.Time) error { + return nil +} + +func (f fakeConn) SetReadDeadline(t time.Time) error { + return nil +} + +func (f fakeConn) SetWriteDeadline(t time.Time) error { + return nil +} diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go index 80ff7fa7990493186924f8c35f1a90deb0c93e5b..8462b2c5db90a073c8dcc1119b35c63600342df7 100644 --- a/protocols/bgp/server/fsm_established.go +++ b/protocols/bgp/server/fsm_established.go @@ -154,8 +154,10 @@ func (s *establishedState) keepaliveTimerExpired() (state, string) { } func (s *establishedState) msgReceived(data []byte) (state, string) { + fmt.Printf("Processing MSG\n") msg, err := packet.Decode(bytes.NewBuffer(data)) if err != nil { + fmt.Printf("Decode failure: %v\n", err) switch bgperr := err.(type) { case packet.BGPError: s.fsm.sendNotification(bgperr.ErrorCode, bgperr.ErrorSubCode) @@ -165,6 +167,7 @@ func (s *establishedState) msgReceived(data []byte) (state, string) { s.fsm.connectRetryCounter++ return newIdleState(s.fsm), "Failed to decode BGP message" } + fmt.Printf("Msg type: %d\n", msg.Header.Type) switch msg.Header.Type { case packet.NotificationMsg: return s.notification() @@ -191,9 +194,12 @@ func (s *establishedState) update(msg *packet.BGPMessage) (state, string) { } u := msg.Body.(*packet.BGPUpdate) + fmt.Printf("Processing withdraws\n") s.withdraws(u) + fmt.Printf("Processing advertisements\n") s.updates(u) + fmt.Printf("update done\n") return newEstablishedState(s.fsm), s.fsm.reason } diff --git a/protocols/bgp/server/fsm_test.go b/protocols/bgp/server/fsm_test.go new file mode 100644 index 0000000000000000000000000000000000000000..eeab5a60e8b25b86bd135254e5d67b08ada7d7b5 --- /dev/null +++ b/protocols/bgp/server/fsm_test.go @@ -0,0 +1,95 @@ +package server + +import ( + "fmt" + "sync" + "testing" + "time" + + "github.com/bio-routing/bio-rd/routingtable/filter" + + "net" + + "github.com/bio-routing/bio-rd/routingtable/locRIB" +) + +func TestFSM(t *testing.T) { + fsmA := newFSM2(&peer{ + addr: net.ParseIP("169.254.100.100"), + rib: locRIB.New(), + importFilter: filter.NewAcceptAllFilter(), + exportFilter: filter.NewAcceptAllFilter(), + }) + + fsmA.holdTimer = time.NewTimer(time.Second * 90) + fsmA.keepaliveTimer = time.NewTimer(time.Second * 30) + fsmA.connectRetryTimer = time.NewTimer(time.Second * 120) + fsmA.state = newEstablishedState(fsmA) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + fsmA.con = fakeConn{} + for { + nextState, reason := fsmA.state.run() + fsmA.state = nextState + stateName := stateName(nextState) + fmt.Printf("New state: %s\n", stateName) + switch stateName { + case "idle": + wg.Done() + return + case "cease": + t.Errorf("Unexpected cease state: %s", reason) + wg.Done() + return + case "established": + continue + default: + t.Errorf("Unexpected new state: %s", reason) + wg.Done() + return + } + } + + }() + + for i := uint8(0); i < 255; i++ { + fsmA.msgRecvCh <- []byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 53, + 2, + 0, 0, + 0, 26, + 64, // Attribute flags + 1, // Attribute Type code (ORIGIN) + 1, // Length + 2, // INCOMPLETE + + 64, // Attribute flags + 2, // Attribute Type code (AS Path) + 12, // Length + 2, // Type = AS_SEQUENCE + 2, // Path Segement Length + 59, 65, // AS15169 + 12, 248, // AS3320 + 1, // Type = AS_SET + 2, // Path Segement Length + 59, 65, // AS15169 + 12, 248, // AS3320 + + 0, // Attribute flags + 3, // Attribute Type code (Next Hop) + 4, // Length + 10, 11, 12, 13, // Next Hop + 24, 169, 254, i, + } + } + + fmt.Printf("Route count in RIB: %d\n", fsmA.rib.RouteCount()) + + fmt.Printf("Stopping FSM\n") + fsmA.eventCh <- ManualStop + fmt.Printf("WAINTING\n") + wg.Wait() +} diff --git a/routingtable/client_interface.go b/routingtable/client_interface.go index e7190c5b6c0bb1829f59cf5faadd0623ef3b395c..536a76020ca6276d22536ebd3781685356dc3738 100644 --- a/routingtable/client_interface.go +++ b/routingtable/client_interface.go @@ -13,4 +13,5 @@ type RouteTableClient interface { Register(RouteTableClient) RegisterWithOptions(RouteTableClient, ClientOptions) Unregister(RouteTableClient) + RouteCount() int64 } diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go index ff5750c34d226080bea079968becdec410d2704e..90004e273867035b71fef699be7511c1e690b947 100644 --- a/routingtable/locRIB/loc_rib.go +++ b/routingtable/locRIB/loc_rib.go @@ -40,6 +40,10 @@ func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error { return nil } +func (a *LocRIB) RouteCount() int64 { + return a.rt. +} + // AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added. func (a *LocRIB) AddPath(pfx net.Prefix, p *route.Path) error { a.mu.Lock()