Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated):
     ofmsgs = []
     if is_updated:
         self.logger.info(
             'Updating next hop for route %s via %s (%s) on VLAN %u' %
             (ip_dst, ip_gw, eth_dst, vlan.vid))
         ofmsgs.extend(self._del_route_flows(vlan, ip_dst))
     else:
         self.logger.info('Adding new route %s via %s (%s) on VLAN %u' %
                          (ip_dst, ip_gw, eth_dst, vlan.vid))
     if self.use_group_table:
         inst = [
             valve_of.apply_actions([
                 valve_of.group_act(
                     group_id=self._group_id_from_ip_gw(vlan, ip_gw))
             ])
         ]
     else:
         inst = [
             valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)),
             valve_of.goto_table(self.eth_dst_table)
         ]
     for routed_vlan in self._routed_vlans(vlan):
         in_match = self._route_match(routed_vlan, ip_dst)
         ofmsgs.append(
             self.fib_table.flowmod(in_match,
                                    priority=self._route_priority(ip_dst),
                                    inst=inst))
     return ofmsgs
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
 def _build_group_flood_rules(self, vlan, modify, command):
     """Build flooding rules for a VLAN using groups."""
     flood_priority = self.flood_priority
     broadcast_group = self.groups.get_entry(
         vlan.vid,
         self._build_group_buckets(vlan, False))
     unicast_group = self.groups.get_entry(
         vlan.vid + valve_of.VLAN_GROUP_OFFSET,
         self._build_group_buckets(vlan, vlan.unicast_flood))
     ofmsgs = []
     if modify:
         ofmsgs.append(broadcast_group.modify())
         ofmsgs.append(unicast_group.modify())
     else:
         ofmsgs.extend(broadcast_group.add())
         ofmsgs.extend(unicast_group.add())
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst and not vlan.unicast_flood:
             continue
         group = broadcast_group
         if not eth_dst:
             group = unicast_group
         match = self.flood_table.match(
             vlan=vlan, eth_dst=eth_dst, eth_dst_mask=eth_dst_mask)
         ofmsgs.append(self.flood_table.flowmod(
             match=match,
             command=command,
             inst=[valve_of.apply_actions([valve_of.group_act(group.group_id)])],
             priority=flood_priority))
         flood_priority += 1
     return ofmsgs
Ejemplo n.º 6
0
 def _build_group_flood_rules(self, vlan, modify, command):
     """Build flooding rules for a VLAN using groups."""
     flood_priority = self.flood_priority
     broadcast_group = self.groups.get_entry(
         vlan.vid, self._build_group_buckets(vlan, False))
     unicast_group = self.groups.get_entry(
         vlan.vid + valve_of.VLAN_GROUP_OFFSET,
         self._build_group_buckets(vlan, vlan.unicast_flood))
     ofmsgs = []
     if modify:
         ofmsgs.append(broadcast_group.modify())
         ofmsgs.append(unicast_group.modify())
     else:
         ofmsgs.extend(broadcast_group.add())
         ofmsgs.extend(unicast_group.add())
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst and not vlan.unicast_flood:
             continue
         group = broadcast_group
         if not eth_dst:
             group = unicast_group
         match = self.flood_table.match(vlan=vlan,
                                        eth_dst=eth_dst,
                                        eth_dst_mask=eth_dst_mask)
         ofmsgs.append(
             self.flood_table.flowmod(
                 match=match,
                 command=command,
                 inst=[
                     valve_of.apply_actions(
                         [valve_of.group_act(group.group_id)])
                 ],
                 priority=flood_priority))
         flood_priority += 1
     return ofmsgs
