Merge "Fix error when using protocol number in security groups"

This commit is contained in:
Zuul
2017-12-09 06:54:38 +00:00
committed by Gerrit Code Review
3 changed files with 124 additions and 62 deletions

View File

@@ -634,18 +634,17 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
return iptables_rules return iptables_rules
def _protocol_arg(self, protocol, is_port): def _protocol_arg(self, protocol, is_port):
if not protocol: iptables_rule = []
return [] rule_protocol = n_const.IPTABLES_PROTOCOL_NAME_MAP.get(protocol,
rule_protocol = protocol protocol)
if (protocol in n_const.IPTABLES_PROTOCOL_NAME_MAP):
rule_protocol = n_const.IPTABLES_PROTOCOL_NAME_MAP[protocol]
# protocol zero is a special case and requires no '-p' # protocol zero is a special case and requires no '-p'
if rule_protocol: if rule_protocol:
iptables_rule = ['-p', rule_protocol] iptables_rule = ['-p', rule_protocol]
if (is_port and protocol in constants.IPTABLES_PROTOCOL_MAP): if (is_port and rule_protocol in constants.IPTABLES_PROTOCOL_MAP):
# iptables adds '-m protocol' when the port number is specified # iptables adds '-m protocol' when the port number is specified
iptables_rule += ['-m', constants.IPTABLES_PROTOCOL_MAP[protocol]] iptables_rule += ['-m',
constants.IPTABLES_PROTOCOL_MAP[rule_protocol]]
return iptables_rule return iptables_rule
def _port_arg(self, direction, protocol, port_range_min, port_range_max): def _port_arg(self, direction, protocol, port_range_min, port_range_max):

View File

