示例#1
0
    def _switch_features_handler(self, ev):

        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        match = parser.OFPMatch()
        reg = oxm_fields.NiciraExtended1('reg0', 0, type_desc.Int4),
        actions_x = [
            parser.NXActionMultipath(
                fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4,
                basis=1024,
                algorithm=nicira_ext.NX_MP_ALG_HRW,
                max_link=1,
                arg=0,
                ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                dst="reg0")
        ]

        actions_x.append(
            parser.NXActionResubmitTable(in_port=8080, table_id=10))
        self.add_flow(datapath, 999, match, actions_x, table=0)

        actions = [
            parser.NXActionOutputReg(ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                                     src="reg0",
                                     max_len=2048)
        ]
        learn_action = parser.NXActionLearn(
            table_id=15,
            specs=[
                # Match
                parser.NXFlowSpecMatch(
                    src=('eth_type_nxm', 16),
                    dst=('eth_type', 0),
                    n_bits=16,
                ),
                parser.NXFlowSpecMatch(
                    src=("ip_proto_nxm", 8),
                    dst=('ip_proto', 0),
                    n_bits=8,
                ),

                # Actions
                parser.NXFlowSpecLoad(
                    src=('reg6', 0),
                    dst=('reg7', 0),
                    n_bits=32,
                ),
            ],
            fin_idle_timeout=1,
            fin_hard_timeout=1,
        )

        actions.append(learn_action)
        self.add_flow(datapath, 999, match, actions, table=10)
示例#2
0
 def natv6_flows(self, nfvip):
     nat_base = nfvip.network.network_address
     assert nfvip.network.prefixlen == 64, 'NFVIPS IPv4 all must be /64'
     # pylint: disable=no-member
     return self.apply_actions([
         # ipv6_src fc01::5 -> fc04::5:0:1, ipv6_dst fc01::1 -> fc04::1
         parser.NXActionRegLoad(value=(int(nat_base) & ((2**64) - 1)),
                                dst=self.AREG,
                                ofs_nbits=nicira_ext.ofs_nbits(0, 63)),
         parser.NXActionRegLoad(value=(int(nat_base) >> 64),
                                dst=self.AREG,
                                ofs_nbits=nicira_ext.ofs_nbits(64, 127)),
     ] + self.nat_actions(ether.ETH_TYPE_IPV6, nfvip, 32))
示例#3
0
 def _get_rewrite_ip_and_output_actions(self, ofproto, parser):
     """
     Retrieve the actions that rewrite the dst IP field with the reg6
     (the tunnel key), set the first bit of that field, and output to the
     metadata service OVS port.
     The IP is set to <reg6> | 0x8000000, so that the transparent proxy
     can extract the <reg6> from the source IP address, and be able to
     identify the source VM. reg6 holds the local DF id identifying the VM.
     """
     return [
         parser.NXActionRegMove(
             src_field='reg6',
             dst_field='ipv4_src',
             n_bits=32,
         ),
         parser.NXActionRegLoad(
             ofs_nbits=nicira_ext.ofs_nbits(31, 31),
             dst="ipv4_src",
             value=1,
         ),
         parser.OFPActionOutput(
             self._ofport,
             ofproto.OFPCML_NO_BUFFER,
         )
     ]
示例#4
0
 def _make_ingress_classification_flow(self, lport, port_num):
     match = self.parser.OFPMatch(in_port=port_num)
     network_id = lport.lswitch.unique_key
     LOG.debug(
         "match in_port=%(in_port)s for ingress classification "
         "of %(lport)s in network %(network)s", {
             'in_port': port_num,
             'lport': lport,
             'network': network_id
         })
     # Reset in_port to 0 to avoid drop by output command.
     actions = [
         self.parser.OFPActionSetField(reg6=lport.unique_key),
         self.parser.OFPActionSetField(metadata=network_id),
         self.parser.NXActionRegLoad(
             dst='in_port',
             value=0,
             ofs_nbits=nicira_ext.ofs_nbits(0, 31),
         ),
         self.parser.NXActionResubmit(),
     ]
     self.mod_flow(
         table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE,
         priority=const.PRIORITY_MEDIUM,
         match=match,
         actions=actions,
     )
