You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3055 lines
143 KiB
3055 lines
143 KiB
# Copyright 2012, Nachi Ueno, NTT MCL, Inc. |
|
# All Rights Reserved. |
|
# |
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
# not use this file except in compliance with the License. You may obtain |
|
# a copy of the License at |
|
# |
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
# |
|
# Unless required by applicable law or agreed to in writing, software |
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
# License for the specific language governing permissions and limitations |
|
# under the License. |
|
|
|
import collections |
|
import contextlib |
|
|
|
import mock |
|
from oslo_config import cfg |
|
import oslo_messaging |
|
from testtools import matchers |
|
import webob.exc |
|
|
|
from neutron.agent import firewall as firewall_base |
|
from neutron.agent.linux import iptables_manager |
|
from neutron.agent import securitygroups_rpc as sg_rpc |
|
from neutron.api.rpc.handlers import securitygroups_rpc |
|
from neutron.common import constants as const |
|
from neutron.common import ipv6_utils as ipv6 |
|
from neutron.common import rpc as n_rpc |
|
from neutron import context |
|
from neutron.db import securitygroups_rpc_base as sg_db_rpc |
|
from neutron.extensions import allowedaddresspairs as addr_pair |
|
from neutron.extensions import securitygroup as ext_sg |
|
from neutron import manager |
|
from neutron.plugins.openvswitch.agent import ovs_neutron_agent |
|
from neutron.tests import base |
|
from neutron.tests.unit.extensions import test_securitygroup as test_sg |
|
|
|
FAKE_PREFIX = {const.IPv4: '10.0.0.0/24', |
|
const.IPv6: '2001:db8::/64'} |
|
FAKE_IP = {const.IPv4: '10.0.0.1', |
|
const.IPv6: 'fe80::1', |
|
'IPv6_GLOBAL': '2001:0db8::1', |
|
'IPv6_LLA': 'fe80::123', |
|
'IPv6_DHCP': '2001:db8::3'} |
|
|
|
TEST_PLUGIN_CLASS = ('neutron.tests.unit.agent.test_securitygroups_rpc.' |
|
'SecurityGroupRpcTestPlugin') |
|
|
|
|
|
FIREWALL_BASE_PACKAGE = 'neutron.agent.linux.iptables_firewall.' |
|
FIREWALL_IPTABLES_DRIVER = FIREWALL_BASE_PACKAGE + 'IptablesFirewallDriver' |
|
FIREWALL_HYBRID_DRIVER = (FIREWALL_BASE_PACKAGE + |
|
'OVSHybridIptablesFirewallDriver') |
|
FIREWALL_NOOP_DRIVER = 'neutron.agent.firewall.NoopFirewallDriver' |
|
|
|
|
|
def set_enable_security_groups(enabled): |
|
cfg.CONF.set_override('enable_security_group', enabled, |
|
group='SECURITYGROUP') |
|
|
|
|
|
def set_firewall_driver(firewall_driver): |
|
cfg.CONF.set_override('firewall_driver', firewall_driver, |
|
group='SECURITYGROUP') |
|
|
|
|
|
class SecurityGroupRpcTestPlugin(test_sg.SecurityGroupTestPlugin, |
|
sg_db_rpc.SecurityGroupServerRpcMixin): |
|
def __init__(self): |
|
super(SecurityGroupRpcTestPlugin, self).__init__() |
|
self.notifier = mock.Mock() |
|
self.devices = {} |
|
|
|
def create_port(self, context, port): |
|
result = super(SecurityGroupRpcTestPlugin, |
|
self).create_port(context, port) |
|
self.devices[result['id']] = result |
|
self.notify_security_groups_member_updated(context, result) |
|
return result |
|
|
|
def update_port(self, context, id, port): |
|
original_port = self.get_port(context, id) |
|
updated_port = super(SecurityGroupRpcTestPlugin, |
|
self).update_port(context, id, port) |
|
self.devices[id] = updated_port |
|
self.update_security_group_on_port( |
|
context, id, port, original_port, updated_port) |
|
|
|
def delete_port(self, context, id): |
|
port = self.get_port(context, id) |
|
super(SecurityGroupRpcTestPlugin, self).delete_port(context, id) |
|
self.notify_security_groups_member_updated(context, port) |
|
del self.devices[id] |
|
|
|
def get_port_from_device(self, device): |
|
device = self.devices.get(device) |
|
if device: |
|
device['security_group_rules'] = [] |
|
device['security_group_source_groups'] = [] |
|
device['fixed_ips'] = [ip['ip_address'] |
|
for ip in device['fixed_ips']] |
|
return device |
|
|
|
|
|
class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): |
|
def setUp(self, plugin=None): |
|
plugin = plugin or TEST_PLUGIN_CLASS |
|
set_firewall_driver(FIREWALL_NOOP_DRIVER) |
|
super(SGServerRpcCallBackTestCase, self).setUp(plugin) |
|
self.notifier = manager.NeutronManager.get_plugin().notifier |
|
self.rpc = securitygroups_rpc.SecurityGroupServerRpcCallback() |
|
|
|
def _test_security_group_port(self, device_owner, gw_ip, |
|
cidr, ip_version, ip_address): |
|
with self.network() as net: |
|
with self.subnet(net, |
|
gateway_ip=gw_ip, |
|
cidr=cidr, |
|
ip_version=ip_version) as subnet: |
|
kwargs = { |
|
'fixed_ips': [{'subnet_id': subnet['subnet']['id'], |
|
'ip_address': ip_address}]} |
|
if device_owner: |
|
kwargs['device_owner'] = device_owner |
|
res = self._create_port( |
|
self.fmt, net['network']['id'], **kwargs) |
|
res = self.deserialize(self.fmt, res) |
|
port_id = res['port']['id'] |
|
if device_owner == const.DEVICE_OWNER_ROUTER_INTF: |
|
data = {'port': {'fixed_ips': []}} |
|
req = self.new_update_request('ports', data, port_id) |
|
res = self.deserialize(self.fmt, |
|
req.get_response(self.api)) |
|
self._delete('ports', port_id) |
|
|
|
def test_notify_security_group_ipv6_gateway_port_added(self): |
|
self._test_security_group_port( |
|
const.DEVICE_OWNER_ROUTER_INTF, |
|
'2001:0db8::1', |
|
'2001:0db8::/64', |
|
6, |
|
'2001:0db8::1') |
|
self.assertTrue(self.notifier.security_groups_provider_updated.called) |
|
|
|
def test_notify_security_group_ipv6_normal_port_added(self): |
|
self._test_security_group_port( |
|
None, |
|
'2001:0db8::1', |
|
'2001:0db8::/64', |
|
6, |
|
'2001:0db8::3') |
|
self.assertFalse(self.notifier.security_groups_provider_updated.called) |
|
|
|
def test_notify_security_group_ipv4_dhcp_port_added(self): |
|
self._test_security_group_port( |
|
const.DEVICE_OWNER_DHCP, |
|
'192.168.1.1', |
|
'192.168.1.0/24', |
|
4, |
|
'192.168.1.2') |
|
self.assertTrue(self.notifier.security_groups_provider_updated.called) |
|
|
|
def test_notify_security_group_ipv4_gateway_port_added(self): |
|
self._test_security_group_port( |
|
const.DEVICE_OWNER_ROUTER_INTF, |
|
'192.168.1.1', |
|
'192.168.1.0/24', |
|
4, |
|
'192.168.1.1') |
|
self.assertFalse(self.notifier.security_groups_provider_updated.called) |
|
|
|
def test_notify_security_group_ipv4_normal_port_added(self): |
|
self._test_security_group_port( |
|
None, |
|
'192.168.1.1', |
|
'192.168.1.0/24', |
|
4, |
|
'192.168.1.3') |
|
self.assertFalse(self.notifier.security_groups_provider_updated.called) |
|
|
|
def test_security_group_rules_for_devices_ipv4_ingress(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv4] |
|
with self.network() as n: |
|
with contextlib.nested( |
|
self.subnet(n), |
|
self.security_group()) as (subnet_v4, sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22') |
|
rule2 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '23', |
|
'23', fake_prefix) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule'], |
|
rule2['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 23, 'security_group_id': sg1_id, |
|
'port_range_min': 23, |
|
'source_ip_prefix': fake_prefix}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
@contextlib.contextmanager |
|
def _port_with_addr_pairs_and_security_group(self): |
|
plugin_obj = manager.NeutronManager.get_plugin() |
|
if ('allowed-address-pairs' |
|
not in plugin_obj.supported_extension_aliases): |
|
self.skipTest("Test depends on allowed-address-pairs extension") |
|
fake_prefix = FAKE_PREFIX['IPv4'] |
|
with self.network() as n: |
|
with contextlib.nested( |
|
self.subnet(n), |
|
self.security_group() |
|
) as (subnet_v4, sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', 'tcp', '22', |
|
'22', remote_group_id=sg1_id) |
|
rule2 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', 'tcp', '23', |
|
'23', fake_prefix) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule'], |
|
rule2['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(res.status_int, 201) |
|
address_pairs = [{'mac_address': '00:00:00:00:00:01', |
|
'ip_address': '10.0.1.0/24'}, |
|
{'mac_address': '00:00:00:00:00:01', |
|
'ip_address': '11.0.0.1'}] |
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id], |
|
arg_list=(addr_pair.ADDRESS_PAIRS,), |
|
allowed_address_pairs=address_pairs) |
|
yield self.deserialize(self.fmt, res1) |
|
|
|
def test_security_group_info_for_devices_ipv4_addr_pair(self): |
|
with self._port_with_addr_pairs_and_security_group() as port: |
|
port_id = port['port']['id'] |
|
sg_id = port['port']['security_groups'][0] |
|
devices = [port_id, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
# verify that address pairs are included in remote SG IPs |
|
sg_member_ips = self.rpc.security_group_info_for_devices( |
|
ctx, devices=devices)['sg_member_ips'] |
|
expected_member_ips = [ |
|
'10.0.1.0/24', '11.0.0.1', |
|
port['port']['fixed_ips'][0]['ip_address']] |
|
self.assertEqual(sorted(expected_member_ips), |
|
sorted(sg_member_ips[sg_id]['IPv4'])) |
|
self._delete('ports', port_id) |
|
|
|
def test_security_group_rules_for_devices_ipv4_ingress_addr_pair(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv4] |
|
with self._port_with_addr_pairs_and_security_group() as port: |
|
port_id = port['port']['id'] |
|
sg_id = port['port']['security_groups'][0] |
|
devices = [port_id, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
|
|
port_rpc = ports_rpc[port_id] |
|
expected = [{'direction': 'egress', 'ethertype': 'IPv4', |
|
'security_group_id': sg_id}, |
|
{'direction': 'egress', 'ethertype': 'IPv6', |
|
'security_group_id': sg_id}, |
|
{'direction': 'ingress', |
|
'protocol': 'tcp', 'ethertype': 'IPv4', |
|
'port_range_max': 22, |
|
'remote_group_id': sg_id, |
|
'security_group_id': sg_id, |
|
'source_ip_prefix': '11.0.0.1/32', |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': 'tcp', 'ethertype': 'IPv4', |
|
'port_range_max': 22, |
|
'remote_group_id': sg_id, |
|
'security_group_id': sg_id, |
|
'source_ip_prefix': '10.0.1.0/24', |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', 'protocol': 'tcp', |
|
'ethertype': 'IPv4', |
|
'port_range_max': 23, 'security_group_id': sg_id, |
|
'port_range_min': 23, |
|
'source_ip_prefix': fake_prefix}, |
|
] |
|
self.assertEqual(expected, |
|
port_rpc['security_group_rules']) |
|
self.assertEqual(port['port']['allowed_address_pairs'], |
|
port_rpc['allowed_address_pairs']) |
|
self._delete('ports', port_id) |
|
|
|
def test_security_group_rules_for_devices_ipv4_egress(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv4] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n), |
|
self.security_group()) as (subnet_v4, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'egress', const.PROTO_NAME_TCP, '22', |
|
'22') |
|
rule2 = self._build_security_group_rule( |
|
sg1_id, |
|
'egress', const.PROTO_NAME_UDP, '23', |
|
'23', fake_prefix) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule'], |
|
rule2['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'egress', |
|
'protocol': const.PROTO_NAME_UDP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 23, 'security_group_id': sg1_id, |
|
'port_range_min': 23, |
|
'dest_ip_prefix': fake_prefix}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_rules_for_devices_ipv4_source_group(self): |
|
|
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n), |
|
self.security_group(), |
|
self.security_group()) as (subnet_v4, |
|
sg1, |
|
sg2): |
|
sg1_id = sg1['security_group']['id'] |
|
sg2_id = sg2['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '24', |
|
'25', remote_group_id=sg2['security_group']['id']) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id, |
|
sg2_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
|
|
res2 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg2_id]) |
|
ports_rest2 = self.deserialize(self.fmt, res2) |
|
port_id2 = ports_rest2['port']['id'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg2_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg2_id}, |
|
{'direction': u'ingress', |
|
'source_ip_prefix': u'10.0.0.3/32', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 25, 'port_range_min': 24, |
|
'remote_group_id': sg2_id, |
|
'security_group_id': sg1_id}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
self._delete('ports', port_id2) |
|
|
|
def test_security_group_info_for_devices_ipv4_source_group(self): |
|
|
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n), |
|
self.security_group(), |
|
self.security_group()) as (subnet_v4, |
|
sg1, |
|
sg2): |
|
sg1_id = sg1['security_group']['id'] |
|
sg2_id = sg2['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '24', |
|
'25', remote_group_id=sg2['security_group']['id']) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(webob.exc.HTTPCreated.code, res.status_int) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
|
|
res2 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg2_id]) |
|
ports_rest2 = self.deserialize(self.fmt, res2) |
|
port_id2 = ports_rest2['port']['id'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_info_for_devices( |
|
ctx, devices=devices) |
|
expected = { |
|
'security_groups': {sg1_id: [ |
|
{'direction': 'egress', 'ethertype': const.IPv4}, |
|
{'direction': 'egress', 'ethertype': const.IPv6}, |
|
{'direction': u'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv4, |
|
'port_range_max': 25, 'port_range_min': 24, |
|
'remote_group_id': sg2_id} |
|
]}, |
|
'sg_member_ips': {sg2_id: { |
|
'IPv4': set([u'10.0.0.3']), |
|
'IPv6': set(), |
|
}} |
|
} |
|
self.assertEqual(expected['security_groups'], |
|
ports_rpc['security_groups']) |
|
self.assertEqual(expected['sg_member_ips'][sg2_id]['IPv4'], |
|
ports_rpc['sg_member_ips'][sg2_id]['IPv4']) |
|
self._delete('ports', port_id1) |
|
self._delete('ports', port_id2) |
|
|
|
def test_security_group_rules_for_devices_ipv6_ingress(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP[const.IPv6] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rule2 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_UDP, '23', |
|
'23', fake_prefix, |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule'], |
|
rule2['security_group_rule']]} |
|
res = self._create_security_group_rule(self.fmt, rules) |
|
self.deserialize(self.fmt, res) |
|
self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) |
|
|
|
dhcp_port = self._create_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], |
|
'ip_address': FAKE_IP['IPv6_DHCP']}], |
|
device_owner=const.DEVICE_OWNER_DHCP, |
|
security_groups=[sg1_id]) |
|
dhcp_rest = self.deserialize(self.fmt, dhcp_port) |
|
dhcp_mac = dhcp_rest['port']['mac_address'] |
|
dhcp_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( |
|
const.IPV6_LLA_PREFIX, |
|
dhcp_mac)) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
source_port, dest_port, ethertype = sg_db_rpc.DHCP_RULE_PORT[6] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_UDP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 23, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 23, |
|
'source_ip_prefix': fake_prefix}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': fake_gateway, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
{'direction': 'ingress', |
|
'ethertype': ethertype, |
|
'port_range_max': dest_port, |
|
'port_range_min': dest_port, |
|
'protocol': const.PROTO_NAME_UDP, |
|
'source_ip_prefix': dhcp_lla_ip, |
|
'source_port_range_max': source_port, |
|
'source_port_range_min': source_port} |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_info_for_devices_only_ipv6_rule(self): |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n), |
|
self.security_group()) as (subnet_v4, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', remote_group_id=sg1_id, |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
res1 = self._create_port( |
|
self.fmt, n['network']['id'], |
|
security_groups=[sg1_id]) |
|
ports_rest1 = self.deserialize(self.fmt, res1) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
|
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_info_for_devices( |
|
ctx, devices=devices) |
|
expected = { |
|
'security_groups': {sg1_id: [ |
|
{'direction': 'egress', 'ethertype': const.IPv4}, |
|
{'direction': 'egress', 'ethertype': const.IPv6}, |
|
{'direction': u'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, 'port_range_min': 22, |
|
'remote_group_id': sg1_id} |
|
]}, |
|
'sg_member_ips': {sg1_id: { |
|
'IPv6': set(), |
|
}} |
|
} |
|
self.assertEqual(expected['security_groups'], |
|
ports_rpc['security_groups']) |
|
self.assertEqual(expected['sg_member_ips'][sg1_id]['IPv6'], |
|
ports_rpc['sg_member_ips'][sg1_id]['IPv6']) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_ra_rules_for_devices_ipv6_gateway_global(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP['IPv6_GLOBAL'] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6, |
|
ipv6_ra_mode=const.IPV6_SLAAC), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
# Create gateway port |
|
gateway_res = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], |
|
'ip_address': fake_gateway}], |
|
device_owner='network:router_interface') |
|
gateway_mac = gateway_res['port']['mac_address'] |
|
gateway_port_id = gateway_res['port']['id'] |
|
gateway_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( |
|
const.IPV6_LLA_PREFIX, |
|
gateway_mac)) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': gateway_lla_ip, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
# Note(xuhanp): remove gateway port's fixed_ips or gateway port |
|
# deletion will be prevented. |
|
data = {'port': {'fixed_ips': []}} |
|
req = self.new_update_request('ports', data, gateway_port_id) |
|
self.deserialize(self.fmt, req.get_response(self.api)) |
|
self._delete('ports', gateway_port_id) |
|
|
|
def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP['IPv6_GLOBAL'] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6, |
|
ipv6_ra_mode=const.IPV6_SLAAC), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
# Create gateway port |
|
gateway_res = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], |
|
'ip_address': fake_gateway}], |
|
device_owner='network:router_interface') |
|
gateway_mac = gateway_res['port']['mac_address'] |
|
gateway_port_id = gateway_res['port']['id'] |
|
gateway_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( |
|
const.IPV6_LLA_PREFIX, |
|
gateway_mac)) |
|
# Create another router interface port |
|
interface_res = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
device_owner='network:router_interface') |
|
interface_port_id = interface_res['port']['id'] |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': gateway_lla_ip, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
data = {'port': {'fixed_ips': []}} |
|
req = self.new_update_request('ports', data, gateway_port_id) |
|
self.deserialize(self.fmt, req.get_response(self.api)) |
|
req = self.new_update_request('ports', data, interface_port_id) |
|
self.deserialize(self.fmt, req.get_response(self.api)) |
|
self._delete('ports', gateway_port_id) |
|
self._delete('ports', interface_port_id) |
|
|
|
def test_security_group_ra_rules_for_devices_ipv6_dvr(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP['IPv6_GLOBAL'] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6, |
|
ipv6_ra_mode=const.IPV6_SLAAC), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
# Create DVR router interface port |
|
gateway_res = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], |
|
'ip_address': fake_gateway}], |
|
device_owner=const.DEVICE_OWNER_DVR_INTERFACE) |
|
gateway_mac = gateway_res['port']['mac_address'] |
|
gateway_port_id = gateway_res['port']['id'] |
|
gateway_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( |
|
const.IPV6_LLA_PREFIX, |
|
gateway_mac)) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': gateway_lla_ip, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
# Note(xuhanp): remove gateway port's fixed_ips or gateway port |
|
# deletion will be prevented. |
|
data = {'port': {'fixed_ips': []}} |
|
req = self.new_update_request('ports', data, gateway_port_id) |
|
self.deserialize(self.fmt, req.get_response(self.api)) |
|
self._delete('ports', gateway_port_id) |
|
|
|
def test_security_group_ra_rules_for_devices_ipv6_gateway_lla(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP['IPv6_LLA'] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6, |
|
ipv6_ra_mode=const.IPV6_SLAAC), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': fake_gateway, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_ra_rules_for_devices_ipv6_no_gateway_port(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=None, |
|
cidr=fake_prefix, |
|
ip_version=6, |
|
ipv6_ra_mode=const.IPV6_SLAAC), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_rules_for_devices_ipv6_egress(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP[const.IPv6] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6), |
|
self.security_group()) as (subnet_v6, |
|
sg1): |
|
sg1_id = sg1['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'egress', const.PROTO_NAME_TCP, '22', |
|
'22', |
|
ethertype=const.IPv6) |
|
rule2 = self._build_security_group_rule( |
|
sg1_id, |
|
'egress', const.PROTO_NAME_UDP, '23', |
|
'23', fake_prefix, |
|
ethertype=const.IPv6) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule'], |
|
rule2['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
|
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 22, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 22}, |
|
{'direction': 'egress', |
|
'protocol': const.PROTO_NAME_UDP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 23, |
|
'security_group_id': sg1_id, |
|
'port_range_min': 23, |
|
'dest_ip_prefix': fake_prefix}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': fake_gateway, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
|
|
def test_security_group_rules_for_devices_ipv6_source_group(self): |
|
fake_prefix = FAKE_PREFIX[const.IPv6] |
|
fake_gateway = FAKE_IP[const.IPv6] |
|
with self.network() as n: |
|
with contextlib.nested(self.subnet(n, |
|
gateway_ip=fake_gateway, |
|
cidr=fake_prefix, |
|
ip_version=6), |
|
self.security_group(), |
|
self.security_group()) as (subnet_v6, |
|
sg1, |
|
sg2): |
|
sg1_id = sg1['security_group']['id'] |
|
sg2_id = sg2['security_group']['id'] |
|
rule1 = self._build_security_group_rule( |
|
sg1_id, |
|
'ingress', const.PROTO_NAME_TCP, '24', |
|
'25', |
|
ethertype=const.IPv6, |
|
remote_group_id=sg2['security_group']['id']) |
|
rules = { |
|
'security_group_rules': [rule1['security_group_rule']]} |
|
self._make_security_group_rule(self.fmt, rules) |
|
|
|
ports_rest1 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg1_id, |
|
sg2_id]) |
|
port_id1 = ports_rest1['port']['id'] |
|
self.rpc.devices = {port_id1: ports_rest1['port']} |
|
devices = [port_id1, 'no_exist_device'] |
|
|
|
ports_rest2 = self._make_port( |
|
self.fmt, n['network']['id'], |
|
fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], |
|
security_groups=[sg2_id]) |
|
port_id2 = ports_rest2['port']['id'] |
|
|
|
ctx = context.get_admin_context() |
|
ports_rpc = self.rpc.security_group_rules_for_devices( |
|
ctx, devices=devices) |
|
port_rpc = ports_rpc[port_id1] |
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv4, |
|
'security_group_id': sg2_id}, |
|
{'direction': 'egress', 'ethertype': const.IPv6, |
|
'security_group_id': sg2_id}, |
|
{'direction': 'ingress', |
|
'source_ip_prefix': '2001:db8::2/128', |
|
'protocol': const.PROTO_NAME_TCP, |
|
'ethertype': const.IPv6, |
|
'port_range_max': 25, 'port_range_min': 24, |
|
'remote_group_id': sg2_id, |
|
'security_group_id': sg1_id}, |
|
{'direction': 'ingress', |
|
'protocol': const.PROTO_NAME_ICMP_V6, |
|
'ethertype': const.IPv6, |
|
'source_ip_prefix': fake_gateway, |
|
'source_port_range_min': const.ICMPV6_TYPE_RA}, |
|
] |
|
self.assertEqual(port_rpc['security_group_rules'], |
|
expected) |
|
self._delete('ports', port_id1) |
|
self._delete('ports', port_id2) |
|
|
|
|
|
class SecurityGroupAgentRpcTestCaseForNoneDriver(base.BaseTestCase): |
|
def test_init_firewall_with_none_driver(self): |
|
set_enable_security_groups(False) |
|
agent = sg_rpc.SecurityGroupAgentRpc( |
|
context=None, plugin_rpc=mock.Mock()) |
|
self.assertEqual(agent.firewall.__class__.__name__, |
|
'NoopFirewallDriver') |
|
|
|
|
|
class BaseSecurityGroupAgentRpcTestCase(base.BaseTestCase): |
|
def setUp(self, defer_refresh_firewall=False): |
|
super(BaseSecurityGroupAgentRpcTestCase, self).setUp() |
|
set_firewall_driver(FIREWALL_NOOP_DRIVER) |
|
self.agent = sg_rpc.SecurityGroupAgentRpc( |
|
context=None, plugin_rpc=mock.Mock(), |
|
defer_refresh_firewall=defer_refresh_firewall) |
|
mock.patch('neutron.agent.linux.iptables_manager').start() |
|
self.default_firewall = self.agent.firewall |
|
self.firewall = mock.Mock() |
|
firewall_object = firewall_base.FirewallDriver() |
|
self.firewall.defer_apply.side_effect = firewall_object.defer_apply |
|
self.agent.firewall = self.firewall |
|
self.fake_device = {'device': 'fake_device', |
|
'network_id': 'fake_net', |
|
'security_groups': ['fake_sgid1', 'fake_sgid2'], |
|
'security_group_source_groups': ['fake_sgid2'], |
|
'security_group_rules': [{'security_group_id': |
|
'fake_sgid1', |
|
'remote_group_id': |
|
'fake_sgid2'}]} |
|
self.firewall.ports = {'fake_device': self.fake_device} |
|
|
|
|
|
class SecurityGroupAgentRpcTestCase(BaseSecurityGroupAgentRpcTestCase): |
|
def setUp(self, defer_refresh_firewall=False): |
|
super(SecurityGroupAgentRpcTestCase, self).setUp( |
|
defer_refresh_firewall) |
|
rpc = self.agent.plugin_rpc |
|
rpc.security_group_info_for_devices.side_effect = ( |
|
oslo_messaging.UnsupportedVersion('1.2')) |
|
rpc.security_group_rules_for_devices.return_value = ( |
|
self.firewall.ports) |
|
|
|
def test_prepare_and_remove_devices_filter(self): |
|
self.agent.prepare_devices_filter(['fake_device']) |
|
self.agent.remove_devices_filter(['fake_device']) |
|
# ignore device which is not filtered |
|
self.firewall.assert_has_calls([mock.call.defer_apply(), |
|
mock.call.prepare_port_filter( |
|
self.fake_device), |
|
mock.call.defer_apply(), |
|
mock.call.remove_port_filter( |
|
self.fake_device), |
|
]) |
|
|
|
def test_prepare_devices_filter_with_noopfirewall(self): |
|
self.agent.firewall = self.default_firewall |
|
self.agent.plugin_rpc.security_group_info_for_devices = mock.Mock() |
|
self.agent.plugin_rpc.security_group_rules_for_devices = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_device']) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_info_for_devices.called) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_rules_for_devices.called) |
|
|
|
def test_prepare_devices_filter_with_firewall_disabled(self): |
|
cfg.CONF.set_override('enable_security_group', False, 'SECURITYGROUP') |
|
self.agent.plugin_rpc.security_group_info_for_devices = mock.Mock() |
|
self.agent.plugin_rpc.security_group_rules_for_devices = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_device']) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_info_for_devices.called) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_rules_for_devices.called) |
|
|
|
def test_security_groups_rule_updated(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_rule_updated(['fake_sgid1', 'fake_sgid3']) |
|
self.agent.refresh_firewall.assert_has_calls( |
|
[mock.call.refresh_firewall([self.fake_device['device']])]) |
|
|
|
def test_security_groups_rule_not_updated(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_rule_updated(['fake_sgid3', 'fake_sgid4']) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
|
|
def test_security_groups_member_updated(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_member_updated(['fake_sgid2', 'fake_sgid3']) |
|
self.agent.refresh_firewall.assert_has_calls( |
|
[mock.call.refresh_firewall([self.fake_device['device']])]) |
|
|
|
def test_security_groups_member_not_updated(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_member_updated(['fake_sgid3', 'fake_sgid4']) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
|
|
def test_security_groups_provider_updated(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_provider_updated() |
|
self.agent.refresh_firewall.assert_has_calls( |
|
[mock.call.refresh_firewall()]) |
|
|
|
def test_refresh_firewall(self): |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.refresh_firewall() |
|
calls = [mock.call.defer_apply(), |
|
mock.call.prepare_port_filter(self.fake_device), |
|
mock.call.defer_apply(), |
|
mock.call.update_port_filter(self.fake_device)] |
|
self.firewall.assert_has_calls(calls) |
|
|
|
def test_refresh_firewall_devices(self): |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.refresh_firewall([self.fake_device]) |
|
calls = [mock.call.defer_apply(), |
|
mock.call.prepare_port_filter(self.fake_device), |
|
mock.call.defer_apply(), |
|
mock.call.update_port_filter(self.fake_device)] |
|
self.firewall.assert_has_calls(calls) |
|
|
|
def test_refresh_firewall_none(self): |
|
self.agent.refresh_firewall([]) |
|
self.assertFalse(self.firewall.called) |
|
|
|
def test_refresh_firewall_with_firewall_disabled(self): |
|
cfg.CONF.set_override('enable_security_group', False, 'SECURITYGROUP') |
|
self.agent.plugin_rpc.security_group_info_for_devices = mock.Mock() |
|
self.agent.plugin_rpc.security_group_rules_for_devices = mock.Mock() |
|
self.agent.firewall.defer_apply = mock.Mock() |
|
self.agent.refresh_firewall([self.fake_device]) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_info_for_devices.called) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_rules_for_devices.called) |
|
self.assertFalse(self.agent.firewall.defer_apply.called) |
|
|
|
def test_refresh_firewall_with_noopfirewall(self): |
|
self.agent.firewall = self.default_firewall |
|
self.agent.plugin_rpc.security_group_info_for_devices = mock.Mock() |
|
self.agent.plugin_rpc.security_group_rules_for_devices = mock.Mock() |
|
self.agent.firewall.defer_apply = mock.Mock() |
|
self.agent.refresh_firewall([self.fake_device]) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_info_for_devices.called) |
|
self.assertFalse(self.agent.plugin_rpc. |
|
security_group_rules_for_devices.called) |
|
self.assertFalse(self.agent.firewall.defer_apply.called) |
|
|
|
|
|
class SecurityGroupAgentEnhancedRpcTestCase( |
|
BaseSecurityGroupAgentRpcTestCase): |
|
|
|
def setUp(self, defer_refresh_firewall=False): |
|
super(SecurityGroupAgentEnhancedRpcTestCase, self).setUp( |
|
defer_refresh_firewall=defer_refresh_firewall) |
|
fake_sg_info = { |
|
'security_groups': collections.OrderedDict([ |
|
('fake_sgid2', []), |
|
('fake_sgid1', [{'remote_group_id': 'fake_sgid2'}])]), |
|
'sg_member_ips': {'fake_sgid2': {'IPv4': [], 'IPv6': []}}, |
|
'devices': self.firewall.ports} |
|
self.agent.plugin_rpc.security_group_info_for_devices.return_value = ( |
|
fake_sg_info) |
|
|
|
def test_prepare_and_remove_devices_filter_enhanced_rpc(self): |
|
self.agent.prepare_devices_filter(['fake_device']) |
|
self.agent.remove_devices_filter(['fake_device']) |
|
# these two mocks are too long, just use tmp_mock to replace them |
|
tmp_mock1 = mock.call.update_security_group_rules( |
|
'fake_sgid1', [{'remote_group_id': 'fake_sgid2'}]) |
|
tmp_mock2 = mock.call.update_security_group_members( |
|
'fake_sgid2', {'IPv4': [], 'IPv6': []}) |
|
# ignore device which is not filtered |
|
self.firewall.assert_has_calls([mock.call.defer_apply(), |
|
mock.call.prepare_port_filter( |
|
self.fake_device), |
|
mock.call.update_security_group_rules( |
|
'fake_sgid2', []), |
|
tmp_mock1, |
|
tmp_mock2, |
|
mock.call.defer_apply(), |
|
mock.call.remove_port_filter( |
|
self.fake_device), |
|
]) |
|
|
|
def test_security_groups_rule_updated_enhanced_rpc(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_rule_updated(['fake_sgid1', 'fake_sgid3']) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
[self.fake_device['device']]) |
|
|
|
def test_security_groups_rule_not_updated_enhanced_rpc(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_rule_updated(['fake_sgid3', 'fake_sgid4']) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
|
|
def test_security_groups_member_updated_enhanced_rpc(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_member_updated( |
|
['fake_sgid2', 'fake_sgid3']) |
|
|
|
self.agent.refresh_firewall.assert_called_once_with( |
|
[self.fake_device['device']]) |
|
|
|
def test_security_groups_member_not_updated_enhanced_rpc(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.security_groups_member_updated( |
|
['fake_sgid3', 'fake_sgid4']) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
|
|
def test_security_groups_provider_updated_enhanced_rpc(self): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_provider_updated() |
|
self.agent.refresh_firewall.assert_has_calls( |
|
[mock.call.refresh_firewall()]) |
|
|
|
def test_refresh_firewall_enhanced_rpc(self): |
|
self.agent.prepare_devices_filter(['fake_port_id']) |
|
self.agent.refresh_firewall() |
|
calls = [mock.call.defer_apply(), |
|
mock.call.prepare_port_filter(self.fake_device), |
|
mock.call.update_security_group_rules('fake_sgid2', []), |
|
mock.call.update_security_group_rules( |
|
'fake_sgid1', [{'remote_group_id': 'fake_sgid2'}]), |
|
mock.call.update_security_group_members( |
|
'fake_sgid2', {'IPv4': [], 'IPv6': []}), |
|
mock.call.defer_apply(), |
|
mock.call.update_port_filter(self.fake_device), |
|
mock.call.update_security_group_rules('fake_sgid2', []), |
|
mock.call.update_security_group_rules( |
|
'fake_sgid1', [{'remote_group_id': 'fake_sgid2'}]), |
|
mock.call.update_security_group_members( |
|
'fake_sgid2', {'IPv4': [], 'IPv6': []})] |
|
self.firewall.assert_has_calls(calls) |
|
|
|
def test_refresh_firewall_devices_enhanced_rpc(self): |
|
self.agent.prepare_devices_filter(['fake_device']) |
|
self.agent.refresh_firewall([self.fake_device]) |
|
calls = [mock.call.defer_apply(), |
|
mock.call.prepare_port_filter(self.fake_device), |
|
mock.call.update_security_group_rules('fake_sgid2', []), |
|
mock.call.update_security_group_rules('fake_sgid1', [ |
|
{'remote_group_id': 'fake_sgid2'}]), |
|
mock.call.update_security_group_members('fake_sgid2', { |
|
'IPv4': [], 'IPv6': [] |
|
}), |
|
mock.call.defer_apply(), |
|
mock.call.update_port_filter(self.fake_device), |
|
mock.call.update_security_group_rules('fake_sgid2', []), |
|
mock.call.update_security_group_rules('fake_sgid1', [ |
|
{'remote_group_id': 'fake_sgid2'}]), |
|
mock.call.update_security_group_members('fake_sgid2', { |
|
'IPv4': [], 'IPv6': []}) |
|
] |
|
self.firewall.assert_has_calls(calls) |
|
|
|
def test_refresh_firewall_none_enhanced_rpc(self): |
|
self.agent.refresh_firewall([]) |
|
self.assertFalse(self.firewall.called) |
|
|
|
|
|
class SecurityGroupAgentRpcWithDeferredRefreshTestCase( |
|
SecurityGroupAgentRpcTestCase): |
|
|
|
def setUp(self): |
|
super(SecurityGroupAgentRpcWithDeferredRefreshTestCase, self).setUp( |
|
defer_refresh_firewall=True) |
|
|
|
@contextlib.contextmanager |
|
def add_fake_device(self, device, sec_groups, source_sec_groups=None): |
|
fake_device = {'device': device, |
|
'security_groups': sec_groups, |
|
'security_group_source_groups': source_sec_groups or [], |
|
'security_group_rules': [{'security_group_id': |
|
'fake_sgid1', |
|
'remote_group_id': |
|
'fake_sgid2'}]} |
|
self.firewall.ports[device] = fake_device |
|
yield |
|
del self.firewall.ports[device] |
|
|
|
def test_security_groups_rule_updated(self): |
|
self.agent.security_groups_rule_updated(['fake_sgid1', 'fake_sgid3']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
|
|
def test_multiple_security_groups_rule_updated_same_port(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgidX']): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_rule_updated(['fake_sgid1']) |
|
self.agent.security_groups_rule_updated(['fake_sgid2']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertNotIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_security_groups_rule_updated_multiple_ports(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgid2']): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_rule_updated(['fake_sgid1', |
|
'fake_sgid2']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_multiple_security_groups_rule_updated_multiple_ports(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgid2']): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_rule_updated(['fake_sgid1']) |
|
self.agent.security_groups_rule_updated(['fake_sgid2']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_security_groups_member_updated(self): |
|
self.agent.security_groups_member_updated(['fake_sgid2', 'fake_sgid3']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
|
|
def test_multiple_security_groups_member_updated_same_port(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgid1', 'fake_sgid1B'], |
|
source_sec_groups=['fake_sgidX']): |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.security_groups_member_updated(['fake_sgid1', |
|
'fake_sgid3']) |
|
self.agent.security_groups_member_updated(['fake_sgid2', |
|
'fake_sgid3']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertNotIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_security_groups_member_updated_multiple_ports(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgid1', 'fake_sgid1B'], |
|
source_sec_groups=['fake_sgid2']): |
|
self.agent.security_groups_member_updated(['fake_sgid2']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_multiple_security_groups_member_updated_multiple_ports(self): |
|
with self.add_fake_device(device='fake_device_2', |
|
sec_groups=['fake_sgid1', 'fake_sgid1B'], |
|
source_sec_groups=['fake_sgid1B']): |
|
self.agent.security_groups_member_updated(['fake_sgid1B']) |
|
self.agent.security_groups_member_updated(['fake_sgid2']) |
|
self.assertIn('fake_device', self.agent.devices_to_refilter) |
|
self.assertIn('fake_device_2', self.agent.devices_to_refilter) |
|
|
|
def test_security_groups_provider_updated(self): |
|
self.agent.security_groups_provider_updated() |
|
self.assertTrue(self.agent.global_refresh_firewall) |
|
|
|
def test_setup_port_filters_new_ports_only(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set() |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(['fake_new_device']), set()) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.prepare_devices_filter.assert_called_once_with( |
|
set(['fake_new_device'])) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
|
|
def test_setup_port_filters_updated_ports_only(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set() |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(), set(['fake_updated_device'])) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_updated_device'])) |
|
self.assertFalse(self.agent.prepare_devices_filter.called) |
|
|
|
def test_setup_port_filter_new_and_updated_ports(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set() |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(['fake_new_device']), |
|
set(['fake_updated_device'])) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.prepare_devices_filter.assert_called_once_with( |
|
set(['fake_new_device'])) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_updated_device'])) |
|
|
|
def test_setup_port_filters_sg_updates_only(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set(['fake_device']) |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(), set()) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_device'])) |
|
self.assertFalse(self.agent.prepare_devices_filter.called) |
|
|
|
def test_setup_port_filters_sg_updates_and_new_ports(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set(['fake_device']) |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(['fake_new_device']), set()) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.prepare_devices_filter.assert_called_once_with( |
|
set(['fake_new_device'])) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_device'])) |
|
|
|
def _test_prepare_devices_filter(self, devices): |
|
# simulate an RPC arriving and calling _security_group_updated() |
|
self.agent.devices_to_refilter |= set(['fake_new_device']) |
|
|
|
def test_setup_port_filters_new_port_and_rpc(self): |
|
# Make sure that if an RPC arrives and adds a device to |
|
# devices_to_refilter while we are in setup_port_filters() |
|
# that it is not cleared, and will be processed later. |
|
self.agent.prepare_devices_filter = self._test_prepare_devices_filter |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set(['new_device', 'fake_device']) |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(['new_device']), set()) |
|
self.assertEqual(self.agent.devices_to_refilter, |
|
set(['fake_new_device'])) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_device'])) |
|
|
|
def test_setup_port_filters_sg_updates_and_updated_ports(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set(['fake_device', 'fake_device_2']) |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters( |
|
set(), set(['fake_device', 'fake_updated_device'])) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_device', 'fake_device_2', 'fake_updated_device'])) |
|
self.assertFalse(self.agent.prepare_devices_filter.called) |
|
|
|
def test_setup_port_filters_all_updates(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set(['fake_device', 'fake_device_2']) |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters( |
|
set(['fake_new_device']), |
|
set(['fake_device', 'fake_updated_device'])) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.prepare_devices_filter.assert_called_once_with( |
|
set(['fake_new_device'])) |
|
self.agent.refresh_firewall.assert_called_once_with( |
|
set(['fake_device', 'fake_device_2', 'fake_updated_device'])) |
|
|
|
def test_setup_port_filters_no_update(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set() |
|
self.agent.global_refresh_firewall = False |
|
self.agent.setup_port_filters(set(), set()) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.assertFalse(self.agent.refresh_firewall.called) |
|
self.assertFalse(self.agent.prepare_devices_filter.called) |
|
|
|
def test_setup_port_filters_with_global_refresh(self): |
|
self.agent.prepare_devices_filter = mock.Mock() |
|
self.agent.refresh_firewall = mock.Mock() |
|
self.agent.devices_to_refilter = set() |
|
self.agent.global_refresh_firewall = True |
|
self.agent.setup_port_filters(set(), set()) |
|
self.assertFalse(self.agent.devices_to_refilter) |
|
self.assertFalse(self.agent.global_refresh_firewall) |
|
self.agent.refresh_firewall.assert_called_once_with() |
|
self.assertFalse(self.agent.prepare_devices_filter.called) |
|
|
|
|
|
class FakeSGNotifierAPI(sg_rpc.SecurityGroupAgentRpcApiMixin): |
|
def __init__(self): |
|
self.topic = 'fake' |
|
target = oslo_messaging.Target(topic=self.topic, version='1.0') |
|
self.client = n_rpc.get_client(target) |
|
|
|
|
|
class SecurityGroupAgentRpcApiTestCase(base.BaseTestCase): |
|
def setUp(self): |
|
super(SecurityGroupAgentRpcApiTestCase, self).setUp() |
|
self.notifier = FakeSGNotifierAPI() |
|
self.mock_prepare = mock.patch.object(self.notifier.client, 'prepare', |
|
return_value=self.notifier.client).start() |
|
self.mock_cast = mock.patch.object(self.notifier.client, |
|
'cast').start() |
|
|
|
def test_security_groups_provider_updated(self): |
|
self.notifier.security_groups_provider_updated(None) |
|
self.mock_cast.assert_has_calls( |
|
[mock.call(None, 'security_groups_provider_updated')]) |
|
|
|
def test_security_groups_rule_updated(self): |
|
self.notifier.security_groups_rule_updated( |
|
None, security_groups=['fake_sgid']) |
|
self.mock_cast.assert_has_calls( |
|
[mock.call(None, 'security_groups_rule_updated', |
|
security_groups=['fake_sgid'])]) |
|
|
|
def test_security_groups_member_updated(self): |
|
self.notifier.security_groups_member_updated( |
|
None, security_groups=['fake_sgid']) |
|
self.mock_cast.assert_has_calls( |
|
[mock.call(None, 'security_groups_member_updated', |
|
security_groups=['fake_sgid'])]) |
|
|
|
def test_security_groups_rule_not_updated(self): |
|
self.notifier.security_groups_rule_updated( |
|
None, security_groups=[]) |
|
self.assertEqual(False, self.mock_cast.called) |
|
|
|
def test_security_groups_member_not_updated(self): |
|
self.notifier.security_groups_member_updated( |
|
None, security_groups=[]) |
|
self.assertEqual(False, self.mock_cast.called) |
|
|
|
#Note(nati) bn -> binary_name |
|
# id -> device_id |
|
|
|
PHYSDEV_MOD = '-m physdev' |
|
PHYSDEV_IS_BRIDGED = '--physdev-is-bridged' |
|
|
|
IPTABLES_ARG = {'bn': iptables_manager.binary_name, |
|
'physdev_mod': PHYSDEV_MOD, |
|
'physdev_is_bridged': PHYSDEV_IS_BRIDGED} |
|
|
|
CHAINS_MANGLE = 'FORWARD|INPUT|OUTPUT|POSTROUTING|PREROUTING|mark' |
|
IPTABLES_ARG['chains'] = CHAINS_MANGLE |
|
|
|
IPTABLES_MANGLE = """# Generated by iptables_manager |
|
*mangle |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A INPUT -j %(bn)s-INPUT |
|
[0:0] -A FORWARD -j %(bn)s-FORWARD |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING |
|
[0:0] -A %(bn)s-PREROUTING -j %(bn)s-mark |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
CHAINS_NAT = 'OUTPUT|POSTROUTING|PREROUTING|float-snat|snat' |
|
|
|
# These Dicts use the same keys as devices2 and devices3 in |
|
# TestSecurityGroupAgentWithIptables() to ensure that the ordering |
|
# is consistent regardless of hashseed value |
|
PORTS = {'tap_port1': 'port1', 'tap_port2': 'port2'} |
|
MACS = {'tap_port1': '12:34:56:78:9a:bc', 'tap_port2': '12:34:56:78:9a:bd'} |
|
IPS = {'tap_port1': '10.0.0.3/32', 'tap_port2': '10.0.0.4/32'} |
|
|
|
IPTABLES_ARG['port1'] = PORTS.values()[0] |
|
IPTABLES_ARG['port2'] = PORTS.values()[1] |
|
IPTABLES_ARG['mac1'] = MACS.values()[0] |
|
IPTABLES_ARG['mac2'] = MACS.values()[1] |
|
IPTABLES_ARG['ip1'] = IPS.values()[0] |
|
IPTABLES_ARG['ip2'] = IPS.values()[1] |
|
IPTABLES_ARG['chains'] = CHAINS_NAT |
|
|
|
IPTABLES_RAW_DEFAULT = """# Generated by iptables_manager |
|
*raw |
|
:%(bn)s-OUTPUT - [0:0] |
|
:%(bn)s-PREROUTING - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
IPTABLES_RAW_DEVICE_1 = """# Generated by iptables_manager |
|
*raw |
|
:%(bn)s-OUTPUT - [0:0] |
|
:%(bn)s-PREROUTING - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port1 -j CT --zone 1 |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port1 -j CT --zone 1 |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
IPTABLES_RAW_DEVICE_2 = """# Generated by iptables_manager |
|
*raw |
|
:%(bn)s-OUTPUT - [0:0] |
|
:%(bn)s-PREROUTING - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port1 -j CT --zone 1 |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port1 -j CT --zone 1 |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port2 -j CT --zone 1 |
|
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port2 -j CT --zone 1 |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
IPTABLES_NAT = """# Generated by iptables_manager |
|
*nat |
|
:neutron-postrouting-bottom - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING |
|
[0:0] -A POSTROUTING -j neutron-postrouting-bottom |
|
[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat |
|
[0:0] -A %(bn)s-snat -j %(bn)s-float-snat |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
CHAINS_RAW = 'OUTPUT|PREROUTING' |
|
IPTABLES_ARG['chains'] = CHAINS_RAW |
|
|
|
IPTABLES_RAW = """# Generated by iptables_manager |
|
*raw |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A PREROUTING -j %(bn)s-PREROUTING |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
CHAINS_EMPTY = 'FORWARD|INPUT|OUTPUT|local|sg-chain|sg-fallback' |
|
CHAINS_1 = CHAINS_EMPTY + '|i_port1|o_port1|s_port1' |
|
CHAINS_2 = CHAINS_1 + '|i_port2|o_port2|s_port2' |
|
|
|
IPTABLES_ARG['chains'] = CHAINS_1 |
|
|
|
IPSET_FILTER_1 = """# Generated by iptables_manager |
|
*filter |
|
:neutron-filter-top - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A FORWARD -j neutron-filter-top |
|
[0:0] -A OUTPUT -j neutron-filter-top |
|
[0:0] -A neutron-filter-top -j %(bn)s-local |
|
[0:0] -A INPUT -j %(bn)s-INPUT |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A FORWARD -j %(bn)s-FORWARD |
|
[0:0] -A %(bn)s-sg-fallback -j DROP |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-i_port1 |
|
[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -s 10.0.0.2/32 -p udp -m udp --sport 67 --dport 68 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -m set --match-set NETIPv4security_group1 src -j \ |
|
RETURN |
|
[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3/32 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-s_port1 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-sg-chain -j ACCEPT |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
IPTABLES_FILTER_1 = """# Generated by iptables_manager |
|
*filter |
|
:neutron-filter-top - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A FORWARD -j neutron-filter-top |
|
[0:0] -A OUTPUT -j neutron-filter-top |
|
[0:0] -A neutron-filter-top -j %(bn)s-local |
|
[0:0] -A INPUT -j %(bn)s-INPUT |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A FORWARD -j %(bn)s-FORWARD |
|
[0:0] -A %(bn)s-sg-fallback -j DROP |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-i_port1 |
|
[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -s 10.0.0.2/32 -p udp -m udp --sport 67 --dport 68 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3/32 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-s_port1 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-sg-chain -j ACCEPT |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
|
|
IPTABLES_FILTER_1_2 = """# Generated by iptables_manager |
|
*filter |
|
:neutron-filter-top - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A FORWARD -j neutron-filter-top |
|
[0:0] -A OUTPUT -j neutron-filter-top |
|
[0:0] -A neutron-filter-top -j %(bn)s-local |
|
[0:0] -A INPUT -j %(bn)s-INPUT |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A FORWARD -j %(bn)s-FORWARD |
|
[0:0] -A %(bn)s-sg-fallback -j DROP |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-i_port1 |
|
[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -s 10.0.0.2/32 -p udp -m udp --sport 67 --dport 68 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -s 10.0.0.4/32 -j RETURN |
|
[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ |
|
%(physdev_is_bridged)s -j %(bn)s-o_port1 |
|
[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3/32 \ |
|
-j RETURN |
|
[0:0] -A %(bn)s-s_port1 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 |
|
[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j RETURN |
|
[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback |
|
[0:0] -A %(bn)s-sg-chain -j ACCEPT |
|
COMMIT |
|
# Completed by iptables_manager |
|
""" % IPTABLES_ARG |
|
|
|
IPTABLES_ARG['chains'] = CHAINS_2 |
|
|
|
IPSET_FILTER_2 = """# Generated by iptables_manager |
|
*filter |
|
:neutron-filter-top - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
:%(bn)s-(%(chains)s) - [0:0] |
|
[0:0] -A FORWARD -j neutron-filter-top |
|
[0:0] -A OUTPUT -j neutron-filter-top |
|
[0:0] -A neutron-filter-top -j %(bn)s-local |
|
[0:0] -A INPUT -j %(bn)s-INPUT |
|
[0:0] -A OUTPUT -j %(bn)s-OUTPUT |
|
[0:0] -A FORWARD -j %(bn)s-FORWARD |
|
[0:0] -A %(bn)s-sg-fallback -j DROP |
|
[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_%(port1)s \ |
|
%(physdev_is_bridged)s -j %(bn)s-sg-chain |
|
[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_%(port1)s \ |
|
%(physdev_is_bridged)s -j %(bn)s-i_%(port1)s |
|
[0:0] -A %(bn)s-i_%(port1)s -m state --state INVALID -j DROP |
|
[0:0] -A %(bn)s-i_%(port1)s -m state --state RELATED,ESTABLISHED -j RETURN |
|
[0:0] -A %(bn)s-i_%(port1)s -s 10.0.0.2/32 -p udp -m udp --sport 67 \ |
|
--dport 68 -j RETURN |
|
|