@@ -58,64 +58,79 @@ IP_PROTOCOL_NUM_TO_NAME_MAP = {
# When using iptables-save we specify '-p {proto}', # When using iptables-save we specify '-p {proto}',
# but sometimes those values are not identical. This is a map # but sometimes those values are not identical. This is a map
# of known protocol names or numbers that require a name change. # of known protocol numbers that require a name to be used and
# This legacy mapping can go away once neutron-lib is updated. # protocol names that require a different name to be used,
IPTABLES_PROTOCOL_LEGACY_NUM_MAP = {3: 'ggp', # because that is how iptables-save will display them.
4: 'ipencap', #
5: 'st', # This is how the list was created, so there is a possibility
9: 'igp', # it will need to be updated in the future:
12: 'pup', #
20: 'hmp', # $ for num in {0..255}; do iptables -A INPUT -p $num; done
22: 'xns-idp', # $ iptables-save
27: 'rdp', #
29: 'iso-tp4', # These cases are special, and were found by inspection:
36: 'xtp',
37: 'ddp',
38: 'idpr-cmtp',
45: 'idrp',
57: 'skip',
73: 'rspf',
81: 'vmtp',
88: 'eigrp',
93: 'ax.25',
94: 'ipip',
97: 'etherip',
98: 'encap',
103: 'pim',
108: 'ipcomp',
115: 'lt2p',
124: 'isis',
133: 'fc',
135: 'mobility-header',
137: 'mpls-in-ip',
138: 'manet',
139: 'hip',
140: 'shim6',
141: 'wesp',
142: 'rohc'}
# - protocol 0 uses no -p argument
# - 'ipv6-encap' uses 'ipv6' # - 'ipv6-encap' uses 'ipv6'
# - 'icmpv6' uses 'ipv6-icmp' # - 'icmpv6' uses 'ipv6-icmp'
# - 'pgm' uses number 113 instead of its name # - 'pgm' uses '113' instead of its name
IPTABLES_PROTOCOL_NAME_MAP = {0: None, # - protocol '0' uses no -p argument
lib_constants.PROTO_NAME_IPV6_ENCAP: IPTABLES_PROTOCOL_NAME_MAP = {lib_constants.PROTO_NAME_IPV6_ENCAP: 'ipv6',
'ipv6',
lib_constants.PROTO_NAME_IPV6_ICMP_LEGACY: lib_constants.PROTO_NAME_IPV6_ICMP_LEGACY:
'ipv6-icmp', 'ipv6-icmp',
lib_constants.PROTO_NAME_PGM: '113'} lib_constants.PROTO_NAME_PGM: '113',
IPTABLES_PROTOCOL_NAME_MAP.update(IPTABLES_PROTOCOL_LEGACY_NUM_MAP) '0': None,
'1': 'icmp',
# When using iptables-save we specify '-p {proto} -m {module}', '2': 'igmp',
# but sometimes those values are not identical. This is a map '3': 'ggp',
# of known protocols that require a '-m {module}', along with '4': 'ipencap',
# the module name that should be used. '5': 'st',
IPTABLES_PROTOCOL_MAP = {lib_constants.PROTO_NAME_DCCP: 'dccp', '6': 'tcp',
lib_constants.PROTO_NAME_ICMP: 'icmp', '8': 'egp',
lib_constants.PROTO_NAME_IPV6_ICMP: 'icmp6', '9': 'igp',
lib_constants.PROTO_NAME_SCTP: 'sctp', '12': 'pup',
lib_constants.PROTO_NAME_TCP: 'tcp', '17': 'udp',
lib_constants.PROTO_NAME_UDP: 'udp'} '20': 'hmp',
'22': 'xns-idp',
'27': 'rdp',
'29': 'iso-tp4',
'33': 'dccp',
'36': 'xtp',
'37': 'ddp',
'38': 'idpr-cmtp',
'41': 'ipv6',
'43': 'ipv6-route',
'44': 'ipv6-frag',
'45': 'idrp',
'46': 'rsvp',
'47': 'gre',
'50': 'esp',
'51': 'ah',
'57': 'skip',
'58': 'ipv6-icmp',
'59': 'ipv6-nonxt',
'60': 'ipv6-opts',
'73': 'rspf',
'81': 'vmtp',
'88': 'eigrp',
'89': 'ospf',
'93': 'ax.25',
'94': 'ipip',
'97': 'etherip',
'98': 'encap',
'103': 'pim',
'108': 'ipcomp',
'112': 'vrrp',
'115': 'l2tp',
'124': 'isis',
'132': 'sctp',
'133': 'fc',
'135': 'mobility-header',
'136': 'udplite',
'137': 'mpls-in-ip',
'138': 'manet',
'139': 'hip',
'140': 'shim6',
'141': 'wesp',
'142': 'rohc'}
# Timeout in seconds for getting an IPv6 LLA # Timeout in seconds for getting an IPv6 LLA
LLA_TASK_TIMEOUT = 40 LLA_TASK_TIMEOUT = 40

View File

@@ -276,6 +276,18 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
egress = None egress = None
self._test_prepare_port_filter(rule, ingress, egress) self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_tcp_port_by_num(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': '6',
'port_range_min': 10,
'port_range_max': 10}
ingress = mock.call.add_rule('ifake_dev',
'-p tcp -m tcp --dport 10 -j RETURN',
comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_tcp_mport(self): def test_filter_ipv4_ingress_tcp_mport(self):
rule = {'ethertype': 'IPv4', rule = {'ethertype': 'IPv4',
'direction': 'ingress', 'direction': 'ingress',
@@ -389,6 +401,42 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
egress = None egress = None
self._test_prepare_port_filter(rule, ingress, egress) self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_protocol_blank(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': ''}
ingress = mock.call.add_rule('ifake_dev', '-j RETURN', comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_protocol_zero(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': '0'}
ingress = mock.call.add_rule('ifake_dev', '-j RETURN', comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_protocol_encap(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': 'encap'}
ingress = mock.call.add_rule('ifake_dev',
'-p encap -j RETURN',
comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_protocol_encap_by_num(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': '98'}
ingress = mock.call.add_rule('ifake_dev',
'-p encap -j RETURN',
comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_egress(self): def test_filter_ipv4_egress(self):
rule = {'ethertype': 'IPv4', rule = {'ethertype': 'IPv4',
'direction': 'egress'} 'direction': 'egress'}