def add_flow( self, datapath: Datapath, priority: OFPriority, match: Sequence[OFPMatch], actions: Sequence[OFPAction], is_direct_flow: bool = True, ) -> None: ofproto = datapath.ofproto parser = datapath.ofproto_parser inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] # If flow via relayer was infinite, then we would never receive a # PACKET_IN event for that destination and would never know that we # should attempt to connect directly. By using a finite timeout for # such flows we have a chance for getting a PACKET_IN event at some # point (after the indirect flow is expired). hard_timeout = (0 if is_direct_flow else settings.FLOW_INDIRECT_MAX_LIFETIME_SECONDS) mod = parser.OFPFlowMod( datapath=datapath, priority=priority.value, match=match, instructions=inst, # idle_timeout=3600, hard_timeout=hard_timeout, ) datapath.send_msg(mod)
def add_flow(datapath: Datapath, priority: int, match: OFPMatch, actions: [OFPActionOutput], idle_timeout: int = 300, hard_timeout: int = 300): """ Send a flow to the switch to be added to the flow table :param datapath: A Datapath object which represents the switch to which we want to add the flow :param priority: The priority of the flow. Should be higher than zero. Zero is the default flow used when traffic does not match and should be sent to the controller. :param match: An OFPMatch object containing the match criteria for this flow :param actions: The actions you want applied if there is a flow match. :param idle_timeout: The timeout for the flow if the switch receives no matching packets. 0 is no timeout. :param hard_timeout: The timeout for the flow regardless if the switch does or doesn't receive packets. 0 is no timeout. """ ofproto = datapath.ofproto # Same as ofproto, indicates the ofproto_parser module. In the case of OpenFlow 1.3 format will be following # module. ryu.ofproto.ofproto_v1_3_parser parser = datapath.ofproto_parser # construct flow_mod message and send it. inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] # The class corresponding to the Flow Mod message is the OFPFlowMod class. The instance of the OFPFlowMod # class is generated and the message is sent to the OpenFlow switch using the Datapath.send_msg() method. mod = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst, idle_timeout=idle_timeout, hard_timeout=hard_timeout) datapath.send_msg(mod)
def send_arp(self, dp: Datapath, port): for dst_id in range(1, 20): actions = [dp.ofproto_parser.OFPActionOutput(port.port_no)] out = dp.ofproto_parser.OFPPacketOut( datapath=dp, buffer_id=dp.ofproto.OFP_NO_BUFFER, in_port=dp.ofproto.OFPP_CONTROLLER, actions=actions, data=utils.build_arp(dst_id)) dp.send_msg(out)
def _create_fake_datapath(): s = socket.socket() app = ryu.base.app_manager.RyuApp() app.name = 'ofp_event' ryu.base.app_manager.register_app(app) datapath = Datapath(s, '1') datapath.ofproto = ofproto datapath.ofproto_parser = parser return datapath
def remove_all_flows(datapath: Datapath): """ Removes all the flows from a switch. :param datapath: A Datapath object which represents the switch from which we want to remove flows """ match = datapath.ofproto_parser.OFPMatch() mod = datapath.ofproto_parser.OFPFlowMod( datapath, 0, 0, datapath.ofproto.OFPTT_ALL, datapath.ofproto.OFPFC_DELETE, 0, 0, 0, 0xffffffff, datapath.ofproto.OFPP_ANY, datapath.ofproto.OFPG_ANY, 0, match, []) datapath.send_msg(mod)
def send_arp_mod(self, dp: Datapath): match = dp.ofproto_parser.OFPMatch(eth_type=ether.ETH_TYPE_ARP, eth_dst='fe:ee:ee:ee:ee:ef') actions = [ dp.ofproto_parser.OFPActionOutput(dp.ofproto.OFPP_CONTROLLER, dp.ofproto.OFPCML_NO_BUFFER) ] instructions = [ dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions=actions) ] mod = dp.ofproto_parser.OFPFlowMod(datapath=dp, match=match, instructions=instructions) dp.send_msg(mod)
def del_flows_to_ofport(self, datapath: Datapath, out_port: OFPort) -> None: ofproto = datapath.ofproto parser = datapath.ofproto_parser mod = parser.OFPFlowMod( datapath=datapath, command=ofproto.OFPFC_DELETE, buffer_id=ofproto.OFPCML_NO_BUFFER, out_port=out_port, out_group=ofproto.OFPG_ANY, match=parser.OFPMatch(), instructions=[], ) datapath.send_msg(mod)
def add_mpls_pop(self, dp: Datapath): ofproto = dp.ofproto parser = dp.ofproto_parser instructions = [ parser.OFPInstructionActions( [parser.OFPActionPopMpls(ether.ETH_TYPE_MPLS)]), parser.OFPInstructionGotoTable(1) ] mod = parser.OFPFlowMod( datapath=dp, table_id=0, priority=3, match=parser.OFPMatch(eth_type=ether.ETH_TYPE_MPLS), instructions=instructions) dp.send_msg(mod)
def add_flow(self, datapath: Datapath, priority, match, actions, table_id=0): ofproto = datapath.ofproto parser = datapath.ofproto_parser inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] mod = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst, table_id=table_id) datapath.send_msg(mod)
def send(self, msg_list: List[MsgBase], datapath: Datapath, txn_id: Any=None, timeout: int=DEFAULT_TIMEOUT_SEC, channel: Optional[MsgChannel]=None) -> MsgChannel: """ Send a message to OVS and track the result asynchronously. Multiple messages can be tracked using a transaction id (txn_id). Args: msg_list: list of messages to send datapath: datapath representing switch to send to txn_id: some kind of marker to track the messages sent (does not have to be unique) timeout: time before ignoring request channel: optional channel to use for the result. If it's not specified, one is created Returns: The channel passed in or the one created if it wasn't passed """ switch = self._switches.get(datapath.id, None) if switch is None: # new switch to track switch = self._SwitchInfo() self._switches[datapath.id] = switch if channel is None: channel = MsgChannel() # set xids in all msgs msg_xids = [datapath.set_xid(msg) for msg in msg_list] req = self._MsgRequest(txn_id, msg_xids, channel) barrier = datapath.ofproto_parser.OFPBarrierRequest(datapath) datapath.set_xid(barrier) # sets xid in the barrier switch.requests_by_barrier[barrier.xid] = req for msg in msg_list: switch.results_by_msg[msg.xid] = None datapath.send_msg(msg) datapath.send_msg(barrier) req.set_timeout(timeout, switch, barrier.xid, msg_xids) return channel
def request_stats(datapath: Datapath) -> None: proto = datapath.ofproto parser = datapath.ofproto_parser req = parser.OFPPortStatsRequest(datapath, 0, proto.OFPP_ANY) datapath.send_msg(req)