示例#5
0
 def arp_reply_actions(self):
     # pylint: disable=no-member
     common_reply = self.common_reply_actions()
     return self.apply_actions([
         parser.NXActionRegLoad(value=arp.ARP_REPLY,
                                dst='arp_op',
                                ofs_nbits=nicira_ext.ofs_nbits(0, 2)),
         parser.NXActionRegMove(src_field='arp_sha',
                                dst_field='arp_tha',
                                n_bits=48,
                                src_ofs=0,
                                dst_ofs=0),
         parser.NXActionRegMove(src_field='arp_tpa',
                                dst_field=self.AREG,
                                n_bits=32,
                                src_ofs=0,
                                dst_ofs=0),
         parser.NXActionRegMove(src_field='arp_spa',
                                dst_field='arp_tpa',
                                n_bits=32,
                                src_ofs=0,
                                dst_ofs=0),
         parser.NXActionRegMove(src_field=self.AREG,
                                dst_field='arp_spa',
                                n_bits=32,
                                src_ofs=0,
                                dst_ofs=0),
         parser.OFPActionSetField(arp_sha=FAKECLIENTMAC),
     ] + common_reply)
示例#6
0
 def _get_instructions(self):
     ofproto = self.datapath.ofproto
     parser = self.datapath.ofproto_parser
     actions = [parser.OFPActionSetField(arp_op=arp.ARP_REPLY),
                parser.NXActionRegMove(src_field='arp_sha',
                                       dst_field='arp_tha',
                                       n_bits=48),
                parser.NXActionRegMove(src_field='arp_spa',
                                       dst_field='arp_tpa',
                                       n_bits=32),
                parser.OFPActionSetField(eth_src=self.mac_address),
                parser.OFPActionSetField(arp_sha=self.mac_address),
                parser.OFPActionSetField(arp_spa=self.interface_ip),
                parser.NXActionRegMove(src_field='reg6',
                                       dst_field='reg7',
                                       n_bits=32),
                parser.NXActionRegLoad(
                        dst='in_port',
                        ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                        value=0)]
     instructions = [
         parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions),
         parser.OFPInstructionGotoTable(const.INGRESS_DISPATCH_TABLE),
     ]
     return instructions
示例#7
0
    def _install_snat_egress_conntrack(self, match, ext_host_ip):
        """implements single sNAT pass for multiple tenant deployment

        :param match: - OVS match expression passed as a parameter
        :param ext_host_ip: - unique ip to translate tenant IPs to it
        :returns: None
        ----Translation logic follows next rules:----

        ipv4_src -> reg5  (temporary save internal tenant local IP)
        reg6 -> ipv4_src  (replace content of ipv4_src with host unique value)
        last_bit(1) -> ipv4_src  (turn unique value into legal IP address)
        reg6-> ct_mark (save unique value associated with port into
                                    OS  conn. track table)
        reg5 -> ct_label (save original tenant local IP for return flow)
        """
        parser = self.parser
        ofproto = self.ofproto

        actions = [
            parser.NXActionRegMove(src_field='ipv4_src',
                                   dst_field='reg5',
                                   n_bits=32),
            parser.NXActionRegMove(src_field='reg6',
                                   dst_field='ipv4_src',
                                   n_bits=32),
            parser.NXActionRegLoad(
                ofs_nbits=nicira_ext.ofs_nbits(31, 31),
                dst="ipv4_src",
                value=1,
            ),
            parser.NXActionCT(alg=0,
                              flags=const.CT_FLAG_COMMIT,
                              recirc_table=const.EGRESS_SNAT_TABLE,
                              zone_ofs_nbits=const.NAT_TRACKING_ZONE,
                              zone_src='',
                              actions=[
                                  parser.NXActionNAT(
                                      flags=const.CT_FLAG_COMMIT,
                                      range_ipv4_min=ext_host_ip,
                                      range_ipv4_max=ext_host_ip,
                                  ),
                                  parser.NXActionRegMove(dst_field='ct_mark',
                                                         src_field='reg6',
                                                         n_bits=32),
                                  parser.NXActionRegMove(dst_field='ct_label',
                                                         src_field='reg5',
                                                         n_bits=32),
                              ])
        ]

        action_inst = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                   actions)

        inst = [action_inst]

        self.mod_flow(inst=inst,
                      table_id=const.EGRESS_NAT_TABLE,
                      priority=const.PRIORITY_LOW,
                      match=match)
