Exemplo n.º 1
0
def build_output_actions(acl_table, output_dict):
    """Implement actions to alter packet/output."""
    output_actions = []
    output_port = None
    ofmsgs = []
    # rewrite any VLAN headers first always
    vlan_actions = rewrite_vlan(acl_table, output_dict)
    if vlan_actions:
        output_actions.extend(vlan_actions)
    if 'set_fields' in output_dict:
        for set_field in output_dict['set_fields']:
            output_actions.append(acl_table.set_field(**set_field))
    if 'port' in output_dict:
        output_port = output_dict['port']
        output_actions.append(valve_of.output_port(output_port))
    if 'ports' in output_dict:
        for output_port in output_dict['ports']:
            output_actions.append(valve_of.output_port(output_port))
    if 'failover' in output_dict:
        failover = output_dict['failover']
        group_id = failover['group_id']
        buckets = []
        for port in failover['ports']:
            buckets.append(
                valve_of.bucket(watch_port=port,
                                actions=[valve_of.output_port(port)]))
        ofmsgs.append(valve_of.groupdel(group_id=group_id))
        ofmsgs.append(valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
        output_actions.append(valve_of.group_act(group_id=group_id))
    return (output_port, output_actions, ofmsgs)
Exemplo n.º 2
0
def build_output_actions(output_dict):
    """Implement actions to alter packet/output."""
    output_actions = []
    output_port = None
    ofmsgs = []
    # if destination rewriting selected, rewrite it.
    if 'dl_dst' in output_dict:
        output_actions.append(valve_of.set_eth_dst(output_dict['dl_dst']))
    # rewrite any VLAN headers.
    vlan_actions = rewrite_vlan(output_dict)
    if vlan_actions:
        output_actions.extend(vlan_actions)
    if 'port' in output_dict:
        output_port = output_dict['port']
        output_actions.append(valve_of.output_port(output_port))
    if 'failover' in output_dict:
        failover = output_dict['failover']
        group_id = failover['group_id']
        buckets = []
        for port in failover['ports']:
            buckets.append(
                valve_of.bucket(watch_port=port,
                                actions=[valve_of.output_port(port)]))
        ofmsgs.append(valve_of.groupdel(group_id=group_id))
        ofmsgs.append(valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
        output_actions.append(valve_of.group_act(group_id=group_id))
    return (output_port, output_actions, ofmsgs)
Exemplo n.º 3
0
    def get_port_acls(self, valve, dot1x_port):
        """Setup the dot1x forward port acls.
        Args:
            dot1x_port:
            valve:

        Returns:
            list of flowmods
        """
        port_acl_table = valve.dp.tables['port_acl']
        nfv_sw_port = valve.dp.dot1x['nfv_sw_port']
        valve_index = self.dp_id_to_valve_index[valve.dp.dp_id]
        mac = get_mac_str(valve_index, dot1x_port.number)
        ofmsgs = []
        ofmsgs.append(port_acl_table.flowmod(
            port_acl_table.match(
                in_port=dot1x_port.number,
                eth_type=valve_packet.ETH_EAPOL),
            priority=valve.dp.highest_priority,
            inst=[valve_of.apply_actions([
                valve_of.set_field(eth_dst=mac),
                valve_of.output_port(nfv_sw_port)])]))
        ofmsgs.append(port_acl_table.flowmod(
            port_acl_table.match(
                in_port=nfv_sw_port,
                eth_type=valve_packet.ETH_EAPOL,
                eth_src=mac),
            priority=valve.dp.highest_priority,
            inst=[valve_of.apply_actions([
                valve_of.set_field(eth_src=EAPOL_DST),
                valve_of.output_port(dot1x_port.number)])]))
        return ofmsgs
Exemplo n.º 4
0
 def create_dot1x_flow_pair(self, dot1x_port, nfv_sw_port, mac):
     ofmsgs = [
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=dot1x_port.number,
                 eth_type=valve_packet.ETH_EAPOL),
             priority=self.acl_priority,
             inst=[
                 valve_of.apply_actions([
                     self.port_acl_table.set_field(eth_dst=mac),
                     valve_of.output_port(nfv_sw_port.number)
                 ])
             ],
         ),
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=nfv_sw_port.number,
                 eth_type=valve_packet.ETH_EAPOL,
                 eth_src=mac),
             priority=self.acl_priority,
             inst=[
                 valve_of.apply_actions([
                     self.port_acl_table.set_field(
                         eth_src=valve_packet.EAPOL_ETH_DST),
                     valve_of.output_port(dot1x_port.number)
                 ])
             ],
         )
     ]
     return ofmsgs
Exemplo n.º 5
0
    def create_flow_pair(self, dot1x_port, nfv_sw_port, valve):
        """Creates the pair of flows that redirects the eapol packets to/from the supplicant and
        nfv port

        Args:
            dot1x_port (Port):
            nfv_sw_port (int):
            valve (Valve):

        Returns:
            list
        """
        port_acl_table = valve.dp.tables['port_acl']
        valve_index = self.dp_id_to_valve_index[valve.dp.dp_id]
        mac = get_mac_str(valve_index, dot1x_port.number)

        if dot1x_port.running():
            return [
                port_acl_table.flowmod(
                    inst=[valve_of.apply_actions([
                        valve_of.set_field(eth_dst=mac),
                        valve_of.output_port(nfv_sw_port)])],
                    **FaucetDot1x.get_dot1x_port_match_priority(dot1x_port, port_acl_table, valve)),
                port_acl_table.flowmod(
                    inst=[valve_of.apply_actions([
                        valve_of.set_field(eth_src=EAPOL_DST),
                        valve_of.output_port(dot1x_port.number)])],
                    **FaucetDot1x.get_nfv_sw_port_match_priority(mac, nfv_sw_port,
                                                                 port_acl_table, valve)
                )]
        return []
