Match IPSEC SA established state

While using IKE policy with version v2,
the IPsec siteconnection status always down.
From librewan wiki[1], the "phase2" in IKEv2 mistakenly
calls itself a PARENT SA which same as "phase1",
This is a known bug for some versions of libreswan.

For the newer versions of libreswan(3.20+),
the "IPsec SA established" will successful output if
phase2 state established.

Here we match the "established" and "newest IPSEC" for
an established IPSEC SA.

[1] https://libreswan.org/wiki/How_to_read_status_output

Change-Id: Iffff7d00f48e69fbc53bb45df17d6a5be6760a6d
Closes-Bug: #1781354
(cherry picked from commit 321392b9a7)
This commit is contained in:
Dongcan Ye 2018-07-12 09:00:13 +00:00 committed by Dongcan Ye
parent 5f96beba88
commit 3f36a0a552
2 changed files with 40 additions and 5 deletions

View File

@ -168,9 +168,9 @@ class BaseSwanProcess(object):
STATUS_RE = '\d\d\d "([a-f0-9\-]+).* (unrouted|erouted);'
STATUS_NOT_RUNNING_RE = 'Command:.*ipsec.*status.*Exit code: [1|3]$'
STATUS_IPSEC_SA_ESTABLISHED_RE = (
'\d{3} #\d+: "([a-f0-9\-]+).*IPsec SA established.*')
'\d{3} #\d+: "([a-f0-9\-]+).*established.*newest IPSEC')
STATUS_IPSEC_SA_ESTABLISHED_RE2 = (
'\d{3} #\d+: "([a-f0-9\-\/x]+).*IPsec SA established.*')
'\d{3} #\d+: "([a-f0-9\-\/x]+).*established.*newest IPSEC')
def __init__(self, conf, process_id, vpnservice, namespace):
self.conf = conf

View File

@ -293,12 +293,19 @@ EXPECTED_IPSEC_STRONGSWAN_SECRET_CONF = '''
'''
PLUTO_ACTIVE_STATUS = """000 "%(conn_id)s/0x1": erouted;\n
000 #4: "%(conn_id)s/0x1":500 STATE_QUICK_R2 (IPsec SA established);""" % {
000 #4: "%(conn_id)s/0x1":500 STATE_QUICK_R2 (IPsec SA established); \
newest IPSEC;""" % {
'conn_id': FAKE_IPSEC_SITE_CONNECTION2_ID}
PLUTO_ACTIVE_STATUS_IKEV2 = """000 "%(conn_id)s/0x1": erouted;\n
000 #4: "%(conn_id)s/0x1":500 STATE_PARENT_R2 (PARENT SA established); \
newest IPSEC;""" % {
'conn_id': FAKE_IPSEC_SITE_CONNECTION2_ID}
PLUTO_MULTIPLE_SUBNETS_ESTABLISHED_STATUS = """000 "%(conn_id1)s/1x1": erouted;\n
000 #4: "%(conn_id1)s/1x1":500 STATE_QUICK_R2 (IPsec SA established);\n
000 #4: "%(conn_id1)s/1x1":500 STATE_QUICK_R2 (IPsec SA established); \
newest IPSEC;\n
000 "%(conn_id2)s/2x1": erouted;\n
000 #4: "%(conn_id2)s/2x1":500 STATE_QUICK_R2 (IPsec SA established);\n""" % {
000 #4: "%(conn_id2)s/2x1":500 STATE_QUICK_R2 (IPsec SA established); \
newest IPSEC;\n""" % {
'conn_id1': FAKE_IPSEC_SITE_CONNECTION1_ID,
'conn_id2': FAKE_IPSEC_SITE_CONNECTION2_ID}
PLUTO_ACTIVE_NO_IPSEC_SA_STATUS = """000 "%(conn_id)s/0x1": erouted;\n
@ -798,6 +805,29 @@ class IPSecDeviceLegacy(BaseIPsecDeviceDriver):
self.assertEqual(constants.ACTIVE,
ipsec_site_conn[connection_id]['status'])
def _test_status_handling_for_ike_v2_active_connection(self,
active_status):
"""Test status handling for active connection."""
router_id = self.router.router_id
connection_id = FAKE_IPSEC_SITE_CONNECTION2_ID
ike_policy = {'ike_version': 'v2',
'encryption_algorithm': 'aes-128',
'auth_algorithm': 'sha1',
'pfs': 'group5',
'lifetime_value': 3600}
vpn_service = FAKE_VPN_SERVICE
for isc in vpn_service["ipsec_site_connections"]:
isc['ikepolicy'] = ike_policy
self.driver.ensure_process(router_id, vpn_service)
self._execute.return_value = active_status
self.driver.report_status(mock.Mock())
process_status = self.driver.process_status_cache[
router_id]
ipsec_site_conn = process_status['ipsec_site_connections']
self.assertEqual(constants.ACTIVE, process_status['status'])
self.assertEqual(constants.ACTIVE,
ipsec_site_conn[connection_id]['status'])
def _test_connection_names_handling_for_multiple_subnets(self,
active_status):
"""Test connection names handling for multiple subnets."""
@ -1392,6 +1422,11 @@ class TestOpenSwanProcess(IPSecDeviceLegacy):
"""Test status handling for active connection."""
self._test_status_handling_for_active_connection(PLUTO_ACTIVE_STATUS)
def test_status_handling_for_ike_v2_active_connection(self):
"""Test status handling for active connection."""
self._test_status_handling_for_ike_v2_active_connection(
PLUTO_ACTIVE_STATUS_IKEV2)
def test_status_handling_for_deleted_connection(self):
"""Test status handling for deleted connection."""
self._test_status_handling_for_deleted_connection(NOT_RUNNING_STATUS)