From af188c5c99d4b4fcb669a6e666b2b421ad69e8d9 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Tue, 3 Jan 2017 18:12:41 +0100 Subject: HONEYCOMB-310: readers&initializers for vpp and macip acls Change-Id: I8892479123091e43bf191c544b6628d6254be564 Signed-off-by: Marek Gradzki --- .../io/fd/hc2vpp/acl/util/AclContextManager.java | 84 +++++++++++ .../fd/hc2vpp/acl/util/AclContextManagerImpl.java | 166 +++++++++++++++++++++ .../io/fd/hc2vpp/acl/util/ace/AceConverter.java | 68 ++++++++- .../util/ace/extractor/MacIpAceDataExtractor.java | 41 ++++- .../ace/extractor/StandardAceDataExtractor.java | 62 +++++++- .../java/io/fd/hc2vpp/acl/util/acl/AclWriter.java | 45 +++--- .../io/fd/hc2vpp/acl/util/factory/AclFactory.java | 68 +++++++++ .../iface/acl/AclInterfaceAssignmentRequest.java | 7 +- .../macip/MacIpInterfaceAssignmentRequest.java | 7 +- .../hc2vpp/acl/util/protocol/IpProtocolReader.java | 140 +++++++++++++++++ 10 files changed, 655 insertions(+), 33 deletions(-) create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java (limited to 'acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util') diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java new file mode 100644 index 000000000..377d4e1dc --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.acl.util; + +import io.fd.honeycomb.translate.MappingContext; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; + +/** + * Manages metadata for acl plugin + */ +public interface AclContextManager { + + /** + * Creates metadata for ACL. Existing mapping is overwritten if exists. + * @param id ACL index + * @param name ACL name + * @param aces list of aces used to create rule-name to index mapping + * @param ctx mapping context providing context data for current transaction + */ + void addAcl(final int id, @Nonnull final String name, @Nonnull final List aces, @Nonnull final MappingContext ctx); + + /** + * Check whether metadata for given ACL is present. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + boolean containsAcl(@Nonnull String name, @Nonnull final MappingContext ctx); + + /** + * Returns ACL index associated with the given name. + * + * @param name ACL name + * @param ctx mapping context providing context data for current transaction + * @return integer index value matching supplied ACL name + * @throws IllegalArgumentException if ACL was not found + */ + int getAclIndex(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Retrieves ACL name for given id. If not present, artificial name will be generated. + * + * @param id ACL index + * @param ctx mapping context providing context data for current transaction + * @return ACL name matching supplied index + */ + String getAclName(final int id, @Nonnull final MappingContext ctx); + + /** + * Removes ACL metadata from current context. + * + * @param name ACL name + * @param ctx mapping context providing context data for current transaction + */ + void removeAcl(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Retrieves ACE name associated with the given ACL and ACE index. If not present, artificial name will be + * generated. + * + * @param aclName ACL name + * @param aceIndex ACE index + * @param ctx mapping context providing context data for current transaction + * @return name of vpp node + */ + String getAceName(final String aclName, final int aceIndex, @Nonnull final MappingContext ctx); +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java new file mode 100644 index 000000000..aa25c3eb1 --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.acl.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.VppAclContextAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.VppAclMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.VppAclContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.VppAclContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMappingKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Facade on top of {@link MappingContext} that manages {@link VppAclContext}. + */ +@ThreadSafe +public final class AclContextManagerImpl implements AclContextManager { + + private static final Collector SINGLE_ITEM_ACL_COLLECTOR = + RWUtils.singleItemCollector(); + + private static final Collector SINGLE_ITEM_ACE_COLLECTOR = + RWUtils.singleItemCollector(); + + private final InstanceIdentifier ctxIid; + + private final String artificialNamePrefix; + + public AclContextManagerImpl(@Nonnull final String artificialNamePrefix, @Nonnull final String aclContextName) { + this.artificialNamePrefix = requireNonNull(artificialNamePrefix, "artificialNamePrefix should not be null"); + requireNonNull(aclContextName, "aclContextName should not be null"); + this.ctxIid = InstanceIdentifier.create(Contexts.class) + .augmentation(VppAclContextAugmentation.class).child(VppAclMappings.class) + .child(VppAclContext.class, new VppAclContextKey(aclContextName)); + } + + @Override + public synchronized void addAcl(final int id, @Nonnull final String name, @Nonnull final List aces, + @Nonnull final MappingContext ctx) { + final KeyedInstanceIdentifier mappingIid = getAclIid(name); + final AclMappingBuilder aclMapping = new AclMappingBuilder().setIndex(id).setName(name); + + final List mappings = new ArrayList<>(aces.size()); + int aceIndex = 0; + for (final Ace ace : aces) { + mappings.add(new AceMappingBuilder().setName(ace.getRuleName()).setIndex(aceIndex++).build()); + } + aclMapping.setAceMapping(mappings); + ctx.put(mappingIid, aclMapping.build()); + } + + @Override + public synchronized boolean containsAcl(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getAclIid(name)); + return read.isPresent(); + } + + @Override + public synchronized int getAclIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getAclIid(name)); + checkArgument(read.isPresent(), "No mapping stored for name: %s", name); + return read.get().getIndex(); + } + + @Override + public synchronized String getAclName(final int id, @Nonnull final MappingContext ctx) { + if (!containsAclName(id, ctx)) { + final String artificialName = getArtificialAclName(id); + addAcl(id, artificialName, Collections.emptyList(), ctx); + } + + final Optional read = ctx.read(ctxIid); + checkState(read.isPresent(), "VppAclContext for index: %s is not present. But should be", id); + + return read.get().getAclMapping().stream() + .filter(t -> t.getIndex().equals(id)) + .collect(SINGLE_ITEM_ACL_COLLECTOR).getName(); + } + + private boolean containsAclName(final int id, @Nonnull final MappingContext mappingContext) { + final Optional read = mappingContext.read(ctxIid); + return read.isPresent() && read.get().getAclMapping().stream().anyMatch(t -> t.getIndex().equals(id)); + } + + private String getArtificialAclName(final int index) { + return artificialNamePrefix + index; + } + + @Override + public synchronized void removeAcl(@Nonnull final String name, @Nonnull final MappingContext ctx) { + ctx.delete(getAclIid(name)); + } + + @Override + public synchronized String getAceName(@Nonnull final String aclName, final int aceIndex, + @Nonnull final MappingContext ctx) { + if (!containsAceName(aclName, aceIndex, ctx)) { + final String artificialName = getArtificialAceName(aceIndex); + addAce(aclName, aceIndex, artificialName, ctx); + } + + final Optional read = ctx.read(getAclIid(aclName)); + checkState(read.isPresent(), "AclMapping for name: %s is not present. But should be", aclName); + + return read.get().getAceMapping().stream() + .filter(t -> t.getIndex().equals(aceIndex)) + .collect(SINGLE_ITEM_ACE_COLLECTOR).getName(); + } + + private boolean containsAceName(@Nonnull final String aclName, final int id, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getAclIid(aclName)); + return read.isPresent() && read.get().getAceMapping().stream().anyMatch(t -> t.getIndex().equals(id)); + } + + private String getArtificialAceName(final int index) { + return artificialNamePrefix + "rule" + index; + } + + private KeyedInstanceIdentifier getAclIid(@Nonnull final String name) { + return ctxIid.child(AclMapping.class, new AclMappingKey(name)); + } + + private void addAce(@Nonnull final String aclName, final int aceIndex, @Nonnull final String aceName, + @Nonnull final MappingContext ctx) { + final AceMappingBuilder aceMapping = new AceMappingBuilder(); + aceMapping.setIndex(aceIndex); + aceMapping.setName(aceName); + final KeyedInstanceIdentifier iid = + getAclIid(aclName).child(AceMapping.class, new AceMappingKey(aceName)); + ctx.put(iid, aceMapping.build()); + } +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java index 325787821..3053fe96f 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java @@ -16,25 +16,34 @@ package io.fd.hc2vpp.acl.util.ace; +import io.fd.hc2vpp.acl.util.AclContextManager; import io.fd.hc2vpp.acl.util.ace.extractor.MacIpAceDataExtractor; import io.fd.hc2vpp.acl.util.ace.extractor.StandardAceDataExtractor; import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer; +import io.fd.honeycomb.translate.MappingContext; import io.fd.vpp.jvpp.acl.types.AclRule; import io.fd.vpp.jvpp.acl.types.MacipAclRule; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodesBuilder; /** - * Convert Ace's to vpp rules + * Convert between Ace's and vpp rules. */ public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtractor, ProtoPreBindRuleProducer { - - default MacipAclRule[] convertToMacIpAclRules(@Nonnull final List aces) { + default MacipAclRule[] toMacIpAclRules(@Nonnull final List aces) { return aces.stream() .map(ace -> { final VppMacipAce macIpAce = fromMacIpAce(ace); @@ -61,7 +70,7 @@ public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtr .toArray(new MacipAclRule[aces.size()]); } - default AclRule[] convertToStandardAclRules(@Nonnull final List aces) { + default AclRule[] toStandardAclRules(@Nonnull final List aces) { return aces.stream() .map(ace -> { final VppAce standardAce = fromStandardAce(ace); @@ -85,10 +94,59 @@ public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtr rule.dstIpPrefixLen = ipv4DestinationAddressPrefix(standardAce); } - return rule; }) .collect(Collectors.toList()) .toArray(new AclRule[aces.size()]); } + + default List toMacIpAces(final String aclName, @Nonnull MacipAclRule[] rules, + @Nonnull final AclContextManager macipAclContext, + @Nonnull final MappingContext mappingContext) { + final List aces = new ArrayList<>(rules.length); + int i = 0; + for (final MacipAclRule rule : rules) { + final AceBuilder ace = new AceBuilder(); + final VppMacipAceBuilder aceType = new VppMacipAceBuilder(); + final VppMacipAceNodesBuilder nodes = new VppMacipAceNodesBuilder(); + nodes.setAceIpVersion(ipVersion(rule)); + nodes.setSourceMacAddress(sourceMac(rule)); + nodes.setSourceMacAddressMask(sourceMacMask(rule)); + aceType.setVppMacipAceNodes(nodes.build()); + + ace.setMatches(new MatchesBuilder().setAceType(aceType.build()).build()); + ace.setActions(actions(rule.isPermit)); + + final String aceName = macipAclContext.getAceName(aclName, i++, mappingContext); + ace.setRuleName(aceName); + ace.setKey(new AceKey(aceName)); + + aces.add(ace.build()); + } + return aces; + } + + default List toStandardAces(final String aclName, @Nonnull AclRule[] rules, + @Nonnull final AclContextManager standardAclContext, + @Nonnull final MappingContext mappingContext) { + final List aces = new ArrayList<>(rules.length); + int i = 0; + for (final AclRule rule : rules) { + final AceBuilder ace = new AceBuilder(); + final VppAceBuilder aceType = new VppAceBuilder(); + final VppAceNodesBuilder nodes = new VppAceNodesBuilder(); + nodes.setAceIpVersion(ipVersion(rule)); + nodes.setIpProtocol(parseProtocol(rule)); + aceType.setVppAceNodes(nodes.build()); + + ace.setMatches(new MatchesBuilder().setAceType(aceType.build()).build()); + ace.setActions(actions(rule.isPermit)); + + final String aceName = standardAclContext.getAceName(aclName, i++, mappingContext); + ace.setRuleName(aceName); + ace.setKey(new AceKey(aceName)); + aces.add(ace.build()); + } + return aces; + } } diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java index a0d19902a..4a29949ec 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java @@ -17,17 +17,23 @@ package io.fd.hc2vpp.acl.util.ace.extractor; import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.vpp.jvpp.acl.types.MacipAclRule; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv4HeaderFields; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv6HeaderFields; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.AceIpVersion; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.ace.ip.version.AceIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.ace.ip.version.AceIpv6Builder; -public interface MacIpAceDataExtractor extends AddressTranslator { +public interface MacIpAceDataExtractor extends AddressTranslator, MacTranslator { default VppMacipAce fromMacIpAce(@Nonnull final Ace ace) { return VppMacipAce.class.cast(ace.getMatches().getAceType()); @@ -80,4 +86,37 @@ public interface MacIpAceDataExtractor extends AddressTranslator { } } + default AceIpVersion ipVersion(final MacipAclRule rule) { + if (rule.isIpv6 == 0) { + return ip4Ace(rule); + } else { + return ip6Ace(rule); + } + } + + default AceIpVersion ip4Ace(MacipAclRule rule) { + final AceIpv4Builder ipVersion = new AceIpv4Builder(); + if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) { + ipVersion.setSourceIpv4Network(toIpv4Prefix(truncateIp4Array(rule.srcIpAddr), rule.srcIpPrefixLen)); + } + return ipVersion.build(); + } + + default AceIpVersion ip6Ace(MacipAclRule rule) { + final AceIpv6Builder ipVersion = new AceIpv6Builder(); + if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) { + ipVersion.setSourceIpv6Network(toIpv6Prefix(rule.srcIpAddr, rule.srcIpPrefixLen)); + } + return ipVersion.build(); + } + + default MacAddress sourceMac(final MacipAclRule rule) { + return new MacAddress(byteArrayToMacSeparated(rule.srcMac)); + } + + default MacAddress sourceMacMask(final MacipAclRule rule) { + return new MacAddress(byteArrayToMacSeparated(rule.srcMacMask)); + } + + } diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java index 2e7ccbdc7..6d395fb01 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java @@ -16,25 +16,33 @@ package io.fd.hc2vpp.acl.util.ace.extractor; - import com.google.common.collect.ImmutableMap; +import io.fd.hc2vpp.acl.util.protocol.IpProtocolReader; import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer; import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.vpp.jvpp.acl.types.AclRule; import java.util.Map; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv6HeaderFields; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.actions.packet.handling.Stateful; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.actions.packet.handling.StatefulBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.AceIpVersion; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv4Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6Builder; - -public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBindRuleProducer { +public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBindRuleProducer, IpProtocolReader { /** * Allowed packet-processing actions for Acl's @@ -95,4 +103,52 @@ public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBin String.format("Unsupported packet-handling action %s for ACE %s", action, ace.getRuleName())))).byteValue(); } + + default AceIpVersion ipVersion(final AclRule rule) { + if (rule.isIpv6 == 0) { + return ip4Ace(rule); + } else { + return ip6Ace(rule); + } + } + + default AceIpVersion ip4Ace(final AclRule rule) { + final AceIpv4Builder ipVersion = new AceIpv4Builder(); + if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) { + ipVersion.setSourceIpv4Network(toIpv4Prefix(truncateIp4Array(rule.srcIpAddr), rule.srcIpPrefixLen)); + } + if (rule.dstIpAddr != null && rule.dstIpAddr.length != 0) { + ipVersion.setDestinationIpv4Network(toIpv4Prefix(truncateIp4Array(rule.dstIpAddr), rule.dstIpPrefixLen)); + } + return ipVersion.build(); + } + + default AceIpVersion ip6Ace(final AclRule rule) { + final AceIpv6Builder ipVersion = new AceIpv6Builder(); + if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) { + ipVersion.setSourceIpv6Network(toIpv6Prefix(rule.srcIpAddr, rule.srcIpPrefixLen)); + } + if (rule.dstIpAddr != null && rule.dstIpAddr.length != 0) { + ipVersion.setDestinationIpv6Network(toIpv6Prefix(rule.dstIpAddr, rule.dstIpPrefixLen)); + } + return ipVersion.build(); + } + + default Actions actions(final byte isPermit) { + final ActionsBuilder actions = new ActionsBuilder(); + switch (isPermit) { + case 0: + actions.setPacketHandling(new DenyBuilder().setDeny(true).build()); + break; + case 1: + actions.setPacketHandling(new PermitBuilder().setPermit(true).build()); + break; + case 2: + actions.setPacketHandling(new StatefulBuilder().setPermit(true).build()); + break; + default: + throw new IllegalArgumentException("Unsupported action: " + isPermit); + } + return actions.build(); + } } diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java index 1fecc6c5b..eae4bab4e 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java @@ -16,9 +16,9 @@ package io.fd.hc2vpp.acl.util.acl; +import io.fd.hc2vpp.acl.util.AclContextManager; import io.fd.hc2vpp.acl.util.ace.AceConverter; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.acl.dto.AclAddReplace; @@ -28,8 +28,10 @@ import io.fd.vpp.jvpp.acl.dto.MacipAclAdd; import io.fd.vpp.jvpp.acl.dto.MacipAclAddReply; import io.fd.vpp.jvpp.acl.dto.MacipAclDel; import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; +import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** @@ -41,84 +43,91 @@ public interface AclWriter extends AclDataExtractor, AceConverter, JvppReplyCons default void addStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade, @Nonnull final InstanceIdentifier id, @Nonnull final Acl acl, - @Nonnull final NamingContext standardAclContext, + @Nonnull final AclContextManager standardAclContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { final AclAddReplace request = new AclAddReplace(); request.tag = getAclNameAsBytes(acl); request.aclIndex = ACL_INDEX_CREATE_NEW; - request.r = convertToStandardAclRules(getAces(acl)); + + final List aces = getAces(acl); + request.r = toStandardAclRules(aces); request.count = request.r.length; final AclAddReplaceReply reply = getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id); // maps new acl to returned index - standardAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext); + standardAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext); } // according to vpp team, this was tested extensively, and should work default void updateStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade, @Nonnull final InstanceIdentifier id, @Nonnull final Acl acl, - @Nonnull final NamingContext standardAclContext, + @Nonnull final AclContextManager standardAclContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { final AclAddReplace request = new AclAddReplace(); request.tag = getAclNameAsBytes(acl); // by setting existing index, request is resolved as update - request.aclIndex = standardAclContext.getIndex(acl.getAclName(), mappingContext); - request.r = convertToStandardAclRules(getAces(acl)); + request.aclIndex = standardAclContext.getAclIndex(acl.getAclName(), mappingContext); + + final List aces = getAces(acl); + request.r = toStandardAclRules(aces); request.count = request.r.length; - getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id); + final AclAddReplaceReply reply = getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id); + // overwrites existing acl metadata (aces might have been changed): + standardAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext); } - default void deleteStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade, @Nonnull final InstanceIdentifier id, @Nonnull final Acl acl, - @Nonnull final NamingContext standardAclContext, + @Nonnull final AclContextManager standardAclContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { final AclDel request = new AclDel(); final String aclName = acl.getAclName(); - request.aclIndex = standardAclContext.getIndex(aclName, mappingContext); + request.aclIndex = standardAclContext.getAclIndex(aclName, mappingContext); getReplyForDelete(futureFacade.aclDel(request).toCompletableFuture(), id); // removes mapping after successful delete - standardAclContext.removeName(aclName, mappingContext); + standardAclContext.removeAcl(aclName, mappingContext); } default void addMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade, @Nonnull final InstanceIdentifier id, @Nonnull final Acl acl, - @Nonnull final NamingContext macIpAclContext, + @Nonnull final AclContextManager macIpAclContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { final MacipAclAdd request = new MacipAclAdd(); request.tag = getAclNameAsBytes(acl); - request.r = convertToMacIpAclRules(getAces(acl)); + + final List aces = getAces(acl); + request.r = toMacIpAclRules(aces); request.count = request.r.length; final MacipAclAddReply reply = getReplyForWrite(futureFacade.macipAclAdd(request).toCompletableFuture(), id); // map mac-ip acl to returned index - macIpAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext); + macIpAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext); } default void deleteMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade, @Nonnull final InstanceIdentifier id, @Nonnull final Acl acl, - @Nonnull final NamingContext macIpAclContext, + @Nonnull final AclContextManager macIpAclContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { final MacipAclDel request = new MacipAclDel(); final String aclName = acl.getAclName(); - request.aclIndex = macIpAclContext.getIndex(aclName, mappingContext); + request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext); getReplyForDelete(futureFacade.macipAclDel(request).toCompletableFuture(), id); - macIpAclContext.removeName(aclName, mappingContext); + macIpAclContext.removeAcl(aclName, mappingContext); } diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java new file mode 100644 index 000000000..4057d229a --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.acl.util.factory; + +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public interface AclFactory { + + default Set> vppAclChildren(final InstanceIdentifier parentId) { + final InstanceIdentifier matchesIid = + parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class); + return ImmutableSet.of(parentId.child(AccessListEntries.class), + parentId.child(AccessListEntries.class).child(Ace.class), + parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class), + parentId.child(AccessListEntries.class).child(Ace.class).child(Actions.class), + matchesIid, + matchesIid.child(VppMacipAceNodes.class), + matchesIid.child(VppAceNodes.class), + matchesIid.child(VppAceNodes.class).child(IcmpNodes.class), + matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpCodeRange.class), + matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpTypeRange.class), + matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class), + matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpCodeRange.class), + matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpTypeRange.class), + matchesIid.child(VppAceNodes.class).child(UdpNodes.class), + matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(SourcePortRange.class), + matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(DestinationPortRange.class), + matchesIid.child(VppAceNodes.class).child(TcpNodes.class), + matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(SourcePortRange.class), + matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(DestinationPortRange.class), + matchesIid.child(VppAceNodes.class).child(OtherNodes.class) + + ); + } + +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java index e3c5b727e..4447b7534 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java @@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.util.iface.acl; import static com.google.common.base.Preconditions.checkNotNull; +import io.fd.hc2vpp.acl.util.AclContextManager; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.NamingContext; @@ -46,7 +47,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat private InstanceIdentifier identifier; private List inputAclNames; private List outputAclNames; - private NamingContext standardAclContext; + private AclContextManager standardAclContext; private NamingContext interfaceContext; @@ -74,7 +75,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat return this; } - public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final NamingContext standardAclContext) { + public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final AclContextManager standardAclContext) { this.standardAclContext = standardAclContext; return this; } @@ -155,7 +156,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat request.nInput = (byte) inputAclNames.size(); request.count = (byte) (inputAclNames.size() + outputAclNames.size()); request.acls = Stream.concat(inputAclNames.stream(), outputAclNames.stream()) - .mapToInt(aclName -> standardAclContext.getIndex(aclName, mappingContext)) + .mapToInt(aclName -> standardAclContext.getAclIndex(aclName, mappingContext)) .toArray(); return request; } diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java index f8d726397..882cfd631 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java @@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.util.iface.macip; import static com.google.common.base.Preconditions.checkNotNull; +import io.fd.hc2vpp.acl.util.AclContextManager; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.NamingContext; @@ -41,7 +42,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp private final MappingContext mappingContext; private InstanceIdentifier identifier; private String aclName; - private NamingContext macIpAclContext; + private AclContextManager macIpAclContext; private NamingContext interfaceContext; @@ -68,7 +69,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp return this; } - public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final NamingContext macIpAclContext) { + public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final AclContextManager macIpAclContext) { this.macIpAclContext = macIpAclContext; return this; } @@ -96,7 +97,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp MacipAclInterfaceAddDel request = new MacipAclInterfaceAddDel(); request.isAdd = booleanToByte(isNew); - request.aclIndex = macIpAclContext.getIndex(aclName, mappingContext); + request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext); request.swIfIndex = interfaceContext.getIndex(interfaceName, mappingContext); diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java new file mode 100644 index 000000000..767baef3d --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * 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.acl.util.protocol; + +import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.ICMPV6_INDEX; +import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.ICMP_INDEX; +import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.TCP_INDEX; +import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.UDP_INDEX; + +import io.fd.vpp.jvpp.acl.types.AclRule; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.IpProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Icmp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpV6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpV6Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.OtherBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Tcp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.TcpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Udp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.UdpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6NodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodesBuilder; + +/** + * Utility for parsing IpProtocol DO based on data returned by vpp as {@link AclRule}. + */ +public interface IpProtocolReader { + + default IpProtocol parseProtocol(final AclRule rule) { + switch (rule.proto) { + case ICMP_INDEX: { + return Impl.parseIcmp(rule); + } + + case TCP_INDEX: { + return Impl.parseTcp(rule); + } + + case UDP_INDEX: { + return Impl.parseUdp(rule); + } + + case ICMPV6_INDEX: { + return Impl.parseIcmp6(rule); + } + default: { + return Impl.parse(rule); + } + } + } + + class Impl { + + private static IcmpCodeRange parseIcmpCodeRange(final AclRule rule) { + return new IcmpCodeRangeBuilder() + .setFirst(rule.dstportOrIcmpcodeFirst) + .setLast(rule.dstportOrIcmpcodeLast).build(); + } + + private static IcmpTypeRange parseIcmpTypeRange(final AclRule rule) { + return new IcmpTypeRangeBuilder() + .setFirst(rule.srcportOrIcmptypeFirst) + .setLast(rule.srcportOrIcmptypeLast).build(); + } + + private static Icmp parseIcmp(final AclRule rule) { + final IcmpNodesBuilder nodes = new IcmpNodesBuilder(); + nodes.setIcmpCodeRange(parseIcmpCodeRange(rule)); + nodes.setIcmpTypeRange(parseIcmpTypeRange(rule)); + return new IcmpBuilder().setIcmpNodes(nodes.build()).build(); + } + + private static DestinationPortRange parseDstPortRange(final AclRule rule) { + return new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(Short.toUnsignedInt(rule.dstportOrIcmpcodeFirst))) + .setUpperPort(new PortNumber(Short.toUnsignedInt(rule.dstportOrIcmpcodeLast))).build(); + } + + private static SourcePortRange parseSrcPortRange(final AclRule rule) { + return new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(Short.toUnsignedInt(rule.srcportOrIcmptypeFirst))) + .setUpperPort(new PortNumber(Short.toUnsignedInt(rule.srcportOrIcmptypeLast))).build(); + } + + private static Tcp parseTcp(final AclRule rule) { + final TcpNodesBuilder nodes = new TcpNodesBuilder(); + nodes.setDestinationPortRange(parseDstPortRange(rule)); + nodes.setSourcePortRange(parseSrcPortRange(rule)); + nodes.setTcpFlagsMask((short) Byte.toUnsignedInt(rule.tcpFlagsMask)); + nodes.setTcpFlagsValue((short) Byte.toUnsignedInt(rule.tcpFlagsValue)); + return new TcpBuilder().setTcpNodes(nodes.build()).build(); + } + + private static Udp parseUdp(final AclRule rule) { + final UdpNodesBuilder nodes = new UdpNodesBuilder(); + nodes.setDestinationPortRange(parseDstPortRange(rule)); + nodes.setSourcePortRange(parseSrcPortRange(rule)); + return new UdpBuilder().setUdpNodes(nodes.build()).build(); + } + + private static IcmpV6 parseIcmp6(final AclRule rule) { + final IcmpV6NodesBuilder nodes = new IcmpV6NodesBuilder(); + nodes.setIcmpCodeRange(parseIcmpCodeRange(rule)); + nodes.setIcmpTypeRange(parseIcmpTypeRange(rule)); + return new IcmpV6Builder().setIcmpV6Nodes(nodes.build()).build(); + } + + private static IpProtocol parse(final AclRule rule) { + final OtherNodesBuilder nodes = new OtherNodesBuilder(); + nodes.setProtocol((short) Short.toUnsignedInt(rule.proto)); + return new OtherBuilder().setOtherNodes(nodes.build()).build(); + } + } +} -- cgit 1.2.3-korg