Exemplo n.º 6
0
 def create_dot1x_flow_pair(self, dot1x_port, nfv_sw_port, mac):
     ofmsgs = [
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=dot1x_port.number,
                 eth_type=valve_packet.ETH_EAPOL),
             priority=self.acl_priority,
             inst=[valve_of.apply_actions([
                 self.port_acl_table.set_field(eth_dst=mac),
                 valve_of.output_port(nfv_sw_port.number)])],
             ),
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=nfv_sw_port.number,
                 eth_type=valve_packet.ETH_EAPOL,
                 eth_src=mac),
             priority=self.acl_priority,
             inst=[valve_of.apply_actions([
                 self.port_acl_table.set_field(
                     eth_src=valve_packet.EAPOL_ETH_DST),
                 valve_of.output_port(dot1x_port.number)
                 ])],
             )
         ]
     return ofmsgs
Exemplo n.º 7
0
def build_output_actions(acl_table, output_dict):
    """Implement actions to alter packet/output."""
    output_actions = []
    output_port = None
    ofmsgs = []
    # rewrite any VLAN headers first always
    vlan_actions = rewrite_vlan(acl_table, output_dict)
    if vlan_actions:
        output_actions.extend(vlan_actions)
    if 'set_fields' in output_dict:
        for set_field in output_dict['set_fields']:
            output_actions.append(acl_table.set_field(**set_field))
    if 'port' in output_dict:
        output_port = output_dict['port']
        output_actions.append(valve_of.output_port(output_port))
    if 'ports' in output_dict:
        for output_port in output_dict['ports']:
            output_actions.append(valve_of.output_port(output_port))
    if 'failover' in output_dict:
        failover = output_dict['failover']
        group_id = failover['group_id']
        buckets = []
        for port in failover['ports']:
            buckets.append(valve_of.bucket(
                watch_port=port, actions=[valve_of.output_port(port)]))
        ofmsgs.append(valve_of.groupdel(group_id=group_id))
        ofmsgs.append(valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
        output_actions.append(valve_of.group_act(group_id=group_id))
    return (output_port, output_actions, ofmsgs)
Exemplo n.º 8
0
 def create_dot1x_flow_pair(self, port_num, nfv_sw_port_num, mac):
     """Create dot1x flow pair"""
     ofmsgs = [
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=port_num,
                 eth_type=valve_packet.ETH_EAPOL),
             priority=self.dot1x_static_rules_priority,
             inst=[valve_of.apply_actions([
                 self.port_acl_table.set_field(eth_dst=mac),
                 valve_of.output_port(nfv_sw_port_num)])],
         ),
         self.port_acl_table.flowmod(
             match=self.port_acl_table.match(
                 in_port=nfv_sw_port_num,
                 eth_type=valve_packet.ETH_EAPOL,
                 eth_src=mac),
             priority=self.dot1x_static_rules_priority,
             inst=[valve_of.apply_actions([
                 self.port_acl_table.set_field(
                     eth_src=valve_packet.EAPOL_ETH_DST),
                 valve_of.output_port(port_num)
             ])],
         )
     ]
     return ofmsgs
Exemplo n.º 9
0
    def create_dot1x_flow_pair(self, port_num, nfv_sw_port_num, mac):
        """Create dot1x flow pair"""
        ofmsgs = [
            self.port_acl_table.flowmod(
                match=self.port_acl_table.match(
                    in_port=port_num,
                    eth_type=valve_packet.ETH_EAPOL),
                priority=self.override_priority,
                inst=(valve_of.apply_actions([
                    self.port_acl_table.set_field(eth_dst=mac),
                    valve_of.output_port(nfv_sw_port_num)]),),
            ),
            self.port_acl_table.flowmod(
                match=self.port_acl_table.match(
                    in_port=nfv_sw_port_num,
                    eth_type=valve_packet.ETH_EAPOL,
                    eth_src=mac),
                priority=self.override_priority,
                inst=(valve_of.apply_actions([
                    self.port_acl_table.set_field(
                        eth_src=valve_packet.EAPOL_ETH_DST),
                    valve_of.output_port(port_num)
                ]),),
            )
        ]

        return ofmsgs
Exemplo n.º 10
0
 def output_port(self, port, hairpin=False):
     actions = port.mirror_actions()
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 11
0
 def output_port(self, port, hairpin=False):
     actions = port.mirror_actions()
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 12
0
 def _build_group_buckets(self, vlan, unicast_flood):
     buckets = []
     for port in vlan.tagged_flood_ports(unicast_flood):
         buckets.append(valve_of.bucket(
             actions=[valve_of.output_port(port.number)]))
     for port in vlan.untagged_flood_ports(unicast_flood):
         buckets.append(valve_of.bucket(
             actions=[
                 valve_of.pop_vlan(),
                 valve_of.output_port(port.number)]))
     return buckets
Exemplo n.º 13
0
 def output_port(self, port, hairpin=False, output_table=None, loop_protect_field=None):
     actions = port.mirror_actions()
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
     elif loop_protect_field is not None:
         actions.append(output_table.set_field(**{STACK_LOOP_PROTECT_FIELD: loop_protect_field}))
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 14
0
def build_acl_entry(rule_conf, acl_allow_inst, port_num=None, vlan_vid=None):
    acl_inst = []
    match_dict = {}
    for attrib, attrib_value in list(rule_conf.items()):
        if attrib == 'in_port':
            continue
        if attrib == 'actions':
            allow = False
            allow_specified = False
            if 'allow' in attrib_value:
                allow_specified = True
                if attrib_value['allow'] == 1:
                    allow = True
            if 'mirror' in attrib_value:
                port_no = attrib_value['mirror']
                acl_inst.append(
                    valve_of.apply_actions([valve_of.output_port(port_no)]))
                if not allow_specified:
                    allow = True
            if 'output' in attrib_value:
                output_dict = attrib_value['output']
                output_actions = []
                output_port = None
                if 'port' in output_dict:
                    output_port = output_dict['port']

                # if destination rewriting selected, rewrite it.
                if 'dl_dst' in output_dict:
                    output_actions.append(
                        valve_of.set_eth_dst(output_dict['dl_dst']))
                # rewrite any VLAN headers.
                vlan_actions = rewrite_vlan(output_dict)
                if vlan_actions:
                    output_actions.extend(vlan_actions)
                # output to a port if specified.
                if output_port is not None:
                    output_actions.append(valve_of.output_port(output_port))

                acl_inst.append(valve_of.apply_actions(output_actions))

                # if port specified, output packet now and exit pipeline.
                if output_port is not None:
                    continue

            if allow:
                acl_inst.append(acl_allow_inst)
        else:
            match_dict[attrib] = attrib_value
    if port_num is not None:
        match_dict['in_port'] = port_num
    if vlan_vid is not None:
        match_dict['vlan_vid'] = valve_of.vid_present(vlan_vid)
    acl_match = valve_of.match_from_dict(match_dict)
    return acl_match, acl_inst
