def add_qos_rule_flow(self, datapath, dst_ip, dst_port, meter_id, buffer_id=None): dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch() # only match by dst. info. match.set_ipv4_dst(ipv4_text_to_int(dst_ip.encode('utf8'))) match.set_udp_dst(int(dst_port)) match.set_dl_type(0x800) # prereq of ipv4 match.set_ip_proto(0x11) # prereq of udp # SimpleSwitch13 forwarding logic if self.ip_to_mac.get(dst_ip, None) in self.mac_to_port.get(dpid, {}): print "\033[1;34;49mAdd QoS flow: dst_ip {}, dst_port {} => Meter {}\033[0;37;49m".format(dst_ip, dst_port, meter_id) out_port = self.mac_to_port[dpid][self.ip_to_mac[dst_ip]] else: return # Go meter before apply actions actions = [parser.OFPActionOutput(out_port)] inst = [parser.OFPInstructionMeter(int(meter_id), ofproto.OFPIT_METER), parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] if buffer_id: mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=FLOW_PRIORITY, match=match, instructions=inst) else: mod = parser.OFPFlowMod(datapath=datapath, priority=FLOW_PRIORITY, match=match, instructions=inst) datapath.send_msg(mod)
def add_qos_rule_flow(self, datapath, dst_ip, meter_id, buffer_id=None): dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch() match.set_ipv4_dst(ipv4_text_to_int(dst_ip.encode('utf8'))) match.set_dl_type(0x800) if self.ip_to_mac.get(dst_ip, None) in self.mac_to_port.get(dpid, {}): print("Add QoS flow: dst_ip {}, dst_port {} => Meter {}".format( dst_ip, dst_port, meter_id)) out_port = self.mac_to_port[dpid][self.ip_to_mac[dst_ip]] else: return # Go meter before apply actions actions = [parser.OFPActionOutput(out_port)] inst = [ parser.OFPInstructionMeter(int(meter_id), ofproto.OFPIT_METER), parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] if buffer_id: mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=FLOW_PRIORITY, match=match, instructions=inst) else: mod = parser.OFPFlowMod(datapath=datapath, priority=FLOW_PRIORITY, match=match, instructions=inst) datapath.send_msg(mod)
def _add_flows_for_vnid(self, tenant_id, vnid, port): dp = self.net_switch_app.switch['datapath'] ofproto = dp.ofproto tunnel_port = self.net_switch_app.tunnel_port parser = dp.ofproto_parser # Outbound flow actions = [] rule = nx_match.ClsRule() # hardware command = ovs_vsctl.VSCtlCommand('get', ('Interface', port, 'ofport')) self.net_switch_app.vsctl.run_command([command]) assert len(command.result) == 1 ofport = command.result[0][0] rule.set_in_port(ofport) logging.debug("Set outbound flow for vnid %s(%s):", vnid, self._vnid_uuid_to_vnid(vnid)) for site in tenants_site_tables[tenant_id]: if site['name'] != self.my_site: remote_vnid = self._get_sites_vnid(site['name'], tenant_id, vnid) remote_ip = str(site['site_proxy'][0]['ip']) # set tunnel key SET_TUNNEL actions.append( dp.ofproto_parser.NXActionSetTunnel( self._vnid_uuid_to_vnid(remote_vnid))) # set tunnel dst pIP REG_LOAD actions.append( dp.ofproto_parser.NXActionRegLoad( 0x1f, # ofs_nbits (ofs < 6 | nbits - 1) 0x014004, # dst ipv4_text_to_int(remote_ip))) # forward OUTPUT(PROXY) actions.append( dp.ofproto_parser.OFPActionOutput(tunnel_port.port_no)) logging.debug( '--------ACTION: vnid:%s(%s)=>site %s:vnid:%s(%s) via tunnel %s', vnid, self._vnid_uuid_to_vnid(vnid), site['name'], remote_vnid, self._vnid_uuid_to_vnid(remote_vnid), site['site_proxy'][0]['ip']) res = dp.send_flow_mod(rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, actions=actions) # Inbound flow actions = [] rule = nx_match.ClsRule() rule.set_in_port(tunnel_port.port_no) rule.set_tun_id(self._vnid_uuid_to_vnid(vnid)) # forward OUTPUT to local SDN controller vnid port actions.append(dp.ofproto_parser.OFPActionOutput(ofport)) logging.debug('Set inbound flow for %s(%s)=> local SDN port:%s', vnid, self._vnid_uuid_to_vnid(vnid), ofport) res = dp.send_flow_mod(rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, actions=actions)
def location_request(self, req, tenant_id, **kwargs): msg = json.loads(req.body) validate(msg, location_request_schema) logging.debug('Enter location_request with %s', msg) # send location request to controller reply = self.net_switch_app.send_request( EventLocationReq(msg['vnid'], str(msg['vip']))) # XXX return error code if reply.vIP == "0.0.0.0": return Response(content_type='application/json', status=500) # set incoming flow in the datapath dp = self.net_switch_app.switch['datapath'] tunnel_port = self.net_switch_app.tunnel_port rule = nx_match.ClsRule() actions = [] ofproto = dp.ofproto # hardware rule.set_in_port(tunnel_port.port_no) rule.set_dl_type(0x0800) # ip rule.set_nw_dst(ipv4_text_to_int(str(msg['vip']))) #rule.set_nw_proto(packet[1].proto) #rule.set_nw_proto(4) # "ip" # encap rule.set_tun_id(msg['vnid']) # set tunnel key SET_TUNNEL actions.append(dp.ofproto_parser.NXActionSetTunnel(msg['vnid'])) # set tunnel dst pIP REG_LOAD actions.append( dp.ofproto_parser.NXActionRegLoad( 0x1f, # ofs_nbits (ofs < 6 | nbits - 1) 0x014004, # dst ipv4_text_to_int(reply.pIP))) # forward OUTPUT(PROXY) actions.append(dp.ofproto_parser.OFPActionOutput(ofproto.OFPP_IN_PORT)) logging.debug('Installing incoming flow for %d:%s=>%s', msg['vnid'], msg['vip'], reply.pIP) dp.send_flow_mod(rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, actions=actions) # Send reply to peer FA net_list = tenants_net_tables[tenant_id]['table'][msg['vnid']] vnid = "" for net in net_list: if net['tenant_id'] == msg['src_tenant_id']: vnid = net['vnid'] if not vnid: raise RyuException("Can not find peer network") body = { "vnid": vnid, "vip": msg['vip'], "vmac": reply.vMAC, "tenant_id": msg['src_tenant_id'], "pip": { "ip": self.net_switch_app.switch['datapath'].address[0] } } body = json.dumps(body) return Response(content_type='application/json', body=body)
def _send_location_req(self, tenant_id, vnid, vip, net): logging.debug('Send location-req %d:%d %s to %s', tenant_id, vnid, vip, net['site_name']) fa_url = self._find_url(tenant_id, net['site_name']) auth = HTTPBasicAuth('admin', 'admin') headers = { 'content-type': 'application/json', 'Accept': 'application/json', 'charsets': 'utf-8' } r = requests.post('http://' + fa_url + url_tenants + '/' + str(net['tenant_id']) + '/location-req', headers=headers, auth=auth, data=json.dumps({ "src_tenant_id": tenant_id, "dst_tenant_id": net['tenant_id'], "vnid": net['vnid'], "vip": vip })) if int(r.status_code) == 200: reply = r.json() validate(reply, location_reply_schema) pip = self.switch['datapath'].address[0] dp = self.switch['datapath'] # send to SDN controller location update self.send_event( 'FaSdnController', EventLocUpdateReq(pip, reply['vnid'], str(reply['vip']), str(reply['vmac']))) # Set outgoing flow in the datapath dp = self.switch['datapath'] ofproto = dp.ofproto tunnel_port = self.tunnel_port parser = dp.ofproto_parser actions = [] rule = nx_match.ClsRule() # hardware rule.set_in_port(tunnel_port.port_no) rule.set_dl_type(0x0800) # ip rule.set_nw_dst(ipv4_text_to_int(vip)) #rule.set_nw_proto(packet[1].proto) #rule.set_nw_proto(4) # "ip" # encap rule.set_tun_id( vnid ) # We assume NET sends the source VNID in the VXLAN header for now # set tunnel key SET_TUNNEL actions.append(dp.ofproto_parser.NXActionSetTunnel(net['vnid'])) # set tunnel dst pIP REG_LOAD actions.append( dp.ofproto_parser.NXActionRegLoad( 0x1f, # ofs_nbits (ofs < 6 | nbits - 1) 0x014004, # dst ipv4_text_to_int(str(reply['pip']['ip'])))) # forward OUTPUT(PROXY) actions.append( dp.ofproto_parser.OFPActionOutput(ofproto.OFPP_IN_PORT)) logging.debug('Set outgoing flow for %d:%s=>%s', net['vnid'], vip, reply['pip']['ip']) dp.send_flow_mod(rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, actions=actions)