SEBA-728 Fix hardcoded UNI port for Ponsim
Change-Id: I5cb2d072c7c5e232c1c9813e3f7318e1346e0d41
diff --git a/tests/atests/build/Makefile b/tests/atests/build/Makefile
index 854c68e..f247d66 100644
--- a/tests/atests/build/Makefile
+++ b/tests/atests/build/Makefile
@@ -113,8 +113,6 @@
touch $@
$(M)/simtype-bbsim: | $(M)/voltha-running
- cd $(HOME)/cord/helm-charts; helm upgrade --install ponnet ponnet
- $(HOME)/cord/helm-charts/scripts/wait_for_pods.sh kube-system
cd $(HOME)/cord/helm-charts; helm upgrade --install bbsim bbsim -f configs/seba-ponsim.yaml --set images.bbsim.repository=voltha/voltha-bbsim,images.bbsim.tag=latest,images.bbsim.pullPolicy=Never
touch $@
@@ -122,19 +120,17 @@
cd $(HOME)/cord/helm-charts; helm upgrade --install ponnet ponnet
$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh kube-system
cd $(HOME)/cord/helm-charts; helm upgrade --install ponsimv2 ponsimv2 -f configs/seba-ponsim.yaml --set images.olt.repository=voltha-ponsim,images.olt.tag=latest,images.olt.pullPolicy=Never,images.onu.repository=voltha-ponsim,images.onu.tag=latest,images.onu.pullPolicy=Never,images.rg.repository=voltha-tester,images.rg.tag=latest,images.rg.pullPolicy=Never
- touch $@
-
-$(M)/pon0-fwd: | $(M)/voltha-running
- echo 8 > /tmp/pon0_group_fwd_mask
- until sudo cp /tmp/pon0_group_fwd_mask /sys/class/net/pon0/bridge/group_fwd_mask; \
+ $(HOME)/cord/helm-charts/scripts/wait_for_pods.sh voltha
+ echo 8 > /tmp/group_fwd_mask
+ for bridge in /sys/class/net/pon*; \
do \
- echo "waiting for pon0..."; \
- sleep 5; \
+ echo Setting up forwarding on `basename $$bridge`; \
+ sudo cp /tmp/group_fwd_mask $$bridge/bridge/group_fwd_mask; \
done
- rm /tmp/pon0_group_fwd_mask
+ rm /tmp/group_fwd_mask
touch $@
-$(M)/voltha-simtype-running: | $(M)/pon0-fwd
+$(M)/voltha-simtype-running:
$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh
until http -a karaf:karaf --ignore-stdin --check-status GET http://127.0.0.1:30120/onos/v1/configuration/org.opencord.olt.impl.Olt; \
do \
@@ -148,7 +144,7 @@
remove-chart-milestones:
cd $(M); sudo rm -f setup kafka kafka-running onos voltha etcd-operator-ready etcd-cluster \
- voltha-running simtype-ponsim simtype-bbsim pon0-fwd voltha-simtype-running
+ voltha-running simtype-ponsim simtype-bbsim voltha-simtype-running
remove-kube-milestones:
cd $(M); sudo rm -f kubeadm helm-init
@@ -161,3 +157,5 @@
sudo rm -f /var/lib/cni/networks/pon*/* || true
sudo rm -f /var/lib/cni/networks/nni*/* || true
sudo rm -f /var/lib/cni/networks/k8s-pod-network/* || true
+ for br in /sys/class/net/pon*; do sudo ip link delete `basename $$br` type bridge; done || true
+ for br in /sys/class/net/nni*; do sudo ip link delete `basename $$br` type bridge; done || true
diff --git a/voltha/adapters/ponsim_olt/ponsim_olt.py b/voltha/adapters/ponsim_olt/ponsim_olt.py
index 2c32904..72b30f7 100644
--- a/voltha/adapters/ponsim_olt/ponsim_olt.py
+++ b/voltha/adapters/ponsim_olt/ponsim_olt.py
@@ -388,7 +388,6 @@
self.pm_metrics = None
self.alarms = None
self.frames = None
- self.uni_ports = []
self.ctag_map = {}
def __del__(self):
@@ -548,7 +547,6 @@
vlan=vlan_id,
serial_number=onu.serial_number
)
- self.uni_ports.append(int(onu.uni_port))
if self.ponsim_comm == 'grpc':
self.log.info('starting-frame-grpc-stream')
@@ -692,71 +690,73 @@
action.output.port = ofp.OFPP_CONTROLLER
self.log.info('sending flow to controller')
- # Lookup subscriber ctag for a particular PON port
- def get_subscriber_ctag(self, flows, port):
- self.log.debug('looking from subscriber flow for port', port=port)
-
- for flow in flows:
- in_port = fd.get_in_port(flow)
- out_port = fd.get_out_port(flow)
- if in_port == port and out_port == self.nni_port.port_no:
- fields = fd.get_ofb_fields(flow)
- self.log.debug('subscriber flow found', fields=fields)
- for field in fields:
- if field.type == fd.VLAN_VID:
- self.log.debug('subscriber ctag found',
- vlan_id=field.vlan_vid)
- return field.vlan_vid & 0x0fff
- self.log.debug('No subscriber flow found', port=port)
- return None
-
# Lookup UNI port for a particular subscriber ctag
def get_subscriber_uni_port(self, ctag):
- self.log.debug('get_subscriber_uni_port', ctag=ctag, ctag_map=self.ctag_map)
+ self.log.debug('get_subscriber_uni_port', ctag=ctag)
c = int(ctag)
if c in self.ctag_map:
return self.ctag_map[c]
- # return None
- # HACK: temporarily pass atest
- return int(128)
-
- def clear_ctag_map(self):
- self.ctag_map = {}
+ elif self.is_uni_port(c):
+ return c
+ self.log.debug('get_subscriber_uni_port: no mapping found', ctag=ctag, ctag_map=self.ctag_map)
+ return None
def update_ctag_map(self, ctag, uni_port):
- c = int(ctag)
- u = int(uni_port)
- if not self.is_uni_port(u):
- self.log.warning('update_ctag_map: unknown UNI port', uni_port=u)
- if c in self.ctag_map and self.ctag_map[c] != u:
- self.log.warning('update_ctag_map: changing UNI port for ctag',
- ctag=c, old=self.ctag_map[c], new=u)
- self.ctag_map[c] = u
+ if ctag is None:
+ for (c, u) in self.ctag_map.iteritems():
+ if u == int(uni_port):
+ self.log.debug('deleting ctag mapping', ctag=c, uni_port=u)
+ del self.ctag_map[c]
+ return
+ else:
+ c = int(ctag)
+ u = int(uni_port)
+ if not self.is_uni_port(u):
+ self.log.warning('unknown UNI port', uni_port=u)
+ if c in self.ctag_map:
+ if self.ctag_map[c] == u:
+ return
+ else:
+ self.log.warning('changing UNI port for ctag',
+ ctag=c, old=self.ctag_map[c], new=u)
- # Create a new flow that's a copy of the old flow but change the vlan_vid
- # Used to create per-subscriber DHCP and EAPOL flows
- def create_secondary_flow(self, flow, vlan_id):
- secondary_flow = copy.deepcopy(flow)
- for field in fd.get_ofb_fields(secondary_flow):
- if field.type == fd.VLAN_VID:
- field.vlan_vid = vlan_id | 0x1000
- return secondary_flow
+ self.ctag_map[c] = u
+ self.log.debug('added mapping', ctag=c, uni_port=u)
def is_uni_port(self, vlan_id):
- return int(vlan_id) in self.uni_ports
+ for onu in self.adapter_agent.get_child_devices(self.device_id):
+ if onu.vlan == vlan_id:
+ return True
+ return False
- def create_secondary_flows(self, trapflows, allflows, type):
- secondary_flows = []
- for vlan_vid, flow in trapflows.iteritems():
- if self.is_uni_port(vlan_vid):
- self.update_ctag_map(vlan_vid, vlan_vid)
- ctag = self.get_subscriber_ctag(allflows, fd.get_in_port(flow))
- if ctag is not None:
- self.update_ctag_map(ctag, vlan_vid)
- if ctag not in trapflows:
- self.log.info('add secondary %s flow' % type, ctag=ctag)
- secondary_flows.append(self.create_secondary_flow(flow, ctag))
- return secondary_flows
+ def get_classifier_info(self, flow):
+ classifier_info = {}
+ for field in fd.get_ofb_fields(flow):
+ if field.type == fd.ETH_TYPE:
+ classifier_info[ETH_TYPE] = field.eth_type
+ elif field.type == fd.IP_PROTO:
+ classifier_info[IP_PROTO] = field.ip_proto
+ elif field.type == fd.IN_PORT:
+ classifier_info[IN_PORT] = field.port
+ elif field.type == fd.VLAN_VID:
+ classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
+ elif field.type == fd.VLAN_PCP:
+ classifier_info[VLAN_PCP] = field.vlan_pcp
+ elif field.type == fd.UDP_DST:
+ classifier_info[UDP_DST] = field.udp_dst
+ elif field.type == fd.UDP_SRC:
+ classifier_info[UDP_SRC] = field.udp_src
+ elif field.type == fd.IPV4_DST:
+ classifier_info[IPV4_DST] = field.ipv4_dst
+ elif field.type == fd.IPV4_SRC:
+ classifier_info[IPV4_SRC] = field.ipv4_src
+ elif field.type == fd.METADATA:
+ classifier_info[METADATA] = field.table_metadata
+ else:
+ self.log.debug('field-type-unhandled field.type={}'.format(
+ field.type))
+
+ return classifier_info
# VOLTHA's flow decomposition removes the information about which flows
# are trap flows where traffic should be forwarded to the controller.
@@ -766,38 +766,11 @@
stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
self.log.info('pushing-olt-flow-table')
- self.clear_ctag_map()
- dhcp_upstream_flows = {}
eapol_flows = {}
- secondary_flows = []
eapol_flow_without_vlan = False
for flow in flows:
- classifier_info = {}
- for field in fd.get_ofb_fields(flow):
- if field.type == fd.ETH_TYPE:
- classifier_info[ETH_TYPE] = field.eth_type
- elif field.type == fd.IP_PROTO:
- classifier_info[IP_PROTO] = field.ip_proto
- elif field.type == fd.IN_PORT:
- classifier_info[IN_PORT] = field.port
- elif field.type == fd.VLAN_VID:
- classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
- elif field.type == fd.VLAN_PCP:
- classifier_info[VLAN_PCP] = field.vlan_pcp
- elif field.type == fd.UDP_DST:
- classifier_info[UDP_DST] = field.udp_dst
- elif field.type == fd.UDP_SRC:
- classifier_info[UDP_SRC] = field.udp_src
- elif field.type == fd.IPV4_DST:
- classifier_info[IPV4_DST] = field.ipv4_dst
- elif field.type == fd.IPV4_SRC:
- classifier_info[IPV4_SRC] = field.ipv4_src
- elif field.type == fd.METADATA:
- classifier_info[METADATA] = field.table_metadata
- else:
- self.log.debug('field-type-unhandled field.type={}'.format(
- field.type))
+ classifier_info = self.get_classifier_info(flow)
self.log.debug('classifier_info', classifier_info=classifier_info)
@@ -806,8 +779,6 @@
if UDP_SRC in classifier_info:
if classifier_info[UDP_SRC] == 68:
self.log.info('dhcp upstream flow add')
- if VLAN_VID in classifier_info:
- dhcp_upstream_flows[classifier_info[VLAN_VID]] = flow
elif classifier_info[UDP_SRC] == 67:
self.log.info('dhcp downstream flow add')
self.to_controller(flow)
@@ -826,11 +797,6 @@
else:
eapol_flow_without_vlan = True
- self.log.info('out_port', out_port=fd.get_out_port(flow))
-
- flows.extend(self.create_secondary_flows(dhcp_upstream_flows, flows, "DHCP"))
- flows.extend(self.create_secondary_flows(eapol_flows, flows, "EAPOL"))
-
# The OLT app is now adding EAPOL flows with VLAN_VID=4091 but Ponsim can't
# properly handle this because it uses VLAN_VID to encode the UNI port ID.
# Add an EAPOL trap flow with no VLAN_VID match if we see the 4091 match.
@@ -845,8 +811,6 @@
flows.extend(new_eapol_flow)
self.log.info('add eapol flow with no VLAN_VID match')
- self.log.debug('ctag_map', ctag_map=self.ctag_map)
-
stub.UpdateFlowTable(FlowTable(
port=0,
flows=flows
@@ -875,6 +839,33 @@
if isinstance(msg, FlowTable):
stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
self.log.info('pushing-onu-flow-table', port=msg.port)
+
+ # Extract ctag -> uni_port mapping from ONU flows.
+ # Below we assume that a downstream flow whose VLAN_VID is not
+ # equal to the logcal port is stripping the ctag.
+ # If we find such a flow we add the mapping to the ctag_map.
+ # Note that this wouldn't be necessary if we actually knew the logical
+ # port that an upstream packet arrived on.
+ logical_port_id = "uni-{}".format(msg.port)
+ logical_port = self.adapter_agent.get_logical_port(self.logical_device_id, logical_port_id)
+ if logical_port:
+ uni_port_id = logical_port.device_port_no
+ ctag = None
+
+ for flow in msg.flows:
+ classifier_info = self.get_classifier_info(flow)
+ self.log.debug('classifier_info', classifier_info=classifier_info)
+
+ if VLAN_VID in classifier_info and IN_PORT in classifier_info:
+ if classifier_info[IN_PORT] != uni_port_id and classifier_info[VLAN_VID] != msg.port:
+ if ctag is not None:
+ self.log.error('more than one ctag inferred', ctag1=ctag, ctag2=classifier_info[VLAN_VID])
+ ctag = classifier_info[VLAN_VID]
+
+ self.update_ctag_map(ctag, msg.port)
+ else:
+ self.log.error('no logical port found', id=logical_port_id)
+
res = stub.UpdateFlowTable(msg)
self.adapter_agent.receive_proxied_message(proxy_address, res)
elif isinstance(msg, PonSimMetricsRequest):