Пример #1
0
 def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip,
                            faucet_vip_host):
     learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen
     ofmsgs = []
     ofmsgs.append(
         self.eth_src_table.flowmod(
             self.eth_src_table.match(eth_type=self.ETH_TYPE,
                                      eth_dst=vlan.faucet_mac,
                                      vlan=vlan),
             priority=self.route_priority,
             inst=[valve_of.goto_table(self.fib_table)]))
     ofmsgs.append(
         self.fib_table.flowmod(self.fib_table.match(
             eth_type=self.ETH_TYPE, vlan=vlan, nw_dst=faucet_vip_host),
                                priority=priority,
                                inst=[valve_of.goto_table(self.vip_table)]))
     if self.proactive_learn:
         for routed_vlan in self._routed_vlans(vlan):
             ofmsgs.append(
                 self.fib_table.flowmod(
                     self.fib_table.match(eth_type=self.ETH_TYPE,
                                          vlan=routed_vlan,
                                          nw_dst=faucet_vip),
                     priority=learn_connected_priority,
                     inst=[valve_of.goto_table(self.vip_table)]))
         ofmsgs.append(
             self.vip_table.flowcontroller(
                 self.vip_table.match(eth_type=self.ETH_TYPE),
                 priority=priority - 1,
                 max_len=self.MAX_LEN))
     return ofmsgs
Пример #2
0
 def build_acl(acl, vid=None):
     """Check that ACL can be built from config and mark mirror destinations."""
     if acl.rules:
         null_dp = namedtuple('null_dp', 'ofproto')
         null_dp.ofproto = valve_of.ofp
         try:
             ofmsgs = valve_acl.build_acl_ofmsgs(
                 [acl],
                 self.wildcard_table,
                 valve_of.goto_table(self.wildcard_table),
                 valve_of.goto_table(self.wildcard_table),
                 2**16 - 1,
                 self.meters,
                 acl.exact_match,
                 vlan_vid=vid)
             assert ofmsgs
             for ofmsg in ofmsgs:
                 ofmsg.datapath = null_dp
                 ofmsg.set_xid(0)
                 ofmsg.serialize()
         except (AddrFormatError, KeyError, ValueError) as err:
             raise InvalidConfigError(err)
         for port_no in mirror_destinations:
             port = self.ports[port_no]
             port.output_only = True
Пример #3
0
 def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host):
     learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen
     faucet_mac = vlan.faucet_mac
     insts = [valve_of.goto_table(self.fib_table)]
     if self._global_routing():
         vlan_mac = valve_packet.int_in_mac(faucet_mac, vlan.vid)
         insts = [valve_of.apply_actions([
             valve_of.set_eth_dst(vlan_mac),
             valve_of.set_vlan_vid(self.global_vlan.vid)])] + insts
     ofmsgs = []
     ofmsgs.append(self.eth_src_table.flowmod(
         self.eth_src_table.match(eth_type=self.ETH_TYPE, eth_dst=faucet_mac, vlan=vlan),
         priority=self.route_priority,
         inst=insts))
     routed_vlans = self._routed_vlans(vlan)
     if self._global_routing():
         vlan = self.global_vlan
     ofmsgs.append(self.fib_table.flowmod(
         self._route_match(vlan, faucet_vip_host),
         priority=priority,
         inst=[valve_of.goto_table(self.vip_table)]))
     if self.proactive_learn and not faucet_vip.ip.is_link_local:
         for routed_vlan in routed_vlans:
             ofmsgs.append(self.fib_table.flowmod(
                 self._route_match(routed_vlan, faucet_vip),
                 priority=learn_connected_priority,
                 inst=[valve_of.goto_table(self.vip_table)]))
         ofmsgs.append(self.vip_table.flowcontroller(
             self.vip_table.match(eth_type=self.ETH_TYPE),
             priority=priority-1,
             max_len=self.MAX_LEN))
     return ofmsgs
