diff options
author | Tibor Král <tibor.kral@pantheon.tech> | 2018-11-14 18:20:02 +0100 |
---|---|---|
committer | Tibor Král <tibor.kral@pantheon.tech> | 2019-01-16 10:07:28 +0100 |
commit | 26589d440f332fe52238fa258d7d7b58df43eee5 (patch) | |
tree | dd3eaa8cf5cc3bd9fcfbff1239227c784ce935e7 /ipsec/ipsec-impl/src/main | |
parent | 8ad4f38beb1350d1cd62d11a9a15ac78ee0623f9 (diff) |
HC2VPP-87: Expose IPSEC management
Change-Id: Ib13a2cdba5a0902581c455de67cc0ee64d20598d
Signed-off-by: Tibor Král <tibor.kral@pantheon.tech>
Diffstat (limited to 'ipsec/ipsec-impl/src/main')
10 files changed, 1320 insertions, 0 deletions
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))); + } +} |