When converting sg rules to iptables, do not emit dport if not supported

Since iptables-restore doesn't support --dport with protocol vrrp,
it errors out setting the security groups on the hypervisor.

Marking this a partial fix, since we need a change to prevent
adding those incompatible rules in the first place, but this
patch will stop the bleeding.

Change-Id: If5e557a8e61c3aa364ba1e2c60be4cbe74c1ec8f
Partial-Bug: #1818385
(cherry picked from commit 8c213e4590)
This commit is contained in:
Doug Wiegley 2019-03-02 22:35:52 -07:00 committed by Erik Olof Gunnar Andersson
parent 119ef92b47
commit 558a977902
2 changed files with 29 additions and 5 deletions

View File

@ -46,6 +46,15 @@ IPSET_DIRECTION = {constants.INGRESS_DIRECTION: 'src',
comment_rule = iptables_manager.comment_rule
libc = ctypes.CDLL(util.find_library('libc.so.6'))
# iptables protocols that support --dport and --sport
IPTABLES_PORT_PROTOCOLS = [
constants.PROTO_NAME_DCCP,
constants.PROTO_NAME_SCTP,
constants.PROTO_NAME_TCP,
constants.PROTO_NAME_UDP,
constants.PROTO_NAME_UDPLITE
]
def get_hybrid_port_name(port_name):
return (constants.TAP_DEVICE_PREFIX + port_name)[:n_const.LINUX_DEV_LEN]
@ -731,11 +740,12 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
# icmp code can be 0 so we cannot use "if port_range_max" here
if port_range_max is not None:
args[-1] += '/%s' % port_range_max
elif port_range_min == port_range_max:
args += ['--%s' % direction, '%s' % (port_range_min,)]
else:
args += ['-m', 'multiport', '--%ss' % direction,
'%s:%s' % (port_range_min, port_range_max)]
elif protocol in IPTABLES_PORT_PROTOCOLS:
if port_range_min == port_range_max:
args += ['--%s' % direction, '%s' % (port_range_min,)]
else:
args += ['-m', 'multiport', '--%ss' % direction,
'%s:%s' % (port_range_min, port_range_max)]
return args
def _ip_prefix_arg(self, direction, ip_prefix):

View File

@ -276,6 +276,20 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_bad_vrrp_with_dport(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',
'protocol': 'vrrp',
'port_range_min': 10,
'port_range_max': 10}
# Dest port isn't support with VRRP, so don't send it
# down to iptables.
ingress = mock.call.add_rule('ifake_dev',
'-p vrrp -j RETURN',
top=False, comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_tcp_port_by_num(self):
rule = {'ethertype': 'IPv4',
'direction': 'ingress',