Пример #4
0
 def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host):
     ofmsgs = []
     ofmsgs.append(
         self.eth_src_table.flowmod(
             self.eth_src_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP,
                                      vlan=vlan),
             priority=priority,
             inst=[valve_of.goto_table(self.vip_table)]))
     ofmsgs.append(
         self.vip_table.flowmod(
             self.vip_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP),
             priority=priority,
             inst=[valve_of.goto_table(self.eth_dst_table)]))
     priority += 1
     ofmsgs.append(
         self.vip_table.flowmod(
             self.vip_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP,
                                  eth_dst=valve_of.mac.BROADCAST_STR),
             priority=priority,
             inst=[valve_of.goto_table(self.flood_table)]))
     priority += 1
     ofmsgs.append(
         self.vip_table.flowcontroller(self.vip_table.match(
             eth_type=valve_of.ether.ETH_TYPE_ARP, nw_dst=faucet_vip_host),
                                       priority=priority,
                                       max_len=self.MAX_LEN))
     return ofmsgs
Пример #5
0
 def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host):
     faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast(
         valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip))
     controller_and_flood = [
         valve_of.apply_actions([valve_of.output_controller()]),
         valve_of.goto_table(self.flood_table)
     ]
     ofmsgs = []
     ofmsgs.append(
         self.vip_table.flowcontroller(self.vip_table.match(
             eth_type=self.ETH_TYPE,
             nw_proto=valve_of.inet.IPPROTO_ICMPV6,
             icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST),
                                       priority=priority,
                                       max_len=self.MAX_LEN))
     # IPv6 ND for FAUCET VIP
     ofmsgs.append(
         self.eth_src_table.flowmod(
             self.eth_src_table.match(eth_type=self.ETH_TYPE,
                                      eth_dst=faucet_vip_host_nd_mcast,
                                      vlan=vlan),
             priority=priority,
             inst=[valve_of.goto_table(self.vip_table)]))
     ofmsgs.append(
         self.vip_table.flowmod(self.vip_table.match(
             eth_type=self.ETH_TYPE,
             nw_proto=valve_of.inet.IPPROTO_ICMPV6,
             icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT),
                                priority=priority,
                                inst=controller_and_flood))
     # IPv6 ND for connected hosts.
     ofmsgs.append(
         self.vip_table.flowcontroller(self.vip_table.match(
             eth_type=self.ETH_TYPE,
             eth_dst=vlan.faucet_mac,
             nw_proto=valve_of.inet.IPPROTO_ICMPV6,
             icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT),
                                       priority=priority,
                                       max_len=self.MAX_LEN))
     if faucet_vip.ip in valve_packet.IPV6_LINK_LOCAL:
         ofmsgs.append(
             self.eth_src_table.flowmod(
                 self.eth_src_table.match(
                     eth_type=self.ETH_TYPE,
                     eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST,
                     vlan=vlan),
                 priority=priority,
                 inst=[valve_of.goto_table(self.vip_table)]))
         ofmsgs.append(
             self.vip_table.flowmod(self.vip_table.match(
                 eth_type=self.ETH_TYPE,
                 nw_proto=valve_of.inet.IPPROTO_ICMPV6,
                 icmpv6_type=icmpv6.ND_ROUTER_SOLICIT),
                                    priority=priority,
                                    inst=controller_and_flood))
     return ofmsgs
Пример #6
0
def build_acl_port_of_msgs(acl, vid, port_num, acl_table, goto_table, priority):
    """A Helper function for building Openflow Mod Messages for Port ACLs"""
    ofmsgs = None
    if acl.rules:
        ofmsgs = build_acl_ofmsgs(
            [acl], acl_table,
            [valve_of.goto_table(goto_table)],
            [valve_of.goto_table(goto_table)],
            priority, acl.meter, acl.exact_match,
            vlan_vid=vid, port_num=port_num)
    return ofmsgs
Пример #7
0
def build_acl_port_of_msgs(acl, vid, port_num, acl_table, goto_table):
    '''A Helper function for building Openflow Mod Messages for Port ACLs'''
    ofmsgs = None
    if acl.rules:
        ofmsgs = build_acl_ofmsgs(
            [acl], acl_table,
            [valve_of.goto_table(goto_table)],
            [valve_of.goto_table(goto_table)],
            2 ** 16 - 1, acl.meter, acl.exact_match,
            vlan_vid=vid, port_num=port_num)
    return ofmsgs