Exemplo n.º 15
0
    def build_port_out_inst(self, vlan, port):
        dst_act = []
        if not vlan.port_is_tagged(port.number) and port.stack is None:
            dst_act.append(valve_of.pop_vlan())
        dst_act.append(valve_of.output_port(port.number))

        if port.mirror is not None:
            mirror_acts = [valve_of.output_port(port.mirror)]
            dst_act.extend(mirror_acts)

        return [valve_of.apply_actions(dst_act)]
Exemplo n.º 16
0
Arquivo: vlan.py Projeto: nfz1/faucet
 def output_port(self, port, hairpin=False):
     actions = []
     # If port should mirror add output to mirror ports
     if port.mirror is not None:
         for mirror_port in port.mirror:
             actions.append(valve_of.output_port(mirror_port))
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 17
0
def build_ordered_output_actions(acl_table,
                                 output_list,
                                 tunnel_rules=None,
                                 source_id=None):
    """Build actions from ordered ACL output list"""
    output_actions = []
    output_ports = []
    output_ofmsgs = []
    output_inst = []
    for action in output_list:
        for key, value in action.items():
            if key == 'pop_vlans':
                for _ in range(value):
                    output_actions.append(valve_of.pop_vlan())
            if key == 'vlan_vid':
                output_actions.extend(push_vlan(acl_table, value))
            if key == 'swap_vid':
                output_actions.append(acl_table.set_vlan_vid(value))
            if key == 'vlan_vids':
                for vlan_vid in value:
                    output_actions.extend(push_vlan(acl_table, vlan_vid))
            if key == 'set_fields':
                for set_field in value:
                    output_actions.append(acl_table.set_field(**set_field))
            if key == 'port':
                output_ports.append(value)
                output_actions.append(valve_of.output_port(value))
            if key == 'ports':
                for output_port in value:
                    output_ports.append(output_port)
                    output_actions.append(valve_of.output_port(output_port))
            if key == 'failover':
                group_id = value['group_id']
                buckets = []
                for port in value['ports']:
                    buckets.append(
                        valve_of.bucket(watch_port=port,
                                        actions=[valve_of.output_port(port)]))
                output_ofmsgs.extend(
                    valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
                output_actions.append(valve_of.group_act(group_id=group_id))
            if key == 'tunnel' and tunnel_rules and source_id is not None:
                source_rule = tunnel_rules[value][source_id]
                _, tunnel_actions, tunnel_ofmsgs, tunnel_inst = build_output_actions(
                    acl_table, source_rule)
                output_actions.extend(tunnel_actions)
                output_ofmsgs.extend(tunnel_ofmsgs)
                output_inst.extend(tunnel_inst)
            if key == 'goto':
                output_inst.append(valve_of.goto_table_id(value))
    return (output_ports, output_actions, output_ofmsgs, output_inst)
Exemplo n.º 18
0
    def build_port_out_inst(self, vlan, port, port_number=None):
        """Return instructions to output a packet on a given port."""
        if port_number is None:
            port_number = port.number
        dst_act = []
        if not vlan.port_is_tagged(port) and port.stack is None:
            dst_act.append(valve_of.pop_vlan())
        dst_act.append(valve_of.output_port(port_number))

        if port.mirror is not None:
            mirror_acts = [valve_of.output_port(port.mirror)]
            dst_act.extend(mirror_acts)

        return [valve_of.apply_actions(dst_act)]
Exemplo n.º 19
0
 def _build_flood_port_outputs(self, ports, exclude_port):
     flood_acts = []
     for port in ports:
         if port == exclude_port:
             continue
         flood_acts.append(valve_of.output_port(port.number))
     return flood_acts
Exemplo n.º 20
0
    def create_mab_flow(self, port_num, nfv_sw_port_num, mac):
        """
        Create MAB ACL for sending IP Activity to Chewie NFV
            Returns flowmods to send all IP traffic to Chewie

        Args:
            port_num (int): Number of port in
            nfv_sw_port_num(int): Number of port out
            mac(str): MAC address of the valve/port combo

        """
        return self.port_acl_table.flowmod(
            match=self.port_acl_table.match(
                in_port=port_num,
                eth_type=valve_of.ether.ETH_TYPE_IP,
                nw_proto=valve_of.inet.IPPROTO_UDP,
                udp_src=68,
                udp_dst=67,
            ),
            priority=self.low_priority,
            inst=(valve_of.apply_actions([
                self.port_acl_table.set_field(eth_dst=mac),
                valve_of.output_port(nfv_sw_port_num)
            ]), ),
        )
Exemplo n.º 21
0
 def _nexthop_group_buckets(self, vlan, port, eth_src):
     actions = self._nexthop_actions(eth_src, vlan)
     if not vlan.port_is_tagged(port):
         actions.append(valve_of.pop_vlan())
     actions.append(valve_of.output_port(port.number))
     buckets = [valve_of.bucket(actions=actions)]
     return buckets
Exemplo n.º 22
0
 def add_port(self, port):
     """Add flows to allow coprocessor to inject or output packets."""
     ofmsgs = []
     if port.coprocessor:
         ofmsgs.append(
             self.vlan_table.flowmod(
                 self.vlan_table.match(in_port=port.number),
                 priority=self.low_priority,
                 inst=(self.vlan_table.goto(self.copro_table), )))
         ofmsgs.append(
             self.eth_src_table.flowmod(
                 match=self.eth_src_table.match(in_port=port.number),
                 priority=self.high_priority,
                 inst=(self.eth_src_table.goto(self.output_table), )))
         # TODO: add additional output port strategies (eg. MPLS) and tagged ports
         vlan_vid_base = port.coprocessor.get('vlan_vid_base', 0)
         for port_number in self.ports:
             inst = (valve_of.apply_actions(
                 (valve_of.pop_vlan(),
                  valve_of.output_port(port_number))), )
             vid = vlan_vid_base + port_number
             vlan = OFVLAN(str(vid), vid)
             match = self.copro_table.match(vlan=vlan)
             ofmsgs.append(
                 self.copro_table.flowmod(match=match,
                                          priority=self.high_priority,
                                          inst=inst))
     return ofmsgs
Exemplo n.º 23
0
def build_output_actions(acl_table,
                         output_dict,
                         tunnel_rules=None,
                         source_id=None):
    """Implement actions to alter packet/output."""
    if isinstance(output_dict, (list, tuple)):
        return build_ordered_output_actions(acl_table, output_dict,
                                            tunnel_rules, source_id)
    output_actions = []
    output_inst = []
    output_port = None
    ofmsgs = []
    # rewrite any VLAN headers first always
    vlan_actions = rewrite_vlan(acl_table, output_dict)
    if vlan_actions:
        output_actions.extend(vlan_actions)
    if 'set_fields' in output_dict:
        for set_field in output_dict['set_fields']:
            output_actions.append(acl_table.set_field(**set_field))
    if 'port' in output_dict:
        output_port = output_dict['port']
        output_actions.append(valve_of.output_port(output_port))
    if 'ports' in output_dict:
        for output_port in output_dict['ports']:
            output_actions.append(valve_of.output_port(output_port))
    if 'failover' in output_dict:
        failover = output_dict['failover']
        group_id = failover['group_id']
        buckets = []
        for port in failover['ports']:
            buckets.append(
                valve_of.bucket(watch_port=port,
                                actions=[valve_of.output_port(port)]))
        ofmsgs.extend(valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
        output_actions.append(valve_of.group_act(group_id=group_id))
    if 'tunnel' in output_dict and tunnel_rules and source_id is not None:
        tunnel_id = output_dict['tunnel']
        source_rule = tunnel_rules[tunnel_id][source_id]
        _, tunnel_actions, tunnel_ofmsgs, tunnel_inst = build_output_actions(
            acl_table, source_rule)
        output_actions.extend(tunnel_actions)
        tunnel_ofmsgs.extend(tunnel_ofmsgs)
        output_inst.extend(tunnel_inst)
    if 'goto' in output_dict:
        output_inst.append(valve_of.goto_table_id(output_dict['goto']))
    return (output_port, output_actions, ofmsgs, output_inst)
Exemplo n.º 24
0
 def output_port(self,
                 port,
                 hairpin=False,
                 output_table=None,
                 loop_protect_field=None):
     actions = port.mirror_actions()
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
     elif loop_protect_field is not None:
         actions.append(
             output_table.set_field(
                 **{STACK_LOOP_PROTECT_FIELD: loop_protect_field}))
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 25
0
 def mirror_actions(self):
     """Return OF actions to mirror this port."""
     if self.mirror is not None:
         return [
             valve_of.output_port(mirror_port)
             for mirror_port in self.mirror
         ]
     return []
Exemplo n.º 26
0
    def learn_host_on_vlan_port_flows(self, port, vlan, eth_src,
                                      delete_existing, refresh_rules,
                                      src_rule_idle_timeout,
                                      src_rule_hard_timeout,
                                      dst_rule_idle_timeout):
        """Return flows that implement learning a host on a port."""
        ofmsgs = []

        # Delete any existing entries for MAC.
        if delete_existing:
            ofmsgs.extend(self.delete_host_from_vlan(eth_src, vlan))

        # Associate this MAC with source port.
        src_match = self.eth_src_table.match(in_port=port.number,
                                             vlan=vlan,
                                             eth_src=eth_src)
        src_priority = self.host_priority - 1
        inst = self.eth_src_table.goto(self.output_table)

        if port.override_output_port:
            inst = valve_of.apply_actions(
                [valve_of.output_port(port.override_output_port.number)])
        ofmsgs.append(
            self.eth_src_table.flowmod(match=src_match,
                                       priority=src_priority,
                                       inst=[inst],
                                       hard_timeout=src_rule_hard_timeout,
                                       idle_timeout=src_rule_idle_timeout))

        hairpinning = port.hairpin or port.hairpin_unicast

        # If we are refreshing only and not in hairpin mode, leave existing eth_dst alone.
        if refresh_rules and not hairpinning:
            return ofmsgs

        # Output packets for this MAC to specified port.
        ofmsgs.append(
            self.eth_dst_table.flowmod(self.eth_dst_table.match(
                vlan=vlan, eth_dst=eth_src),
                                       priority=self.host_priority,
                                       inst=self.pipeline.output(port, vlan),
                                       idle_timeout=dst_rule_idle_timeout))

        # If port is in hairpin mode, install a special rule
        # that outputs packets destined to this MAC back out the same
        # port they came in (e.g. multiple hosts on same WiFi AP,
        # and FAUCET is switching between them on the same port).
        if hairpinning:
            ofmsgs.append(
                self.eth_dst_hairpin_table.flowmod(
                    self.eth_dst_hairpin_table.match(in_port=port.number,
                                                     vlan=vlan,
                                                     eth_dst=eth_src),
                    priority=self.host_priority,
                    inst=self.pipeline.output(port, vlan, hairpin=True),
                    idle_timeout=dst_rule_idle_timeout))

        return ofmsgs
Exemplo n.º 27
0
    def learn_host_on_vlan_port_flows(self, port, vlan, eth_src,
                                      delete_existing, refresh_rules,
                                      src_rule_idle_timeout,
                                      src_rule_hard_timeout,
                                      dst_rule_idle_timeout):
        """Return flows that implement learning a host on a port."""
        ofmsgs = []

        # Delete any existing entries for MAC.
        if delete_existing:
            ofmsgs.extend(self.delete_host_from_vlan(eth_src, vlan))

        # Associate this MAC with source port.
        src_match = self.eth_src_table.match(
            in_port=port.number, vlan=vlan, eth_src=eth_src)
        src_priority = self.host_priority - 1
        inst = self.eth_src_table.goto(self.output_table)

        if port.override_output_port:
            inst = valve_of.apply_actions([
                valve_of.output_port(port.override_output_port.number)])

        loop_protect_field = None
        if port.tagged_vlans and port.loop_protect_external and self.stack:
            loop_protect_field = 0

        ofmsgs.append(self.eth_src_table.flowmod(
            match=src_match,
            priority=src_priority,
            inst=[inst],
            hard_timeout=src_rule_hard_timeout,
            idle_timeout=src_rule_idle_timeout))

        hairpinning = port.hairpin or port.hairpin_unicast

        # If we are refreshing only and not in hairpin mode, leave existing eth_dst alone.
        if refresh_rules and not hairpinning:
            return ofmsgs

        # Output packets for this MAC to specified port.
        ofmsgs.append(self.eth_dst_table.flowmod(
            self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src),
            priority=self.host_priority,
            inst=self.pipeline.output(port, vlan, loop_protect_field=loop_protect_field),
            idle_timeout=dst_rule_idle_timeout))

        # If port is in hairpin mode, install a special rule
        # that outputs packets destined to this MAC back out the same
        # port they came in (e.g. multiple hosts on same WiFi AP,
        # and FAUCET is switching between them on the same port).
        if hairpinning:
            ofmsgs.append(self.eth_dst_hairpin_table.flowmod(
                self.eth_dst_hairpin_table.match(in_port=port.number, vlan=vlan, eth_dst=eth_src),
                priority=self.host_priority,
                inst=self.pipeline.output(port, vlan, hairpin=True),
                idle_timeout=dst_rule_idle_timeout))

        return ofmsgs
Exemplo n.º 28
0
 def output_port(self, port, hairpin=False, output_table=None, external_forwarding_requested=None):
     actions = []
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
         # Packet is mirrored, as the receiving host sees it (without a tag).
         actions.extend(port.mirror_actions())
     else:
         actions.extend(port.mirror_actions())
         if external_forwarding_requested is not None:
             if external_forwarding_requested:
                 actions.append(output_table.set_external_forwarding_requested())
             else:
                 actions.append(output_table.set_no_external_forwarding_requested())
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 29
0
    def learn_host_on_vlan_port_flows(self, port, vlan, eth_src, delete_existing,
                                      src_rule_idle_timeout, src_rule_hard_timeout,
                                      dst_rule_idle_timeout):
        """Return flows that implement learning a host on a port."""
        ofmsgs = []

        if port.permanent_learn:
            # Antispoofing rule for this MAC.
            ofmsgs.append(self.eth_src_table.flowdrop(
                self.eth_src_table.match(vlan=vlan, eth_src=eth_src),
                priority=(self.host_priority - 2)))
        else:
            # Delete any existing entries for MAC.
            # TODO: for LAGs, don't delete entries in the same LAG.
            if delete_existing:
                ofmsgs.extend(self.delete_host_from_vlan(eth_src, vlan))

        # Associate this MAC with source port.
        src_match = self.eth_src_table.match(
            in_port=port.number, vlan=vlan, eth_src=eth_src)
        if port.override_output_port:
            ofmsgs.append(self.eth_src_table.flowmod(
                match=src_match,
                priority=(self.host_priority - 1),
                inst=[valve_of.apply_actions([
                    valve_of.output_port(port.override_output_port.number)])],
                hard_timeout=src_rule_hard_timeout,
                idle_timeout=src_rule_idle_timeout))
        else:
            ofmsgs.append(self.eth_src_table.flowmod(
                match=src_match,
                priority=(self.host_priority - 1),
                inst=[valve_of.goto_table(self.eth_dst_table)],
                hard_timeout=src_rule_hard_timeout,
                idle_timeout=src_rule_idle_timeout))

        # Output packets for this MAC to specified port.
        ofmsgs.append(self.eth_dst_table.flowmod(
            self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src),
            priority=self.host_priority,
            inst=[valve_of.apply_actions(vlan.output_port(port))],
            idle_timeout=dst_rule_idle_timeout))

        # If port is in hairpin mode, install a special rule
        # that outputs packets destined to this MAC back out the same
        # port they came in (e.g. multiple hosts on same WiFi AP,
        # and FAUCET is switching between them on the same port).
        if port.hairpin:
            ofmsgs.append(self.eth_dst_table.flowmod(
                self.eth_dst_table.match(in_port=port.number, vlan=vlan, eth_dst=eth_src),
                priority=(self.host_priority + 1),
                inst=[valve_of.apply_actions(vlan.output_port(port, hairpin=True))],
                idle_timeout=dst_rule_idle_timeout))

        return ofmsgs
