[VOL-2176] Adding -no-auth and -no-dhcp option in BBSim CLI
Change-Id: I3d0f7adb26c1df0d42f67b9b8fbc782754491c31
diff --git a/VERSION b/VERSION
index ccf3e96..bbdeab6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.5-dev
+0.0.5
diff --git a/cmd/bbr/bbr.go b/cmd/bbr/bbr.go
index a98decd..4f4c590 100644
--- a/cmd/bbr/bbr.go
+++ b/cmd/bbr/bbr.go
@@ -70,7 +70,19 @@
apiDoneChannel := make(chan bool)
// create the OLT device
- olt := devices.CreateOLT(options.OltID, options.NumNniPerOlt, options.NumPonPerOlt, options.NumOnuPerPon, options.STag, options.CTagInit, &oltDoneChannel, &apiDoneChannel, true)
+ olt := devices.CreateOLT(
+ options.OltID,
+ options.NumNniPerOlt,
+ options.NumPonPerOlt,
+ options.NumOnuPerPon,
+ options.STag,
+ options.CTagInit,
+ &oltDoneChannel,
+ &apiDoneChannel,
+ true, // this parameter is not important in the BBR Case
+ true, // this parameter is not important in the BBR Case
+ true,
+ )
oltMock := bbrdevices.OltMock{
Olt: olt,
TargetOnus: options.NumPonPerOlt * options.NumOnuPerPon,
diff --git a/cmd/bbsim/bbsim.go b/cmd/bbsim/bbsim.go
index d8cfcf0..e7eef11 100644
--- a/cmd/bbsim/bbsim.go
+++ b/cmd/bbsim/bbsim.go
@@ -151,6 +151,8 @@
"NumPonPerOlt": options.NumPonPerOlt,
"NumOnuPerPon": options.NumOnuPerPon,
"TotalOnus": options.NumPonPerOlt * options.NumOnuPerPon,
+ "Auth": options.Auth,
+ "Dhcp": options.Dhcp,
}).Info("BroadBand Simulator is on")
// control channels, they are only closed when the goroutine needs to be terminated
@@ -171,7 +173,19 @@
wg := sync.WaitGroup{}
wg.Add(5)
- olt := devices.CreateOLT(options.OltID, options.NumNniPerOlt, options.NumPonPerOlt, options.NumOnuPerPon, options.STag, options.CTagInit, &oltDoneChannel, &apiDoneChannel, false)
+ olt := devices.CreateOLT(
+ options.OltID,
+ options.NumNniPerOlt,
+ options.NumPonPerOlt,
+ options.NumOnuPerPon,
+ options.STag,
+ options.CTagInit,
+ &oltDoneChannel,
+ &apiDoneChannel,
+ options.Auth,
+ options.Dhcp,
+ false,
+ )
go devices.StartOlt(olt, &wg)
log.Debugf("Created OLT with id: %d", options.OltID)
go startApiServer(apiDoneChannel, &wg)
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 9acc4d5..585de35 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -41,12 +41,24 @@
helm install -n bbsim cord/bbsim
+If you need to specify a custom image for BBSim you can:
+
+.. code:: bash
+
+ helm install -n bbsim cord/bbsim --set images.bbsim.repository=bbsim --set images.bbsim.tag=candidate --set images.bbsim.pullPolicy=Never
+
The BBSim installation can be customized to emulate multiple ONUs and multiple PON Ports:
.. code:: bash
helm install -n bbsim cord/bbsim --set onu=8 --set pon=2
+BBSim can also be configured to automatically start Authentication or DHCP:
+
+.. code:: bash
+
+ helm install -n bbsim cord/bbsim --set auth=true --set dhcp=true
+
Once BBSim is installed you can verify that it's running with:
.. code:: bash
@@ -67,3 +79,35 @@
.. code:: bash
voltctl device enable $(voltctl device list --filter Type~openolt -q)
+
+BBSim startup options
+---------------------
+
+``BBSim`` supports a series of options that can be set at startup, you can see the list via ``./bbsim --help``
+
+.. code:: bash
+
+ $ ./bbsim --help
+ Usage of ./bbsim:
+ -auth
+ Set this flag if you want authentication to start automatically
+ -c_tag int
+ C-Tag starting value, each ONU will get a sequential one (targeting 1024 ONUs per BBSim instance the range is big enough) (default 900)
+ -cpuprofile string
+ write cpu profile to file
+ -dhcp
+ Set this flag if you want DHCP to start automatically
+ -logCaller
+ Whether to print the caller filename or not
+ -logLevel string
+ Set the log level (trace, debug, info, warn, error) (default "debug")
+ -nni int
+ Number of NNI ports per OLT device to be emulated (default 1)
+ -olt_id int
+ Number of OLT devices to be emulated
+ -onu int
+ Number of ONU devices per PON port to be emulated (default 1)
+ -pon int
+ Number of PON ports per OLT device to be emulated (default 1)
+ -s_tag int
+ S-Tag value (default 900)
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
}