Пример #8
0
 def add_faucet_vip(self, vlan, faucet_vip):
     ofmsgs = []
     max_prefixlen = faucet_vip.ip.max_prefixlen
     faucet_vip_host = self._host_from_faucet_vip(faucet_vip)
     priority = self.route_priority + max_prefixlen
     faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast(
         valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip))
     ofmsgs.append(self.valve_flowmod(
         self.eth_src_table,
         self.valve_in_match(
             self.eth_src_table,
             eth_type=self._eth_type(),
             vlan=vlan,
             nw_proto=inet.IPPROTO_ICMPV6,
             eth_dst=faucet_vip_host_nd_mcast,
             icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT),
         priority=priority,
         inst=[
             valve_of.apply_actions([valve_of.output_controller()]),
             valve_of.goto_table(self.flood_table)]))
     ofmsgs.append(self.valve_flowmod(
         self.eth_src_table,
         self.valve_in_match(
             self.eth_src_table,
             eth_type=self._eth_type(),
             eth_dst=self.faucet_mac,
             vlan=vlan,
             nw_proto=inet.IPPROTO_ICMPV6,
             icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT),
         priority=priority,
         inst=[valve_of.apply_actions([valve_of.output_controller()])]))
     # Initialize IPv6 FIB
     ofmsgs.append(self.valve_flowmod(
         self.eth_src_table,
         self.valve_in_match(
             self.eth_src_table,
             eth_type=self._eth_type(),
             eth_dst=self.faucet_mac,
             vlan=vlan),
         priority=self.route_priority,
         inst=[valve_of.goto_table(self.fib_table)]))
     ofmsgs.append(self.valve_flowcontroller(
         self.fib_table,
         self.valve_in_match(
             self.fib_table,
             eth_type=self._eth_type(),
             vlan=vlan,
             nw_proto=inet.IPPROTO_ICMPV6,
             nw_dst=faucet_vip_host,
             icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST),
         priority=priority))
     return ofmsgs
Пример #9
0
    def build(self, meters, vid, port_num):
        """Check that ACL can be built from config."""
        class NullRyuDatapath:
            """Placeholder Ryu Datapath."""
            ofproto = valve_of.ofp

        self.matches = {}
        self.set_fields = set()
        self.meter = False
        if self.rules:
            try:
                ofmsgs = valve_acl.build_acl_ofmsgs(
                    [self],
                    wildcard_table,
                    valve_of.goto_table(wildcard_table),
                    valve_of.goto_table(wildcard_table),
                    2**16 - 1,
                    meters,
                    self.exact_match,
                    vlan_vid=vid,
                    port_num=port_num)
            except (netaddr.core.AddrFormatError, KeyError, ValueError) as err:
                raise InvalidConfigError(err)
            test_config_condition(not ofmsgs, 'OF messages is empty')
            for ofmsg in ofmsgs:
                ofmsg.datapath = NullRyuDatapath()
                ofmsg.set_xid(0)
                try:
                    ofmsg.serialize()
                except (KeyError, ValueError) as err:
                    raise InvalidConfigError(err)
                except Exception as err:
                    print(ofmsg)
                    raise err
                if valve_of.is_flowmod(ofmsg):
                    apply_actions = []
                    for inst in ofmsg.instructions:
                        if valve_of.is_apply_actions(inst):
                            apply_actions.extend(inst.actions)
                        elif valve_of.is_meter(inst):
                            self.meter = True
                    for action in apply_actions:
                        if valve_of.is_set_field(action):
                            self.set_fields.add(action.key)
                    for match, value in list(ofmsg.match.items()):
                        has_mask = isinstance(value, (tuple, list))
                        if has_mask or match not in self.matches:
                            self.matches[match] = has_mask
        return (self.matches, self.set_fields, self.meter)
Пример #10
0
 def _add_vlan_flood_flow(self):
     """Add a flow to flood packets for unknown destinations."""
     return [
         self.dp.tables['eth_dst'].flowmod(
             priority=self.dp.low_priority,
             inst=[valve_of.goto_table(self.dp.tables['flood'])])
     ]
Пример #11
0
 def _add_controller_learn_flow(self):
     """Add a flow for controller to learn/add flows for destinations."""
     return [
         self.dp.tables['eth_src'].flowcontroller(
             priority=self.dp.low_priority,
             inst=[valve_of.goto_table(self.dp.tables['eth_dst'])])
     ]