Exemplo n.º 30
0
def build_acl_entry(rule_conf,
                    acl_allow_inst,
                    meters,
                    port_num=None,
                    vlan_vid=None):
    acl_inst = []
    acl_match_dict = {}
    acl_ofmsgs = []
    acl_cookie = None
    for attrib, attrib_value in list(rule_conf.items()):
        if attrib == 'in_port':
            continue
        if attrib == 'cookie':
            acl_cookie = attrib_value
            continue
        if attrib == 'actions':
            allow = False
            allow_specified = False
            if 'allow' in attrib_value:
                allow_specified = True
                if attrib_value['allow'] == 1:
                    allow = True
            if 'meter' in attrib_value:
                meter_name = attrib_value['meter']
                acl_inst.append(
                    valve_of.apply_meter(meters[meter_name].meter_id))
            if 'mirror' in attrib_value:
                port_no = attrib_value['mirror']
                acl_inst.append(
                    valve_of.apply_actions([valve_of.output_port(port_no)]))
                if not allow_specified:
                    allow = True
            if 'output' in attrib_value:
                output_port, output_actions, output_ofmsgs = build_output_actions(
                    attrib_value['output'])
                acl_inst.append(valve_of.apply_actions(output_actions))
                acl_ofmsgs.extend(output_ofmsgs)

                # if port specified, output packet now and exit pipeline.
                if output_port is not None:
                    continue

            if allow:
                acl_inst.append(acl_allow_inst)
        else:
            acl_match_dict[attrib] = attrib_value
    if port_num is not None:
        acl_match_dict['in_port'] = port_num
    if vlan_vid is not None:
        acl_match_dict['vlan_vid'] = valve_of.vid_present(vlan_vid)
    try:
        acl_match = valve_of.match_from_dict(acl_match_dict)
    except TypeError:
        assert False, 'invalid type in ACL'
    return (acl_match, acl_inst, acl_cookie, acl_ofmsgs)
Exemplo n.º 31
0
 def _build_mirrored_flood_rules(self, vlan, eth_dst, eth_dst_mask,
                                 exclude_unicast, command, flood_priority):
     ofmsgs = []
     mirrored_ports = vlan.mirrored_ports()
     for port in mirrored_ports:
         mirror_acts = [valve_of.output_port(port.mirror)]
         ofmsgs.extend(self._build_flood_rule_for_port(
             vlan, eth_dst, eth_dst_mask,
             exclude_unicast, command, flood_priority,
             port, mirror_acts))
     return ofmsgs
Exemplo n.º 32
0
 def _add_egress_table_rule(self, port, vlan, pop_vlan=True):
     metadata, metadata_mask = faucet_md.get_egress_metadata(
         port.number, vlan.vid)
     actions = copy.copy(port.mirror_actions())
     if pop_vlan:
         actions.append(valve_of.pop_vlan())
     actions.append(valve_of.output_port(port.number))
     inst = (valve_of.apply_actions(tuple(actions)), )
     return self.egress_table.flowmod(self.egress_table.match(
         vlan=vlan, metadata=metadata, metadata_mask=metadata_mask),
                                      priority=self.dp.high_priority,
                                      inst=inst)
Exemplo n.º 33
0
 def add_port(self, port):
     """initialise override_output_port if necessary"""
     ofmsgs = []
     if port.override_output_port:
         ofmsgs.append(self.eth_src_table.flowmod(
             match=self.eth_src_table.match(
                 in_port=port.number),
             priority=self.low_priority + 1,
             inst=[valve_of.apply_actions([
                 valve_of.output_controller(),
                 valve_of.output_port(port.override_output_port.number)])]))
     return ofmsgs
Exemplo n.º 34
0
 def add_port(self, port):
     """initialise override_output_port if necessary"""
     ofmsgs = []
     if port.override_output_port:
         ofmsgs.append(self.eth_src_table.flowmod(
             match=self.eth_src_table.match(
                 in_port=port.number),
             priority=self.low_priority + 1,
             inst=[valve_of.apply_actions([
                 valve_of.output_controller(),
                 valve_of.output_port(port.override_output_port.number)])]))
     return ofmsgs
Exemplo n.º 35
0
 def output_port(self,
                 port,
                 hairpin=False,
                 output_table=None,
                 loop_protect_field=None):
     actions = []
     if self.port_is_untagged(port):
         actions.append(valve_of.pop_vlan())
         # Packet is mirrored, as the receiving host sees it (without a tag).
         actions.extend(port.mirror_actions())
     else:
         actions.extend(port.mirror_actions())
         if loop_protect_field is not None:
             actions.append(
                 output_table.set_field(
                     **{STACK_LOOP_PROTECT_FIELD: loop_protect_field}))
     if hairpin:
         actions.append(valve_of.output_port(valve_of.OFP_IN_PORT))
     else:
         actions.append(valve_of.output_port(port.number))
     return actions
Exemplo n.º 36
0
 def _add_egress_table_rule(self, port, vlan, pop_vlan=True):
     metadata, metadata_mask = faucet_md.get_egress_metadata(
         port.number, vlan.vid)
     actions = copy.copy(port.mirror_actions())
     if pop_vlan:
         actions.append(valve_of.pop_vlan())
     actions.append(valve_of.output_port(port.number))
     inst = [valve_of.apply_actions(actions)]
     return self.egress_table.flowmod(
         self.egress_table.match(
             vlan=vlan,
             metadata=metadata,
             metadata_mask=metadata_mask
             ),
         priority=self.dp.high_priority,
         inst=inst
         )