示例#8
0
 def natv4_flows(self, nfvip):
     nat_base = nfvip.network.network_address
     assert nfvip.network.prefixlen == 16, 'NFVIPS IPv4 all must be /16'
     # pylint: disable=no-member
     return self.apply_actions([
         # ipv4_src 192.168.2.5->10.10.5.1, ipv4_dst 192.168.2.1->10.10.0.1
         parser.NXActionRegLoad(value=int(nat_base), dst=self.AREG, ofs_nbits=nicira_ext.ofs_nbits(0, 31)),
     ] + self.nat_actions(ether.ETH_TYPE_IP, nfvip, 8))
示例#9
0
文件: conntrack.py 项目: sdechi/magma
    def _install_default_flows(self, datapath):
        parser = datapath.ofproto_parser

        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                           ct_state=(0x0, self.CT_TRK))
        actions = [
            parser.NXActionCT(flags=0x0,
                              zone_src=None,
                              zone_ofs_nbits=ofs_nbits(14, 15),
                              recirc_table=self.conntrack_scratch,
                              alg=0,
                              actions=[])
        ]
        flows.add_resubmit_next_service_flow(datapath,
                                             self.tbl_num,
                                             match,
                                             actions,
                                             priority=flows.DEFAULT_PRIORITY,
                                             resubmit_table=self.next_table)

        # Match all new connections on scratch table
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                           ct_zone=ofs_nbits(14, 15),
                           ct_state=(self.CT_NEW | self.CT_TRK,
                                     self.CT_NEW | self.CT_TRK))
        actions = [
            parser.NXActionCT(flags=0x1,
                              zone_src=None,
                              zone_ofs_nbits=ofs_nbits(14, 15),
                              recirc_table=self.connection_event_table,
                              alg=0,
                              actions=[])
        ]
        flows.add_drop_flow(datapath,
                            self.conntrack_scratch,
                            match,
                            actions,
                            priority=flows.DEFAULT_PRIORITY)

        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP)
        flows.add_resubmit_next_service_flow(datapath,
                                             self.tbl_num,
                                             match, [],
                                             priority=flows.MINIMUM_PRIORITY,
                                             resubmit_table=self.next_table)
示例#10
0
    def ct(cls, ofproto, action_str):
        str_to_port = {'ftp': 21, 'tftp': 69}
        flags = 0
        zone_src = ""
        zone_ofs_nbits = 0
        recirc_table = nicira_ext.NX_CT_RECIRC_NONE
        alg = 0
        ct_actions = []

        if len(action_str) > 2:
            if (not action_str.startswith('ct(') or action_str[-1] != ')'):
                raise ryu.exception.OFPInvalidActionString(
                    action_str=action_str)
            rest = tokenize_ofp_instruction_arg(action_str[len('ct('):-1])
        else:
            rest = []
        for arg in rest:
            if arg == 'commit':
                flags |= nicira_ext.NX_CT_F_COMMIT
                rest = rest[len('commit'):]
            elif arg == 'force':
                flags |= nicira_ext.NX_CT_F_FORCE
            elif arg.startswith('exec('):
                ct_actions = ofp_instruction_from_str(ofproto,
                                                      arg[len('exec('):-1])
            else:
                try:
                    k, v = arg.split('=', 1)
                    if k == 'table':
                        recirc_table = str_to_int(v)
                    elif k == 'zone':
                        m = re.search('\[(\d*)\.\.(\d*)\]', v)
                        if m:
                            zone_ofs_nbits = nicira_ext.ofs_nbits(
                                int(m.group(1)), int(m.group(2)))
                            zone_src = nxm_field_name_to_ryu(v[:m.start(0)])
                        else:
                            zone_ofs_nbits = str_to_int(v)
                    elif k == 'alg':
                        alg = str_to_port[arg[len('alg='):]]
                except Exception:
                    raise ryu.exception.OFPInvalidActionString(
                        action_str=action_str)
        return dict(
            NXActionCT={
                'flags': flags,
                'zone_src': zone_src,
                'zone_ofs_nbits': zone_ofs_nbits,
                'recirc_table': recirc_table,
                'alg': alg,
                'actions': ct_actions
            })