Пример #12
0
 def add_faucet_vip(self, vlan, faucet_vip):
     ofmsgs = []
     max_prefixlen = faucet_vip.ip.max_prefixlen
     faucet_vip_host = self._host_from_faucet_vip(faucet_vip)
     priority = self.route_priority + max_prefixlen
     ofmsgs.append(self.valve_flowmod(
         self.eth_src_table,
         self.valve_in_match(
             self.eth_src_table,
             eth_type=ether.ETH_TYPE_ARP,
             nw_dst=faucet_vip_host,
             vlan=vlan),
         priority=priority,
         inst=[valve_of.apply_actions([valve_of.output_controller()])]))
     # Initialize IPv4 FIB
     ofmsgs.append(self.valve_flowmod(
         self.eth_src_table,
         self.valve_in_match(
             self.eth_src_table,
             eth_type=self._eth_type(),
             eth_dst=self.faucet_mac,
             vlan=vlan),
         priority=self.route_priority,
         inst=[valve_of.goto_table(self.fib_table)]))
     ofmsgs.append(self.valve_flowcontroller(
         self.fib_table,
         self.valve_in_match(
             self.fib_table,
             vlan=vlan,
             eth_type=self._eth_type(),
             nw_proto=inet.IPPROTO_ICMP,
             nw_src=faucet_vip,
             nw_dst=faucet_vip_host),
         priority=priority))
     return ofmsgs
Пример #13
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
Пример #14
0
 def _port_add_vlan_tagged(self, port, vlan, forwarding_table, mirror_act):
     vlan_inst = [
         valve_of.goto_table(forwarding_table)
     ]
     if mirror_act:
         vlan_inst = [valve_of.apply_actions(mirror_act)] + vlan_inst
     return self._port_add_vlan_rules(port, vlan, vlan_inst)
Пример #15
0
 def build_flood_rules(self, vlan, modify=False):
     """Add flows to flood packets to unknown destinations on a VLAN."""
     command = valve_of.ofp.OFPFC_ADD
     if modify:
         command = valve_of.ofp.OFPFC_MODIFY_STRICT
     # TODO: group tables for stacking
     ofmsgs = self._build_multiout_flood_rules(vlan, command)
     # Because stacking uses reflected broadcasts from the root,
     # don't try to learn broadcast sources from stacking ports.
     for port in self.stack_ports:
         ofmsgs.append(self.eth_src_table.flowdrop(
             self.eth_src_table.match(
                 in_port=port.number,
                 vlan=vlan,
                 eth_dst=valve_packet.BRIDGE_GROUP_ADDRESS,
                 eth_dst_mask=valve_packet.BRIDGE_GROUP_MASK),
             priority=self.bypass_priority+1))
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst:
             continue
         for port in self.stack_ports:
             match = self.eth_src_table.match(
                 in_port=port.number,
                 vlan=vlan,
                 eth_dst=eth_dst,
                 eth_dst_mask=eth_dst_mask)
             ofmsgs.append(self.eth_src_table.flowmod(
                 match=match,
                 command=command,
                 inst=[valve_of.goto_table(self.flood_table)],
                 priority=self.bypass_priority))
     return ofmsgs
Пример #16
0
    def build(self, meters, vid, port_num):
        """Check that ACL can be built from config."""

        class NullRyuDatapath:
            """Placeholder Ryu Datapath."""
            ofproto = valve_of.ofp

        self.matches = {}
        self.set_fields = set()
        self.meter = False
        if self.rules:
            try:
                ofmsgs = valve_acl.build_acl_ofmsgs(
                    [self], wildcard_table,
                    [valve_of.goto_table(wildcard_table)],
                    [valve_of.goto_table(wildcard_table)],
                    2**16-1, meters, self.exact_match,
                    vlan_vid=vid, port_num=port_num)
            except (netaddr.core.AddrFormatError, KeyError, ValueError) as err:
                raise InvalidConfigError(err)
            test_config_condition(not ofmsgs, 'OF messages is empty')
            for ofmsg in ofmsgs:
                ofmsg.datapath = NullRyuDatapath()
                ofmsg.set_xid(0)
                try:
                    ofmsg.serialize()
                except (KeyError, ValueError) as err:
                    raise InvalidConfigError(err)
                except Exception as err:
                    print(ofmsg)
                    raise err
                if valve_of.is_flowmod(ofmsg):
                    apply_actions = []
                    for inst in ofmsg.instructions:
                        if valve_of.is_apply_actions(inst):
                            apply_actions.extend(inst.actions)
                        elif valve_of.is_meter(inst):
                            self.meter = True
                    for action in apply_actions:
                        if valve_of.is_set_field(action):
                            self.set_fields.add(action.key)
                    for match, value in ofmsg.match.items():
                        has_mask = isinstance(value, (tuple, list))
                        if has_mask or match not in self.matches:
                            self.matches[match] = has_mask
        return (self.matches, self.set_fields, self.meter)