Exemplo n.º 37
0
 def test_delete_order(self):
     """Test delete ordering/deupdlication."""
     global_groupdel = valve_of.groupdel(group_id=valve_of.ofp.OFPG_ALL)
     global_flowdel = valve_of.flowmod(cookie=None,
                                       hard_timeout=None,
                                       idle_timeout=None,
                                       match_fields=None,
                                       out_port=None,
                                       table_id=valve_of.ofp.OFPTT_ALL,
                                       inst=(),
                                       priority=0,
                                       command=valve_of.ofp.OFPFC_DELETE,
                                       out_group=valve_of.ofp.OFPG_ANY)
     flowdel = valve_of.flowmod(cookie=None,
                                hard_timeout=None,
                                idle_timeout=None,
                                match_fields=None,
                                out_port=None,
                                table_id=9,
                                inst=(),
                                priority=0,
                                command=valve_of.ofp.OFPFC_DELETE,
                                out_group=valve_of.ofp.OFPG_ANY)
     flow = valve_of.output_port(1)
     flows = [flowdel, flow, flow, flow, global_flowdel, global_groupdel]
     reordered = valve_of.valve_flowreorder(flows, use_barriers=True)
     reordered_str = [str(flow) for flow in reordered]
     # global deletes come first
     self.assertTrue(valve_of.is_global_groupdel(reordered[0]),
                     msg=reordered)
     self.assertTrue(valve_of.is_global_flowdel(reordered[1]),
                     msg=reordered)
     # with a berrier
     self.assertEqual(str(valve_of.barrier()),
                      str(reordered[2]),
                      msg=reordered)
     # without the individual delete
     self.assertTrue(str(flowdel) not in reordered_str, msg=reordered)
     # with regular flow last
     self.assertEqual(str(flow), reordered_str[-1], msg=reordered)
Exemplo n.º 38
0
def build_acl_entry(  # pylint: disable=too-many-arguments,too-many-branches,too-many-statements
        acl_table, rule_conf, meters,
        acl_allow_inst, acl_force_port_vlan_inst,
        port_num=None, vlan_vid=None, tunnel_rules=None, source_id=None):
    """Build flow/groupmods for one ACL rule entry."""
    acl_inst = []
    acl_act = []
    acl_match_dict = {}
    acl_ofmsgs = []
    acl_cookie = None
    allow_inst = acl_allow_inst

    for attrib, attrib_value in rule_conf.items():
        # if attrib == 'in_port':
        #     continue
        if attrib == 'cookie':
            acl_cookie = attrib_value
            continue
        if attrib == 'description':
            continue
        if attrib == 'actions':
            allow = False
            allow_specified = False
            if 'allow' in attrib_value:
                allow_specified = True
                if attrib_value['allow'] == 1:
                    allow = True
            if 'force_port_vlan' in attrib_value:
                if attrib_value['force_port_vlan'] == 1:
                    allow_inst = acl_force_port_vlan_inst
            if 'meter' in attrib_value:
                meter_name = attrib_value['meter']
                acl_inst.append(valve_of.apply_meter(meters[meter_name].meter_id))
            if 'mirror' in attrib_value:
                port_no = attrib_value['mirror']
                acl_act.append(valve_of.output_port(port_no))
                if not allow_specified:
                    allow = True
            if 'output' in attrib_value:
                output_port, output_actions, output_ofmsgs, output_inst = build_output_actions(
                    acl_table, attrib_value['output'], tunnel_rules, source_id)
                acl_act.extend(output_actions)
                acl_ofmsgs.extend(output_ofmsgs)
                acl_inst.extend(output_inst)

                # if port specified, output packet now and exit pipeline.
                if not allow and output_port is not None:
                    continue
            if 'ct' in attrib_value:
                ct_action = build_ct_actions(acl_table, attrib_value['ct'])
                acl_act.append(ct_action)

            if allow:
                acl_inst.extend(allow_inst)
        else:
            acl_match_dict[attrib] = attrib_value
    if port_num is not None:
        # This overwrites the `in_port` match if it is specified in the ACL config
        acl_match_dict['in_port'] = port_num
    if vlan_vid is not None:
        # This overwrites the `vlan_vid` match if it is specified in the ACL config
        acl_match_dict['vlan_vid'] = valve_of.vid_present(vlan_vid)
    try:
        acl_match = valve_of.match_from_dict(acl_match_dict)
    except TypeError as type_error:
        raise InvalidConfigError('invalid match type in ACL') from type_error
    if acl_act:
        acl_inst.append(valve_of.apply_actions(acl_act))
    return (acl_match, acl_inst, acl_cookie, acl_ofmsgs)
Exemplo n.º 39
0
    def learn_host_on_vlan_port_flows(self, port, vlan, eth_src,
                                      delete_existing, refresh_rules,
                                      src_rule_idle_timeout,
                                      src_rule_hard_timeout,
                                      dst_rule_idle_timeout):
        """Return flows that implement learning a host on a port."""
        ofmsgs = []

        if port.permanent_learn:
            # Antispoofing rule for this MAC.
            if self.classification_table != self.eth_src_table:
                ofmsgs.append(self.classification_table.flowmod(
                    self.classification_table.match(
                        in_port=port.number, vlan=vlan, eth_src=eth_src),
                    priority=self.host_priority,
                    inst=[self.classification_table.goto(self.eth_src_table)]))
            ofmsgs.append(self.classification_table.flowdrop(
                self.classification_table.match(vlan=vlan, eth_src=eth_src),
                priority=(self.host_priority - 2)))
        else:
            # Delete any existing entries for MAC.
            if delete_existing:
                ofmsgs.extend(self.delete_host_from_vlan(eth_src, vlan))

        # Associate this MAC with source port.
        src_match = self.eth_src_table.match(
            in_port=port.number, vlan=vlan, eth_src=eth_src)
        src_priority = self.host_priority - 1
        inst = self.eth_src_table.goto(self.output_table)

        if port.override_output_port:
            inst = valve_of.apply_actions([
                valve_of.output_port(port.override_output_port.number)])
        ofmsgs.append(self.eth_src_table.flowmod(
            match=src_match,
            priority=src_priority,
            inst=[inst],
            hard_timeout=src_rule_hard_timeout,
            idle_timeout=src_rule_idle_timeout))

        hairpinning = port.hairpin or port.hairpin_unicast

        # If we are refreshing only and not in hairpin mode, leave existing eth_dst alone.
        if refresh_rules and not hairpinning:
            return ofmsgs

        # Output packets for this MAC to specified port.
        if self.egress_table is not None:
            metadata, metadata_mask = get_egress_metadata(port.number, vlan.vid)
            ofmsgs.append(self.eth_dst_table.flowmod(
                self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src),
                priority=self.host_priority,
                inst=valve_of.metadata_goto_table(
                    metadata, metadata_mask, self.egress_table),
                idle_timeout=dst_rule_idle_timeout))
        else:
            ofmsgs.append(self.eth_dst_table.flowmod(
                self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src),
                priority=self.host_priority,
                inst=[valve_of.apply_actions(vlan.output_port(port))],
                idle_timeout=dst_rule_idle_timeout))

        # If port is in hairpin mode, install a special rule
        # that outputs packets destined to this MAC back out the same
        # port they came in (e.g. multiple hosts on same WiFi AP,
        # and FAUCET is switching between them on the same port).
        if hairpinning:
            ofmsgs.append(self.eth_dst_hairpin_table.flowmod(
                self.eth_dst_hairpin_table.match(in_port=port.number, vlan=vlan, eth_dst=eth_src),
                priority=self.host_priority,
                inst=[valve_of.apply_actions(vlan.output_port(port, hairpin=True))],
                idle_timeout=dst_rule_idle_timeout))

        return ofmsgs