示例#11
0
    def ct(cls, ofproto, action_str):
        str_to_port = {'ftp': 21, 'tftp': 69}
        flags = 0
        zone_src = ""
        zone_ofs_nbits = 0
        recirc_table = nicira_ext.NX_CT_RECIRC_NONE
        alg = 0
        ct_actions = []

        if len(action_str) > 2:
            if (not action_str.startswith('ct(') or
                    action_str[-1] != ')'):
                raise ryu.exception.OFPInvalidActionString(
                    action_str=action_str)
            rest = tokenize_ofp_instruction_arg(action_str[len('ct('):-1])
        else:
            rest = []
        for arg in rest:
            if arg == 'commit':
                flags |= nicira_ext.NX_CT_F_COMMIT
                rest = rest[len('commit'):]
            elif arg == 'force':
                flags |= nicira_ext.NX_CT_F_FORCE
            elif arg.startswith('exec('):
                ct_actions = ofp_instruction_from_str(
                    ofproto, arg[len('exec('):-1])
            else:
                try:
                    k, v = arg.split('=', 1)
                    if k == 'table':
                        recirc_table = str_to_int(v)
                    elif k == 'zone':
                        m = re.search('\[(\d*)\.\.(\d*)\]', v)
                        if m:
                            zone_ofs_nbits = nicira_ext.ofs_nbits(
                                int(m.group(1)), int(m.group(2)))
                            zone_src = nxm_field_name_to_ryu(
                                v[:m.start(0)])
                        else:
                            zone_ofs_nbits = str_to_int(v)
                    elif k == 'alg':
                        alg = str_to_port[arg[len('alg='):]]
                except Exception:
                    raise ryu.exception.OFPInvalidActionString(
                        action_str=action_str)
        return dict(NXActionCT={'flags': flags,
                                'zone_src': zone_src,
                                'zone_ofs_nbits': zone_ofs_nbits,
                                'recirc_table': recirc_table,
                                'alg': alg,
                                'actions': ct_actions})
示例#12
0
    def _install_snat_ingress_after_conntrack(self,
                                              unique_key,
                                              vm_mac,
                                              external_host_mac):
        """complements reverse sNAT translation from unique IP to tenant IP

        :param unique_key: - key to match with
        :param vm_mac: - original VM mac address to restore
        :returns: None

        ---Translation complement follows next rules:---
        unique_key -> reg7 ( load unique port key into dedicated register)
        ct_label -> ipv4_src (restore original local tenant IP)
        change src/dst mac addresses to push packet further to destination
        """
        parser = self.parser
        ofproto = self.ofproto
        match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP,
                                ct_mark=int(unique_key))

        actions = [
            parser.OFPActionSetField(eth_src=external_host_mac),
            parser.OFPActionSetField(eth_dst=vm_mac),
            parser.NXActionRegLoad(
                            ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                            dst='reg7',
                            value=unique_key),
            parser.NXActionRegMove(
                            src_field='ct_label',
                            dst_field='ipv4_dst',
                            n_bits=32)
                   ]
        action_inst = parser.OFPInstructionActions(
            ofproto.OFPIT_APPLY_ACTIONS, actions)
        goto_inst = parser.OFPInstructionGotoTable(
            const.INGRESS_DISPATCH_TABLE)
        inst = [action_inst, goto_inst]

        self.mod_flow(
            inst=inst,
            table_id=const.INGRESS_SNAT_TABLE,
            priority=const.PRIORITY_LOW,
            match=match)

        actions = [self.parser.OFPActionOutput(
                self.external_ofport, self.ofproto.OFPCML_NO_BUFFER)]
        self.mod_flow(
            actions=actions,
            table_id=const.INGRESS_DISPATCH_TABLE,
            priority=const.PRIORITY_DEFAULT)
示例#13
0
    def _install_ingress_goto_rules(self):
        parser = self.parser
        match = parser.OFPMatch(in_port=self.external_ofport)
        actions = [parser.NXActionRegLoad(
                dst='in_port',
                value=0,
                ofs_nbits=nicira_ext.ofs_nbits(0, 31))]

        inst = [parser.OFPInstructionActions(
                    self.datapath.ofproto.OFPIT_APPLY_ACTIONS, actions),
                parser.OFPInstructionGotoTable(const.INGRESS_NAT_TABLE)]
        self.mod_flow(inst=inst,
                      table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE,
                      priority=const.PRIORITY_DEFAULT,
                      match=match)
