def meteradd(meter_conf, command=ofp.OFPMC_ADD): """Add a meter based on YAML configuration.""" class NoopDP: """Fake DP to be able to use ofctl to parse meter config.""" id = 0 msg = None ofproto = ofp ofproto_parser = parser def send_msg(self, msg): """Save msg only.""" self.msg = msg @staticmethod def set_xid(msg): """Clear msg XID.""" msg.xid = 0 noop_dp = NoopDP() ofctl.mod_meter_entry(noop_dp, meter_conf, command) noop_dp.msg.xid = None noop_dp.msg.datapath = None return noop_dp.msg
def mod_meter_entry(self, req, cmd, **_kwargs): try: flow = ast.literal_eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if cmd == 'add': cmd = dp.ofproto.OFPMC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPMC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPMC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_meter_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \ dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: LOG.debug('Request not supported in this OF protocol version') return Response(status=501) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def mod_meter_entry(self, req, cmd, **_kwargs): try: flow = eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \ dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: LOG.debug('Unsupported OF protocol') return Response(status=501) if cmd == 'add': cmd = dp.ofproto.OFPMC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPMC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPMC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_meter_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def meteradd(meter_conf): """Add a meter based on YAML configuration.""" class NoopDP: """Fake DP to be able to use ofctl to parse meter config.""" id = 0 msg = None ofproto = ofp ofproto_parser = parser def send_msg(self, msg): """Save msg only.""" self.msg = msg @staticmethod def set_xid(msg): """Clear msg XID.""" msg.xid = 0 noop_dp = NoopDP() ofctl.mod_meter_entry(noop_dp, meter_conf, ofp.OFPMC_ADD) noop_dp.msg.xid = None noop_dp.msg.datapath = None return noop_dp.msg
def mod_meter_entry(self, req, cmd, **_kwargs): try: flow = eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \ dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: LOG.debug('Unsupported OF protocol') return Response(status=501) if cmd == 'add': cmd = dp.ofproto.OFPMC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPMC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPMC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_meter_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) res = Response(status=200) res.headers.add('Access-Control-Allow-Origin', '*') return res
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst src = eth.src dpid = datapath.id #TODO add meter if self.addmeter==0: cmd=datapath.ofproto.OFPMC_ADD if datapath.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: print self.flow ofctl_v1_3.mod_meter_entry(datapath,self.flow,cmd)#TODO complete the parameters def mod_meter_entry(dp, flow, cmd) #TODO check ofproto_v1_3_paser.py class OFPMeterMod(MsgBase): self.addmeter=1 print 'add meter table' self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) self.add_flow(datapath, 1, match, actions) print 'add flow' action = [parser.OFPInstructionMeter(self.flow.get('meter_id'))] self.add_meter(datapath, 1, match, action)#TODO the action should be a meter TODO so we should add meter entry to meter table first print 'add meter' data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def init_meters(self, datapath, ofproto, parser): self.cookie += 1 meter_id = self.cookie self.meter_ids[datapath.id] = meter_id #meter_id = self._next_cookie() meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 30000 }] } ofctl.mod_meter_entry(datapath, meter, ofproto.OFPMC_ADD)
def initialize_switch(self): flow_stat = ofctl.get_flow_stats(self.dp, self.waiters) for s in flow_stat[str(self.dp.id)]: self.logger.debug("deleting flow [cookie: %d]" % s['cookie']) cmd = self.dp.ofproto.OFPFC_DELETE ofctl.mod_flow_entry(self.dp, {'table_id':self.dp.ofproto.OFPTT_ALL}, cmd) group_stat = ofctl.get_group_desc(self.dp, self.waiters) for s in group_stat[str(self.dp.id)]: self.logger.debug("deleting group[id: %d] %s" % (s['group_id'], s)) cmd = self.dp.ofproto.OFPGC_DELETE ofctl.mod_group_entry(self.dp, {'type':s['type'], 'group_id':s['group_id']}, cmd) ofctl.mod_meter_entry(self.dp, {'meter_id':self.dp.ofproto.OFPM_ALL}, self.dp.ofproto.OFPMC_DELETE)
def __init__(self, _id, conf=None): if conf is None: conf = {} assert (conf['entry']) assert (conf['entry']['flags']) assert (conf['entry']['bands']) self.update(conf) self._id = _id conf['entry']['meter_id'] = self.meter_id noop_dp = NoopDP() noop_dp.ofproto = ofp noop_dp.ofproto_parser = parser ofctl.mod_meter_entry(noop_dp, self.entry, ofp.OFPMC_ADD) noop_dp.msg.xid = None noop_dp.msg.datapath = None self.entry_msg = noop_dp.msg
def addflowsql(self, dst, dpid, in_port, out_port, flag, priority): print 'add flow sql !!!!!!!!!!!!!!!!!!!!!!!!!!!' print dpid, in_port, out_port data_path = get_switch(self, dpid) #TODO test print type(data_path) print '!!!!!!!!!!!!!!!!!!!' print data_path datapath = data_path[0].dp #TODO test print 'datapath = ' print datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser print 'dst = ' + str(dst) print 'dpid = ' + str(dpid) print 'in_port = ' + str(in_port) print 'out port = ' + str(out_port) ## actions=[parser.OFPActionOutput(out_port)] match = parser.OFPMatch(in_port=in_port, eth_dst=dst) f = 'ff:ff:ff:ff:ff:ff' if 1 == flag: self.delete_flow(datapath, match) #TODO test delete flow!! #TODO delete the ff:ff:ff:ff:ff:ff flow matchf = parser.OFPMatch(in_port=in_port, eth_dst=f) self.delete_flow(datapath, matchf) print '!!!!!!!!!!!!!!!!!!add flow!!!!!!!!!!!!!!!!!!!!in_port=' + str( in_port) + ' dst=' + str(dst) + ' out_port=' + str( out_port) + ' dpid=' + str(dpid) ## self.add_flow(datapath, 1, match, actions) if None == self.addmeter.get(dpid): #TODO test add meter cmd = datapath.ofproto.OFPMC_ADD if datapath.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: print self.flow ofctl_v1_3.mod_meter_entry( datapath, self.flow, cmd ) #TODO complete the parameters def mod_meter_entry(dp, flow, cmd) #TODO check ofproto_v1_3_paser.py class OFPMeterMod(MsgBase): self.addmeter[dpid] = 1 #self.addflow[dpid]=0 print 'add meter table' ## action = [parser.OFPInstructionMeter(self.flow.get('meter_id'))] ## self.add_meter(datapath, 1, match, action)#TODO the action should be a meter TODO so we should add meter entry to meter table first ## print 'add meter' flowaction = [parser.OFPActionOutput(out_port)] meteraction = parser.OFPInstructionMeter(self.flow.get('meter_id')) self.add_flow_meter(datapath, priority, match, flowaction, meteraction)
def addflowsql(self, dst, dpid, in_port, out_port, flag, priority): print 'add flow sql !!!!!!!!!!!!!!!!!!!!!!!!!!!' print dpid,in_port,out_port data_path=get_switch(self,dpid)#TODO test print type(data_path) print '!!!!!!!!!!!!!!!!!!!' print data_path datapath=data_path[0].dp#TODO test print 'datapath = ' print datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser print 'dst = '+str(dst) print 'dpid = '+str(dpid) print 'in_port = '+str(in_port) print 'out port = '+str(out_port) ## actions=[parser.OFPActionOutput(out_port)] match=parser.OFPMatch(in_port=in_port,eth_dst=dst) f='ff:ff:ff:ff:ff:ff' if 1==flag: self.delete_flow(datapath, match)#TODO test delete flow!! #TODO delete the ff:ff:ff:ff:ff:ff flow matchf=parser.OFPMatch(in_port=in_port,eth_dst=f) self.delete_flow(datapath, matchf) print '!!!!!!!!!!!!!!!!!!add flow!!!!!!!!!!!!!!!!!!!!in_port='+str(in_port)+' dst='+str(dst)+' out_port='+str(out_port)+' dpid='+str(dpid) ## self.add_flow(datapath, 1, match, actions) if None==self.addmeter.get(dpid):#TODO test add meter cmd=datapath.ofproto.OFPMC_ADD if datapath.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: print self.flow ofctl_v1_3.mod_meter_entry(datapath,self.flow,cmd)#TODO complete the parameters def mod_meter_entry(dp, flow, cmd) #TODO check ofproto_v1_3_paser.py class OFPMeterMod(MsgBase): self.addmeter[dpid]=1 #self.addflow[dpid]=0 print 'add meter table' ## action = [parser.OFPInstructionMeter(self.flow.get('meter_id'))] ## self.add_meter(datapath, 1, match, action)#TODO the action should be a meter TODO so we should add meter entry to meter table first ## print 'add meter' flowaction=[parser.OFPActionOutput(out_port)] meteraction=parser.OFPInstructionMeter(self.flow.get('meter_id')) self.add_flow_meter(datapath,priority,match,flowaction,meteraction)
def initialize_switch(self): flow_stat = ofctl.get_flow_stats(self.dp, self.waiters) for s in flow_stat[str(self.dp.id)]: self.logger.debug("deleting flow [cookie: %d]" % s['cookie']) cmd = self.dp.ofproto.OFPFC_DELETE ofctl.mod_flow_entry(self.dp, {'table_id': self.dp.ofproto.OFPTT_ALL}, cmd) group_stat = ofctl.get_group_desc(self.dp, self.waiters) for s in group_stat[str(self.dp.id)]: self.logger.debug("deleting group[id: %d] %s" % (s['group_id'], s)) cmd = self.dp.ofproto.OFPGC_DELETE ofctl.mod_group_entry(self.dp, { 'type': s['type'], 'group_id': s['group_id'] }, cmd) ofctl.mod_meter_entry(self.dp, {'meter_id': self.dp.ofproto.OFPM_ALL}, self.dp.ofproto.OFPMC_DELETE)
def meteradd(meter_conf): class NoopDP(object): id = 0 msg = None ofproto = ofp ofproto_parser = parser def send_msg(self, msg): self.msg = msg def set_xid(self, msg): msg.xid = 0 noop_dp = NoopDP() ofctl.mod_meter_entry(noop_dp, meter_conf, ofp.OFPMC_ADD) noop_dp.msg.xid = None noop_dp.msg.datapath = None return noop_dp.msg
def _setup_dp(): self.dp = ev.dp # delete all flows and groups at first self.logger.debug("initializing..") self.initialize_switch() # create flood to down group entry buckets = [] for vid in (i + 101 for i in range(3)): actions = [{ 'type': 'PUSH_VLAN', 'ethertype': ether.ETH_TYPE_8021Q }, { 'type': 'SET_FIELD', 'field': 'vlan_vid', 'value': vid | 0x1000 }, { 'type': 'OUTPUT', 'port': self.inter_port }] buckets.append({'actions': actions}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.access_port }]}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.wlc_port }]}) self.flood_group_ids = [] for i in range(len(buckets)): group_id = self._next_cookie() self.flood_group_ids.append(group_id) b = [] for j, e in enumerate(buckets): if j != i: b.append(e) ofctl.mod_group_entry(self.dp, { 'type': 'ALL', 'group_id': group_id, 'buckets': b }, self.dp.ofproto.OFPGC_ADD) buckets = [] buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.access_port }]}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.wlc_port }]}) group_id = self._next_cookie() self.flood_group_ids.append(group_id) ofctl.mod_group_entry(self.dp, { 'type': 'ALL', 'group_id': group_id, 'buckets': buckets }, self.dp.ofproto.OFPGC_ADD) # create 3 meter entry meter_id = self._next_cookie() self.low_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 50000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.mid_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 30000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.high_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 20000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) # default drop at table 0 cmd = self.dp.ofproto.OFPFC_ADD flow = { 'priority': 0, 'table_id': 0, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) # default flood up at table 1 cmd = self.dp.ofproto.OFPFC_ADD # match = {'in_port' : self.inter_port, 'metadata' : '101'} match = {'in_port': self.inter_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[5]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) ## match = {'in_port' : self.inter_port, 'metadata' : '102'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[1]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) # ## match = {'in_port' : self.inter_port, 'metadata' : '103'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[2]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.access_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[3]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.wlc_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[4]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) # packet-in when node is not familier at table 0 actions = [{ 'type': 'OUTPUT', 'port': self.dp.ofproto.OFPP_CONTROLLER }] # should be more tight? may occur many packet in match = {'in_port': self.inter_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.access_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.wlc_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd)
def _setup_dp(): self.dp = ev.dp # delete all flows and groups at first self.logger.debug("initializing..") self.initialize_switch() # create flood to down group entry buckets = [] for vid in (i+101 for i in range(3)): actions = [{'type':'PUSH_VLAN', 'ethertype':ether.ETH_TYPE_8021Q}, {'type':'SET_FIELD', 'field':'vlan_vid', 'value':vid | 0x1000}, {'type':'OUTPUT', 'port':self.inter_port}] buckets.append({'actions': actions}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.access_port}]}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.wlc_port}]}) self.flood_group_ids = [] for i in range(len(buckets)): group_id = self._next_cookie() self.flood_group_ids.append(group_id) b = [] for j, e in enumerate(buckets): if j != i: b.append(e) ofctl.mod_group_entry(self.dp, {'type':'ALL', 'group_id':group_id, 'buckets':b}, self.dp.ofproto.OFPGC_ADD) buckets = [] buckets.append({'actions':[{'type':'OUTPUT', 'port':self.access_port}]}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.wlc_port}]}) group_id = self._next_cookie() self.flood_group_ids.append(group_id) ofctl.mod_group_entry(self.dp, {'type':'ALL', 'group_id':group_id, 'buckets':buckets}, self.dp.ofproto.OFPGC_ADD) # create 3 meter entry meter_id = self._next_cookie() self.low_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 50000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.mid_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 30000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.high_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 20000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) # default drop at table 0 cmd = self.dp.ofproto.OFPFC_ADD flow = {'priority':0, 'table_id':0, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) # default flood up at table 1 cmd = self.dp.ofproto.OFPFC_ADD # match = {'in_port' : self.inter_port, 'metadata' : '101'} match = {'in_port' : self.inter_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[5]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) ## match = {'in_port' : self.inter_port, 'metadata' : '102'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[1]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) # ## match = {'in_port' : self.inter_port, 'metadata' : '103'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[2]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.access_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[3]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.wlc_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[4]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) # packet-in when node is not familier at table 0 actions = [{'type':'OUTPUT', 'port':self.dp.ofproto.OFPP_CONTROLLER}] # should be more tight? may occur many packet in match = {'in_port' : self.inter_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.access_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.wlc_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd)