def test_acl_protocol_and_ports_for_ipv6_icmp_protocol(self): sg_rule = {'port_range_min': None, 'port_range_max': None} icmp = 'icmp6' expected_match = ' && icmp6' sg_rule['protocol'] = const.PROTO_NAME_ICMP match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule['protocol'] = str(const.PROTO_NUM_ICMP) match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule['protocol'] = const.PROTO_NAME_IPV6_ICMP match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule['protocol'] = const.PROTO_NAME_IPV6_ICMP_LEGACY match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule['protocol'] = str(const.PROTO_NUM_IPV6_ICMP) match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match)
def test_acl_protocol_and_ports_for_icmp4_and_icmp6_port_range(self): match_list = [ (None, None, ' && icmp4'), (0, None, ' && icmp4 && icmp4.type == 0'), (0, 0, ' && icmp4 && icmp4.type == 0 && icmp4.code == 0'), (0, 5, ' && icmp4 && icmp4.type == 0 && icmp4.code == 5') ] v6_match_list = [ (None, None, ' && icmp6'), (133, None, ' && icmp6 && icmp6.type == 133'), (1, 1, ' && icmp6 && icmp6.type == 1 && icmp6.code == 1'), (138, 1, ' && icmp6 && icmp6.type == 138 && icmp6.code == 1') ] sg_rule = {'protocol': const.PROTO_NAME_ICMP} icmp = 'icmp4' for pmin, pmax, expected_match in match_list: sg_rule['port_range_min'] = pmin sg_rule['port_range_max'] = pmax match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule = {'protocol': const.PROTO_NAME_IPV6_ICMP} icmp = 'icmp6' for pmin, pmax, expected_match in v6_match_list: sg_rule['port_range_min'] = pmin sg_rule['port_range_max'] = pmax match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match)
def test_acl_protocol_and_ports_for_icmp4_and_icmp6_port_range(self): match_list = [ (None, None, ' && icmp4'), (0, None, ' && icmp4 && icmp4.type == 0'), (0, 0, ' && icmp4 && icmp4.type == 0 && icmp4.code == 0'), (0, 5, ' && icmp4 && icmp4.type == 0 && icmp4.code == 5')] v6_match_list = [ (None, None, ' && icmp6'), (133, None, ' && icmp6 && icmp6.type == 133'), (1, 1, ' && icmp6 && icmp6.type == 1 && icmp6.code == 1'), (138, 1, ' && icmp6 && icmp6.type == 138 && icmp6.code == 1')] sg_rule = {'protocol': const.PROTO_NAME_ICMP} icmp = 'icmp4' for pmin, pmax, expected_match in match_list: sg_rule['port_range_min'] = pmin sg_rule['port_range_max'] = pmax match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match) sg_rule = {'protocol': const.PROTO_NAME_IPV6_ICMP} icmp = 'icmp6' for pmin, pmax, expected_match in v6_match_list: sg_rule['port_range_min'] = pmin sg_rule['port_range_max'] = pmax match = ovn_acl.acl_protocol_and_ports(sg_rule, icmp) self.assertEqual(expected_match, match)
def test_acl_protocol_and_ports_for_tcp_and_udp_number(self): sg_rule = {'port_range_min': None, 'port_range_max': None} sg_rule['protocol'] = str(const.PROTO_NUM_TCP) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && tcp', match) sg_rule['protocol'] = str(const.PROTO_NUM_UDP) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && udp', match)
def test_acl_protocol_and_ports_for_tcp_udp_and_sctp_number_range(self): sg_rule = {'port_range_min': 21, 'port_range_max': 23} sg_rule['protocol'] = str(const.PROTO_NUM_TCP) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && tcp && tcp.dst >= 21 && tcp.dst <= 23', match) sg_rule['protocol'] = str(const.PROTO_NUM_UDP) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && udp && udp.dst >= 21 && udp.dst <= 23', match) sg_rule['protocol'] = str(const.PROTO_NUM_SCTP) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && sctp && sctp.dst >= 21 && sctp.dst <= 23', match)
def _add_sg_rule_acl_for_port(self, admin_context, port, r, sg_ports_cache, subnet_cache): # Update the match based on which direction this rule is for (ingress # or egress). match, remote_portdir = ovn_acl.acl_direction(r, port) # Update the match for IPv4 vs IPv6. ip_match, ip_version, icmp = ovn_acl.acl_ethertype(r) match += ip_match # Update the match if an IPv4 or IPv6 prefix was specified. match += ovn_acl.acl_remote_ip_prefix(r, ip_version) group_match, empty_match = self._acl_remote_group_id( admin_context, r, sg_ports_cache, subnet_cache, port, remote_portdir, ip_version) if empty_match: # If there are no other ports on this security group, then this # rule can never match, so no ACL row will be created for this # rule. return None match += group_match # Update the match for the protocol (tcp, udp, icmp) and port/type # range if specified. match += ovn_acl.acl_protocol_and_ports(r, icmp) # Finally, create the ACL entry for the direction specified. return ovn_acl.add_sg_rule_acl_for_port(port, r, match)
def _add_sg_rule_acl_for_port(self, admin_context, port, r, sg_ports_cache, subnet_cache): # Update the match based on which direction this rule is for (ingress # or egress). match, remote_portdir = ovn_acl.acl_direction(r, port) # Update the match for IPv4 vs IPv6. ip_match, ip_version, icmp = ovn_acl.acl_ethertype(r) match += ip_match # Update the match if an IPv4 or IPv6 prefix was specified. match += ovn_acl.acl_remote_ip_prefix(r, ip_version) group_match, empty_match = self._acl_remote_group_id(admin_context, r, sg_ports_cache, subnet_cache, port, remote_portdir, ip_version) if empty_match: # If there are no other ports on this security group, then this # rule can never match, so no ACL row will be created for this # rule. return None match += group_match # Update the match for the protocol (tcp, udp, icmp) and port/type # range if specified. match += ovn_acl.acl_protocol_and_ports(r, icmp) # Finally, create the ACL entry for the direction specified. return ovn_acl.add_sg_rule_acl_for_port(port, r, match)
def test_acl_protocol_and_ports_protocol_range(self): sg_rule = {'port_range_min': None, 'port_range_max': None} # For more common protocols such as TCP, UDP and ICMP, we # prefer to use the protocol name in the match string instead of # the protocol number (e.g: the word "tcp" instead of "ip.proto # == 6"). This improves the readability/debbugability when # troubleshooting the ACLs skip_protos = (const.PROTO_NUM_TCP, const.PROTO_NUM_UDP, const.PROTO_NUM_SCTP, const.PROTO_NUM_ICMP, const.PROTO_NUM_IPV6_ICMP) for proto in range(256): if proto in skip_protos: continue sg_rule['protocol'] = str(proto) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && ip.proto == %s' % proto, match)
def test_acl_protocol_and_ports_name_to_number(self): sg_rule = {'port_range_min': None, 'port_range_max': None} sg_rule['protocol'] = str(const.PROTO_NAME_OSPF) match = ovn_acl.acl_protocol_and_ports(sg_rule, None) self.assertEqual(' && ip.proto == 89', match)