示例#14
0
文件: fc.py 项目: snapiri/dragonflow
    def _install_dispatch_flows(self, flow_classifier):
        lport = self._get_flow_classifier_lport(flow_classifier)
        # End-of-chain
        # 1) Restore network ID in metadata and zero reg6 + reg2
        # 2) Restore port ID in reg7 in dest port
        # 3) Resubmit to the next table
        lswitch = lport.lswitch

        actions = [
            self.parser.OFPActionSetField(metadata=lswitch.unique_key),
            self.parser.OFPActionSetField(reg6=0),
            self.parser.OFPActionSetField(reg2=0),
        ]

        if flow_classifier.source_port == lport:
            done_bit = _SRC_BIT
        elif flow_classifier.dest_port == lport:
            done_bit = _DST_BIT

            # FIXME (dimak) maybe get it from L2 table
            actions.append(
                self.parser.OFPActionSetField(reg7=lport.unique_key))

        actions += [
            self.parser.NXActionRegLoad(
                dst='reg3',
                value=1,
                ofs_nbits=nicira_ext.ofs_nbits(done_bit, done_bit),
            ),
            self.parser.NXActionResubmitTable(
                table_id=self._get_flow_classifier_table(flow_classifier))
        ]

        self.mod_flow(
            table_id=constants.SFC_END_OF_CHAIN_TABLE,
            priority=constants.PRIORITY_MEDIUM,
            match=self.parser.OFPMatch(reg2=flow_classifier.unique_key),
            actions=actions,
        )
示例#15
0
    def add_arp_flow(self):
        #     need to get iface number from ovs
        ofproto = self.datapath.ofproto
        match = self.parser.OFPMatch(in_port=self.mpls_port_id)
        match.set_dl_type(ether.ETH_TYPE_ARP)
        match.set_arp_tpa(utils.ipv4_text_to_int(self.interface_ip))
        match.set_arp_opcode(arp.ARP_REQUEST)

        actions = [
            self.parser.OFPActionSetField(arp_op=arp.ARP_REPLY),
            self.parser.NXActionRegMove(src_field='arp_sha',
                                        dst_field='arp_tha',
                                        n_bits=48),
            self.parser.NXActionRegMove(src_field='arp_sha',
                                        dst_field='eth_dst',
                                        n_bits=48),
            self.parser.NXActionRegMove(src_field='arp_spa',
                                        dst_field='arp_tpa',
                                        n_bits=32),
            self.parser.OFPActionSetField(eth_src=self.mac_address),
            self.parser.OFPActionSetField(arp_sha=self.mac_address),
            self.parser.OFPActionSetField(arp_spa=self.interface_ip),
            self.parser.NXActionRegLoad(dst='in_port',
                                        ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                                        value=0),
            self.parser.OFPActionOutput(self.mpls_port_id,
                                        ofproto.OFPCML_NO_BUFFER)
        ]

        inst = [
            self.parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                              actions)
        ]
        self.mod_flow(
            inst=inst,
            match=match,
            table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE,
        )
示例#16
0
    def _match_actions_by_network_type(self, lport, network_id, network_type):
        actions = [
            self.parser.NXActionRegLoad(
                dst='in_port',
                value=0,
                ofs_nbits=nicira_ext.ofs_nbits(0, 31),
            ),
            self.parser.OFPActionSetField(metadata=network_id),
        ]

        if network_type == NET_VLAN:
            vlan_vid = self.ofproto.OFPVID_PRESENT
            vlan_vid |= lport.lswitch.segmentation_id
            actions.append(self.parser.OFPActionPopVlan())
        elif network_type == NET_FLAT:
            vlan_vid = 0

        match = self.parser.OFPMatch(
            in_port=self.int_ofports[lport.lswitch.physical_network],
            vlan_vid=vlan_vid,
        )

        return match, actions
