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 Doug Wiegley
parent 55daaeca3e
commit f6be9d7ad9
2 changed files with 29 additions and 5 deletions

View File

@ -50,6 +50,15 @@ IPSET_DIRECTION = {firewall.INGRESS_DIRECTION: 'src',
comment_rule = iptables_manager.comment_rule comment_rule = iptables_manager.comment_rule
libc = ctypes.CDLL(util.find_library('libc.so.6')) 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): def get_hybrid_port_name(port_name):
return (constants.TAP_DEVICE_PREFIX + port_name)[:n_const.LINUX_DEV_LEN] return (constants.TAP_DEVICE_PREFIX + port_name)[:n_const.LINUX_DEV_LEN]
@ -756,11 +765,12 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
# icmp code can be 0 so we cannot use "if port_range_max" here # icmp code can be 0 so we cannot use "if port_range_max" here
if port_range_max is not None: if port_range_max is not None:
args[-1] += '/%s' % port_range_max args[-1] += '/%s' % port_range_max
elif port_range_min == port_range_max: elif protocol in IPTABLES_PORT_PROTOCOLS:
args += ['--%s' % direction, '%s' % (port_range_min,)] if port_range_min == port_range_max:
else: args += ['--%s' % direction, '%s' % (port_range_min,)]
args += ['-m', 'multiport', '--%ss' % direction, else:
'%s:%s' % (port_range_min, port_range_max)] args += ['-m', 'multiport', '--%ss' % direction,
'%s:%s' % (port_range_min, port_range_max)]
return args return args
def _ip_prefix_arg(self, direction, ip_prefix): def _ip_prefix_arg(self, direction, ip_prefix):

View File

@ -276,6 +276,20 @@ 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_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',
comment=None)
egress = None
self._test_prepare_port_filter(rule, ingress, egress)
def test_filter_ipv4_ingress_tcp_port_by_num(self): def test_filter_ipv4_ingress_tcp_port_by_num(self):
rule = {'ethertype': 'IPv4', rule = {'ethertype': 'IPv4',
'direction': 'ingress', 'direction': 'ingress',