Пример #17
0
 def build_acl(acl, vid):
     """Check that ACL can be built from config and mark mirror destinations."""
     matches = {}
     set_fields = set()
     meter = False
     if acl.rules:
         try:
             ofmsgs = valve_acl.build_acl_ofmsgs(
                 [acl],
                 self.wildcard_table,
                 valve_of.goto_table(self.wildcard_table),
                 valve_of.goto_table(self.wildcard_table),
                 2**16 - 1,
                 self.meters,
                 acl.exact_match,
                 vlan_vid=vid)
         except (netaddr.core.AddrFormatError, KeyError,
                 ValueError) as err:
             raise InvalidConfigError(err)
         test_config_condition(not ofmsgs, 'OF messages is empty')
         for ofmsg in ofmsgs:
             ofmsg.datapath = NullRyuDatapath()
             ofmsg.set_xid(0)
             try:
                 ofmsg.serialize()
             except (KeyError, ValueError) as err:
                 raise InvalidConfigError(err)
             if valve_of.is_flowmod(ofmsg):
                 apply_actions = []
                 for inst in ofmsg.instructions:
                     if valve_of.is_apply_actions(inst):
                         apply_actions.extend(inst.actions)
                     elif valve_of.is_meter(inst):
                         meter = True
                 for action in apply_actions:
                     if valve_of.is_set_field(action):
                         set_fields.add(action.key)
                 for match, value in list(ofmsg.match.items()):
                     has_mask = isinstance(value, (tuple, list))
                     if has_mask or match not in matches:
                         matches[match] = has_mask
         for port_no in mirror_destinations:
             port = self.ports[port_no]
             port.output_only = True
     return (matches, set_fields, meter)
Пример #18
0
 def _port_add_vlan_untagged(self, port, vlan, forwarding_table, mirror_act):
     push_vlan_act = mirror_act + valve_of.push_vlan_act(vlan.vid)
     push_vlan_inst = [
         valve_of.apply_actions(push_vlan_act),
         valve_of.goto_table(forwarding_table)
     ]
     null_vlan = namedtuple('null_vlan', 'vid')
     null_vlan.vid = valve_of.ofp.OFPVID_NONE
     return self._port_add_vlan_rules(port, null_vlan, push_vlan_inst)
Пример #19
0
 def build_acl(acl, vid=None):
     """Check that ACL can be built from config."""
     assert valve_acl.build_acl_ofmsgs([acl],
                                       self.wildcard_table,
                                       valve_of.goto_table(
                                           self.wildcard_table),
                                       2**16,
                                       self.meters,
                                       vlan_vid=vid)
Пример #20
0
 def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host):
     ofmsgs = super(ValveIPv6RouteManager, self)._add_faucet_fib_to_vip(
         vlan, priority, faucet_vip, faucet_vip_host)
     faucet_vip_broadcast = ipaddress.IPv6Interface(faucet_vip.network.broadcast_address)
     ofmsgs.append(self.fib_table.flowmod(
         self.fib_table.match(eth_type=self.ETH_TYPE, vlan=vlan, nw_dst=faucet_vip_broadcast),
         priority=priority,
         inst=[valve_of.goto_table(self.vip_table)]))
     return ofmsgs