示例#17
0
 def _install_ingress_nat_rules(self, floatingip):
     network_id = floatingip.floating_lport.lswitch.unique_key
     # TODO(Fei Rao) check the network type
     if self._is_first_external_network(network_id):
         # if it is the first floating ip on this node, then
         # install the common goto flow rule.
         parser = self.parser
         self.mod_flow(
             table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE,
             priority=const.PRIORITY_DEFAULT,
             match=parser.OFPMatch(in_port=self.external_ofport),
             inst=[
                 parser.OFPInstructionActions(
                     self.ofproto.OFPIT_APPLY_ACTIONS,
                     [
                         parser.NXActionRegLoad(
                             dst='in_port',
                             value=0,
                             ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                         ),
                     ],
                 ),
                 parser.OFPInstructionGotoTable(const.INGRESS_NAT_TABLE),
             ],
         )
         # Take over reg7 == 0 for the external_ofport
         match = parser.OFPMatch(reg7=0)
         actions = [self.parser.OFPActionOutput(
                 self.external_ofport, self.ofproto.OFPCML_NO_BUFFER)]
         self.mod_flow(
             actions=actions,
             table_id=const.INGRESS_DISPATCH_TABLE,
             priority=const.PRIORITY_MEDIUM,
             match=match)
     self._install_floatingip_arp_responder(floatingip)
     self._install_dnat_ingress_rules(floatingip)
     self._increase_external_network_count(network_id)
示例#18
0
    def config_switch(self, parser):
        mod_flow = self.parent.mod_flow
        ul_port = self.parent.ul_port
        dl_port = self.parent.dl_port
        flag_commit = 1
        flag_snat = 1
        flag_dnat = 2
        ct_state_minus_trk = (0, 32)
        ct_state_plus_trk = (32, 32)

        # dl -> ul (priv -> pubilc, orig -> translated)
        #
        # ip,in_port="ul_port" actions=ct(commit,zone=1,nat(dst=dst)),output:"dl_port"
        match = {'in_port': dl_port, 'eth_type': 0x0800}
        actions = [
            action_ct(
                parser, {
                    'flags':
                    flag_commit,
                    'zone_ofs_nbits':
                    nicira_ext.ofs_nbits(0, 1),
                    'actions': [
                        action_nat(
                            parser, {
                                'flags': flag_dnat,
                                'range_ipv4_min': self.conf.range_ipv4_min,
                                'range_ipv4_max': self.conf.range_ipv4_max,
                                'range_proto_min': self.conf.range_port_min,
                                'range_proto_max': self.conf.range_port_max,
                            })
                    ]
                }),
            parser.OFPActionSetField(eth_dst=self.conf.uplink_dst_mac),
        ]
        mod_flow(match=match, actions=actions, output=ul_port)

        # ul -> dl (pubilc -> priv, translated -> orig)
        #
        # ct_state=-trk,ip,in_port="dl_port" actions=ct(table=0,zone=1,nat)
        match = {
            'in_port': ul_port,
            'eth_type': 0x0800,
            'ct_state': ct_state_minus_trk,
        }
        actions = [
            action_ct(
                parser, {
                    'flags': 0,
                    'zone_ofs_nbits': nicira_ext.ofs_nbits(0, 1),
                    'recirc_table': 0,
                    'actions': [action_nat(parser, {'flags': 0})],
                }),
            parser.OFPActionSetField(eth_dst=self.conf.downlink_dst_mac),
        ]
        mod_flow(match=match, actions=actions, output=dl_port)

        # ct_state=+trk,ct_zone=1,in_port="dl_port" actions=output:"ul_port"
        match = {
            'in_port': ul_port,
            'eth_type': 0x0800,
            'ct_state': ct_state_plus_trk,
            'ct_zone': 1,
        }
        actions = [
            parser.OFPActionSetField(eth_dst=self.conf.downlink_dst_mac),
        ]
        mod_flow(match=match, actions=actions, output=dl_port)