Ejemplo n.º 7
0
    def _build_group_flood_rules(self, vlan, modify, command):
        """Build flooding rules for a VLAN using groups."""
        ofmsgs = []
        groups_by_unicast_eth = {}

        _, vlan_flood_acts = self._build_flood_rule_for_vlan(
            vlan, None, None, False, command)

        group_id = vlan.vid
        group = self.groups.get_entry(
            group_id, valve_of.build_group_flood_buckets(vlan_flood_acts))
        groups_by_unicast_eth[False] = group
        groups_by_unicast_eth[True] = group

        # Only configure unicast flooding group if has different output
        # actions to non unicast flooding.
        _, unicast_eth_vlan_flood_acts = self._build_flood_rule_for_vlan(
            vlan, None, None, True, command)
        unicast_eth_vlan_flood_acts, unicast_output_ports, _ = self._output_non_output_actions(
            unicast_eth_vlan_flood_acts)
        vlan_flood_acts, vlan_output_ports, _ = self._output_non_output_actions(
            vlan_flood_acts)
        if unicast_output_ports != vlan_output_ports:
            group_id += valve_of.VLAN_GROUP_OFFSET
            group = self.groups.get_entry(
                group_id,
                valve_of.build_group_flood_buckets(
                    unicast_eth_vlan_flood_acts))
            groups_by_unicast_eth[True] = group

        for group in groups_by_unicast_eth.values():
            if modify:
                ofmsgs.append(group.modify())
            else:
                ofmsgs.extend(group.add())

        for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
            if unicast_eth_dst and not vlan.unicast_flood:
                continue
            group = groups_by_unicast_eth[unicast_eth_dst]
            match = self.flood_table.match(vlan=vlan,
                                           eth_dst=eth_dst,
                                           eth_dst_mask=eth_dst_mask)
            flood_priority = self._mask_flood_priority(eth_dst_mask)
            ofmsgs.append(
                self.flood_table.flowmod(
                    match=match,
                    command=command,
                    inst=[
                        valve_of.apply_actions(
                            [valve_of.group_act(group.group_id)])
                    ],
                    priority=flood_priority))
        return ofmsgs
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
    def _build_group_flood_rules(self, vlan, modify, command):
        """Build flooding rules for a VLAN using groups."""
        ofmsgs = []
        groups_by_unicast_eth = {}

        _, vlan_flood_acts = self._build_flood_rule_for_vlan(
            vlan, None, None, False, command)

        group_id = vlan.vid
        group = self.groups.get_entry(
            group_id, valve_of.build_group_flood_buckets(vlan_flood_acts))
        groups_by_unicast_eth[False] = group
        groups_by_unicast_eth[True] = group

        # Only configure unicast flooding group if has different output
        # actions to non unicast flooding.
        _, unicast_eth_vlan_flood_acts = self._build_flood_rule_for_vlan(
            vlan, None, None, True, command)
        unicast_eth_vlan_flood_acts, unicast_output_ports, _ = self._output_non_output_actions(
            unicast_eth_vlan_flood_acts)
        vlan_flood_acts, vlan_output_ports, _ = self._output_non_output_actions(vlan_flood_acts)
        if unicast_output_ports != vlan_output_ports:
            group_id += valve_of.VLAN_GROUP_OFFSET
            group = self.groups.get_entry(
                group_id, valve_of.build_group_flood_buckets(unicast_eth_vlan_flood_acts))
            groups_by_unicast_eth[True] = group

        for group in groups_by_unicast_eth.values():
            if modify:
                ofmsgs.append(group.modify())
            else:
                ofmsgs.extend(group.add())

        for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
            if unicast_eth_dst and not vlan.unicast_flood:
                continue
            group = groups_by_unicast_eth[unicast_eth_dst]
            match = self.flood_table.match(
                vlan=vlan, eth_dst=eth_dst, eth_dst_mask=eth_dst_mask)
            flood_priority = self._mask_flood_priority(eth_dst_mask)
            ofmsgs.append(self.flood_table.flowmod(
                match=match,
                command=command,
                inst=[valve_of.apply_actions([valve_of.group_act(group.group_id)])],
                priority=flood_priority))
        return ofmsgs
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated):
     ofmsgs = []
     if self.routers:
         in_match = self.valve_in_match(
             self.fib_table, vlan=AnyVlan(),
             eth_type=self._eth_type(), nw_dst=ip_dst)
     else:
         in_match = self.valve_in_match(
             self.fib_table, vlan=vlan,
             eth_type=self._eth_type(), nw_dst=ip_dst)
     prefixlen = ipaddress.ip_network(ip_dst).prefixlen
     priority = self.route_priority + prefixlen
     if is_updated:
         self.logger.info(
             'Updating next hop for route %s via %s (%s)',
             ip_dst, ip_gw, eth_dst)
         ofmsgs.extend(self.valve_flowdel(
             self.fib_table,
             in_match,
             priority=priority))
     else:
         self.logger.info(
             'Adding new route %s via %s (%s)',
             ip_dst, ip_gw, eth_dst)
     if self.use_group_table:
         inst = [valve_of.apply_actions([valve_of.group_act(
             group_id=self.ip_gw_to_group_id[ip_gw])])]
     else:
         inst = [valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)),
                 valve_of.goto_table(self.eth_dst_table)]
     ofmsgs.append(self.valve_flowmod(
         self.fib_table,
         in_match,
         priority=priority,
         inst=inst))
     return ofmsgs
Ejemplo n.º 12
0
 def _build_group_flood_rules(self, vlan, modify, command):
     flood_priority = self.flood_priority
     broadcast_buckets = self._build_group_buckets(vlan, False)
     unicast_buckets = self._build_group_buckets(vlan, vlan.unicast_flood)
     group_id = vlan.vid
     ofmsgs = []
     group_mod_method = valve_of.groupadd
     if modify:
         group_mod_method = valve_of.groupmod
     else:
         ofmsgs.append(
             valve_of.groupdel(group_id=group_id))
         ofmsgs.append(
             valve_of.groupdel(group_id=group_id+valve_of.VLAN_GROUP_OFFSET))
     ofmsgs.append(
         group_mod_method(group_id=group_id, buckets=broadcast_buckets))
     ofmsgs.append(
         group_mod_method(group_id=group_id+valve_of.VLAN_GROUP_OFFSET,
                          buckets=unicast_buckets))
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst and not vlan.unicast_flood:
             continue
         group_id = vlan.vid
         if not eth_dst:
             group_id = group_id + valve_of.VLAN_GROUP_OFFSET
         match = self.valve_in_match(
             self.flood_table, vlan=vlan,
             eth_dst=eth_dst, eth_dst_mask=eth_dst_mask)
         ofmsgs.append(self.valve_flowmod(
             self.flood_table,
             match=match,
             command=command,
             inst=[valve_of.apply_actions([valve_of.group_act(group_id)])],
             priority=flood_priority))
         flood_priority += 1
     return ofmsgs