[VOL-2176] Adding -no-auth and -no-dhcp option in BBSim CLI
Change-Id: I3d0f7adb26c1df0d42f67b9b8fbc782754491c31
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 2a31eb2..c374d4a 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -65,7 +65,7 @@
return &olt
}
-func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, isMock bool) *OltDevice {
+func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, auth bool, dhcp bool, isMock bool) *OltDevice {
oltLogger.WithFields(log.Fields{
"ID": oltId,
"NumNni": nni,
@@ -133,7 +133,7 @@
// create ONU devices
for j := 0; j < onuPerPon; j++ {
- o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag)
+ o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag, auth, dhcp)
p.Onus = append(p.Onus, o)
availableCTag = availableCTag + 1
}
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index cc467b8..564c21e 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -44,6 +44,8 @@
PonPort PonPort
STag int
CTag int
+ Auth bool // automatically start EAPOL if set to true
+ Dhcp bool // automatically start DHCP if set to true
// PortNo comes with flows and it's used when sending packetIndications,
// There is one PortNo per UNI Port, for now we're only storing the first one
// FIXME add support for multiple UNIs
@@ -72,7 +74,7 @@
return common.OnuSnToString(o.SerialNumber)
}
-func CreateONU(olt OltDevice, pon PonPort, id uint32, sTag int, cTag int) *Onu {
+func CreateONU(olt OltDevice, pon PonPort, id uint32, sTag int, cTag int, auth bool, dhcp bool) *Onu {
o := Onu{
ID: id,
@@ -80,6 +82,8 @@
PonPort: pon,
STag: sTag,
CTag: cTag,
+ Auth: auth,
+ Dhcp: dhcp,
HwAddress: net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, byte(pon.ID), byte(id)},
PortNo: 0,
Channel: make(chan Message, 2048),
@@ -511,9 +515,19 @@
log.Warnf("Can't go to eapol_flow_received: %v", err)
}
} else if o.InternalState.Is("gem_port_added") {
- if err := o.InternalState.Event("start_auth"); err != nil {
- log.Warnf("Can't go to auth_started: %v", err)
+
+ if o.Auth == true {
+ if err := o.InternalState.Event("start_auth"); err != nil {
+ log.Warnf("Can't go to auth_started: %v", err)
+ }
+ } else {
+ onuLogger.WithFields(log.Fields{
+ "IntfId": o.PonPortID,
+ "OnuId": o.ID,
+ "SerialNumber": o.Sn(),
+ }).Warn("Not starting authentication as Auth bit is not set in CLI parameters")
}
+
}
} else if msg.Flow.Classifier.EthType == uint32(layers.EthernetTypeIPv4) &&
msg.Flow.Classifier.SrcPort == uint32(68) &&
@@ -521,9 +535,18 @@
// keep track that we reveived the DHCP Flows so that we can transition the state to dhcp_started
o.DhcpFlowReceived = true
- // NOTE we are receiving mulitple DHCP flows but we shouldn't call the transition multiple times
- if err := o.InternalState.Event("start_dhcp"); err != nil {
- log.Errorf("Can't go to dhcp_started: %v", err)
+
+ if o.Dhcp == true {
+ // NOTE we are receiving mulitple DHCP flows but we shouldn't call the transition multiple times
+ if err := o.InternalState.Event("start_dhcp"); err != nil {
+ log.Errorf("Can't go to dhcp_started: %v", err)
+ }
+ } else {
+ onuLogger.WithFields(log.Fields{
+ "IntfId": o.PonPortID,
+ "OnuId": o.ID,
+ "SerialNumber": o.Sn(),
+ }).Warn("Not starting DHCP as Dhcp bit is not set in CLI parameters")
}
}
}
diff --git a/internal/bbsim/devices/onu_flow_test.go b/internal/bbsim/devices/onu_flow_test.go
index 4194aa5..fad206c 100644
--- a/internal/bbsim/devices/onu_flow_test.go
+++ b/internal/bbsim/devices/onu_flow_test.go
@@ -25,7 +25,7 @@
)
func Test_Onu_SendEapolFlow(t *testing.T) {
- onu := createMockOnu(1, 1, 900, 900)
+ onu := createMockOnu(1, 1, 900, 900, false, false)
client := &mockClient{
FlowAddSpy: FlowAddSpy{
@@ -49,7 +49,7 @@
// it transition to auth_started state
func Test_HandleFlowUpdateEapolFromGem(t *testing.T) {
- onu := createMockOnu(1, 1, 900, 900)
+ onu := createMockOnu(1, 1, 900, 900, true, false)
onu.InternalState = fsm.NewFSM(
"gem_port_added",
@@ -90,7 +90,7 @@
// no action is taken
func Test_HandleFlowUpdateEapolFromGemIgnore(t *testing.T) {
- onu := createMockOnu(1, 1, 900, 900)
+ onu := createMockOnu(1, 1, 900, 900, false, false)
onu.InternalState = fsm.NewFSM(
"gem_port_added",
@@ -131,7 +131,7 @@
// it transition to auth_started state
func Test_HandleFlowUpdateEapolFromEnabled(t *testing.T) {
- onu := createMockOnu(1, 1, 900, 900)
+ onu := createMockOnu(1, 1, 900, 900, false, false)
onu.InternalState = fsm.NewFSM(
"enabled",
@@ -172,7 +172,7 @@
// no action is taken
func Test_HandleFlowUpdateEapolFromEnabledIgnore(t *testing.T) {
- onu := createMockOnu(1, 1, 900, 900)
+ onu := createMockOnu(1, 1, 900, 900, false, false)
onu.InternalState = fsm.NewFSM(
"enabled",
@@ -209,4 +209,122 @@
assert.Equal(t, onu.InternalState.Current(), "enabled")
}
-// TODO add tests for DHCP flow
+// validates that when an ONU receives an EAPOL flow for UNI 0
+// but the noAuth bit is set no action is taken
+func Test_HandleFlowUpdateEapolNoAuth(t *testing.T) {
+ onu := createMockOnu(1, 1, 900, 900, false, false)
+
+ onu.InternalState = fsm.NewFSM(
+ "gem_port_added",
+ fsm.Events{
+ {Name: "start_auth", Src: []string{"eapol_flow_received", "gem_port_added"}, Dst: "auth_started"},
+ },
+ fsm.Callbacks{},
+ )
+
+ flow := openolt.Flow{
+ AccessIntfId: int32(onu.PonPortID),
+ OnuId: int32(onu.ID),
+ UniId: int32(0),
+ FlowId: uint32(onu.ID),
+ FlowType: "downstream",
+ AllocId: int32(0),
+ NetworkIntfId: int32(0),
+ Classifier: &openolt.Classifier{
+ EthType: uint32(layers.EthernetTypeEAPOL),
+ OVid: 4091,
+ },
+ Action: &openolt.Action{},
+ Priority: int32(100),
+ PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
+ }
+
+ msg := OnuFlowUpdateMessage{
+ PonPortID: 1,
+ OnuID: 1,
+ Flow: &flow,
+ }
+
+ onu.handleFlowUpdate(msg)
+ assert.Equal(t, onu.InternalState.Current(), "gem_port_added")
+}
+
+func Test_HandleFlowUpdateDhcp(t *testing.T) {
+ onu := createMockOnu(1, 1, 900, 900, false, true)
+
+ onu.InternalState = fsm.NewFSM(
+ "eap_response_success_received",
+ fsm.Events{
+ {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
+ },
+ fsm.Callbacks{},
+ )
+
+ flow := openolt.Flow{
+ AccessIntfId: int32(onu.PonPortID),
+ OnuId: int32(onu.ID),
+ UniId: int32(0),
+ FlowId: uint32(onu.ID),
+ FlowType: "downstream",
+ AllocId: int32(0),
+ NetworkIntfId: int32(0),
+ Classifier: &openolt.Classifier{
+ EthType: uint32(layers.EthernetTypeIPv4),
+ SrcPort: uint32(68),
+ DstPort: uint32(67),
+ },
+ Action: &openolt.Action{},
+ Priority: int32(100),
+ PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
+ }
+
+ msg := OnuFlowUpdateMessage{
+ PonPortID: 1,
+ OnuID: 1,
+ Flow: &flow,
+ }
+
+ onu.handleFlowUpdate(msg)
+ assert.Equal(t, onu.InternalState.Current(), "dhcp_started")
+ assert.Equal(t, onu.DhcpFlowReceived, true)
+}
+
+func Test_HandleFlowUpdateDhcpNoDhcp(t *testing.T) {
+ onu := createMockOnu(1, 1, 900, 900, false, false)
+
+ onu.InternalState = fsm.NewFSM(
+ "eap_response_success_received",
+ fsm.Events{
+ {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
+ },
+ fsm.Callbacks{},
+ )
+
+ flow := openolt.Flow{
+ AccessIntfId: int32(onu.PonPortID),
+ OnuId: int32(onu.ID),
+ UniId: int32(0),
+ FlowId: uint32(onu.ID),
+ FlowType: "downstream",
+ AllocId: int32(0),
+ NetworkIntfId: int32(0),
+ Classifier: &openolt.Classifier{
+ EthType: uint32(layers.EthernetTypeIPv4),
+ SrcPort: uint32(68),
+ DstPort: uint32(67),
+ },
+ Action: &openolt.Action{},
+ Priority: int32(100),
+ PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
+ }
+
+ msg := OnuFlowUpdateMessage{
+ PonPortID: 1,
+ OnuID: 1,
+ Flow: &flow,
+ }
+
+ onu.handleFlowUpdate(msg)
+ assert.Equal(t, onu.InternalState.Current(), "eap_response_success_received")
+ assert.Equal(t, onu.DhcpFlowReceived, true)
+}
diff --git a/internal/bbsim/devices/onu_state_machine_test.go b/internal/bbsim/devices/onu_state_machine_test.go
index 239869b..c8ad84c 100644
--- a/internal/bbsim/devices/onu_state_machine_test.go
+++ b/internal/bbsim/devices/onu_state_machine_test.go
@@ -22,13 +22,7 @@
)
func Test_Onu_StateMachine_enable(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
assert.Equal(t, onu.InternalState.Current(), "created")
onu.InternalState.Event("discover")
@@ -38,13 +32,7 @@
}
func Test_Onu_StateMachine_eapol_start_eap_flow(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.InternalState.SetState("enabled")
@@ -62,13 +50,7 @@
}
func Test_Onu_StateMachine_eapol_start_gem_port(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.InternalState.SetState("enabled")
@@ -86,13 +68,7 @@
}
func Test_Onu_StateMachine_eapol_states(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.InternalState.SetState("auth_started")
@@ -108,13 +84,7 @@
}
func Test_Onu_StateMachine_dhcp_start(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.DhcpFlowReceived = true
onu.InternalState.SetState("eap_response_success_received")
@@ -126,13 +96,7 @@
}
func Test_Onu_StateMachine_dhcp_start_error(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.InternalState.SetState("eap_response_success_received")
assert.Equal(t, onu.InternalState.Current(), "eap_response_success_received")
@@ -144,13 +108,7 @@
}
func Test_Onu_StateMachine_dhcp_states(t *testing.T) {
- olt := OltDevice{
- ID: 0,
- }
- pon := PonPort{
- ID: 1,
- }
- onu := CreateONU(olt, pon, 1, 900, 900)
+ onu := createTestOnu()
onu.DhcpFlowReceived = false
diff --git a/internal/bbsim/devices/onu_test_helpers.go b/internal/bbsim/devices/onu_test_helpers.go
index 1044913..a2e7ddd 100644
--- a/internal/bbsim/devices/onu_test_helpers.go
+++ b/internal/bbsim/devices/onu_test_helpers.go
@@ -104,7 +104,8 @@
return nil, errors.New("unimplemented-in-mock-client")
}
-func createMockOnu(id uint32, ponPortId uint32, sTag int, cTag int) Onu {
+// this method creates a fake ONU used in the tests
+func createMockOnu(id uint32, ponPortId uint32, sTag int, cTag int, auth bool, dhcp bool) Onu {
o := Onu{
ID: id,
PonPortID: ponPortId,
@@ -112,7 +113,21 @@
CTag: cTag,
HwAddress: net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, byte(ponPortId), byte(id)},
PortNo: 0,
+ Auth: auth,
+ Dhcp: dhcp,
}
o.SerialNumber = o.NewSN(0, ponPortId, o.ID)
return o
}
+
+// this method creates a real ONU to be used in the tests
+func createTestOnu() *Onu {
+ olt := OltDevice{
+ ID: 0,
+ }
+ pon := PonPort{
+ ID: 1,
+ }
+ onu := CreateONU(olt, pon, 1, 900, 900, false, false)
+ return onu
+}
diff --git a/internal/common/options.go b/internal/common/options.go
index 41c3522..eee91cc 100644
--- a/internal/common/options.go
+++ b/internal/common/options.go
@@ -25,6 +25,8 @@
NumOnuPerPon int
STag int
CTagInit int
+ Auth bool
+ Dhcp bool
ProfileCpu *string
LogLevel string
LogCaller bool
@@ -45,6 +47,9 @@
pon := flag.Int("pon", 1, "Number of PON ports per OLT device to be emulated")
onu := flag.Int("onu", 1, "Number of ONU devices per PON port to be emulated")
+ auth := flag.Bool("auth", false, "Set this flag if you want authentication to start automatically")
+ dhcp := flag.Bool("dhcp", false, "Set this flag if you want DHCP to start automatically")
+
s_tag := flag.Int("s_tag", 900, "S-Tag value")
c_tag_init := flag.Int("c_tag", 900, "C-Tag starting value, each ONU will get a sequential one (targeting 1024 ONUs per BBSim instance the range is big enough)")
@@ -66,6 +71,8 @@
o.ProfileCpu = profileCpu
o.LogLevel = *logLevel
o.LogCaller = *logCaller
+ o.Auth = *auth
+ o.Dhcp = *dhcp
return o
}