示例#19
0
 def nat_actions(self, eth_type, nfvip, nat_offset):
     ip_ver = nfvip.ip.version
     ip_src_nxm = 'ipv%u_src_nxm' % ip_ver
     ip_dst_nxm = 'ipv%u_dst_nxm' % ip_ver
     ipbits = nfvip.ip.max_prefixlen
     # pylint: disable=no-member
     return [
         parser.NXActionRegMove(src_field='ipv%u_src' % ip_ver, dst_field=self.AREG, n_bits=nat_offset, src_ofs=0, dst_ofs=nat_offset),
         parser.NXActionRegMove(src_field='ipv%u_dst' % ip_ver, dst_field=self.AREG, n_bits=nat_offset, src_ofs=0, dst_ofs=0),
         # we have to load output port numbers into reg1 and reg2 because NXFlowSpecOutput() won't take a literal.
         parser.NXActionRegLoad(value=self.FAKEPORT, dst=self.FAKEPORTREG, ofs_nbits=nicira_ext.ofs_nbits(0, 15)),
         parser.NXActionRegLoad(value=self.COPROPORT, dst=self.COPROPORTREG, ofs_nbits=nicira_ext.ofs_nbits(0, 15)),
         # now program an inbound flow to perform NAT.
         parser.NXActionLearn(
             table_id=self.FROM_COPRO_TABLE,
             priority=2,
             hard_timeout=self.IDLE,
             specs=[
                 parser.NXFlowSpecMatch(src=eth_type, dst=('eth_type_nxm', 0), n_bits=16),
                 parser.NXFlowSpecMatch(src=(ip_src_nxm, 0), dst=(ip_src_nxm, 0), n_bits=ipbits),
                 parser.NXFlowSpecMatch(src=(ip_dst_nxm, 0), dst=(ip_dst_nxm, 0), n_bits=ipbits),
                 parser.NXFlowSpecLoad(src=int(self.FAKECLIENTMAC), dst=('eth_src_nxm', 0), n_bits=48),
                 parser.NXFlowSpecLoad(src=int(self.FAKESERVERMAC), dst=('eth_dst_nxm', 0), n_bits=48),
             ] + self.reg_copy(self.AREG, ip_src_nxm, ipbits) + [
                 parser.NXFlowSpecLoad(src=int(nfvip.ip), dst=(ip_dst_nxm, 0), n_bits=ipbits),
                 parser.NXFlowSpecOutput(src=(self.FAKEPORTREG, 0), dst='', n_bits=16),
             ]),
         # now program outbound an outbound flow.
         parser.NXActionLearn(
             table_id=self.TO_COPRO_TABLE,
             priority=2,
             idle_timeout=self.IDLE,
             specs=[
                 parser.NXFlowSpecMatch(src=eth_type, dst=('eth_type_nxm', 0), n_bits=16),
                 parser.NXFlowSpecMatch(src=int(nfvip.ip), dst=(ip_src_nxm, 0), n_bits=ipbits),
             ] + self.reg_copy(self.AREG, ip_dst_nxm, ipbits) + [
                 parser.NXFlowSpecLoad(src=('eth_dst_nxm', 0), dst=('eth_src_nxm', 0), n_bits=48),
                 parser.NXFlowSpecLoad(src=('eth_src_nxm', 0), dst=('eth_dst_nxm', 0), n_bits=48),
                 parser.NXFlowSpecLoad(src=(ip_dst_nxm, 0), dst=(ip_src_nxm, 0), n_bits=ipbits),
                 parser.NXFlowSpecLoad(src=(ip_src_nxm, 0), dst=(ip_dst_nxm, 0), n_bits=ipbits),
                 parser.NXFlowSpecOutput(src=(self.COPROPORTREG, 0), dst='', n_bits=16),
             ]),
         # now that future flows are programmed, handle the packet we have.
         parser.OFPActionSetField(eth_src=self.FAKECLIENTMAC),
         parser.OFPActionSetField(eth_dst=self.FAKESERVERMAC),
         parser.NXActionRegMove(src_field=self.AREG, dst_field=('ipv%u_src' % ip_ver), n_bits=ipbits, src_ofs=0, dst_ofs=0),
         parser.OFPActionSetField(**{'ipv%u_dst' % ip_ver: str(nfvip.ip)}),
         parser.OFPActionOutput(self.FAKEPORT)
     ]
