Merge "Adding release target for bbsimctl and bbr"
diff --git a/README.md b/README.md
index b6dee44..4566a7d 100644
--- a/README.md
+++ b/README.md
@@ -144,13 +144,4 @@
More advanced documentation lives in the [here](./docs/README.md)
-## Know Issues
-
-In some runs, EAPOL fails with:
-```
-time="2019-09-20T21:24:31Z" level=error msg="Can't send EapStart Message: ONU {intfid:1, onuid:2} - Not DONE (GemportID is not set)" IntfId=1 OnuId=2 OnuSn=BBSM00000102 module=EAPOL
-time="2019-09-20T21:24:31Z" level=error msg="ONU failed to authenticate!" IntfId=1 OnuId=2 OnuSn=BBSM00000102 module=ONU
-```
-Investigate why this happens (we believe the source to be in the OMCI library)
-
> This project structure is based on [golang-standards/project-layout](https://github.com/golang-standards/project-layout).
diff --git a/docs/assets/bbr_runs.png b/docs/assets/bbr_runs.png
new file mode 100644
index 0000000..f436d44
--- /dev/null
+++ b/docs/assets/bbr_runs.png
Binary files differ
diff --git a/docs/bbr.md b/docs/bbr.md
index fafdf77..359d106 100644
--- a/docs/bbr.md
+++ b/docs/bbr.md
@@ -1,5 +1,17 @@
# BBR
+BBR (a.k.a BBSim Reflector) is a tool designed to scale test BBSim.
+It is responsible to emulate ONOS and VOLTHA in order to quickly reply
+to any message that BBSim sends.
+
+Here is a graph of the measuraments of BBSim performance captured over
+10 runs with different PON Layout
+
+![BBSim Performances](./assets/bbr_runs.png "BBSim Performances")
+
+
+## Run BBR
+
To run `bbr` you need to have a `bbsim` instance running.
You can start `bbsim` locally with:
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 27f4e78..bfaa5fd 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -25,6 +25,7 @@
"github.com/looplab/fsm"
"github.com/opencord/bbsim/internal/bbsim/packetHandlers"
bbsim "github.com/opencord/bbsim/internal/bbsim/types"
+ omcisim "github.com/opencord/omci-sim"
"github.com/opencord/voltha-protos/go/openolt"
"github.com/opencord/voltha-protos/go/tech_profile"
log "github.com/sirupsen/logrus"
@@ -212,7 +213,7 @@
}
o.channel <- msg
}
-
+ go o.processOmciMessages()
// send PON Port indications
for _, pon := range o.Pons {
msg := Message{
@@ -226,7 +227,6 @@
for _, onu := range pon.Onus {
go onu.ProcessOnuMessages(stream, nil)
- go onu.processOmciMessages(stream)
// FIXME move the message generation in the state transition
// from here only invoke the state transition
msg := Message{
@@ -244,6 +244,22 @@
return nil
}
+func (o OltDevice) processOmciMessages() {
+ ch := omcisim.GetChannel()
+
+ oltLogger.Debug("Started OMCI Indication Channel")
+
+ for message := range ch {
+ onuId := message.Data.OnuId
+ intfId := message.Data.IntfId
+ onu, err := o.FindOnuById(intfId, onuId)
+ if err != nil {
+ oltLogger.Errorf("Failed to find onu: %v", err)
+ }
+ go onu.processOmciMessage(message)
+ }
+}
+
// Helpers method
func (o OltDevice) GetPonById(id uint32) (*PonPort, error) {
@@ -433,6 +449,22 @@
return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-serial-number-%s", serialNumber))
}
+// returns an ONU with a given interface/Onu Id
+func (o OltDevice) FindOnuById(intfId uint32, onuId uint32) (*Onu, error) {
+ // TODO this function can be a performance bottlenec when we have many ONUs,
+ // memoizing it will remove the bottleneck
+ for _, pon := range o.Pons {
+ if pon.ID == intfId {
+ for _, onu := range pon.Onus {
+ if onu.ID == onuId {
+ return onu, nil
+ }
+ }
+ }
+ }
+ return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-id-%v-%v", intfId, onuId))
+}
+
// returns an ONU with a given Mac Address
func (o OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
// TODO this function can be a perfoormance bottlenec when we have many ONUs,
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index f4ef84b..2aba5d2 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -294,32 +294,23 @@
}
}
-func (o Onu) processOmciMessages(stream openolt.Openolt_EnableIndicationServer) {
- ch := omcisim.GetChannel()
+func (o Onu) processOmciMessage(message omcisim.OmciChMessage) {
+ switch message.Type {
+ case omcisim.GemPortAdded:
+ log.WithFields(log.Fields{
+ "OnuId": message.Data.OnuId,
+ "IntfId": message.Data.IntfId,
+ }).Infof("GemPort Added")
- onuLogger.WithFields(log.Fields{
- "onuID": o.ID,
- "onuSN": o.Sn(),
- }).Debug("Started OMCI Indication Channel")
-
- for message := range ch {
- switch message.Type {
- case omcisim.GemPortAdded:
- log.WithFields(log.Fields{
- "OnuId": message.Data.OnuId,
- "IntfId": message.Data.IntfId,
- }).Infof("GemPort Added")
-
- // NOTE if we receive the GemPort but we don't have EAPOL flows
- // go an intermediate state, otherwise start auth
- if o.InternalState.Is("enabled") {
- if err := o.InternalState.Event("add_gem_port"); err != nil {
- log.Errorf("Can't go to gem_port_added: %v", err)
- }
- } else if o.InternalState.Is("eapol_flow_received") {
- if err := o.InternalState.Event("start_auth"); err != nil {
- log.Errorf("Can't go to auth_started: %v", err)
- }
+ // NOTE if we receive the GemPort but we don't have EAPOL flows
+ // go an intermediate state, otherwise start auth
+ if o.InternalState.Is("enabled") {
+ if err := o.InternalState.Event("add_gem_port"); err != nil {
+ log.Errorf("Can't go to gem_port_added: %v", err)
+ }
+ } else if o.InternalState.Is("eapol_flow_received") {
+ if err := o.InternalState.Event("start_auth"); err != nil {
+ log.Errorf("Can't go to auth_started: %v", err)
}
}
}
diff --git a/tests/bbr.sh b/tests/bbr.sh
new file mode 100644
index 0000000..434cb56
--- /dev/null
+++ b/tests/bbr.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+# Copyright 2018-present Open Networking Foundation
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+usage()
+{
+ echo " "
+ echo "Runs BBR against BBSim a number of times and output the results in a file name results.logs"
+ echo " "
+ echo "Usage: $0 [--onus|--pons|--runs]" >&2
+ echo " "
+ echo " -o, --onus Number of ONUs to emulate on each PON"
+ echo " -p, --pons Number of PONs to emulate"
+ echo " -r, --runs Number of runs to perform"
+ echo " "
+ echo "Example usages:"
+ echo " ./$0 -i -p 2 -o 32 -r 10"
+ echo " "
+}
+
+run()
+{
+ echo "Running with: ${ONU} Onus ${PON} Pons for ${RUN} times" >> results.logs
+ for i in {0..10}
+ do
+ echo "RUN Number: $i"
+ docker rm -f bbsim
+ DOCKER_RUN_ARGS="-pon ${PON} -onu ${ONU}" make docker-run
+ sleep 5
+ ./bbr -pon $PON -onu $ONU 2>&1 | tee bbr.logs
+ docker logs bbsim 2>&1 | tee bbsim.logs
+ echo "RUN Number: $i" >> results.logs
+ cat bbr.logs | grep Duration | awk '{print $5}' >> results.logs
+ done
+}
+
+ONU=1
+PON=1
+RUN=10
+
+while [ "$1" != "" ]; do
+ case $1 in
+ -h | --help)
+ usage
+ exit 0
+ ;;
+ -o | --onus ) ONU=$2
+ ;;
+ -p | --pons ) PON=$2
+ ;;
+ -r | --runs ) RUN=$2
+ ;;
+ --) # End of all options
+ shift
+ break
+ ;;
+ esac
+ shift
+done
+
+run
+