Пример #21
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.
        ofmsgs.append(
            self.eth_src_table.flowmod(
                self.eth_src_table.match(in_port=port.number,
                                         vlan=vlan,
                                         eth_src=eth_src),
                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
Пример #22
0
 def _vlan_add_acl(self, vlan):
     ofmsgs = []
     if vlan.acl_in:
         acl_table = self.dp.tables['vlan_acl']
         acl_allow_inst = valve_of.goto_table(self.dp.tables['eth_src'])
         ofmsgs = valve_acl.build_acl_ofmsgs(
             [vlan.acl_in], acl_table, acl_allow_inst,
             self.dp.highest_priority, self.dp.meters,
             vlan.acl_in.exact_match, vlan_vid=vlan.vid)
     return ofmsgs
Пример #23
0
 def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip,
                            faucet_vip_host):
     learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen
     faucet_mac = vlan.faucet_mac
     insts = [valve_of.goto_table(self.fib_table)]
     if self._global_routing():
         vlan_mac = faucet_mac.split(':')[:4] + [
             '%x' % (vlan.vid >> 8),
             '%x' % (vlan.vid & 0xff)
         ]
         vlan_mac = ':'.join(vlan_mac)
         insts = [
             valve_of.apply_actions([
                 valve_of.set_eth_dst(vlan_mac),
                 valve_of.set_vlan_vid(self.global_vlan.vid)
             ])
         ] + insts
     ofmsgs = []
     ofmsgs.append(
         self.eth_src_table.flowmod(self.eth_src_table.match(
             eth_type=self.ETH_TYPE, eth_dst=faucet_mac, vlan=vlan),
                                    priority=self.route_priority,
                                    inst=insts))
     routed_vlans = self._routed_vlans(vlan)
     if self._global_routing():
         vlan = self.global_vlan
     ofmsgs.append(
         self.fib_table.flowmod(self._route_match(vlan, faucet_vip_host),
                                priority=priority,
                                inst=[valve_of.goto_table(self.vip_table)]))
     if self.proactive_learn and faucet_vip.ip not in self.LINK_LOCAL:
         for routed_vlan in routed_vlans:
             ofmsgs.append(
                 self.fib_table.flowmod(
                     self._route_match(routed_vlan, faucet_vip),
                     priority=learn_connected_priority,
                     inst=[valve_of.goto_table(self.vip_table)]))
         ofmsgs.append(
             self.vip_table.flowcontroller(
                 self.vip_table.match(eth_type=self.ETH_TYPE),
                 priority=priority - 1,
                 max_len=self.MAX_LEN))
     return ofmsgs
Пример #24
0
 def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host):
     ofmsgs = super(ValveIPv6RouteManager, self)._add_faucet_fib_to_vip(
         vlan, priority, faucet_vip, faucet_vip_host)
     faucet_vip_broadcast = ipaddress.IPv6Interface(faucet_vip.network.broadcast_address)
     if self._global_routing():
         vlan = self.global_vlan
     ofmsgs.append(self.fib_table.flowmod(
         self._route_match(vlan, faucet_vip_broadcast),
         priority=priority,
         inst=[valve_of.goto_table(self.vip_table)]))
     return ofmsgs
Пример #25
0
 def build_acl(acl, vid=None):
     """Check that ACL can be built from config and mark mirror destinations."""
     if acl.rules:
         try:
             assert valve_acl.build_acl_ofmsgs(
                 [acl], self.wildcard_table,
                 valve_of.goto_table(self.wildcard_table),
                 2**16, self.meters, acl.exact_match,
                 vlan_vid=vid)
         except (AddrFormatError, ValueError) as err:
             raise InvalidConfigError(err)
         for port_no in acl.mirror_destinations:
             port = self.ports[port_no]
             port.mirror_destination = True
Пример #26
0
 def build_acl(acl, vid=None):
     """Check that ACL can be built from config and mark mirror destinations."""
     if acl.rules:
         try:
             ofmsgs = valve_acl.build_acl_ofmsgs(
                 [acl],
                 self.wildcard_table,
                 valve_of.goto_table(self.wildcard_table),
                 valve_of.goto_table(self.wildcard_table),
                 2**16 - 1,
                 self.meters,
                 acl.exact_match,
                 vlan_vid=vid)
             test_config_condition(not ofmsgs,
                                   'of messages is empty')
             for ofmsg in ofmsgs:
                 ofmsg.datapath = NullRyuDatapath()
                 ofmsg.set_xid(0)
                 ofmsg.serialize()
         except (AddrFormatError, KeyError, ValueError) as err:
             raise InvalidConfigError(err)
         for port_no in mirror_destinations:
             port = self.ports[port_no]
             port.output_only = True
