def rcv_packet(self, port, vid, match): """Simulate control plane receiving a packet on a port/VID.""" pkt = build_pkt(match) vlan_pkt = pkt # TODO: packet submitted to packet in always has VID # Fake OF switch implementation should do this by applying actions. if vid not in match: vlan_match = match vlan_match['vid'] = vid vlan_pkt = build_pkt(match) msg = namedtuple( 'null_msg', ('match', 'in_port', 'data', 'total_len', 'cookie', 'reason')) msg.reason = valve_of.ofp.OFPR_ACTION msg.data = vlan_pkt.data msg.total_len = len(msg.data) msg.match = {'in_port': port} msg.cookie = self.valve.dp.cookie pkt_meta = self.valve.parse_pkt_meta(msg) self.valves_manager.valve_packet_in(self.valve, pkt_meta) # pylint: disable=no-member rcv_packet_ofmsgs = valve_of.valve_flowreorder(self.last_flows_to_dp[self.DP_ID]) self.table.apply_ofmsgs(rcv_packet_ofmsgs) resolve_ofmsgs = self.valve.resolve_gateways() self.table.apply_ofmsgs(resolve_ofmsgs) self.valve.advertise() self.valve.state_expire() self.valves_manager.update_metrics() return rcv_packet_ofmsgs
def _send_flow_msgs(self, dp_id, flow_msgs, ryu_dp=None): """Send OpenFlow messages to a connected datapath. Args: dp_id (int): datapath ID. flow_msgs (list): OpenFlow messages to send. ryu_dp: Override datapath from DPSet. """ if ryu_dp is None: ryu_dp = self.dpset.get(dp_id) if not ryu_dp: self.logger.error('send_flow_msgs: %s not up', dpid_log(dp_id)) return if dp_id not in self.valves: self.logger.error('send_flow_msgs: unknown %s', dpid_log(dp_id)) return valve = self.valves[dp_id] reordered_flow_msgs = valve_of.valve_flowreorder(flow_msgs) valve.ofchannel_log(reordered_flow_msgs) for flow_msg in reordered_flow_msgs: # pylint: disable=no-member self.metrics.of_flowmsgs_sent.labels(dp_id=hex(dp_id)).inc() flow_msg.datapath = ryu_dp ryu_dp.send_msg(flow_msg)
def rcv_packet(self, port, vid, match): pkt, eth_type = build_pkt(match) eth_pkt = valve_packet.parse_eth_pkt(pkt) pkt_meta = self.valve.parse_rcv_packet(port, vid, eth_type, pkt.data, len(pkt.data), pkt, eth_pkt) rcv_packet_ofmsgs = self.valve.rcv_packet(other_valves=[], pkt_meta=pkt_meta) rcv_packet_ofmsgs = valve_of.valve_flowreorder(rcv_packet_ofmsgs) self.table.apply_ofmsgs(rcv_packet_ofmsgs) resolve_ofmsgs = self.valve.resolve_gateways() self.table.apply_ofmsgs(resolve_ofmsgs) self.valve.advertise() self.valve.state_expire() self.valve.update_metrics(self.metrics) return rcv_packet_ofmsgs
def send_flows(self, ryu_dp, flow_msgs): """Send flows to datapath. Args: ryu_dp (ryu.controller.controller.Datapath): datapath. flow_msgs (list): OpenFlow messages to send. """ reordered_flow_msgs = valve_of.valve_flowreorder(flow_msgs) self.ofchannel_log(reordered_flow_msgs) self.metrics.of_flowmsgs_sent.labels( # pylint: disable=no-member **self.base_prom_labels).inc(len(reordered_flow_msgs)) self.recent_ofmsgs.extend(reordered_flow_msgs) for flow_msg in reordered_flow_msgs: flow_msg.datapath = ryu_dp ryu_dp.send_msg(flow_msg)
def test_delete_order(self): """Test delete ordering/deupdlication.""" global_groupdel = valve_of.groupdel(group_id=valve_of.ofp.OFPG_ALL) global_flowdel = valve_of.flowmod(cookie=None, hard_timeout=None, idle_timeout=None, match_fields=None, out_port=None, table_id=valve_of.ofp.OFPTT_ALL, inst=(), priority=0, command=valve_of.ofp.OFPFC_DELETE, out_group=valve_of.ofp.OFPG_ANY) flowdel = valve_of.flowmod(cookie=None, hard_timeout=None, idle_timeout=None, match_fields=None, out_port=None, table_id=9, inst=(), priority=0, command=valve_of.ofp.OFPFC_DELETE, out_group=valve_of.ofp.OFPG_ANY) flow = valve_of.output_port(1) flows = [flowdel, flow, flow, flow, global_flowdel, global_groupdel] reordered = valve_of.valve_flowreorder(flows, use_barriers=True) reordered_str = [str(flow) for flow in reordered] # global deletes come first self.assertTrue(valve_of.is_global_groupdel(reordered[0]), msg=reordered) self.assertTrue(valve_of.is_global_flowdel(reordered[1]), msg=reordered) # with a berrier self.assertEqual(str(valve_of.barrier()), str(reordered[2]), msg=reordered) # without the individual delete self.assertTrue(str(flowdel) not in reordered_str, msg=reordered) # with regular flow last self.assertEqual(str(flow), reordered_str[-1], msg=reordered)
def test_reorder_dupe(self): """Test simple reordering discards duplicate.""" flow = valve_of.output_port(1) flows = [flow, flow, flow] reordered = valve_of.valve_flowreorder(flows, use_barriers=False) self.assertEqual(1, len(reordered))