Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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)