Exemplo n.º 40
0
def build_acl_entry(acl_table,
                    rule_conf,
                    meters,
                    acl_allow_inst,
                    acl_force_port_vlan_inst,
                    port_num=None,
                    vlan_vid=None):
    """Build flow/groupmods for one ACL rule entry."""
    acl_inst = []
    acl_act = []
    acl_match_dict = {}
    acl_ofmsgs = []
    acl_cookie = None
    allow_inst = acl_allow_inst

    for attrib, attrib_value in rule_conf.items():
        if attrib == 'in_port':
            continue
        if attrib == 'cookie':
            acl_cookie = attrib_value
            continue
        if attrib == 'description':
            continue
        if attrib == 'actions':
            allow = False
            allow_specified = False
            if 'allow' in attrib_value:
                allow_specified = True
                if attrib_value['allow'] == 1:
                    allow = True
            if 'force_port_vlan' in attrib_value:
                if attrib_value['force_port_vlan'] == 1:
                    allow_inst = acl_force_port_vlan_inst
            if 'meter' in attrib_value:
                meter_name = attrib_value['meter']
                acl_inst.append(
                    valve_of.apply_meter(meters[meter_name].meter_id))
            if 'mirror' in attrib_value:
                port_no = attrib_value['mirror']
                acl_act.append(valve_of.output_port(port_no))
                if not allow_specified:
                    allow = True
            if 'output' in attrib_value:
                output_port, output_actions, output_ofmsgs = build_output_actions(
                    acl_table, attrib_value['output'])
                acl_act.extend(output_actions)
                acl_ofmsgs.extend(output_ofmsgs)

                # if port specified, output packet now and exit pipeline.
                if not allow and output_port is not None:
                    continue

            if allow:
                acl_inst.extend(allow_inst)
        else:
            acl_match_dict[attrib] = attrib_value
    if port_num is not None:
        acl_match_dict['in_port'] = port_num
    if vlan_vid is not None:
        acl_match_dict['vlan_vid'] = valve_of.vid_present(vlan_vid)
    try:
        acl_match = valve_of.match_from_dict(acl_match_dict)
    except TypeError:
        raise InvalidConfigError('invalid type in ACL')
    if acl_act:
        acl_inst.append(valve_of.apply_actions(acl_act))
    return (acl_match, acl_inst, acl_cookie, acl_ofmsgs)
Exemplo n.º 41
0
 def mirror_actions(self):
     """Return OF actions to mirror this port."""
     if self.mirror is not None:
         return [valve_of.output_port(mirror_port) for mirror_port in self.mirror]
     return []
Exemplo n.º 42
0
def build_acl_entry(acl_table, rule_conf, meters,
                    acl_allow_inst, acl_force_port_vlan_inst,
                    port_num=None, vlan_vid=None):
    """Build flow/groupmods for one ACL rule entry."""
    acl_inst = []
    acl_act = []
    acl_match_dict = {}
    acl_ofmsgs = []
    acl_cookie = None
    allow_inst = acl_allow_inst

    for attrib, attrib_value in rule_conf.items():
        if attrib == 'in_port':
            continue
        if attrib == 'cookie':
            acl_cookie = attrib_value
            continue
        if attrib == 'description':
            continue
        if attrib == 'actions':
            allow = False
            allow_specified = False
            if 'allow' in attrib_value:
                allow_specified = True
                if attrib_value['allow'] == 1:
                    allow = True
            if 'force_port_vlan' in attrib_value:
                if attrib_value['force_port_vlan'] == 1:
                    allow_inst = acl_force_port_vlan_inst
            if 'meter' in attrib_value:
                meter_name = attrib_value['meter']
                acl_inst.append(valve_of.apply_meter(meters[meter_name].meter_id))
            if 'mirror' in attrib_value:
                port_no = attrib_value['mirror']
                acl_act.append(valve_of.output_port(port_no))
                if not allow_specified:
                    allow = True
            if 'output' in attrib_value:
                output_port, output_actions, output_ofmsgs = build_output_actions(
                    acl_table, attrib_value['output'])
                acl_act.extend(output_actions)
                acl_ofmsgs.extend(output_ofmsgs)

                # if port specified, output packet now and exit pipeline.
                if not allow and output_port is not None:
                    continue

            if allow:
                acl_inst.extend(allow_inst)
        else:
            acl_match_dict[attrib] = attrib_value
    if port_num is not None:
        acl_match_dict['in_port'] = port_num
    if vlan_vid is not None:
        acl_match_dict['vlan_vid'] = valve_of.vid_present(vlan_vid)
    try:
        acl_match = valve_of.match_from_dict(acl_match_dict)
    except TypeError:
        raise InvalidConfigError('invalid type in ACL')
    if acl_act:
        acl_inst.append(valve_of.apply_actions(acl_act))
    return (acl_match, acl_inst, acl_cookie, acl_ofmsgs)