summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTibor Král <tibor.kral@pantheon.tech>2018-11-14 18:20:02 +0100
committerTibor Král <tibor.kral@pantheon.tech>2019-01-16 10:07:28 +0100
commit26589d440f332fe52238fa258d7d7b58df43eee5 (patch)
treedd3eaa8cf5cc3bd9fcfbff1239227c784ce935e7
parent8ad4f38beb1350d1cd62d11a9a15ac78ee0623f9 (diff)
HC2VPP-87: Expose IPSEC management
Change-Id: Ib13a2cdba5a0902581c455de67cc0ee64d20598d Signed-off-by: Tibor Král <tibor.kral@pantheon.tech>
-rw-r--r--ipsec/Ipsec_postman_collection.json486
-rw-r--r--ipsec/ipsec-api/pom.xml52
-rw-r--r--ipsec/ipsec-api/src/main/yang/hc2vpp-ietf-ipsec@2018-12-14.yang3679
-rw-r--r--ipsec/ipsec-api/src/main/yang/vpp-ipsec@2018-12-13.yang147
-rw-r--r--ipsec/ipsec-impl/pom.xml114
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/IpsecModule.java53
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecReaderFactory.java63
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizer.java127
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizer.java249
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizer.java68
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizer.java156
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizer.java104
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizer.java233
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizer.java148
-rw-r--r--ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecWriterFactory.java119
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/IpsecModuleTest.java83
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/helpers/SchemaContextTestHelper.java35
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizerTest.java113
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizerTest.java116
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizerTest.java60
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizerTest.java167
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizerTest.java119
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizerTest.java287
-rw-r--r--ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizerTest.java175
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_after.json25
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_before.json25
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/addIkev2Profile.json25
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_ipv4.json8
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_rfc822.json8
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_fqdn.json8
-rw-r--r--ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_ipv6.json8
-rw-r--r--ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry.json32
-rw-r--r--ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_after.json25
-rw-r--r--ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_before.json32
-rw-r--r--ipsec/ipsec-impl/src/test/resources/sadEntries/delSadEntry.json11
-rw-r--r--ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd.json31
-rw-r--r--ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_after.json21
-rw-r--r--ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_before.json21
-rw-r--r--ipsec/pom.xml61
-rw-r--r--pom.xml1
-rw-r--r--vpp-integration/minimal-distribution/pom.xml6
41 files changed, 7301 insertions, 0 deletions
diff --git a/ipsec/Ipsec_postman_collection.json b/ipsec/Ipsec_postman_collection.json
new file mode 100644
index 000000000..cbe0759d3
--- /dev/null
+++ b/ipsec/Ipsec_postman_collection.json
@@ -0,0 +1,486 @@
+{
+ "info": {
+ "_postman_id": "d17abd36-ad9a-4b5f-bb10-fe09c412dbe6",
+ "name": "IPsec",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+ },
+ "item": [
+ {
+ "name": "Add Sad Entry - ESP",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"sad-entries\": [\n\t\t{\n\t\t\t\"sa-id\":10,\n\t\t\t\"spi\": 1001,\n\t\t\t\"anti-replay-window\": 88,\n\t\t\t\"direction\": \"outbound\",\n\t\t\t\"security-protocol\": \"esp\",\n\t\t\t\"esp\": {\n\t\t\t\t\"authentication\" : {\n\t\t\t\t\t\"hmac-sha1-96\" : {\n\t\t\t\t\t\t\"key-str\" : \"0123456789012345\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"encryption\" : {\n\t\t\t\t\t\"aes-128-cbc\": {\n\t\t\t\t\t\t\"key-str\" : \"0123456789012345\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"source-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.3\"\n\t\t\t},\n\t\t\t\"destination-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.2\"\n\t\t\t}\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/sad/sad-entries/1001/outbound",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ "sad",
+ "sad-entries",
+ "1001",
+ "outbound"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Sad Entry - ESP inbound",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"sad-entries\": [\n\t\t{\n\t\t\t\"sa-id\":20,\n\t\t\t\"spi\": 1002,\n\t\t\t\"anti-replay-window\": 88,\n\t\t\t\"direction\": \"inbound\",\n\t\t\t\"security-protocol\": \"esp\",\n\t\t\t\"esp\": {\n\t\t\t\t\"authentication\" : {\n\t\t\t\t\t\"hmac-sha1-96\" : {\n\t\t\t\t\t\t\"key-str\" : \"0123456789012345\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"encryption\" : {\n\t\t\t\t\t\"aes-128-cbc\": {\n\t\t\t\t\t\t\"key-str\" : \"0123456789012345\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"source-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.3\"\n\t\t\t},\n\t\t\t\"destination-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.2\"\n\t\t\t}\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/sad/sad-entries/1002/inbound",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ "sad",
+ "sad-entries",
+ "1002",
+ "inbound"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Sad Entry- AH",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"sad-entries\": [\n\t\t{\n\t\t\t\"sa-id\":50,\n\t\t\t\"spi\": 1005,\n\t\t\t\"anti-replay-window\": 55,\n\t\t\t\"direction\": \"inbound\",\n\t\t\t\"security-protocol\": \"ah\",\n\t\t\t\"ah\": {\n\t\t\t\t\"hmac-sha1-96\" : {\n\t\t\t\t\t\"key-str\" : \"0123456789055555\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"source-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.5\"\n\t\t\t},\n\t\t\t\"destination-address\": {\n\t\t\t\t\"ipv4-address\": \"192.168.100.55\"\n\t\t\t}\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/sad/sad-entries/1005/inbound",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ "sad",
+ "sad-entries",
+ "1005",
+ "inbound"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add SPD",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"spd\": [\n\t\t{\n\t\t\t\"spd-id\":10,\n\t\t\t\"spd-entries\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"testEntry1\",\n\t\t\t\t\t\"priority\":10,\n\t\t\t\t\t\"direction\":\"inbound\",\n\t\t\t\t\t\"operation\":\"bypass\",\n\t\t\t\t\t\"laddr-start\":\"192.168.4.4\",\n\t\t\t\t\t\"laddr-stop\":\"192.168.4.4\",\n\t\t\t\t\t\"raddr-start\":\"192.168.3.3\",\n\t\t\t\t\t\"raddr-stop\":\"192.168.3.3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"testEntry2\",\n\t\t\t\t\t\"priority\":100,\n\t\t\t\t\t\"direction\":\"outbound\",\n\t\t\t\t\t\"operation\":\"discard\",\n\t\t\t\t\t\"laddr-start\":\"192.168.5.5\",\n\t\t\t\t\t\"laddr-stop\":\"192.168.5.5\",\n\t\t\t\t\t\"raddr-start\":\"192.168.6.6\",\n\t\t\t\t\t\"raddr-stop\":\"192.168.6.6\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/spd/10",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ "spd",
+ "10"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Ikev2 profile SHARED-KEY",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"policy\": [\n\t\t{\n\t\t\t\"name\":\"testPolicy\",\n\t\t\t\"lifetime\": 0,\n\t\t\t\"connection-type\":\"both\",\n\t\t\t\"description\": \"policy profile named testPolicy\",\n\t\t\t\"authentication\": {\n\t\t\t\t\"preshared-key\":\"true\"\n\t\t\t},\n\t\t\t\"pre-shared-key\":\"Vpp0123456789123\",\n\t\t\t\"traffic-selectors\": [\n\t\t\t\t{\n\t\t\t\t\t\"ts-name\":\"ts1\",\n\t\t\t\t\t\"protocol\":0,\n\t\t\t\t\t\"local-address-low\":\"192.168.124.0\",\n\t\t\t\t\t\"local-address-high\":\"192.168.124.255\",\n\t\t\t\t\t\"local-port-low\":0,\n\t\t\t\t\t\"local-port-high\":65535\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ikev2/policy/testPolicy",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ikev2",
+ "policy",
+ "testPolicy"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Ikev2 profile RSA",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"policy\": [\n\t\t{\n\t\t\t\"name\":\"testPolicyRsa\",\n\t\t\t\"lifetime\": 0,\n\t\t\t\"connection-type\":\"both\",\n\t\t\t\"description\": \"policy profile named testPolicyRsa\",\n\t\t\t\"authentication\": {\n\t\t\t\t\"rsa-signature\":\"true\"\n\t\t\t},\n\t\t\t\"certificate\":\"/home/localadmin/certs/server-cert.pem\"\n\t\t}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ikev2/policy/testPolicyRsa",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ikev2",
+ "policy",
+ "testPolicyRsa"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Ikev2 profile local ID FQDN",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"identity\": {\n\t\t\"local\": {\n\t\t\t\"fqdn-string\":\"vpp.home\"\n\t\t}\n\t}\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ikev2/policy/testPolicy/identity",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ikev2",
+ "policy",
+ "testPolicy",
+ "identity"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Add Ikev2 profile remote ID IPv4",
+ "request": {
+ "method": "PUT",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"identity\": {\n\t\t\"remote\": {\n\t\t\t\"ipv4-address\":\"192.168.123.20\"\n\t\t}\n\t}\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ikev2/policy/testPolicy/identity",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ikev2",
+ "policy",
+ "testPolicy",
+ "identity"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Show SAD 1001 outbound - config",
+ "request": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"relay\": [\n\t\t{\n\t\t\t\"address-family\": \"vpp-fib-table-management:ipv4\",\n\t\t\t\"rx-vrf-id\": 0,\n\t\t\t\"server-address\": \"1.2.3.4\",\n\t\t\t\"gateway-address\": \"5.6.7.8\"}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/sad/sad-entries/1001/outbound",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ "sad",
+ "sad-entries",
+ "1001",
+ "outbound"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Show IPSEC - oper",
+ "request": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"relay\": [\n\t\t{\n\t\t\t\"address-family\": \"vpp-fib-table-management:ipv4\",\n\t\t\t\"rx-vrf-id\": 0,\n\t\t\t\"server-address\": \"1.2.3.4\",\n\t\t\t\"gateway-address\": \"5.6.7.8\"}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/operational/hc2vpp-ietf-ipsec:ipsec-state/",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "operational",
+ "hc2vpp-ietf-ipsec:ipsec-state",
+ ""
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Show IPSEC - oper SPD",
+ "request": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"relay\": [\n\t\t{\n\t\t\t\"address-family\": \"vpp-fib-table-management:ipv4\",\n\t\t\t\"rx-vrf-id\": 0,\n\t\t\t\"server-address\": \"1.2.3.4\",\n\t\t\t\"gateway-address\": \"5.6.7.8\"}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/operational/hc2vpp-ietf-ipsec:ipsec-state/spd/10/spd-interfaces/",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "operational",
+ "hc2vpp-ietf-ipsec:ipsec-state",
+ "spd",
+ "10",
+ "spd-interfaces",
+ ""
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Show IPSEC Config",
+ "request": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"relay\": [\n\t\t{\n\t\t\t\"address-family\": \"vpp-fib-table-management:ipv4\",\n\t\t\t\"rx-vrf-id\": 0,\n\t\t\t\"server-address\": \"1.2.3.4\",\n\t\t\t\"gateway-address\": \"5.6.7.8\"}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ipsec/",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ipsec",
+ ""
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Show Ikev2",
+ "request": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Authorization",
+ "value": "Basic YWRtaW46YWRtaW4="
+ },
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"relay\": [\n\t\t{\n\t\t\t\"address-family\": \"vpp-fib-table-management:ipv4\",\n\t\t\t\"rx-vrf-id\": 0,\n\t\t\t\"server-address\": \"1.2.3.4\",\n\t\t\t\"gateway-address\": \"5.6.7.8\"}\n\t]\n}\n"
+ },
+ "url": {
+ "raw": "http://localhost:8183/restconf/config/hc2vpp-ietf-ipsec:ikev2/",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8183",
+ "path": [
+ "restconf",
+ "config",
+ "hc2vpp-ietf-ipsec:ikev2",
+ ""
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+} \ No newline at end of file
diff --git a/ipsec/ipsec-api/pom.xml b/ipsec/ipsec-api/pom.xml
new file mode 100644
index 000000000..169f55cf5
--- /dev/null
+++ b/ipsec/ipsec-api/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2019 PANTHEON.tech.
+
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>api-parent</artifactId>
+ <version>1.19.01-SNAPSHOT</version>
+ <relativePath>../../common/api-parent</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>io.fd.hc2vpp.ipsec</groupId>
+ <artifactId>ipsec-api</artifactId>
+ <name>${project.artifactId}</name>
+ <version>1.19.01-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <naming.context.version>1.19.01-SNAPSHOT</naming.context.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types-20130715</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types-2013-07-15</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.hc2vpp.v3po</groupId>
+ <artifactId>v3po-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/ipsec/ipsec-api/src/main/yang/hc2vpp-ietf-ipsec@2018-12-14.yang b/ipsec/ipsec-api/src/main/yang/hc2vpp-ietf-ipsec@2018-12-14.yang
new file mode 100644
index 000000000..6df2c6588
--- /dev/null
+++ b/ipsec/ipsec-api/src/main/yang/hc2vpp-ietf-ipsec@2018-12-14.yang
@@ -0,0 +1,3679 @@
+module hc2vpp-ietf-ipsec {
+ namespace "urn:ietf:params:xml:ns:yang:ietf-ipsec";
+ prefix "eipsec";
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import ietf-yang-types {
+ prefix yang;
+ }
+
+ organization "Ericsson AB.
+ Huawei Technologies India Pvt Ltd.";
+
+ contact "Web: <http://www.ericsson.com>";
+
+ description
+ "This YANG module defines the configuration and operational
+ state data for Internet Protocol Security (IPSec) on
+ IETF draft.
+ Copyright (c) 2016 Ericsson AB.
+ All rights reserved.";
+
+ revision 2018-12-14 {
+ description
+ "HC2VPP modifications for use case with VPP.
+ See https://jira.fd.io/browse/HC2VPP-399";
+ }
+
+ revision 2016-03-09 {
+ description
+ "Third revision.
+ Fix YANG compiling error because it used internal
+ data model econtext and should be removed in the
+ draft.
+ Fix warnings.
+ Run validation on
+ http://www.netconfcentral.org/yangdumpresults";
+ reference
+ "Update since second revision.";
+ }
+ revision 2015-09-13 {
+ description
+ "Second revision.";
+ reference
+ "updates since initial revision.
+ combining:
+ draft-tran-ipecme-yang-ipsec-00.
+ draft-wang-ipsecme-ike-yang-00.
+ draft-wang-ipsecme-ipsec-yang-00.";
+ }
+ revision 2015-05-14 {
+ description
+ "Initial revision.";
+ reference
+ "May 14, 2015 draft-tran-ipecme-yang-ipsec-00.
+ May 22, 2015 draft-wang-ipsecme-ike-yang-00.
+ June 15, 2015 draft-wang-ipsecme-ipsec-yang-00.";
+ }
+ /*--------------------*/
+ /* Feature */
+ /*--------------------*/
+
+ feature ikev1 {
+ description
+ "Feature IKEv1";
+ }
+
+ feature ike-proposal-state {
+ description
+ "IKEv2 Proposal Operational State";
+ }
+
+ feature ike-policy-state {
+ description
+ "IKEv1 Policy Operational State";
+ }
+
+ feature ikev1-state {
+ description
+ "IKEv1 Operational State";
+ }
+
+ feature ike-reauth-failure {
+ description
+ "IKEv1 Reauthorization Failure";
+ }
+
+ feature ike-rekey-failure {
+ description
+ "IKEv1 Rekey Failure";
+ }
+
+
+ feature ikev2 {
+ description
+ "Feature IKEv2";
+
+ }
+
+ feature ikev2-global {
+ description
+ "Feature IKEv2 Global Parameters";
+
+ }
+
+ feature ikev2-peer {
+ description
+ "Feature IKEv2 Peer";
+
+ }
+
+ feature ikev2-proposal {
+ description
+ "Feature IKEv2 Proposal";
+
+ }
+
+ feature ikev2-policy {
+ description
+ "Feature IKEv2 Policy";
+
+ }
+
+ feature ikev2-proposal-state {
+ description
+ "IKEv2 Proposal Operational State";
+ }
+
+ feature ikev2-state {
+ description
+ "IKEv2 Operational State";
+ }
+
+ feature ipsec {
+ description
+ "Feature IPsec";
+
+ }
+
+ feature ipsec-acl {
+ description
+ "Feature IPsec ACL";
+
+ }
+ feature ipsec-sad {
+ description
+ "Feature IPsec SAD";
+
+ }
+
+ feature ipsec-proposal {
+ description
+ "Feature IPsec Proposal";
+
+ }
+
+ feature ipsec-spd {
+ description
+ "Feature IPsec SPD";
+
+ }
+
+ feature ipsec-policy-state {
+ description
+ "IPsec Policy Operational State";
+ }
+
+ feature ipsec-proposal-state {
+ description
+ "IPsec Proposal Operational State";
+ }
+
+ feature ipsec-alarms-state {
+ description
+ "IPsec Alarm State Operational State";
+ }
+
+ feature ipsec-sa-ah-state {
+ description
+ "IPsec SA AH Operational State";
+ }
+
+ feature ipsec-sa-state {
+ description
+ "IPsec SA Operational State";
+ }
+
+ feature ipsec-tunnel {
+ description
+ "IPsec Tunnel";
+ }
+
+ feature ipsec-local-address-range {
+ description
+ "IPsec Local Address Range";
+ }
+
+ feature ipsec-remote-address-range {
+ description
+ "IPsec Remote Address Range";
+ }
+
+ feature ipsec-next-protocol-range {
+ description
+ "IPsec Next Protocol Range";
+ }
+
+ feature ipsec-local-port-range {
+ description
+ "IPsec Local Port Range";
+ }
+
+ feature ipsec-remote-port-range {
+ description
+ "IPsec Remote Port Range";
+ }
+
+ feature ipsec-ah-authentication {
+ description
+ "IPsec AH Authentication";
+ }
+
+ feature ipsec-esp-integrity {
+ description
+ "IPsec ESP Integrity";
+ }
+
+ feature ipsec-esp-encrypt {
+ description
+ "IPsec ESP encryption";
+ }
+
+ feature ipsec-stat {
+ description
+ "IPsec Stats";
+ }
+
+ feature ipsec-state {
+ description
+ "IPsec Operational State";
+ }
+
+ feature ipsec-rekey-failure {
+ description
+ "IPsec Rekey Failure";
+ }
+
+ feature ipsec-redundancy {
+ description
+ "IPsec Redundancy State";
+ }
+
+ feature sad {
+ description
+ "Security Association (SA) Database";
+ }
+
+ feature spd {
+ description
+ "Security Policy Database";
+ }
+
+ feature ipsec-global-stats {
+ description
+ "IPsec Global Stats";
+ }
+
+ feature clear-ipsec-group {
+ description
+ "Clear IPsec group";
+ }
+
+ feature clear-ike-group {
+ description
+ "Clear IKE group";
+ }
+
+ feature clear-ikev2-group {
+ description
+ "Clear IKEv2 group";
+ }
+
+ feature reset-ipv4 {
+ description
+ "Reset IPv4";
+ }
+
+ feature reset-ipv6 {
+ description
+ "Reset IPv6";
+ }
+
+ feature reset-global {
+ description
+ "Reset Global";
+ }
+
+ feature peer-authentication-failure {
+ description
+ "Peer Authentication Failure";
+ }
+ /*--------------------*/
+ /* Typedefs */
+ /*--------------------*/
+
+ typedef authentication-method-t {
+ type enumeration {
+ enum psk {
+ value 0;
+ description
+ "Pre-Sharing Keys.";
+ }
+ enum certificate {
+ value 1;
+ description
+ "Certificate.";
+ }
+ }
+ description
+ "Available authentication methods.";
+ }
+
+ /* IKEv2 Exchange Types (ET) */
+ typedef ikev2-exchange-type-t {
+ type enumeration {
+ enum ikev2-et-ike-sa-init {
+ value 34;
+ description
+ "ikev2-et-ike-sa-init - RFC 7296.";
+ }
+ enum ikev2-et-ike-auth {
+ value 35;
+ description
+ "ikev2-et-ike-auth - RFC 7296.";
+ }
+ enum ikev2-et-create-child-sa {
+ value 36;
+ description
+ "ikev2-et-create-child-sa - RFC 7296.";
+ }
+ enum ikev2-et-informational {
+ value 37;
+ description
+ "ikev2-et-informational - RFC 7296.";
+ }
+ enum ikev2-et-ike-session-resume {
+ value 38;
+ description
+ "ikev2-et-ike-session-resume - RFC 7296.";
+ }
+ enum ikev2-et-gsa-auth {
+ value 39;
+ description
+ "ikev2-et-gsa-auth - RFC 7296.";
+ }
+ enum ikev2-et-gsa-registration {
+ value 40;
+ description
+ "ikev2-et-gsa-registration - RFC 7296.";
+ }
+ enum ikev2-et-gsa-rekey {
+ value 41;
+ description
+ "ikev2-et-gsa-rekey - RFC 7296.";
+ }
+ }
+ description
+ "IKEv2 Exchange Types (ET).";
+ }
+
+ /* Transform Type Values (TTV), RFC 7296 */
+ typedef transform-type-value-t {
+ type enumeration {
+ enum ttv-reserved-0 {
+ value 0;
+ description
+ "ttv-reserved-0 - Transform Type Value Reserved "+
+ "(RFC 7296).";
+ }
+ enum ttv-encr {
+ value 1;
+ description
+ "ttv-encr - Transform Type Value 1,
+ Encryption Algorithm "+
+ "(ENCR) used in IKE and ESP.";
+ }
+ enum ttv-prf {
+ value 2;
+ description
+ "ttv-prf - Transform Type Value 2, "+
+ "Pseudo-Random Function(PRF) used in IKE.";
+ }
+ enum ttv-integ {
+ value 3;
+ description
+ "ttv-integ - Transform Type Value 3, Integrity Algorithm"+
+ " (INTEG) used in IKE, AH, optional ESP.";
+ }
+ enum ttv-dh {
+ value 4;
+ description
+ "ttv-dh - Transform Type Value 4, Diffie-Hellman (DH) "+
+ "used in IKE, optional AH and ESP.";
+ }
+ enum ttv-esn {
+ value 5;
+ description
+ "ttv-esn - Transform Type Value 5, Extended Sequence "+
+ "Numbers (ESN) used in AH and ESP.";
+ }
+ }
+ description
+ "Transform Type Values (RFC 7296).";
+ }
+
+ /* IKEv2 Transform Attribute Types (TAT) */
+ typedef ikev2-transform-attribute-type-t {
+ type enumeration {
+ enum ikev2-tat-reserved-0 {
+ value 0;
+ description
+ "ikev2-tat-reserved-0 - IKEv2 Transform Attribute "+
+ "Type Reserved-0 (RFC 7296).";
+ }
+ enum ikev2-tat-reserved-1 {
+ value 1;
+ description
+ "ikev2-tat-reserved-1 - IKEv2 Transform Attribute "+
+ "Type Reserved-1 (RFC 7296).";
+ }
+ enum ikev2-tat-reserved-13 {
+ value 13;
+ description
+ "ikev2-tat-reserved-13 - IKEv2 Transform Attribute "+
+ "Type Reserved-13 (RFC 7296).";
+ }
+ enum ikev2-tat-key-length {
+ value 41;
+ description
+ "ikev2-tat-key-length - IKEv2 Transform Attribute "+
+ "Type KEY LENGTH (in bits) (RFC 7296).";
+ }
+ }
+ description
+ "IKEv2 Transform Attribute Types (TAT) (RFC 7296).";
+ }
+
+ /* Transform Type 1 (Encryption Algorithm Transform IDs) */
+ typedef ike-encryption-algorithm-t {
+ type enumeration {
+ enum encr-reserved-0 {
+ value 0;
+ description
+ "encr-reserved-0 --> RFC_5996.";
+ }
+ enum encr-des-iv4 {
+ value 1;
+ description
+ "encr-des-iv4 --> RFC_5996.";
+ }
+ enum encr-des {
+ value 2;
+ description
+ "encr-des --> RFC_5996.";
+ }
+ enum encr-3des {
+ value 3;
+ description
+ "encr-3des --> RFC_5996.";
+ }
+ enum encr-rc5 {
+ value 4;
+ description
+ "encr-rc5 --> RFC_5996.";
+ }
+ enum encr-idea {
+ value 5;
+ description
+ "encr-idea --> RFC_5996.";
+ }
+ enum encr-cast {
+ value 6;
+ description
+ "encr-cast --> RFC_5996.";
+ }
+ enum encr-blowfish {
+ value 7;
+ description
+ "encr-blowfish --> RFC_5996.";
+ }
+ enum encr-3idea {
+ value 8;
+ description
+ "encr-3idea --> RFC_5996.";
+ }
+ enum encr-des-iv32 {
+ value 9;
+ description
+ "encr-des-iv32 --> RFC_5996.";
+ }
+ enum encr-reserved-10 {
+ value 10;
+ description
+ "encr-reserved-10 --> RFC_5996.";
+ }
+ enum encr-null {
+ value 11;
+ description
+ "encr-null --> RFC_5996.";
+ }
+ enum encr-aes-cbc {
+ value 12;
+ description
+ "encr-aes-cbc --> RFC_5996.";
+ }
+ enum encr-aes-ctr {
+ value 13;
+ description
+ "encr-aes-ctr --> RFC_5996.";
+ }
+ enum encr-aes-ccm-8 {
+ value 14;
+ description
+ "encr-aes-ccm-8 --> RFC_5996.";
+ }
+ enum encr-aes-ccm-12 {
+ value 15;
+ description
+ "encr-aes-ccm-12 --> RFC_5996.";
+ }
+ enum encr-aes-ccm-16 {
+ value 16;
+ description
+ "encr-aes-ccm-16 --> RFC_5996.";
+ }
+ enum encr-reserved-17 {
+ value 17;
+ description
+ "encr-reserved-17 --> RFC_5996.";
+ }
+ enum encr-aes-gcm-8-icv {
+ value 18;
+ description
+ "encr-aes-gcm-8-icv --> RFC_5996.";
+ }
+ enum encr-aes-gcm-12-icv {
+ value 19;
+ description
+ "encr-aes-gcm-12-icv --> RFC_5996.";
+ }
+ enum encr-aes-gcm-16-icv {
+ value 20;
+ description
+ "encr-aes-gcm-16-icv--> RFC_5996.";
+ }
+ enum encr-null-auth-aes-gmac {
+ value 21;
+ description
+ "encr-null-auth-aes-gmac --> RFC_5996.";
+ }
+ enum encr-ieee-p1619-xts-aes {
+ value 22;
+ description
+ "encr-ieee-p1619-xts-aes --> Reserved for "+
+ "IEEE P1619 XTS-AES.";
+ }
+ enum encr-camellia-cbc {
+ value 23;
+ description
+ "encr-camellia-cbc --> RFC_5996.";
+ }
+ enum encr-camellia-ctr {
+ value 24;
+ description
+ "encr-camellia-ctr --> RFC_5996.";
+ }
+ enum encr-camellia-ccm-8-icv {
+ value 25;
+ description
+ "encr-camellia-ccm-8-icv --> RFC_5996.";
+ }
+ enum encr-camellia-ccm-12-icv {
+ value 26;
+ description
+ "encr-camellia-ccm-12-icv --> RFC_5996.";
+ }
+ enum encr-camellia-ccm-16-icv {
+ value 27;
+ description
+ "encr-camellia-ccm-16-icv --> RFC_5996.";
+ }
+ enum encr-aes-cbc-128 {
+ value 1024;
+ description
+ "encr-aes-cbc-128 --> RFC_5996.";
+ }
+ enum encr-aes-cbc-192 {
+ value 1025;
+ description
+ "encr-aes-cbc-192 --> RFC_5996.";
+ }
+ enum encr-aes-cbc-256 {
+ value 1026;
+ description
+ "encr-aes-cbc-256 --> RFC_5996.";
+ }
+ enum encr-blowfish-128 {
+ value 1027;
+ description
+ "encr-blowfish-128 --> RFC_5996.";
+ }
+ enum encr-blowfish-192 {
+ value 1028;
+ description
+ "encr-blowfish-192 --> RFC_5996.";
+ }
+ enum encr-blowfish-256 {
+ value 1029;
+ description
+ "encr-blowfish-256 --> RFC_5996.";
+ }
+ enum encr-blowfish-448 {
+ value 1030;
+ description
+ "encr-blowfish-448 --> RFC_5996.";
+ }
+ enum encr-camellia-128 {
+ value 1031;
+ description
+ "encr-camellia-128 --> RFC_5996.";
+ }
+ enum encr-camellia-192 {
+ value 1032;
+ description
+ "encr-camellia-192 --> RFC_5996.";
+ }
+ enum encr-camellia-256 {
+ value 1033;
+ description
+ "encr-camellia-256 --> RFC_5996.";
+ }
+ }
+ description
+ "Transform Type 1 - Internet Key Exchange (IKE) "+
+ "encryption algorithms.";
+ }
+
+ /* Transform Type 2 (Pseudo-Random Function PRF) */
+ typedef pseudo-random-function-t {
+ type enumeration {
+ enum prf-reserved-0 {
+ value 0;
+ description
+ "prf-reserved-0 --> RFC_2104.";
+ }
+ enum prf-hmac-md5 {
+ value 1;
+ description
+ "prf-hmac-md5 --> RFC_2104.";
+ }
+ enum prf-hmac-sha1 {
+ value 2;
+ description
+ "prf-hmac-sha1 --> RFC2104.";
+ }
+ enum prf-hmac-tiger {
+ value 3;
+ description
+ "prf-hmac-tiger --> RFC2104.";
+ }
+ enum prf-aes128-xcbc {
+ value 4;
+ description
+ "prf-aes128-xcbc --> RFC_4434.";
+ }
+ enum prf-hmac-sha2-256 {
+ value 5;
+ description
+ "prf-hmac-sha2-256 --> RFC_4434.";
+ }
+ enum prf-hmac-sha2-384 {
+ value 6;
+ description
+ "prf-hmac-sha2-384 --> RFC_4434.";
+ }
+ enum prf-hmac-sha2-512 {
+ value 7;
+ description
+ "prf-hmac-sha2-512 --> RFC_4434.";
+ }
+ enum prf-aes128-cmac {
+ value 8;
+ description
+ "prf-aes128-cmac --> RFC_4615.";
+ }
+ }
+ description
+ "Available Pseudo-Random Functions (PRF).";
+ }
+
+ /* Transform Type 3 (Integrity Algorithm) */
+ typedef ike-integrity-algorithm-t {
+ type enumeration {
+ enum auth-none {
+ value 0;
+ description
+ "auth-none --> RFC_5996.";
+ }
+ enum auth-hmac-md5-96 {
+ value 1;
+ description
+ "auth-hmac-md5-96 --> RFC_5996.";
+ }
+ enum auth-hmac-sha1-96 {
+ value 2;
+ description
+ "auth-hmac-sha1-96 --> RFC_5996.";
+ }
+ enum auth-des-mac {
+ value 3;
+ description
+ "auth-des-mac --> RFC_5996.";
+ }
+ enum auth-kpdk-md5 {
+ value 4;
+ description
+ "auth-kpdk-md5 --> RFC_5996.";
+ }
+ enum auth-aes-xcbc-96 {
+ value 5;
+ description
+ "auth-aes-xcbc-96 --> RFC_5996.";
+ }
+ enum auth-hmac-md5-128 {
+ value 6;
+ description
+ "auth-hmac-md5-128 --> RFC_5996.";
+ }
+ enum auth-hmac-sha1-160 {
+ value 7;
+ description
+ "auth-hmac-sha1-160 --> RFC_5996.";
+ }
+ enum auth-aes-cmac-96 {
+ value 8;
+ description
+ "auth-aes-cmac-96 --> RFC_5996.";
+ }
+ enum auth-aes-128-gmac {
+ value 9;
+ description
+ "auth-aes-128-gmac --> RFC_5996.";
+ }
+ enum auth-aes-192-gmac {
+ value 10;
+ description
+ "auth-aes-192-gmac --> RFC_5996.";
+ }
+ enum auth-aes-256-gmac {
+ value 11;
+ description
+ "auth-aes-256-gmac --> RFC_5996.";
+ }
+ enum auth-hmac-sha2-256-128 {
+ value 12;
+ description
+ "auth-hmac-sha2-256-128 --> RFC_5996.";
+ }
+ enum auth-hmac-sha2-384-192 {
+ value 13;
+ description
+ "auth-hmac-sha2-384-192 --> RFC_5996.";
+ }
+ enum auth-hmac-sha2-512-256 {
+ value 14;
+ description
+ "auth-hmac-sha2-512-256 --> RFC_5996.";
+ }
+ enum auth-hmac-sha2-256-96 {
+ value 1024;
+ description
+ "auth-hmac-sha2-256-96.";
+ }
+ }
+ description
+ "Transform Type 3 - Internet Key Exchange (IKE) "+
+ "Integrity Algorithms.";
+ }
+
+ /* Transform Type 4 (Diffie-Hellman Group) */
+ typedef diffie-hellman-group-t {
+ type enumeration {
+ enum group-none {
+ value 0;
+ description
+ "group-none --> RFC_5996.";
+ }
+ enum modp-768-group-1 {
+ value 1;
+ description
+ "modp-768-group-1 --> RFC_5996.";
+ }
+ enum modp-1024-group-2 {
+ value 2;
+ description
+ "modp-1024-group-2 --> RFC_5996.";
+ }
+ enum modp-1536-group-5 {
+ value 5;
+ description
+ "modp-1536-group-5 --> RFC_3526.";
+ }
+ enum modp-2048-group-14 {
+ value 14;
+ description
+ "modp-2048-group-14 --> RFC_3526.";
+ }
+ enum modp-3072-group-15 {
+ value 15;
+ description
+ "modp-3072-group-15 --> RFC_3526.";
+ }
+ enum modp-4096-group-16 {
+ value 16;
+ description
+ "modp-4096-group-16 --> RFC_3526.";
+ }
+ enum modp-6144-group-17 {
+ value 17;
+ description
+ "modp-6144-group-17 --> RFC_3526.";
+ }
+ enum modp-8192-group-18 {
+ value 18;
+ description
+ "modp-8192-group-18 --> RFC_3526.";
+ }
+ enum recp-256-group-19 {
+ value 19;
+ description
+ "recp-256-group-19 --> RFC_6989. 256-bit"+
+ " Random ECP Group.";
+ }
+ enum recp-384-group-20 {
+ value 20;
+ description
+ "recp-384-group-20 --> RFC_6989. 384-bit"+
+ " Random ECP Group.";
+ }
+ enum recp-521-group-21 {
+ value 21;
+ description
+ "recp-521-group-21 --> RFC_6989. 521-bit"+
+ " Random ECP Group.";
+ }
+ enum modp-1024-160-pos-group-22 {
+ value 22;
+ description
+ "modp-1024-160-pos-group-22 --> RFC_6989."+
+ " 1024-bit MODP Group with"+
+ " 160-bit Prime Order Subgroup (POS).";
+ }
+ enum modp-2048-224-pos-group-23 {
+ value 23;
+ description
+ "modp-2048-224-pos-group-23 --> RFC_6989."+
+ " 2048-bit MODP Group with"+
+ " 224-bit Prime Order Subgroup (POS).";
+ }
+ enum modp-2048-256-pos-group-24 {
+ value 24;
+ description
+ "modp-2048-256-pos-group-24 --> RFC_6989."+
+ " 2048-bit MODP Group with"+
+ " 256-bit Prime Order Subgroup (POS).";
+ }
+ enum recp-192-group-25 {
+ value 25;
+ description
+ "recp-192-group-25 --> RFC_6989."+
+ " 192-bit Random ECP Group.";
+ }
+ enum recp-224-group-26 {
+ value 26;
+ description
+ "recp-224-group-26 --> RFC_6989."+
+ " 224-bit Random ECP Group.";
+ }
+ }
+ description
+ "Diffie-Hellman Groups (RFC 5996).";
+ }
+
+
+ /* Transform Type 5 (Extended Sequence Numbers
+ Transform ESN IDs) */
+ typedef extended-sequence-number-t {
+ type enumeration {
+ enum esn-none {
+ value 0;
+ description
+ "esn-none - Extended Sequence Number None --> RFC_7296.";
+ }
+ enum esn-1 {
+ value 1;
+ description
+ "esn-1 - Extended Sequence Number --> RFC_7296.";
+ }
+ }
+ description
+ "Extended Sequence Number (RFC 7296).";
+ }
+
+
+ typedef connection-type-t {
+ type enumeration {
+ enum initiator-only {
+ value 0;
+ description
+ "initiator-only: ME will act as initiator for"+
+ " bringing up IKEv2"+
+ " session with its IKE peer.";
+ }
+ enum responder-only {
+ value 1;
+ description
+ "responder-only: ME will act as responder for"+
+ " bringing up IKEv2"+
+ " session with its IKE peer.";
+ }
+ enum both {
+ value 2;
+ description
+ "both: ME can act as initiator or responder.";
+ }
+ }
+ description
+ "Connection type for IKE session.";
+ }
+
+ typedef transport-protocol-name-t {
+ type enumeration {
+ enum tcp {
+ value 1;
+ description
+ "Transmission Control Protocol (TCP) Transport Protocol.";
+ }
+ enum udp {
+ value 2;
+ description
+ "User Datagram Protocol (UDP) Transport Protocol";
+ }
+ enum sctp {
+ value 3;
+ description
+ "Stream Control Transmission Protocol (SCTP) Transport "+
+ "Protocol";
+ }
+ enum icmp {
+ value 4;
+ description
+ "Internet Control Message Protocol (ICMP) Transport "+
+ "Protocol";
+ }
+ }
+ description
+ "Enumeration of well known transport protocols.";
+ }
+
+ typedef preshared-key-t {
+ type string;
+ description
+ "Derived string used as Pre-Shared Key.";
+ }
+
+ typedef pad-type-t {
+ type enumeration {
+ enum dns-name {
+ value 1;
+ description
+ "DNS name (specific or partial)";
+ }
+ enum distinguished-name {
+ value 2;
+ description
+ "Distinguished Name (complete or sub-tree constrained)";
+ }
+ enum rfc-822 {
+ value 3;
+ description
+ "RFC 822 email address (complete or partially qualified)";
+ }
+ enum ipv4-range {
+ value 4;
+ description
+ "IPv4 Address Range";
+ }
+ enum ipv6-range {
+ value 5;
+ description
+ "IPv6 Address Range";
+ }
+ enum key-id {
+ value 6;
+ description
+ "Key ID (exact match only)";
+ }
+ }
+ description
+ "PAD Type";
+ }
+
+
+ /*-------------------------------------------------- */
+ /* draft-wang-ipsecme-ipsec-yang-00: ietf-ipsec-type */
+ /*-------------------------------------------------- */
+ typedef ipsec-mode {
+ type enumeration {
+ enum "transport" {
+ description
+ "Transport mode";
+ }
+ enum "tunnel" {
+ description
+ "Tunnel mode";
+ }
+ }
+ description
+ "type define of ipsec mode";
+ }
+
+ typedef ipsec-protocol {
+ type enumeration {
+ enum "ah" {
+ description
+ "AH Protocol";
+ }
+ enum "esp" {
+ description
+ "ESP Protocol";
+ }
+ }
+ description
+ "type define of ipsec security protocol";
+ }
+
+ typedef ipsec-spi {
+ type uint32 {
+ range "1..max";
+ }
+ description
+ "SPI";
+ }
+
+ typedef ipsec-spd-name {
+ type enumeration {
+ enum id_rfc_822_addr {
+ description
+ "Fully qualified user name string.";
+ }
+ enum id_fqdn {
+ description
+ "Fully qualified DNS name.";
+ }
+ enum id_der_asn1_dn {
+ description
+ "X.500 distinguished name.";
+ }
+ enum id_key {
+ description
+ "IKEv2 Key ID.";
+ }
+ }
+ description
+ "IPsec SPD name type";
+ }
+
+ typedef ipsec-traffic-direction {
+ type enumeration {
+ enum inbound {
+ description
+ "Inbound traffic";
+ }
+ enum outbound {
+ description
+ "Outbound traffic";
+ }
+ }
+ description
+ "IPsec traffic direction";
+ }
+
+ typedef ipsec-spd-operation {
+ type enumeration {
+ enum protect {
+ description
+ "PROTECT the traffic with IPsec";
+ }
+ enum bypass {
+ description
+ "BYPASS the traffic";
+ }
+ enum discard {
+ description
+ "DISCARD the traffic";
+ }
+ }
+ description
+ "The operation when traffic matches IPsec security policy";
+ }
+
+
+ /*---------------------------------------------------- */
+ /* draft-wang-ipsecme-ipsec-yang-00: ietf-ipsec-crypto */
+ /*---------------------------------------------------- */
+ typedef ipsec-authentication-algorithm {
+ type enumeration {
+ enum "null" {
+ value 0;
+ description
+ "null";
+ }
+ enum "md5" {
+ value 1;
+ description
+ "MD5 authentication algorithm";
+ }
+ enum "sha1" {
+ value 2;
+ description
+ "SHA1 authentication algorithm";
+ }
+ enum "sha2-256" {
+ value 3;
+ description
+ "SHA2-256 authentication algorithm";
+ }
+ enum "sha2-384" {
+ value 4;
+ description
+ "SHA2-384 authentication algorithm";
+ }
+ enum "sha2-512" {
+ value 5;
+ description
+ "SHA2-512 authentication algorithm";
+ }
+ }
+ description
+ "typedef for ipsec authentication algorithm";
+ }
+
+ typedef ipsec-encryption-algorithm {
+ type enumeration {
+ enum "null" {
+ description
+ "null";
+ }
+ enum "des" {
+ description
+ "DES encryption algorithm";
+ }
+ enum "3des" {
+ description
+ "3DES encryption algorithm";
+ }
+ enum "aes-128" {
+ description
+ "AES-128 encryption algorithm";
+ }
+ enum "aes-192" {
+ description
+ "AES-192 encryption algorithm";
+ }
+ enum "aes-256" {
+ description
+ "AES-256 encryption algorithm";
+ }
+ }
+ description
+ "typedef for ipsec encryption algorithm";
+ }
+
+ /*-------------------------------------------------- */
+ /* draft-wang-ipsecme-ike-yang-00: ietf-ipsec-type */
+ /*-------------------------------------------------- */
+ typedef ike-integrity-algorithm {
+ type enumeration {
+ enum "hmac-md5-96" {
+ description
+ "HMAC-MD5-96 Integrity Algorithm";
+ }
+ enum "hmac-sha1-96" {
+ description
+ "HMAC-SHA1-96 Integrity Algorithm";
+ }
+ enum "hmac-sha2-256" {
+ description
+ "HMAC-SHA2-256 Integrity Algorithm";
+ }
+ enum "hmac-sha2-384" {
+ description
+ "HMAC-SHA2-384 Integrity Algorithm";
+ }
+ enum "hmac-sha2-512" {
+ description
+ "HMAC-SHA2-512 Integrity Algorithm";
+ }
+ }
+ description
+ "typedef for ike integrity algorithm.";
+ }
+
+ typedef ike-encryption-algorithm {
+ type enumeration {
+ enum "des-cbc" {
+ description
+ "DES-CBC Encryption algorithm";
+ }
+ enum "3des-cbc" {
+ description
+ "3DES-CBC Encryption algorithm";
+ }
+ enum "aes-cbc-128" {
+ description
+ "AES-CBC-128 Encryption algorithm";
+ }
+ enum "aes-cbc-192" {
+ description
+ "AES-CBC-192 Encryption algorithm";
+ }
+ enum "aes-cbc-256" {
+ description
+ "AES-CBC-256 Encryption algorithm";
+ }
+ }
+ description
+ "typedef for ike encryption algorithm.";
+ }
+
+ typedef ike-prf-algorithm {
+ type enumeration {
+ enum "hmac-md5-96" {
+ description
+ "HMAC-MD5-96 PRF Algorithm";
+ }
+ enum "hmac-sha1-96" {
+ description
+ "HMAC-SHA1-96 PRF Algorithm";
+ }
+ enum "hmac-sha2-256" {
+ description
+ "HMAC-SHA2-256 PRF Algorithm";
+ }
+ enum "hmac-sha2-384" {
+ description
+ "HMAC-SHA2-384 PRF Algorithm";
+ }
+ enum "hmac-sha2-512" {
+ description
+ "HMAC-SHA2-512 PRF Algorithm";
+ }
+ }
+ description
+ "typedef for ike prf algorithm.";
+ }
+
+ typedef ike-dh-group {
+ type enumeration {
+ enum "dh-group-none" {
+ description
+ "None Diffie-Hellman group";
+ }
+ enum "dh-group-1" {
+ description
+ "768 bits Diffie-Hellman group";
+ }
+ enum "dh-group-2" {
+ description
+ "1024 bits Diffie-Hellman group";
+ }
+ enum "dh-group-5" {
+ description
+ "1536 bits Diffie-Hellman group";
+ }
+ enum "dh-group-14" {
+ description
+ "2048 bits Diffie-Hellman group";
+ }
+ }
+ description
+ "typedef for ike dh group";
+ }
+
+
+ typedef ike-peer-name-ref {
+ type leafref {
+ path "/ikev2/ike-peer/ike-peer-entries/peer-name";
+ }
+ description "reference to ike peer name";
+ }
+
+ typedef ike-proposal-number-ref {
+ type leafref {
+ path "/ikev2/proposal/name";
+ }
+ description "reference to ike proposal name";
+ }
+
+ typedef ipsec-proposal-name-ref{
+ type leafref {
+ path "/ipsec/proposal/ipsec-proposal/name";
+ }
+ description "reference to ike proposal name";
+ }
+
+ typedef ike-auth-method {
+ type enumeration {
+ enum pre-share {
+ description
+ "Select pre-shared key message as the
+ authentication method";
+ }
+ enum rsa-digital-signature {
+ description
+ "Select rsa digital signature as the
+ authentication method";
+ }
+ enum dss-digital-signature {
+ description
+ "Select dss digital signature as the
+ authentication method";
+ }
+ }
+ description "IKE authentication methods";
+ }
+
+ /*--------------------*/
+ /* grouping */
+ /*--------------------*/
+
+ /* The following groupings are used in both configuration data
+ and operational state data */
+ grouping name-grouping {
+ description
+ "This grouping provides a leaf identifying the name.";
+ leaf name {
+ type string;
+ description
+ "Name of a identifying.";
+ }
+ leaf description {
+ type string;
+ description
+ "Specify the description.";
+ }
+ }
+
+ grouping sequence-number-grouping {
+ description
+ "This grouping provides a leaf identifying
+ a sequence number.";
+ leaf sequence-number {
+ type uint32 {
+ range "1..4294967295";
+ }
+ description
+ "Specify the sequence number.";
+ }
+ }
+
+ grouping description-grouping {
+ description
+ "description for free use.";
+ leaf description {
+ type string;
+ description
+ "description for free use.";
+ }
+ }
+
+ grouping traffic-selector-grouping {
+ description
+ "Traffic selector to be used for SA negotiation.";
+ leaf traffic-selector-id {
+ type string;
+ mandatory true;
+ description
+ "Traffic selector identifier.";
+ }
+ leaf protocol-name {
+ type transport-protocol-name-t;
+ description
+ "Specifies the protocol selector.";
+ }
+ leaf address-range {
+ type string;
+ mandatory true;
+ description
+ "Specifies the IPv4 or IPv6 address range.";
+ }
+ }
+
+
+
+ grouping ike-general-proposal-grouping {
+ description
+ "IKE proposal.";
+ leaf name {
+ type string;
+ mandatory true;
+ description
+ "IKE Proposal identify.";
+ }
+ leaf description {
+ type string;
+ description
+ "Specify the description.";
+ }
+
+ leaf dh-group {
+ type diffie-hellman-group-t;
+ mandatory true;
+ description
+ "Specifies a Diffie-Hellman group.";
+ }
+ container encryption {
+ description
+ "Specify IKE Proposal encryption configuration";
+ leaf algorithm {
+ type ike-encryption-algorithm-t;
+ description
+ "Specifies an Encryption Algorithm.";
+ }
+ }
+ }
+
+ grouping ike-proposal-grouping {
+ description
+ "Configure the IKE Proposal";
+ uses ike-general-proposal-grouping;
+
+ leaf lifetime {
+ type uint32;
+ mandatory true;
+ description
+ "Configure lifetime for IKE SAs
+ 0: for no timeout.
+ 300 .. 99999999: IKE SA lifetime in seconds.";
+ }
+ container authentication {
+ description
+ "Specify IKE Proposal authentication configuration";
+ leaf algorithm {
+ type ike-integrity-algorithm-t;
+ description
+ "Specify the authentication algorithm";
+ }
+ leaf preshared-key {
+ type empty;
+ description
+ "Use pre-shared key based authentication";
+ }
+ leaf rsa-signature {
+ type empty;
+ description
+ "Use signature based authentication by using
+ PKI certificates";
+ }
+ }
+ }
+
+ grouping ikev2-proposal-grouping {
+ description
+ "Holds an IKEv2 transform proposal used during "+
+ "IKEv2 SA negotiation. Multiple IKEv2 Transforms "+
+ " can be proposed during an IKEv2 session initiation "+
+ "in an ordered list.";
+ uses ike-general-proposal-grouping;
+
+ leaf pseudo-random-function {
+ type pseudo-random-function-t;
+ mandatory true;
+ description
+ "Specifies Pseudo Random Function for IKEv2 key exchange";
+ }
+ container authentication {
+ description
+ "Specify IKEv2 Proposal authentication configuration";
+ leaf algorithm {
+ type ike-integrity-algorithm-t;
+ description
+ "Specify the authentication algorithm";
+ }
+ }
+ }
+
+ grouping ipsec-proposal-grouping {
+ description
+ "Configure IPSec Proposal";
+ leaf name {
+ type string;
+ mandatory true;
+ description
+ "IPSec proposal identifier.";
+ }
+ leaf ah {
+ type ike-integrity-algorithm-t;
+ description
+ "Configure Authentication Header (AH).";
+ }
+ container esp {
+ description
+ "Configure Encapsulating Security Payload (ESP).";
+ leaf authentication {
+ type ike-integrity-algorithm-t;
+ description
+ "Configure ESP authentication";
+ }
+ leaf encryption {
+ type ike-encryption-algorithm-t;
+ description
+ "Configure ESP encryption";
+ }
+ }
+ leaf ip-comp{
+ type empty;
+ description
+ "Enable IPSec proposal IP-COMP which uses the IP Payload "+
+ "compression protocol to compress IP Security (IPSec) "+
+ "packets before encryption";
+ }
+ container lifetime {
+ description
+ "Configure lifetime for IPSEC SAs";
+ leaf kbytes {
+ type uint32 {
+ range "128..2147483647";
+ }
+ description
+ "Enter lifetime kbytes for IPSEC SAs";
+ }
+ leaf seconds {
+ type uint32 {
+ range "300..99999999";
+ }
+ description
+ "Enter lifetime seconds for IPSEC SAs
+ 0: lifetime of 0 for no timeout
+ 300..99999999: IPSec SA lifetime in seconds";
+ }
+ }
+ }
+
+ grouping identity-grouping {
+ description
+ "Identification type. It is an union identity, "+
+ "possible type as follows: "+
+ "a) ID_FQDN: A fully-qualified domain name string. "+
+ " An example of a ID_FQDN is, example.com. "+
+ " The string MUST not contain any terminators "+
+ "(e.g., NULL, CR, etc.). "+
+ "b) ID_RFC822_ADDR: A fully-qualified RFC822 email "+
+ " address string, An example of a ID_RFC822_ADDR is, "+
+ " jsmith@example.com. The string MUST not contain "+
+ " any terminators. "+
+ "c) ID_IPV4_ADDR: A single four (4) octet IPv4 address. "+
+ "d) ID_IPV6_ADDR: A single sixteen (16) octet IPv6 address. "+
+ "e) DN_X509: Distinguished name in the X.509 tradition.";
+ choice identity {
+ description
+ "Choice of identity.";
+ leaf ipv4-address {
+ type inet:ipv4-address;
+ description
+ "Specifies the identity as a single four (4)
+ octet IPv4 address.
+ An example is, 10.10.10.10. ";
+ }
+ leaf ipv6-address {
+ type inet:ipv6-address;
+ description
+ "Specifies the identity as a single sixteen (16) "+
+ "octet IPv6 address. "+
+ "An example is, "+
+ "FF01::101, 2001:DB8:0:0:8:800:200C:417A .";
+ }
+ leaf fqdn-string {
+ type inet:domain-name;
+ description
+ "Specifies the identity as a Fully-Qualified
+ Domain Name (FQDN) string.
+ An example is: example.com.
+ The string MUST not contain any terminators
+ (e.g., NULL, CR, etc.).";
+ }
+ leaf rfc822-address-string {
+ type string;
+ description
+ "Specifies the identity as a fully-qualified RFC822
+ email address string.
+ An example is, jsmith@example.com.
+ The string MUST not contain any terminators
+ (e.g., NULL, CR, etc.).";
+ }
+ leaf dnX509 {
+ type string;
+ description
+ "Specifies the identity as a distinguished name
+ in the X.509 tradition.";
+ }
+ }
+ } /* grouping identity-grouping */
+
+ grouping ike-general-policy-profile-grouping {
+ description
+ "IKE policy.";
+ leaf connection-type {
+ type connection-type-t;
+ mandatory true;
+ description
+ "Specify the IKE connection type";
+ }
+ leaf pre-shared-key {
+ type union {
+ type string {
+ length "16";
+ }
+ /* TODO HC2VPP-399: Removed length from hex-string which caused
+ failures when building using ODL yangtools
+ */
+ type yang:hex-string;
+ }
+ description
+ "Specify IKE pre-shared-key value";
+ }
+ leaf validate-certificate-identity {
+ type empty;
+ description
+ "Validate Remote-ID payload against the
+ ID's available in the certificate";
+ }
+ list seq {
+ key seq-id;
+ description
+ "list of sequence of policy.";
+ leaf seq-id {
+ type uint32 {
+ range "1..429496729";
+ }
+ description
+ "Sequence Number";
+ }
+ leaf proposal {
+ type leafref {
+ path "/eipsec:ikev1/eipsec:proposal"+
+ "/eipsec:name";
+ }
+ description
+ "IKE Proposal reference.";
+ }
+ }
+ container identity {
+ description
+ "Specify IKE identity value";
+ container local {
+ description
+ "Specify the identity of the local IP Security (IPSec)
+ tunnel endpoint in an Internet Key Exchange (IKE)
+ policy to use when negotiating IKE request with a
+ remote peer.";
+ uses identity-grouping;
+ }
+ container remote {
+ description
+ "Specify the identity of the remote IP Security (IPSec)
+ tunnel endpoint in an
+ Internet Key Exchange (IKE) policy to use when
+ negotiating IKE request with a remote peer.";
+ uses identity-grouping;
+ }
+ }
+ }
+
+ grouping ike-policy-mode-grouping {
+ description
+ "IKE Policy Mode";
+ container mode {
+ description
+ "Specify IKE mode configuration";
+ leaf aggressive {
+ type empty;
+ description
+ "Set IKE Aggressive mode";
+ }
+ leaf main {
+ type empty;
+ description
+ "Set IKE Main mode";
+ }
+ }
+ }
+
+ grouping ike-policy-profile-grouping {
+ description
+ "Configure IKE policy";
+ leaf name {
+ type string;
+ mandatory true;
+ description
+ "Specify an IKE policy name";
+ }
+ uses ike-policy-mode-grouping;
+ uses ike-general-policy-profile-grouping;
+ }
+
+ grouping ikev2-policy-profile-grouping {
+ description
+ "Common information for multiple IKE sessions
+ to be instantiated on a managed element.;
+ One or more Ikev2Session instances might refer
+ to this instance.";
+ leaf name {
+ type string;
+ mandatory true;
+ description
+ "Value component of the RDN.";
+ }
+ container authentication {
+ description
+ "Specify IKE Proposal authentication configuration";
+ leaf preshared-key {
+ type empty;
+ description
+ "Use pre-shared key based authentication";
+ }
+ leaf rsa-signature {
+ type empty;
+ description
+ "Use signature based authentication by using
+ PKI certificates";
+ }
+ }
+ leaf lifetime {
+ type uint32;
+ mandatory true;
+ description
+ "Configure lifetime for IKE SAs
+ 0: for no timeout.
+ 300 .. 99999999: IKE SA lifetime in seconds.";
+ }
+
+ container address-allocation {
+ must "../connection-type = 'responder-only'" {
+ description
+ "address-allocation can be configured only with
+ responder-only in ike2 policy";
+ }
+ leaf aaa {
+ type empty;
+ description
+ "IRAC address allocation by AAA";
+ }
+ description
+ "Specify IKE IRAS address allocation option";
+ }
+
+ uses ike-general-policy-profile-grouping;
+
+ leaf description {
+ type string;
+ description
+ "Specify the description.";
+ }
+ }
+
+ grouping ipsec-policy-grouping {
+ description
+ "Holds configuration information for IPSec policies.";
+ leaf name {
+ type string;
+ mandatory true;
+ description
+ "IPSec Policy Identification";
+ }
+ leaf description {
+ type string;
+ description
+ "Specify the description.";
+ }
+
+ leaf anti-replay-window {
+ type uint32 {
+ range "0 | 32..1024";
+ }
+ description
+ "Configure replay window size
+ 0: to disable anti-replay-window
+ 32..1024: IPSec anti-replay-window size in multiple of 32";
+ }
+ container perfect-forward-secrecy {
+ description
+ "Configure Perfect Forward Secrecy (PFS) for IPSec Policy";
+ leaf dh-group {
+ type diffie-hellman-group-t;
+ description
+ "Configure Diffie-Hellman group for
+ perfect-forward-secrecy";
+ }
+ }
+ list seq {
+ key seq-id;
+ description
+ "Specify IPSEC proposal sequence number";
+ leaf seq-id {
+ type uint32;
+ description
+ "Sequence ID";
+ }
+ leaf description {
+ type string;
+ description
+ "Specify the description.";
+ }
+
+ leaf proposal {
+ type leafref {
+ path "/eipsec:ipsec/"+
+ "eipsec:proposal/eipsec:ipsec-proposal/eipsec:name";
+ }
+ description
+ "IKE proposal reference.";
+ }
+ }
+ }
+
+ grouping key-string-grouping {
+ description
+ "Configure key for authentication algorithm";
+ leaf key-str {
+ type union {
+ type string {
+ length "16";
+ }
+ /* TODO HC2VPP-399: Removed length from hex-string which caused
+ failures when building using ODL yangtools
+ */
+ type yang:hex-string;
+ }
+ description
+ "Key string input is either string value (length of 16)
+ or hexadecimal (length of 40)";
+ }
+ }
+
+ grouping ipsec-sa-ah-grouping {
+ description
+ "Configure Authentication Header (AH) for
+ Security Association (SA)";
+ container ah {
+ description
+ "Configure Authentication Header (AH) for SA";
+ choice authentication-algorithm {
+ description
+ "choice for authentication algorithm to set for AH";
+ case hmac-aes-xcbc {
+ container hmac-aes-xcbc {
+ description
+ "Set the authentication algorithm to hmac-aes-xcbc";
+ uses key-string-grouping;
+ }
+ }
+ case hmac-md5-96 {
+ container hmac-md5-96 {
+ description
+ "Set the authentication algorithm to hmac-md5-96";
+ uses key-string-grouping;
+ }
+ }
+ case hmac-sha1-96 {
+ container hmac-sha1-96 {
+ description
+ "Set the authentication algorithm to hmac-sha1-96";
+ uses key-string-grouping;
+ }
+ }
+ case key-string {
+ container key-string {
+ description
+ "Configure key for authentication algorithm";
+ uses key-string-grouping;
+ }
+ }
+ }
+ }
+ }
+
+ grouping ipsec-sa-esp-grouping {
+ description
+ "Configure IPSec Encapsulation Security Payload (ESP)";
+ container esp {
+ description
+ "Set IPSec Encapsulation Security Payloer (ESP)";
+ container authentication {
+ description
+ "Configure authentication for IPSec
+ Encapsulation Secutiry Payload (ESP)";
+ choice authentication-algorithm {
+ description
+ "choice for authentication algorithm to set";
+ case hmac-aes-xcbc {
+ container hmac-aes-xcbc {
+ description
+ "Set the authentication algorithm to hmac-aes-xcbc";
+ uses key-string-grouping;
+ }
+ }
+ case hmac-md5-96 {
+ container hmac-md5-96 {
+ description
+ "Set the authentication algorithm to hmac-md5-96";
+ uses key-string-grouping;
+ }
+ }
+ case hmac-sha1-96 {
+ container hmac-sha1-96 {
+ description
+ "Set the authentication algorithm to hmac-sha1-96";
+ uses key-string-grouping;
+ }
+ }
+ case key-string {
+ container key-string {
+ description
+ "Configure key for authentication algorithm";
+ uses key-string-grouping;
+ }
+ }
+ }
+ }
+ container encryption {
+ description
+ "Configure encryption for IPSec
+ Encapsulation Secutiry Payload (ESP)";
+ choice encryption-algorithm {
+ description
+ "type of encryption";
+ case des3-cbc {
+ container des3-cbd {
+ description
+ "Set the encryption algorithm to des3-cbc";
+ uses key-string-grouping;
+ }
+ }
+ case aes-128-cbc {
+ container aes-128-cbc {
+ description
+ "Set the encryption algorithm to aes-128-cbc";
+ uses key-string-grouping;
+ }
+ }
+ case aes-192-cbc {
+ container aes-192-cbc {
+ description
+ "Set the encryption algorithm to aes-192-cbc";
+ uses key-string-grouping;
+ }
+ }
+ case aes-256-cbc {
+ container aes-256-cbc {
+ description
+ "Set the encryption algorithm to aes-256-cbc";
+ uses key-string-grouping;
+ }
+ }
+ case des-cbc {
+ container des-cbc {
+ description
+ "Set the encryption algorithm to des-cbc";
+ uses key-string-grouping;
+ }
+ }
+ case key-string {
+ container key-string {
+ description
+ "Configure key for encryption algorithm";
+ uses key-string-grouping;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ grouping ipsec-acl-dest-grouping {
+ description
+ "IPSEC ACL destination.";
+ /* For destination */
+ choice dest-address {
+ description
+ "destination address.";
+ case dest-ipv4-address {
+ leaf destination-ipv4-address {
+ type inet:ipv4-address;
+ description
+ "Destination IPv4 Address A.B.C.D/0..32.";
+ }
+ }
+ case dest-any {
+ leaf dest-any {
+ type empty;
+ description
+ "Match Any Destination IPv4 Address.";
+ }
+ }
+ }
+ }
+
+ grouping ipsec-acl-seq-protocol-number-grouping {
+ description
+ "IPSec ACL Sequence protocol number.";
+ leaf number {
+ type uint16 {
+ range "0..255";
+ }
+ description
+ "Specify protocol number.";
+ }
+ choice argument {
+ description
+ "Source IPv4 address.";
+ case source-ipv4-address {
+ leaf source-ipv4-address {
+ type inet:ipv4-address;
+ description
+ "Source IPv4 Address A.B.C.D/0..32.";
+ }
+ }
+ case any {
+ /* For source */
+ leaf source-any {
+ type empty;
+ description
+ "Match Any Source IPv4 Address.";
+ }
+ }
+ }
+ }
+
+ grouping ipsec-acl-seq-ip-address-grouping {
+ description
+ "IPSec ACL Sequence IP Address.";
+ leaf source-ipv4-address {
+ type inet:ipv4-address;
+ description
+ "Source is IPv4 Address A.B.C.D/0..32.";
+ }
+ }
+
+ grouping ipsec-acl-seq-any-grouping {
+ description
+ "IPSec ACL Sequence Any.";
+ leaf any {
+ type empty;
+ description
+ "Source is Any.";
+ }
+ }
+
+ grouping ipsec-acl-seq-tcp-grouping {
+ description
+ "IPSec ACL Sequence TCP.";
+ leaf tcp {
+ type empty;
+ description
+ "Source is TCP protocol.";
+ }
+ }
+
+ grouping ipsec-acl-seq-udp-grouping {
+ description
+ "IPSec ACL Sequence for UDP.";
+ leaf udp {
+ type empty;
+ description
+ "Source is UDP protocol.";
+ }
+ }
+
+ grouping ipsec-acl-grouping {
+ description
+ "IPSec ACL";
+ list access-list {
+ if-feature ipsec-acl;
+ key "name sequence-number";
+ uses name-grouping;
+ uses sequence-number-grouping;
+ description
+ "Configure the IPSec access-list.";
+ choice protocol {
+ description
+ "IPSec ACL protocol.";
+ case number {
+ uses ipsec-acl-seq-protocol-number-grouping;
+ }
+ case source-ipv4-address {
+ uses ipsec-acl-seq-ip-address-grouping;
+ }
+ case any {
+ uses ipsec-acl-seq-any-grouping;
+ }
+ case tcp {
+ uses ipsec-acl-seq-tcp-grouping;
+ }
+ case udp {
+ uses ipsec-acl-seq-udp-grouping;
+ }
+ }
+ uses ipsec-acl-dest-grouping;
+ }
+ }
+
+ grouping ipsec-df-bit-grouping {
+ description
+ "IPSec Dont Fragment (DF) bit for IP header.";
+ container df-bit {
+ description
+ "Configure Don't Fragment (DF) bit for IP Header.";
+ leaf clear {
+ type empty;
+ description
+ "Clear DF bit for outer IP header.";
+ }
+ leaf propagate {
+ type empty;
+ description
+ "Propagate DF bit for outer IP header.";
+ }
+ leaf set {
+ type empty;
+ description
+ "Set DF bit for outer IP header.";
+ }
+ }
+ }
+
+ grouping ipsec-profile-grouping {
+ description
+ "IPSec profile.";
+ list profile {
+ key "name";
+ uses name-grouping;
+ uses ipsec-df-bit-grouping;
+ description
+ "Configure the IPSec Profile.";
+ leaf mtu {
+ type uint32 {
+ range "256..1600";
+ }
+ description
+ "Set the MTU.";
+ }
+ list seq {
+ key "sequence-number";
+ uses sequence-number-grouping;
+ description
+ "IPSec Access List sequence number.";
+ leaf policy {
+ type leafref {
+ //TODO: fixed path (HC2VPP-399)
+ path "/eipsec:ipsec/eipsec:spd/"+
+ "eipsec:spd-entries/eipsec:name";
+ }
+ description
+ "Specify IPSec policy name.";
+ }
+ }
+ }
+ }
+
+ grouping ip-address-grouping {
+ description
+ "IP Address grouping";
+
+ choice ip-address {
+ description
+ "Choice of IPv4 or IPv6.";
+ leaf ipv4-address {
+ type inet:ipv4-address;
+ description
+ "Specifies the identity as a single four (4)
+ octet IPv4 address.
+ An example is, 10.10.10.10. ";
+ }
+ leaf ipv6-address {
+ type inet:ipv6-address;
+ description
+ "Specifies the identity as a single sixteen (16) "+
+ "octet IPv6 address. "+
+ "An example is, "+
+ "FF01::101, 2001:DB8:0:0:8:800:200C:417A .";
+ }
+ }
+ }
+
+ grouping ipsec-sa-grouping {
+ description
+ "Configure Security Association (SA)";
+ leaf spi {
+ type uint32;
+ description
+ "Specify Security Parameter Index";
+ }
+ leaf anti-replay-window {
+ type uint16 {
+ range "0 | 32..1024";
+ }
+ description
+ "Specify replay window size";
+ }
+ leaf ip-comp {
+ type empty;
+ description
+ "Enables IPCOMP, which uses the IP payload compression
+ protocol to compress IP security (IPsec) packets
+ before encryption";
+ }
+
+ container local-peer {
+ description
+ "Specify the local peer IP address";
+ uses ip-address-grouping;
+ }
+ container remote-peer {
+ description
+ "Specify the remote peer IP address";
+ uses ip-address-grouping;
+ }
+ leaf sa-mode {
+ type ipsec-mode;
+ description
+ "SA Mode: tunnel or transport mode";
+ }
+ leaf security-protocol {
+ type ipsec-protocol;
+ description
+ "Security protocol of IPsec SA: Either AH or ESP.";
+ }
+ leaf sequence-number {
+ type uint64;
+ description
+ "Current sequence number of IPsec packet.";
+ }
+ leaf sequence-number-overflow-flag {
+ type boolean;
+ description
+ "The flag indicating whether overflow of the sequence
+ number counter should prevent transmission of additional
+ packets on the SA, or whether rollover is permitted.";
+ }
+ leaf path-mtu {
+ type uint16;
+ description
+ "maximum size of an IPsec packet that can be transmitted
+ without fragmentation";
+ }
+ container life-time {
+ leaf life-time-in-seconds {
+ type uint32;
+ description
+ "SA life time in seconds";
+ }
+ leaf remain-life-time-in-seconds {
+ type uint32;
+ description
+ "Remain SA life time in seconds";
+ }
+ leaf life-time-in-byte {
+ type uint32;
+ description
+ "SA life time in bytes";
+ }
+ leaf remain-life-time-in-byte {
+ type uint32;
+ description
+ "Remain SA life time in bytes";
+ }
+ description
+ "SA life time information";
+ }
+ leaf upper-protocol {
+ type string;
+ description
+ "Upper-layer protocol to be used";
+ }
+ leaf direction {
+ type ipsec-traffic-direction;
+ description
+ "It indicates whether the SA is inbound SA or
+ out bound SA.";
+ }
+ container source-address {
+ description
+ "Specify the source IP address and
+ port of protected traffic";
+ uses ip-address-grouping;
+ leaf port-number {
+ type uint32;
+ description
+ "port of protected traffic";
+ }
+ }
+ container destination-address {
+ description
+ "Specify the destination IP address and
+ port of protected traffic";
+ uses ip-address-grouping;
+ leaf port-number {
+ type uint32;
+ description
+ "port of protected traffic";
+ }
+ }
+ leaf nat-traversal-flag {
+ type boolean;
+ description
+ "Whether the SA is used to protect traffic that needs
+ nat traversal";
+ }
+ uses ipsec-sa-ah-grouping;
+ uses ipsec-sa-esp-grouping;
+ }
+
+
+ /* draft-wang-ipsecme-ike-yang-00 */
+ grouping ipsec-common-configuration {
+ choice df-flag {
+ default copy;
+ case set {
+ leaf set {
+ type empty;
+ description
+ "Set the df bit when encapsulate IPsec tunnel.";
+ }
+ }
+ case clear {
+ leaf clear {
+ type empty;
+ description
+ "Clear the df bit when encapsulate IPsec tunnel.";
+ }
+ }
+ case copy {
+ leaf copy {
+ type empty;
+ description
+ "Copy the inner IP header df bit.";
+ }
+ }
+ description
+ "It indicates how to process the df bit when encapsulate
+ IPsec tunnel.";
+ }
+ leaf stateful-frag-check {
+ type boolean;
+ default false;
+ description "Whether stateful fragment checking applies.";
+ }
+ leaf life-time-kb {
+ type uint32;
+ units "KB";
+ default 2000000;
+ description "IPsec SA Life time in KB.";
+ }
+ leaf life-time-second {
+ type uint32;
+ units "Second";
+ default 18400;
+ description "IPsec SA Life time in Seconds";
+ }
+ choice anti-replay {
+ default enable;
+ case enable {
+ leaf enable {
+ type empty;
+ description "Enable Anti-replay";
+ }
+ choice anti-replay-windows-size {
+ case size-32;
+ case size-64;
+ case size-128;
+ case size-256;
+ case size-512;
+ case size-1024;
+ default size-1024;
+ description "It indicate the size of anti-replay window";
+ }
+ }
+ case disable {
+ leaf disable {
+ type empty;
+ description "Disable Anti-replay";
+ }
+ }
+ description "Whether enable or disable anti-replay";
+ }
+ leaf inbound-dscp {
+ type uint16 {
+ range "0..63";
+ }
+ default 0;
+ description "Inbound DSCP value";
+ }
+ leaf outbound-dscp {
+ type uint16 {
+ range "0..63";
+ }
+ default 0;
+ description "Outbound DSCP value";
+ }
+ description "Common IPsec configurations";
+ }
+
+ /*--------------------*/
+ /* Configuration Data */
+ /*--------------------*/
+ container ikev1 {
+ if-feature ikev1;
+ description
+ "Configuration IPSec IKEv1";
+ /* The following is for <configure> */
+ list proposal {
+ key "name";
+ uses ike-proposal-grouping;
+ description
+ "Configure IKE proposal";
+ }
+ leaf keepalive {
+ type empty;
+ description
+ "Enables sending Dead Peer Detection (DPD) messages "+
+ "to Internet Key Exchange (IKE) peers.";
+ }
+ list policy {
+ key "name";
+ uses ike-policy-profile-grouping;
+ description
+ "Configure IKE Policy Profile.";
+ }
+ }
+
+ container ikev2 {
+ if-feature ikev2;
+ description
+ "Configuration IPSec IKEv2";
+ /* The following is for <configure> */
+ /* draft-wang-ipsecme-ike-yang-00 */
+ container ike-global-configuration {
+ if-feature ikev2-global;
+ description "Global IKE configurations";
+ uses ipsec-common-configuration;
+ leaf local-name {
+ type string;
+ description
+ "Global local name configuration, if it is not configed,
+ ip address will be used as default. If configing special
+ local name for special peer, it will overwrite the global
+ name configuration when negotion with that peer.";
+ }
+ leaf nat-keepalive-interval {
+ type uint16 {
+ range "5..300";
+ }
+ units "Seconds";
+ default 20;
+ description "Global nat keepalive interval";
+ }
+ leaf dpd-interval {
+ type uint16 {
+ range "10..3600";
+ }
+ units "Seconds";
+ default 30;
+ description "Global DPD interval";
+ }
+ }
+ container ike-peer {
+ if-feature ikev2-peer;
+ description "IKE peer information";
+ list ike-peer-entries {
+ key "peer-name";
+ description "IKE peer information";
+ leaf peer-name {
+ type string;
+ mandatory true;
+ description "Name of IKE peer";
+ }
+ leaf ike-proposal-number {
+ type ike-proposal-number-ref;
+ description "IKE proposal number referenced by IKE peer";
+ }
+ leaf PresharedKey {
+ type string;
+ description "Preshare key";
+ }
+ leaf nat-traversal {
+ type boolean;
+ default false;
+ description "Enable/Disable nat traversal";
+ }
+ choice local-id-type {
+ default ip;
+ case ip {
+ leaf ip {
+ type empty;
+ description "IP address";
+ }
+ }
+ case fqdn {
+ leaf fqdn {
+ type empty;
+ description "Fully Qualifed Domain name ";
+ }
+ }
+ case dn {
+ leaf dn {
+ type empty;
+ description "Domain name";
+ }
+ }
+ case user_fqdn {
+ leaf user_fqdn {
+ type empty;
+ description "User FQDN";
+ }
+ }
+ description "Local ID type";
+ }
+ leaf local-id {
+ type string;
+ description
+ "Local ID Name. When IP is used as local ID type,
+ it is ignored. If it is not configurated,
+ global local name will be used.";
+ }
+ leaf remote-id {
+ type "string";
+ description "ID of IKE peer";
+ }
+ leaf low-remote-address {
+ type inet:ip-address;
+ description "Low range of remote address";
+ }
+ leaf high-remote-address {
+ type inet:ip-address;
+ description "High range of remote address";
+ }
+ leaf certificate {
+ type string;
+ description "Certificate file name";
+ }
+ leaf auth-address-begin {
+ type inet:ip-address;
+ description
+ "The begin range of authenticated peer address";
+ }
+ leaf auth-address-end {
+ type inet:ip-address;
+ description
+ "The end range of authenticated peer address";
+ }
+ }
+ }//End of IKEPeerEntries
+
+
+ list proposal {
+ if-feature ikev2-proposal;
+ key "name";
+ uses ikev2-proposal-grouping;
+ description
+ "Configure IKEv2 proposal";
+ }
+ list policy {
+ if-feature ikev2-policy;
+ key "name";
+ uses ikev2-policy-profile-grouping;
+ description
+ "IKEv2 Policy Profile";
+ }
+ }
+
+ container ipsec {
+ if-feature ipsec;
+ description
+ "Configuration IPsec";
+ container sad {
+ if-feature ipsec-sad;
+ description
+ "Configure the IPSec Security Association Database (SAD)";
+ list sad-entries {
+ key "spi direction";
+ description
+ "Configure IPsec Security Association Database(SAD)";
+ uses ipsec-sa-grouping;
+ }
+ }
+ container proposal {
+ if-feature ipsec-proposal;
+ description
+ "IPSec Proposal Profile";
+ list ipsec-proposal {
+ key "name";
+ uses ipsec-proposal-grouping;
+ description
+ "Configure the IP Security (IPSec) proposal";
+ }
+ }
+ /*
+ TODO HC2VPP-399: modified spd container to list to support multiple spds for VPP
+ */
+ list spd {
+ key "spd-id";
+ if-feature ipsec-spd;
+ description
+ "List of Security Policy Databases (SPD)";
+ leaf spd-id {
+ type int32;
+ }
+ list spd-entries {
+ key "name";
+ ordered-by user;
+ uses ipsec-policy-grouping;
+ description
+ "Specify an IPSec policy name";
+ }
+ }
+ container pad {
+ description
+ "Configure Peer Authorization Database (PAD)";
+ list pad-entries {
+ key "pad-type pad-id";
+ ordered-by user;
+ uses identity-grouping;
+ description
+ "Peer Authorization Database (PAD)";
+ leaf pad-id {
+ type uint32;
+ description
+ "PAD identity";
+ }
+ leaf pad-type {
+ type pad-type-t;
+ description
+ " PAD type";
+ }
+ leaf ike-peer-name {
+ type string;
+ description
+ "IKE Peer Name";
+ }
+ container peer-authentication {
+ description
+ "Specify IKE peer authentication configuration";
+ leaf algorithm {
+ type ike-integrity-algorithm-t;
+ description
+ "Specify the authentication algorithm";
+ }
+ leaf preshared-key {
+ type empty;
+ description
+ "Use pre-shared key based authentication";
+ }
+ leaf rsa-signature {
+ type empty;
+ description
+ "Use signature based authentication by using
+ PKI certificates";
+ }
+ }
+ }
+ }
+ }
+
+
+
+ /*--------------------------*/
+ /* Operational State Data */
+ /*--------------------------*/
+ grouping ike-proposal-state-components {
+ description
+ "IKE Proposal operational state";
+ list proposal {
+ if-feature ike-proposal-state;
+ description
+ "Operational data for IKE Proposal";
+ leaf name {
+ type string {
+ length "1..50";
+ }
+ description
+ "Name of the IKE proposal.";
+ }
+ leaf lifetime {
+ type uint32;
+ units "seconds";
+ description
+ "lifetime";
+ }
+ leaf encryption {
+ type ike-encryption-algorithm-t;
+ description
+ "Encryption algorithm";
+ }
+ leaf dh-group {
+ type diffie-hellman-group-t;
+ description
+ "Diffie-Hellman group.";
+ }
+ leaf authentication {
+ type ike-integrity-algorithm-t;
+ description
+ "authentication";
+ }
+ }
+ }
+
+ grouping ike-policy-state-grouping {
+ description
+ "IKE Policy State.";
+ list policy {
+ if-feature ike-policy-state;
+ description
+ "Operational data for IKE policy";
+ leaf name {
+ type string {
+ length "1..50";
+ }
+ description
+ "Name of the IKE Policy.";
+ }
+ leaf description {
+ type string;
+ description
+ "Description for IKE Policy.";
+ }
+ leaf mode {
+ type enumeration {
+ enum aggressive {
+ description
+ "Aggressive mode.";
+ }
+ enum main {
+ description
+ "Main mode.";
+ }
+ }
+ description
+ "IKE policy mode.";
+ }
+ leaf connection-type {
+ type connection-type-t;
+ description
+ "IKE policy connection type.";
+ }
+ leaf local-identity {
+ type inet:ipv4-address-no-zone;
+ description
+ "IP address of the local identity.";
+ }
+ leaf remote-identity {
+ type inet:ipv4-address-no-zone;
+ description
+ "IP address of the remote identity.";
+ }
+ leaf pre-shared-key {
+ type string;
+ description
+ "Pre-shared key";
+ }
+ leaf seq {
+ type uint32;
+ description
+ "sequence number";
+ }
+ leaf proposal {
+ type string;
+ description
+ "proposal name";
+ }
+ }
+ }
+
+ grouping ikev2-proposal-state-components {
+ description
+ "IKEv2 Operational state";
+ list proposal {
+ if-feature ikev2-proposal-state;
+ description
+ "IKEv2 proposal operational data";
+ leaf name {
+ type string;
+ description
+ "Name of IKEv2 Proposal.";
+ }
+ leaf pseudo-random-function {
+ type pseudo-random-function-t;
+ description
+ "Pseudo Random Function for IKEv2.";
+ }
+ leaf authentication {
+ type ike-integrity-algorithm-t;
+ description
+ "authentication";
+ }
+ leaf encryption {
+ type ike-encryption-algorithm-t;
+ description
+ "Encryption algorithm";
+ }
+ leaf dh-group {
+ type diffie-hellman-group-t;
+ mandatory true;
+ description
+ "Diffie-Hellman group.";
+ }
+ }
+ }
+
+ grouping ipsec-policy-state-grouping {
+ description
+ "IPSec operational state";
+ list policy {
+ if-feature ipsec-policy-state;
+ description
+ "IPSec policy operational data";
+ leaf name {
+ type string;
+ description
+ "IPSec Policy name.";
+ }
+ leaf anti-replay-window {
+ type uint32;
+ description
+ "replay window size";
+ }
+ leaf perfect-forward-secrecy {
+ type diffie-hellman-group-t;
+ description
+ "Diffie-Hellman group for perfect-forward-secrecy";
+ }
+ list seq {
+ description
+ "Sequence number";
+ leaf seq-id {
+ type uint32;
+ description
+ "Sequence number";
+ }
+ leaf proposal-name {
+ type string;
+ description
+ "IPSec proposal name";
+ }
+ }
+ }
+ }
+ grouping ipsec-proposal-state-grouping {
+ description
+ "IPSec proposal operational data";
+ list proposal {
+ if-feature ipsec-proposal-state;
+ description
+ "IPSec proposal operational data";
+ leaf name {
+ type string;
+ description
+ "IPSec Proposal name";
+ }
+ leaf ah {
+ type ike-integrity-algorithm-t;
+ description
+ "Authentication Header (AH).";
+ }
+ container esp {
+ description
+ "Encapsulating Security Payload (ESP).";
+ leaf authentication {
+ type ike-integrity-algorithm-t;
+ description
+ "ESP authentication";
+ }
+ leaf encryption {
+ type ike-encryption-algorithm-t;
+ description
+ "ESP encryption";
+ }
+ }
+ leaf ip-comp{
+ type empty;
+ description
+ "IPSec proposal IP-COMP which uses the IP Payload "+
+ "compression protocol to compress IP Security (IPSec) "+
+ "packets before encryption";
+ }
+ container lifetime {
+ description
+ "lifetime for IPSEC SAs";
+ leaf kbytes {
+ type uint32;
+ description
+ "lifetime kbytes for IPSEC SAs";
+
+ }
+ leaf seconds {
+ type uint32;
+ description
+ "lifetime seconds for IPSEC SAs";
+ }
+ }
+ }
+ }
+
+ grouping ipsec-alarms-state-grouping {
+ description
+ "IPSec alarms operational data";
+ leaf hold-down {
+ if-feature ipsec-alarms-state;
+ type uint32;
+ description
+ "Hold-down value";
+ }
+ }
+
+ grouping ipsec-sa-ah-state-grouping {
+ description
+ "IPSec SA's AH operational data";
+
+ leaf spi {
+ if-feature ipsec-sa-ah-state;
+ type uint32;
+ description
+ "Security Parameter Index (SPI) value";
+ }
+ leaf description {
+ if-feature ipsec-sa-ah-state;
+ type string;
+ description
+ "the description.";
+ }
+ leaf authentication-algorithm {
+ if-feature ipsec-sa-ah-state;
+ type ike-integrity-algorithm-t;
+ description
+ "Authentication algorithm";
+ }
+ leaf encryption-algorithm {
+ if-feature ipsec-sa-ah-state;
+ type ike-encryption-algorithm-t;
+ description
+ "Encryption algorithm";
+ }
+ }
+
+ grouping ipsec-sa-state-grouping {
+ description
+ "IPSec Security Association Operational data";
+ list sa {
+ if-feature ipsec-sa-state;
+ description
+ "IPSec SA operational data";
+ leaf name {
+ type string;
+ description
+ "Specify IPSec Security Association (SA) name";
+ }
+ leaf anti-replay-window {
+ type uint16;
+ description
+ "replay window size";
+ }
+ leaf ip-comp {
+ type empty;
+ description
+ "Enables IPCOMP, which uses the IP payload compression
+ protocol to compress IP security (IPsec) packets before
+ encryption";
+ }
+ uses ipsec-sa-ah-state-grouping;
+ }
+ }
+
+ /* draft-wang-ipsecme-ipsec-yang-00 */
+ grouping ipsec-tunnel-mode-info {
+ description
+ "common infomations when using IPsec tunnel mode";
+ leaf local-address {
+ if-feature ipsec-tunnel;
+ type string;
+ description
+ "Local address of IPsec tunnel mode";
+ }
+ leaf remote-address {
+ if-feature ipsec-tunnel;
+ type string;
+ description
+ "Remote address of IPsec tunnel mode";
+ }
+ leaf bypass-df {
+ if-feature ipsec-tunnel;
+ type enumeration {
+ enum "set" {
+ description
+ "Set the df bit";
+ }
+ enum "clear" {
+ description
+ "Clear the df bit";
+ }
+ enum "copy" {
+ description
+ "Copy the df bit from inner header";
+ }
+ }
+ description
+ "This flag indicates how to process tunnel mode df flag";
+ }
+ leaf dscp-flag {
+ if-feature ipsec-tunnel;
+ type boolean;
+ description
+ "This flag indicate whether bypass DSCP or map to
+ unprotected DSCP values (array) if needed to
+ restrict bypass of DSCP values.";
+ }
+ leaf stateful-frag-check-flag {
+ if-feature ipsec-tunnel;
+ type boolean;
+ description
+ "This flag indicates whether stateful fragment checking
+ will be used.";
+ }
+ }
+ grouping traffic-selector {
+ description
+ "IPsec traffic selector information";
+ leaf local-address-low {
+ if-feature ipsec-local-address-range;
+ type inet:ip-address;
+ description
+ "Low range of local address";
+ }
+ leaf local-address-high {
+ if-feature ipsec-local-address-range;
+ type inet:ip-address;
+ description
+ "High range of local address";
+ }
+ leaf remote-address-low {
+ if-feature ipsec-remote-address-range;
+ type inet:ip-address;
+ description
+ "Low range of remote address";
+ }
+ leaf remote-address-high {
+ if-feature ipsec-remote-address-range;
+ type inet:ip-address;
+ description
+ "High range of remote address";
+ }
+ leaf next-protocol-low {
+ if-feature ipsec-next-protocol-range;
+ type uint16;
+ description
+ "Low range of next protocol";
+ }
+ leaf next-protocol-high {
+ if-feature ipsec-next-protocol-range;
+ type uint16;
+ description
+ "High range of next protocol";
+ }
+ leaf local-port-low {
+ if-feature ipsec-local-port-range;
+ type inet:port-number;
+ description
+ "Low range of local port";
+ }
+ leaf local-port-high {
+ if-feature ipsec-local-port-range;
+ type inet:port-number;
+ description
+ "High range of local port";
+ }
+ leaf remote-port-high {
+ if-feature ipsec-remote-port-range;
+ type inet:port-number;
+ description
+ "Low range of remote port";
+ }
+ leaf remote-port-low {
+ if-feature ipsec-remote-port-range;
+ type inet:port-number;
+ description
+ "High range of remote port";
+ }
+ }
+ grouping ipsec-algorithm-info {
+ description
+ "IPsec algorithm information used by SPD and SAD";
+ leaf ah-auth-algorithm {
+ if-feature ipsec-ah-authentication;
+ type ipsec-authentication-algorithm;
+ description
+ "Authentication algorithm used by AH";
+ }
+ leaf esp-integrity-algorithm {
+ if-feature ipsec-esp-integrity;
+ type ipsec-authentication-algorithm;
+ description
+ "Integrity algorithm used by ESP";
+ }
+ leaf esp-encrypt-algorithm {
+ if-feature ipsec-esp-encrypt;
+ type ipsec-encryption-algorithm;
+ description
+ "Encryption algorithm used by ESP";
+ }
+ }
+ grouping ipsec-stat {
+ leaf inbound-packets {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Inbound Packet count";
+ }
+ leaf outbound-packets {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Outbound Packet count";
+ }
+ leaf inbound-bytes {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Inbound Packet bytes";
+ }
+ leaf outbound-bytes {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Outbound Packet bytes";
+ }
+ leaf inbound-drop-packets {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Inbound dropped packets count";
+ }
+ leaf outbound-drop-packets {
+ if-feature ipsec-stat;
+ type uint64;
+ config false;
+ description "Outbound dropped packets count";
+ }
+ container dropped-packet-detail {
+ if-feature ipsec-stat;
+ description "The detail information of dropped packets";
+ leaf sa-non-exist {
+ type uint64;
+ config false;
+ description
+ "The dropped packets counts caused by SA non-exist.";
+ }
+ leaf queue-full {
+ type uint64;
+ config false;
+ description
+ "The dropped packets counts caused by full processing
+ queue";
+ }
+ leaf auth-failure {
+ type uint64;
+ config false;
+ description
+ "The dropped packets counts caused by authentication
+ failure";
+ }
+ leaf malform {
+ type uint64;
+ config false;
+ description "The dropped packets counts of malform";
+ }
+ leaf replay {
+ type uint64;
+ config false;
+ description "The dropped packets counts of replay";
+ }
+ leaf large-packet {
+ type uint64;
+ config false;
+ description "The dropped packets counts of too large";
+ }
+ leaf invalid-sa {
+ type uint64;
+ config false;
+ description "The dropped packets counts of invalid SA";
+ }
+ leaf policy-deny {
+ type uint64;
+ config false;
+ description
+ "The dropped packets counts of denyed by policy";
+ }
+ leaf other-reason {
+ type uint64;
+ config false;
+ description
+ "The dropped packets counts of other reason";
+ }
+ }
+ description "IPsec statistics information";
+ }
+
+
+ container ike-state {
+ if-feature ikev1-state;
+ config "false";
+ uses ike-proposal-state-components;
+ uses ike-policy-state-grouping;
+ description
+ "Contain the operational data for IKE.";
+ }
+ container ikev2-state {
+ if-feature ikev2-state;
+ config "false";
+ uses ikev2-proposal-state-components;
+ uses ike-policy-state-grouping;
+ description
+ "Contain the operational data for IKEv2.";
+ }
+ container ipsec-state {
+ if-feature ipsec-state;
+ config "false";
+ uses ipsec-policy-state-grouping;
+ uses ipsec-proposal-state-grouping;
+ uses ipsec-alarms-state-grouping;
+ uses ipsec-sa-state-grouping;
+ container redundancy {
+ if-feature ipsec-redundancy;
+ description
+ "Configure redundancy for IPSec";
+ leaf inter-chassis {
+ type empty;
+ description
+ "Set redundancy at chassis level";
+ }
+ }
+
+ description
+ "Contain the operational data for IPSec.";
+ }
+
+ /* draft-wang-ipsecme-ipsec-yang-00 */
+ container sad {
+ if-feature sad;
+ config false;
+ description
+ "The IPsec SA database";
+ list sad-entries {
+ key "spi security-protocol direction";
+ description
+ "The SA entries information";
+ leaf spi {
+ type ipsec-spi;
+ description
+ "Security parameter index of SA entry.";
+ }
+ leaf security-protocol {
+ type ipsec-protocol;
+ description
+ "Security protocol of IPsec SA.";
+ }
+ leaf direction {
+ type ipsec-traffic-direction;
+ description
+ "It indicates whether the SA is inbound SA or
+ out bound SA.";
+ }
+ leaf sa-type {
+ type enumeration {
+ enum "manual" {
+ description
+ "Manual IPsec SA";
+ }
+ enum "isakmp" {
+ description
+ "ISAKMP IPsec SA";
+ }
+ }
+ description
+ "It indicates whether the SA is created by manual
+ or by dynamic protocol.";
+ }
+ leaf sequence-number {
+ type uint64;
+ description
+ "Current sequence number of IPsec packet.";
+ }
+ leaf sequence-number-overflow-flag {
+ type boolean;
+ description
+ "The flag indicating whether overflow of the sequence
+ number counter should prevent transmission of additional
+ packets on the SA, or whether rollover is permitted.";
+ }
+ leaf anti-replay-enable-flag {
+ type boolean;
+ description
+ "It indicates whether anti-replay is enable or disable.";
+ }
+ leaf anti-replay-window-size {
+ type uint64;
+ description
+ "The size of anti-replay window.";
+ }
+ uses ipsec-algorithm-info;
+ container life-time {
+ leaf life-time-in-seconds {
+ type uint32;
+ description
+ "SA life time in seconds";
+ }
+ leaf remain-life-time-in-seconds {
+ type uint32;
+ description
+ "Remain SA life time in seconds";
+ }
+ leaf life-time-in-byte {
+ type uint32;
+ description
+ "SA life time in bytes";
+ }
+ leaf remain-life-time-in-byte {
+ type uint32;
+ description
+ "Remain SA life time in bytes";
+ }
+ description
+ "SA life time information";
+ }
+ leaf protocol-mode {
+ type ipsec-mode;
+ description
+ "It indicates whether tunnel mode or transport mode
+ will be used.";
+ }
+ container tunnel-mode-process-info {
+ when "../protocol-mode = 'tunnel'" {
+ description
+ "External information of SA when SA works in
+ tunnel mode.";
+ }
+ uses ipsec-tunnel-mode-info;
+ description
+ "External information of SA when SA works in
+ tunnel mode.";
+ }
+ leaf-list dscp {
+ type uint8 {
+ range "0..63";
+ }
+ description
+ "When traffic matchs SPD, the DSCP values used to
+ filter traffic";
+ }
+ leaf path-mtu {
+ type uint16;
+ description
+ "Path MTU valie";
+ }
+ leaf nat-traversal-flag {
+ type boolean;
+ description
+ "Whether the SA is used to protect traffic that needs
+ nat traversal";
+ }
+ }
+ }
+ container spd {
+ if-feature spd;
+ config false;
+ description
+ "IPsec security policy database information";
+ list spd-entries {
+ description
+ "IPsec SPD entry information";
+ list name {
+ description
+ "SPD name information.";
+ leaf name-type {
+ type ipsec-spd-name;
+ description
+ "SPD name type.";
+ }
+ leaf name-string {
+ when "../name-type = 'id_rfc_822_addr' or ../name-type =
+ 'id_fqdn'" {
+ description
+ "when name type is id_rfc_822_addr or id_fqdn, the
+ name are saved in string";
+ }
+ type string;
+ description
+ "SPD name content";
+ }
+ leaf name-binary {
+ when "../name-type = 'id_der_asn1_dn' or ../name-type =
+ 'id_key'" {
+ description
+ "when name type is id_der_asn1_dn or id_key, the name
+ are saved in binary";
+ }
+ type binary;
+ description
+ "SPD name content";
+ }
+ }
+ leaf pfp-flag {
+ type boolean;
+ description
+ "populate from packet flag";
+ }
+ list traffic-selector {
+ min-elements 1;
+ uses traffic-selector;
+ description
+ "Traffic selectors of SAD entry";
+ }
+ leaf operation {
+ type ipsec-spd-operation;
+ description
+ "It indicates how to process the traffic when it matches
+ the security policy.";
+ }
+ container protect-operation {
+ when "../operation = 'protect'" {
+ description
+ "How to protect the traffic when the SPD operation
+ is protect";
+ }
+ leaf spd-ipsec-mode {
+ type ipsec-mode;
+ description
+ "It indicates which mode is chosen when the traffic need
+ be protected by IPsec.";
+ }
+ leaf esn-flag {
+ type boolean;
+ description
+ "It indicates whether ESN is used.";
+ }
+ leaf spd-ipsec-protocol {
+ type ipsec-protocol;
+ description
+ "It indicates which protocol (AH or ESP) is chosen.";
+ }
+ container tunnel-mode-additional {
+ when "../spd-ipsec-mode = 'tunnel'" {
+ description
+ "Additional informations when choose tunnel mode";
+ }
+ uses ipsec-tunnel-mode-info;
+ description
+ "When use tunnel mode, the additional information of
+ SPD.";
+ }
+ list spd-algorithm {
+ min-elements 1;
+ uses ipsec-algorithm-info;
+ description
+ "Algorithms defined in SPD, ordered by decreasing
+ priority.";
+ }
+ description
+ "How to protect the traffic when the SPD operation is
+ protect";
+ }
+ }
+ }
+
+ container ipsec-global-statistics {
+ if-feature ipsec-global-stats;
+ config false;
+ description "IPsec global statistics";
+ container ipv4 {
+ description "IPsec statistics of IPv4";
+ uses ipsec-stat;
+ }
+ container ipv6 {
+ description "IPsec statistics of IPv6";
+ uses ipsec-stat;
+ }
+ container global {
+ description "IPsec statistics of global";
+ uses ipsec-stat;
+ }
+ }
+
+
+ /*--------------------*/
+ /* RPC */
+ /*--------------------*/
+ rpc clear-ipsec-group {
+ if-feature clear-ipsec-group;
+ description
+ "RPC for clear ipsec states";
+ input {
+ leaf alarm-hold-down {
+ type uint8;
+ description
+ "IPSec alarm hold-down";
+ }
+ leaf ipsec-policy-name {
+ type leafref {
+ path "/eipsec:ipsec/eipsec:spd/"+
+ "eipsec:spd-entries/eipsec:name";
+ }
+ description
+ "IPSec Policy name.";
+ }
+ }
+ }
+
+ rpc clear-ike-group {
+ if-feature clear-ike-group;
+ description
+ "RPC for clear IKE states";
+ input {
+ leaf proposal {
+ type leafref {
+ path "/eipsec:ikev1/eipsec:proposal/"+
+ "eipsec:name";
+ }
+ description
+ "IPSec IKE Proposal name.";
+ }
+ }
+ }
+
+ rpc clear-ikev2-group {
+ if-feature clear-ikev2-group;
+ description
+ "RPC for clear IKEv2 states";
+ input {
+ leaf proposal {
+ type leafref {
+ path "/eipsec:ikev2/eipsec:proposal/"+
+ "eipsec:name";
+ }
+ description
+ "IPSec IKEv2 Proposal name.";
+ }
+ }
+ }
+
+ /* draft-wang-ipsecme-ipsec-yang-00 */
+ rpc reset-ipv4 {
+ if-feature reset-ipv4;
+ description "Reset IPsec IPv4 statistics";
+ input {
+ leaf ipv4 {
+ type empty;
+ description "Reset IPsec IPv4 statistics";
+ }
+ }
+ output {
+ leaf status {
+ type string;
+ description "Operation status";
+ }
+ }
+ }
+ rpc reset-ipv6 {
+ if-feature reset-ipv6;
+ description "Reset IPsec IPv6 statistics";
+ input {
+ leaf ipv6 {
+ type empty;
+ description "Reset IPsec IPv6 statistics";
+ }
+ }
+ output {
+ leaf status {
+ type string;
+ description "Operation status";
+ }
+ }
+ }
+ rpc reset-global {
+ if-feature reset-global;
+ description "Reset IPsec global statistics";
+ input {
+ leaf ipv6 {
+ type empty;
+ description "Reset IPsec global statistics";
+ }
+ }
+ output {
+ leaf status {
+ type string;
+ description "Operation status";
+ }
+ }
+ }
+
+ notification dpd-failure{
+ description "IKE peer DPD detect failure";
+ leaf peer-id {
+ type string;
+ description "Peer ID";
+ }
+ }
+
+ notification peer-authentication-failure {
+ if-feature peer-authentication-failure;
+ description "Peer authentication fail when negotication";
+ leaf peer-id {
+ type string;
+ description "The ID of remote peer";
+ }
+ }
+
+ notification ike-reauth-failure {
+ if-feature ike-reauth-failure;
+ description "IKE peer reauthentication fail";
+ leaf peer-id {
+ type string;
+ description "The ID of remote peer";
+ }
+ }
+
+ notification ike-rekey-failure {
+ if-feature ike-rekey-failure;
+ description "IKE SA rekey failure";
+ leaf peer-id {
+ type string;
+ description "The ID of remote peer";
+ }
+ leaf old-i-spi {
+ type uint64;
+ description "old SPI";
+ }
+ leaf old-r-spi {
+ type uint64;
+ description "old SPI";
+ }
+ }
+
+ notification ipsec-rekey-failure {
+ if-feature ipsec-rekey-failure;
+ description "IPsec SA rekey failure";
+ leaf peer-id {
+ type string;
+ description "The ID of remote peer";
+ }
+ leaf old-inbound-spi {
+ type ipsec-spi;
+ description "old inbound SPI";
+ }
+ leaf old-outbound-spi {
+ type ipsec-spi;
+ description "old outbound SPI";
+ }
+ }
+} /* module ericsson-ipsec */
diff --git a/ipsec/ipsec-api/src/main/yang/vpp-ipsec@2018-12-13.yang b/ipsec/ipsec-api/src/main/yang/vpp-ipsec@2018-12-13.yang
new file mode 100644
index 000000000..72ade372a
--- /dev/null
+++ b/ipsec/ipsec-api/src/main/yang/vpp-ipsec@2018-12-13.yang
@@ -0,0 +1,147 @@
+module vpp-ipsec {
+ yang-version 1;
+ namespace "http://fd.io/hc2vpp/yang/vpp-ipsec";
+ prefix "vpp-ipsec";
+
+ import hc2vpp-ietf-ipsec {
+ prefix "hc2vpp-ietf-ipsec";
+ }
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import yang-ext {
+ prefix "ext";
+ }
+
+ import ietf-interfaces {
+ prefix "if";
+ }
+
+ revision "2018-12-13" {
+ description "Initial revision of ipsec model";
+ }
+
+ grouping vpp-ipsec-spd-entry-grouping {
+ description
+ "common information when using IPsec tunnel mode";
+ leaf spi {
+ type int32;
+ }
+
+ leaf priority {
+ type int32;
+ }
+
+ leaf direction {
+ type hc2vpp-ietf-ipsec:ipsec-traffic-direction;
+ }
+
+ leaf is-ipv6 {
+ type boolean;
+ }
+
+ leaf operation {
+ type hc2vpp-ietf-ipsec:ipsec-spd-operation;
+ }
+
+ leaf protect-sa-id {
+ type int32;
+ }
+
+ leaf laddr-start {
+ type inet:ip-address;
+ }
+
+ leaf laddr-stop {
+ type inet:ip-address;
+ }
+
+ leaf raddr-start {
+ type inet:ip-address;
+ }
+
+ leaf raddr-stop {
+ type inet:ip-address;
+ }
+ }
+
+ grouping spd-interfaces-grouping {
+ container spd-interfaces {
+ list interface {
+ key "interface-ref";
+
+ leaf interface-ref {
+ type if:interface-ref;
+ }
+ }
+ }
+ }
+
+ grouping ikev2-policy-aug-grouping {
+ leaf certificate {
+ type string;
+ description "Local file with RSA signature";
+ }
+
+ list traffic-selectors {
+ key "ts-name";
+ description "List of traffic selectors of profile";
+ leaf ts-name {
+ type string;
+ }
+ uses hc2vpp-ietf-ipsec:traffic-selector;
+ leaf protocol {
+ type uint8;
+ description "Protocol. If zero not relevant.";
+ }
+ }
+ }
+
+ augment /hc2vpp-ietf-ipsec:ipsec/hc2vpp-ietf-ipsec:sad/hc2vpp-ietf-ipsec:sad-entries {
+ ext:augment-identifier "ipsec-sad-entries-augmentation";
+ leaf sa-id {
+ type int32;
+ }
+ }
+
+ augment /hc2vpp-ietf-ipsec:ikev2/hc2vpp-ietf-ipsec:ike-global-configuration {
+ ext:augment-identifier "ipsec-ike-global-conf-augmentation";
+ leaf local-key-file {
+ type string;
+ description "Local file with RSA signature";
+ }
+ }
+
+ augment /hc2vpp-ietf-ipsec:ikev2/hc2vpp-ietf-ipsec:policy {
+ ext:augment-identifier "ipsec-ikev2-policy-augmentation";
+ uses ikev2-policy-aug-grouping;
+ }
+
+ augment /hc2vpp-ietf-ipsec:ipsec/hc2vpp-ietf-ipsec:spd {
+ ext:augment-identifier "ipsec-spd-enabled-interfaces-augmentation";
+ uses spd-interfaces-grouping;
+ }
+
+ augment /hc2vpp-ietf-ipsec:ipsec/hc2vpp-ietf-ipsec:spd/hc2vpp-ietf-ipsec:spd-entries {
+ ext:augment-identifier "ipsec-spd-entries-augmentation";
+ uses vpp-ipsec-spd-entry-grouping;
+ }
+
+ augment /hc2vpp-ietf-ipsec:ipsec-state {
+ ext:augment-identifier "ipsec-state-spd-augmentation";
+ list spd {
+ key "spd-id";
+
+ leaf spd-id {
+ type int32;
+ }
+ list spd-entries {
+ uses vpp-ipsec-spd-entry-grouping;
+ }
+
+ uses spd-interfaces-grouping;
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/pom.xml b/ipsec/ipsec-impl/pom.xml
new file mode 100644
index 000000000..9cf3dd97a
--- /dev/null
+++ b/ipsec/ipsec-impl/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2019 PANTHEON.tech.
+
+ 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.
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-impl-parent</artifactId>
+ <relativePath>../../vpp-common/vpp-impl-parent</relativePath>
+ <version>1.19.01-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>io.fd.hc2vpp.ipsec</groupId>
+ <artifactId>ipsec-impl</artifactId>
+ <name>${project.artifactId}</name>
+ <version>1.19.01-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>ipsec-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!--VPP common-->
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>translate-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>translate-spi</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>cfg-init</artifactId>
+ </dependency>
+
+ <!-- Translation -->
+ <dependency>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-translate-utils</artifactId>
+ </dependency>
+
+ <!-- DI -->
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.jmob</groupId>
+ <artifactId>guice.conf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-multibindings</artifactId>
+ </dependency>
+ <!-- Testing dependencies-->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-testlib</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-translate-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.honeycomb.infra</groupId>
+ <artifactId>test-tools</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>RELEASE</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/IpsecModule.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/IpsecModule.java
new file mode 100644
index 000000000..36dd8ae85
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/IpsecModule.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
+import io.fd.hc2vpp.ipsec.read.IpsecReaderFactory;
+import io.fd.hc2vpp.ipsec.write.IpsecWriterFactory;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Module class instantiating IpSec plugin components.
+ */
+public class IpsecModule extends AbstractModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IpsecModule.class);
+ private static final String SAD_ENTRIES_MAPPING = "sad-entries-mapping";
+
+ @Override
+ protected void configure() {
+ LOG.info("Installing IPSec module");
+
+ bind(MultiNamingContext.class).toInstance(new MultiNamingContext(SAD_ENTRIES_MAPPING, 1));
+ LOG.info("Injecting writers factories");
+ final Multibinder<WriterFactory> writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class);
+ writerFactoryBinder.addBinding().to(IpsecWriterFactory.class).in(Singleton.class);
+
+ LOG.info("Injecting readers factories");
+ final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class);
+ readerFactoryBinder.addBinding().to(IpsecReaderFactory.class).in(Singleton.class);
+
+ LOG.info("Module IPSec successfully configured");
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecReaderFactory.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecReaderFactory.java
new file mode 100644
index 000000000..e148022e8
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecReaderFactory.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.read;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+import io.fd.honeycomb.translate.impl.read.GenericInitListReader;
+import io.fd.honeycomb.translate.impl.read.GenericReader;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.Spd;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.spd.SpdEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.state.grouping.Sa;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Factory producing readers for IpSec plugin's data.
+ */
+public final class IpsecReaderFactory implements ReaderFactory {
+
+ private static final InstanceIdentifier<IpsecState> IPSEC_STATE_ID = InstanceIdentifier.create(IpsecState.class);
+ private FutureJVppCore vppApi;
+
+ @Inject
+ public IpsecReaderFactory(final FutureJVppCore vppApi) {
+ this.vppApi = vppApi;
+ }
+
+ @Override
+ public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+ registry.subtreeAdd(Sets
+ .newHashSet(InstanceIdentifier.create(IpsecState.class).child(Sa.class),
+ InstanceIdentifier.create(IpsecState.class).augmentation(IpsecStateSpdAugmentation.class)
+ .child(Spd.class)), new GenericReader<>(IPSEC_STATE_ID,
+ new IpsecStateCustomizer(vppApi)));
+ registry.addStructuralReader(IPSEC_STATE_ID.augmentation(IpsecStateSpdAugmentation.class),
+ IpsecStateSpdAugmentationBuilder.class);
+ registry.subtreeAdd(Sets
+ .newHashSet(InstanceIdentifier.create(Spd.class).child(SpdEntries.class)),
+ new GenericInitListReader<>(
+ IPSEC_STATE_ID.augmentation(IpsecStateSpdAugmentation.class).child(Spd.class),
+ new IpsecStateSpdCustomizer(vppApi)));
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizer.java
new file mode 100644
index 000000000..4755c7a82
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizer.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.read;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.LinkedList;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IkeEncryptionAlgorithmT;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IkeIntegrityAlgorithmT;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.state.grouping.Sa;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.state.grouping.SaBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class IpsecStateCustomizer extends FutureJVppCustomizer
+ implements JvppReplyConsumer, InitializingReaderCustomizer<IpsecState, IpsecStateBuilder>, Ipv4Translator,
+ Ipv6Translator {
+
+ private final DumpCacheManager<IpsecSaDetailsReplyDump, Void> ipsecSaDetailsReplyDumpManager;
+
+ public IpsecStateCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ this.ipsecSaDetailsReplyDumpManager =
+ new DumpCacheManager.DumpCacheManagerBuilder<IpsecSaDetailsReplyDump, Void>()
+ .withExecutor(new IpsecStateCustomizer.IpsecStateSaDetailsDumpExecutor(vppApi))
+ .acceptOnly(IpsecSaDetailsReplyDump.class)
+ .build();
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<IpsecState> id,
+ @Nonnull final IpsecState readValue, @Nonnull final ReadContext ctx) {
+ return Initialized.create(id, readValue);
+ }
+
+ @Nonnull
+ @Override
+ public IpsecStateBuilder getBuilder(@Nonnull final InstanceIdentifier<IpsecState> id) {
+ return new IpsecStateBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<IpsecState> id,
+ @Nonnull final IpsecStateBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ final Optional<IpsecSaDetailsReplyDump> dumpSa =
+ ipsecSaDetailsReplyDumpManager.getDump(id, ctx.getModificationCache());
+
+ if (dumpSa.isPresent()) {
+ LinkedList<Sa> listSa = new LinkedList<>();
+ IpsecSaDetailsReplyDump reply = dumpSa.get();
+ for (IpsecSaDetails details : reply.ipsecSaDetails) {
+ SaBuilder saBuilder = new SaBuilder();
+ saBuilder.setSpi(Integer.toUnsignedLong(details.spi))
+ .setAntiReplayWindow(Long.valueOf(details.replayWindow).intValue())
+ .setAuthenticationAlgorithm(IkeIntegrityAlgorithmT.forValue(details.integAlg))
+ .setEncryptionAlgorithm(IkeEncryptionAlgorithmT.forValue(details.cryptoAlg));
+ listSa.add(saBuilder.build());
+ }
+ builder.setSa(listSa);
+ }
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final IpsecState readValue) {
+ IpsecStateBuilder ipsecParentBuilder = (IpsecStateBuilder) parentBuilder;
+ ipsecParentBuilder.setHoldDown(readValue.getHoldDown())
+ .setPolicy(readValue.getPolicy())
+ .setProposal(readValue.getProposal())
+ .setRedundancy(readValue.getRedundancy())
+ .setSa(readValue.getSa())
+ .addAugmentation(IpsecStateSpdAugmentation.class,
+ readValue.augmentation(IpsecStateSpdAugmentation.class));
+ }
+
+ static final class IpsecStateSaDetailsDumpExecutor
+ implements EntityDumpExecutor<IpsecSaDetailsReplyDump, Void>, JvppReplyConsumer {
+
+ private final FutureJVppCore jvpp;
+
+ IpsecStateSaDetailsDumpExecutor(final FutureJVppCore jvpp) {
+ this.jvpp = jvpp;
+ }
+
+ @Nonnull
+ @Override
+ public IpsecSaDetailsReplyDump executeDump(final InstanceIdentifier<?> identifier, final Void params)
+ throws ReadFailedException {
+ IpsecSaDump dump = new IpsecSaDump();
+ dump.saId = -1;
+ return getReplyForRead(jvpp.ipsecSaDump(dump).toCompletableFuture(), identifier);
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizer.java
new file mode 100644
index 000000000..45f54cdb8
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizer.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.read;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdsDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdsDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.Spd;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.SpdBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.SpdKey;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.spd.SpdEntries;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.spd.SpdEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecSpdOperation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecTrafficDirection;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IpsecStateSpdCustomizer extends FutureJVppCustomizer
+ implements JvppReplyConsumer, InitializingListReaderCustomizer<Spd, SpdKey, SpdBuilder>, Ipv4Translator,
+ Ipv6Translator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IpsecStateSpdCustomizer.class);
+ private final DumpCacheManager<IpsecSpdDetailsReplyDump, Void> ipsecSpdDetailsReplyDumpManager;
+ private final DumpCacheManager<IpsecSpdsDetailsReplyDump, Void> ipsecSpdsReplyDumpManager;
+
+ public IpsecStateSpdCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ IpsecStateSpdsReplyDumpExecutor spdsExecutor =
+ new IpsecStateSpdCustomizer.IpsecStateSpdsReplyDumpExecutor(vppApi);
+ this.ipsecSpdsReplyDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpsecSpdsDetailsReplyDump, Void>()
+ .withExecutor(spdsExecutor)
+ .acceptOnly(IpsecSpdsDetailsReplyDump.class)
+ .build();
+
+ this.ipsecSpdDetailsReplyDumpManager =
+ new DumpCacheManager.DumpCacheManagerBuilder<IpsecSpdDetailsReplyDump, Void>()
+ .withExecutor(
+ new IpsecStateSpdCustomizer.IpsecStateSpdDetailsDumpExecutor(vppApi, spdsExecutor))
+ .acceptOnly(IpsecSpdDetailsReplyDump.class)
+ .build();
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<Spd> id,
+ @Nonnull final Spd readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(id, readValue);
+ }
+
+ @Nonnull
+ @Override
+ public SpdBuilder getBuilder(@Nonnull final InstanceIdentifier<Spd> id) {
+ return new SpdBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Spd> id, @Nonnull final SpdBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ SpdKey key = id.firstKeyOf(Spd.class);
+ builder.withKey(key);
+ builder.setSpdId(key.getSpdId());
+ Optional<IpsecSpdDetailsReplyDump> spdDump =
+ ipsecSpdDetailsReplyDumpManager.getDump(id, ctx.getModificationCache());
+ if (spdDump.isPresent()) {
+ List<SpdEntries> spdEntries =
+ spdDump.get().ipsecSpdDetails.stream().map(details -> translateDetailToEntry(details))
+ .collect(Collectors.toList());
+ builder.setSpdEntries(spdEntries);
+ }
+ }
+
+ @Nonnull
+ @Override
+ public List<SpdKey> getAllIds(@Nonnull final InstanceIdentifier<Spd> id, @Nonnull final ReadContext context)
+ throws ReadFailedException {
+ List<SpdKey> spdKeys = new LinkedList<>();
+ Optional<IpsecSpdsDetailsReplyDump> spdsDump =
+ ipsecSpdsReplyDumpManager.getDump(id, context.getModificationCache());
+ if (spdsDump.isPresent()) {
+ spdKeys = spdsDump.get().ipsecSpdsDetails.stream().map(details -> new SpdKey(details.spdId))
+ .collect(Collectors.toList());
+ }
+
+ LOG.debug("SPDs found in VPP: {}", spdKeys);
+ return spdKeys;
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Spd> readData) {
+ ((IpsecStateSpdAugmentationBuilder) builder).setSpd(readData);
+ }
+
+ private SpdEntries translateDetailToEntry(final IpsecSpdDetails details) {
+
+ SpdEntriesBuilder builder = new SpdEntriesBuilder();
+ builder.setDirection(IpsecTrafficDirection.forValue(details.isOutbound))
+ .setIsIpv6(ByteDataTranslator.INSTANCE.byteToBoolean(details.isIpv6))
+ .setPriority(details.priority);
+ switch (details.policy) {
+ case 0:
+ builder.setOperation(IpsecSpdOperation.Bypass);
+ break;
+ case 1:
+ builder.setOperation(IpsecSpdOperation.Discard);
+ break;
+ case 3:
+ builder.setOperation(IpsecSpdOperation.Protect);
+ builder.setProtectSaId(details.saId);
+ break;
+ }
+
+ if (builder.isIsIpv6()) {
+ processIpv6AddressRanges(builder, details);
+ } else {
+ processIpv4AddressRanges(builder, details);
+ }
+
+ return builder.build();
+ }
+
+ private void processIpv4AddressRanges(final SpdEntriesBuilder builder, final IpsecSpdDetails details) {
+ if (details.localStartAddr != null && details.localStartAddr.length > 0) {
+ builder.setLaddrStart(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv4AddressNoZone(details.localStartAddr)).stringValue()));
+ }
+ if (details.localStopAddr != null && details.localStopAddr.length > 0) {
+ builder.setLaddrStop(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv4AddressNoZone(details.localStopAddr)).stringValue()));
+ }
+ if (details.remoteStartAddr != null && details.remoteStartAddr.length > 0) {
+ builder.setRaddrStart(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv4AddressNoZone(details.remoteStartAddr)).stringValue()));
+ }
+ if (details.remoteStopAddr != null && details.remoteStopAddr.length > 0) {
+ builder.setRaddrStop(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv4AddressNoZone(details.remoteStopAddr)).stringValue()));
+ }
+ }
+
+ private void processIpv6AddressRanges(final SpdEntriesBuilder builder, final IpsecSpdDetails details) {
+ if (details.localStartAddr != null && details.localStartAddr.length > 0) {
+ builder.setLaddrStart(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv6AddressNoZone(details.localStartAddr)).stringValue()));
+ }
+ if (details.localStopAddr != null && details.localStopAddr.length > 0) {
+ builder.setLaddrStop(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv6AddressNoZone(details.localStopAddr)).stringValue()));
+ }
+ if (details.remoteStartAddr != null && details.remoteStartAddr.length > 0) {
+ builder.setRaddrStart(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv6AddressNoZone(details.remoteStartAddr)).stringValue()));
+ }
+ if (details.remoteStopAddr != null && details.remoteStopAddr.length > 0) {
+ builder.setRaddrStop(IpAddressBuilder.getDefaultInstance(
+ new IpAddressNoZone(arrayToIpv6AddressNoZone(details.remoteStopAddr)).stringValue()));
+ }
+ }
+
+ public static class IpsecStateSpdDetailsDumpExecutor
+ implements EntityDumpExecutor<IpsecSpdDetailsReplyDump, Void>, JvppReplyConsumer {
+ private FutureJVppCore jvpp;
+ private IpsecStateSpdsReplyDumpExecutor spdsDumpExecutor;
+
+ public IpsecStateSpdDetailsDumpExecutor(
+ final FutureJVppCore vppApi, final IpsecStateSpdsReplyDumpExecutor spdsDumpExecutor) {
+ this.jvpp = vppApi;
+ this.spdsDumpExecutor = spdsDumpExecutor;
+ }
+
+ @Nonnull
+ @Override
+ public IpsecSpdDetailsReplyDump executeDump(final InstanceIdentifier<?> identifier, final Void params)
+ throws ReadFailedException {
+ IpsecSpdDetailsReplyDump fullReplyDump = new IpsecSpdDetailsReplyDump();
+ fullReplyDump.ipsecSpdDetails = new LinkedList<>();
+
+ Optional<IpsecSpdsDetailsReplyDump> spdsReply =
+ Optional.of(spdsDumpExecutor.executeDump(identifier, params));
+ IpsecSpdsDetailsReplyDump spdDump = spdsReply.get();
+ for (IpsecSpdsDetails spdsDetail : spdDump.ipsecSpdsDetails) {
+ IpsecSpdDump dump = new IpsecSpdDump();
+ dump.spdId = spdsDetail.spdId;
+ dump.saId = -1;
+ IpsecSpdDetailsReplyDump reply =
+ getReplyForRead(jvpp.ipsecSpdDump(dump).toCompletableFuture(), identifier);
+ fullReplyDump.ipsecSpdDetails.addAll(reply.ipsecSpdDetails);
+ }
+
+ return fullReplyDump;
+ }
+ }
+
+ private class IpsecStateSpdsReplyDumpExecutor implements EntityDumpExecutor<IpsecSpdsDetailsReplyDump, Void> {
+ private final FutureJVppCore jvpp;
+
+ public IpsecStateSpdsReplyDumpExecutor(
+ final FutureJVppCore vppApi) {
+ this.jvpp = vppApi;
+ }
+
+ @Nonnull
+ @Override
+ public IpsecSpdsDetailsReplyDump executeDump(final InstanceIdentifier<?> identifier, final Void params)
+ throws ReadFailedException {
+ return getReplyForRead(jvpp.ipsecSpdsDump(new IpsecSpdsDump()).toCompletableFuture(), identifier);
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizer.java
new file mode 100644
index 000000000..6886b9b5d
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2SetLocalKey;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkeGlobalConfAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.IkeGlobalConfiguration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ikev2GlobalConfigurationCustomizer extends FutureJVppCustomizer
+ implements WriterCustomizer<IkeGlobalConfiguration>, JvppReplyConsumer {
+ public Ikev2GlobalConfigurationCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<IkeGlobalConfiguration> id,
+ @Nonnull final IkeGlobalConfiguration dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ IpsecIkeGlobalConfAugmentation fileAUg = dataAfter.augmentation(IpsecIkeGlobalConfAugmentation.class);
+ if (fileAUg != null) {
+ if (fileAUg.getLocalKeyFile() != null) {
+ Ikev2SetLocalKey request = new Ikev2SetLocalKey();
+ request.keyFile = fileAUg.getLocalKeyFile().getBytes();
+ getReplyForWrite(getFutureJVpp().ikev2SetLocalKey(request).toCompletableFuture(), id);
+ }
+ }
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<IkeGlobalConfiguration> id,
+ @Nonnull final IkeGlobalConfiguration dataBefore,
+ @Nonnull final IkeGlobalConfiguration dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ writeCurrentAttributes(id, dataAfter, writeContext);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<IkeGlobalConfiguration> id,
+ @Nonnull final IkeGlobalConfiguration dataBefore,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ // VPP doesn't support deletion of local key file
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizer.java
new file mode 100644
index 000000000..300ea6b8e
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizer.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileAddDel;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetAuth;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetTs;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.nio.ByteBuffer;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkev2PolicyAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ikev2.policy.aug.grouping.TrafficSelectors;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IkeGeneralPolicyProfileGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.Policy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.PolicyKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.policy.profile.grouping.Authentication;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ikev2PolicyCustomizer extends FutureJVppCustomizer
+ implements ListWriterCustomizer<Policy, PolicyKey>, JvppReplyConsumer, ByteDataTranslator, Ipv4Translator {
+
+ public Ikev2PolicyCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Policy> id, @Nonnull final Policy dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ final Ikev2ProfileAddDel request = new Ikev2ProfileAddDel();
+ request.isAdd = BYTE_TRUE;
+ request.name = dataAfter.getName().getBytes();
+ getReplyForWrite(getFutureJVpp().ikev2ProfileAddDel(request).toCompletableFuture(), id);
+ addAuthorization(dataAfter, id);
+ addTrafficSelectors(dataAfter, id);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Policy> id, @Nonnull final Policy dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ final Ikev2ProfileAddDel request = new Ikev2ProfileAddDel();
+ request.isAdd = BYTE_FALSE;
+ request.name = dataBefore.getName().getBytes();
+ getReplyForWrite(getFutureJVpp().ikev2ProfileAddDel(request).toCompletableFuture(), id);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Policy> id, @Nonnull final Policy dataBefore,
+ @Nonnull final Policy dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ addAuthorization(dataAfter, id);
+ addTrafficSelectors(dataAfter, id);
+ }
+
+ private void addTrafficSelectors(final Policy dataAfter, final InstanceIdentifier<Policy> id)
+ throws WriteFailedException {
+ IpsecIkev2PolicyAugmentation aug = dataAfter.augmentation(IpsecIkev2PolicyAugmentation.class);
+ if (aug == null) {
+ return;
+ }
+ if (aug.getTrafficSelectors() != null) {
+ for (TrafficSelectors selector : aug.getTrafficSelectors()) {
+ Ikev2ProfileSetTs addTsRequest = new Ikev2ProfileSetTs();
+ if (selector.getLocalAddressHigh() != null && selector.getLocalAddressLow() != null) {
+ addTsRequest.isLocal = BYTE_TRUE;
+ addTsRequest.startAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getLocalAddressLow().getIpv4Address().getValue()))
+ .getInt();
+ addTsRequest.endAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getLocalAddressHigh().getIpv4Address().getValue()))
+ .getInt();
+ if (selector.getLocalPortHigh() != null && selector.getLocalPortLow() != null) {
+ addTsRequest.startPort = selector.getLocalPortLow().getValue().shortValue();
+ addTsRequest.endPort = selector.getLocalPortHigh().getValue().shortValue();
+ }
+ } else if (selector.getRemoteAddressHigh() != null && selector.getRemoteAddressLow() != null) {
+ addTsRequest.isLocal = BYTE_FALSE;
+ addTsRequest.startAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getRemoteAddressLow().getIpv4Address().getValue()))
+ .getInt();
+ addTsRequest.endAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getRemoteAddressHigh().getIpv4Address().getValue()))
+ .getInt();
+ if (selector.getRemotePortHigh() != null && selector.getRemotePortLow() != null) {
+ addTsRequest.startPort = selector.getRemotePortLow().getValue().shortValue();
+ addTsRequest.endPort = selector.getRemotePortHigh().getValue().shortValue();
+ }
+ }
+ if (selector.getProtocol() != null) {
+ addTsRequest.proto = selector.getProtocol().byteValue();
+ }
+ if (dataAfter.getName() != null) {
+ addTsRequest.name = dataAfter.getName().getBytes();
+ }
+ getReplyForWrite(getFutureJVpp().ikev2ProfileSetTs(addTsRequest).toCompletableFuture(), id);
+ }
+ }
+ }
+
+ private void addAuthorization(final Policy data, final InstanceIdentifier<Policy> id)
+ throws WriteFailedException {
+ Authentication auth = data.getAuthentication();
+ if (auth != null) {
+ if (auth.isPresharedKey() != null && data.getPreSharedKey() != null) {
+ setProfilePreSharedKeyAuth(data.key().getName(), data.getPreSharedKey(), id);
+ } else if (auth.isRsaSignature() != null) {
+ IpsecIkev2PolicyAugmentation aug = data.augmentation(IpsecIkev2PolicyAugmentation.class);
+ if (aug != null && aug.getCertificate() != null) {
+ setProfileRSAAuth(data.key().getName(), aug.getCertificate(), id);
+ }
+ }
+ }
+ }
+
+ private void setProfileRSAAuth(final String name, final String fileName, final InstanceIdentifier<Policy> id)
+ throws WriteFailedException {
+ Ikev2ProfileSetAuth request = new Ikev2ProfileSetAuth();
+ request.name = name.getBytes();
+ request.data = fileName.getBytes();
+ request.authMethod = BYTE_TRUE;
+ getReplyForWrite(getFutureJVpp().ikev2ProfileSetAuth(request).toCompletableFuture(), id);
+ }
+
+ private void setProfilePreSharedKeyAuth(final String name,
+ final IkeGeneralPolicyProfileGrouping.PreSharedKey preSharedKey,
+ final InstanceIdentifier<Policy> id) throws WriteFailedException {
+ final Ikev2ProfileSetAuth request = new Ikev2ProfileSetAuth();
+ request.authMethod = BYTE_FALSE;
+ if (preSharedKey.getHexString() != null) {
+ request.isHex = BYTE_TRUE;
+ }
+ request.data = preSharedKey.stringValue().getBytes();
+ request.name = name.getBytes();
+ getReplyForWrite(getFutureJVpp().ikev2ProfileSetAuth(request).toCompletableFuture(), id);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizer.java
new file mode 100644
index 000000000..4c11f1633
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetId;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.identity.FqdnString;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.identity.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.identity.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.identity.Rfc822AddressString;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ike.general.policy.profile.grouping.Identity;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.Policy;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ikev2PolicyIdentityCustomizer extends FutureJVppCustomizer
+ implements WriterCustomizer<Identity>, JvppReplyConsumer, ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ public Ikev2PolicyIdentityCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Identity> id,
+ @Nonnull final Identity dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ String name = id.firstKeyOf(Policy.class).getName();
+ if (dataAfter.getLocal() != null) {
+ setProfileId(id, name, dataAfter.getLocal().getIdentity(), true);
+ }
+
+ if (dataAfter.getRemote() != null) {
+ setProfileId(id, name, dataAfter.getRemote().getIdentity(), false);
+ }
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Identity> id,
+ @Nonnull final Identity dataBefore,
+ @Nonnull final Identity dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ writeCurrentAttributes(id, dataAfter, writeContext);
+ }
+
+ private void setProfileId(final InstanceIdentifier<Identity> id,
+ final String profileName,
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.Identity data,
+ final boolean isLocalId) throws WriteFailedException {
+ final Ikev2ProfileSetId request = new Ikev2ProfileSetId();
+ request.name = profileName.getBytes();
+ transformIdentityToRequest(data, request);
+ request.isLocal = isLocalId
+ ? BYTE_TRUE
+ : BYTE_FALSE;
+ getReplyForWrite(getFutureJVpp().ikev2ProfileSetId(request).toCompletableFuture(), id);
+ }
+
+ private void transformIdentityToRequest(
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.identity.grouping.Identity
+ identityData, final Ikev2ProfileSetId request) {
+ if (identityData instanceof Ipv4Address) {
+ request.idType = 1;
+ request.data = ipv4AddressNoZoneToArray(((Ipv4Address) identityData).getIpv4Address().getValue());
+ } else if (identityData instanceof FqdnString) {
+ request.idType = 2;
+ request.data = ((FqdnString) identityData).getFqdnString().getValue().getBytes();
+ } else if (identityData instanceof Rfc822AddressString) {
+ request.idType = 3;
+ request.data = ((Rfc822AddressString) identityData).getRfc822AddressString().getBytes();
+ } else if (identityData instanceof Ipv6Address) {
+ request.idType = 5;
+ request.data = ipv6AddressNoZoneToArray(((Ipv6Address) identityData).getIpv6Address());
+ }
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Identity> id,
+ @Nonnull final Identity dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ // VPP doesn't support deletion of Ikev2 Profile ID
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizer.java
new file mode 100644
index 000000000..d7bbee32d
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizer.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.IpsecSadAddDelEntry;
+import io.fd.vpp.jvpp.core.dto.IpsecSadAddDelEntryReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecSadEntriesAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ip.address.grouping.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ip.address.grouping.ip.address.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ip.address.grouping.ip.address.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.Ah;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.AuthenticationAlgorithm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.Esp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.HmacMd596;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.HmacSha196;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.EncryptionAlgorithm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes128Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes192Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes256Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.DesCbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntriesKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IpsecSadEntryCustomizer extends FutureJVppCustomizer
+ implements ListWriterCustomizer<SadEntries, SadEntriesKey>,
+ JvppReplyConsumer, ByteDataTranslator, Ipv6Translator, Ipv4Translator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IpsecSadEntryCustomizer.class);
+ private MultiNamingContext sadEntryMapping;
+
+ IpsecSadEntryCustomizer(final FutureJVppCore vppApi, final MultiNamingContext sadEntryMapping) {
+ super(vppApi);
+ this.sadEntryMapping = sadEntryMapping;
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<SadEntries> id,
+ @Nonnull final SadEntries dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ addDelEntry(id, dataAfter, writeContext, true);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<SadEntries> id,
+ @Nonnull final SadEntries dataBefore,
+ @Nonnull final SadEntries dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ writeCurrentAttributes(id, dataAfter, writeContext);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<SadEntries> id,
+ @Nonnull final SadEntries dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ addDelEntry(id, dataBefore, writeContext, false);
+ }
+
+ private void addDelEntry(final InstanceIdentifier<SadEntries> id,
+ final SadEntries dataAfter,
+ final WriteContext writeContext, boolean adding) throws WriteFailedException {
+ final IpsecSadAddDelEntry entry = new IpsecSadAddDelEntry();
+ IpsecSadEntriesAugmentation augment = dataAfter.augmentation(IpsecSadEntriesAugmentation.class);
+ if (augment != null && augment.getSaId() != null) {
+ entry.sadId = augment.getSaId();
+ }
+ if (dataAfter.getSpi() != null) {
+ entry.spi = dataAfter.getSpi().intValue();
+ }
+ if (dataAfter.getAntiReplayWindow() != null) {
+ entry.useAntiReplay = dataAfter.getAntiReplayWindow() > 0
+ ? BYTE_TRUE
+ : BYTE_FALSE;
+ }
+
+ if (dataAfter.getSaMode() != null) {
+ entry.isTunnel = Integer.valueOf(dataAfter.getSaMode().getIntValue()).byteValue();
+ }
+ entry.isAdd = adding
+ ? ByteDataTranslator.BYTE_TRUE
+ : ByteDataTranslator.BYTE_FALSE;
+ if (dataAfter.getEsp() != null) {
+ entry.protocol = 1;
+ fillEspAuthentication(entry, dataAfter.getEsp());
+ fillEspEncryption(entry, dataAfter.getEsp());
+
+ } else if (dataAfter.getAh() != null) {
+ entry.protocol = 0;
+ fillAhAuthentication(entry, dataAfter.getAh());
+ }
+
+ fillAddresses(entry, dataAfter);
+
+ LOG.debug("IPSec config change id={} request={}", id, entry);
+ final CompletionStage<IpsecSadAddDelEntryReply> ipsecSadEntryAddDellReplyFuture =
+ getFutureJVpp().ipsecSadAddDelEntry(entry);
+ getReplyForWrite(ipsecSadEntryAddDellReplyFuture.toCompletableFuture(), id);
+ if (adding) {
+ sadEntryMapping.addChild(dataAfter.key().getDirection().getName(), entry.sadId,
+ String.valueOf(dataAfter.key().getSpi()), writeContext.getMappingContext());
+ } else {
+ sadEntryMapping
+ .removeChild(dataAfter.key().getDirection().getName(), String.valueOf(dataAfter.key().getSpi()),
+ writeContext.getMappingContext());
+ }
+ }
+
+ private void fillAhAuthentication(IpsecSadAddDelEntry targetEntry, Ah data) {
+ //0 = None, 1 = MD5-96, 2 = SHA1-96, 3 = SHA-256, 4 = SHA-384, 5=SHA-512
+ AuthenticationAlgorithm authAlg = data.getAuthenticationAlgorithm();
+ if (authAlg != null) {
+ String integKey;
+ if (authAlg instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacMd596) {
+ integKey =
+ ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacMd596) authAlg)
+ .getHmacMd596().getKeyStr().stringValue();
+ targetEntry.integrityAlgorithm = 1;
+ } else if (authAlg instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacSha196) {
+ integKey =
+ ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacSha196) authAlg)
+ .getHmacSha196().getKeyStr().stringValue();
+ targetEntry.integrityAlgorithm = 2;
+ } else {
+ targetEntry.integrityAlgorithm = 0;
+ return;
+ }
+ targetEntry.integrityKey = integKey.getBytes();
+ }
+ }
+
+ private void fillEspAuthentication(IpsecSadAddDelEntry targetEntry, Esp data) {
+ //0 = None, 1 = MD5-96, 2 = SHA1-96, 3 = SHA-256, 4 = SHA-384, 5=SHA-512
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.Authentication
+ authAlg = data.getAuthentication();
+ if (authAlg != null) {
+ String integKey;
+ if (authAlg.getAuthenticationAlgorithm() instanceof HmacMd596) {
+ integKey = ((HmacMd596) authAlg.getAuthenticationAlgorithm()).getHmacMd596().getKeyStr().stringValue();
+ targetEntry.integrityAlgorithm = 1;
+ } else if (authAlg.getAuthenticationAlgorithm() instanceof HmacSha196) {
+ integKey =
+ ((HmacSha196) authAlg.getAuthenticationAlgorithm()).getHmacSha196().getKeyStr().stringValue();
+ targetEntry.integrityAlgorithm = 2;
+ } else {
+ targetEntry.integrityAlgorithm = 0;
+ return;
+ }
+ targetEntry.integrityKey = integKey.getBytes();
+ }
+ }
+
+ private void fillEspEncryption(IpsecSadAddDelEntry targetEntry, Esp data) {
+ //0 = Null, 1 = AES-CBC-128, 2 = AES-CBC-192, 3 = AES-CBC-256, 4 = 3DES-CBC
+ if (data.getEncryption() != null && data.getEncryption().getEncryptionAlgorithm() != null) {
+ String cryptoKey = "";
+ EncryptionAlgorithm encrAlg = data.getEncryption().getEncryptionAlgorithm();
+ if (encrAlg instanceof Aes128Cbc) {
+ cryptoKey = ((Aes128Cbc) encrAlg).getAes128Cbc().getKeyStr().stringValue();
+ targetEntry.cryptoAlgorithm = 1;
+ } else if (encrAlg instanceof Aes192Cbc) {
+ cryptoKey = ((Aes192Cbc) encrAlg).getAes192Cbc().getKeyStr().stringValue();
+ targetEntry.cryptoAlgorithm = 2;
+ } else if (encrAlg instanceof Aes256Cbc) {
+ cryptoKey = ((Aes256Cbc) encrAlg).getAes256Cbc().getKeyStr().stringValue();
+ targetEntry.cryptoAlgorithm = 3;
+ } else if (encrAlg instanceof DesCbc) {
+ cryptoKey = ((DesCbc) encrAlg).getDesCbc().getKeyStr().stringValue();
+ targetEntry.cryptoAlgorithm = 4;
+ } else {
+ targetEntry.cryptoAlgorithm = 0;
+ return;
+ }
+ targetEntry.cryptoKey = cryptoKey.getBytes();
+ }
+ }
+
+ private void fillAddresses(IpsecSadAddDelEntry targetEntry, SadEntries data) {
+ if (data.getSourceAddress() != null && data.getSourceAddress().getIpAddress() != null) {
+ IpAddress sourceAddr = data.getSourceAddress().getIpAddress();
+ if (sourceAddr instanceof Ipv4Address) {
+ Ipv4Address ipv4 = (Ipv4Address) sourceAddr;
+ targetEntry.isTunnelIpv6 = 0;
+ targetEntry.tunnelSrcAddress = ipv4AddressNoZoneToArray(ipv4.getIpv4Address().getValue());
+ } else if (sourceAddr instanceof Ipv6Address) {
+ Ipv6Address ipv6 = (Ipv6Address) sourceAddr;
+ targetEntry.isTunnelIpv6 = 1;
+ targetEntry.tunnelSrcAddress = ipv6AddressNoZoneToArray(ipv6.getIpv6Address());
+ }
+ }
+
+ if (data.getDestinationAddress() != null && data.getDestinationAddress().getIpAddress() != null) {
+ IpAddress destAddr = data.getDestinationAddress().getIpAddress();
+
+ if (destAddr instanceof Ipv4Address) {
+ Ipv4Address ipv4 = (Ipv4Address) destAddr;
+ targetEntry.isTunnelIpv6 = 0;
+ targetEntry.tunnelDstAddress = ipv4AddressNoZoneToArray(ipv4.getIpv4Address().getValue());
+ } else if (destAddr instanceof Ipv6Address) {
+ Ipv6Address ipv6 = (Ipv6Address) destAddr;
+ targetEntry.isTunnelIpv6 = 1;
+ targetEntry.tunnelDstAddress = ipv6AddressNoZoneToArray(ipv6.getIpv6Address());
+ }
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizer.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizer.java
new file mode 100644
index 000000000..771cf676a
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizer.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDel;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDelEntry;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecSpdEntriesAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.Spd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.SpdKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.spd.SpdEntries;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class IpsecSpdCustomizer extends FutureJVppCustomizer
+ implements ListWriterCustomizer<Spd, SpdKey>, JvppReplyConsumer, ByteDataTranslator,
+ Ipv6Translator, Ipv4Translator {
+
+ public IpsecSpdCustomizer(final FutureJVppCore vppApi) {
+ super(vppApi);
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Spd> id, @Nonnull final Spd dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ IpsecSpdAddDel spdCreate = new IpsecSpdAddDel();
+ spdCreate.isAdd = ByteDataTranslator.BYTE_TRUE;
+ spdCreate.spdId = dataAfter.getSpdId();
+ getReplyForWrite(getFutureJVpp().ipsecSpdAddDel(spdCreate).toCompletableFuture(), id);
+ if (dataAfter.getSpdEntries() != null) {
+ for (SpdEntries entry : dataAfter.getSpdEntries()) {
+ addSpdEntry(id, dataAfter.getSpdId(), entry);
+ }
+ }
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Spd> id, @Nonnull final Spd dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ IpsecSpdAddDel spdDelete = new IpsecSpdAddDel();
+ spdDelete.isAdd = ByteDataTranslator.BYTE_FALSE;
+ spdDelete.spdId = dataBefore.getSpdId();
+ getReplyForWrite(getFutureJVpp().ipsecSpdAddDel(spdDelete).toCompletableFuture(), id);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Spd> id, @Nonnull final Spd dataBefore,
+ @Nonnull final Spd dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ if (dataAfter.getSpdEntries() != null) {
+ for (SpdEntries entry : dataAfter.getSpdEntries()) {
+ addSpdEntry(id, dataAfter.getSpdId(), entry);
+ }
+ }
+ }
+
+ private void addSpdEntry(final InstanceIdentifier<Spd> id, int spdId, final SpdEntries entry)
+ throws WriteFailedException {
+ IpsecSpdAddDelEntry request = new IpsecSpdAddDelEntry();
+ request.spdId = spdId;
+ request.isAdd = ByteDataTranslator.BYTE_TRUE;
+ IpsecSpdEntriesAugmentation entryAug = entry.augmentation(IpsecSpdEntriesAugmentation.class);
+ if (entryAug == null) {
+ return;
+ }
+
+ if (entryAug.isIsIpv6() != null) {
+ request.isIpv6 = (byte) (entryAug.isIsIpv6()
+ ? 1
+ : 0);
+ }
+ if (entryAug.getDirection() != null) {
+ request.isOutbound = (byte) entryAug.getDirection().getIntValue();
+ }
+
+ if (entryAug.getPriority() != null) {
+ request.priority = entryAug.getPriority();
+ }
+
+ if (entryAug.getOperation() != null) {
+ final String operation = entryAug.getOperation().getName();
+ if (operation.equalsIgnoreCase("bypass")) {
+ request.policy = (byte) 0;
+ } else if (operation.equalsIgnoreCase("discard")) {
+ request.policy = (byte) 1;
+ } else if (operation.equalsIgnoreCase("protect")) {
+ request.policy = (byte) 3;
+ }
+ }
+
+ if (entryAug.getLaddrStart() != null) {
+ if (entryAug.getLaddrStart().getIpv4Address() != null) {
+ request.localAddressStart =
+ ipv4AddressNoZoneToArray(entryAug.getLaddrStart().getIpv4Address().getValue());
+ } else if (entryAug.getLaddrStart().getIpv6Address() != null) {
+ request.localAddressStart = ipv6AddressNoZoneToArray(entryAug.getLaddrStart().getIpv6Address());
+ }
+ }
+ if (entryAug.getLaddrStop() != null) {
+ if (entryAug.getLaddrStop().getIpv4Address() != null) {
+ request.localAddressStop =
+ ipv4AddressNoZoneToArray(entryAug.getLaddrStop().getIpv4Address().getValue());
+ } else if (entryAug.getLaddrStop().getIpv6Address() != null) {
+ request.localAddressStop = ipv6AddressNoZoneToArray(entryAug.getLaddrStop().getIpv6Address());
+ }
+ }
+ if (entryAug.getRaddrStop() != null) {
+ if (entryAug.getRaddrStop().getIpv4Address() != null) {
+ request.remoteAddressStop =
+ ipv4AddressNoZoneToArray(entryAug.getRaddrStop().getIpv4Address().getValue());
+ } else if (entryAug.getRaddrStop().getIpv6Address() != null) {
+ request.remoteAddressStop = ipv6AddressNoZoneToArray(entryAug.getRaddrStop().getIpv6Address());
+ }
+ }
+
+ if (entryAug.getRaddrStart() != null) {
+ if (entryAug.getRaddrStart().getIpv4Address() != null) {
+ request.remoteAddressStart =
+ ipv4AddressNoZoneToArray(entryAug.getRaddrStart().getIpv4Address().getValue());
+ } else if (entryAug.getRaddrStart().getIpv6Address() != null) {
+ request.remoteAddressStart = ipv6AddressNoZoneToArray(entryAug.getRaddrStart().getIpv6Address());
+ }
+ }
+ getReplyForWrite(getFutureJVpp().ipsecSpdAddDelEntry(request).toCompletableFuture(), id);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecWriterFactory.java b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecWriterFactory.java
new file mode 100644
index 000000000..8b164ac74
--- /dev/null
+++ b/ipsec/ipsec-impl/src/main/java/io/fd/hc2vpp/ipsec/write/IpsecWriterFactory.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
+import io.fd.honeycomb.translate.impl.write.GenericListWriter;
+import io.fd.honeycomb.translate.impl.write.GenericWriter;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkeGlobalConfAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkev2PolicyAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecSadEntriesAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecSpdEntriesAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ikev2.policy.aug.grouping.TrafficSelectors;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ikev2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ipsec;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ike.general.policy.profile.grouping.Identity;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ike.general.policy.profile.grouping.identity.Local;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ike.general.policy.profile.grouping.identity.Remote;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.IkeGlobalConfiguration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.Policy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.Sad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.Spd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.Ah;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.Esp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.Authentication;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.Encryption;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.hmac.md5._96.HmacMd596;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.hmac.sha1._96.HmacSha196;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._128.cbc.Aes128Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._192.cbc.Aes192Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._256.cbc.Aes256Cbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.des.cbc.DesCbc;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.grouping.DestinationAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.grouping.SourceAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.spd.SpdEntries;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Factory producing writers for IpSec plugin's data.
+ */
+public final class IpsecWriterFactory implements WriterFactory {
+
+ private static final InstanceIdentifier<Ikev2> IKE2_ID = InstanceIdentifier.create(Ikev2.class);
+ private static final InstanceIdentifier<Ipsec> IPSEC_ID = InstanceIdentifier.create(Ipsec.class);
+ private static final InstanceIdentifier<Sad> SAD_ID = IPSEC_ID.child(Sad.class);
+ private static final InstanceIdentifier<SadEntries> SAD_ENTRIES_ID = SAD_ID.child(SadEntries.class);
+ private static final InstanceIdentifier<Spd> SPD_ID = IPSEC_ID.child(Spd.class);
+
+ private final FutureJVppCore vppApi;
+ private MultiNamingContext sadEntriesMapping;
+
+ @Inject
+ public IpsecWriterFactory(final FutureJVppCore vppApi, final MultiNamingContext sadEntriesMappingContext) {
+ this.vppApi = vppApi;
+ this.sadEntriesMapping = sadEntriesMappingContext;
+ }
+
+ @Override
+ public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+ registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(SadEntries.class).child(SourceAddress.class),
+ InstanceIdentifier.create(SadEntries.class).child(DestinationAddress.class),
+ InstanceIdentifier.create(SadEntries.class).child(Ah.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.hmac.sha1._96.HmacSha196.class),
+ InstanceIdentifier.create(SadEntries.class).child(Ah.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.hmac.md5._96.HmacMd596.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Authentication.class)
+ .child(HmacSha196.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Authentication.class)
+ .child(HmacMd596.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Encryption.class)
+ .child(Aes128Cbc.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Encryption.class)
+ .child(Aes192Cbc.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Encryption.class)
+ .child(Aes256Cbc.class),
+ InstanceIdentifier.create(SadEntries.class).child(Esp.class).child(Encryption.class)
+ .child(DesCbc.class),
+ InstanceIdentifier.create(SadEntries.class).augmentation(IpsecSadEntriesAugmentation.class)),
+ new GenericListWriter<>(SAD_ENTRIES_ID, new IpsecSadEntryCustomizer(vppApi, sadEntriesMapping)));
+ registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(Spd.class).child(SpdEntries.class),
+ InstanceIdentifier.create(Spd.class).child(SpdEntries.class)
+ .augmentation(IpsecSpdEntriesAugmentation.class)),
+ new GenericListWriter<>(SPD_ID, new IpsecSpdCustomizer(vppApi)));
+ registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(IkeGlobalConfiguration.class)
+ .augmentation(IpsecIkeGlobalConfAugmentation.class)),
+ new GenericWriter<>(IKE2_ID.child(IkeGlobalConfiguration.class),
+ new Ikev2GlobalConfigurationCustomizer(vppApi)));
+ registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(Policy.class).child(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.policy.profile.grouping.Authentication.class),
+ InstanceIdentifier.create(Policy.class).augmentation(IpsecIkev2PolicyAugmentation.class),
+ InstanceIdentifier.create(Policy.class).augmentation(IpsecIkev2PolicyAugmentation.class)
+ .child(TrafficSelectors.class)),
+ new GenericListWriter<>(IKE2_ID.child(Policy.class), new Ikev2PolicyCustomizer(vppApi)));
+ registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(Identity.class).child(Local.class),
+ InstanceIdentifier.create(Identity.class).child(Remote.class)),
+ new GenericWriter<>(IKE2_ID.child(Policy.class).child(Identity.class),
+ new Ikev2PolicyIdentityCustomizer(vppApi)));
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/IpsecModuleTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/IpsecModuleTest.java
new file mode 100644
index 000000000..42817d42a
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/IpsecModuleTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.empty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.testing.fieldbinder.Bind;
+import com.google.inject.testing.fieldbinder.BoundFieldModule;
+import io.fd.hc2vpp.ipsec.read.IpsecReaderFactory;
+import io.fd.hc2vpp.ipsec.write.IpsecWriterFactory;
+import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder;
+import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.util.YangDAG;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class IpsecModuleTest {
+
+ @Bind
+ @Mock
+ private FutureJVppCore futureJVppCore;
+
+ @Inject
+ private Set<WriterFactory> writerFactories = new HashSet<>();
+
+ @Inject
+ private Set<ReaderFactory> readerFactories = new HashSet<>();
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+ Guice.createInjector(new IpsecModule(), BoundFieldModule.of(this)).injectMembers(this);
+ }
+
+ @Test
+ public void testWriterFactories() throws Exception {
+ assertThat(writerFactories, is(not(empty())));
+ final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(new YangDAG());
+ writerFactories.stream().forEach(factory -> factory.init(registryBuilder));
+ assertNotNull(registryBuilder.build());
+ assertEquals(1, writerFactories.size());
+ assertTrue(writerFactories.iterator().next() instanceof IpsecWriterFactory);
+ }
+
+ @Test
+ public void testReaderFactories() throws Exception {
+ assertThat(readerFactories, is(not(empty())));
+ final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(new YangDAG());
+ readerFactories.stream().forEach(factory -> factory.init(registryBuilder));
+ assertNotNull(registryBuilder.build());
+ assertEquals(1, readerFactories.size());
+ assertTrue(readerFactories.iterator().next() instanceof IpsecReaderFactory);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/helpers/SchemaContextTestHelper.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/helpers/SchemaContextTestHelper.java
new file mode 100644
index 000000000..bce8a982a
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/helpers/SchemaContextTestHelper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.helpers;
+
+import com.google.common.collect.ImmutableSet;
+import io.fd.honeycomb.test.tools.annotations.InjectablesProcessor;
+import io.fd.honeycomb.test.tools.annotations.SchemaContextProvider;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+
+public interface SchemaContextTestHelper extends InjectablesProcessor {
+
+ @SchemaContextProvider
+ default ModuleInfoBackedContext getSchemaContext() {
+ return provideSchemaContextFor(ImmutableSet.of(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.$YangModuleInfoImpl
+ .getInstance(),
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.$YangModuleInfoImpl
+ .getInstance()
+ ));
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizerTest.java
new file mode 100644
index 000000000..9b8f9157f
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateCustomizerTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.read;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSaDump;
+import java.util.LinkedList;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.state.grouping.Sa;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class IpsecStateCustomizerTest extends ReaderCustomizerTest<IpsecState, IpsecStateBuilder>
+ implements ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static InstanceIdentifier<IpsecState> IPSEC_STATE_ID = InstanceIdentifier.create(IpsecState.class);
+ private static final String LOCAL_ADDR_START = "192.168.11.1";
+ private static final String REMOTE_ADDR_START = "192.168.22.1";
+ private static final String TUNNEL_SRC_ADDR = LOCAL_ADDR_START;
+ private static final String TUNNEL_DST_ADDR = REMOTE_ADDR_START;
+ private static final int REPLY_WINDOW = 88;
+ private static final int SA_ID = 10;
+ private static final int SPI = 1001;
+ private static final int CRYPTO_ALG = 1;
+ private static final String CRYPTO_KEY = "123456789";
+ private static final int INTEG_ALG = 2;
+ private static final String INTEG_KEY = "987654321";
+ private static final int PROTOCOL = 1;
+ private static final int LAST_SEQ_INB = 8;
+ private static final int HOLD_DOWN = 88;
+
+ public IpsecStateCustomizerTest() {
+ super(IpsecState.class, IpsecStateBuilder.class);
+ }
+
+ @Override
+ protected ReaderCustomizer<IpsecState, IpsecStateBuilder> initCustomizer() {
+ return new IpsecStateCustomizer(api);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ final IpsecSaDetailsReplyDump saDetailsReply = new IpsecSaDetailsReplyDump();
+ LinkedList<IpsecSaDetails> saDetails = new LinkedList<>();
+ IpsecSaDetails saDetail = new IpsecSaDetails();
+ saDetail.spi = SPI;
+ saDetail.saId = SA_ID;
+ saDetail.cryptoAlg = CRYPTO_ALG;
+ saDetail.cryptoKey = CRYPTO_KEY.getBytes();
+ saDetail.integAlg = INTEG_ALG;
+ saDetail.integKey = INTEG_KEY.getBytes();
+ saDetail.isTunnel = BYTE_TRUE;
+ saDetail.isTunnelIp6 = BYTE_FALSE;
+ saDetail.protocol = PROTOCOL;
+ saDetail.lastSeqInbound = LAST_SEQ_INB;
+ saDetail.replayWindow = REPLY_WINDOW;
+ saDetail.useAntiReplay = BYTE_TRUE;
+ saDetail.tunnelSrcAddr = ipv4AddressNoZoneToArray(TUNNEL_SRC_ADDR);
+ saDetail.tunnelDstAddr = ipv4AddressNoZoneToArray(TUNNEL_DST_ADDR);
+ saDetails.add(saDetail);
+ saDetailsReply.ipsecSaDetails = saDetails;
+ IpsecSaDump saDump = new IpsecSaDump();
+ saDump.saId = SA_ID;
+ when(api.ipsecSaDump(any())).thenReturn(future(saDetailsReply));
+ }
+
+ @Test
+ public void testReadSa() throws ReadFailedException {
+ final IpsecStateBuilder builder = new IpsecStateBuilder();
+ getCustomizer().readCurrentAttributes(IPSEC_STATE_ID, builder, ctx);
+ assertEquals(builder.getSa().size(), 1);
+ Sa sa = builder.getSa().get(0);
+ assertEquals(sa.getAntiReplayWindow().intValue(), REPLY_WINDOW);
+ assertEquals(sa.getAuthenticationAlgorithm().getIntValue(), INTEG_ALG);
+ assertEquals(sa.getEncryptionAlgorithm().getIntValue(), CRYPTO_ALG);
+ assertEquals(sa.getSpi().intValue(), SPI);
+ }
+
+ @Test
+ public void testMerge() throws Exception {
+ final IpsecStateBuilder parentBuilder = new IpsecStateBuilder();
+ final IpsecStateBuilder builderForNewdata = new IpsecStateBuilder();
+ builderForNewdata.setHoldDown(new Long(HOLD_DOWN));
+ getCustomizer().merge(parentBuilder, builderForNewdata.build());
+ assertEquals(parentBuilder.getHoldDown().intValue(), HOLD_DOWN);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizerTest.java
new file mode 100644
index 000000000..bf08fa8c3
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/read/IpsecStateSpdCustomizerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.read;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdsDetails;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdsDetailsReplyDump;
+import java.util.LinkedList;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecStateSpdAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.Spd;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.SpdBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.SpdKey;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ipsec.state.spd.SpdEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecState;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class IpsecStateSpdCustomizerTest extends ReaderCustomizerTest<Spd, SpdBuilder>
+ implements ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static InstanceIdentifier<Spd> SPD_IID = InstanceIdentifier.create(IpsecState.class)
+ .augmentation(IpsecStateSpdAugmentation.class).child(Spd.class, new SpdKey(10));
+
+ private static final String LOCAL_ADDR_START = "192.168.11.1";
+ private static final String LOCAL_ADDR_END = "192.168.11.255";
+ private static final short PORT_START = 0;
+ private static final short PORT_END = Short.MAX_VALUE;
+ private static final int POLICY_PROTECT = 3;
+ private static final int SPD_ID = 10;
+ private static final int SA_ID = 10;
+ private static final int PROTOCOL = 1;
+ private static final int PRIORITY = 100;
+
+ public IpsecStateSpdCustomizerTest() {
+ super(Spd.class, SpdBuilder.class);
+ }
+
+ @Override
+ protected ReaderCustomizer<Spd, SpdBuilder> initCustomizer() {
+ return new IpsecStateSpdCustomizer(api);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ final IpsecSpdDetailsReplyDump spdDetailsReply = new IpsecSpdDetailsReplyDump();
+ LinkedList<IpsecSpdDetails> spdDetails = new LinkedList<>();
+ IpsecSpdDetails spdDetail = new IpsecSpdDetails();
+ spdDetail.isIpv6 = BYTE_FALSE;
+ spdDetail.isOutbound = BYTE_TRUE;
+ spdDetail.spdId = SPD_ID;
+ spdDetail.protocol = PROTOCOL;
+ spdDetail.localStartAddr = ipv4AddressNoZoneToArray(LOCAL_ADDR_START);
+ spdDetail.localStopAddr = ipv4AddressNoZoneToArray(LOCAL_ADDR_END);
+ spdDetail.localStartPort = PORT_START;
+ spdDetail.localStopPort = PORT_END;
+ spdDetail.policy = POLICY_PROTECT;
+ spdDetail.saId = SA_ID;
+ spdDetail.priority = PRIORITY;
+ spdDetails.add(spdDetail);
+ spdDetailsReply.ipsecSpdDetails = spdDetails;
+ when(api.ipsecSpdDump(any())).thenReturn(future(spdDetailsReply));
+
+ IpsecSpdsDetailsReplyDump spdsReply = new IpsecSpdsDetailsReplyDump();
+ IpsecSpdsDetails spdsDetail = new IpsecSpdsDetails();
+ spdsDetail.spdId = SPD_ID;
+ spdsReply.ipsecSpdsDetails.add(spdsDetail);
+ when(api.ipsecSpdsDump(any())).thenReturn(future(spdsReply));
+ }
+
+ @Test
+ public void testReadSpd() throws ReadFailedException {
+ final SpdBuilder builder = new SpdBuilder();
+ getCustomizer().readCurrentAttributes(SPD_IID, builder, ctx);
+ assertEquals(builder.getSpdEntries().size(), 1);
+ SpdEntries spdEntries = builder.getSpdEntries().get(0);
+ assertEquals(spdEntries.getDirection().getName(), "outbound");
+ assertEquals(spdEntries.getPriority().intValue(), PRIORITY);
+ }
+
+ @Test
+ public void testMerge() throws Exception {
+ final IpsecStateSpdAugmentationBuilder parentBuilder = new IpsecStateSpdAugmentationBuilder();
+ final IpsecStateSpdAugmentationBuilder builderForNewData = new IpsecStateSpdAugmentationBuilder();
+ SpdBuilder spdBuilder = new SpdBuilder();
+ spdBuilder.setSpdId(SPD_ID);
+ getCustomizer().merge(parentBuilder, spdBuilder.build());
+ assertEquals(parentBuilder.getSpd().size(), 1);
+ assertEquals(parentBuilder.getSpd().get(0).getSpdId().intValue(), SPD_ID);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizerTest.java
new file mode 100644
index 000000000..cf9e8b102
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2GlobalConfigurationCustomizerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.ipsec.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2SetLocalKey;
+import io.fd.vpp.jvpp.core.dto.Ikev2SetLocalKeyReply;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkeGlobalConfAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkeGlobalConfAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ikev2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.IkeGlobalConfiguration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.IkeGlobalConfigurationBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ikev2GlobalConfigurationCustomizerTest extends WriterCustomizerTest
+ implements SchemaContextTestHelper {
+ InstanceIdentifier<IkeGlobalConfiguration> IID = InstanceIdentifier.create(Ikev2.class)
+ .child(IkeGlobalConfiguration.class);
+ private Ikev2GlobalConfigurationCustomizer customizer;
+ private static final String LOCAL_KEY_FILE = "/home/localadmin/certs/client-key.pem";
+
+ @Override
+ protected void setUpTest() throws Exception {
+ customizer = new Ikev2GlobalConfigurationCustomizer(api);
+ when(api.ikev2SetLocalKey(any())).thenReturn(future(new Ikev2SetLocalKeyReply()));
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ IkeGlobalConfigurationBuilder dataAfterBuilder = new IkeGlobalConfigurationBuilder();
+ IpsecIkeGlobalConfAugmentationBuilder augBuilder = new IpsecIkeGlobalConfAugmentationBuilder();
+ augBuilder.setLocalKeyFile(LOCAL_KEY_FILE);
+ dataAfterBuilder.addAugmentation(IpsecIkeGlobalConfAugmentation.class, augBuilder.build());
+ customizer.writeCurrentAttributes(IID, dataAfterBuilder.build(), writeContext);
+ Ikev2SetLocalKey request = new Ikev2SetLocalKey();
+ request.keyFile = LOCAL_KEY_FILE.getBytes();
+ verify(api).ikev2SetLocalKey(request);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizerTest.java
new file mode 100644
index 000000000..0c7b65f1b
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyCustomizerTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.ipsec.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.test.tools.HoneycombTestRunner;
+import io.fd.honeycomb.test.tools.annotations.InjectTestData;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileAddDel;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileAddDelReply;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetAuth;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetAuthReply;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetTs;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetTsReply;
+import java.nio.ByteBuffer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecIkev2PolicyAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.ikev2.policy.aug.grouping.TrafficSelectors;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ikev2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.Policy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.PolicyKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.policy.profile.grouping.Authentication;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(HoneycombTestRunner.class)
+public class Ikev2PolicyCustomizerTest extends WriterCustomizerTest implements SchemaContextTestHelper,
+ ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static final String IKEV2_PATH = "/hc2vpp-ietf-ipsec:ikev2";
+ private Ikev2PolicyCustomizer customizer;
+
+ @Override
+ protected void setUpTest() throws Exception {
+ customizer = new Ikev2PolicyCustomizer(api);
+ when(api.ikev2ProfileAddDel(any())).thenReturn(future(new Ikev2ProfileAddDelReply()));
+ when(api.ikev2ProfileSetTs(any())).thenReturn(future(new Ikev2ProfileSetTsReply()));
+ when(api.ikev2ProfileSetAuth(any())).thenReturn(future(new Ikev2ProfileSetAuthReply()));
+ }
+
+ @Test
+ public void testWrite(@InjectTestData(resourcePath = "/ikev2/addIkev2Profile.json", id = IKEV2_PATH) Ikev2 ikev2)
+ throws WriteFailedException {
+ Policy policy = ikev2.getPolicy().get(0);
+ customizer.writeCurrentAttributes(getId(policy.getName()), policy, writeContext);
+ Ikev2ProfileAddDel profileAddrequest = new Ikev2ProfileAddDel();
+ profileAddrequest.isAdd = BYTE_TRUE;
+ profileAddrequest.name = policy.getName().getBytes();
+
+ verify(api).ikev2ProfileAddDel(profileAddrequest);
+ verify(api).ikev2ProfileSetTs(translateTStoRequest(policy.augmentation(IpsecIkev2PolicyAugmentation.class)
+ .getTrafficSelectors().get(0), policy.getName()));
+ verify(api).ikev2ProfileSetAuth(translateAuthToRequest(policy));
+ }
+
+ @Test
+ public void testUpdate(
+ @InjectTestData(resourcePath = "/ikev2/addDelProfile_before.json", id = IKEV2_PATH) Ikev2 ikev2Before,
+ @InjectTestData(resourcePath = "/ikev2/addDelProfile_after.json", id = IKEV2_PATH) Ikev2 ikev2After)
+ throws WriteFailedException {
+ final Policy before = ikev2Before.getPolicy().get(0);
+ final Policy after = ikev2After.getPolicy().get(0);
+ customizer.updateCurrentAttributes(getId(before.getName()), before, after, writeContext);
+
+ verify(api, times(0)).ikev2ProfileAddDel(any());
+ verify(api).ikev2ProfileSetTs(translateTStoRequest(after.augmentation(IpsecIkev2PolicyAugmentation.class)
+ .getTrafficSelectors().get(0), after.getName()));
+ verify(api).ikev2ProfileSetAuth(translateAuthToRequest(after));
+ }
+
+ @Test
+ public void testDelete(@InjectTestData(resourcePath = "/ikev2/addIkev2Profile.json", id = IKEV2_PATH) Ikev2 ikev2)
+ throws WriteFailedException {
+ Policy policy = ikev2.getPolicy().get(0);
+ customizer.deleteCurrentAttributes(getId(policy.getName()), policy, writeContext);
+ final Ikev2ProfileAddDel request = new Ikev2ProfileAddDel();
+ request.name = policy.getName().getBytes();
+ request.isAdd = BYTE_FALSE;
+ verify(api).ikev2ProfileAddDel(request);
+ verify(api, times(0)).ikev2ProfileSetTs(any());
+ verify(api, times(0)).ikev2ProfileSetAuth(any());
+ }
+
+ private InstanceIdentifier<Policy> getId(final String name) {
+ return InstanceIdentifier.create(Ikev2.class).child(Policy.class, new PolicyKey(name));
+ }
+
+ private Ikev2ProfileSetTs translateTStoRequest(final TrafficSelectors selector, final String policyName) {
+ Ikev2ProfileSetTs addTsRequest = new Ikev2ProfileSetTs();
+ if (selector.getLocalAddressHigh() != null && selector.getLocalAddressLow() != null) {
+ addTsRequest.isLocal = ByteDataTranslator.BYTE_TRUE;
+ addTsRequest.startAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getLocalAddressLow().getIpv4Address().getValue())).getInt();
+ addTsRequest.endAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getLocalAddressHigh().getIpv4Address().getValue()))
+ .getInt();
+ if (selector.getLocalPortHigh() != null && selector.getLocalPortLow() != null) {
+ addTsRequest.startPort = selector.getLocalPortLow().getValue().shortValue();
+ addTsRequest.endPort = selector.getLocalPortHigh().getValue().shortValue();
+ }
+ } else if (selector.getRemoteAddressHigh() != null && selector.getRemoteAddressLow() != null) {
+ addTsRequest.isLocal = ByteDataTranslator.BYTE_FALSE;
+ addTsRequest.startAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getRemoteAddressLow().getIpv4Address().getValue()))
+ .getInt();
+ addTsRequest.endAddr = ByteBuffer
+ .wrap(ipv4AddressNoZoneToArray(selector.getRemoteAddressHigh().getIpv4Address().getValue()))
+ .getInt();
+ if (selector.getRemotePortHigh() != null && selector.getRemotePortLow() != null) {
+ addTsRequest.startPort = selector.getRemotePortLow().getValue().shortValue();
+ addTsRequest.endPort = selector.getRemotePortHigh().getValue().shortValue();
+ }
+ }
+ if (selector.getProtocol() != null) {
+ addTsRequest.proto = selector.getProtocol().byteValue();
+ }
+ if (policyName != null) {
+ addTsRequest.name = policyName.getBytes();
+ }
+ return addTsRequest;
+ }
+
+ private Ikev2ProfileSetAuth translateAuthToRequest(Policy policy) {
+ final Ikev2ProfileSetAuth request = new Ikev2ProfileSetAuth();
+ Authentication auth = policy.getAuthentication();
+ if (auth != null) {
+ request.name = policy.getName().getBytes();
+ if (auth.isPresharedKey() != null && policy.getPreSharedKey() != null) {
+ request.authMethod = ByteDataTranslator.BYTE_FALSE;
+ if (policy.getPreSharedKey().getHexString() != null) {
+ request.isHex = ByteDataTranslator.BYTE_TRUE;
+ }
+ request.data = policy.getPreSharedKey().stringValue().getBytes();
+ } else if (auth.isRsaSignature() != null) {
+ IpsecIkev2PolicyAugmentation aug = policy.augmentation(IpsecIkev2PolicyAugmentation.class);
+ if (aug != null && aug.getCertificate() != null) {
+ request.data = aug.getCertificate().getBytes();
+ request.authMethod = ByteDataTranslator.BYTE_TRUE;
+ }
+ }
+ }
+ return request;
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizerTest.java
new file mode 100644
index 000000000..bb8f0d762
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/Ikev2PolicyIdentityCustomizerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.ipsec.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.test.tools.HoneycombTestRunner;
+import io.fd.honeycomb.test.tools.annotations.InjectTestData;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetId;
+import io.fd.vpp.jvpp.core.dto.Ikev2ProfileSetIdReply;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ikev2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ike.general.policy.profile.grouping.Identity;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.Policy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ikev2.PolicyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(HoneycombTestRunner.class)
+public class Ikev2PolicyIdentityCustomizerTest extends WriterCustomizerTest implements SchemaContextTestHelper,
+ ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static final String POLICY_NAME = "testPolicy";
+ private static final String IPV4_TYPE_DATA = "192.168.123.22";
+ private static final String IPV6_TYPE_DATA = "2001:DB8:0:0:8:800:200C:417A";
+ private static final String FQDN_TYPE_DATA = "vpp.home";
+ private static final String RFC822_TYPE_DATA = "rfc822@example.com";
+ private static final String IDENTITY_PATH =
+ "/hc2vpp-ietf-ipsec:ikev2/hc2vpp-ietf-ipsec:policy[hc2vpp-ietf-ipsec:name='" + POLICY_NAME +
+ "']/hc2vpp-ietf-ipsec:identity";
+ private Ikev2PolicyIdentityCustomizer customizer;
+
+ @Override
+ protected void setUpTest() throws Exception {
+ customizer = new Ikev2PolicyIdentityCustomizer(api);
+ when(api.ikev2ProfileSetId(any())).thenReturn(future(new Ikev2ProfileSetIdReply()));
+ }
+
+ @Test
+ public void testWriteLocalIpv4(
+ @InjectTestData(resourcePath = "/ikev2/identity/identity_local_ipv4.json", id = IDENTITY_PATH) Identity identity)
+ throws WriteFailedException {
+ customizer.writeCurrentAttributes(getId(), identity, writeContext);
+ Ikev2ProfileSetId request = new Ikev2ProfileSetId();
+ request.name = POLICY_NAME.getBytes();
+ request.idType = (byte) 1;
+ request.isLocal = BYTE_TRUE;
+ request.data = ipv4AddressNoZoneToArray(IPV4_TYPE_DATA);
+ verify(api).ikev2ProfileSetId(request);
+ }
+
+ @Test
+ public void testWriteRemoteFqdn(
+ @InjectTestData(resourcePath = "/ikev2/identity/identity_remote_fqdn.json", id = IDENTITY_PATH) Identity identity)
+ throws WriteFailedException {
+ customizer.writeCurrentAttributes(getId(), identity, writeContext);
+ Ikev2ProfileSetId request = new Ikev2ProfileSetId();
+ request.name = POLICY_NAME.getBytes();
+ request.idType = (byte) 2;
+ request.isLocal = BYTE_FALSE;
+ request.data = FQDN_TYPE_DATA.getBytes();
+ verify(api).ikev2ProfileSetId(request);
+ }
+
+ @Test
+ public void testWriteLocalIpv6(
+ @InjectTestData(resourcePath = "/ikev2/identity/identity_remote_ipv6.json", id = IDENTITY_PATH) Identity identity)
+ throws WriteFailedException {
+ customizer.writeCurrentAttributes(getId(), identity, writeContext);
+ Ikev2ProfileSetId request = new Ikev2ProfileSetId();
+ request.name = POLICY_NAME.getBytes();
+ request.idType = (byte) 5;
+ request.isLocal = BYTE_FALSE;
+ request.data = ipv6AddressNoZoneToArray(new Ipv6Address(IPV6_TYPE_DATA));
+ verify(api).ikev2ProfileSetId(request);
+ }
+
+ @Test
+ public void testUpdate(
+ @InjectTestData(resourcePath = "/ikev2/identity/identity_local_ipv4.json", id = IDENTITY_PATH) Identity before,
+ @InjectTestData(resourcePath = "/ikev2/identity/identity_local_rfc822.json", id = IDENTITY_PATH) Identity after)
+ throws WriteFailedException {
+ customizer.updateCurrentAttributes(getId(), before, after, writeContext);
+ Ikev2ProfileSetId request = new Ikev2ProfileSetId();
+ request.name = POLICY_NAME.getBytes();
+ request.idType = (byte) 3;
+ request.isLocal = BYTE_TRUE;
+ request.data = RFC822_TYPE_DATA.getBytes();
+ verify(api).ikev2ProfileSetId(request);
+ }
+
+ private InstanceIdentifier<Identity> getId() {
+ return InstanceIdentifier.create(Ikev2.class).child(Policy.class, new PolicyKey(POLICY_NAME))
+ .child(Identity.class);
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizerTest.java
new file mode 100644
index 000000000..912f50f27
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSadEntryCustomizerTest.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
+import io.fd.hc2vpp.ipsec.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.test.tools.HoneycombTestRunner;
+import io.fd.honeycomb.test.tools.annotations.InjectTestData;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.IpsecSadAddDelEntry;
+import io.fd.vpp.jvpp.core.dto.IpsecSadAddDelEntryReply;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IkeEncryptionAlgorithmT;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IkeIntegrityAlgorithmT;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ipsec;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.IpsecTrafficDirection;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.KeyStringGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.Sad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.AhBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.AuthenticationAlgorithm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.EspBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.Authentication;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.AuthenticationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.Encryption;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.EncryptionBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.HmacMd596Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.HmacSha196Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes128CbcBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes192CbcBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.Aes256CbcBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.DesCbcBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sad.SadEntriesKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(HoneycombTestRunner.class)
+public class IpsecSadEntryCustomizerTest extends WriterCustomizerTest implements SchemaContextTestHelper,
+ ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static final String SAD_PATH = "/hc2vpp-ietf-ipsec:ipsec/hc2vpp-ietf-ipsec:sad";
+ private static final InstanceIdentifier<Sad> SAD_IID =
+ InstanceIdentifier.create(Ipsec.class).child(Sad.class);
+ private static final String INTEG_KEY = "0123456789012346";
+ private static final String CRYPTO_KEY = "9876543210987654";
+ private static final String TNL_SRC_ADDR = "192.168.1.1";
+ private static final String TNL_DST_ADDR = "192.168.1.2";
+ private static final int SPI_1002 = 1002;
+ private static final int SAD_ID = 10;
+
+ private IpsecSadEntryCustomizer customizer;
+ @Mock
+ private MultiNamingContext namingCntext;
+
+ @Override
+ protected void setUpTest() throws Exception {
+ customizer = new IpsecSadEntryCustomizer(api, namingCntext);
+ when(api.ipsecSadAddDelEntry(any())).thenReturn(future(new IpsecSadAddDelEntryReply()));
+ }
+
+ @Test
+ public void testWrite(@InjectTestData(resourcePath = "/sadEntries/addDelSadEntry.json", id = SAD_PATH) Sad sad)
+ throws WriteFailedException {
+ final SadEntries data = sad.getSadEntries().get(0);
+ final IpsecSadAddDelEntry request = new IpsecSadAddDelEntry();
+ request.isAdd = BYTE_TRUE;
+ request.spi = SPI_1002;
+ request.sadId = SAD_ID;
+ request.isTunnel = BYTE_TRUE;
+ request.isTunnelIpv6 = BYTE_FALSE;
+ request.integrityKey = INTEG_KEY.getBytes();
+ request.cryptoKey = CRYPTO_KEY.getBytes();
+ request.useAntiReplay = 0;
+ request.tunnelSrcAddress = ipv4AddressNoZoneToArray(TNL_SRC_ADDR);
+ request.tunnelDstAddress = ipv4AddressNoZoneToArray(TNL_DST_ADDR);
+
+ // ESP
+ request.protocol = BYTE_TRUE; //0 = AH, 1 = ESP
+ // - auth MD5-96
+ // - crypto Aes-Cbc-128
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacMd596,
+ IkeEncryptionAlgorithmT.EncrAesCbc128, request);
+ // - crypto Aes-Cbc-192
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacMd596,
+ IkeEncryptionAlgorithmT.EncrAesCbc192, request);
+ // - crypto Aes-Cbc-256
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacMd596,
+ IkeEncryptionAlgorithmT.EncrAesCbc256, request);
+ // - crypto DesCbc
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacMd596,
+ IkeEncryptionAlgorithmT.EncrDes, request);
+
+ // - auth SHA1-96
+ // - crypto Aes-Cbc-128
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacSha196,
+ IkeEncryptionAlgorithmT.EncrAesCbc128, request);
+ // - crypto Aes-Cbc-192
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacSha196,
+ IkeEncryptionAlgorithmT.EncrAesCbc192, request);
+ // - crypto Aes-Cbc-256
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacSha196,
+ IkeEncryptionAlgorithmT.EncrAesCbc256, request);
+ // - crypto DesCbc
+ testEspAuthEncrCombination(data, IkeIntegrityAlgorithmT.AuthHmacSha196,
+ IkeEncryptionAlgorithmT.EncrDes, request);
+
+ // AH
+ request.protocol = BYTE_FALSE;
+ request.cryptoAlgorithm = 0;
+ request.cryptoKey = null;
+ request.cryptoKeyLength = 0;
+ // - auth SHA1-96
+ testAhAuthorization(data, IkeIntegrityAlgorithmT.AuthHmacSha196, request);
+ // - auth MD5-96
+ testAhAuthorization(data, IkeIntegrityAlgorithmT.AuthHmacMd596, request);
+ }
+
+ @Test
+ public void testUpdate(
+ @InjectTestData(resourcePath = "/sadEntries/addDelSadEntry_Ipv6_before.json", id = SAD_PATH) Sad relaysBefore,
+ @InjectTestData(resourcePath = "/sadEntries/addDelSadEntry_Ipv6_after.json", id = SAD_PATH) Sad relayAfter)
+ throws WriteFailedException {
+ final SadEntries before = relaysBefore.getSadEntries().get(0);
+ final SadEntries after = relayAfter.getSadEntries().get(0);
+ final Long spi = after.getSpi();
+ customizer.updateCurrentAttributes(getId(IpsecTrafficDirection.Outbound, spi), before, after, writeContext);
+ final IpsecSadAddDelEntry request = new IpsecSadAddDelEntry();
+ request.isAdd = BYTE_TRUE;
+ request.spi = SPI_1002;
+ request.sadId = SAD_ID;
+ request.protocol = BYTE_FALSE;
+ request.isTunnel = BYTE_FALSE;
+ request.isTunnelIpv6 = BYTE_TRUE;
+ request.integrityAlgorithm = 1;
+ request.integrityKey = INTEG_KEY.getBytes();
+ request.useAntiReplay = BYTE_TRUE;
+ request.tunnelSrcAddress = ipv6AddressNoZoneToArray(Ipv6Address.getDefaultInstance("2001::11"));
+ request.tunnelDstAddress = ipv6AddressNoZoneToArray(Ipv6Address.getDefaultInstance("2001::12"));
+ verify(api).ipsecSadAddDelEntry(request);
+ }
+
+ @Test
+ public void testDelete(@InjectTestData(resourcePath = "/sadEntries/delSadEntry.json", id = SAD_PATH) Sad sad)
+ throws WriteFailedException {
+ final SadEntries data = sad.getSadEntries().get(0);
+ final Long spi = data.getSpi();
+ customizer.deleteCurrentAttributes(getId(IpsecTrafficDirection.Outbound, spi), data, writeContext);
+ final IpsecSadAddDelEntry request = new IpsecSadAddDelEntry();
+ request.isAdd = BYTE_FALSE;
+ request.spi = SPI_1002;
+ request.sadId = SAD_ID;
+ verify(api).ipsecSadAddDelEntry(request);
+ }
+
+ private InstanceIdentifier<SadEntries> getId(final IpsecTrafficDirection direction, final Long spi) {
+ return SAD_IID.child(SadEntries.class, new SadEntriesKey(direction, spi));
+ }
+
+ private void testAhAuthorization(final SadEntries otherData, final IkeIntegrityAlgorithmT authAlg,
+ final IpsecSadAddDelEntry request) throws WriteFailedException {
+ SadEntriesBuilder builder = new SadEntriesBuilder(otherData);
+ builder.setEsp(null);
+ AhBuilder ahBuilder = new AhBuilder();
+ ahBuilder.setAuthenticationAlgorithm(getAhAuthentication(authAlg));
+ builder.setAh(ahBuilder.build());
+ customizer.writeCurrentAttributes(getId(IpsecTrafficDirection.Outbound, Integer.toUnsignedLong(SPI_1002)),
+ builder.build(), writeContext);
+ verify(api).ipsecSadAddDelEntry(request);
+ }
+
+ private void testEspAuthEncrCombination(final SadEntries otherData, final IkeIntegrityAlgorithmT authAlg,
+ final IkeEncryptionAlgorithmT encrAlg, final IpsecSadAddDelEntry request)
+ throws WriteFailedException {
+ SadEntriesBuilder builder = new SadEntriesBuilder(otherData);
+ builder.setAh(null);
+ EspBuilder espBuilder = new EspBuilder();
+ espBuilder.setAuthentication(getEspAuthentication(authAlg))
+ .setEncryption(getEspEncryption(encrAlg));
+ builder.setEsp(espBuilder.build());
+ customizer.writeCurrentAttributes(getId(IpsecTrafficDirection.Outbound, Integer.toUnsignedLong(SPI_1002)),
+ builder.build(), writeContext);
+
+ if (encrAlg == IkeEncryptionAlgorithmT.EncrAesCbc128) {
+ request.cryptoAlgorithm = 1;
+ } else if (encrAlg == IkeEncryptionAlgorithmT.EncrAesCbc192) {
+ request.cryptoAlgorithm = 2;
+ } else if (encrAlg == IkeEncryptionAlgorithmT.EncrAesCbc256) {
+ request.cryptoAlgorithm = 3;
+ } else if (encrAlg == IkeEncryptionAlgorithmT.EncrDes) {
+ request.cryptoAlgorithm = 4;
+ } else {
+ request.cryptoAlgorithm = 0;
+ }
+
+ if (authAlg == IkeIntegrityAlgorithmT.AuthHmacMd596) {
+ request.integrityAlgorithm = 1;
+ } else if (authAlg == IkeIntegrityAlgorithmT.AuthHmacSha196) {
+ request.integrityAlgorithm = 2;
+ } else {
+ request.integrityAlgorithm = 0;
+ }
+
+ verify(api).ipsecSadAddDelEntry(request);
+ }
+
+ private Encryption getEspEncryption(IkeEncryptionAlgorithmT alg) {
+ if (alg == IkeEncryptionAlgorithmT.EncrAesCbc128) {
+ return new EncryptionBuilder().setEncryptionAlgorithm(new Aes128CbcBuilder().
+ setAes128Cbc(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._128.cbc.Aes128CbcBuilder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(CRYPTO_KEY))
+ .build()).build()).build();
+ } else if (alg == IkeEncryptionAlgorithmT.EncrAesCbc192) {
+ return new EncryptionBuilder().setEncryptionAlgorithm(new Aes192CbcBuilder().
+ setAes192Cbc(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._192.cbc.Aes192CbcBuilder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(CRYPTO_KEY))
+ .build()).build()).build();
+ } else if (alg == IkeEncryptionAlgorithmT.EncrAesCbc256) {
+ return new EncryptionBuilder().setEncryptionAlgorithm(new Aes256CbcBuilder().
+ setAes256Cbc(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.aes._256.cbc.Aes256CbcBuilder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(CRYPTO_KEY))
+ .build()).build()).build();
+ } else if (alg == IkeEncryptionAlgorithmT.EncrDes) {
+ return new EncryptionBuilder().setEncryptionAlgorithm(new DesCbcBuilder().setDesCbc(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.encryption.encryption.algorithm.des.cbc.DesCbcBuilder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(CRYPTO_KEY))
+ .build()).build()).build();
+ }
+
+ return null;
+ }
+
+ private Authentication getEspAuthentication(IkeIntegrityAlgorithmT alg) {
+ if (alg == IkeIntegrityAlgorithmT.AuthHmacSha196) {
+ return new AuthenticationBuilder().setAuthenticationAlgorithm(new HmacSha196Builder().setHmacSha196(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.hmac.sha1._96.HmacSha196Builder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(INTEG_KEY)).build()).build()).build();
+ } else if (alg == IkeIntegrityAlgorithmT.AuthHmacMd596) {
+ return new AuthenticationBuilder().setAuthenticationAlgorithm(new HmacMd596Builder().setHmacMd596(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.esp.grouping.esp.authentication.authentication.algorithm.hmac.md5._96.HmacMd596Builder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(INTEG_KEY)).build()).build()).build();
+ }
+ return null;
+ }
+
+ private AuthenticationAlgorithm getAhAuthentication(IkeIntegrityAlgorithmT alg) {
+ if (alg == IkeIntegrityAlgorithmT.AuthHmacSha196) {
+ return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacSha196Builder()
+ .setHmacSha196(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.hmac.sha1._96.HmacSha196Builder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(INTEG_KEY)).build()).build();
+ } else if (alg == IkeIntegrityAlgorithmT.AuthHmacMd596) {
+ return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.HmacMd596Builder()
+ .setHmacMd596(
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.sa.ah.grouping.ah.authentication.algorithm.hmac.md5._96.HmacMd596Builder()
+ .setKeyStr(new KeyStringGrouping.KeyStr(INTEG_KEY)).build()).build();
+ }
+ return null;
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizerTest.java b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizerTest.java
new file mode 100644
index 000000000..a4b294002
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/java/io/fd/hc2vpp/ipsec/write/IpsecSpdCustomizerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.
+ */
+
+package io.fd.hc2vpp.ipsec.write;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.ipsec.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.test.tools.HoneycombTestRunner;
+import io.fd.honeycomb.test.tools.annotations.InjectTestData;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDel;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDelEntry;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDelEntryReply;
+import io.fd.vpp.jvpp.core.dto.IpsecSpdAddDelReply;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.ipsec.rev181213.IpsecSpdEntriesAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.Ipsec;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.Spd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.SpdBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.SpdKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.spd.SpdEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipsec.rev181214.ipsec.spd.SpdEntriesBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(HoneycombTestRunner.class)
+public class IpsecSpdCustomizerTest extends WriterCustomizerTest implements SchemaContextTestHelper,
+ ByteDataTranslator, Ipv4Translator, Ipv6Translator {
+
+ private static final int SPD_ID = 10;
+ private static final String IPSEC_PATH = "/hc2vpp-ietf-ipsec:ipsec";
+ private IpsecSpdCustomizer customizer;
+
+ @Override
+ protected void setUpTest() throws Exception {
+ customizer = new IpsecSpdCustomizer(api);
+ when(api.ipsecSpdAddDel(any())).thenReturn(future(new IpsecSpdAddDelReply()));
+ when(api.ipsecSpdAddDelEntry(any())).thenReturn(future(new IpsecSpdAddDelEntryReply()));
+ }
+
+ @Test
+ public void testWrite(@InjectTestData(resourcePath = "/spdEntries/addDelSpd.json", id = IPSEC_PATH) Ipsec ipsec)
+ throws WriteFailedException {
+ Spd spd = ipsec.getSpd().get(0);
+ customizer.writeCurrentAttributes(getSpdId(SPD_ID), spd, writeContext);
+ final IpsecSpdAddDel createSpdRequest = new IpsecSpdAddDel();
+ createSpdRequest.isAdd = BYTE_TRUE;
+ createSpdRequest.spdId = SPD_ID;
+
+ verify(api).ipsecSpdAddDel(createSpdRequest);
+ verify(api).ipsecSpdAddDelEntry(translateSpdEntry(spd.getSpdEntries().get(0), SPD_ID, true));
+ verify(api).ipsecSpdAddDelEntry(translateSpdEntry(spd.getSpdEntries().get(1), SPD_ID, true));
+ }
+
+ @Test
+ public void testUpdate(
+ @InjectTestData(resourcePath = "/spdEntries/addDelSpd_before.json", id = IPSEC_PATH) Ipsec ipsecBefore,
+ @InjectTestData(resourcePath = "/spdEntries/addDelSpd_after.json", id = IPSEC_PATH) Ipsec ipsecAfter)
+ throws WriteFailedException {
+ Spd before = ipsecBefore.getSpd().get(0);
+ Spd after = ipsecAfter.getSpd().get(0);
+ customizer.updateCurrentAttributes(getSpdId(SPD_ID), before, after, writeContext);
+ verify(api).ipsecSpdAddDelEntry(translateSpdEntry(after.getSpdEntries().get(0), SPD_ID, true));
+ }
+
+ @Test
+ public void testDelete()
+ throws WriteFailedException {
+ SpdBuilder spdBuilder = new SpdBuilder();
+ spdBuilder.setSpdId(SPD_ID)
+ .withKey(new SpdKey(SPD_ID))
+ .setSpdEntries(Collections.singletonList(new SpdEntriesBuilder().build()));
+ customizer.deleteCurrentAttributes(getSpdId(SPD_ID), spdBuilder.build(), writeContext);
+ IpsecSpdAddDel request = new IpsecSpdAddDel();
+ request.spdId = SPD_ID;
+ request.isAdd = BYTE_FALSE;
+ verify(api).ipsecSpdAddDel(request);
+ }
+
+ private InstanceIdentifier<Spd> getSpdId(final int spdId) {
+ return InstanceIdentifier.create(Ipsec.class).child(Spd.class, new SpdKey(spdId));
+ }
+
+ private IpsecSpdAddDelEntry translateSpdEntry(final SpdEntries entry, int spdId, boolean isAdd) {
+ IpsecSpdAddDelEntry request = new IpsecSpdAddDelEntry();
+ request.spdId = spdId;
+ request.isAdd = isAdd
+ ? BYTE_TRUE
+ : BYTE_FALSE;
+ IpsecSpdEntriesAugmentation aug = entry.augmentation(IpsecSpdEntriesAugmentation.class);
+ if (aug != null) {
+ if (aug.isIsIpv6() != null) {
+ request.isIpv6 = (byte) (aug.isIsIpv6()
+ ? 1
+ : 0);
+ }
+
+ if (aug.getDirection() != null) {
+ request.isOutbound = (byte) aug.getDirection().getIntValue();
+ }
+
+ if (aug.getPriority() != null) {
+ request.priority = aug.getPriority();
+ }
+
+ if (aug.getOperation() != null) {
+ final String operation = aug.getOperation().getName();
+ if (operation.equalsIgnoreCase("bypass")) {
+ request.policy = (byte) 0;
+ } else if (operation.equalsIgnoreCase("discard")) {
+ request.policy = (byte) 1;
+ } else if (operation.equalsIgnoreCase("protect")) {
+ request.policy = (byte) 3;
+ }
+ }
+
+ if (aug.getLaddrStart() != null) {
+ if (aug.getLaddrStart().getIpv4Address() != null) {
+ request.localAddressStart =
+ ipv4AddressNoZoneToArray(aug.getLaddrStart().getIpv4Address().getValue());
+ } else if (aug.getLaddrStart().getIpv6Address() != null) {
+ request.localAddressStart = ipv6AddressNoZoneToArray(aug.getLaddrStart().getIpv6Address());
+ }
+ }
+
+ if (aug.getLaddrStop() != null) {
+ if (aug.getLaddrStop().getIpv4Address() != null) {
+ request.localAddressStop = ipv4AddressNoZoneToArray(aug.getLaddrStop().getIpv4Address().getValue());
+ } else if (aug.getLaddrStop().getIpv6Address() != null) {
+ request.localAddressStop = ipv6AddressNoZoneToArray(aug.getLaddrStop().getIpv6Address());
+ }
+ }
+
+ if (aug.getRaddrStop() != null) {
+ if (aug.getRaddrStop().getIpv4Address() != null) {
+ request.remoteAddressStop =
+ ipv4AddressNoZoneToArray(aug.getRaddrStop().getIpv4Address().getValue());
+ } else if (aug.getRaddrStop().getIpv6Address() != null) {
+ request.remoteAddressStop = ipv6AddressNoZoneToArray(aug.getRaddrStop().getIpv6Address());
+ }
+ }
+
+ if (aug.getRaddrStart() != null) {
+ if (aug.getRaddrStart().getIpv4Address() != null) {
+ request.remoteAddressStart =
+ ipv4AddressNoZoneToArray(aug.getRaddrStart().getIpv4Address().getValue());
+ } else if (aug.getRaddrStart().getIpv6Address() != null) {
+ request.remoteAddressStart = ipv6AddressNoZoneToArray(aug.getRaddrStart().getIpv6Address());
+ }
+ }
+ }
+ return request;
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_after.json b/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_after.json
new file mode 100644
index 000000000..ac5f8c797
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_after.json
@@ -0,0 +1,25 @@
+{
+ "ikev2": {
+ "policy": [
+ {
+ "name": "testPolicy",
+ "lifetime": 0,
+ "connection-type": "both",
+ "authentication" : {
+ "rsa-signature" : "true"
+ },
+ "certificate": "/home/localadmin/certs/server-cert.pem",
+ "traffic-selectors": [
+ {
+ "ts-name":"TS1",
+ "protocol":0,
+ "remote-address-low":"192.168.124.0",
+ "remote-address-high":"192.168.124.255",
+ "remote-port-low":0,
+ "remote-port-high":65535
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_before.json b/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_before.json
new file mode 100644
index 000000000..3dfa39345
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/addDelProfile_before.json
@@ -0,0 +1,25 @@
+{
+ "ikev2": {
+ "policy": [
+ {
+ "name": "testPolicy",
+ "lifetime": 0,
+ "connection-type": "both",
+ "authentication" : {
+ "preshared-key" : "true"
+ },
+ "pre-shared-key": "0123456789012345",
+ "traffic-selectors": [
+ {
+ "ts-name":"TS1",
+ "protocol":0,
+ "local-address-low":"192.168.124.0",
+ "local-address-high":"192.168.124.255",
+ "local-port-low":0,
+ "local-port-high":65535
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/addIkev2Profile.json b/ipsec/ipsec-impl/src/test/resources/ikev2/addIkev2Profile.json
new file mode 100644
index 000000000..3dfa39345
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/addIkev2Profile.json
@@ -0,0 +1,25 @@
+{
+ "ikev2": {
+ "policy": [
+ {
+ "name": "testPolicy",
+ "lifetime": 0,
+ "connection-type": "both",
+ "authentication" : {
+ "preshared-key" : "true"
+ },
+ "pre-shared-key": "0123456789012345",
+ "traffic-selectors": [
+ {
+ "ts-name":"TS1",
+ "protocol":0,
+ "local-address-low":"192.168.124.0",
+ "local-address-high":"192.168.124.255",
+ "local-port-low":0,
+ "local-port-high":65535
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_ipv4.json b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_ipv4.json
new file mode 100644
index 000000000..f068bd78b
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_ipv4.json
@@ -0,0 +1,8 @@
+{
+ "identity" : {
+ "local":
+ {
+ "ipv4-address": "192.168.123.22"
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_rfc822.json b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_rfc822.json
new file mode 100644
index 000000000..6e152d9c4
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_local_rfc822.json
@@ -0,0 +1,8 @@
+{
+ "identity" : {
+ "local":
+ {
+ "rfc822-address-string": "rfc822@example.com"
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_fqdn.json b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_fqdn.json
new file mode 100644
index 000000000..514f84116
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_fqdn.json
@@ -0,0 +1,8 @@
+{
+ "identity" : {
+ "remote":
+ {
+ "fqdn-string": "vpp.home"
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_ipv6.json b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_ipv6.json
new file mode 100644
index 000000000..0674d357f
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/ikev2/identity/identity_remote_ipv6.json
@@ -0,0 +1,8 @@
+{
+ "identity" : {
+ "remote":
+ {
+ "ipv6-address": "2001:DB8:0:0:8:800:200C:417A"
+ }
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry.json b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry.json
new file mode 100644
index 000000000..c522ba2de
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry.json
@@ -0,0 +1,32 @@
+{
+ "sad": {
+ "sad-entries": [
+ {
+ "spi": 1002,
+ "direction": "outbound",
+ "sa-id": 10,
+ "security-protocol": "esp",
+ "sa-mode": "tunnel",
+ "esp": {
+ "authentication": {
+ "hmac-sha1-96": {
+ "key-str": "0123456789012346"
+ }
+ },
+ "encryption": {
+ "aes-128-cbc": {
+ "key-str": "9876543210987654"
+ }
+ }
+ },
+ "source-address": {
+ "ipv4-address": "192.168.1.1"
+ },
+ "destination-address": {
+ "ipv4-address": "192.168.1.2"
+ },
+ "anti-replay-window": 0
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_after.json b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_after.json
new file mode 100644
index 000000000..fa618a391
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_after.json
@@ -0,0 +1,25 @@
+{
+ "sad": {
+ "sad-entries": [
+ {
+ "spi": 1002,
+ "direction": "inbound",
+ "sa-id": 10,
+ "security-protocol": "ah",
+ "sa-mode": "transport",
+ "ah": {
+ "hmac-md5-96": {
+ "key-str": "0123456789012346"
+ }
+ },
+ "source-address": {
+ "ipv6-address": "2001::11"
+ },
+ "destination-address": {
+ "ipv6-address": "2001::12"
+ },
+ "anti-replay-window": 32
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_before.json b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_before.json
new file mode 100644
index 000000000..a88a14600
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/sadEntries/addDelSadEntry_Ipv6_before.json
@@ -0,0 +1,32 @@
+{
+ "sad": {
+ "sad-entries": [
+ {
+ "spi": 1002,
+ "direction": "outbound",
+ "sa-id": 10,
+ "security-protocol": "esp",
+ "sa-mode": "tunnel",
+ "esp": {
+ "authentication": {
+ "hmac-sha1-96": {
+ "key-str": "0123456789012346"
+ }
+ },
+ "encryption": {
+ "aes-128-cbc": {
+ "key-str": "9876543210987654"
+ }
+ }
+ },
+ "source-address": {
+ "ipv6-address": "2001::1"
+ },
+ "destination-address": {
+ "ipv6-address": "2001::10"
+ },
+ "anti-replay-window": 32
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/sadEntries/delSadEntry.json b/ipsec/ipsec-impl/src/test/resources/sadEntries/delSadEntry.json
new file mode 100644
index 000000000..23998d60f
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/sadEntries/delSadEntry.json
@@ -0,0 +1,11 @@
+{
+ "sad": {
+ "sad-entries": [
+ {
+ "spi": 1002,
+ "direction": "outbound",
+ "sa-id": 10
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd.json b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd.json
new file mode 100644
index 000000000..85fe81d0d
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd.json
@@ -0,0 +1,31 @@
+{
+ "ipsec" : {
+ "spd": [
+ {
+ "spd-id": 10,
+ "spd-entries": [
+ {
+ "name": "test",
+ "priority":100,
+ "direction":"outbound",
+ "operation":"bypass",
+ "laddr-start":"192.168.124.0",
+ "laddr-stop":"192.168.124.255",
+ "raddr-start":"192.168.125.0",
+ "raddr-stop":"192.168.125.255"
+ },
+ {
+ "name": "TestSPDEntryIpv6",
+ "priority":100,
+ "direction":"inbound",
+ "operation":"bypass",
+ "laddr-start":"2001::1",
+ "laddr-stop":"2001::100",
+ "raddr-start":"2001::101",
+ "raddr-stop":"2001::200"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_after.json b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_after.json
new file mode 100644
index 000000000..600dde46a
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_after.json
@@ -0,0 +1,21 @@
+{
+ "ipsec" : {
+ "spd": [
+ {
+ "spd-entries": [
+ {
+ "name": "TestSPDEntryUpdate",
+ "priority":80,
+ "direction":"inbound",
+ "operation":"bypass",
+ "laddr-start":"2001::1",
+ "laddr-stop":"2001::100",
+ "raddr-start":"2001::101",
+ "raddr-stop":"2001::200"
+ }
+ ],
+ "spd-id": 10
+ }
+ ]
+ }
+}
diff --git a/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_before.json b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_before.json
new file mode 100644
index 000000000..be14bd6f9
--- /dev/null
+++ b/ipsec/ipsec-impl/src/test/resources/spdEntries/addDelSpd_before.json
@@ -0,0 +1,21 @@
+{
+ "ipsec" : {
+ "spd": [
+ {
+ "spd-entries": [
+ {
+ "name": "TestSPDEntryUpdate",
+ "priority":100,
+ "direction":"outbound",
+ "operation":"discard",
+ "laddr-start":"192.168.124.0",
+ "laddr-stop":"192.168.124.255",
+ "raddr-start":"192.168.125.0",
+ "raddr-stop":"192.168.125.255"
+ }
+ ],
+ "spd-id": 10
+ }
+ ]
+ }
+}
diff --git a/ipsec/pom.xml b/ipsec/pom.xml
new file mode 100644
index 000000000..471ade96e
--- /dev/null
+++ b/ipsec/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2019 PANTHEON.tech.
+
+ 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.
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>hc2vpp-parent</artifactId>
+ <version>1.19.01-SNAPSHOT</version>
+ <relativePath>../common/hc2vpp-parent</relativePath>
+ </parent>
+
+ <groupId>io.fd.hc2vpp.ipsec</groupId>
+ <artifactId>ipsec-aggregator</artifactId>
+ <version>1.19.01-SNAPSHOT</version>
+ <name>${project.artifactId}</name>
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.1.1</maven>
+ </prerequisites>
+ <description>Aggregator for Hc2vpp IPSec plugin</description>
+
+ <modules>
+ <module>ipsec-api</module>
+ <module>ipsec-impl</module>
+ </modules>
+
+ <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/pom.xml b/pom.xml
index 9b6714df1..565c50b71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,5 +57,6 @@
<module>bgp</module>
<module>mpls</module>
<module>srv6</module>
+ <module>ipsec</module>
</modules>
</project>
diff --git a/vpp-integration/minimal-distribution/pom.xml b/vpp-integration/minimal-distribution/pom.xml
index 286bfda47..ef3e37e99 100644
--- a/vpp-integration/minimal-distribution/pom.xml
+++ b/vpp-integration/minimal-distribution/pom.xml
@@ -67,6 +67,7 @@
io.fd.hc2vpp.policer.PolicerModule,
io.fd.hc2vpp.mpls.MplsModule,
io.fd.hc2vpp.srv6.Srv6Module,
+ io.fd.hc2vpp.ipsec.IpsecModule
<!-- Nsh module by default disabled, because it needs vpp-nsh plugin, which is not part of vpp codebase.-->
// io.fd.hc2vpp.vppnsh.impl.VppNshModule,
<!-- iOAM module by default disabled, because it needs ioam plugin (not part of vpp codebase.)-->
@@ -191,5 +192,10 @@
<artifactId>bgp-prefix-sid</artifactId>
<version>${hc2vpp.bgp.version}</version>
</dependency>
+ <dependency>
+ <groupId>io.fd.hc2vpp.ipsec</groupId>
+ <artifactId>ipsec-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>