From 2d92edf65ee34329d9226e2efe90a5d10265cd72 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Wed, 11 Jan 2017 10:11:20 +0100 Subject: Fix NPE in L3 rules Patch introduces proper handling for IP adresses, which are optional. Change-Id: Ib009207b4b241d3e2b8c665a35bb1ff87b4a12ac Signed-off-by: Marek Gradzki (cherry picked from commit e0b4359b39acfe8a583089117a0c2485b85ff7e4) --- .../acl/util/ace/extractor/AddressExtractor.java | 57 ++++++++++++++++++++++ .../util/ace/extractor/MacIpAceDataExtractor.java | 11 ++--- .../ace/extractor/StandardAceDataExtractor.java | 23 +++++---- .../fd/hc2vpp/acl/write/VppAclCustomizerTest.java | 19 +++++++- .../acl/standard/standard-acl-tcp-src-only.json | 37 ++++++++++++++ 5 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/AddressExtractor.java create mode 100644 acl/acl-impl/src/test/resources/acl/standard/standard-acl-tcp-src-only.json (limited to 'acl') diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/AddressExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/AddressExtractor.java new file mode 100644 index 000000000..abb2eb339 --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/AddressExtractor.java @@ -0,0 +1,57 @@ +/* + * 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.ace.extractor; + +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; + +public interface AddressExtractor extends AddressTranslator { + + default byte[] extractIp4Address(@Nullable Ipv4Prefix ip) { + if (ip == null) { + return new byte[4]; + } else { + return ipv4AddressPrefixToArray(ip); + } + } + + default byte extractIp4AddressPrefix(@Nullable Ipv4Prefix ip) { + if (ip == null) { + return 0; + } else { + return extractPrefix(ip); + } + } + + default byte[] extractIp6Address(@Nullable Ipv6Prefix ip) { + if (ip == null) { + return new byte[16]; + } else { + return ipv6AddressPrefixToArray(ip); + } + } + + default byte extractIp6AddressPrefix(@Nullable Ipv6Prefix ip) { + if (ip == null) { + return 0; + } else { + return extractPrefix(ip); + } + } +} 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 4a29949ec..b98daa5ce 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 @@ -16,7 +16,6 @@ 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; @@ -33,7 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl. 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, MacTranslator { +public interface MacIpAceDataExtractor extends AddressExtractor, MacTranslator { default VppMacipAce fromMacIpAce(@Nonnull final Ace ace) { return VppMacipAce.class.cast(ace.getMatches().getAceType()); @@ -52,22 +51,22 @@ public interface MacIpAceDataExtractor extends AddressTranslator, MacTranslator } default byte[] ipv4Address(@Nonnull final VppMacipAce ace) { - return ipv4AddressPrefixToArray( + return extractIp4Address( VppMacipAceIpv4HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv4Network()); } default byte ipv4AddressPrefix(@Nonnull final VppMacipAce ace) { - return extractPrefix( + return extractIp4AddressPrefix( VppMacipAceIpv4HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv4Network()); } default byte[] ipv6Address(@Nonnull final VppMacipAce ace) { - return ipv6AddressPrefixToArray( + return extractIp6Address( VppMacipAceIpv6HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv6Network()); } default byte ipv6AddressPrefix(@Nonnull final VppMacipAce ace) { - return extractPrefix( + return extractIp6AddressPrefix( VppMacipAceIpv6HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv6Network()); } 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 6d395fb01..664023947 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 @@ -19,7 +19,6 @@ 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; @@ -42,7 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl. 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, IpProtocolReader { +public interface StandardAceDataExtractor extends AddressExtractor, ProtoPreBindRuleProducer, IpProtocolReader { /** * Allowed packet-processing actions for Acl's @@ -59,39 +58,43 @@ public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBin } default byte[] ipv4SourceAddress(@Nonnull final VppAce ace) { - return ipv4AddressPrefixToArray( + return extractIp4Address( AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv4Network()); } default byte ipv4SourceAddressPrefix(@Nonnull final VppAce ace) { - return extractPrefix(AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv4Network()); + return extractIp4AddressPrefix( + AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv4Network()); } default byte[] ipv4DestinationAddress(@Nonnull final VppAce ace) { - return ipv4AddressPrefixToArray( + return extractIp4Address( AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv4Network()); } default byte ipv4DestinationAddressPrefix(@Nonnull final VppAce ace) { - return extractPrefix(AceIpv4.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv4Network()); + return extractIp4AddressPrefix(AceIpv4.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv4Network()); } + default byte[] ipv6SourceAddress(@Nonnull final VppAce ace) { - return ipv6AddressPrefixToArray( + return extractIp6Address( AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv6Network()); } default byte ipv6SourceAddressPrefix(@Nonnull final VppAce ace) { - return extractPrefix(AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv6Network()); + return extractIp6AddressPrefix( + AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv6Network()); } default byte[] ipv6DestinationAddress(@Nonnull final VppAce ace) { - return ipv6AddressPrefixToArray( + return extractIp6Address( AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv6Network()); } default byte ipv6DestinationAddressPrefix(@Nonnull final VppAce ace) { - return extractPrefix(AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv6Network()); + return extractIp6AddressPrefix( + AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv6Network()); } default byte standardAction(@Nonnull final Ace ace) { diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/write/VppAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/write/VppAclCustomizerTest.java index bfdd17682..b4b4ef9ba 100644 --- a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/write/VppAclCustomizerTest.java +++ b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/write/VppAclCustomizerTest.java @@ -168,7 +168,7 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes @Test public void updateCurrentAttributesTcp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-tcp.json") - AccessLists standardAcls) throws Exception { + AccessLists standardAcls) throws Exception { final int aclIndex = 4; when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex); final Acl data = standardAcls.getAcl().get(0); @@ -178,6 +178,23 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes verifyTcpRequest(aclIndex); } + @Test + public void updateCurrentAttributesTcpSrcOnly(@InjectTestData(resourcePath = "/acl/standard/standard-acl-tcp-src-only.json") + AccessLists standardAcls) throws Exception { + final int aclIndex = 4; + when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex); + final Acl data = standardAcls.getAcl().get(0); + aclCustomizer.updateCurrentAttributes(validId, data, data, writeContext); + + verify(aclApi, times(1)).aclAddReplace(aclAddReplaceRequestCaptor.capture()); + final AclAddReplace request = aclAddReplaceRequestCaptor.getValue(); + final AclRule tcpRule = request.r[0]; + assertTrue(Arrays.equals(new byte[]{-64, -88, 2, 2}, tcpRule.srcIpAddr)); + assertEquals(32, tcpRule.srcIpPrefixLen); + assertTrue(Arrays.equals(new byte[]{0, 0, 0, 0}, tcpRule.dstIpAddr)); + assertEquals(0, tcpRule.dstIpPrefixLen); + } + @Test public void writeCurrentAttributesUdp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-udp.json") diff --git a/acl/acl-impl/src/test/resources/acl/standard/standard-acl-tcp-src-only.json b/acl/acl-impl/src/test/resources/acl/standard/standard-acl-tcp-src-only.json new file mode 100644 index 000000000..48e6f8807 --- /dev/null +++ b/acl/acl-impl/src/test/resources/acl/standard/standard-acl-tcp-src-only.json @@ -0,0 +1,37 @@ +{ + "access-lists": { + "acl": [ + { + "acl-name": "standard-acl", + "acl-type": "vpp-acl:vpp-acl", + "access-list-entries": { + "ace": [ + { + "rule-name": "tcp-rule", + "matches": { + "vpp-ace-nodes": { + "source-ipv4-network": "192.168.2.2/32", + "tcp-nodes": { + "source-port-range": { + "lower-port": "1", + "upper-port": "5487" + }, + "destination-port-range": { + "lower-port": "87", + "upper-port": "6745" + }, + "tcp-flags-mask": "1", + "tcp-flags-value": "7" + } + } + }, + "actions": { + "permit": {} + } + } + ] + } + } + ] + } +} \ No newline at end of file -- cgit 1.2.3-korg