def flow_removed_hybrid(self, label, expire, overflow, curtime): instractions = [] for entry in expire: if entry.timeout_type == setting.TIMEOUT_IDLE and entry.priority < 32: # print('*remove dependency') rule = (entry.priority, entry.match_field) deprules = self.ruleset.depset[rule] for r in deprules: if r[0] == 32: entry = element.Entry(setting.FIELD_DSTIP, 32, r[1], None) else: entry = element.Entry(setting.FIELD_DSTPREFIX, r[0], r[1], None) instractions.append((setting.INST_DELETE, label, entry)) return instractions
def packet_in_hybrid(self, label, pkt, curtime): rule = self.ruleset.rules[pkt.dstip] deprules = self.ruleset.depset[rule] timeout = setting.DEFAULT_TIMEOUT if self.predictor.name == setting.PREDICTOR_SIMPLE: self.predictor.update((setting.INFO_PACKET_IN, label, curtime, rule)) timeout = self.predictor.predict(rule, curtime, label) if (self.predictor.name == setting.PREDICTOR_Q or self.predictor.name == setting.PREDICTOR_DQN): timeout = self.predictor.predict(rule, curtime, label) instractions = [] dst = pkt.dst path = self.shortest_pathes[label][dst][0] if rule[0] == 32: field = setting.FIELD_DSTIP priority = 32 else: field = setting.FIELD_DSTPREFIX[rule[0]] priority = rule[0] match_field = rule[1] for cnt in range(len(path)-1): action = [(setting.ACT_FWD, path[cnt+1])] entry = element.Entry(field, priority, match_field, action, flag=setting.FLAG_REMOVE_NOTIFY, ts=curtime, timeout=timeout, timeout_type=setting.TIMEOUT_IDLE) instractions.append((setting.INST_ADD, path[cnt], entry)) self.record_install(rule) for r in deprules: if r[0] == 32: field = setting.FIELD_DSTIP priority = 32 else: field = setting.FIELD_DSTPREFIX[r[0]] priority = r[0] match_field = r[1] for cnt in range(len(path)-1): action = [(setting.ACT_FWD, path[cnt+1])] entry = element.Entry(field, priority, match_field, action, flag=None, ts=curtime, timeout=setting.INF, timeout_type=setting.TIMEOUT_HARD) instractions.append((setting.INST_ADD, path[cnt], entry)) self.record_install(r) return instractions
def packet_in_idle(self, label, pkt, curtime): instractions = [] dst = pkt.dst path = self.shortest_pathes[label][dst][0] field = setting.FIELD_DSTIP priority = 32 match_field = pkt.dstip timeout = setting.DEFAULT_TIMEOUT if self.predictor.name == setting.PREDICTOR_SIMPLE: rule = (32, match_field) self.predictor.update((setting.INFO_PACKET_IN, label, curtime, rule)) timeout = self.predictor.predict(rule, curtime, label) if (self.predictor.name == setting.PREDICTOR_Q or self.predictor.name == setting.PREDICTOR_DQN): rule = (32, match_field) timeout = self.predictor.predict(rule, curtime, label) for cnt in range(len(path)-1): action = [(setting.ACT_FWD, path[cnt+1])] entry = element.Entry(field, priority, match_field, action, flag=setting.FLAG_REMOVE_NOTIFY, ts=curtime, timeout=timeout, timeout_type=setting.TIMEOUT_IDLE) instractions.append((setting.INST_ADD, path[cnt], entry)) self.record_install((32, match_field)) return instractions
def get_match_entry(self, pkt): match_entry = element.Entry(None, -1, None, None) def comp_entry(new_entry, old_entry): if new_entry.priority > old_entry.priority: return new_entry elif new_entry.priority == old_entry.priority: # TODO: ECMP return old_entry else: return old_entry # fast match (exact matching) pkt_attr = {setting.FIELD_TP: pkt.tp, setting.FIELD_DSTIP: pkt.dstip} for field in pkt_attr: if field in self.flow_table: attr = pkt_attr[field] if attr in self.flow_table[field]: entry = self.flow_table[field][attr] match_entry = comp_entry(entry, match_entry) # slow match (wildcard matching for dstip) if match_entry.priority == -1: for prefix in setting.FIELD_DSTPREFIX: field = setting.FIELD_DSTPREFIX[prefix] if field in self.flow_table: attr = element.int2ip( element.get_ip_range(pkt.dstip, prefix)[0]) if attr in self.flow_table[field]: entry = self.flow_table[field][attr] match_entry = comp_entry(entry, match_entry) return match_entry
def get_match_entry(self, pkt): match_entry = element.Entry(None, -1, None, None) def comp_entry(new_entry, old_entry): if new_entry.priority > old_entry.priority: return new_entry elif new_entry.priority == old_entry.priority: # TODO: ECMP return old_entry else: return old_entry # fast match (exact matching) # sequential matching against label(50) -> tuple(40) -> dstip(32) -> others if setting.FIELD_LABEL_SRC_DST in self.fast_table: if (pkt.label, pkt.src, pkt.dst) in self.fast_table[setting.FIELD_LABEL_SRC_DST]: entry = self.fast_table[setting.FIELD_LABEL_SRC_DST][(pkt.label, pkt.src, pkt.dst)] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_LABEL_RLABEL_DST in self.fast_table: if (pkt.label, pkt.rlabel, pkt.dst) in self.fast_table[setting.FIELD_LABEL_RLABEL_DST]: entry = self.fast_table[setting.FIELD_LABEL_RLABEL_DST][(pkt.label, pkt.rlabel, pkt.dst)] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_LABEL in self.fast_table: if pkt.label in self.fast_table[setting.FIELD_LABEL]: entry = self.fast_table[setting.FIELD_LABEL][pkt.label] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_LABEL_RLABEL in self.fast_table: if (pkt.label, pkt.rlabel) in self.fast_table[setting.FIELD_LABEL_RLABEL]: entry = self.fast_table[setting.FIELD_LABEL_RLABEL][(pkt.label, pkt.rlabel)] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_TP in self.fast_table: if pkt.tp in self.fast_table[setting.FIELD_TP]: entry = self.fast_table[setting.FIELD_TP][pkt.tp] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_DSTIP in self.fast_table: if pkt.dstip in self.fast_table[setting.FIELD_DSTIP]: entry = self.fast_table[setting.FIELD_DSTIP][pkt.dstip] if entry is not None: match_entry = comp_entry(entry, match_entry) if setting.FIELD_DST in self.fast_table: if pkt.dst in self.fast_table[setting.FIELD_DST]: entry = self.fast_table[setting.FIELD_DST][pkt.dst] if entry is not None: match_entry = comp_entry(entry, match_entry) # TODO: slow match (wildcard matching) return match_entry
def packet_in_default(self, label, pkt): dst = pkt.dst path = self.shortest_pathes[label][dst][0] field = setting.FIELD_TP priority = 40 match_field = pkt.tp action = [(setting.ACT_FWD, path[1])] entry = element.Entry(field, priority, match_field, action) inst = [(setting.INST_ADD, label, entry) ] # instructions = [(action, object, content), ...] return inst
def packet_in_default(self, label, pkt, curtime): dst = pkt.dst path = self.shortest_pathes[label][dst][0] field = setting.FIELD_TP priority = 40 match_field = pkt.tp action = [(setting.ACT_FWD, path[1])] entry = element.Entry(field, priority, match_field, action, flag=setting.FLAG_REMOVE_NOTIFY, ts=curtime, timeout=setting.DEFAULT_TIMEOUT, timeout_type=setting.TIMEOUT_IDLE) # 1s idle timeout inst = [(setting.INST_ADD, label, entry)] # instructions = [(action, object, content), ...] return inst
def packet_in_spath(self, label, pkt): dst = pkt.dst path = self.shortest_pathes[label][dst][0] instractions = [] field = setting.FIELD_TP priority = 40 match_field = pkt.tp for cnt in range(len(path) - 1): action = [(setting.ACT_FWD, path[cnt + 1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_ADD, path[cnt], entry) instractions.append(inst) return instractions
def packet_in_spath(self, label, pkt, curtime): dst = pkt.dst path = self.shortest_pathes[label][dst][0] instractions = [] field = setting.FIELD_TP priority = 40 match_field = pkt.tp for cnt in range(len(path)-1): action = [(setting.ACT_FWD, path[cnt+1])] entry = element.Entry(field, priority, match_field, action, flag=setting.FLAG_REMOVE_NOTIFY, ts=curtime, timeout=setting.DEFAULT_TIMEOUT, timeout_type=setting.TIMEOUT_IDLE) # 1s idle timeout inst = (setting.INST_ADD, path[cnt], entry) instractions.append(inst) return instractions
def fabric_simu(net, log_prefix, check_interval=5000): # print('***simulation begins***') n = net c = n.controller instractions = [] for src in range(n.switch_num): for dst in range(n.switch_num): if src == dst: continue # select a path path = c.shortest_pathes[src][dst][0] # install tagging entries at the first switch field = setting.FIELD_DST priority = 1 match_field = dst action = [(setting.ACT_TAG, dst), (setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, src, entry) instractions.append(inst) # install forwarding entries field = setting.FIELD_LABEL priority = 50 match_field = dst for cnt in range(1, len(path) - 1): action = [(setting.ACT_FWD, path[cnt + 1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, path[cnt], entry) instractions.append(inst) n.process_ctrl_messages(instractions) flownum = n.traffic.flownum d = data.Data() delay = 0 overflow_num = 0 pktnum = 0 for pkt in n.traffic.pkts: # print('processing packet');pkt.print_pkt() sw = n.switches[pkt.src] # print('arriving switch %d' % sw.label) hop = 0 of = 0 while True: if pkt.dst == sw.label: pkt.path.append(sw.label) break [pkt, next_hop] = sw.recv_pkt(pkt) # print('\tforwarding to %s' % str(next_hop)) if next_hop == setting.CTRL: raise AssertionError( 'Error. Packets in Fabric do not go pass controller. Exit.' ) elif next_hop == setting.LOCAL: src = pkt.src dst = pkt.dst path = c.shortest_pathes[src][dst][0] # install tagging rule matching exact dst IP field = setting.FIELD_TP priority = 40 match_field = pkt.tp action = [(setting.ACT_TAG, dst), (setting.ACT_FWD, path[1])] entry = element.Entry(field, priority, match_field, action) instractions = [(setting.INST_ADD, src, entry)] of = n.process_ctrl_messages(instractions) # forward next_hop = path[1] sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) else: sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) hop += 1 assert hop < 10 * len(n.topo) # print('pkt path = {}'.format(pkt.path)) fnum = flownum[pktnum] pktnum += 1 overflow_num += of pkttime = c.get_delay(pkt.path, pkt.size) delay += pkttime flowsize = n.traffic.flowsize[pkt.tp] d.record_fct(pkt.tp, pkttime, flowsize) if fnum % check_interval == 0: if fnum not in d.delay['flownum']: instractions = [(setting.INST_QUERY, setting.INST_OBJ_ALL, None)] totentry = n.process_ctrl_messages(instractions) maxentry = 0 for label in range(n.switch_num): instractions = [(setting.INST_QUERY, setting.INST_OBJ_TABLE, label)] maxentry = max(maxentry, n.process_ctrl_messages(instractions)) d.record(fnum, delay, totentry, maxentry, overflow_num) d.print_checkpoint(fnum, log_prefix + '_checkpoint.txt') d.print_data(log_prefix) return
if next_hop == setting.CTRL: pkt.path.append(setting.CTRL) return [pkt, next_hop] def print_table(self, filename=None): for entry in self.flow_table: entry.print_entry(filename) return 0 if __name__ == '__main__': label = 1 sw = Switch(label) entry = element.Entry(setting.FIELD_DSTIP, 32, '1.2.3.4', [(setting.ACT_FWD, 2)]) sw.add_entry(entry) pkt = traffic.Packet(('0.0.3.0', '1.2.3.4')) [pkt, next_hop] = sw.recv_pkt(pkt) assert next_hop == 2 entry = element.Entry(setting.FIELD_DSTIP, 40, '1.2.3.4', [(setting.ACT_TAG, 10), (setting.ACT_FWD, 10)]) sw.add_entry(entry) entry = element.Entry(setting.FIELD_DSTIP, 10, '1.2.3.4', [(setting.ACT_TAG, 10), (setting.ACT_FWD, 10)]) sw.add_entry(entry) [pkt, next_hop] = sw.recv_pkt(pkt) assert next_hop == 10 assert pkt.label == 10 assert sw.get_size() == 1
def difane_simu(net, log_prefix, check_interval=5000): # print('***simulation begins***') n = net c = n.controller instractions = [] for region_label in c.regions: for dst in c.regions[region_label]: # install relay rule to forward packets from auth. switch to egress path = c.shortest_pathes[region_label][dst][0] field = setting.FIELD_LABEL priority = 50 match_field = dst for cnt in range(1, len(path) - 1): action = [(setting.ACT_FWD, path[cnt + 1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, path[cnt], entry) instractions.append(inst) for src in range(n.switch_num): if src == dst: continue # install auth. rule to trigger local action field = setting.FIELD_LABEL_SRC_DST priority = 50 match_field = (region_label, src, dst) action = [(setting.ACT_TAG, dst), (setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, region_label, entry) instractions.append(inst) path = c.shortest_pathes[src][region_label][0] if len(path) > 1: # src != region_label # install part. rule to forward unknown packets to # corresponding auth. swich field = setting.FIELD_DST priority = 1 match_field = dst action = [(setting.ACT_TAG, region_label), (setting.ACT_FWD, path[1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, src, entry) instractions.append(inst) # install relay rule to forward packets to auth. switch field = setting.FIELD_LABEL priority = 50 match_field = region_label action = [(setting.ACT_FWD, path[1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, src, entry) instractions.append(inst) else: # src == region_label: forward to local field = setting.FIELD_DST priority = 1 match_field = dst action = [(setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, src, entry) instractions.append(inst) n.process_ctrl_messages(instractions) flownum = n.traffic.flownum d = data.Data() delay = 0 overflow_num = 0 pktnum = 0 for pkt in n.traffic.pkts: # print('processing packet');pkt.print_pkt() sw = n.switches[pkt.src] # print('arriving switch %d' % sw.label) hop = 0 of = 0 while True: if pkt.dst == sw.label: # abandon using receving entry pkt.path.append(sw.label) break [pkt, next_hop] = sw.recv_pkt(pkt) # print('\tforwarding to %s' % str(next_hop)) if next_hop == setting.CTRL: raise AssertionError( 'Error. Packets in DIFANE do not go pass controller. Exit.' ) elif next_hop == setting.LOCAL: # perform local actions # install forwarding entries on shortest path instractions = [] src = pkt.src dst = pkt.dst fast_path = c.shortest_pathes[src][dst][0] field = setting.FIELD_TP priority = 40 match_field = pkt.tp for cnt in range(len(fast_path) - 1): action = [(setting.ACT_FWD, fast_path[cnt + 1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_ADD, fast_path[cnt], entry) instractions.append(inst) of = n.process_ctrl_messages(instractions) # forward slow_path = c.shortest_pathes[sw.label][dst][0] next_hop = slow_path[1] sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) else: sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) hop += 1 assert hop < 10 * len(n.topo) # print('pkt path = {}'.format(pkt.path)) fnum = flownum[pktnum] pktnum += 1 overflow_num += of pkttime = c.get_delay(pkt.path, pkt.size) delay += pkttime flowsize = n.traffic.flowsize[pkt.tp] d.record_fct(pkt.tp, pkttime, flowsize) if fnum % check_interval == 0: if fnum not in d.delay['flownum']: instractions = [(setting.INST_QUERY, setting.INST_OBJ_ALL, None)] totentry = n.process_ctrl_messages(instractions) maxentry = 0 for label in range(n.switch_num): instractions = [(setting.INST_QUERY, setting.INST_OBJ_TABLE, label)] maxentry = max(maxentry, n.process_ctrl_messages(instractions)) d.record(fnum, delay, totentry, maxentry, overflow_num) d.print_checkpoint(fnum, log_prefix + '_checkpoint.txt') d.print_data(log_prefix) return
assert p.round(p.t_max[label]) == 6e6 rule = (32, '1.2.3.4') p.update((setting.INFO_PACKET_IN, label, 12e6, rule)) assert p.predict(rule, 12, label) == 6e6 p.update((setting.INFO_FLOW_REMOVED, label, 11e6, rule)) assert p.predict(rule, 12, label) == 3e6 import element p = QPredictor() p.init(1) rule = (32, '1.2.3.4') timeout = p.predict(rule, 0, label) e = element.Entry(setting.FIELD_DSTIP, 32, '1.2.3.4', None, flag=None, ts=0, timeout=timeout, timeout_type=None) e.counter = 10 # 10 hits between 0~timeout then expire p.update((setting.INFO_FLOW_REMOVED, label, timeout, e)) p.train() assert p.Q[(0, 0)][(timeout / 1e6) - 1] == 1.0 * e.counter / (timeout / 1e6) p = DQNPredictor() p.init(1) rule = (32, '1.2.3.4') timeout = p.predict(rule, 0, label) e = element.Entry(setting.FIELD_DSTIP, 32,
else: raise NameError('Error. No such act type. Exit.') pkt.path.append(self.label) if next_hop == setting.CTRL: pkt.path.append(setting.CTRL) return [pkt, next_hop] if __name__ == '__main__': label = 0 sw = Switch(label) # basic tests entry = element.Entry(setting.FIELD_DSTIP, 32, '1.2.3.4', [(setting.ACT_FWD, 1)]) sw.add_entry(entry) assert sw.table_size == 1 pkt = traffic.Packet(('0.0.0.0', '1.2.3.4')) [pkt, next_hop] = sw.recv_pkt(pkt) assert next_hop == 1 entry = element.Entry(setting.FIELD_DSTPREFIX[24], 24, '1.2.3.0', [(setting.ACT_FWD, 2)]) sw.add_entry(entry) pkt = traffic.Packet(('0.0.0.0', '1.2.3.5')) [pkt, next_hop] = sw.recv_pkt(pkt) assert next_hop == 2 setting.FLOW_TABLE_SIZE[setting.TYPE_HARDWARE] = 1 [_, overflow] = sw.update() assert len(overflow) == 1
def sdls_ctrl_simu(net, log_prefix, check_interval=5000, upd_delay=0, policy=0, k=1.0, ctrl_delay=setting.CONTROLLER_DELAY / 2): # print('***simulation begins***') n = net c = n.controller instractions = [] for region_label in c.regions: # intra-region routing rules for src in c.regions[region_label]: for dst in c.regions[region_label]: if src == dst: continue # tag and forward by IP for src path = c.region_pathes[src][dst][0] field = setting.FIELD_DST priority = 1 match_field = dst action = [(setting.ACT_TAG, dst), (setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, src, entry) instractions.append(inst) # forward by label field = setting.FIELD_LABEL priority = 50 match_field = dst for cnt in range(1, len(path) - 1): action = [(setting.ACT_FWD, path[cnt + 1])] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, path[cnt], entry) instractions.append(inst) # change default action for src in c.regions[region_label]: sw = n.switches[src] if src == region_label: continue else: path = c.region_pathes[src][region_label][0] action = [(setting.ACT_TAG, region_label), (setting.ACT_RTAG, src), (setting.ACT_FWD, path[1])] sw.set_default_action(action) # software switch as a sender for dst in range(n.switch_num): if dst in c.regions[region_label]: continue fast_path = c.shortest_pathes[region_label][dst][0] (_, seg) = c.segments[region_label][dst][0][0] end_point = seg[-1] end_cnt = fast_path.index(end_point) next_begin_point = fast_path[end_cnt + 1] field = setting.FIELD_DST priority = 1 match_field = dst action = [(setting.ACT_TAG, end_point), (setting.ACT_RTAG, next_begin_point), (setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, region_label, entry) instractions.append(inst) # inter-region routing rules for src in range(n.switch_num): for dst in range(n.switch_num): if c.label2region[src] == c.label2region[dst]: continue if dst in c.regions[region_label]: continue fast_path = c.shortest_pathes[src][dst][0] segments = c.segments[src][dst][0] # find the segment for (belong_region, seg) in segments: if belong_region == region_label: begin_point = seg[0] end_point = seg[-1] end_cnt = fast_path.index(end_point) next_begin_point = fast_path[end_cnt + 1] slow_path = c.region_pathes[region_label][end_point][0] # install tagging rule field = setting.FIELD_LABEL_RLABEL_DST priority = 60 match_field = (region_label, begin_point, dst) action = [(setting.ACT_TAG, end_point), (setting.ACT_RTAG, next_begin_point), (setting.ACT_FWD, setting.LOCAL)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, region_label, entry) instractions.append(inst) # install rule to forward packets to another region field = setting.FIELD_LABEL_RLABEL priority = 50 match_field = (end_point, next_begin_point) action = [(setting.ACT_TAG, None), (setting.ACT_RTAG, None), (setting.ACT_FWD, next_begin_point)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_FIX, end_point, entry) instractions.append(inst) n.process_ctrl_messages(instractions) flownum = n.traffic.flownum d = data.Data() delay = 0 overflow_num = 0 pktnum = 0 inst_queue = [] inst_point = 0 for pkt in n.traffic.pkts: # print('processing packet');pkt.print_pkt() sw = n.switches[pkt.src] # print('arriving switch %d' % sw.label) hop = 0 of = 0 while True: if pkt.dst == sw.label: # abandon using receving entry pkt.path.append(sw.label) break [pkt, next_hop] = sw.recv_pkt(pkt) # print('\tforwarding to %s' % str(next_hop)) if next_hop == setting.CTRL: raise AssertionError( 'Error. Packets in SDLS do not go pass controller. Exit.') elif next_hop == setting.LOCAL: dst = pkt.dst # intra-region routing local action if c.label2region[sw.label] == c.label2region[dst]: intra_path = c.region_pathes[sw.label][dst][0] filed = setting.FIELD_TP priority = 40 match_field = pkt.tp action = [(setting.ACT_TAG, dst), (setting.ACT_FWD, intra_path[1])] entry = element.Entry(filed, priority, match_field, action) instractions = [(setting.INST_ADD, sw.label, entry)] of = n.process_ctrl_messages(instractions) # forward next_hop = intra_path[1] sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) # inter-region routing local action else: src = pkt.src fast_path = c.shortest_pathes[src][dst][0] segment = c.segments[src][dst][0] instractions = [] for (belong_region, seg) in segment[:-1]: # no need for last segment begin_point = seg[0] end_point = seg[-1] end_cnt = fast_path.index(end_point) next_begin_point = fast_path[end_cnt + 1] if pkt.label == end_point: now_end_point = end_point now_next_begin_point = next_begin_point field = setting.FIELD_TP priority = 40 match_field = pkt.tp if begin_point != end_point: # install forwarding entries on segment of the shortest path action = [(setting.ACT_TAG, end_point), (setting.ACT_RTAG, next_begin_point), (setting.ACT_FWD, seg[1])] else: action = [(setting.ACT_FWD, next_begin_point)] entry = element.Entry(field, priority, match_field, action) inst = (setting.INST_ADD, begin_point, entry) instractions.append(inst) inst_queue.append((instractions, delay, pkt.tp)) # forward if sw.label != now_end_point: slow_path = c.region_pathes[sw.label][now_end_point][0] next_hop = slow_path[1] else: next_hop = now_next_begin_point sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) else: sw = n.switches[next_hop] # print('arriving switch %d' % sw.label) hop += 1 assert hop < 10 * len(n.topo) # print('pkt path = {}'.format(pkt.path)) if (inst_point < len(inst_queue) and inst_queue[inst_point][1] + ctrl_delay + upd_delay <= delay): new_inst_point = inst_point + 1 while (new_inst_point < len(inst_queue) and inst_queue[new_inst_point][1] + ctrl_delay < delay): new_inst_point += 1 # controller update flow table in batch available_update = inst_queue[inst_point:new_inst_point] inst_point = new_inst_point if policy == 0: # update all to_update = available_update elif policy == 1: # update randomly from random import sample to_update = sample(available_update, int(k * len(available_update))) elif policy == 2: # select elephant flow flow_cnt = {} for (_, _, tp) in available_update: if tp in flow_cnt: flow_cnt[tp] += 1 else: flow_cnt[tp] = 1 select_tp = sorted(flow_cnt, key=lambda e: flow_cnt[e], reverse=True)[:int(k * len(flow_cnt))] to_update = [] for update in available_update: if update[2] in select_tp: to_update.append(update) else: raise NameError('Error. No such policy. Exit.') exit(1) for (instractions, _, _) in to_update: of += n.process_ctrl_messages(instractions) fnum = flownum[pktnum] pktnum += 1 overflow_num += of pkttime = c.get_delay(pkt.path, pkt.size) delay += pkttime flowsize = n.traffic.flowsize[pkt.tp] d.record_fct(pkt.tp, pkttime, flowsize) if fnum % check_interval == 0: if fnum not in d.delay['flownum']: instractions = [(setting.INST_QUERY, setting.INST_OBJ_ALL, None)] totentry = n.process_ctrl_messages(instractions) maxentry = 0 for label in range(n.switch_num): instractions = [(setting.INST_QUERY, setting.INST_OBJ_TABLE, label)] maxentry = max(maxentry, n.process_ctrl_messages(instractions)) d.record(fnum, delay, totentry, maxentry, overflow_num) d.print_checkpoint(fnum, log_prefix + '_checkpoint.txt') d.print_data(log_prefix) return