Пример #27
0
 def _port_add_acl(self, port, cold_start=False):
     ofmsgs = []
     acl_table = self.dp.tables['port_acl']
     in_port_match = acl_table.match(in_port=port.number)
     if cold_start:
         ofmsgs.extend(acl_table.flowdel(in_port_match))
     acl_allow_inst = valve_of.goto_table(self.dp.tables['vlan'])
     if port.acl_in:
         ofmsgs.extend(valve_acl.build_acl_ofmsgs(
             [port.acl_in], acl_table, acl_allow_inst,
             self.dp.highest_priority, self.dp.meters,
             port.acl_in.exact_match, port_num=port.number))
     else:
         ofmsgs.append(acl_table.flowmod(
             in_port_match,
             priority=self.dp.highest_priority,
             inst=[acl_allow_inst]))
     return ofmsgs
Пример #28
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
Пример #29
0
 def goto_miss(self, next_table):
     """Add miss goto table instruction."""
     assert next_table.name == self.table_config.miss_goto, (
         '%s not configured as miss table in %s' % (
             next_table.name, self.name))
     return valve_of.goto_table(next_table)
Пример #30
0
 def goto_this(self):
     return valve_of.goto_table(self)
Пример #31
0
 def goto(self, next_table):
     """Add goto next table instruction."""
     assert next_table.name in self.table_config.next_tables, (
         '%s not configured as next table in %s' %
         (next_table.name, self.name))
     return valve_of.goto_table(next_table)
Пример #32
0
 def goto_this(self):
     return valve_of.goto_table(self)
Пример #33
0
    def ports_add(self, port_nums, cold_start=False):
        """Handle the addition of ports.

        Args:
            port_num (list): list of port numbers.
            cold_start (bool): True if configuring datapath from scratch.
        Returns:
            list: OpenFlow messages, if any.
        """
        ofmsgs = []
        vlans_with_ports_added = set()
        eth_src_table = self.dp.tables['eth_src']
        vlan_table = self.dp.tables['vlan']

        for port_num in port_nums:
            if port_num not in self.dp.ports:
                self.logger.info(
                    'Ignoring port:%u not present in configuration file' %
                    port_num)
                continue

            port = self.dp.ports[port_num]
            port.dyn_phys_up = True
            self.logger.info('%s up, configuring' % port)

            if not port.running():
                continue

            # Port is a mirror destination; drop all input packets
            if port.mirror_destination:
                ofmsgs.append(
                    vlan_table.flowdrop(
                        match=vlan_table.match(in_port=port_num),
                        priority=self.dp.highest_priority))
                continue

            # Port has LACP processing enabled.
            if port.lacp:
                ofmsgs.extend(self.lacp_down(port))

            # Add ACL if any.
            acl_ofmsgs = self._port_add_acl(port)
            ofmsgs.extend(acl_ofmsgs)

            port_vlans = port.vlans()

            # If this is a stacking port, accept all VLANs (came from another FAUCET)
            if port.stack is not None:
                ofmsgs.append(
                    vlan_table.flowmod(
                        match=vlan_table.match(in_port=port_num),
                        priority=self.dp.low_priority,
                        inst=[valve_of.goto_table(eth_src_table)]))
                port_vlans = list(self.dp.vlans.values())
            else:
                mirror_act = []
                # Add mirroring if any
                if port.mirror:
                    mirror_act = [valve_of.output_port(port.mirror)]
                # Add port/to VLAN rules.
                ofmsgs.extend(self._port_add_vlans(port, mirror_act))

            for vlan in port_vlans:
                vlans_with_ports_added.add(vlan)

        # Only update flooding rules if not cold starting.
        if not cold_start:
            for vlan in vlans_with_ports_added:
                ofmsgs.extend(self.flood_manager.build_flood_rules(vlan))

        return ofmsgs
Пример #34
0
 def goto_miss(self, next_table):
     """Add miss goto table instruction."""
     assert next_table.name == self.table_config.miss_goto, (
         '%s not configured as miss table in %s' %
         (next_table.name, self.name))
     return valve_of.goto_table(next_table)
Пример #35
0
 def goto(self, next_table):
     """Add goto next table instruction."""
     assert next_table.name in self.table_config.next_tables, (
         '%s not configured as next table in %s' % (
             next_table.name, self.name))
     return valve_of.goto_table(next_table)