示例#20
0
 def _add_tap_metadata_port(self, ofport, mac):
     """
     Add the flows that can be added with the current available information:
     Regular Client->Server packets have IP rewritten, and sent to OVS port
     TCP Syn packets are sent to controller, so that response flows can be
         added.
     Packets from the OVS port are detected and sent for classification.
     """
     self._ofport = ofport
     datapath = self.get_datapath()
     ofproto = datapath.ofproto
     parser = datapath.ofproto_parser
     self._add_incoming_flows()
     # Regular packet
     match = parser.OFPMatch(eth_type=ethernet.ether.ETH_TYPE_IP)
     actions = self._get_rewrite_ip_and_output_actions(ofproto, parser)
     inst = [
         parser.OFPInstructionActions(
             ofproto.OFPIT_APPLY_ACTIONS,
             actions,
         )
     ]
     self.mod_flow(
         datapath=datapath,
         table_id=const.METADATA_SERVICE_TABLE,
         command=ofproto.OFPFC_ADD,
         priority=const.PRIORITY_MEDIUM,
         match=match,
         inst=inst,
     )
     # TCP SYN packet
     match = parser.OFPMatch(
         eth_type=ethernet.ether.ETH_TYPE_IP,
         ip_proto=ipv4.inet.IPPROTO_TCP,
         tcp_flags=(TCP_SYN, TCP_SYN | TCP_ACK),
     )
     learn_actions = self._get_learn_actions(ofproto, parser)
     learn_actions.extend(actions)
     inst = [
         parser.OFPInstructionActions(
             ofproto.OFPIT_APPLY_ACTIONS,
             learn_actions,
         )
     ]
     self.mod_flow(
         datapath=datapath,
         table_id=const.METADATA_SERVICE_TABLE,
         command=ofproto.OFPFC_ADD,
         priority=const.PRIORITY_HIGH,
         match=match,
         inst=inst,
     )
     # Response packet
     actions = [
         parser.NXActionRegLoad(ofs_nbits=nicira_ext.ofs_nbits(0, 31),
                                dst="in_port",
                                value=0),
     ]
     inst = [
         parser.OFPInstructionActions(
             ofproto.OFPIT_APPLY_ACTIONS,
             actions,
         ),
         parser.OFPInstructionGotoTable(const.METADATA_SERVICE_REPLY_TABLE),
     ]
     self.mod_flow(
         datapath=datapath,
         table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE,
         command=ofproto.OFPFC_ADD,
         priority=const.PRIORITY_MEDIUM,
         match=parser.OFPMatch(in_port=ofport),
         inst=inst,
     )
     self._create_arp_responder(mac)
示例#21
0
def get_add_output_flow_msg(datapath,
                            table,
                            match,
                            actions=None,
                            instructions=None,
                            priority=MINIMUM_PRIORITY,
                            cookie=0x0,
                            idle_timeout=0,
                            hard_timeout=0,
                            output_port=None,
                            output_reg=None,
                            copy_table=None,
                            max_len=None):
    """
    Add a flow to a table that sends the packet to the specified port

    Args:
        datapath (ryu.controller.controller.Datapath):
            Datapath to push the flow to
        table (int): Table number to apply the flow to
        match (MagmaMatch): The match for the flow
        actions ([OFPAction]):
            List of actions for the flow.
        instructions ([OFPInstruction]):
            List of instructions for the flow. This will default to a
            single OFPInstructionsActions to apply `actions`.
            Ignored if `actions` is set.
        priority (int): Flow priority
        cookie (hex): cookie value for the flow
        idle_timeout (int): idle timeout for the flow
        hard_timeout (int): hard timeout for the flow
        output_port (int): the port to send the packet
        copy_table (int): optional table to send the packet to
        max_len (int): Max length to send to controller

    Raises:
        MagmaOFError: if the flow can't be added
        Exception: If the actions contain NXActionResubmitTable.
    """

    ofproto, parser = datapath.ofproto, datapath.ofproto_parser
    _check_resubmit_action(actions, parser)

    if actions is None:
        actions = []

    if output_reg is not None:
        output_action = parser.NXActionOutputReg2(ofs_nbits=ofs_nbits(0, 31),
                                                  src=output_reg,
                                                  max_len=1234)
    else:
        if max_len is None:
            output_action = parser.OFPActionOutput(output_port)
        else:
            output_action = parser.OFPActionOutput(output_port, max_len)

    actions = actions + [
        output_action,
    ]
    if copy_table:
        actions.append(parser.NXActionResubmitTable(table_id=copy_table))
    inst = __get_instructions_for_actions(ofproto, parser, actions,
                                          instructions)
    ryu_match = parser.OFPMatch(**match.ryu_match)

    return parser.OFPFlowMod(datapath=datapath,
                             priority=priority,
                             match=ryu_match,
                             instructions=inst,
                             table_id=table,
                             cookie=cookie,
                             idle_timeout=idle_timeout,
                             hard_timeout=hard_timeout)