Source code for sts.dataplane_traces.trace

# Copyright 2011-2013 Colin Scott
#
# 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.

import pickle
from pox.lib.util import assert_type
from pox.lib.packet.ethernet import *
from sts.entities import HostInterface

import base64
import logging
log = logging.getLogger("dataplane_trace")

[docs]class DataplaneEvent (object): ''' Encapsulates a packet injected at a (switch.dpid, port) pair in the network Used for trace generation or replay debugging '''
[docs] def __init__ (self, interface, packet): assert_type("interface", interface, HostInterface, none_ok=False) assert_type("packet", packet, ethernet, none_ok=False) self.interface = interface self.packet = packet
[docs] def to_json(self): json_safe_packet = base64.b64encode(self.packet.pack()).replace("\n", "") return {'interface' : self.interface.to_json(), 'packet' : json_safe_packet}
@staticmethod
[docs] def from_json(json_hash): interface = HostInterface.from_json(json_hash['interface']) raw = base64.b64decode(json_hash['packet']) packet = ethernet(raw=raw) return DataplaneEvent(interface, packet)
def __repr__(self): return "Interface:%s Packet:%s" % (str(self.interface), str(self.packet))
[docs]class Trace(object): '''Encapsulates a sequence of dataplane events to inject into a simulated network.'''
[docs] def __init__(self, tracefile_path, topology=None): with file(tracefile_path, 'r') as tracefile: self.dataplane_trace = pickle.load(tracefile) if topology is not None: # Hashmap used to inject packets from the dataplane_trace self.interface2host = { interface: host for host in topology.hosts for interface in host.interfaces } self._type_check_dataplane_trace()
def _type_check_dataplane_trace(self): for dp_event in self.dataplane_trace: if dp_event.interface not in self.interface2host: raise RuntimeError("Dataplane trace does not type check (%s)" % str(dp_event.interface))
[docs] def inject_trace_event(self): if len(self.dataplane_trace) == 0: log.warn("No more trace inputs to inject!") return else: log.info("Injecting trace input") dp_event = self.dataplane_trace.pop(0) if dp_event.interface not in self.interface2host: log.warn("Interface %s not present" % str(dp_event.interface)) return host = self.interface2host[dp_event.interface] host.send(dp_event.interface, dp_event.packet) return (dp_event, host)