From bf1d5db448edc1ae352960f14bca9ccb41612186 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Wed, 8 Mar 2017 14:01:34 +0100 Subject: HC2VPP-7 - split vpp-classifiers to separate module Split vpp-classifiers and vpp-classifiers acls' to separate modules. Contains TODO's for future change of dependencies Change-Id: I94f92ce2ec8960c67bd406f085f2fe928079ee23 Signed-off-by: Jan Srnicek --- acl/acl-api/pom.xml | 4 +- pom.xml | 1 + routing/routing-api/pom.xml | 4 +- routing/routing-impl/pom.xml | 4 +- .../hc2vpp/routing/write/Ipv4RouteCustomizer.java | 2 +- .../hc2vpp/routing/write/Ipv6RouteCustomizer.java | 2 +- .../hc2vpp/routing/write/RoutingWriterFactory.java | 2 +- .../write/factory/MultipathHopRequestFactory.java | 2 +- .../write/factory/SimpleHopRequestFactory.java | 2 +- .../factory/SpecialNextHopRequestFactory.java | 11 +- .../write/factory/base/BasicHopRequestFactory.java | 7 +- .../routing/write/trait/RouteRequestProducer.java | 17 +- .../io/fd/hc2vpp/routing/RoutingModuleTest.java | 2 +- .../routing/helpers/ClassifyTableTestHelper.java | 2 +- .../routing/write/Ipv4RouteCustomizerTest.java | 2 +- .../routing/write/Ipv6RouteCustomizerTest.java | 2 +- .../MultipathHopRequestFactoryIpv4Test.java | 2 +- .../MultipathHopRequestFactoryIpv6Test.java | 2 +- .../factory/SimpleHopRequestFactoryIpv4Test.java | 2 +- .../factory/SimpleHopRequestFactoryIpv6Test.java | 2 +- .../SpecialNextHopRequestFactoryIpv4Test.java | 12 +- .../SpecialNextHopRequestFactoryIpv6Test.java | 2 +- .../classifier/rev161214/OpaqueIndexBuilder.java | 39 --- .../vpp/classifier/rev161214/VppNodeBuilder.java | 40 ---- .../src/main/yang/ietf-access-control-list.yang | 208 ---------------- v3po/api/src/main/yang/ietf-packet-fields.yang | 180 -------------- v3po/api/src/main/yang/v3po.yang | 39 --- v3po/api/src/main/yang/vpp-classfier-acl.yang | 163 ------------- v3po/api/src/main/yang/vpp-classifier-context.yang | 68 ------ v3po/api/src/main/yang/vpp-classifier.yang | 215 ----------------- v3po/api/src/main/yang/vpp-vlan.yang | 21 -- .../io/fd/hc2vpp/v3po/ClassifierIetfAclModule.java | 54 ----- .../main/java/io/fd/hc2vpp/v3po/V3poModule.java | 21 +- .../fd/hc2vpp/v3po/factory/AclWriterFactory.java | 60 ----- .../v3po/factory/EgressIetfAClWriterProvider.java | 39 --- .../v3po/factory/IngressIetfAClWriterProvider.java | 39 --- .../InterfacesClassifierIetfAclWriterFactory.java | 81 ------- .../v3po/factory/InterfacesStateReaderFactory.java | 24 -- .../v3po/factory/InterfacesWriterFactory.java | 25 -- ...ubInterfacesClassifierIetfAclWriterFactory.java | 83 ------- .../SubinterfaceAugmentationWriterFactory.java | 25 +- ...SubinterfaceStateAugmentationReaderFactory.java | 24 +- .../VppClassifierHoneycombWriterFactory.java | 64 ----- .../v3po/factory/VppClassifierReaderFactory.java | 60 ----- .../hc2vpp/v3po/interfaces/acl/IetfAclWriter.java | 106 --------- .../acl/common/AbstractIetfAclWriter.java | 252 -------------------- .../v3po/interfaces/acl/common/AceEthWriter.java | 85 ------- .../v3po/interfaces/acl/common/AceIp4Writer.java | 94 -------- .../v3po/interfaces/acl/common/AceIp6Writer.java | 99 -------- .../interfaces/acl/common/AceIpAndEthWriter.java | 132 ----------- .../v3po/interfaces/acl/common/AceWriter.java | 54 ----- .../acl/common/AclTableContextManager.java | 53 ----- .../acl/common/AclTableContextManagerImpl.java | 68 ------ .../v3po/interfaces/acl/common/AclTranslator.java | 74 ------ .../v3po/interfaces/acl/common/IetfAclWriter.java | 47 ---- .../interfaces/acl/common/Ip4AclTranslator.java | 149 ------------ .../interfaces/acl/common/Ip6AclTranslator.java | 182 -------------- .../interfaces/acl/common/L2AclTranslator.java | 90 ------- .../v3po/interfaces/acl/common/PortPair.java | 126 ---------- .../interfaces/acl/egress/EgressIetfAclWriter.java | 120 ---------- .../interfaces/acl/egress/IetfAclCustomizer.java | 85 ------- .../acl/egress/SubInterfaceIetfAclCustomizer.java | 105 -------- .../v3po/interfaces/acl/ingress/AclCustomizer.java | 83 ------- .../v3po/interfaces/acl/ingress/AclWriter.java | 73 ------ .../interfaces/acl/ingress/IetfAclCustomizer.java | 89 ------- .../acl/ingress/IngressIetfAclWriter.java | 118 --------- .../acl/ingress/SubInterfaceAclCustomizer.java | 93 -------- .../acl/ingress/SubInterfaceIetfAclCustomizer.java | 108 --------- .../interfacesstate/acl/ingress/AclCustomizer.java | 118 --------- .../interfacesstate/acl/ingress/AclReader.java | 60 ----- .../acl/ingress/SubInterfaceAclCustomizer.java | 120 ---------- .../v3po/vppclassifier/ClassifySessionReader.java | 212 ----------------- .../v3po/vppclassifier/ClassifySessionWriter.java | 165 ------------- .../v3po/vppclassifier/ClassifyTableReader.java | 176 -------------- .../v3po/vppclassifier/ClassifyTableWriter.java | 149 ------------ .../vppclassifier/VppClassifierContextManager.java | 106 --------- .../VppClassifierContextManagerImpl.java | 181 -------------- .../hc2vpp/v3po/vppclassifier/VppNodeReader.java | 45 ---- .../hc2vpp/v3po/vppclassifier/VppNodeWriter.java | 79 ------- .../hc2vpp/v3po/ClassifierIetfAclModuleTest.java | 71 ------ .../hc2vpp/v3po/interfaces/AclCustomizerTest.java | 153 ------------ .../hc2vpp/v3po/interfaces/acl/AclWriterTest.java | 103 -------- .../interfaces/acl/common/AceEthWriterTest.java | 94 -------- .../interfaces/acl/common/AceIp4WriterTest.java | 189 --------------- .../interfaces/acl/common/AceIp6WriterTest.java | 200 ---------------- .../acl/common/AceIpAndEthWriterTest.java | 124 ---------- .../acl/common/AceIpWriterTestUtils.java | 34 --- .../acl/common/AclTableContextManagerImplTest.java | 62 ----- .../v3po/interfaces/acl/common/PortPairTest.java | 114 --------- .../acl/egress/EgressIetfAclWriterTest.java | 152 ------------ .../acl/egress/IetfAclCustomizerTest.java | 114 --------- .../egress/SubInterfaceIetfAclCustomizerTest.java | 130 ---------- .../acl/ingress/IetfAclCustomizerTest.java | 205 ---------------- .../acl/ingress/SubInterfaceAclCustomizerTest.java | 140 ----------- .../ingress/SubInterfaceIetfAclCustomizerTest.java | 155 ------------ .../acl/ingress/AclCustomizerTest.java | 99 -------- .../acl/ingress/SubInterfaceAclCustomizerTest.java | 108 --------- .../vppclassifier/ClassifySessionReaderTest.java | 116 --------- .../vppclassifier/ClassifySessionWriterTest.java | 177 -------------- .../vppclassifier/ClassifyTableReaderTest.java | 126 ---------- .../vppclassifier/ClassifyTableWriterTest.java | 181 -------------- .../VppClassifierContextManagerImplTest.java | 163 ------------- vpp-classifier/api/asciidoc/Readme.adoc | 3 + vpp-classifier/api/pom.xml | 60 +++++ .../classifier/rev161214/OpaqueIndexBuilder.java | 40 ++++ .../vpp/classifier/rev161214/VppNodeBuilder.java | 41 ++++ .../src/main/yang/ietf-access-control-list.yang | 208 ++++++++++++++++ .../api/src/main/yang/ietf-packet-fields.yang | 180 ++++++++++++++ .../api/src/main/yang/vpp-classifier-acl.yang | 183 ++++++++++++++ .../api/src/main/yang/vpp-classifier-context.yang | 68 ++++++ .../api/src/main/yang/vpp-classifier.yang | 215 +++++++++++++++++ .../api/src/main/yang/vpp-interface-acl.yang | 32 +++ .../api/src/main/yang/vpp-subinterface-acl.yang | 36 +++ vpp-classifier/asciidoc/Readme.adoc | 3 + vpp-classifier/impl/asciidoc/Readme.adoc | 9 + vpp-classifier/impl/pom.xml | 131 ++++++++++ .../classifier/InterfaceClassifierAclModule.java | 39 +++ .../InterfaceClassifierIetfAclModule.java | 32 +++ .../SubInterfaceClassifierAclModule.java | 37 +++ .../SubInterfaceClassifierIetfAclModule.java | 32 +++ .../vpp/classifier/VppClassifierAclModule.java | 46 ++++ .../hc2vpp/vpp/classifier/VppClassifierModule.java | 55 +++++ .../context/VppClassifierContextManager.java | 106 +++++++++ .../context/VppClassifierContextManagerImpl.java | 181 ++++++++++++++ .../factory/read/InterfaceAclReaderFactory.java | 76 ++++++ .../factory/read/SubInterfaceAclReaderFactory.java | 83 +++++++ .../factory/read/VppClassifierReaderFactory.java | 60 +++++ .../classifier/factory/write/AclWriterFactory.java | 57 +++++ .../factory/write/InterfaceAclWriterFactory.java | 77 ++++++ .../InterfacesClassifierIetfAclWriterFactory.java | 81 +++++++ .../write/SubInterfaceAclWriterFactory.java | 78 ++++++ ...ubInterfacesClassifierIetfAclWriterFactory.java | 89 +++++++ .../write/VppClassifierHoneycombWriterFactory.java | 64 +++++ .../provider/EgressIetfAClWriterProvider.java | 39 +++ .../provider/IngressIetfAClWriterProvider.java | 39 +++ .../vpp/classifier/read/ClassifySessionReader.java | 212 +++++++++++++++++ .../vpp/classifier/read/ClassifyTableReader.java | 177 ++++++++++++++ .../hc2vpp/vpp/classifier/read/VppNodeReader.java | 46 ++++ .../vpp/classifier/read/acl/AclCustomizer.java | 119 ++++++++++ .../hc2vpp/vpp/classifier/read/acl/AclReader.java | 60 +++++ .../read/acl/SubInterfaceAclCustomizer.java | 122 ++++++++++ .../classifier/write/ClassifySessionWriter.java | 165 +++++++++++++ .../vpp/classifier/write/ClassifyTableWriter.java | 150 ++++++++++++ .../hc2vpp/vpp/classifier/write/VppNodeWriter.java | 80 +++++++ .../vpp/classifier/write/acl/IetfAclWriter.java | 105 ++++++++ .../write/acl/common/AbstractIetfAclWriter.java | 252 ++++++++++++++++++++ .../classifier/write/acl/common/AceEthWriter.java | 85 +++++++ .../classifier/write/acl/common/AceIp4Writer.java | 94 ++++++++ .../classifier/write/acl/common/AceIp6Writer.java | 99 ++++++++ .../write/acl/common/AceIpAndEthWriter.java | 132 +++++++++++ .../vpp/classifier/write/acl/common/AceWriter.java | 54 +++++ .../write/acl/common/AclTableContextManager.java | 53 +++++ .../acl/common/AclTableContextManagerImpl.java | 68 ++++++ .../classifier/write/acl/common/AclTranslator.java | 74 ++++++ .../classifier/write/acl/common/IetfAclWriter.java | 47 ++++ .../write/acl/common/Ip4AclTranslator.java | 149 ++++++++++++ .../write/acl/common/Ip6AclTranslator.java | 182 ++++++++++++++ .../write/acl/common/L2AclTranslator.java | 90 +++++++ .../vpp/classifier/write/acl/common/PortPair.java | 126 ++++++++++ .../write/acl/egress/EgressIetfAclWriter.java | 120 ++++++++++ .../write/acl/egress/IetfAclCustomizer.java | 85 +++++++ .../acl/egress/SubInterfaceIetfAclCustomizer.java | 105 ++++++++ .../write/acl/ingress/AclCustomizer.java | 83 +++++++ .../classifier/write/acl/ingress/AclWriter.java | 73 ++++++ .../write/acl/ingress/IetfAclCustomizer.java | 89 +++++++ .../write/acl/ingress/IngressIetfAclWriter.java | 118 +++++++++ .../acl/ingress/SubInterfaceAclCustomizer.java | 93 ++++++++ .../acl/ingress/SubInterfaceIetfAclCustomizer.java | 108 +++++++++ .../vpp/classifier/VppClassifierModuleTest.java | 84 +++++++ .../VppClassifierContextManagerImplTest.java | 163 +++++++++++++ .../classifier/read/ClassifySessionReaderTest.java | 117 +++++++++ .../classifier/read/ClassifyTableReaderTest.java | 126 ++++++++++ .../vpp/classifier/read/acl/AclCustomizerTest.java | 99 ++++++++ .../read/acl/SubInterfaceAclCustomizerTest.java | 111 +++++++++ .../write/ClassifySessionWriterTest.java | 178 ++++++++++++++ .../classifier/write/ClassifyTableWriterTest.java | 182 ++++++++++++++ .../classifier/write/acl/AclCustomizerTest.java | 153 ++++++++++++ .../vpp/classifier/write/acl/AclWriterTest.java | 103 ++++++++ .../write/acl/common/AceEthWriterTest.java | 94 ++++++++ .../write/acl/common/AceIp4WriterTest.java | 189 +++++++++++++++ .../write/acl/common/AceIp6WriterTest.java | 200 ++++++++++++++++ .../write/acl/common/AceIpAndEthWriterTest.java | 124 ++++++++++ .../write/acl/common/AceIpWriterTestUtils.java | 34 +++ .../acl/common/AclTableContextManagerImplTest.java | 62 +++++ .../classifier/write/acl/common/PortPairTest.java | 114 +++++++++ .../write/acl/egress/EgressIetfAclWriterTest.java | 152 ++++++++++++ .../write/acl/egress/IetfAclCustomizerTest.java | 114 +++++++++ .../egress/SubInterfaceIetfAclCustomizerTest.java | 133 +++++++++++ .../write/acl/ingress/IetfAclCustomizerTest.java | 205 ++++++++++++++++ .../acl/ingress/SubInterfaceAclCustomizerTest.java | 143 +++++++++++ .../ingress/SubInterfaceIetfAclCustomizerTest.java | 158 +++++++++++++ vpp-classifier/pom.xml | 36 +++ .../vpp_classifier_postman_collection.json | 263 +++++++++++++++++++++ vpp-integration/minimal-distribution/pom.xml | 13 +- 194 files changed, 9493 insertions(+), 8518 deletions(-) delete mode 100644 v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java delete mode 100644 v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java delete mode 100644 v3po/api/src/main/yang/ietf-access-control-list.yang delete mode 100644 v3po/api/src/main/yang/ietf-packet-fields.yang delete mode 100644 v3po/api/src/main/yang/vpp-classfier-acl.yang delete mode 100644 v3po/api/src/main/yang/vpp-classifier-context.yang delete mode 100644 v3po/api/src/main/yang/vpp-classifier.yang delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModule.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/AclWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/EgressIetfAClWriterProvider.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/IngressIetfAClWriterProvider.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesClassifierIetfAclWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubInterfacesClassifierIetfAclWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierHoneycombWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModuleTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java create mode 100644 vpp-classifier/api/asciidoc/Readme.adoc create mode 100644 vpp-classifier/api/pom.xml create mode 100644 vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java create mode 100644 vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java create mode 100644 vpp-classifier/api/src/main/yang/ietf-access-control-list.yang create mode 100644 vpp-classifier/api/src/main/yang/ietf-packet-fields.yang create mode 100644 vpp-classifier/api/src/main/yang/vpp-classifier-acl.yang create mode 100644 vpp-classifier/api/src/main/yang/vpp-classifier-context.yang create mode 100644 vpp-classifier/api/src/main/yang/vpp-classifier.yang create mode 100644 vpp-classifier/api/src/main/yang/vpp-interface-acl.yang create mode 100644 vpp-classifier/api/src/main/yang/vpp-subinterface-acl.yang create mode 100644 vpp-classifier/asciidoc/Readme.adoc create mode 100644 vpp-classifier/impl/asciidoc/Readme.adoc create mode 100644 vpp-classifier/impl/pom.xml create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierAclModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierIetfAclModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierAclModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierIetfAclModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierAclModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModule.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManager.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImpl.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/InterfaceAclReaderFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/SubInterfaceAclReaderFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/VppClassifierReaderFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/AclWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfaceAclWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfacesClassifierIetfAclWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfaceAclWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfacesClassifierIetfAclWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/VppClassifierHoneycombWriterFactory.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/EgressIetfAClWriterProvider.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/IngressIetfAClWriterProvider.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReader.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReader.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/VppNodeReader.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclReader.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/VppNodeWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/IetfAclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AbstractIetfAclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4Writer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6Writer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManager.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImpl.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTranslator.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/IetfAclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip4AclTranslator.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip6AclTranslator.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/L2AclTranslator.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPair.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IngressIetfAclWriter.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizer.java create mode 100644 vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizer.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModuleTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImplTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReaderTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReaderTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4WriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6WriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpWriterTestUtils.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImplTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPairTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriterTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizerTest.java create mode 100644 vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizerTest.java create mode 100644 vpp-classifier/pom.xml create mode 100644 vpp-classifier/vpp_classifier_postman_collection.json diff --git a/acl/acl-api/pom.xml b/acl/acl-api/pom.xml index 6efa30444..feed86bf1 100644 --- a/acl/acl-api/pom.xml +++ b/acl/acl-api/pom.xml @@ -49,8 +49,8 @@ - io.fd.hc2vpp.v3po - v3po-api + io.fd.hc2vpp.vpp.classifier + vpp-classifier-api ${project.version} diff --git a/pom.xml b/pom.xml index 940257bd0..0b8d9b64c 100644 --- a/pom.xml +++ b/pom.xml @@ -46,5 +46,6 @@ acl dhcp samples + vpp-classifier diff --git a/routing/routing-api/pom.xml b/routing/routing-api/pom.xml index e473ebb51..f781340f9 100644 --- a/routing/routing-api/pom.xml +++ b/routing/routing-api/pom.xml @@ -61,8 +61,8 @@ yang-ext - io.fd.hc2vpp.v3po - v3po-api + io.fd.hc2vpp.vpp.classifier + vpp-classifier-api ${project.version} diff --git a/routing/routing-impl/pom.xml b/routing/routing-impl/pom.xml index b67fc4f71..88120868f 100644 --- a/routing/routing-impl/pom.xml +++ b/routing/routing-impl/pom.xml @@ -105,8 +105,8 @@ - io.fd.hc2vpp.v3po - v3po2vpp + io.fd.hc2vpp.vpp.classifier + vpp-classifier-impl ${project.version} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizer.java index a1975a10c..efdef904a 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizer.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizer.java @@ -25,7 +25,7 @@ import io.fd.hc2vpp.routing.trait.RouteMapper; import io.fd.hc2vpp.routing.write.factory.MultipathHopRequestFactory; import io.fd.hc2vpp.routing.write.factory.SimpleHopRequestFactory; import io.fd.hc2vpp.routing.write.factory.SpecialNextHopRequestFactory; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizer.java index 4c4a6e7d6..9d87a5bea 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizer.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizer.java @@ -26,7 +26,7 @@ import io.fd.hc2vpp.routing.trait.RouteMapper; import io.fd.hc2vpp.routing.write.factory.MultipathHopRequestFactory; import io.fd.hc2vpp.routing.write.factory.SimpleHopRequestFactory; import io.fd.hc2vpp.routing.write.factory.SpecialNextHopRequestFactory; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java index e5487e570..30efbcede 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java @@ -26,7 +26,7 @@ import com.google.inject.name.Named; import io.fd.hc2vpp.common.translate.util.MultiNamingContext; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.RoutingConfiguration; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.impl.write.GenericWriter; import io.fd.honeycomb.translate.write.WriterFactory; import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactory.java index 6df95a0fd..991c78b0e 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactory.java @@ -19,7 +19,7 @@ package io.fd.hc2vpp.routing.write.factory; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory; import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; import javax.annotation.Nonnull; diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactory.java index 60be15d44..4d6abe08f 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactory.java @@ -19,7 +19,7 @@ package io.fd.hc2vpp.routing.write.factory; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory; import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; import javax.annotation.Nonnull; diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactory.java index e9c9c63ee..49e1bc1c5 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactory.java @@ -16,23 +16,22 @@ package io.fd.hc2vpp.routing.write.factory; +import static com.google.common.base.Preconditions.checkNotNull; + import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory; import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; +import java.util.Optional; +import javax.annotation.Nonnull; 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; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VppRouteAttributes; -import javax.annotation.Nonnull; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkNotNull; - public class SpecialNextHopRequestFactory extends BasicHopRequestFactory implements RouteRequestProducer { diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/base/BasicHopRequestFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/base/BasicHopRequestFactory.java index 740c30c21..d220e5379 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/base/BasicHopRequestFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/base/BasicHopRequestFactory.java @@ -16,13 +16,12 @@ package io.fd.hc2vpp.routing.write.factory.base; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import static com.google.common.base.Preconditions.checkNotNull; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import javax.annotation.Nonnull; -import static com.google.common.base.Preconditions.checkNotNull; - /** * Extension to {@code ClassifierContextHolder} to hold also {@code NamingContext} */ diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/trait/RouteRequestProducer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/trait/RouteRequestProducer.java index 458aac165..36dc4b4b1 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/trait/RouteRequestProducer.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/trait/RouteRequestProducer.java @@ -16,25 +16,24 @@ package io.fd.hc2vpp.routing.write.trait; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.isNull; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; + import com.google.common.collect.ImmutableSet.Builder; import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; +import java.util.Set; +import java.util.regex.Pattern; 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; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference; -import java.util.Set; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.Objects.isNull; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; - /** * Common logic for writing of routes diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/RoutingModuleTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/RoutingModuleTest.java index 670f7afe3..171926d0f 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/RoutingModuleTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/RoutingModuleTest.java @@ -33,7 +33,7 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.read.RoutingStateReaderFactory; import io.fd.hc2vpp.routing.write.RoutingWriterFactory; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; import io.fd.honeycomb.translate.read.ReaderFactory; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/helpers/ClassifyTableTestHelper.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/helpers/ClassifyTableTestHelper.java index 8e8f50c3d..51f60a354 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/helpers/ClassifyTableTestHelper.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/helpers/ClassifyTableTestHelper.java @@ -19,7 +19,7 @@ package io.fd.hc2vpp.routing.helpers; import static org.mockito.Mockito.when; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.translate.MappingContext; public interface ClassifyTableTestHelper { diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizerTest.java index a34b3debb..f0cb89b1f 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizerTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizerTest.java @@ -34,7 +34,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; import io.fd.hc2vpp.routing.naming.Ipv4RouteNamesFactory; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.write.WriteFailedException; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizerTest.java index 15c836411..dc932cd0f 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizerTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizerTest.java @@ -29,7 +29,7 @@ import io.fd.hc2vpp.routing.Ipv6RouteData; import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.write.WriteFailedException; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv4Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv4Test.java index 1eb91aa37..f534b9a38 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv4Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv4Test.java @@ -25,7 +25,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.InterfaceTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv6Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv6Test.java index dfbd093de..7a296181b 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv6Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactoryIpv6Test.java @@ -24,7 +24,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.InterfaceTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv4Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv4Test.java index d344e016e..d097a5d6c 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv4Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv4Test.java @@ -24,7 +24,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.InterfaceTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv6Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv6Test.java index 721fac315..a58529bfa 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv6Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactoryIpv6Test.java @@ -24,7 +24,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.InterfaceTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv4Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv4Test.java index d93a4bf1c..71b449daf 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv4Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv4Test.java @@ -16,6 +16,12 @@ package io.fd.hc2vpp.routing.write.factory; +import static io.fd.hc2vpp.routing.write.factory.SpecialNextHopRequestFactory.forContexts; +import static org.junit.Assert.assertEquals; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping.SpecialNextHop.Prohibit; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping.SpecialNextHop.Receive; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping.SpecialNextHop.Unreachable; + import io.fd.hc2vpp.common.test.util.NamingContextHelper; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.routing.Ipv4RouteData; @@ -23,7 +29,7 @@ import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; @@ -39,10 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicas import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutes; -import static io.fd.hc2vpp.routing.write.factory.SpecialNextHopRequestFactory.forContexts; -import static org.junit.Assert.assertEquals; -import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping.SpecialNextHop.*; - @RunWith(HoneycombTestRunner.class) public class SpecialNextHopRequestFactoryIpv4Test implements RouteRequestProducer, RoutingRequestTestHelper, ClassifyTableTestHelper, diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv6Test.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv6Test.java index fcd97da54..d673ee0e1 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv6Test.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/factory/SpecialNextHopRequestFactoryIpv6Test.java @@ -29,7 +29,7 @@ import io.fd.hc2vpp.routing.Ipv6RouteData; import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper; import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper; import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; import io.fd.honeycomb.test.tools.HoneycombTestRunner; import io.fd.honeycomb.test.tools.annotations.InjectTestData; import io.fd.honeycomb.translate.MappingContext; diff --git a/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java b/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java deleted file mode 100644 index d633dc61c..000000000 --- a/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214; - -/** - * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. - * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). - * - * The reason behind putting it under src/main/java is: - * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent - * loss of user code. - * - */ -public class OpaqueIndexBuilder { - - public static OpaqueIndex getDefaultInstance(java.lang.String defaultValue) { - try { - final long value = Long.parseLong(defaultValue); // u32 value - return new OpaqueIndex(value); - } catch (NumberFormatException e) { - return new OpaqueIndex(VppNodeBuilder.getDefaultInstance(defaultValue)); - } - } - -} diff --git a/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java b/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java deleted file mode 100644 index ad124ab85..000000000 --- a/v3po/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214; - -/** - * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. - * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). - * - * The reason behind putting it under src/main/java is: - * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent - * loss of user code. - * - */ -public class VppNodeBuilder { - - public static VppNode getDefaultInstance(java.lang.String defaultValue) { - if (PacketHandlingAction.Deny.toString().equalsIgnoreCase(defaultValue)) { - return new VppNode(PacketHandlingAction.Deny); - } else if (PacketHandlingAction.Permit.toString().equalsIgnoreCase(defaultValue)) { - return new VppNode(PacketHandlingAction.Permit); - } else { - return new VppNode(new VppNodeName(defaultValue)); - } - } - -} diff --git a/v3po/api/src/main/yang/ietf-access-control-list.yang b/v3po/api/src/main/yang/ietf-access-control-list.yang deleted file mode 100644 index 3083ee2a0..000000000 --- a/v3po/api/src/main/yang/ietf-access-control-list.yang +++ /dev/null @@ -1,208 +0,0 @@ -module ietf-access-control-list { - yang-version 1.1; - namespace "urn:ietf:params:xml:ns:yang:ietf-access-control-list"; - prefix acl; - import ietf-yang-types { - prefix yang; - } - import ietf-packet-fields { - prefix packet-fields; - } - organization "IETF NETMOD (NETCONF Data Modeling Language) - Working Group"; - contact - "WG Web: http://tools.ietf.org/wg/netmod/ - WG List: netmod@ietf.org - WG Chair: Juergen Schoenwaelder - j.schoenwaelder@jacobs-university.de - WG Chair: Tom Nadeau - tnadeau@lucidvision.com - Editor: Dean Bogdanovic - ivandean@gmail.com - Editor: Kiran Agrahara Sreenivasa - kkoushik@cisco.com - Editor: Lisa Huang - lyihuang16@gmail.com - Editor: Dana Blair - dblair@cisco.com"; - description - "This YANG module defines a component that describing the - configuration of Access Control Lists (ACLs). - Copyright (c) 2015 IETF Trust and the persons identified as - the document authors. All rights reserved. - Redistribution and use in source and binary forms, with or - without modification, is permitted pursuant to, and subject - to the license terms contained in, the Simplified BSD - License set forth in Section 4.c of the IETF Trust's Legal - Provisions Relating to IETF Documents - (http://trustee.ietf.org/license-info). - This version of this YANG module is part of RFC XXXX; see - the RFC itself for full legal notices."; - revision 2016-07-08 { - description - "Base model for Network Access Control List (ACL)."; - reference - "RFC XXXX: Network Access Control List (ACL) - YANG Data Model"; - } - identity acl-base { - description - "Base Access Control List type for all Access Control List type - identifiers."; - } - identity ipv4-acl { - base acl:acl-base; - description - "ACL that primarily matches on fields from the IPv4 header - (e.g. IPv4 destination address) and layer 4 headers (e.g. TCP - destination port). An acl of type ipv4-acl does not contain - matches on fields in the ethernet header or the IPv6 header."; - } - identity ipv6-acl { - base acl:acl-base; - description - "ACL that primarily matches on fields from the IPv6 header - (e.g. IPv6 destination address) and layer 4 headers (e.g. TCP - destination port). An acl of type ipv6-acl does not contain - matches on fields in the ethernet header or the IPv4 header."; - } - identity eth-acl { - base acl:acl-base; - description - "ACL that primarily matches on fields in the ethernet header, - like 10/100/1000baseT or WiFi Access Control List. An acl of - type eth-acl does not contain matches on fields in the IPv4 - header, IPv6 header or layer 4 headers."; - } - typedef acl-type { - type identityref { - base acl:acl-base; - } - description - "This type is used to refer to an Access Control List - (ACL) type"; - } - typedef access-control-list-ref { - type leafref { - path "/access-lists/acl/acl-name"; - } - description - "This type is used by data models that need to reference an - Access Control List"; - } - container access-lists { - description - "This is a top level container for Access Control Lists. - It can have one or more Access Control Lists."; - list acl { - key "acl-type acl-name"; - description - "An Access Control List(ACL) is an ordered list of - Access List Entries (ACE). Each Access Control Entry has a - list of match criteria and a list of actions. - Since there are several kinds of Access Control Lists - implemented with different attributes for - different vendors, this - model accommodates customizing Access Control Lists for - each kind and for each vendor."; - leaf acl-name { - type string; - description - "The name of access-list. A device MAY restrict the length - and value of this name, possibly space and special - characters are not allowed."; - } - leaf acl-type { - type acl-type; - description - "Type of access control list. Indicates the primary intended - type of match criteria (e.g. ethernet, IPv4, IPv6, mixed, etc) - used in the list instance."; - } - container acl-oper-data { - config false; - description - "Overall Access Control List operational data"; - } - container access-list-entries { - description - "The access-list-entries container contains - a list of access-list-entries(ACE)."; - list ace { - key "rule-name"; - ordered-by user; - description - "List of access list entries(ACE)"; - leaf rule-name { - type string; - description - "A unique name identifying this Access List - Entry(ACE)."; - } - container matches { - description - "Definitions for match criteria for this Access List - Entry."; - choice ace-type { - description - "Type of access list entry."; - case ace-ip { - description "IP Access List Entry."; - choice ace-ip-version { - description - "IP version used in this Access List Entry."; - case ace-ipv4 { - uses packet-fields:acl-ipv4-header-fields; - } - case ace-ipv6 { - uses packet-fields:acl-ipv6-header-fields; - } - } - uses packet-fields:acl-ip-header-fields; - } - case ace-eth { - description - "Ethernet Access List entry."; - uses packet-fields:acl-eth-header-fields; - } - } - } - container actions { - description - "Definitions of action criteria for this Access List - Entry."; - choice packet-handling { - default "deny"; - description - "Packet handling action."; - case deny { - leaf deny { - type empty; - description - "Deny action."; - } - } - case permit { - leaf permit { - type empty; - description - "Permit action."; - } - } - } - } - container ace-oper-data { - config false; - description - "Operational data for this Access List Entry."; - leaf match-counter { - type yang:counter64; - description - "Number of matches for this Access List Entry"; - } - } - } - } - } - } -} diff --git a/v3po/api/src/main/yang/ietf-packet-fields.yang b/v3po/api/src/main/yang/ietf-packet-fields.yang deleted file mode 100644 index 0b1ce5cdd..000000000 --- a/v3po/api/src/main/yang/ietf-packet-fields.yang +++ /dev/null @@ -1,180 +0,0 @@ -module ietf-packet-fields { - yang-version 1.1; - namespace "urn:ietf:params:xml:ns:yang:ietf-packet-fields"; - prefix packet-fields; - import ietf-inet-types { - prefix inet; - } - import ietf-yang-types { - prefix yang; - } - organization "IETF NETMOD (NETCONF Data Modeling Language) Working - Group"; - contact - "WG Web: http://tools.ietf.org/wg/netmod/ - WG List: netmod@ietf.org - WG Chair: Juergen Schoenwaelder - j.schoenwaelder@jacobs-university.de - WG Chair: Tom Nadeau - tnadeau@lucidvision.com - Editor: Dean Bogdanovic - deanb@juniper.net - Editor: Kiran Agrahara Sreenivasa - kkoushik@cisco.com - Editor: Lisa Huang - lyihuang16@gmail.com - Editor: Dana Blair - dblair@cisco.com"; - description - "This YANG module defines groupings that are used by - ietf-access-control-list YANG module. Their usage is not - limited to ietf-access-control-list and can be - used anywhere as applicable. - Copyright (c) 2015 IETF Trust and the persons identified as - the document authors. All rights reserved. - Redistribution and use in source and binary forms, with or - without modification, is permitted pursuant to, and subject - to the license terms contained in, the Simplified BSD - License set forth in Section 4.c of the IETF Trust's Legal - Provisions Relating to IETF Documents - (http://trustee.ietf.org/license-info). - This version of this YANG module is part of RFC XXXX; see - the RFC itself for full legal notices."; - revision 2016-07-08 { - description - "Initial version of packet fields used by - ietf-access-control-list"; - reference - "RFC XXXX: Network Access Control List (ACL) - YANG Data Model"; - } - grouping acl-transport-header-fields { - description - "Transport header fields"; - container source-port-range { - presence "Enables setting source port range"; - description - "Inclusive range representing source ports to be used. - When only lower-port is present, it represents a single port."; - leaf lower-port { - type inet:port-number; - mandatory true; - description - "Lower boundary for port."; - } - leaf upper-port { - type inet:port-number; - must ". >= ../lower-port" { - error-message - "The upper-port must be greater than or equal to lower-port"; - } - description - "Upper boundary for port . If existing, the upper port - must be greater or equal to lower-port."; - } - } - container destination-port-range { - presence "Enables setting destination port range"; - description - "Inclusive range representing destination ports to be used. When - only lower-port is present, it represents a single port."; - leaf lower-port { - type inet:port-number; - mandatory true; - description - "Lower boundary for port."; - } - leaf upper-port { - type inet:port-number; - must ". >= ../lower-port" { - error-message - "The upper-port must be greater than or equal to lower-port"; - } - - description - "Upper boundary for port. If existing, the upper port must - be greater or equal to lower-port"; - } - } - } - grouping acl-ip-header-fields { - description - "IP header fields common to ipv4 and ipv6"; - leaf dscp { - type inet:dscp; - description - "Value of dscp."; - } - leaf protocol { - type uint8; - description - "Internet Protocol number."; - } - uses acl-transport-header-fields; - } - grouping acl-ipv4-header-fields { - description - "Fields in IPv4 header."; - leaf destination-ipv4-network { - type inet:ipv4-prefix; - description - "Destination IPv4 address prefix."; - } - leaf source-ipv4-network { - type inet:ipv4-prefix; - description - "Source IPv4 address prefix."; - } - } - grouping acl-ipv6-header-fields { - description - "Fields in IPv6 header"; - leaf destination-ipv6-network { - type inet:ipv6-prefix; - description - "Destination IPv6 address prefix."; - } - leaf source-ipv6-network { - type inet:ipv6-prefix; - description - "Source IPv6 address prefix."; - } - leaf flow-label { - type inet:ipv6-flow-label; - description - "IPv6 Flow label."; - } - reference - "RFC 4291: IP Version 6 Addressing Architecture - RFC 4007: IPv6 Scoped Address Architecture - RFC 5952: A Recommendation for IPv6 Address Text Representation"; - } - grouping acl-eth-header-fields { - description - "Fields in Ethernet header."; - leaf destination-mac-address { - type yang:mac-address; - description - "Destination IEEE 802 MAC address."; - } - leaf destination-mac-address-mask { - type yang:mac-address; - description - "Destination IEEE 802 MAC address mask."; - } - leaf source-mac-address { - type yang:mac-address; - description - "Source IEEE 802 MAC address."; - } - leaf source-mac-address-mask { - type yang:mac-address; - description - "Source IEEE 802 MAC address mask."; - } - reference - "IEEE 802: IEEE Standard for Local and Metropolitan Area - Networks: Overview and Architecture."; - } - -} \ No newline at end of file diff --git a/v3po/api/src/main/yang/v3po.yang b/v3po/api/src/main/yang/v3po.yang index 14ca14d92..f5f6b3293 100644 --- a/v3po/api/src/main/yang/v3po.yang +++ b/v3po/api/src/main/yang/v3po.yang @@ -36,9 +36,6 @@ module v3po { import yang-ext { prefix "ext"; } - import vpp-classfier-acl { - prefix "vpp-classfier-acl"; - } typedef bridge-domain-ref { type leafref { @@ -583,24 +580,6 @@ module v3po { uses vxlan-gpe-base-attributes; } - container acl { - container ingress { - uses vpp-classfier-acl:acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:acl-base-attributes; - } - } - - container ietf-acl { - container ingress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - } - container span { uses span-attributes; } @@ -678,24 +657,6 @@ module v3po { uses l2-base-attributes; } - container acl { - container ingress { - uses vpp-classfier-acl:acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:acl-base-attributes; - } - } - - container ietf-acl { - container ingress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - } - container span { uses span-attributes; } diff --git a/v3po/api/src/main/yang/vpp-classfier-acl.yang b/v3po/api/src/main/yang/vpp-classfier-acl.yang deleted file mode 100644 index 42550d95d..000000000 --- a/v3po/api/src/main/yang/vpp-classfier-acl.yang +++ /dev/null @@ -1,163 +0,0 @@ -module vpp-classfier-acl { - yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:vpp:classfier:acl"; - prefix "vpp-classfier-acl"; - - revision "2016-12-14" { - description - "Initial revision of vpp-classfier-acl model."; - } - - import ietf-access-control-list { - prefix "acl"; - } - - import vpp-classifier { - prefix "vpp-classifier"; - } - - import yang-ext { - prefix "ext"; - } - - import ietf-packet-fields { - prefix packet-fields; - } - - identity mixed-acl { - base acl:acl-base; - description - "ACL that can match on any of L2/L3/L4 fields."; - } - - typedef interface-mode { - type enumeration { - enum "l2"; - enum "l3"; - } - } - - grouping acl-base-attributes { - description - "Defines references to classify tables. - At least one table reference should be specified."; - container l2-acl { - leaf classify-table { - type vpp-classifier:classify-table-ref; - description - "An L2 ACL table"; - } - } - container ip4-acl { - leaf classify-table { - type vpp-classifier:classify-table-ref; - description - "An IPv4 ACL table"; - } - } - container ip6-acl { - leaf classify-table { - type vpp-classifier:classify-table-ref; - description - "An IPv6 ACL table"; - } - } - } - - grouping ietf-acl-base-attributes { - description - "Provides limited support for ietf-acl model."; - - container access-lists { - description - "Defines references to ietf-acl lists. - ACLs are translated into classify tables and sessions when assigned to interface. - - In case of L2 interfaces, acls are translated into a chain of classify tables and assigned as L2 table. - In case of L3 interfaces, acls are translated into ip4 and ip6 chains (eth only rules go to both chains, - rest - depending on ip-version). - User ordering is preserved in both cases. - - Assignment update/delete removes all created tables and sessions and repeats process described above. - Update/delete of ACL lists referenced here is not permitted (assignment needs to be removed first). - - Read is supported only for acls that were created and assigned by Honeycomb agent - (corresponding metadata is present). - - Extensions: - - mixing ACEs of different type in one list is permited - - mixing L2/L3/L4 rules in one ACE is permited - - Limitations (due to vpp limitations): - - egress rules are currently ignored (HONEYCOMB-234) - - L4 rules support is limited (every port pair from provided ranges is translated to single classify - session; which can very slow or even crash vpp if ranges are big, see HONEYCOMB-260) - - ace-ip-version needs to be provided for all aces (consequence of posibility to mix ACEs of different types, - and vpp classfier api limitation: common header fields for IP4/IP6 have different offsets) - - L2 rules on L3 interfaces are applied only to IP traffic (vpp classfier limitation) - - vlan tags are supported only for sub-interfaces defined as exact-match"; - - list acl { - key "type name"; - ordered-by user; - - leaf type { - type acl:acl-type; - } - - leaf name { - type acl:access-control-list-ref; - } - } - - leaf default-action { - type enumeration { - enum "deny"; - enum "permit"; - } - default "deny"; - description - "Default action applied to packet that does not match any of rules defined in assigned ACLs. - It is translated to single classify table and applied at the end of assigned chains."; - } - - leaf mode { - type interface-mode; - default l3; - description - "The way ACLs are translated depends on the interface mode. - In case of L2 interfaces (bridge/interconnection) - classify tables are assigned as l2_table using input_acl_set_interface (ether type matching is automatically - added in case of L3 rules). - In case of L3 interfaces, classify tables are assigned as ip4/ip6 tables. - - It is the user responsibility to choose mode that matches target interface. - "; - } - } - } - - augment /acl:access-lists/acl:acl/acl:access-list-entries/acl:ace/acl:matches/acl:ace-type { - ext:augment-identifier "vpp-classfier-acl-type-augmentation"; - case ace-ip-and-eth { - description - "Access List entry that can define both ip and eth rules."; - container ace-ip-and-eth-nodes { - - choice ace-ip-version { - description - "IP version used in this Access List Entry."; - mandatory true; - case ace-ipv4 { - uses packet-fields:acl-ipv4-header-fields; - } - case ace-ipv6 { - uses packet-fields:acl-ipv6-header-fields; - } - } - uses packet-fields:acl-ip-header-fields; - uses packet-fields:acl-eth-header-fields; - } - } - } -} \ No newline at end of file diff --git a/v3po/api/src/main/yang/vpp-classifier-context.yang b/v3po/api/src/main/yang/vpp-classifier-context.yang deleted file mode 100644 index 01eae862d..000000000 --- a/v3po/api/src/main/yang/vpp-classifier-context.yang +++ /dev/null @@ -1,68 +0,0 @@ -module vpp-classifier-context { - yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:vpp:classifier"; - prefix "vpp-classifier-context"; - - description - "This module contains vpp classfier metadata definition"; - - revision "2016-09-09" { - description - "Initial revision."; - } - - container vpp-classifier-context { - - config "false"; - - description - "Classify tables and sessions contain relative node indexes. Management agent like Honeycomb, - needs to use node names instead (indexes might change after vpp restart). - VPP does not provide relative index to node name conversion (https://jira.fd.io/browse/VPP-219), - also finding base node that is needed to perform the conversion - is not allways possible (https://jira.fd.io/browse/VPP-220). - - Therefore Honeycomb needs to provide relative node to index mapping. - "; - - list classify-table-context { - key "name"; - unique "index"; - - leaf name { - type string; - description - "Name of the classify table."; - } - - leaf index { - type int32; - description - "Classify table index used by VPP."; - } - - leaf classifier-node-name { - type string; - description - "Name of VPP node the table is defined for."; - } - - list node-context { - key "name"; - unique "index"; - - leaf name { - type string; - description - "Name of vpp node (neighbour of classifier-node-name)"; - } - - leaf index { - type int32; - description - "Inted of the vpp node relative to classifier-node-name"; - } - } - } - } -} \ No newline at end of file diff --git a/v3po/api/src/main/yang/vpp-classifier.yang b/v3po/api/src/main/yang/vpp-classifier.yang deleted file mode 100644 index beb4def85..000000000 --- a/v3po/api/src/main/yang/vpp-classifier.yang +++ /dev/null @@ -1,215 +0,0 @@ -module vpp-classifier { - yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:vpp:classifier"; - prefix "vpp-classifier"; - - revision "2016-12-14" { - description - "This revision adds the following new features: - - updates order of union types for opaque-index"; - } - - revision "2015-06-03" { - description - "Initial revision of model for VPP packet classifier. - The model can be used ony to implement ACLs. - Other classify table usages are not supported yet, - see https://jira.fd.io/browse/VPP-203 for details."; - reference - "https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers"; - } - - import ietf-yang-types { - prefix "yang"; - } - - typedef classify-table-ref { - type leafref { - path "/vpp-classifier:vpp-classifier/classify-table/name"; - } - description - "This type is used by data models that need to reference - configured classify tables."; - } - - typedef packet-handling-action { - type enumeration { - enum "deny" { - // by VPP convention, first neighbour node (at index 0) is a drop node - value 0; - } - enum "permit" { - value -1; // indicates that the next node not set - } - } - } - - typedef vpp-node-name { - type string; - } - - typedef vpp-node { - type union { - type packet-handling-action; - type vpp-node-name; - } - description - "Defines VPP node reference using packet handling action or relative node name - (if definition in terms of packet handling action is not possible)."; - } - - typedef opaque-index { - type union { - type uint32; - type vpp-node; - } - description - "Defines opaque-index type - metadata that can be attached to session-hit packets. - Vpp nodes can't be referenced by index, because node indexes might change after vpp restart."; - } - - grouping classify-session-attributes { - description - "Defines classify session attributes that are mapped to classify_add_del_session - and classify_session_details messages parameters."; - - leaf hit_next { - type vpp-node; - mandatory true; - description - "Vpp node to which packet will be send when it produces a match."; - } - leaf opaque_index { - type opaque-index; - } - leaf advance { - type int32; - default 0; - description - "Nodes like ip4/6-classify use the parameter to \"consume\" networking layer. - Example: tunnel decapsulation."; - } - } - - grouping classify-table-base-attributes { - description - "Defines classify table attributes that are mapped to classify_add_del_table message parameters."; - - leaf classifier-node { - type vpp-node-name; - description - "Name of VPP node the table is defined for."; - } - leaf nbuckets { - mandatory true; - type uint32; - description - "Used by classifier hashing algorithm. It is not possible to resize the bucket array, - therefore suggested value is approximate number of expected entries."; - } - leaf skip_n_vectors { - type uint32; - default 0; - description - "Number of 16 byte vectors to be skipped before applying mask."; - } - leaf next_table { - type classify-table-ref; - description - "Reference to the next classify table. Required when multiple table chaining is used."; - } - leaf miss_next { - mandatory true; - type vpp-node; - description - "Vpp node to which packet will be send when it falis to produce a match"; - } - leaf mask { - type yang:hex-string; - mandatory true; - description - "Defines match mask (multiple of 16 bytes)"; - } - - list classify-session { - key "match"; - - leaf match { - type yang:hex-string; - description - "Defines actual value to be matched that is - a byte vector, which length is multiple of 16 bytes"; - - must "string-length(match) = string-length(../../mask)" { - error-message - "Match length is not equal to classify table mask length."; - description - "Match length must be equal to classify table mask length."; - } - } - - uses classify-session-attributes; - } - } - - grouping classify-table-config-attributes { - description - "Defines classify table config only attributes (present in classify_add_del_table message - but not in classify_table_info_reply)."; - - // TODO(HC2VPP-10): move to classify-table-base-attributes - // after https://jira.fd.io/browse/VPP-208 is fixed - leaf memory_size { - type uint32; - // mandatory true; // TODO(HC2VPP-10): uncomment - description - "Memory size for classify table and its entries."; - } - } - - grouping classify-table-operational-attributes { - description - "Defines classify table operational attributes (present in classify_table_info_reply message - but not in classify_add_del_table)."; - - leaf active_sessions { - type uint32; - config false; - description - "Number of sessions defined for the classify table."; - } - } - - container vpp-classifier { - list classify-table { - key "name"; - - leaf name { - type string; - description - "Hides classify table identifier managed by vpp."; - } - - uses classify-table-base-attributes; - uses classify-table-config-attributes; - } - } - - container vpp-classifier-state { - config false; - - list classify-table { - key "name"; - - leaf name { - type string; - description - "Hides classify table identifier managed by vpp."; - } - - uses classify-table-base-attributes; - uses classify-table-operational-attributes; - } - } - -} diff --git a/v3po/api/src/main/yang/vpp-vlan.yang b/v3po/api/src/main/yang/vpp-vlan.yang index 383e70f1a..f4fac56b8 100644 --- a/v3po/api/src/main/yang/vpp-vlan.yang +++ b/v3po/api/src/main/yang/vpp-vlan.yang @@ -33,9 +33,6 @@ module vpp-vlan { import v3po { prefix v3po; } - import vpp-classfier-acl { - prefix vpp-classfier-acl; - } typedef sub-interface-status { type enumeration { @@ -167,24 +164,6 @@ module vpp-vlan { uses tag-rewrite; } } - - container acl { - container ingress { - uses vpp-classfier-acl:acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:acl-base-attributes; - } - } - - container ietf-acl { - container ingress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - container egress { - uses vpp-classfier-acl:ietf-acl-base-attributes; - } - } } grouping sub-interface-config-attributes { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModule.java deleted file mode 100644 index dc21a2911..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModule.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.v3po; - -import com.google.inject.AbstractModule; -import com.google.inject.multibindings.Multibinder; -import io.fd.hc2vpp.v3po.factory.AclWriterFactory; -import io.fd.hc2vpp.v3po.factory.EgressIetfAClWriterProvider; -import io.fd.hc2vpp.v3po.factory.IngressIetfAClWriterProvider; -import io.fd.hc2vpp.v3po.factory.InterfacesClassifierIetfAclWriterFactory; -import io.fd.hc2vpp.v3po.factory.SubInterfacesClassifierIetfAclWriterFactory; -import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import net.jmob.guice.conf.core.ConfigurationModule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ClassifierIetfAclModule extends AbstractModule { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifierIetfAclModule.class); - - @Override - protected void configure() { - LOG.debug("Installing VppClassifierAcl module"); - install(ConfigurationModule.create()); - - // Utils - bind(IngressIetfAclWriter.class).toProvider(IngressIetfAClWriterProvider.class); - bind(EgressIetfAclWriter.class).toProvider(EgressIetfAClWriterProvider.class); - - // Writers - final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); - writerFactoryBinder.addBinding().to(AclWriterFactory.class); - writerFactoryBinder.addBinding().to(InterfacesClassifierIetfAclWriterFactory.class); - writerFactoryBinder.addBinding().to(SubInterfacesClassifierIetfAclWriterFactory.class); - - LOG.info("Module VppClassifierAcl module successfully configured"); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java index fda7498f8..42e406eb1 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java @@ -21,8 +21,6 @@ import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.cfgattrs.V3poConfiguration; -import io.fd.hc2vpp.v3po.factory.EgressIetfAClWriterProvider; -import io.fd.hc2vpp.v3po.factory.IngressIetfAClWriterProvider; import io.fd.hc2vpp.v3po.factory.InterfacesStateReaderFactory; import io.fd.hc2vpp.v3po.factory.InterfacesWriterFactory; import io.fd.hc2vpp.v3po.factory.Ipv4StateReaderFactory; @@ -36,16 +34,10 @@ import io.fd.hc2vpp.v3po.factory.SubInterfaceStateIpv4ReaderFactory; import io.fd.hc2vpp.v3po.factory.SubInterfaceStateIpv6ReaderFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceAugmentationWriterFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceStateAugmentationReaderFactory; -import io.fd.hc2vpp.v3po.factory.VppClassifierHoneycombWriterFactory; -import io.fd.hc2vpp.v3po.factory.VppClassifierReaderFactory; import io.fd.hc2vpp.v3po.factory.VppHoneycombWriterFactory; import io.fd.hc2vpp.v3po.factory.VppStateHoneycombReaderFactory; -import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; import io.fd.hc2vpp.v3po.notification.InterfaceChangeNotificationProducer; import io.fd.hc2vpp.v3po.rpc.CliInbandService; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManagerImpl; import io.fd.honeycomb.notification.ManagedNotificationProducer; import io.fd.honeycomb.rpc.RpcService; import io.fd.honeycomb.translate.read.ReaderFactory; @@ -74,16 +66,11 @@ public class V3poModule extends AbstractModule { bind(NamingContext.class) .annotatedWith(Names.named("bridge-domain-context")) .toInstance(new NamingContext("bridge-domain-", "bridge-domain-context")); - bind(VppClassifierContextManager.class) - .annotatedWith(Names.named("classify-table-context")) - .toInstance(new VppClassifierContextManagerImpl("classify-table-")); // Executor needed for keepalives bind(ScheduledExecutorService.class).toInstance(Executors.newScheduledThreadPool(1)); - // Utils - bind(IngressIetfAclWriter.class).toProvider(IngressIetfAClWriterProvider.class); - bind(EgressIetfAclWriter.class).toProvider(EgressIetfAClWriterProvider.class); + // Context utility for deleted interfaces bind(DisabledInterfacesManager.class).toInstance(new DisabledInterfacesManager()); @@ -92,11 +79,10 @@ public class V3poModule extends AbstractModule { readerFactoryBinder.addBinding().to(InterfacesStateReaderFactory.class); readerFactoryBinder.addBinding().to(SubinterfaceStateAugmentationReaderFactory.class); readerFactoryBinder.addBinding().to(VppStateHoneycombReaderFactory.class); - readerFactoryBinder.addBinding().to(VppClassifierReaderFactory.class); + // Expose disabled interfaces in operational data readerFactoryBinder.addBinding().to(DisabledInterfacesManager.ContextsReaderFactory.class); - // Expose vpp-classfier-context interfaces in operational data - readerFactoryBinder.addBinding().to(VppClassifierContextManagerImpl.ContextsReaderFactory.class); + //Ipv4/Ipv6 readerFactoryBinder.addBinding().to(Ipv4StateReaderFactory.class); readerFactoryBinder.addBinding().to(Ipv6StateReaderFactory.class); @@ -109,7 +95,6 @@ public class V3poModule extends AbstractModule { writerFactoryBinder.addBinding().to(ProxyArpWriterFactory.class); writerFactoryBinder.addBinding().to(SubinterfaceAugmentationWriterFactory.class); writerFactoryBinder.addBinding().to(VppHoneycombWriterFactory.class); - writerFactoryBinder.addBinding().to(VppClassifierHoneycombWriterFactory.class); //Ipv4/Ipv6 writerFactoryBinder.addBinding().to(Ipv4WriterFactory.class); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/AclWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/AclWriterFactory.java deleted file mode 100644 index 235e7da2a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/AclWriterFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.v3po.factory; - -import static io.fd.hc2vpp.v3po.factory.InterfacesClassifierIetfAclWriterFactory.IETF_ACL_ID; -import static io.fd.hc2vpp.v3po.factory.SubInterfacesClassifierIetfAclWriterFactory.SUBIF_IETF_ACL_ID; - -import com.google.common.collect.Sets; -import io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -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.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodes; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class AclWriterFactory implements WriterFactory { - - public static final InstanceIdentifier ACL_ID = - InstanceIdentifier.create(AccessLists.class).child(Acl.class); - - @Override - public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { - - final InstanceIdentifier aclIdRelative = InstanceIdentifier.create(Acl.class); - - final InstanceIdentifier aceId = aclIdRelative.child(AccessListEntries.class).child(Ace.class); - final InstanceIdentifier actionsId = aceId.child(Actions.class); - final InstanceIdentifier matchesId = aceId.child(Matches.class); - final InstanceIdentifier aceIpAndEthId = matchesId.child(AceIpAndEthNodes.class); - final InstanceIdentifier srcPortId = matchesId.child((Class)SourcePortRange.class); - final InstanceIdentifier dstPortId = matchesId.child((Class)DestinationPortRange.class); - - registry.subtreeAddBefore(Sets.newHashSet(aceId, actionsId, matchesId, aceIpAndEthId, srcPortId, dstPortId), - new GenericListWriter<>(ACL_ID, new IetfAclWriter()), - Sets.newHashSet(IETF_ACL_ID, SUBIF_IETF_ACL_ID)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/EgressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/EgressIetfAClWriterProvider.java deleted file mode 100644 index 9ccc1d8e5..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/EgressIetfAClWriterProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManagerImpl; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; - -public class EgressIetfAClWriterProvider implements Provider { - - private final FutureJVppCore jvpp; - - @Inject - public EgressIetfAClWriterProvider(final FutureJVppCore jvpp) { - this.jvpp = jvpp; - } - - @Override - public EgressIetfAclWriter get() { - return new EgressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Egress)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/IngressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/IngressIetfAClWriterProvider.java deleted file mode 100644 index be6a2a3fb..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/IngressIetfAClWriterProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManagerImpl; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; - -public class IngressIetfAClWriterProvider implements Provider { - - private final FutureJVppCore jvpp; - - @Inject - public IngressIetfAClWriterProvider(final FutureJVppCore jvpp) { - this.jvpp = jvpp; - } - - @Override - public IngressIetfAclWriter get() { - return new IngressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Ingress)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesClassifierIetfAclWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesClassifierIetfAclWriterFactory.java deleted file mode 100644 index b463e47c6..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesClassifierIetfAclWriterFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.honeycomb.translate.impl.write.GenericWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class InterfacesClassifierIetfAclWriterFactory implements WriterFactory { - - public static final InstanceIdentifier IFC_ID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class); - public static final InstanceIdentifier VPP_IFC_AUG_ID = - IFC_ID.augmentation(VppInterfaceAugmentation.class); - public static final InstanceIdentifier IETF_ACL_ID = VPP_IFC_AUG_ID.child(IetfAcl.class); - public static final InstanceIdentifier INGRESS_IETF_ACL_ID = IETF_ACL_ID.child(Ingress.class); - public static final InstanceIdentifier EGRESS_IETF_ACL_ID = IETF_ACL_ID.child(Egress.class); - - private final IngressIetfAclWriter ingressAclWriter; - private final EgressIetfAclWriter egressAclWriter; - private final NamingContext ifcNamingContext; - - @Inject - public InterfacesClassifierIetfAclWriterFactory(final IngressIetfAclWriter ingressAclWriter, - final EgressIetfAclWriter egressAclWriter, - @Named("interface-context") final NamingContext interfaceContextDependency) { - this.ingressAclWriter = ingressAclWriter; - this.egressAclWriter = egressAclWriter; - this.ifcNamingContext = interfaceContextDependency; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Ingress IETF-ACL, also handles AccessLists and Acl: - final InstanceIdentifier accessListsIdIngress = - InstanceIdentifier.create(Ingress.class).child(AccessLists.class); - final InstanceIdentifier aclIdIngress = accessListsIdIngress.child(Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdIngress, aclIdIngress), - new GenericWriter<>(INGRESS_IETF_ACL_ID, - new io.fd.hc2vpp.v3po.interfaces.acl.ingress.IetfAclCustomizer(ingressAclWriter, ifcNamingContext))); - - // Ingress IETF-ACL, also handles AccessLists and Acl: - final InstanceIdentifier accessListsIdEgress = - InstanceIdentifier.create(Egress.class).child(AccessLists.class); - final InstanceIdentifier aclIdEgress = accessListsIdEgress.child(Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdEgress, aclIdEgress), - new GenericWriter<>(EGRESS_IETF_ACL_ID, - new io.fd.hc2vpp.v3po.interfaces.acl.egress.IetfAclCustomizer(egressAclWriter, ifcNamingContext))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java index 91294d05f..67684a1dd 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java @@ -17,7 +17,6 @@ package io.fd.hc2vpp.v3po.factory; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import com.google.inject.Inject; import com.google.inject.name.Named; import io.fd.hc2vpp.common.translate.util.NamingContext; @@ -31,10 +30,8 @@ import io.fd.hc2vpp.v3po.interfacesstate.TapCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VhostUserCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VxlanCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VxlanGpeCustomizer; -import io.fd.hc2vpp.v3po.interfacesstate.acl.ingress.AclCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.pbb.PbbRewriteStateCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.span.MirroredInterfacesCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.impl.read.GenericInitReader; import io.fd.honeycomb.translate.impl.read.GenericReader; @@ -46,8 +43,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; @@ -58,12 +53,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.span.attributes.MirroredInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.span.attributes.mirrored.interfaces.MirroredInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; @@ -73,7 +64,6 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { private final NamingContext ifcNamingCtx; private final NamingContext bdNamingCtx; - private final VppClassifierContextManager classifyContext; private final DisabledInterfacesManager ifcDisableContext; private final FutureJVppCore jvpp; @@ -85,12 +75,10 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { public InterfacesStateReaderFactory(final FutureJVppCore jvpp, @Named("interface-context") final NamingContext ifcNamingCtx, @Named("bridge-domain-context") final NamingContext bdNamingCtx, - @Named("classify-table-context") final VppClassifierContextManager classifyContext, final DisabledInterfacesManager ifcDisableContext) { this.jvpp = jvpp; this.ifcNamingCtx = ifcNamingCtx; this.bdNamingCtx = bdNamingCtx; - this.classifyContext = classifyContext; this.ifcDisableContext = ifcDisableContext; } @@ -135,18 +123,6 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { // L2 registry.add(new GenericInitReader<>(vppIfcAugId.child(L2.class), new L2Customizer(jvpp, ifcNamingCtx, bdNamingCtx))); - - // Acl(Structural) - final InstanceIdentifier aclIid = vppIfcAugId.child(Acl.class); - registry.addStructuralReader(aclIid, AclBuilder.class); - // Ingress(Subtree) - final InstanceIdentifier ingressIdRelative = InstanceIdentifier.create(Ingress.class); - registry.subtreeAdd( - Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), - ingressIdRelative.child(Ip6Acl.class)), - new GenericInitReader<>(aclIid.child(Ingress.class), - new AclCustomizer(jvpp, ifcNamingCtx, classifyContext))); - // Span final InstanceIdentifier spanId = vppIfcAugId.child(Span.class); registry.addStructuralReader(spanId, SpanBuilder.class); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java index 3dd7bb323..f9baf7c0a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java @@ -16,9 +16,6 @@ package io.fd.hc2vpp.v3po.factory; -import static io.fd.hc2vpp.v3po.factory.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; -import static io.fd.hc2vpp.v3po.factory.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; - import com.google.common.collect.Sets; import com.google.inject.Inject; import com.google.inject.name.Named; @@ -34,10 +31,8 @@ import io.fd.hc2vpp.v3po.interfaces.TapCustomizer; import io.fd.hc2vpp.v3po.interfaces.VhostUserCustomizer; import io.fd.hc2vpp.v3po.interfaces.VxlanCustomizer; import io.fd.hc2vpp.v3po.interfaces.VxlanGpeCustomizer; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.AclCustomizer; import io.fd.hc2vpp.v3po.interfaces.pbb.PbbRewriteCustomizer; import io.fd.hc2vpp.v3po.interfaces.span.MirroredInterfaceCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; import io.fd.honeycomb.translate.impl.write.GenericListWriter; import io.fd.honeycomb.translate.impl.write.GenericWriter; import io.fd.honeycomb.translate.write.WriterFactory; @@ -47,7 +42,6 @@ import java.util.Set; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; @@ -58,12 +52,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.span.attributes.MirroredInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.span.attributes.mirrored.interfaces.MirroredInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -74,27 +64,22 @@ public final class InterfacesWriterFactory implements WriterFactory { InstanceIdentifier.create(Interfaces.class).child(Interface.class); public static final InstanceIdentifier VPP_IFC_AUG_ID = IFC_ID.augmentation(VppInterfaceAugmentation.class); - public static final InstanceIdentifier ACL_ID = VPP_IFC_AUG_ID.child(Acl.class); - public static final InstanceIdentifier INGRESS_ACL_ID = ACL_ID.child(Ingress.class); public static final InstanceIdentifier L2_ID = VPP_IFC_AUG_ID.child(L2.class); private final FutureJVppCore jvpp; private final NamingContext bdNamingContext; private final NamingContext ifcNamingContext; - private final VppClassifierContextManager classifyTableContext; private final DisabledInterfacesManager ifcDisableContext; @Inject public InterfacesWriterFactory(final FutureJVppCore vppJvppIfcDependency, @Named("bridge-domain-context") final NamingContext bridgeDomainContextDependency, @Named("interface-context") final NamingContext interfaceContextDependency, - @Named("classify-table-context") final VppClassifierContextManager classifyTableContext, final DisabledInterfacesManager ifcDisableContext) { this.jvpp = vppJvppIfcDependency; this.bdNamingContext = bridgeDomainContextDependency; this.ifcNamingContext = interfaceContextDependency; this.ifcDisableContext = ifcDisableContext; - this.classifyTableContext = classifyTableContext; } @Override @@ -149,16 +134,6 @@ public final class InterfacesWriterFactory implements WriterFactory { // L2(Execute only after subinterface (and all other ifc types) = registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcNamingContext, bdNamingContext)), SubinterfaceAugmentationWriterFactory.SUB_IFC_ID); - // Ingress (execute after classify table and session writers) - // also handles L2Acl, Ip4Acl and Ip6Acl: - final InstanceIdentifier ingressId = InstanceIdentifier.create(Ingress.class); - registry - .subtreeAddAfter( - Sets.newHashSet(ingressId.child(L2Acl.class), ingressId.child(Ip4Acl.class), - ingressId.child(Ip6Acl.class)), - new GenericWriter<>(INGRESS_ACL_ID, - new AclCustomizer(jvpp, ifcNamingContext, classifyTableContext)), - Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)); // Span writers // Mirrored interfaces diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubInterfacesClassifierIetfAclWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubInterfacesClassifierIetfAclWriterFactory.java deleted file mode 100644 index 5748f081b..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubInterfacesClassifierIetfAclWriterFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.SubInterfaceIetfAclCustomizer; -import io.fd.honeycomb.translate.impl.write.GenericWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class SubInterfacesClassifierIetfAclWriterFactory implements WriterFactory { - - public static final InstanceIdentifier SUB_IFC_AUG_ID = - InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); - public static final InstanceIdentifier SUB_IFC_ID = - SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); - public static final InstanceIdentifier SUBIF_IETF_ACL_ID = SUB_IFC_ID.child(IetfAcl.class); - public static final InstanceIdentifier SUBIF_INGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child(Ingress.class); - public static final InstanceIdentifier SUBIF_EGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child(Egress.class); - - private final IngressIetfAclWriter ingressAclWriter; - private final EgressIetfAclWriter egressAclWriter; - private final NamingContext ifcContext; - - @Inject - public SubInterfacesClassifierIetfAclWriterFactory(final IngressIetfAclWriter ingressAclWriter, - final EgressIetfAclWriter egressAclWriter, - @Named("interface-context") final NamingContext ifcContext) { - this.ingressAclWriter = ingressAclWriter; - this.egressAclWriter = egressAclWriter; - this.ifcContext = ifcContext; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Ingress IETF-ACL, also handles AccessLists and Acl: - final InstanceIdentifier accessListsIdIngress = - InstanceIdentifier.create(Ingress.class).child(AccessLists.class); - final InstanceIdentifier aclIdIngress = accessListsIdIngress.child(Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdIngress, aclIdIngress), - new GenericWriter<>(SUBIF_INGRESS_IETF_ACL_ID, - new SubInterfaceIetfAclCustomizer(ingressAclWriter, ifcContext))); - - // Egress IETF-ACL, also handles AccessLists and Acl: - final InstanceIdentifier accessListsIdEgress = - InstanceIdentifier.create(Egress.class).child(AccessLists.class); - final InstanceIdentifier aclIdEgress = accessListsIdEgress.child(Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdEgress, aclIdEgress), - new GenericWriter<>(SUBIF_EGRESS_IETF_ACL_ID, - new io.fd.hc2vpp.v3po.interfaces.acl.egress.SubInterfaceIetfAclCustomizer( - egressAclWriter, ifcContext))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java index 7a60c7dae..479649225 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java @@ -23,26 +23,19 @@ import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.interfaces.RewriteCustomizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceCustomizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceL2Customizer; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.SubInterfaceAclCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; 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 org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; @@ -53,7 +46,6 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor private final FutureJVppCore jvpp; private final NamingContext ifcContext; private final NamingContext bdContext; - private final VppClassifierContextManager classifyTableContext; public static final InstanceIdentifier SUB_IFC_AUG_ID = InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); @@ -61,18 +53,14 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); public static final InstanceIdentifier L2_ID = SUB_IFC_ID.child( L2.class); - public static final InstanceIdentifier SUBIF_ACL_ID = SUB_IFC_ID.child(Acl.class); - public static final InstanceIdentifier SUBIF_INGRESS_ACL_ID = SUBIF_ACL_ID.child(Ingress.class); @Inject public SubinterfaceAugmentationWriterFactory(final FutureJVppCore jvpp, @Named("interface-context") final NamingContext ifcContext, - @Named("bridge-domain-context") final NamingContext bdContext, - @Named("classify-table-context") final VppClassifierContextManager classifyTableContext) { + @Named("bridge-domain-context") final NamingContext bdContext) { this.jvpp = jvpp; this.ifcContext = ifcContext; this.bdContext = bdContext; - this.classifyTableContext = classifyTableContext; } @Override @@ -103,16 +91,5 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), new GenericWriter<>(rewriteId, new RewriteCustomizer(jvpp, ifcContext)), L2_ID); - - // Ingress (execute after classify table and session writers) - // also handles L2Acl, Ip4Acl and Ip6Acl: - final InstanceIdentifier aclId = InstanceIdentifier.create(Ingress.class); - registry - .subtreeAddAfter( - Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)), - new GenericWriter<>(SUBIF_INGRESS_ACL_ID, - new SubInterfaceAclCustomizer(jvpp, ifcContext, classifyTableContext)), - Sets.newHashSet(VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID, - VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID)); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java index 50233b690..76b6baa51 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java @@ -23,8 +23,6 @@ import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.interfacesstate.RewriteCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceL2Customizer; -import io.fd.hc2vpp.v3po.interfacesstate.acl.ingress.SubInterfaceAclCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.impl.read.GenericInitReader; import io.fd.honeycomb.translate.impl.read.GenericReader; @@ -32,21 +30,15 @@ import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; @@ -57,17 +49,14 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF private final FutureJVppCore jvpp; private final NamingContext ifcCtx; private final NamingContext bdCtx; - private final VppClassifierContextManager classifyCtx; @Inject public SubinterfaceStateAugmentationReaderFactory(final FutureJVppCore jvpp, @Named("interface-context") final NamingContext ifcCtx, - @Named("bridge-domain-context") final NamingContext bdCtx, - @Named("classify-table-context") final VppClassifierContextManager classifyCtx) { + @Named("bridge-domain-context") final NamingContext bdCtx) { this.jvpp = jvpp; this.ifcCtx = ifcCtx; this.bdCtx = bdCtx; - this.classifyCtx = classifyCtx; } @Override @@ -98,16 +87,5 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF .child( org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx))); - - // Acl(Structural) - final InstanceIdentifier aclIid = subIfcId.child(Acl.class); - registry.addStructuralReader(aclIid, AclBuilder.class); - // Ingress(Subtree) - final InstanceIdentifier ingressIdRelative = InstanceIdentifier.create(Ingress.class); - registry.subtreeAdd( - Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), - ingressIdRelative.child(Ip6Acl.class)), - new GenericInitReader<>(aclIid.child(Ingress.class), - new SubInterfaceAclCustomizer(jvpp, ifcCtx, classifyCtx))); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierHoneycombWriterFactory.java deleted file mode 100644 index 5a7b64694..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierHoneycombWriterFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.hc2vpp.v3po.vppclassifier.ClassifySessionWriter; -import io.fd.hc2vpp.v3po.vppclassifier.ClassifyTableWriter; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public final class VppClassifierHoneycombWriterFactory implements WriterFactory { - - public static final InstanceIdentifier CLASSIFY_TABLE_ID = - InstanceIdentifier.create(VppClassifier.class).child(ClassifyTable.class); - - public static final InstanceIdentifier CLASSIFY_SESSION_ID = - CLASSIFY_TABLE_ID.child(ClassifySession.class); - - private final FutureJVppCore jvpp; - private final VppClassifierContextManager classifyTableContext; - - @Inject - public VppClassifierHoneycombWriterFactory(@Nonnull final FutureJVppCore jvpp, - @Named("classify-table-context") @Nonnull final VppClassifierContextManager classifyTableContext) { - this.jvpp = jvpp; - this.classifyTableContext = classifyTableContext; - } - - @Override - public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { - // Ordering here is: First create table, then create sessions and then assign as ACL - // ClassifyTable - registry.addBefore( - new GenericListWriter<>(CLASSIFY_TABLE_ID, new ClassifyTableWriter(jvpp, classifyTableContext)), - CLASSIFY_SESSION_ID); - // ClassifyTableSession - registry.addBefore( - new GenericListWriter<>(CLASSIFY_SESSION_ID, new ClassifySessionWriter(jvpp, classifyTableContext)), - InterfacesWriterFactory.ACL_ID); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierReaderFactory.java deleted file mode 100644 index 56983e9f3..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppClassifierReaderFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.v3po.factory; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericListReader; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.hc2vpp.v3po.vppclassifier.ClassifySessionReader; -import io.fd.hc2vpp.v3po.vppclassifier.ClassifyTableReader; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VppClassifierReaderFactory implements ReaderFactory { - - private final FutureJVppCore jvpp; - private final VppClassifierContextManager classifyCtx; - - @Inject - public VppClassifierReaderFactory(final FutureJVppCore jvpp, - @Named("classify-table-context") final VppClassifierContextManager classifyCtx) { - this.jvpp = jvpp; - this.classifyCtx = classifyCtx; - } - - @Override - public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { - // VppClassifierState - final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppClassifierState.class); - registry.addStructuralReader(vppStateId, VppClassifierStateBuilder.class); - // ClassifyTable - final InstanceIdentifier classTblId = vppStateId.child(ClassifyTable.class); - registry.add(new GenericInitListReader<>(classTblId, new ClassifyTableReader(jvpp, classifyCtx))); - // ClassifySession - final InstanceIdentifier classSesId = classTblId.child(ClassifySession.class); - registry.add(new GenericListReader<>(classSesId, new ClassifySessionReader(jvpp, classifyCtx))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java deleted file mode 100644 index d97bdee54..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.v3po.interfaces.acl; - -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.Optional; -import java.util.stream.Stream; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -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.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for Access Control Lists management. Does not send any messages to VPP. All the config - * data are stored in HC and used when acl is assigned/unassigned to/from an interface. - * - * ACLs that are currently assigned to an interface cannot be updated/deleted. - */ -public class IetfAclWriter implements ListWriterCustomizer { - - public static final InstanceIdentifier ACL_ID = - InstanceIdentifier.create(AccessLists.class); - - private static final Logger LOG = LoggerFactory.getLogger(IetfAclWriter.class); - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Creating ACL: iid={} dataAfter={}", id, dataAfter); - - // no vpp call, just updates DataTree - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, - @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Updating ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); - - if (isAssigned(dataAfter, writeContext)) { - throw new WriteFailedException(id, - String.format("Failed to update data at %s: acl %s is already assigned", id, dataAfter)); - } - - LOG.debug("Updating unassigned ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); - - // no vpp call, just updates DataTree - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Deleting ACL: iid={} dataBefore={}", id, dataBefore); - - if (isAssigned(dataBefore, writeContext)) { - throw new WriteFailedException(id, - String.format("Failed to delete data at %s: acl %s is already assigned", id, dataBefore)); - } - - LOG.debug("Deleting unassigned ACL: iid={} dataBefore={}", id, dataBefore); - - // no vpp call, just updates DataTree - } - - private static boolean isAssigned(@Nonnull final Acl acl, - @Nonnull final WriteContext writeContext) { - final String aclName = acl.getAclName(); - final Class aclType = acl.getAclType(); - final Interfaces interfaces = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class)).get(); - - return interfaces.getInterface().stream() - .map(i -> Optional.ofNullable(i.getAugmentation(VppInterfaceAugmentation.class)) - .map(aug -> aug.getIetfAcl()) - .map(ietfAcl -> ietfAcl.getIngress()) - .map(ingress -> ingress.getAccessLists()) - .map(accessLists -> accessLists.getAcl()) - ) - .flatMap(iacl -> iacl.isPresent() - ? iacl.get().stream() - : Stream.empty()) - .filter(assignedAcl -> aclName.equals(assignedAcl.getName()) && aclType.equals(assignedAcl.getType())) - .findFirst().isPresent(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java deleted file mode 100644 index 331db10dc..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -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.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.matches.AceType; -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.ace.type.AceEth; -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.ace.type.AceIp; -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.ace.type.ace.ip.AceIpVersion; -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.ace.type.ace.ip.ace.ip.version.AceIpv4; -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.ace.type.ace.ip.ace.ip.version.AceIpv6; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyConsumer, AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractIetfAclWriter.class); - protected static final int NOT_DEFINED = -1; - protected final FutureJVppCore jvpp; - - private Map> aceWriters = new HashMap<>(); - - public AbstractIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { - this.jvpp = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); - aceWriters.put(AclType.ETH, new AceEthWriter()); - aceWriters.put(AclType.IP4, new AceIp4Writer()); - aceWriters.put(AclType.IP6, new AceIp6Writer()); - aceWriters.put(AclType.ETH_AND_IP, new AceIpAndEthWriter()); - } - - private static Stream aclToAceStream(@Nonnull final Acl assignedAcl, - @Nonnull final WriteContext writeContext) { - final String aclName = assignedAcl.getName(); - final Class aclType = assignedAcl.getType(); - - // ietf-acl updates are handled first, so we use writeContext.readAfter - final Optional - aclOptional = - writeContext.readAfter(io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter.ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, - new AclKey(aclName, aclType))); - checkArgument(aclOptional.isPresent(), "Acl lists not configured"); - final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl - acl = aclOptional.get(); - - final AccessListEntries accessListEntries = acl.getAccessListEntries(); - checkArgument(accessListEntries != null, "access list entries not configured"); - - return accessListEntries.getAce().stream(); - } - - protected void removeClassifyTables(@Nonnull final InstanceIdentifier id, @Nonnull final MappingEntry entry) - throws WriteFailedException { - removeClassifyTable(id, entry.getL2TableId()); - removeClassifyTable(id, entry.getIp4TableId()); - removeClassifyTable(id, entry.getIp6TableId()); - } - - private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) - throws WriteFailedException { - - if (tableIndex == -1) { - return; // classify table id is absent - } - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.delChain = 1; - request.tableIndex = tableIndex; - final CompletionStage cs = jvpp.classifyAddDelTable(request); - getReplyForDelete(cs.toCompletableFuture(), id); - } - - protected static boolean appliesToIp4Path(final Ace ace) { - final AceType aceType = ace.getMatches().getAceType(); - final AclType aclType = AclType.fromAce(ace); - if (aclType == AclType.IP4) { - return true; - } - if (aclType == AclType.ETH) { - return true; // L2 only rules are possible for IP4 traffic - } - if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType).getAceIpAndEthNodes() - .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4) { - return true; - } - return false; - } - - protected static boolean appliesToIp6Path(final Ace ace) { - final AceType aceType = ace.getMatches().getAceType(); - final AclType aclType = AclType.fromAce(ace); - if (aclType == AclType.IP6) { - return true; - } - if (aclType == AclType.ETH) { - return true; // L2 only rules are possible for IP6 traffic - } - if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType).getAceIpAndEthNodes() - .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv6) { - return true; - } - return false; - } - - protected static List getACEs(@Nonnull final List acls, @Nonnull final WriteContext writeContext, - final Predicate filter) { - return acls.stream().flatMap(acl -> aclToAceStream(acl, writeContext)).filter(filter) - .collect(Collectors.toList()); - } - - protected int writeAces(final InstanceIdentifier id, final List aces, - final AccessLists.DefaultAction defaultAction, final InterfaceMode mode, - final int vlanTags) throws WriteFailedException { - if (aces.isEmpty()) { - return NOT_DEFINED; - } - - int nextTableIndex = configureDefaultAction(id, defaultAction); - final ListIterator iterator = aces.listIterator(aces.size()); - while (iterator.hasPrevious()) { - final Ace ace = iterator.previous(); - LOG.trace("Processing ACE: {}", ace); - - final AceWriter aceWriter = - aceWriters.get(AclType.fromAce(ace)); - if (aceWriter == null) { - LOG.warn("AceProcessor for {} not registered. Skipping ACE.", ace.getClass()); - } else { - final AceType aceType = ace.getMatches().getAceType(); - final PacketHandling action = ace.getActions().getPacketHandling(); - final ClassifyAddDelTable ctRequest = aceWriter.createTable(aceType, mode, nextTableIndex, vlanTags); - nextTableIndex = createClassifyTable(id, ctRequest); - final List sessionRequests = - aceWriter.createSession(action, aceType, mode, nextTableIndex, vlanTags); - for (ClassifyAddDelSession csRequest : sessionRequests) { - createClassifySession(id, csRequest); - } - } - } - return nextTableIndex; - } - - private int configureDefaultAction(@Nonnull final InstanceIdentifier id, - final AccessLists.DefaultAction defaultAction) - throws WriteFailedException { - ClassifyAddDelTable ctRequest = createTable(-1); - if (AccessLists.DefaultAction.Permit.equals(defaultAction)) { - ctRequest.missNextIndex = -1; - } else { - ctRequest.missNextIndex = 0; - } - ctRequest.mask = new byte[16]; - ctRequest.skipNVectors = 0; - ctRequest.matchNVectors = 1; - return createClassifyTable(id, ctRequest); - } - - private int createClassifyTable(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyAddDelTable request) - throws WriteFailedException { - final CompletionStage cs = jvpp.classifyAddDelTable(request); - - final ClassifyAddDelTableReply reply = getReplyForWrite(cs.toCompletableFuture(), id); - return reply.newTableIndex; - } - - private void createClassifySession(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyAddDelSession request) - throws WriteFailedException { - final CompletionStage cs = jvpp.classifyAddDelSession(request); - - getReplyForWrite(cs.toCompletableFuture(), id); - } - - private enum AclType { - ETH, IP4, IP6, ETH_AND_IP; - - @Nonnull - private static AclType fromAce(final Ace ace) { - AclType result = null; - final AceType aceType; - try { - aceType = ace.getMatches().getAceType(); - if (aceType instanceof AceEth) { - result = ETH; - } else if (aceType instanceof AceIp) { - final AceIpVersion aceIpVersion = ((AceIp) aceType).getAceIpVersion(); - if (aceIpVersion == null) { - throw new IllegalArgumentException("Incomplete ACE (ip-version was not provided): " + ace); - } - if (aceIpVersion instanceof AceIpv4) { - result = IP4; - } else if (aceIpVersion instanceof AceIpv6) { - result = IP6; - } - } else if (aceType instanceof AceIpAndEth) { - result = ETH_AND_IP; - } - } catch (NullPointerException e) { - throw new IllegalArgumentException("Incomplete ACE: " + ace, e); - } - if (result == null) { - throw new IllegalArgumentException(String.format("Not supported ace type %s", aceType)); - } - return result; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java deleted file mode 100644 index 3992c8da7..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import com.google.common.annotations.VisibleForTesting; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.matches.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceEthWriter implements AceWriter, AclTranslator, L2AclTranslator { - - @VisibleForTesting - static final int MATCH_N_VECTORS = 1; - private static final Logger LOG = LoggerFactory.getLogger(AceEthWriter.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceEth aceEth, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - final ClassifyAddDelTable request = createTable(nextTableIndex); - - request.mask = new byte[16]; - boolean aceIsEmpty = - destinationMacAddressMask(aceEth.getDestinationMacAddressMask(), aceEth.getDestinationMacAddress(), - request); - aceIsEmpty &= - sourceMacAddressMask(aceEth.getSourceMacAddressMask(), aceEth.getSourceMacAddress(), request); - - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceEth.toString())); - } - - request.skipNVectors = 0; - request.matchNVectors = MATCH_N_VECTORS; - - LOG.debug("ACE rule={} translated to table={}.", aceEth, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceEth aceEth, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - - request.match = new byte[16]; - boolean noMatch = destinationMacAddressMatch(aceEth.getDestinationMacAddress(), request); - noMatch &= sourceMacAddressMatch(aceEth.getSourceMacAddress(), request); - - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define neither source nor destination MAC address", - aceEth.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceEth, request); - return Collections.singletonList(request); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java deleted file mode 100644 index c760af756..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.VisibleForTesting; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.matches.ace.type.AceIp; -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.ace.type.ace.ip.ace.ip.version.AceIpv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceIp4Writer implements AceWriter, AclTranslator, Ip4AclTranslator { - - @VisibleForTesting - static final int MATCH_N_VECTORS = 3; // number of 16B vectors - private static final int TABLE_MASK_LENGTH = 48; - private static final Logger LOG = LoggerFactory.getLogger(AceIp4Writer.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); - final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); - - final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - request.skipNVectors = 0; // match entire L2 and L3 header - request.matchNVectors = MATCH_N_VECTORS; - request.mask = new byte[TABLE_MASK_LENGTH]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean aceIsEmpty = ip4Mask(baseOffset, mode, aceIp, ipVersion, request); - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", aceIp, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); - final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); - - final List portPairs = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[TABLE_MASK_LENGTH]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean noMatch = ip4Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java deleted file mode 100644 index d3ed32dab..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.matches.ace.type.AceIp; -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.ace.type.ace.ip.ace.ip.version.AceIpv6; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceIp6Writer implements AceWriter, AclTranslator, Ip6AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); - final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); - - final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - request.skipNVectors = 0; // match entire L2 and L3 header - request.mask = new byte[getTableMaskLength(vlanTags)]; - request.matchNVectors = request.mask.length/16; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean aceIsEmpty = ip6Mask(baseOffset, mode, aceIp, ipVersion, request); - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", aceIp, request); - return request; - } - - private static int getTableMaskLength(final int vlanTags) { - if (vlanTags == 2) { - return 80; - } else { - return 64; - } - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); - final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); - final List portPairs = - PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); - - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[getTableMaskLength(vlanTags)]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean noMatch = ip6Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java deleted file mode 100644 index fcc657189..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.AceIpVersion; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv6; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class AceIpAndEthWriter - implements AceWriter, AclTranslator, L2AclTranslator, Ip4AclTranslator, Ip6AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AceIpAndEthWriter.class); - - private static int maskLength(@Nonnull final AceIpAndEth ace, final int vlanTags) { - if (ace.getAceIpAndEthNodes().getAceIpVersion() != null) { - if (ace.getAceIpAndEthNodes().getAceIpVersion() instanceof AceIpv4) { - return 48; - } else { - return vlanTags == 2 - ? 80 - : 64; - } - } - return 16; - } - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIpAndEth ace, @Nullable final InterfaceMode mode, - final int nextTableIndex, final int vlanTags) { - final AceIpAndEthNodes nodes = ace.getAceIpAndEthNodes(); - final int numberOfSessions = PortPair.fromRange(nodes.getSourcePortRange(), nodes.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - final int maskLength = maskLength(ace, vlanTags); - request.mask = new byte[maskLength]; - request.skipNVectors = 0; - request.matchNVectors = maskLength / 16; - - boolean aceIsEmpty = - destinationMacAddressMask(nodes.getDestinationMacAddressMask(), nodes.getDestinationMacAddress(), request); - aceIsEmpty &= sourceMacAddressMask(nodes.getSourceMacAddressMask(), nodes.getSourceMacAddress(), request); - - // if we use classifier API, we need to know ip version (fields common for ip4 and ip6 have different offsets): - final AceIpVersion aceIpVersion = nodes.getAceIpVersion(); - checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); - - final int baseOffset = getVlanTagsLen(vlanTags); - if (aceIpVersion instanceof AceIpv4) { - final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; - aceIsEmpty &= ip4Mask(baseOffset, mode, nodes, ipVersion, request); - } else if (aceIpVersion instanceof AceIpv6) { - final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; - aceIsEmpty &= ip6Mask(baseOffset, mode, nodes, ipVersion, request); - } else { - throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); - } - - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", ace.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", ace, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIpAndEth ace, - @Nullable final InterfaceMode mode, final int tableIndex, - final int vlanTags) { - final AceIpAndEthNodes nodes = ace.getAceIpAndEthNodes(); - final List portPairs = PortPair.fromRange(nodes.getSourcePortRange(), nodes.getDestinationPortRange()); - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[maskLength(ace, vlanTags)]; - - boolean noMatch = destinationMacAddressMatch(nodes.getDestinationMacAddress(), request); - noMatch &= sourceMacAddressMatch(nodes.getSourceMacAddress(), request); - - final AceIpVersion aceIpVersion = nodes.getAceIpVersion(); - checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); - - final int baseOffset = getVlanTagsLen(vlanTags); - if (aceIpVersion instanceof AceIpv4) { - final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; - noMatch &= ip4Match(baseOffset, mode, nodes, ipVersion, pair.getSrc(), pair.getDst(), request); - } else if (aceIpVersion instanceof AceIpv6) { - final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; - noMatch &= ip6Match(baseOffset, mode, nodes, ipVersion, pair.getSrc(), pair.getDst(), request); - } else { - throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); - } - - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", ace.toString())); - } - LOG.debug("ACE action={}, rule={} translated to session={}.", action, ace, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java deleted file mode 100644 index 6dca7bdef..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.matches.AceType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; - -/** - * Writer responsible for translation of ietf-acl model ACEs to VPP's classify tables and sessions. - * - * @param type of access control list entry - */ -interface AceWriter { - /** - * @param ace access list entry - * @param mode interface mode (L2/L3) - * @param nextTableIndex index of the next classify table in chain - * @param vlanTags number of vlan tags - */ - @Nonnull - ClassifyAddDelTable createTable(@Nonnull final T ace, @Nullable final InterfaceMode mode, final int nextTableIndex, - final int vlanTags); - - /** - * @param action to be taken when packet does match the specified ace - * @param ace access list entry - * @param mode interface mode (L2/L3) - * @param tableIndex index of corresponding classify table - * @param vlanTags number of vlan tags - */ - @Nonnull - List createSession(@Nonnull final PacketHandling action, @Nonnull T ace, - @Nullable final InterfaceMode mode, final int tableIndex, final int vlanTags); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java deleted file mode 100644 index 0728944f2..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; - -/** - * Manages interface metadata for ietf-acl model. - */ -public interface AclTableContextManager { - - /** - * Obtains mapping entry for given interface. - * - * @param index interface index - * @param mappingContext mapping context providing context data for current transaction - * @return ietf-acl metadata for given interface - */ - Optional getEntry(final int index, @Nonnull final MappingContext mappingContext); - - /** - * Adds mapping entry. - * - * @param entry to be added - * @param mappingContext mapping context providing context data for current transaction - */ - void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext); - - /** - * Removes entry for given interface (if present). - * - * @param index interface index - * @param mappingContext mapping context providing context data for current transaction - */ - void removeEntry(final int index, @Nonnull final MappingContext mappingContext); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java deleted file mode 100644 index 659244fda..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -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.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.AclMappingEntryCtxAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.AclMappingEntryContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTableKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -@ThreadSafe -public class AclTableContextManagerImpl implements AclTableContextManager { - - private MappingTable.Direction direction; - - public AclTableContextManagerImpl(@Nonnull final MappingTable.Direction direction) { - this.direction = checkNotNull(direction, "direction should not be null"); - } - - @Nonnull - @Override - public synchronized Optional getEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { - return mappingContext.read(getId(swIfIndex)); - } - - @Override - public synchronized void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext) { - mappingContext.put(getId(entry.getIndex()), entry); - } - - @Override - public synchronized void removeEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { - mappingContext.delete(getId(swIfIndex)); - } - - @VisibleForTesting - protected InstanceIdentifier getId(final int index) { - return InstanceIdentifier.create(Contexts.class) - .augmentation(AclMappingEntryCtxAugmentation.class) - .child(AclMappingEntryContext.class) - .child(MappingTable.class, new MappingTableKey(direction)) - .child(MappingEntry.class, new MappingEntryKey(index)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java deleted file mode 100644 index e4291122d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import javax.annotation.Nonnegative; -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.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.Permit; - -/** - * Utility that helps translating of ietf-acl model ACEs to VPP's classify tables and sessions. - */ -interface AclTranslator { - int TABLE_MEM_SIZE = 8 * 1024; - int VLAN_TAG_LEN = 4; - - default ClassifyAddDelTable createTable(final int nextTableIndex) { - return createTable(nextTableIndex, 1); - } - - default ClassifyAddDelTable createTable(final int nextTableIndex, @Nonnegative final int numberOfSessions) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = 1; - request.tableIndex = -1; // value not present - request.nbuckets = numberOfSessions; - request.nextTableIndex = nextTableIndex; - - - // TODO: HONEYCOMB-181 minimise memory used by classify tables (we create a lot of them to make ietf-acl model - // mapping more convenient): - // according to https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers#Creating_a_classifier_table, - // classify table needs 16*(1 + match_n_vectors) bytes, but this does not quite work, - // so setting 8K +1k*numberOfSessions for now - checkArgument(numberOfSessions>0, "negative numberOfSessions %s", numberOfSessions); - request.memorySize = TABLE_MEM_SIZE+1024*(numberOfSessions-1); - request.missNextIndex = -1; // value not set, but anyway it is ignored for tables in chain - return request; - } - - default ClassifyAddDelSession createSession(@Nonnull final PacketHandling action, final int tableIndex) { - final ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = 1; - request.tableIndex = tableIndex; - request.opaqueIndex = ~0; // value not used - - if (action instanceof Permit) { - request.hitNextIndex = -1; - } // deny (0) is default value - - return request; - } - - default int getVlanTagsLen(final int vlanTags) { - return vlanTags * VLAN_TAG_LEN; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java deleted file mode 100644 index 3e4e2c04f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.List; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public interface IetfAclWriter { - default void write(@Nonnull final InstanceIdentifier id, final int ifIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - write(id, ifIndex, acls, defaultAction, mode, writeContext, 0, mappingContext); - } - - void write(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException; - - void deleteAcl(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final MappingContext mappingContext) - throws WriteFailedException; -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java deleted file mode 100644 index 3c1dc753d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import com.google.common.primitives.Ints; -import io.fd.hc2vpp.common.translate.util.Ipv4Translator; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -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.packet.fields.rev160708.AclIpHeaderFields; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; - -interface Ip4AclTranslator extends Ipv4Translator { - int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) - int DSCP_OFFSET = 15; - int DSCP_MASK = 0xfc; - - int IP_PROTOCOL_OFFSET = ETHER_TYPE_OFFSET + 11; - int IP_PROTOCOL_MASK = 0xff; - - int IP4_LEN = 4; - int IP4_MASK_BIT_LENGTH = 32; - int SRC_IP_OFFSET = ETHER_TYPE_OFFSET + 14; - int DST_IP_OFFSET = SRC_IP_OFFSET + IP4_LEN; - int SRC_PORT_OFFSET = DST_IP_OFFSET + IP4_LEN; - int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; - - default boolean ip4Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv4HeaderFields ip4, final ClassifyAddDelTable request) { - boolean aceIsEmpty = true; - if (InterfaceMode.L2.equals(mode)) { - // in L2 mode we need to match ether type - request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; - request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; - } - if (header.getDscp() != null) { - aceIsEmpty = false; - request.mask[baseOffset + DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits - } - if (header.getProtocol() != null) { // Internet Protocol number - aceIsEmpty = false; - request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; - } - if (ip4.getSourceIpv4Network() != null) { - aceIsEmpty = false; - System.arraycopy(Impl.toByteMask(ip4.getSourceIpv4Network()), 0, request.mask, - baseOffset + SRC_IP_OFFSET, IP4_LEN); - } - if (ip4.getDestinationIpv4Network() != null) { - aceIsEmpty = false; - System.arraycopy(Impl.toByteMask(ip4.getDestinationIpv4Network()), 0, request.mask, - baseOffset + DST_IP_OFFSET, IP4_LEN); - } - return aceIsEmpty; - } - - default boolean ip4Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv4HeaderFields ip4, final Integer srcPort, - final Integer dstPort, final ClassifyAddDelSession request) { - boolean noMatch = true; - if (InterfaceMode.L2.equals(mode)) { - // match IP4 etherType (0x0800) - request.match[baseOffset + ETHER_TYPE_OFFSET] = 0x08; - request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = 0x00; - } - if (header.getDscp() != null) { - noMatch = false; - request.match[baseOffset + DSCP_OFFSET] = (byte) (DSCP_MASK & (header.getDscp().getValue() << 2)); - } - if (header.getProtocol() != null) { // Internet Protocol number - noMatch = false; - request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); - } - if (srcPort != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); - request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); - request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); - } - if (ip4.getSourceIpv4Network() != null) { - noMatch = false; - System.arraycopy(Impl.toMatchValue(ip4.getSourceIpv4Network()), 0, request.match, - baseOffset + SRC_IP_OFFSET, IP4_LEN); - - } - if (ip4.getDestinationIpv4Network() != null) { - noMatch = false; - System.arraycopy(Impl.toMatchValue(ip4.getDestinationIpv4Network()), 0, request.match, - baseOffset + DST_IP_OFFSET, IP4_LEN); - - } - return noMatch; - } - - class Impl { - private static byte[] toByteMask(final int prefixLength) { - final long mask = ((1L << prefixLength) - 1) << (IP4_MASK_BIT_LENGTH - prefixLength); - return Ints.toByteArray((int) mask); - } - - private static byte[] toByteMask(final Ipv4Prefix ipv4Prefix) { - final int prefixLength = Byte.valueOf(ipv4Prefix.getValue().split("/")[1]); - return toByteMask(prefixLength); - } - - private static byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { - final String[] split = ipv4Prefix.getValue().split("/"); - final byte[] addressBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(split[0]); - final byte[] mask = Impl.toByteMask(Byte.valueOf(split[1])); - for (int i = 0; i < addressBytes.length; ++i) { - addressBytes[i] &= mask[i]; - } - return addressBytes; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java deleted file mode 100644 index 9f80a9f94..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.BitSet; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; -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.classfier.acl.rev161214.InterfaceMode; - -interface Ip6AclTranslator { - - int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) - int IP_VERSION_OFFSET = ETHER_TYPE_OFFSET + 2; - int DSCP_MASK1 = 0x0f; - int DSCP_MASK2 = 0xc0; - int IP_PROTOCOL_OFFSET = IP_VERSION_OFFSET + 6; - int IP_PROTOCOL_MASK = 0xff; - int IP6_LEN = 16; - int SRC_IP_OFFSET = IP_VERSION_OFFSET + 8; - int DST_IP_OFFSET = SRC_IP_OFFSET + IP6_LEN; - int SRC_PORT_OFFSET = DST_IP_OFFSET + IP6_LEN; - int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; - - default boolean ip6Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv6HeaderFields ip6, final ClassifyAddDelTable request) { - boolean aceIsEmpty = true; - if (InterfaceMode.L2.equals(mode)) { - // in L2 mode we need to match ether type - request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; - request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; - } - if (header.getDscp() != null) { - aceIsEmpty = false; - // DCSP (bits 4-9 of IP6 header) - request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1; - request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2; - } - if (header.getProtocol() != null) { // Internet Protocol number - aceIsEmpty = false; - request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; - } - if (ip6.getFlowLabel() != null) { - aceIsEmpty = false; - // bits 12-31 - request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) 0x0f; - request.mask[baseOffset + IP_VERSION_OFFSET + 2] = (byte) 0xff; - request.mask[baseOffset + IP_VERSION_OFFSET + 3] = (byte) 0xff; - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; - } - if (ip6.getSourceIpv6Network() != null) { - aceIsEmpty = false; - final byte[] mask = Impl.toByteMask(ip6.getSourceIpv6Network()); - System.arraycopy(mask, 0, request.mask, baseOffset + SRC_IP_OFFSET, mask.length); - } - if (ip6.getDestinationIpv6Network() != null) { - aceIsEmpty = false; - final byte[] mask = Impl.toByteMask(ip6.getDestinationIpv6Network()); - System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length); - } - return aceIsEmpty; - } - - default boolean ip6Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv6HeaderFields ip6, final Integer srcPort, final Integer dstPort, final ClassifyAddDelSession request) { - boolean noMatch = true; - if (InterfaceMode.L2.equals(mode)) { - // match IP6 etherType (0x86dd) - request.match[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0x86; - request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xdd; - } - if (header.getDscp() != null) { - noMatch = false; - final int dcsp = header.getDscp().getValue(); - // set bits 4-9 of IP6 header: - request.match[baseOffset + IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dcsp >> 2)); - request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dcsp << 6)); - } - if (header.getProtocol() != null) { // Internet Protocol number - noMatch = false; - request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); - } - if (ip6.getFlowLabel() != null) { - noMatch = false; - final int flowLabel = ip6.getFlowLabel().getValue().intValue(); - // bits 12-31 - request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16)); - request.match[baseOffset + IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8)); - request.match[baseOffset + IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel); - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); - request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); - request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); - } - if (ip6.getSourceIpv6Network() != null) { - noMatch = false; - final byte[] match = Impl.toMatchValue(ip6.getSourceIpv6Network()); - System.arraycopy(match, 0, request.match, baseOffset + SRC_IP_OFFSET, IP6_LEN); - } - if (ip6.getDestinationIpv6Network() != null) { - noMatch = false; - final byte[] match = Impl.toMatchValue(ip6.getDestinationIpv6Network()); - System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN); - } - return noMatch; - } - - class Impl { - private static final int IP6_MASK_BIT_LENGTH = 128; - - private static byte[] toByteMask(final int prefixLength) { - final BitSet mask = new BitSet(IP6_MASK_BIT_LENGTH); - mask.set(0, prefixLength, true); - if (prefixLength < IP6_MASK_BIT_LENGTH) { - mask.set(prefixLength, IP6_MASK_BIT_LENGTH, false); - } - return mask.toByteArray(); - } - - private static byte[] toByteMask(final Ipv6Prefix ipv6Prefix) { - final int prefixLength = Short.valueOf(ipv6Prefix.getValue().split("/")[1]); - return toByteMask(prefixLength); - } - - private static byte[] toMatchValue(final Ipv6Prefix ipv6Prefix) { - final String[] split = ipv6Prefix.getValue().split("/"); - final byte[] addressBytes; - try { - addressBytes = InetAddress.getByName(split[0]).getAddress(); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid IP6 address", e); - } - final byte[] mask = toByteMask(Short.valueOf(split[1])); - int pos = 0; - for (; pos < mask.length; ++pos) { - addressBytes[pos] &= mask[pos]; - } - // mask can be shorter that address, so we need to clear rest of the address: - for (; pos < addressBytes.length; ++pos) { - addressBytes[pos] = 0; - } - return addressBytes; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java deleted file mode 100644 index 5a6807bba..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import io.fd.hc2vpp.common.translate.util.MacTranslator; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.List; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; - -interface L2AclTranslator extends MacTranslator { - - default boolean destinationMacAddressMask(final MacAddress dstMask, final MacAddress dstAddress, - final ClassifyAddDelTable request) { - // destination-mac-address or destination-mac-address-mask is present => - // ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00 - if (dstMask != null) { - final List parts = COLON_SPLITTER.splitToList(dstMask.getValue()); - int i = 0; - for (String part : parts) { - request.mask[i++] = parseHexByte(part); - } - return false; - } else if (dstAddress != null) { - for (int i = 0; i < 6; ++i) { - request.mask[i] = (byte) 0xff; - } - return false; - } - return true; - } - - default boolean sourceMacAddressMask(final MacAddress srcMask, final MacAddress srcAddress, - final ClassifyAddDelTable request) { - // source-mac-address or source-mac-address-mask => - // 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00 - if (srcMask != null) { - final List parts = COLON_SPLITTER.splitToList(srcMask.getValue()); - int i = 6; - for (String part : parts) { - request.mask[i++] = parseHexByte(part); - } - return false; - } else if (srcAddress != null) { - for (int i = 6; i < 12; ++i) { - request.mask[i] = (byte) 0xff; - } - return false; - } - return true; - } - - default boolean destinationMacAddressMatch(final MacAddress dstAddress, final ClassifyAddDelSession request) { - if (dstAddress != null) { - final List parts = COLON_SPLITTER.splitToList(dstAddress.getValue()); - int i = 0; - for (String part : parts) { - request.match[i++] = parseHexByte(part); - } - return false; - } - return true; - } - - default boolean sourceMacAddressMatch(final MacAddress srcAddress, final ClassifyAddDelSession request) { - if (srcAddress != null) { - final List parts = COLON_SPLITTER.splitToList(srcAddress.getValue()); - int i = 6; - for (String part : parts) { - request.match[i++] = parseHexByte(part); - } - return false; - } - return true; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java deleted file mode 100644 index 1630f58fd..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.BiFunction; -import javax.annotation.Nullable; -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.SourcePortRange; - -/** - * Utility that produces cartesian product out of src and dst port ranges (used to translate ranges into - * list of classify sessions). - */ -final class PortPair { - private final Integer src; - private final Integer dst; - - PortPair(@Nullable final Integer src, @Nullable final Integer dst) { - this.src = src; - this.dst = dst; - } - - Integer getSrc() { - return src; - } - - Integer getDst() { - return dst; - } - - @Override - public String toString() { - return "(" + src + "," + dst + ")"; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final PortPair that = (PortPair) o; - if (!Objects.equals(src, that.src)) { - return false; - } - if (!Objects.equals(dst, that.dst)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(src, dst); - } - - static List fromRange(final SourcePortRange srcRange, - final DestinationPortRange dstRange) { - final List result = new ArrayList<>(); - if (srcRange == null && dstRange == null) { - result.add(new PortPair(null, null)); - } else if (srcRange != null && dstRange == null) { - processSingleRange(result, srcRange.getLowerPort(), srcRange.getUpperPort(), PortPair::new); - } else if (srcRange == null && dstRange != null) { - processSingleRange(result, dstRange.getLowerPort(), dstRange.getUpperPort(), - (dst, src) -> new PortPair(src, dst)); - } else { - processDoubleRange(result, srcRange, dstRange); - } - return result; - } - - private static void processSingleRange(final List result, - final PortNumber lowerPort, - final PortNumber upperPort, - final BiFunction f) { - int low = lowerPort.getValue(); // mandatory - int hi = low; - if (upperPort != null) { - hi = upperPort.getValue(); - } - for (; low <= hi; ++low) { - result.add(f.apply(low, null)); - } - } - - private static void processDoubleRange(final List result, final SourcePortRange srcRange, - final DestinationPortRange dstRange) { - int srcL = srcRange.getLowerPort().getValue(); - int srcH = srcL; - if (srcRange.getUpperPort() != null) { - srcH = srcRange.getUpperPort().getValue(); - } - int dstL = dstRange.getLowerPort().getValue(); - int dstH = dstL; - if (dstRange.getUpperPort() != null) { - dstH = dstRange.getUpperPort().getValue(); - } - for (int i=srcL; i <= srcH; ++i) { - for (int j=dstL; j <= dstH; ++j) { - result.add(new PortPair(i, j)); - } - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java deleted file mode 100644 index 759034308..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AbstractIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.Matches; -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.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class EgressIetfAclWriter extends AbstractIetfAclWriter { - private final AclTableContextManager aclCtx; - - public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { - super(futureJVppCore); - this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); - } - - @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); - checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); - final MappingEntry entry = optional.get(); - unassignClassifyTables(id, swIfIndex); - removeClassifyTables(id, entry); - aclCtx.removeEntry(swIfIndex, mappingContext); - } - - private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final int swIfIndex) - throws WriteFailedException { - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.swIfIndex = swIfIndex; - request.ip4TableIndex = NOT_DEFINED; - request.ip6TableIndex = NOT_DEFINED; - request.otherTableIndex = NOT_DEFINED; - request.isInput = 0; // egress - final CompletionStage cs = jvpp.classifySetInterfaceL2Tables(request); - getReplyForDelete(cs.toCompletableFuture(), id); - } - - @Override - public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); - checkArgument(InterfaceMode.L2.equals(mode), "Writing egress Acls is supported only in L2 mode"); - - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; // egress - request.swIfIndex = swIfIndex; - - // applied to packets according to their ether type - final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); - request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); - final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); - request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); - final List aces = getACEs(acls, writeContext, EgressIetfAclWriter::isNotIpRule); - request.otherTableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); - - final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) - .setIp4TableId(request.ip4TableIndex) - .setIp6TableId(request.ip6TableIndex) - .setL2TableId(request.otherTableIndex) - .build(); - aclCtx.addEntry(entry, mappingContext); - - try { - getReplyForWrite(jvpp.classifySetInterfaceL2Tables(request).toCompletableFuture(), id); - } catch (WriteFailedException e) { - removeClassifyTables(id, entry); - throw e; - } - } - - private static boolean isNotIpRule(final Ace ace) { - final Matches matches = ace.getMatches(); - checkArgument(matches != null, "Incomplete ACE: %s", ace); - return matches.getAceType() instanceof AceEth; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java deleted file mode 100644 index 50101f34f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class IetfAclCustomizer implements WriterCustomizer { - private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); - private final IetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public IetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Adding egress ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - if (!InterfaceMode.L2.equals(accessLists.getMode())) { - LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); - return; - } - - aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java deleted file mode 100644 index f016c1bd7..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); - private final IetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public SubInterfaceIetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - final Optional subInterfaceOptional = - writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); - checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); - final SubInterface subInterface = subInterfaceOptional.get(); - - if (!InterfaceMode.L2.equals(accessLists.getMode())) { - LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); - return; - } - - aclWriter - .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("Sub-interface ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("Sub-interface ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java deleted file mode 100644 index 05233ce40..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs on given interface based on low lever classfier model. - */ -public class AclCustomizer extends FutureJVppCustomizer implements WriterCustomizer, AclWriter { - - private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public AclCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(vppApi); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(true, id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(false, id, dataBefore, writeContext); - } - - private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - - LOG.debug("Setting ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); - - inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, ifIndex, classifyTableContext, - writeContext.getMappingContext()); - LOG.debug("Successfully set ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java deleted file mode 100644 index ae0f37376..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.AclBaseAttributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -interface AclWriter extends ByteDataTranslator, JvppReplyConsumer { - - default void inputAclSetInterface(@Nonnull final FutureJVppCore futureJVppCore, final boolean isAdd, - @Nonnull final InstanceIdentifier id, @Nonnull final AclBaseAttributes acl, - @Nonnegative final int ifIndex, - @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) throws WriteFailedException { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = booleanToByte(isAdd); - request.swIfIndex = ifIndex; - request.l2TableIndex = ~0; // skip - request.ip4TableIndex = ~0; // skip - request.ip6TableIndex = ~0; // skip - - final L2Acl l2Acl = acl.getL2Acl(); - if (l2Acl != null) { - final String tableName = checkNotNull(l2Acl.getClassifyTable(), "L2 classify table is null"); - request.l2TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - final Ip4Acl ip4Acl = acl.getIp4Acl(); - if (ip4Acl != null) { - final String tableName = checkNotNull(ip4Acl.getClassifyTable(), "IPv4 classify table is null"); - request.ip4TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - final Ip6Acl ip6Acl = acl.getIp6Acl(); - if (ip6Acl != null) { - final String tableName = checkNotNull(ip6Acl.getClassifyTable(), "IPv6 classify table is null"); - request.ip6TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - - final CompletionStage inputAclSetInterfaceReplyCompletionStage = - futureJVppCore.inputAclSetInterface(request); - - getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java deleted file mode 100644 index 41e776fb5..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs for given interface (as defined in ietf-acl model). - * - * The customizer assumes it owns classify table management for interfaces where ietf-acl container is present. Using - * low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported and - * can result in unpredictable behaviour. - */ -public class IetfAclCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); - private final IngressIetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public IetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, - @Nonnull final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Adding ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java deleted file mode 100644 index e4fd83bd2..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AbstractIetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -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.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class IngressIetfAclWriter extends AbstractIetfAclWriter { - private final AclTableContextManager aclCtx; - - public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { - super(futureJVppCore); - this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); - } - - @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); - checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); - final MappingEntry entry = optional.get(); - unassignClassifyTables(id, entry); - removeClassifyTables(id, entry); - aclCtx.removeEntry(swIfIndex, mappingContext); - } - - private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, - @Nonnull final MappingEntry entry) - throws WriteFailedException { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 0; - request.swIfIndex = entry.getIndex(); - request.l2TableIndex = entry.getL2TableId(); - request.ip4TableIndex = entry.getIp4TableId(); - request.ip6TableIndex = entry.getIp6TableId(); - final CompletionStage inputAclSetInterfaceReplyCompletionStage = - jvpp.inputAclSetInterface(request); - getReplyForDelete(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); - } - - @Override - public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); - - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 1; - request.swIfIndex = swIfIndex; - request.l2TableIndex = NOT_DEFINED; - request.ip4TableIndex = NOT_DEFINED; - request.ip6TableIndex = NOT_DEFINED; - - if (InterfaceMode.L2.equals(mode)) { - final List aces = getACEs(acls, writeContext, ace -> true); - request.l2TableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); - } else { - final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); - request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); - final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); - request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); - } - - final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) - .setIp4TableId(request.ip4TableIndex) - .setIp6TableId(request.ip6TableIndex) - .setL2TableId(request.l2TableIndex) - .build(); - aclCtx.addEntry(entry, mappingContext); - - try { - getReplyForWrite(jvpp.inputAclSetInterface(request).toCompletableFuture(), id); - } catch (WriteFailedException e) { - removeClassifyTables(id, entry); - throw e; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java deleted file mode 100644 index b0be5d71f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs on given sub-interface. - */ -public class SubInterfaceAclCustomizer extends FutureJVppCustomizer - implements WriterCustomizer, AclWriter { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi, - @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(vppApi); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(true, id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(false, id, dataBefore, writeContext); - } - - private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - final String subInterfaceName = SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - - LOG.debug("Setting ACL(isAdd={}) on sub-interface={}(id={}): {}", - isAdd, subInterfaceName, subInterfaceIndex, acl); - inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, subInterfaceIndex, classifyTableContext, - writeContext.getMappingContext()); - LOG.debug("Successfully set ACL(isAdd={}) on sub-interface={}(id={}): {}", - isAdd, subInterfaceName, subInterfaceIndex, acl); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java deleted file mode 100644 index d28b8d66f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs for given sub-interface (as defined in ietf-acl model). - * - * The customizer assumes it owns classify table management for sub-interfaces where ietf-acl container is present. - * Using low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported - * and can result in unpredictable behaviour. - */ -public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); - private final IngressIetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public SubInterfaceIetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, - @Nonnull final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - final Optional subInterfaceOptional = - writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); - checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); - final SubInterface subInterface = subInterfaceOptional.get(); - - aclWriter - .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("Sub-interface ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("Sub-interface ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java deleted file mode 100644 index 713868d2e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.v3po.interfacesstate.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -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.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -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.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; -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; - -/** - * Customizer for reading ingress ACLs enabled on given interface. - */ -public class AclCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public AclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(jvpp); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { - ((AclBuilder) parentBuilder).setIngress(readValue); - } - - @Nonnull - @Override - public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new IngressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final IngressBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for interface ACL: {}", id); - final InterfaceKey interfaceKey = id.firstKeyOf(Interface.class); - checkArgument(interfaceKey != null, "No parent interface key found"); - - final ClassifyTableByInterface request = new ClassifyTableByInterface(); - request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext()); - - final ClassifyTableByInterfaceReply reply = - getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); - - builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Ingress readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder() - .setL2Acl(readValue.getL2Acl()) - .setIp4Acl(readValue.getIp4Acl()) - .setIp6Acl(readValue.getIp6Acl()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java deleted file mode 100644 index 19ea355e1..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.v3po.interfacesstate.acl.ingress; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2AclBuilder; - -interface AclReader { - - @Nonnull - default L2Acl readL2Acl(final int l2TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (l2TableId == ~0) { - return null; - } - return new L2AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(l2TableId, mappingContext)).build(); - } - - @Nonnull - default Ip4Acl readIp4Acl(final int ip4TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (ip4TableId == ~0) { - return null; - } - return new Ip4AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(ip4TableId, mappingContext)).build(); - } - - @Nonnull - default Ip6Acl readIp6Acl(final int ip6TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (ip6TableId == ~0) { - return null; - } - return new Ip6AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(ip6TableId, mappingContext)).build(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java deleted file mode 100644 index 4190619b8..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.v3po.interfacesstate.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -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.RWUtils; -import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -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.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -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; - -/** - * Customizer for reading ingress ACLs enabled on given sub-interface. - */ -public class SubInterfaceAclCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(jvpp); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { - ((AclBuilder) parentBuilder).setIngress(readValue); - } - - @Nonnull - @Override - public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new IngressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final IngressBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for sub-interface ACL: {}", id); - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - checkArgument(parentInterfacekey != null, "No parent interface key found"); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - checkArgument(subInterfacekey != null, "No sub-interface key found"); - final String subInterfaceName = - getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - - final ClassifyTableByInterface request = new ClassifyTableByInterface(); - request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); - - final ClassifyTableByInterfaceReply reply = - getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); - - builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final Ingress readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), readValue); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) - .child(Acl.class) - .child(Ingress.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java deleted file mode 100644 index 5d22df267..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedInts; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; -import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -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; - -/** - * Reader customizer responsible for classify session read.
to VPP.
Equivalent to invoking {@code vppctl show - * class table verbose} command. - */ -public class ClassifySessionReader extends FutureJVppCustomizer - implements ListReaderCustomizer, - InterfaceDataTranslator, VppNodeReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionReader.class); - static final String CACHE_KEY = ClassifySessionReader.class.getName(); - - private final VppClassifierContextManager classifyTableContext; - - public ClassifySessionReader(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((ClassifyTableBuilder) builder).setClassifySession(readData); - } - - @Nonnull - @Override - public ClassifySessionBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new ClassifySessionBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySessionBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for classify session: {}", id); - - final ClassifySessionKey key = id.firstKeyOf(ClassifySession.class); - checkArgument(key != null, "could not find ClassifySession key in {}", id); - - final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); - final byte[] match = DatatypeConverter.parseHexBinary(key.getMatch().getValue().replace(":", "")); - final Optional classifySession = - findClassifySessionDetailsByMatch(classifySessionDump, match); - - if (classifySession.isPresent()) { - final ClassifySessionDetails detail = classifySession.get(); - final Optional node = - readVppNode(detail.tableId, detail.hitNextIndex, classifyTableContext, ctx.getMappingContext(), LOG); - if (node.isPresent()) { - builder.setHitNext(node.get()); - } else { - builder.setHitNext(new VppNode(new VppNodeName("unknown"))); // TODO(HC2VPP-9): remove this workaround - } - if (detail.opaqueIndex != ~0) { - // value is specified: - builder.setOpaqueIndex(readOpaqueIndex(detail.tableId, detail.opaqueIndex, ctx.getMappingContext())); - } - builder.setAdvance(detail.advance); - builder.setMatch(key.getMatch()); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for classify session {} successfully read: {}", id, builder.build()); - } - } - } - - private OpaqueIndex readOpaqueIndex(final int tableIndex, final int opaqueIndex, final MappingContext ctx) { - // We first try to map the value to a vpp node, if that fails, simply wrap the u32 value - // TODO: HONEYCOMB-118 the approach might fail if the opaqueIndex contains small value that collides - // with some of the adjacent nodes - - final Optional node = readVppNode(tableIndex, opaqueIndex, classifyTableContext, ctx, LOG); - if (node.isPresent()) { - return new OpaqueIndex(node.get()); - } else { - return new OpaqueIndex(UnsignedInts.toLong(opaqueIndex)); - } - } - - @Nullable - private ClassifySessionDetailsReplyDump dumpClassifySessions(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) - throws ReadFailedException { - final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); - checkArgument(tableKey != null, "could not find ClassifyTable key in {}", id); - - final String cacheKey = CACHE_KEY + tableKey; - - ClassifySessionDetailsReplyDump classifySessionDump = - (ClassifySessionDetailsReplyDump) ctx.getModificationCache().get(cacheKey); - if (classifySessionDump != null) { - LOG.debug("Classify sessions is present in cache: {}", cacheKey); - return classifySessionDump; - } - - final String tableName = tableKey.getName(); - checkState(classifyTableContext.containsTable(tableName, ctx.getMappingContext()), - "Reading classify sessions for table {}, but table index could not be found in the classify table context", - tableName); - final int tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); - LOG.debug("Dumping classify sessions for classify table id={}", tableId); - - - final ClassifySessionDump dumpRequest = new ClassifySessionDump(); - dumpRequest.tableId = tableId; - final int timeOut = 30; // there can be many session with current ietf-acl implementation (could be probably - // removed after fixing HONEYCOMB-247) - classifySessionDump = - getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id, timeOut); - - if (classifySessionDump != null) { - // update the cache: - ctx.getModificationCache().put(cacheKey, classifySessionDump); - } - - return classifySessionDump; - } - - private static Optional findClassifySessionDetailsByMatch( - @Nullable final ClassifySessionDetailsReplyDump classifySessionDump, @Nonnull final byte[] match) { - if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { - final List details = classifySessionDump.classifySessionDetails; - final List filteredSessions = details.stream() - .filter(singleDetail -> Arrays.equals(singleDetail.match, match)).collect(Collectors.toList()); - if (filteredSessions.isEmpty()) { - return Optional.absent(); - } else if (filteredSessions.size() == 1) { - return Optional.of(filteredSessions.get(0)); - } else { - throw new IllegalStateException(String.format( - "Found %d classify sessions witch given match. Single session expected.", - filteredSessions.size())); - } - } - return Optional.absent(); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading list of keys for classify sessions: {}", id); - - final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); - if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { - return classifySessionDump.classifySessionDetails.stream() - .map(detail -> new ClassifySessionKey(new HexString(printHexBinary(detail.match)))) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java deleted file mode 100644 index 4e1a51265..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for classify session create/delete.
Sends {@code classify_add_del_session} message - * to VPP.
Equivalent to invoking {@code vppctl classify table} command. - */ -public class ClassifySessionWriter extends VppNodeWriter - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionWriter.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifySessionWriter(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Creating classify session: iid={} dataAfter={}", id, dataAfter); - try { - classifyAddDelSession(true, id, dataAfter, writeContext); - LOG.debug("Successfully created classify session: iid={} dataAfter={}", id, dataAfter); - } catch (VppBaseCallException e) { - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataBefore, - @Nonnull final ClassifySession dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException("Classify session update is not supported"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Removing classify session: iid={} dataBefore={}", id, dataBefore); - try { - classifyAddDelSession(false, id, dataBefore, writeContext); - LOG.debug("Successfully removed classify session: iid={} dataBefore={}", id, dataBefore); - } catch (VppBaseCallException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - } - - private void classifyAddDelSession(final boolean isAdd, @Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession classifySession, - @Nonnull final WriteContext writeContext) - throws VppBaseCallException, WriteFailedException { - final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); - checkArgument(tableKey != null, "could not find classify table key in {}", id); - - final String tableName = tableKey.getName(); - checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), - "Could not find classify table index for {} in the classify table context", tableName); - final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); - - final ClassifyTable classifyTable = - getClassifyTable(writeContext, id.firstIdentifierOf(ClassifyTable.class), isAdd); - final int hitNextIndex = getNodeIndex(classifySession.getHitNext(), classifyTable, classifyTableContext, - writeContext.getMappingContext(), id); - final int opaqueIndex = - getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); - - final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() - .classifyAddDelSession( - getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); - - getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); - } - - private ClassifyTable getClassifyTable(final WriteContext writeContext, - @Nonnull final InstanceIdentifier id, - final boolean isAdd) { - final Optional classifyTable; - if (isAdd) { - classifyTable = writeContext.readAfter(id); - } else { - classifyTable = writeContext.readBefore(id); - } - return classifyTable.get(); - } - - private ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, - @Nonnull final ClassifySession classifySession, - final int tableIndex, - final int hitNextIndex, - final int opaqueIndex) { - ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = booleanToByte(isAdd); - request.tableIndex = tableIndex; - request.hitNextIndex = hitNextIndex; - request.opaqueIndex = opaqueIndex; - - // default 0: - request.advance = classifySession.getAdvance(); - - request.match = DatatypeConverter.parseHexBinary(classifySession.getMatch().getValue().replace(":", "")); - return request; - } - - private int getOpaqueIndex(@Nullable final OpaqueIndex opaqueIndex, final ClassifyTable classifyTable, - final MappingContext ctx, final InstanceIdentifier id) - throws VppBaseCallException, WriteFailedException { - if (opaqueIndex == null) { - return ~0; // value not specified - } - if (opaqueIndex.getUint32() != null) { - return opaqueIndex.getUint32().intValue(); - } else { - return getNodeIndex(opaqueIndex.getVppNode(), classifyTable, classifyTableContext, ctx, id); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java deleted file mode 100644 index 6ecfbaa45..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedInts; -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.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.MacTranslator; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Arrays; -import java.util.Collections; -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.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -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; - -/** - * Reader customizer responsible for classify table read.
to VPP.
Equivalent to invoking {@code vppctl show - * class table} command. - */ -public class ClassifyTableReader extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, VppNodeReader, - MacTranslator, InterfaceDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableReader.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifyTableReader(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((VppClassifierStateBuilder) builder).setClassifyTable(readData); - } - - @Nonnull - @Override - public ClassifyTableBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new ClassifyTableBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTableBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for classify table: {}", id); - - final ClassifyTableKey key = id.firstKeyOf(ClassifyTable.class); - checkArgument(key != null, "could not find ClassifyTable key in {}", id); - final ClassifyTableInfo request = new ClassifyTableInfo(); - - final String tableName = key.getName(); - if (!classifyTableContext.containsTable(tableName, ctx.getMappingContext())) { - LOG.debug("Could not find classify table {} in the naming context", tableName); - return; - } - request.tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); - - - final ClassifyTableInfoReply reply = - getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); - - // mandatory values: - builder.setName(tableName); - builder.setKey(key); - builder.setNbuckets(UnsignedInts.toLong(reply.nbuckets)); - builder.setSkipNVectors(UnsignedInts.toLong(reply.skipNVectors)); - - // optional value read from context - final Optional tableBaseNode = - classifyTableContext.getTableBaseNode(tableName, ctx.getMappingContext()); - if (tableBaseNode.isPresent()) { - builder.setClassifierNode(new VppNodeName(tableBaseNode.get())); - } - - final Optional node = - readVppNode(reply.tableId, reply.missNextIndex, classifyTableContext, ctx.getMappingContext(), LOG); - if (node.isPresent()) { - builder.setMissNext(node.get()); - } else { - builder.setMissNext(new VppNode(new VppNodeName("unknown"))); // TODO(HC2VPP-9): remove this workaround - } - builder.setMask(new HexString(printHexBinary(reply.mask))); - builder.setActiveSessions(UnsignedInts.toLong(reply.activeSessions)); - - if (reply.nextTableIndex != ~0) { - // next table index is present: - builder.setNextTable(classifyTableContext.getTableName(reply.nextTableIndex, ctx.getMappingContext())); - } - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for classify table {} successfully read: {}", id, builder.build()); - } - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - LOG.debug("Reading list of keys for classify tables: {}", id); - - final ClassifyTableIdsReply classifyTableIdsReply = - getReplyForRead(getFutureJVpp().classifyTableIds(new ClassifyTableIds()).toCompletableFuture(), - id); - if (classifyTableIdsReply.ids != null) { - return Arrays.stream(classifyTableIdsReply.ids).mapToObj(i -> { - final String tableName = classifyTableContext.getTableName(i, context.getMappingContext()); - LOG.trace("Classify table with name: {} and index: {} found in VPP", tableName, i); - return new ClassifyTableKey(tableName); - }).collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder(readValue) - .setName(readValue.getName()) - .build()); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InstanceIdentifier.create(VppClassifier.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey(id.firstKeyOf(ClassifyTable.class).getName())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java deleted file mode 100644 index 62b6a2142..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for classify table create/delete.
Sends {@code classify_add_del_table} message to - * VPP.
Equivalent to invoking {@code vppctl classify table} command. - */ -public class ClassifyTableWriter extends VppNodeWriter - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableWriter.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifyTableWriter(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Creating classify table: iid={} dataAfter={}", id, dataAfter); - try { - final int newTableIndex = - classifyAddDelTable(true, id, dataAfter, ~0 /* value not present */, - writeContext.getMappingContext()); - - // Add classify table name <-> vpp index mapping to the naming context: - classifyTableContext.addTable(newTableIndex, dataAfter.getName(), dataAfter.getClassifierNode(), - writeContext.getMappingContext()); - LOG.debug("Successfully created classify table(id={]): iid={} dataAfter={}", newTableIndex, id, dataAfter); - } catch (VppBaseCallException e) { - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataBefore, @Nonnull final ClassifyTable dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException("Classify table update is not supported"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Removing classify table: iid={} dataBefore={}", id, dataBefore); - final String tableName = dataBefore.getName(); - checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), - "Removing classify table {}, but index could not be found in the classify table context", tableName); - - final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); - try { - classifyAddDelTable(false, id, dataBefore, tableIndex, writeContext.getMappingContext()); - - // Remove deleted interface from interface context: - classifyTableContext.removeTable(dataBefore.getName(), writeContext.getMappingContext()); - LOG.debug("Successfully removed classify table(id={]): iid={} dataAfter={}", tableIndex, id, dataBefore); - } catch (VppBaseCallException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - } - - private int classifyAddDelTable(final boolean isAdd, @Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable table, final int tableId, final MappingContext ctx) - throws VppBaseCallException, WriteFailedException { - - final int missNextIndex = - getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); - - final CompletionStage createClassifyTableReplyCompletionStage = - getFutureJVpp() - .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); - - final ClassifyAddDelTableReply reply = - getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); - return reply.newTableIndex; - } - - private ClassifyAddDelTable getClassifyAddDelTableRequest(final boolean isAdd, final int tableIndex, - @Nonnull final ClassifyTable table, - final int missNextIndex, - @Nonnull final MappingContext ctx) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = booleanToByte(isAdd); - request.tableIndex = tableIndex; - - // mandatory, all u32 values are permitted: - request.nbuckets = table.getNbuckets().intValue(); - request.memorySize = table.getMemorySize().intValue(); - request.skipNVectors = table.getSkipNVectors().intValue(); - - // mandatory - request.missNextIndex = missNextIndex; - - final String nextTable = table.getNextTable(); - if (isAdd && nextTable != null) { - request.nextTableIndex = classifyTableContext.getTableIndex(nextTable, ctx); - } else { - request.nextTableIndex = ~0; // value not specified - } - request.mask = DatatypeConverter.parseHexBinary(table.getMask().getValue().replace(":", "")); - checkArgument(request.mask.length % 16 == 0, "Number of mask bytes must be multiple of 16."); - request.matchNVectors = request.mask.length / 16; - - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java deleted file mode 100644 index c06ef2700..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; - -/** - * Manages metadata for vpp-classifier - */ -public interface VppClassifierContextManager { - - /** - * Creates metadata for classify table. - * - * @param id classify table index - * @param name classify table name - * @param classifierNode name of VPP node the table is defined for - * @param ctx mapping context providing context data for current transaction - */ - void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, - @Nonnull final MappingContext ctx); - - /** - * Check whether metadata for given classify table metadata is present. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return true if present, false otherwise - */ - boolean containsTable(@Nonnull String name, @Nonnull final MappingContext ctx); - - /** - * Returns classify table index associated with the given name. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return integer index value matching supplied classify table name - * @throws IllegalArgumentException if classify table was not found - */ - int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx); - - /** - * Retrieves classify table name for given id. If not present, artificial name will be generated. - * - * @param id classify table index - * @param ctx mapping context providing context data for current transaction - * @return classify table name matching supplied index - */ - String getTableName(final int id, @Nonnull final MappingContext ctx); - - /** - * Returns name of the base vpp node associated with the classify table. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return name of VPP node the table is defined for - */ - Optional getTableBaseNode(final String name, @Nonnull final MappingContext ctx); - - /** - * Removes classify table metadata from current context. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - */ - void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx); - - /** - * Adds relative node index to node name mapping for given classify table. - * - * @param tableName classify table name - * @param nodeIndex index of a vpp node, relative to table's base node - * @param nodeName name of a vpp node - * @param ctx mapping context providing context data for current transaction - */ - void addNodeName(@Nonnull String tableName, final int nodeIndex, @Nonnull final String nodeName, - @Nonnull final MappingContext ctx); - - /** - * Retrieves node name associated with the given classify table and node index. - * - * @param tableIndex classify table index - * @param nodeIndex relative index of a vpp node - * @param ctx mapping context providing context data for current transaction - * @return name of vpp node - */ - Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java deleted file mode 100644 index 2255c78a7..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.BindingBrokerReader; -import java.util.List; -import java.util.stream.Collector; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.inject.Named; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -/** - * Facade on top of {@link MappingContext} that manages {@link ClassifyTableContext}. - */ -public final class VppClassifierContextManagerImpl implements VppClassifierContextManager { - private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - @VisibleForTesting - static final InstanceIdentifier - VPP_CLASSIFIER_CONTEXT_IID = KeyedInstanceIdentifier.create(VppClassifierContext.class); - private final String artificialNamePrefix; - - /** - * Creates new VppClassifierContextManagerImpl. - * - * @param artificialNamePrefix artificial name to be used to generate names for classify tables without existing - * metadata - */ - public VppClassifierContextManagerImpl(@Nonnull final String artificialNamePrefix) { - this.artificialNamePrefix = - Preconditions.checkNotNull(artificialNamePrefix, "artificialNamePrefix should not be null"); - } - - private KeyedInstanceIdentifier getMappingIid(final String name) { - return VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(name)); - } - - @Override - public void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, - @Nonnull final MappingContext ctx) { - final KeyedInstanceIdentifier mappingIid = getMappingIid(name); - final ClassifyTableContextBuilder tableCtx = new ClassifyTableContextBuilder().setIndex(id).setName(name); - if (classifierNode != null) { - tableCtx.setClassifierNodeName(classifierNode.getValue()); - } - ctx.put(mappingIid, tableCtx.build()); - } - - @Override - public boolean containsTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - return read.isPresent(); - } - - @Override - public int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - checkArgument(read.isPresent(), "No mapping stored for name: %s", name); - return read.get().getIndex(); - } - - @Override - public String getTableName(final int id, @Nonnull final MappingContext ctx) { - if (!containsName(id, ctx)) { - final String artificialName = getArtificialName(id); - addTable(id, artificialName, null, ctx); - } - - final Optional read = ctx.read(VPP_CLASSIFIER_CONTEXT_IID); - checkState(read.isPresent(), "VppClassifierContext for index: %s is not present. But should be", id); - - return read.get().getClassifyTableContext().stream() - .filter(t -> t.getIndex().equals(id)) - .collect(SINGLE_ITEM_COLLECTOR).getName(); - } - - private boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { - final Optional read = mappingContext.read(VPP_CLASSIFIER_CONTEXT_IID); - return read.isPresent() - ? read.get().getClassifyTableContext().stream().anyMatch(t -> t.getIndex().equals(index)) - : false; - } - - @Override - public Optional getTableBaseNode(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - if (read.isPresent()) { - return Optional.fromNullable(read.get().getClassifierNodeName()); - } - return Optional.absent(); - } - - @Override - public void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { - ctx.delete(getMappingIid(name)); - } - - @Override - public void addNodeName(@Nonnull final String tableName, final int nodeIndex, - @Nonnull final String nodeName, - @Nonnull final MappingContext ctx) { - final KeyedInstanceIdentifier iid = - getMappingIid(tableName).child(NodeContext.class, new NodeContextKey(nodeName)); - ctx.put(iid, new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build()); - } - - @Override - public Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx) { - if (!containsName(tableIndex, ctx)) { - return Optional.absent(); - } - final String tableName = getTableName(tableIndex, ctx); - final Optional tableCtx = ctx.read(getMappingIid(tableName)); - final List nodeContext = tableCtx.get().getNodeContext(); - if (nodeContext == null) { - return Optional.absent(); - } - return Optional.fromNullable(nodeContext.stream() - .filter(n -> n.getIndex().equals(nodeIndex)) - .findFirst() - .map(nodes -> nodes.getName()) - .orElse(null)); - } - - private String getArtificialName(final int index) { - return artificialNamePrefix + index; - } - - public static final class ContextsReaderFactory implements ReaderFactory { - - @Inject - @Named("honeycomb-context") - private DataBroker contextBindingBrokerDependency; - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - registry.add(new BindingBrokerReader<>(VPP_CLASSIFIER_CONTEXT_IID, - contextBindingBrokerDependency, - LogicalDatastoreType.OPERATIONAL, VppClassifierContextBuilder.class)); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java deleted file mode 100644 index c25a4572c..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.slf4j.Logger; - -interface VppNodeReader { - - /** - * Converts vpp node index to YANG representation of vpp node. - * - * @param nodeIndex index of vpp node treated as signed integer. - * @return vpp node representation - */ - default Optional readVppNode(final int tableIndex, final int nodeIndex, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final Logger log) { - final PacketHandlingAction action = PacketHandlingAction.forValue(nodeIndex); - if (action == null) { - return vppClassifierContextManager.getNodeName(tableIndex, nodeIndex, ctx) - .transform(nodeName -> new VppNode(new VppNodeName(nodeName))); - } - return Optional.of(new VppNode(action)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java deleted file mode 100644 index dd0b2d5ec..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.GetNextIndex; -import io.fd.vpp.jvpp.core.dto.GetNextIndexReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -abstract class VppNodeWriter extends FutureJVppCustomizer implements JvppReplyConsumer { - - protected VppNodeWriter(@Nonnull final FutureJVppCore futureJvpp) { - super(futureJvpp); - } - - protected int getNodeIndex(@Nonnull final VppNode node, @Nonnull final ClassifyTable classifyTable, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) - throws VppBaseCallException, WriteFailedException { - if (node.getPacketHandlingAction() != null) { - return node.getPacketHandlingAction().getIntValue(); - } else { - return nodeNameToIndex(classifyTable, node.getVppNodeName().getValue(), vppClassifierContextManager, ctx, - id); - } - } - - private int nodeNameToIndex(@Nonnull final ClassifyTable classifyTable, @Nonnull final String nextNodeName, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) - throws WriteFailedException { - checkArgument(classifyTable != null && classifyTable.getClassifierNode() != null, - "to use relative node names, table classifier node needs to be provided"); - final GetNextIndex request = new GetNextIndex(); - request.nodeName = classifyTable.getClassifierNode().getValue().getBytes(); - request.nextName = nextNodeName.getBytes(); - final CompletionStage getNextIndexCompletionStage = - getFutureJVpp().getNextIndex(request); - - final GetNextIndexReply reply; - try { - reply = getReplyForRead(getNextIndexCompletionStage.toCompletableFuture(), id); - - // vpp does not provide relative node index to node name conversion (https://jira.fd.io/browse/VPP-219) - // as a workaround we need to add mapping to vpp-classfier-context - vppClassifierContextManager.addNodeName(classifyTable.getName(), reply.nextIndex, nextNodeName, ctx); - } catch (ReadFailedException e) { - throw new WriteFailedException(id, String.format("Failed to get node index for %s relative to %s", - nextNodeName, classifyTable.getClassifierNode()), e); - } - return reply.nextIndex; - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModuleTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModuleTest.java deleted file mode 100644 index f134e661a..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/ClassifierIetfAclModuleTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.v3po; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.HashSet; -import java.util.Set; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -public class ClassifierIetfAclModuleTest { - - @Bind - @Mock - private FutureJVppCore futureJVppCore; - - @Named("interface-context") - @Bind - private NamingContext ifcContext; - - @Inject - private Set writerFactories = new HashSet<>(); - - @Before - public void setUp() { - initMocks(this); - ifcContext = new NamingContext("interface-", "interface-context"); - Guice.createInjector(new ClassifierIetfAclModule(), BoundFieldModule.of(this)).injectMembers(this); - } - - @Test - public void testWriterFactories() throws Exception { - assertThat(writerFactories, is(not(empty()))); - - // Test registration process (all dependencies present, topological order of writers does exist, etc.) - final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(); - writerFactories.stream().forEach(factory -> factory.init(registryBuilder)); - assertNotNull(registryBuilder.build()); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java deleted file mode 100644 index 441247f66..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.v3po.interfaces; - -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.ingress.AclCustomizer; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final int ACL_TABLE_INDEX = 0; - private static final String ACL_TABLE_NAME = "table0"; - @Mock - private VppClassifierContextManager classifyTableContext; - private AclCustomizer customizer; - - private static InputAclSetInterface generateInputAclSetInterface(final byte isAdd, final int ifIndex, - final int l2TableIndex) { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = isAdd; - request.l2TableIndex = l2TableIndex; - request.ip4TableIndex = ~0; - request.ip6TableIndex = ~0; - request.swIfIndex = ifIndex; - return request; - } - - @Override - public void setUpTest() { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - customizer = new AclCustomizer(api, new NamingContext("generatedInterfaceName", IFC_TEST_INSTANCE), - classifyTableContext); - } - - private InstanceIdentifier getAclId(final String name) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( - VppInterfaceAugmentation.class).child(Acl.class).child(Ingress.class); - } - - private Ingress generateAcl(final String tableName) { - final IngressBuilder builder = new IngressBuilder(); - final L2Acl l2Acl = new L2AclBuilder().setClassifyTable(tableName).build(); - builder.setL2Acl(l2Acl); - return builder.build(); - } - - private void whenInputAclSetInterfaceThenSuccess() { - doReturn(future(new InputAclSetInterfaceReply())).when(api) - .inputAclSetInterface(any(InputAclSetInterface.class)); - } - - private void whenInputAclSetInterfaceThenFailure() { - doReturn(failedFuture()).when(api).inputAclSetInterface(any(InputAclSetInterface.class)); - } - - @Test - public void testCreate() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenSuccess(); - - customizer.writeCurrentAttributes(id, acl, writeContext); - - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); - } - - @Test - public void testCreateFailed() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenFailure(); - - try { - customizer.writeCurrentAttributes(id, acl, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testDelete() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenSuccess(); - - customizer.deleteCurrentAttributes(id, acl, writeContext); - - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, acl, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java deleted file mode 100644 index 0df8e5b7b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.v3po.interfaces.acl; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.Collections; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -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.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclWriterTest extends WriterCustomizerTest { - - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(ACL_NAME, ACL_TYPE)); - - @Mock - private Acl acl; - private IetfAclWriter customizer; - - @Override - public void setUpTest() { - customizer = new IetfAclWriter(); - when(acl.getAclName()).thenReturn(ACL_NAME); - doReturn(ACL_TYPE).when(acl).getAclType(); - } - - private void defineInterfacesContext(final List interfaces) { - when(writeContext.readAfter(InstanceIdentifier.create(Interfaces.class))).thenReturn(Optional.of( - new InterfacesBuilder().setInterface(interfaces).build() - )); - } - - @Test - public void testWrite() throws Exception { - customizer.writeCurrentAttributes(IID, acl, writeContext); - } - - @Test - public void testUpdate() throws WriteFailedException { - defineInterfacesContext(Collections.emptyList()); - customizer.updateCurrentAttributes(IID, acl, acl, writeContext); - } - - @Test - public void testDelete() throws WriteFailedException { - defineInterfacesContext(Collections.emptyList()); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - } - - @Test(expected = WriteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - final Interface iface = new InterfaceBuilder().addAugmentation(VppInterfaceAugmentation.class, - new VppInterfaceAugmentationBuilder().setIetfAcl( - new IetfAclBuilder().setIngress( - new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder().setName(ACL_NAME).setType(ACL_TYPE).build()) - ).build() - ).build() - ).build() - ).build() - ).build(); - defineInterfacesContext(Collections.singletonList(iface)); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java deleted file mode 100644 index 9a1697e67..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -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.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.matches.ace.type.AceEth; -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.ace.type.AceEthBuilder; -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.classfier.acl.rev161214.InterfaceMode; - -public class AceEthWriterTest { - - private AceEthWriter writer; - private PacketHandling action; - private AceEth aceEth; - - @Before - public void setUp() { - initMocks(this); - writer = new AceEthWriter(); - action = new DenyBuilder().setDeny(true).build(); - aceEth = new AceEthBuilder() - .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) - .setDestinationMacAddressMask(new MacAddress("ff:ff:ff:ff:ff:ff")) - .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) - .setSourceMacAddressMask(new MacAddress("ff:ff:ff:00:00:00")) - .build(); - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceEth, InterfaceMode.L2, nextTableIndex, 0); - - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(AceEthWriter.MATCH_N_VECTORS, request.matchNVectors); - assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // destination MAC: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // source MAC: - (byte) 0xff, (byte) 0xff, (byte) 0xff, 0, 0, 0, - 0, 0, 0, 0 - }; - assertArrayEquals(expectedMask, request.mask); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceEth, InterfaceMode.L2, tableIndex, 0).get(0); - - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // destination MAC: - (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - // source MAC: - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, - 0, 0, 0, 0 - }; - assertArrayEquals(expectedMatch, request.match); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java deleted file mode 100644 index d53b32e88..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static io.fd.hc2vpp.v3po.interfaces.acl.common.AclTranslator.VLAN_TAG_LEN; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -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.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.matches.ace.type.AceIp; -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.ace.type.AceIpBuilder; -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.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; -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.PortNumber; -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.SourcePortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; - -public class AceIp4WriterTest { - - private AceIp4Writer writer; - private PacketHandling action; - private AceIp aceIp; - - @Before - public void setUp() throws Exception { - initMocks(this); - writer = new AceIp4Writer(); - action = new DenyBuilder().setDeny(true).build(); - aceIp = new AceIpBuilder() - .setProtocol((short) 132) - .setDscp(new Dscp((short) 11)) - .setAceIpVersion(new AceIpv4Builder() - .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")) - .setDestinationIpv4Network(new Ipv4Prefix("1.2.4.5/24")) - .build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build(); - } - - private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(AceIp4Writer.MATCH_N_VECTORS, request.matchNVectors); - assertEquals(AceIp4Writer.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp: - (byte) 0x00, (byte) 0xfc, - // protocol: - 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, 0, 0, - // source address: - -1, -1, -1, -1, - // destination address: - -1, -1, -1, 0, - // source and destination port: - -1, -1, -1, -1, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMask[12] = (byte) 0xff; - expectedMask[13] = (byte) 0xff; - } - AceIpWriterTestUtils - .assertArrayEqualsWithOffset(expectedMask, expectedMask.length, request.mask, vlanTags * VLAN_TAG_LEN); - - } - - private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp: - 0, (byte) 0x2c, - // protocol (132): - 0, 0, 0, 0, 0, 0, 0, (byte) 132, 0, 0, - // source address: - 1, 2, 3, 4, - // destination address: - 1, 2, 4, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMatch[12] = (byte) 0x08; - expectedMatch[13] = (byte) 0x00; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, expectedMatch.length, request.match, vlanTags * VLAN_TAG_LEN); - - } - - @Test - public void testCreateTable() throws Exception { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, false); - } - - @Test - public void testCreateTableForL2Interface() throws Exception { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, true); - } - - @Test - public void testCreateTable1VlanTag() throws Exception { - final int nextTableIndex = 42; - final int vlanTags = 1; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateTable2VlanTags() throws Exception { - final int nextTableIndex = 42; - final int vlanTags = 2; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession() throws Exception { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, false); - } - - @Test - public void testCreateClassifySessionForL2Interface() throws Exception { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, true); - } - - @Test - public void testCreateClassifySession1VlanTag() throws Exception { - final int tableIndex = 123; - final int vlanTags = 1; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession2VlanTags() throws Exception { - final int tableIndex = 123; - final int vlanTags = 2; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - - verifySessionRequest(request, tableIndex, vlanTags, false); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java deleted file mode 100644 index 483377a66..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -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.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.matches.ace.type.AceIp; -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.ace.type.AceIpBuilder; -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.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; -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.DestinationPortRangeBuilder; -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.classfier.acl.rev161214.InterfaceMode; - -public class AceIp6WriterTest { - - private AceIp6Writer writer; - private PacketHandling action; - private AceIp aceIp; - - @Before - public void setUp() { - initMocks(this); - writer = new AceIp6Writer(); - action = new DenyBuilder().setDeny(true).build(); - aceIp = new AceIpBuilder() - .setProtocol((short) 132) - .setDscp(new Dscp((short) 11)) - .setAceIpVersion(new AceIpv6Builder() - .setFlowLabel(new Ipv6FlowLabel(123L)) - .setSourceIpv6Network(new Ipv6Prefix("2001:db8:85a3:8d3:1319:8a2e:370:7348/128")) - .setDestinationIpv6Network(new Ipv6Prefix("fe80:1234:5678:abcd:ef01::/64")) - .build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build(); - } - - - private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(vlanTags == 2 ? 5 : 4, request.matchNVectors); - assertEquals(AceIp6Writer.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp, flow: - (byte) 0x0f, (byte) 0xcf, (byte) 0xff, (byte) 0xff, - // protocol: - 0, 0, (byte) 0xff, 0, - // source address: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // destination address: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - 0, 0, 0, 0, 0, 0, 0, 0, - // source and destination port: - -1, -1, -1, -1, - // padding to multiple of 16B: - 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMask[12] = (byte) 0xff; - expectedMask[13] = (byte) 0xff; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMask, vlanTags == 2 ? 80 : 64, request.mask, vlanTags * AclTranslator.VLAN_TAG_LEN); - } - - private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp(11), flow(123): - (byte) 0x02, (byte) 0xc0, (byte) 0x00, (byte) 0x7b, - // protocol (132): - 0, 0, (byte) 132, 0, - // source address: - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, (byte) 0x08, (byte) 0xd3, - (byte) 0x13, (byte) 0x19, (byte) 0x8a, (byte) 0x2e, (byte) 0x03, (byte) 0x70, (byte) 0x73, (byte) 0x48, - // destination address: - (byte) 0xfe, (byte) 0x80, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0xab, (byte) 0xcd, - 0, 0, 0, 0, 0, 0, 0, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding to multiple of 16B: - 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMatch[12] = (byte) 0x86; - expectedMatch[13] = (byte) 0xdd; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, vlanTags == 2 ? 80 : 64, request.match, vlanTags * AclTranslator.VLAN_TAG_LEN); - - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, false); - } - - @Test - public void testCreateTableForL2Interface() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, true); - } - - @Test - public void testCreateTable1VlanTag() { - final int nextTableIndex = 42; - final int vlanTags = 1; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateTable2VlanTags() { - final int nextTableIndex = 42; - final int vlanTags = 2; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, false); - } - - @Test - public void testCreateClassifySessionForL2Interface() { - final int tableIndex = 123; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, true); - } - - @Test - public void testCreateClassifySession1VlanTag() { - final int tableIndex = 123; - final int vlanTags = 1; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession2VlanTags() { - final int tableIndex = 123; - final int vlanTags = 2; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java deleted file mode 100644 index 4d155b2f3..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -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.DenyBuilder; -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.PortNumber; -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.SourcePortRangeBuilder; -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.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEthBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4Builder; - -public class AceIpAndEthWriterTest { - - private AceIpAndEthWriter writer; - private PacketHandling action; - private AceIpAndEth ace; - - @Before - public void setUp() { - initMocks(this); - writer = new AceIpAndEthWriter(); - action = new DenyBuilder().setDeny(true).build(); - ace = new AceIpAndEthBuilder().setAceIpAndEthNodes(new AceIpAndEthNodesBuilder() - .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) - .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) - .setAceIpVersion(new AceIpv4Builder() - .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")).build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build()).build(); - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(ace, InterfaceMode.L2, nextTableIndex, 0); - - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(3, request.matchNVectors); - assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // destination MAC: - -1, -1, -1, -1, -1, -1, - // source MAC: - -1, -1, -1, -1, -1, -1, - // ether type: - -1, -1, - // IP header - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // source address: - -1, -1, -1, -1, - // destination address: - 0, 0, 0, 0, - // source and destination port: - -1, -1, -1, -1, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assertArrayEquals(expectedMask, request.mask); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, ace, InterfaceMode.L2, tableIndex, 0).get(0); - - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // destination MAC: - (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - // source MAC: - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, - // ether type (IP4): - 0x08, 0, - // IP header - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // source address: - 1, 2, 3, 4, - // destination address: - 0, 0, 0, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assertArrayEquals(expectedMatch, request.match); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java deleted file mode 100644 index 087d91d26..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; - -final class AceIpWriterTestUtils { - - private AceIpWriterTestUtils() { - throw new UnsupportedOperationException("This utility class cannot be instantiated"); - } - - protected static void assertArrayEqualsWithOffset(final byte[] baseExpected, final int expectedLength, final byte[] actual, - final int offset) { - byte[] expected = new byte[expectedLength]; - System.arraycopy(baseExpected, 0, expected, offset, Math.min(baseExpected.length, expectedLength-offset)); - - assertArrayEquals(expected, actual); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java deleted file mode 100644 index 3f106ccce..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.honeycomb.translate.MappingContext; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; - -public class AclTableContextManagerImplTest { - - private AclTableContextManagerImpl ctx; - @Mock - private MappingContext mappingContext; - private static final int INDEX = 42; - - @Before - public void setUp() throws Exception { - initMocks(this); - ctx = new AclTableContextManagerImpl(MappingTable.Direction.Ingress); - } - - @Test - public void testAddEntry() throws Exception { - final MappingEntry entry = - new MappingEntryBuilder().setL2TableId(1).setIp4TableId(2).setIp6TableId(3).setIndex(INDEX).build(); - ctx.addEntry(entry, mappingContext); - verify(mappingContext).put(ctx.getId(INDEX), entry); - } - - @Test - public void testRemoveEntry() throws Exception { - ctx.removeEntry(INDEX, mappingContext); - verify(mappingContext).delete(ctx.getId(INDEX)); - } - - @Test - public void testReadEntry() throws Exception { - ctx.getEntry(INDEX, mappingContext); - verify(mappingContext).read(ctx.getId(INDEX)); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java deleted file mode 100644 index f5c319fb6..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.v3po.interfaces.acl.common; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasSize; - -import java.util.List; -import org.junit.Test; -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; - -public class PortPairTest { - - @Test - public void testSingleSrc() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final List portPairs = PortPair.fromRange(src, null); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(123, null))); - } - - @Test - public void testSrcRange() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(123)) - .setUpperPort(new PortNumber(125)).build(); - final List portPairs = PortPair.fromRange(src, null); - assertThat(portPairs, hasSize(3)); - assertThat(portPairs, contains(new PortPair(123, null), new PortPair(124, null), new PortPair(125, null))); - } - - @Test - public void testSrcRangeWithDst() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(123)) - .setUpperPort(new PortNumber(125)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(111)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(3)); - assertThat(portPairs, contains(new PortPair(123, 111), new PortPair(124, 111), new PortPair(125, 111))); - } - - @Test - public void testSingleDst() { - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final List portPairs = PortPair.fromRange(null, dst); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(null, 123))); - } - - @Test - public void testDstRange() { - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(10)) - .setUpperPort(new PortNumber(11)).build(); - final List portPairs = PortPair.fromRange(null, dst); - assertThat(portPairs, hasSize(2)); - assertThat(portPairs, contains(new PortPair(null, 10), new PortPair(null, 11))); - } - - @Test - public void testDstRangeWithSrc() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(111)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(10)) - .setUpperPort(new PortNumber(11)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(2)); - assertThat(portPairs, contains(new PortPair(111, 10), new PortPair(111, 11))); - } - - @Test - public void testSinglePair() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(321)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(123, 321))); - } - - @Test - public void testCartesianProduct() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(1)) - .setUpperPort(new PortNumber(2)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(1)) - .setUpperPort(new PortNumber(3)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(6)); - assertThat(portPairs, - contains(new PortPair(1, 1), new PortPair(1, 2), new PortPair(1, 3), new PortPair(2, 1), new PortPair(2, 2), - new PortPair(2, 3))); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java deleted file mode 100644 index cb182272a..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -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.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.MatchesBuilder; -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.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -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.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class EgressIetfAclWriterTest extends WriterCustomizerTest { - - private static final int IF_INDEX = 1; - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - private EgressIetfAclWriter writer; - @Mock - private AclTableContextManager aclCtx; - @Mock - private InstanceIdentifier id; - - private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { - final ClassifyAddDelTable reply = new ClassifyAddDelTable(); - reply.tableIndex = tableIndex; - reply.delChain = 1; - return reply; - } - - @Override - protected void setUpTest() throws Exception { - writer = new EgressIetfAclWriter(api, aclCtx); - } - - private ClassifySetInterfaceL2Tables classifySetInterfaceL2TablesRequest() { - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - request.otherTableIndex = -1; - request.swIfIndex = IF_INDEX; - return request; - } - - @Test - public void testDeleteAcl() throws Exception { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); - when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(IF_INDEX) - .setL2TableId(1) - .setIp4TableId(2) - .setIp6TableId(3) - .build())); - - writer.deleteAcl(id, IF_INDEX, mappingContext); - - verify(api).classifySetInterfaceL2Tables(classifySetInterfaceL2TablesRequest()); - verify(api).classifyAddDelTable(classifyAddDelTable(1)); - verify(api).classifyAddDelTable(classifyAddDelTable(2)); - verify(api).classifyAddDelTable(classifyAddDelTable(3)); - verify(aclCtx).removeEntry(IF_INDEX, mappingContext); - } - - @Test - public void testWrite() throws Exception { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); - when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); - - final Egress - acl = new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(InterfaceMode.L2).build() - ).build(); - - final AccessLists accessLists = acl.getAccessLists(); - - when(writeContext.readAfter(any())).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Collections.singletonList(new AceBuilder() - .setMatches(new MatchesBuilder().setAceType( - new AceIpBuilder() - .setAceIpVersion(new AceIpv4Builder().build()) - .setProtocol((short) 1) - .build() - ).build()) - .setActions(new ActionsBuilder().setPacketHandling(new PermitBuilder().build()).build()) - .build())).build() - ).build() - - )); - - writer.write(id, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, mappingContext); - - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; - request.swIfIndex = IF_INDEX; - request.otherTableIndex = -1; - request.ip4TableIndex = 0; - request.ip6TableIndex = -1; - verify(api).classifySetInterfaceL2Tables(request); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java deleted file mode 100644 index 079f9f745..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.MixedAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class IetfAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - VppInterfaceAugmentation.class).child(IetfAcl.class).child(Egress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = MixedAcl.class; - - @Mock - private IetfAclWriter aclWriter; - private IetfAclCustomizer customizer; - - private static Egress acl(final InterfaceMode mode) { - return new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(mode) - .build() - ).build(); - } - - @Override - protected void setUpTest() { - customizer = new IetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - } - - private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { - verify(aclWriter) - .write(IID, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, mappingContext); - } - - private void verifyDelete() throws WriteFailedException { - verify(aclWriter).deleteAcl(IID, IF_INDEX, mappingContext); - } - - @Test - public void testWriteL3() throws Exception { - customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); - verifyZeroInteractions(aclWriter); - } - - @Test - public void testWriteL2() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.writeCurrentAttributes(IID, acl, writeContext); - verifyWrite(acl.getAccessLists()); - } - - @Test - public void testUpdate() throws Exception { - final Egress aclBefore = acl(InterfaceMode.L3); - final Egress aclAfter = acl(InterfaceMode.L2); - customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); - verifyDelete(); - verifyWrite(aclAfter.getAccessLists()); - } - - @Test - public void testDelete() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - verifyDelete(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java deleted file mode 100644 index 83427ea92..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.v3po.interfaces.acl.egress; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.MixedAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.EgressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.0"; - private static final int SUBIF_INDEX = 11; - private static final long SUBIF_ID = 0; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(IetfAcl.class).child(Egress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = MixedAcl.class; - - @Mock - private IetfAclWriter aclWriter; - private SubInterfaceIetfAclCustomizer customizer; - - private static Egress acl(final InterfaceMode mode) { - return new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(mode) - .build() - ).build(); - } - - @Override - protected void setUpTest() { - customizer = new SubInterfaceIetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - - - when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( - new SubInterfaceBuilder().build() - )); - } - - private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { - verify(aclWriter) - .write(IID, SUBIF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, 0, mappingContext); - } - - private void verifyDelete() throws WriteFailedException { - verify(aclWriter).deleteAcl(IID, SUBIF_INDEX, mappingContext); - } - - @Test - public void testWriteL3() throws Exception { - customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); - verifyZeroInteractions(aclWriter); - } - - @Test - public void testWriteL2() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.writeCurrentAttributes(IID, acl, writeContext); - verifyWrite(acl.getAccessLists()); - } - - @Test - public void testUpdate() throws Exception { - final Egress aclBefore = acl(InterfaceMode.L3); - final Egress aclAfter = acl(InterfaceMode.L2); - customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); - verifyDelete(); - verifyWrite(aclAfter.getAccessLists()); - } - - @Test - public void testDelete() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - verifyDelete(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java deleted file mode 100644 index 07d4166c8..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import java.util.Arrays; -import java.util.Collections; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -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.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.MatchesBuilder; -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.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -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.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class IetfAclCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - VppInterfaceAugmentation.class).child(IetfAcl.class).child(Ingress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - @Mock - private AclTableContextManager aclCtx; - - private IetfAclCustomizer customizer; - private Ingress acl; - private int DENY = 0; - private int PERMIT = -1; - - private static Ace ace(final PacketHandling action) { - return new AceBuilder() - .setMatches(new MatchesBuilder().setAceType( - new AceIpBuilder() - .setAceIpVersion(new AceIpv6Builder().build()) - .setProtocol((short) 1) - .build() - ).build()) - .setActions(new ActionsBuilder().setPacketHandling(action).build()) - .build(); - } - - private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = IF_INDEX; - request.l2TableIndex = 1; - request.ip4TableIndex = 2; - request.ip6TableIndex = 3; - return request; - } - - private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { - final ClassifyAddDelTable reply = new ClassifyAddDelTable(); - reply.tableIndex = tableIndex; - reply.delChain = 1; - return reply; - } - - private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = IF_INDEX; - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = 0; - return request; - } - - @Override - protected void setUpTest() { - customizer = new IetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - acl = new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).build() - ).build(); - } - - @Test - public void testWrite() throws WriteFailedException { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); - - when(writeContext.readAfter(any())).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Arrays.asList(ace(permit()), ace(permit()), ace(deny()) - )).build() - ).build() - - )); - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - - customizer.writeCurrentAttributes(IID, acl, writeContext); - - final InOrder inOrder = Mockito.inOrder(api); - inOrder.verify(api).classifyAddDelTable(argThat(actionOnMissEquals(DENY))); // default action - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(DENY))); // last deny ACE - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); - inOrder.verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); // assignment - } - - private ArgumentMatcher actionOnMissEquals(final int action) { - return table -> table.missNextIndex == action; - } - - private ArgumentMatcher actionOnHitEquals(final int action) { - return session -> session.hitNextIndex == action; - } - - private Deny deny() { - return new DenyBuilder().build(); - } - - private Permit permit() { - return new PermitBuilder().build(); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(IF_INDEX) - .setL2TableId(1) - .setIp4TableId(2) - .setIp6TableId(3) - .build())); - - customizer.deleteCurrentAttributes(IID, acl, writeContext); - - final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); - expectedRequest.swIfIndex = IF_INDEX; - verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); - verify(api).classifyAddDelTable(classifyAddDelTable(1)); - verify(api).classifyAddDelTable(classifyAddDelTable(2)); - verify(api).classifyAddDelTable(classifyAddDelTable(3)); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java deleted file mode 100644 index accb1ae6d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.0"; - private static final int SUBIF_INDEX = 11; - private static final long SUBIF_ID = 0; - private static final String TABLE_NAME = "table0"; - private static final int TABLE_INDEX = 123; - - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Acl.class).child(Ingress.class); - - @Mock - private VppClassifierContextManager classifyTableContext; - - private SubInterfaceAclCustomizer customizer; - - @Override - protected void setUpTest() throws Exception { - customizer = new SubInterfaceAclCustomizer(api, new NamingContext("prefix", IFC_TEST_INSTANCE), - classifyTableContext); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - when(classifyTableContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - } - - @Test - public void testCreate() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); - verify(api).inputAclSetInterface(expectedIp4AclRequest()); - } - - @Test(expected = WriteFailedException.class) - public void testCreateFailed() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); - customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws WriteFailedException { - customizer.updateCurrentAttributes(IID, ip4Acl(), ip6Acl(), writeContext); - } - - @Test - public void testDelete() throws Exception { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - customizer.deleteCurrentAttributes(IID, ip6Acl(), writeContext); - verify(api).inputAclSetInterface(expectedIp6AclRequest()); - } - - @Test(expected = WriteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); - customizer.deleteCurrentAttributes(IID, ip4Acl(), writeContext); - } - - private Ingress ip4Acl() { - final IngressBuilder builder = new IngressBuilder(); - final Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build(); - builder.setIp4Acl(acl); - return builder.build(); - } - - private InputAclSetInterface expectedIp4AclRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = TABLE_INDEX; - request.ip6TableIndex = -1; - request.swIfIndex = SUBIF_INDEX; - return request; - } - - private Ingress ip6Acl() { - final IngressBuilder builder = new IngressBuilder(); - final Ip6Acl acl = new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build(); - builder.setIp6Acl(acl); - return builder.build(); - } - - private InputAclSetInterface expectedIp6AclRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 0; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = TABLE_INDEX; - request.swIfIndex = SUBIF_INDEX; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java deleted file mode 100644 index 256ae420d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter; -import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.123"; - private static final int SUBIF_INDEX = 2; - private static final long SUB_IF_ID = 123; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(IetfAcl.class).child(Ingress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - private SubInterfaceIetfAclCustomizer customizer; - private Ingress acl; - - @Mock - private AclTableContextManager aclCtx; - - private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = SUBIF_INDEX; - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - return request; - } - - private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = SUBIF_INDEX; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - return request; - } - - @Override - protected void setUpTest() { - customizer = - new SubInterfaceIetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - - acl = new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).build() - ).build(); - } - - @Test - public void testDelete() throws WriteFailedException { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - when(aclCtx.getEntry(SUBIF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(SUBIF_INDEX) - .setL2TableId(-1) - .setIp4TableId(-1) - .setIp6TableId(-1) - .build())); - - customizer.deleteCurrentAttributes(IID, acl, writeContext); - - final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); - expectedRequest.swIfIndex = SUBIF_INDEX; - verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); - } - - @Test - public void testWrite() throws WriteFailedException { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - - when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( - new SubInterfaceBuilder().build() - )); - - when(writeContext.readAfter(IetfAclWriter.ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, - new AclKey(ACL_NAME, ACL_TYPE)))).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Collections.emptyList()).build() - ).build() - )); - - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - - customizer.writeCurrentAttributes(IID, acl, writeContext); - - verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java deleted file mode 100644 index 9edb7e7c7..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.v3po.interfacesstate.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.L2AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclCustomizerTest extends ReaderCustomizerTest { - - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Acl.class).child(Ingress.class); - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private NamingContext interfaceContext; - - @Mock - private VppClassifierContextManager classifyTableContext; - - public AclCustomizerTest() { - super(Ingress.class, AclBuilder.class); - } - - @Override - public void setUp() { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new AclCustomizer(api, interfaceContext, classifyTableContext); - } - - @Test - public void testRead() throws ReadFailedException { - final IngressBuilder builder = mock(IngressBuilder.class); - - final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); - reply.l2TableId = TABLE_INDEX; - reply.ip4TableId = ~0; - reply.ip6TableId = ~0; - when(api.classifyTableByInterface(any())).thenReturn(future(reply)); - - when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); - - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - verify(builder).setL2Acl(new L2AclBuilder().setClassifyTable(TABLE_NAME).build()); - verify(builder).setIp4Acl(null); - verify(builder).setIp6Acl(null); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java deleted file mode 100644 index 48c730892..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.v3po.interfacesstate.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceAclCustomizerTest extends ReaderCustomizerTest { - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUB_IF_NAME = "local0.1"; - private static final long SUB_IF_ID = 1; - private static final int SUB_IF_INDEX = 11; - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(Acl.class).child(Ingress.class); - - private NamingContext interfaceContext; - - @Mock - private VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizerTest() { - super(Ingress.class, AclBuilder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new SubInterfaceAclCustomizer(api, interfaceContext, classifyTableContext); - } - - @Test - public void testRead() throws ReadFailedException { - final IngressBuilder builder = mock(IngressBuilder.class); - - final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); - reply.swIfIndex = SUB_IF_INDEX; - reply.l2TableId = ~0; - reply.ip4TableId = TABLE_INDEX; - reply.ip6TableId = TABLE_INDEX; - when(api.classifyTableByInterface(any())).thenReturn(future(reply)); - - when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); - - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - verify(builder).setL2Acl(null); - verify(builder).setIp4Acl(new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build()); - verify(builder).setIp6Acl(new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build()); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java deleted file mode 100644 index f8645da4d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; - -public class ClassifySessionReaderTest extends - ListReaderCustomizerTest { - - private static final String MATCH_1 = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - private static final String MATCH_2 = "00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00"; - - private static final int TABLE_INDEX = 1; - private static final String TABLE_NAME = "table1"; - - @Mock - private VppClassifierContextManager classifierContext; - - public ClassifySessionReaderTest() { - super(ClassifySession.class, ClassifyTableBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new ClassifySessionReader(api, classifierContext); - } - - private static InstanceIdentifier getClassifySessionId(final String tableName, - final String match) { - return InstanceIdentifier.create(VppClassifierState.class) - .child(ClassifyTable.class, new ClassifyTableKey(tableName)) - .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); - } - - @Test - public void testReadWithCache() throws ReadFailedException { - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); - final ClassifySessionBuilder builder = mock(ClassifySessionBuilder.class); - final ModificationCache cache = new ModificationCache(); - final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); - final ClassifySessionDetails details = new ClassifySessionDetails(); - details.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - dump.classifySessionDetails = Collections.singletonList(details); - cache.put(ClassifySessionReader.CACHE_KEY + id.firstKeyOf(ClassifyTable.class), dump); - when(ctx.getModificationCache()).thenReturn(cache); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); - final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); - final ClassifySessionDetails details1 = new ClassifySessionDetails(); - details1.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - final ClassifySessionDetails details2 = new ClassifySessionDetails(); - details2.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x07, 0x00, 0x00, 0x00, 0x00}; - dump.classifySessionDetails = Arrays.asList(details1, details2); - doReturn(future(dump)).when(api).classifySessionDump(any(ClassifySessionDump.class)); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - - final List allIds = getCustomizer().getAllIds(id, ctx); - assertEquals(2, allIds.size()); - assertEquals(MATCH_1, allIds.get(0).getMatch().getValue()); - assertEquals(MATCH_2, allIds.get(1).getMatch().getValue()); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java deleted file mode 100644 index 3cc4511bb..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class ClassifySessionWriterTest extends WriterCustomizerTest { - - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - private static final int SESSION_INDEX = 456; - @Mock - private VppClassifierContextManager classfierContext; - private ClassifySessionWriter customizer; - - private static ClassifySession generateClassifySession(final long opaqueIndex, final String match) { - final ClassifySessionBuilder builder = new ClassifySessionBuilder(); - builder.setOpaqueIndex(new OpaqueIndex(opaqueIndex)); - builder.setHitNext(new VppNode(PacketHandlingAction.Deny)); - builder.setAdvance(123); - builder.setMatch(new HexString(match)); - return builder.build(); - } - - private static InstanceIdentifier getClassifySessionId(final String tableName, - final String match) { - return InstanceIdentifier.create(VppClassifier.class) - .child(ClassifyTable.class, new ClassifyTableKey(tableName)) - .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); - } - - private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, - final int sessionIndex) { - final ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = isAdd; - request.tableIndex = tableIndex; - request.opaqueIndex = sessionIndex; - request.hitNextIndex = 0; - request.advance = 123; - request.match = - new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return request; - } - - @Override - public void setUpTest() throws Exception { - customizer = new ClassifySessionWriter(api, classfierContext); - - when(classfierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classfierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - - final ClassifyTable table = mock(ClassifyTable.class); - when(table.getClassifierNode()).thenReturn(new VppNodeName("ip4-classifier")); - when(writeContext.readAfter(any())).thenReturn(Optional.of(table)); - when(writeContext.readBefore(any())).thenReturn(Optional.of(table)); - } - - private void whenClassifyAddDelSessionThenSuccess() { - doReturn(future(new ClassifyAddDelSessionReply())).when(api) - .classifyAddDelSession(any(ClassifyAddDelSession.class)); - } - - private void whenClassifyAddDelSessionThenFailure() { - doReturn(failedFuture()).when(api).classifyAddDelSession(any(ClassifyAddDelSession.class)); - } - - @Test - public void testCreate() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenSuccess(); - - customizer.writeCurrentAttributes(id, classifySession, writeContext); - - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); - } - - @Test - public void testCreateFailed() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenFailure(); - - try { - customizer.writeCurrentAttributes(id, classifySession, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - customizer.updateCurrentAttributes(null, null, null, writeContext); - } - - @Test - public void testDelete() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenSuccess(); - - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java deleted file mode 100644 index 70200743f..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; - -public class ClassifyTableReaderTest extends - ListReaderCustomizerTest { - - private static final int TABLE_INDEX_1 = 1; - private static final String TABLE_NAME_1 = "table1"; - private static final int TABLE_INDEX_2 = 2; - private static final String TABLE_NAME_2 = "table2"; - - @Mock - private VppClassifierContextManager classifierContext; - - public ClassifyTableReaderTest() { - super(ClassifyTable.class, VppClassifierStateBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new ClassifyTableReader(api, classifierContext); - } - - private static InstanceIdentifier getClassifyTableId(final String name) { - return InstanceIdentifier.create(VppClassifierState.class) - .child(ClassifyTable.class, new ClassifyTableKey(name)); - } - - private static ClassifyTableInfoReply generateClassifyTableInfoReply() { - final ClassifyTableInfoReply reply = new ClassifyTableInfoReply(); - reply.tableId = TABLE_INDEX_1; - reply.nbuckets = 2; - reply.skipNVectors = 0; - reply.matchNVectors = 1; - reply.nextTableIndex = ~0; - reply.missNextIndex = ~0; - reply.mask = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return reply; - } - - private void verifyClasifyTableRead(final ClassifyTableBuilder builder) { - verify(builder).setName(TABLE_NAME_1); - verify(builder).setNbuckets(2L); - verify(builder, times(0)).setNextTable(anyString()); - verify(builder).setMissNext(new VppNode(PacketHandlingAction.Permit)); - verify(builder).setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); - verify(builder).setActiveSessions(0L); - } - - @Test - public void testRead() throws ReadFailedException { - doReturn(future(generateClassifyTableInfoReply())).when(api).classifyTableInfo(any(ClassifyTableInfo.class)); - - when(classifierContext.containsTable(TABLE_NAME_1, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME_1, mappingContext)).thenReturn(TABLE_INDEX_1); - when(classifierContext.getTableBaseNode(TABLE_NAME_1, mappingContext)).thenReturn(Optional.absent()); - - final ClassifyTableBuilder builder = mock(ClassifyTableBuilder.class); - getCustomizer().readCurrentAttributes(getClassifyTableId(TABLE_NAME_1), builder, ctx); - - verifyClasifyTableRead(builder); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - final ClassifyTableIdsReply reply = new ClassifyTableIdsReply(); - reply.ids = new int[] {1, 2}; - doReturn(future(reply)).when(api).classifyTableIds(any(ClassifyTableIds.class)); - - when(classifierContext.getTableName(TABLE_INDEX_1, mappingContext)).thenReturn(TABLE_NAME_1); - when(classifierContext.getTableName(TABLE_INDEX_2, mappingContext)).thenReturn(TABLE_NAME_2); - - final List allIds = getCustomizer().getAllIds(getClassifyTableId(TABLE_NAME_1), ctx); - - assertEquals(reply.ids.length, allIds.size()); - assertEquals(TABLE_NAME_1, allIds.get(0).getName()); - assertEquals(TABLE_NAME_2, allIds.get(1).getName()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java deleted file mode 100644 index f09cea7d9..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class ClassifyTableWriterTest extends WriterCustomizerTest { - - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - - @Mock - private VppClassifierContextManager classifierContext; - - private ClassifyTableWriter customizer; - - private static ClassifyTable generateClassifyTable(final String name) { - final ClassifyTableBuilder builder = new ClassifyTableBuilder(); - builder.setName(name); - builder.setClassifierNode(new VppNodeName("ip4-classifier")); - builder.setKey(new ClassifyTableKey(name)); - builder.setSkipNVectors(0L); - builder.setNbuckets(2L); - builder.setMemorySize(2L << 20); - builder.setMissNext(new VppNode(PacketHandlingAction.Permit)); - builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); - return builder.build(); - } - - private static InstanceIdentifier getClassifyTableId(final String name) { - return InstanceIdentifier.create(VppClassifier.class) - .child(ClassifyTable.class, new ClassifyTableKey(name)); - } - - private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd) { - return generateClassifyAddDelTable(isAdd, -1); - } - - private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = isAdd; - request.tableIndex = tableIndex; - request.nbuckets = 2; - request.memorySize = 2 << 20; - request.skipNVectors = 0; - request.matchNVectors = 1; - request.nextTableIndex = ~0; - request.missNextIndex = ~0; - request.mask = - new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return request; - } - - @Override - public void setUpTest() throws Exception { - customizer = new ClassifyTableWriter(api, classifierContext); - } - - private void whenClassifyAddDelTableThenSuccess() { - final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply(); - reply.newTableIndex = TABLE_INDEX; - doReturn(future(reply)).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); - } - - private void whenClassifyAddDelTableThenFailure() { - doReturn(failedFuture()).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); - } - - @Test - public void testCreate() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - whenClassifyAddDelTableThenSuccess(); - - customizer.writeCurrentAttributes(id, classifyTable, writeContext); - - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); - verify(classifierContext) - .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); - } - - @Test - public void testCreateFailed() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - whenClassifyAddDelTableThenFailure(); - - try { - customizer.writeCurrentAttributes(id, classifyTable, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); - verify(classifierContext, times(0)) - .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testDelete() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - whenClassifyAddDelTableThenSuccess(); - - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - whenClassifyAddDelTableThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java deleted file mode 100644 index c334fe84f..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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.v3po.vppclassifier; - -import static io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManagerImpl.VPP_CLASSIFIER_CONTEXT_IID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import java.util.Arrays; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -public class VppClassifierContextManagerImplTest { - - private static final int TABLE_ID_0 = 0; - private static final String TABLE_NAME_0 = "table0"; - private static final KeyedInstanceIdentifier TABLE_IID_0 = - VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(TABLE_NAME_0)); - - private static final int TABLE_ID_1 = 1; - private static final String TABLE_NAME_1 = "table1"; - - private VppClassifierContextManagerImpl vppClassfierContext; - - @Mock - private MappingContext ctx; - - @Before - public void setUp() throws Exception { - initMocks(this); - vppClassfierContext = new VppClassifierContextManagerImpl("classify-table-"); - } - - @Test - public void testAddTable() throws Exception { - final String classfierNodeName = "node123"; - vppClassfierContext.addTable(TABLE_ID_0, TABLE_NAME_0, new VppNodeName(classfierNodeName), ctx); - verify(ctx).put(TABLE_IID_0, table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName)); - } - - @Test - public void testContainsTable() throws Exception { - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.absent()); - assertFalse(vppClassfierContext.containsTable(TABLE_NAME_0, ctx)); - } - - @Test - public void testGetTableIndex() throws Exception { - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0))); - assertEquals(TABLE_ID_0, vppClassfierContext.getTableIndex(TABLE_NAME_0, ctx)); - } - - @Test - public void testGetTableName() throws Exception { - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)) - .thenReturn(Optional.of(context(table(TABLE_ID_0, TABLE_NAME_0), table(TABLE_ID_1, TABLE_NAME_1)))); - assertEquals(TABLE_NAME_0, (vppClassfierContext.getTableName(TABLE_ID_0, ctx))); - } - - @Test - public void testGetTableBaseNode() throws Exception { - final String classfierNodeName = "node123"; - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName))); - vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx); - assertEquals(Optional.of(classfierNodeName), (vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx))); - } - - @Test - public void testRemoveTable() throws Exception { - vppClassfierContext.removeTable(TABLE_NAME_0, ctx); - verify(ctx).delete(TABLE_IID_0); - } - - @Test - public void testAddNodeName() throws Exception { - final String nodeName = "node123"; - final int nodeIndex = 1; - - vppClassfierContext.addNodeName(TABLE_NAME_0, nodeIndex, nodeName, ctx); - verify(ctx).put( - TABLE_IID_0.child(NodeContext.class, new NodeContextKey(nodeName)), - node(nodeName, nodeIndex) - ); - } - - @Test - public void testGetNonExistingNodeName() throws Exception { - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(table(TABLE_ID_1, TABLE_NAME_1)))); - assertFalse(vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx).isPresent()); - } - - @Test - public void testGetNodeNameMissingNodeCtx() throws Exception { - final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa"); - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); - assertEquals(Optional.absent(), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); - } - - @Test - public void testGetNodeName() throws Exception { - final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa", node("node123", 123)); - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); - assertEquals(Optional.of("node123"), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); - } - - private VppClassifierContext context(ClassifyTableContext... tables) { - VppClassifierContextBuilder context = new VppClassifierContextBuilder(); - context.setClassifyTableContext(Arrays.asList(tables)); - return context.build(); - } - - private static ClassifyTableContext table(final Integer id, final String name) { - return table(id, name, null); - } - - private static ClassifyTableContext table(final Integer id, final String name, final String classfierNodeName, - final NodeContext... nodeContexts) { - final ClassifyTableContextBuilder builder = - new ClassifyTableContextBuilder().setIndex(id).setName(name).setClassifierNodeName(classfierNodeName); - - if (nodeContexts.length > 0) { - builder.setNodeContext(Arrays.asList(nodeContexts)); - } - - return builder.build(); - } - - private NodeContext node(final String nodeName, final int nodeIndex) { - return new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build(); - } -} \ No newline at end of file diff --git a/vpp-classifier/api/asciidoc/Readme.adoc b/vpp-classifier/api/asciidoc/Readme.adoc new file mode 100644 index 000000000..c87cbb22b --- /dev/null +++ b/vpp-classifier/api/asciidoc/Readme.adoc @@ -0,0 +1,3 @@ += vpp-classifier-api + +Overview of vpp-classifier-api \ No newline at end of file diff --git a/vpp-classifier/api/pom.xml b/vpp-classifier/api/pom.xml new file mode 100644 index 000000000..ed79610ab --- /dev/null +++ b/vpp-classifier/api/pom.xml @@ -0,0 +1,60 @@ + + + + + + io.fd.honeycomb.common + api-parent + 1.17.04-SNAPSHOT + + 4.0.0 + + io.fd.hc2vpp.vpp.classifier + vpp-classifier-api + 1.17.04-SNAPSHOT + bundle + + + + org.opendaylight.mdsal.model + ietf-yang-types-20130715 + + + + org.opendaylight.mdsal.model + yang-ext + + + + org.opendaylight.mdsal.model + ietf-inet-types-2013-07-15 + + + + org.opendaylight.mdsal.model + ietf-interfaces + + + + io.fd.hc2vpp.v3po + v3po-api + ${project.version} + + + \ No newline at end of file diff --git a/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java b/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java new file mode 100644 index 000000000..a0c086bda --- /dev/null +++ b/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/OpaqueIndexBuilder.java @@ -0,0 +1,40 @@ +/* + * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class OpaqueIndexBuilder { + + public static OpaqueIndex getDefaultInstance(java.lang.String defaultValue) { + try { + final long value = Long.parseLong(defaultValue); // u32 value + return new OpaqueIndex(value); + } catch (NumberFormatException e) { + return new OpaqueIndex(VppNodeBuilder.getDefaultInstance(defaultValue)); + } + } + +} diff --git a/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java b/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java new file mode 100644 index 000000000..1c13e80d7 --- /dev/null +++ b/vpp-classifier/api/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpp/classifier/rev161214/VppNodeBuilder.java @@ -0,0 +1,41 @@ +/* + * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class VppNodeBuilder { + + public static VppNode getDefaultInstance(java.lang.String defaultValue) { + if (PacketHandlingAction.Deny.toString().equalsIgnoreCase(defaultValue)) { + return new VppNode(PacketHandlingAction.Deny); + } else if (PacketHandlingAction.Permit.toString().equalsIgnoreCase(defaultValue)) { + return new VppNode(PacketHandlingAction.Permit); + } else { + return new VppNode(new VppNodeName(defaultValue)); + } + } + +} diff --git a/vpp-classifier/api/src/main/yang/ietf-access-control-list.yang b/vpp-classifier/api/src/main/yang/ietf-access-control-list.yang new file mode 100644 index 000000000..3083ee2a0 --- /dev/null +++ b/vpp-classifier/api/src/main/yang/ietf-access-control-list.yang @@ -0,0 +1,208 @@ +module ietf-access-control-list { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-access-control-list"; + prefix acl; + import ietf-yang-types { + prefix yang; + } + import ietf-packet-fields { + prefix packet-fields; + } + organization "IETF NETMOD (NETCONF Data Modeling Language) + Working Group"; + contact + "WG Web: http://tools.ietf.org/wg/netmod/ + WG List: netmod@ietf.org + WG Chair: Juergen Schoenwaelder + j.schoenwaelder@jacobs-university.de + WG Chair: Tom Nadeau + tnadeau@lucidvision.com + Editor: Dean Bogdanovic + ivandean@gmail.com + Editor: Kiran Agrahara Sreenivasa + kkoushik@cisco.com + Editor: Lisa Huang + lyihuang16@gmail.com + Editor: Dana Blair + dblair@cisco.com"; + description + "This YANG module defines a component that describing the + configuration of Access Control Lists (ACLs). + Copyright (c) 2015 IETF Trust and the persons identified as + the document authors. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices."; + revision 2016-07-08 { + description + "Base model for Network Access Control List (ACL)."; + reference + "RFC XXXX: Network Access Control List (ACL) + YANG Data Model"; + } + identity acl-base { + description + "Base Access Control List type for all Access Control List type + identifiers."; + } + identity ipv4-acl { + base acl:acl-base; + description + "ACL that primarily matches on fields from the IPv4 header + (e.g. IPv4 destination address) and layer 4 headers (e.g. TCP + destination port). An acl of type ipv4-acl does not contain + matches on fields in the ethernet header or the IPv6 header."; + } + identity ipv6-acl { + base acl:acl-base; + description + "ACL that primarily matches on fields from the IPv6 header + (e.g. IPv6 destination address) and layer 4 headers (e.g. TCP + destination port). An acl of type ipv6-acl does not contain + matches on fields in the ethernet header or the IPv4 header."; + } + identity eth-acl { + base acl:acl-base; + description + "ACL that primarily matches on fields in the ethernet header, + like 10/100/1000baseT or WiFi Access Control List. An acl of + type eth-acl does not contain matches on fields in the IPv4 + header, IPv6 header or layer 4 headers."; + } + typedef acl-type { + type identityref { + base acl:acl-base; + } + description + "This type is used to refer to an Access Control List + (ACL) type"; + } + typedef access-control-list-ref { + type leafref { + path "/access-lists/acl/acl-name"; + } + description + "This type is used by data models that need to reference an + Access Control List"; + } + container access-lists { + description + "This is a top level container for Access Control Lists. + It can have one or more Access Control Lists."; + list acl { + key "acl-type acl-name"; + description + "An Access Control List(ACL) is an ordered list of + Access List Entries (ACE). Each Access Control Entry has a + list of match criteria and a list of actions. + Since there are several kinds of Access Control Lists + implemented with different attributes for + different vendors, this + model accommodates customizing Access Control Lists for + each kind and for each vendor."; + leaf acl-name { + type string; + description + "The name of access-list. A device MAY restrict the length + and value of this name, possibly space and special + characters are not allowed."; + } + leaf acl-type { + type acl-type; + description + "Type of access control list. Indicates the primary intended + type of match criteria (e.g. ethernet, IPv4, IPv6, mixed, etc) + used in the list instance."; + } + container acl-oper-data { + config false; + description + "Overall Access Control List operational data"; + } + container access-list-entries { + description + "The access-list-entries container contains + a list of access-list-entries(ACE)."; + list ace { + key "rule-name"; + ordered-by user; + description + "List of access list entries(ACE)"; + leaf rule-name { + type string; + description + "A unique name identifying this Access List + Entry(ACE)."; + } + container matches { + description + "Definitions for match criteria for this Access List + Entry."; + choice ace-type { + description + "Type of access list entry."; + case ace-ip { + description "IP Access List Entry."; + choice ace-ip-version { + description + "IP version used in this Access List Entry."; + case ace-ipv4 { + uses packet-fields:acl-ipv4-header-fields; + } + case ace-ipv6 { + uses packet-fields:acl-ipv6-header-fields; + } + } + uses packet-fields:acl-ip-header-fields; + } + case ace-eth { + description + "Ethernet Access List entry."; + uses packet-fields:acl-eth-header-fields; + } + } + } + container actions { + description + "Definitions of action criteria for this Access List + Entry."; + choice packet-handling { + default "deny"; + description + "Packet handling action."; + case deny { + leaf deny { + type empty; + description + "Deny action."; + } + } + case permit { + leaf permit { + type empty; + description + "Permit action."; + } + } + } + } + container ace-oper-data { + config false; + description + "Operational data for this Access List Entry."; + leaf match-counter { + type yang:counter64; + description + "Number of matches for this Access List Entry"; + } + } + } + } + } + } +} diff --git a/vpp-classifier/api/src/main/yang/ietf-packet-fields.yang b/vpp-classifier/api/src/main/yang/ietf-packet-fields.yang new file mode 100644 index 000000000..0b1ce5cdd --- /dev/null +++ b/vpp-classifier/api/src/main/yang/ietf-packet-fields.yang @@ -0,0 +1,180 @@ +module ietf-packet-fields { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-packet-fields"; + prefix packet-fields; + import ietf-inet-types { + prefix inet; + } + import ietf-yang-types { + prefix yang; + } + organization "IETF NETMOD (NETCONF Data Modeling Language) Working + Group"; + contact + "WG Web: http://tools.ietf.org/wg/netmod/ + WG List: netmod@ietf.org + WG Chair: Juergen Schoenwaelder + j.schoenwaelder@jacobs-university.de + WG Chair: Tom Nadeau + tnadeau@lucidvision.com + Editor: Dean Bogdanovic + deanb@juniper.net + Editor: Kiran Agrahara Sreenivasa + kkoushik@cisco.com + Editor: Lisa Huang + lyihuang16@gmail.com + Editor: Dana Blair + dblair@cisco.com"; + description + "This YANG module defines groupings that are used by + ietf-access-control-list YANG module. Their usage is not + limited to ietf-access-control-list and can be + used anywhere as applicable. + Copyright (c) 2015 IETF Trust and the persons identified as + the document authors. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices."; + revision 2016-07-08 { + description + "Initial version of packet fields used by + ietf-access-control-list"; + reference + "RFC XXXX: Network Access Control List (ACL) + YANG Data Model"; + } + grouping acl-transport-header-fields { + description + "Transport header fields"; + container source-port-range { + presence "Enables setting source port range"; + description + "Inclusive range representing source ports to be used. + When only lower-port is present, it represents a single port."; + leaf lower-port { + type inet:port-number; + mandatory true; + description + "Lower boundary for port."; + } + leaf upper-port { + type inet:port-number; + must ". >= ../lower-port" { + error-message + "The upper-port must be greater than or equal to lower-port"; + } + description + "Upper boundary for port . If existing, the upper port + must be greater or equal to lower-port."; + } + } + container destination-port-range { + presence "Enables setting destination port range"; + description + "Inclusive range representing destination ports to be used. When + only lower-port is present, it represents a single port."; + leaf lower-port { + type inet:port-number; + mandatory true; + description + "Lower boundary for port."; + } + leaf upper-port { + type inet:port-number; + must ". >= ../lower-port" { + error-message + "The upper-port must be greater than or equal to lower-port"; + } + + description + "Upper boundary for port. If existing, the upper port must + be greater or equal to lower-port"; + } + } + } + grouping acl-ip-header-fields { + description + "IP header fields common to ipv4 and ipv6"; + leaf dscp { + type inet:dscp; + description + "Value of dscp."; + } + leaf protocol { + type uint8; + description + "Internet Protocol number."; + } + uses acl-transport-header-fields; + } + grouping acl-ipv4-header-fields { + description + "Fields in IPv4 header."; + leaf destination-ipv4-network { + type inet:ipv4-prefix; + description + "Destination IPv4 address prefix."; + } + leaf source-ipv4-network { + type inet:ipv4-prefix; + description + "Source IPv4 address prefix."; + } + } + grouping acl-ipv6-header-fields { + description + "Fields in IPv6 header"; + leaf destination-ipv6-network { + type inet:ipv6-prefix; + description + "Destination IPv6 address prefix."; + } + leaf source-ipv6-network { + type inet:ipv6-prefix; + description + "Source IPv6 address prefix."; + } + leaf flow-label { + type inet:ipv6-flow-label; + description + "IPv6 Flow label."; + } + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text Representation"; + } + grouping acl-eth-header-fields { + description + "Fields in Ethernet header."; + leaf destination-mac-address { + type yang:mac-address; + description + "Destination IEEE 802 MAC address."; + } + leaf destination-mac-address-mask { + type yang:mac-address; + description + "Destination IEEE 802 MAC address mask."; + } + leaf source-mac-address { + type yang:mac-address; + description + "Source IEEE 802 MAC address."; + } + leaf source-mac-address-mask { + type yang:mac-address; + description + "Source IEEE 802 MAC address mask."; + } + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture."; + } + +} \ No newline at end of file diff --git a/vpp-classifier/api/src/main/yang/vpp-classifier-acl.yang b/vpp-classifier/api/src/main/yang/vpp-classifier-acl.yang new file mode 100644 index 000000000..ccf3e286a --- /dev/null +++ b/vpp-classifier/api/src/main/yang/vpp-classifier-acl.yang @@ -0,0 +1,183 @@ +module vpp-classifier-acl { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:classifier:acl"; + prefix "vpp-classifier-acl"; + + revision "2016-12-14" { + description + "Initial revision of vpp-classfier-acl model."; + } + + import ietf-access-control-list { + prefix "acl"; + } + + import vpp-classifier { + prefix "vpp-classifier"; + } + + import yang-ext { + prefix "ext"; + } + + import ietf-packet-fields { + prefix packet-fields; + } + + identity mixed-acl { + base acl:acl-base; + description + "ACL that can match on any of L2/L3/L4 fields."; + } + + typedef interface-mode { + type enumeration { + enum "l2"; + enum "l3"; + } + } + + grouping acl-base-attributes { + description + "Defines references to classify tables. + At least one table reference should be specified."; + container l2-acl { + leaf classify-table { + type vpp-classifier:classify-table-ref; + description + "An L2 ACL table"; + } + } + container ip4-acl { + leaf classify-table { + type vpp-classifier:classify-table-ref; + description + "An IPv4 ACL table"; + } + } + container ip6-acl { + leaf classify-table { + type vpp-classifier:classify-table-ref; + description + "An IPv6 ACL table"; + } + } + } + + grouping ietf-acl-base-attributes { + description + "Provides limited support for ietf-acl model."; + + container access-lists { + description + "Defines references to ietf-acl lists. + ACLs are translated into classify tables and sessions when assigned to interface. + + In case of L2 interfaces, acls are translated into a chain of classify tables and assigned as L2 table. + In case of L3 interfaces, acls are translated into ip4 and ip6 chains (eth only rules go to both chains, + rest - depending on ip-version). + User ordering is preserved in both cases. + + Assignment update/delete removes all created tables and sessions and repeats process described above. + Update/delete of ACL lists referenced here is not permitted (assignment needs to be removed first). + + Read is supported only for acls that were created and assigned by Honeycomb agent + (corresponding metadata is present). + + Extensions: + - mixing ACEs of different type in one list is permited + - mixing L2/L3/L4 rules in one ACE is permited + + Limitations (due to vpp limitations): + - egress rules are currently ignored (HONEYCOMB-234) + - L4 rules support is limited (every port pair from provided ranges is translated to single classify + session; which can very slow or even crash vpp if ranges are big, see HONEYCOMB-260) + - ace-ip-version needs to be provided for all aces (consequence of posibility to mix ACEs of different types, + and vpp classfier api limitation: common header fields for IP4/IP6 have different offsets) + - L2 rules on L3 interfaces are applied only to IP traffic (vpp classfier limitation) + - vlan tags are supported only for sub-interfaces defined as exact-match"; + + list acl { + key "type name"; + ordered-by user; + + leaf type { + type acl:acl-type; + } + + leaf name { + type acl:access-control-list-ref; + } + } + + leaf default-action { + type enumeration { + enum "deny"; + enum "permit"; + } + default "deny"; + description + "Default action applied to packet that does not match any of rules defined in assigned ACLs. + It is translated to single classify table and applied at the end of assigned chains."; + } + + leaf mode { + type interface-mode; + default l3; + description + "The way ACLs are translated depends on the interface mode. + In case of L2 interfaces (bridge/interconnection) + classify tables are assigned as l2_table using input_acl_set_interface (ether type matching is automatically + added in case of L3 rules). + In case of L3 interfaces, classify tables are assigned as ip4/ip6 tables. + + It is the user responsibility to choose mode that matches target interface. + "; + } + } + } + + grouping vpp-acl-attributes { + container acl { + container ingress { + uses vpp-classifier-acl:acl-base-attributes; + } + container egress { + uses vpp-classifier-acl:acl-base-attributes; + } + } + + container ietf-acl { + container ingress { + uses vpp-classifier-acl:ietf-acl-base-attributes; + } + container egress { + uses vpp-classifier-acl:ietf-acl-base-attributes; + } + } + } + + augment /acl:access-lists/acl:acl/acl:access-list-entries/acl:ace/acl:matches/acl:ace-type { + ext:augment-identifier "vpp-classfier-acl-type-augmentation"; + case ace-ip-and-eth { + description + "Access List entry that can define both ip and eth rules."; + container ace-ip-and-eth-nodes { + + choice ace-ip-version { + description + "IP version used in this Access List Entry."; + mandatory true; + case ace-ipv4 { + uses packet-fields:acl-ipv4-header-fields; + } + case ace-ipv6 { + uses packet-fields:acl-ipv6-header-fields; + } + } + uses packet-fields:acl-ip-header-fields; + uses packet-fields:acl-eth-header-fields; + } + } + } +} \ No newline at end of file diff --git a/vpp-classifier/api/src/main/yang/vpp-classifier-context.yang b/vpp-classifier/api/src/main/yang/vpp-classifier-context.yang new file mode 100644 index 000000000..01eae862d --- /dev/null +++ b/vpp-classifier/api/src/main/yang/vpp-classifier-context.yang @@ -0,0 +1,68 @@ +module vpp-classifier-context { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:classifier"; + prefix "vpp-classifier-context"; + + description + "This module contains vpp classfier metadata definition"; + + revision "2016-09-09" { + description + "Initial revision."; + } + + container vpp-classifier-context { + + config "false"; + + description + "Classify tables and sessions contain relative node indexes. Management agent like Honeycomb, + needs to use node names instead (indexes might change after vpp restart). + VPP does not provide relative index to node name conversion (https://jira.fd.io/browse/VPP-219), + also finding base node that is needed to perform the conversion + is not allways possible (https://jira.fd.io/browse/VPP-220). + + Therefore Honeycomb needs to provide relative node to index mapping. + "; + + list classify-table-context { + key "name"; + unique "index"; + + leaf name { + type string; + description + "Name of the classify table."; + } + + leaf index { + type int32; + description + "Classify table index used by VPP."; + } + + leaf classifier-node-name { + type string; + description + "Name of VPP node the table is defined for."; + } + + list node-context { + key "name"; + unique "index"; + + leaf name { + type string; + description + "Name of vpp node (neighbour of classifier-node-name)"; + } + + leaf index { + type int32; + description + "Inted of the vpp node relative to classifier-node-name"; + } + } + } + } +} \ No newline at end of file diff --git a/vpp-classifier/api/src/main/yang/vpp-classifier.yang b/vpp-classifier/api/src/main/yang/vpp-classifier.yang new file mode 100644 index 000000000..beb4def85 --- /dev/null +++ b/vpp-classifier/api/src/main/yang/vpp-classifier.yang @@ -0,0 +1,215 @@ +module vpp-classifier { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:classifier"; + prefix "vpp-classifier"; + + revision "2016-12-14" { + description + "This revision adds the following new features: + - updates order of union types for opaque-index"; + } + + revision "2015-06-03" { + description + "Initial revision of model for VPP packet classifier. + The model can be used ony to implement ACLs. + Other classify table usages are not supported yet, + see https://jira.fd.io/browse/VPP-203 for details."; + reference + "https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers"; + } + + import ietf-yang-types { + prefix "yang"; + } + + typedef classify-table-ref { + type leafref { + path "/vpp-classifier:vpp-classifier/classify-table/name"; + } + description + "This type is used by data models that need to reference + configured classify tables."; + } + + typedef packet-handling-action { + type enumeration { + enum "deny" { + // by VPP convention, first neighbour node (at index 0) is a drop node + value 0; + } + enum "permit" { + value -1; // indicates that the next node not set + } + } + } + + typedef vpp-node-name { + type string; + } + + typedef vpp-node { + type union { + type packet-handling-action; + type vpp-node-name; + } + description + "Defines VPP node reference using packet handling action or relative node name + (if definition in terms of packet handling action is not possible)."; + } + + typedef opaque-index { + type union { + type uint32; + type vpp-node; + } + description + "Defines opaque-index type - metadata that can be attached to session-hit packets. + Vpp nodes can't be referenced by index, because node indexes might change after vpp restart."; + } + + grouping classify-session-attributes { + description + "Defines classify session attributes that are mapped to classify_add_del_session + and classify_session_details messages parameters."; + + leaf hit_next { + type vpp-node; + mandatory true; + description + "Vpp node to which packet will be send when it produces a match."; + } + leaf opaque_index { + type opaque-index; + } + leaf advance { + type int32; + default 0; + description + "Nodes like ip4/6-classify use the parameter to \"consume\" networking layer. + Example: tunnel decapsulation."; + } + } + + grouping classify-table-base-attributes { + description + "Defines classify table attributes that are mapped to classify_add_del_table message parameters."; + + leaf classifier-node { + type vpp-node-name; + description + "Name of VPP node the table is defined for."; + } + leaf nbuckets { + mandatory true; + type uint32; + description + "Used by classifier hashing algorithm. It is not possible to resize the bucket array, + therefore suggested value is approximate number of expected entries."; + } + leaf skip_n_vectors { + type uint32; + default 0; + description + "Number of 16 byte vectors to be skipped before applying mask."; + } + leaf next_table { + type classify-table-ref; + description + "Reference to the next classify table. Required when multiple table chaining is used."; + } + leaf miss_next { + mandatory true; + type vpp-node; + description + "Vpp node to which packet will be send when it falis to produce a match"; + } + leaf mask { + type yang:hex-string; + mandatory true; + description + "Defines match mask (multiple of 16 bytes)"; + } + + list classify-session { + key "match"; + + leaf match { + type yang:hex-string; + description + "Defines actual value to be matched that is + a byte vector, which length is multiple of 16 bytes"; + + must "string-length(match) = string-length(../../mask)" { + error-message + "Match length is not equal to classify table mask length."; + description + "Match length must be equal to classify table mask length."; + } + } + + uses classify-session-attributes; + } + } + + grouping classify-table-config-attributes { + description + "Defines classify table config only attributes (present in classify_add_del_table message + but not in classify_table_info_reply)."; + + // TODO(HC2VPP-10): move to classify-table-base-attributes + // after https://jira.fd.io/browse/VPP-208 is fixed + leaf memory_size { + type uint32; + // mandatory true; // TODO(HC2VPP-10): uncomment + description + "Memory size for classify table and its entries."; + } + } + + grouping classify-table-operational-attributes { + description + "Defines classify table operational attributes (present in classify_table_info_reply message + but not in classify_add_del_table)."; + + leaf active_sessions { + type uint32; + config false; + description + "Number of sessions defined for the classify table."; + } + } + + container vpp-classifier { + list classify-table { + key "name"; + + leaf name { + type string; + description + "Hides classify table identifier managed by vpp."; + } + + uses classify-table-base-attributes; + uses classify-table-config-attributes; + } + } + + container vpp-classifier-state { + config false; + + list classify-table { + key "name"; + + leaf name { + type string; + description + "Hides classify table identifier managed by vpp."; + } + + uses classify-table-base-attributes; + uses classify-table-operational-attributes; + } + } + +} diff --git a/vpp-classifier/api/src/main/yang/vpp-interface-acl.yang b/vpp-classifier/api/src/main/yang/vpp-interface-acl.yang new file mode 100644 index 000000000..1932e9c97 --- /dev/null +++ b/vpp-classifier/api/src/main/yang/vpp-interface-acl.yang @@ -0,0 +1,32 @@ +module vpp-interface-acl { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:interface:acl"; + prefix "vpp-ifc-acl"; + + revision "2016-12-14" { + description + "Initial revision of vpp-acl model."; + } + + import ietf-interfaces { + prefix "if"; + } + + import vpp-classifier-acl { + prefix "vpp-classifier-acl"; + } + + import yang-ext { + prefix "ext"; + } + + augment /if:interfaces/if:interface { + ext:augment-identifier "vpp-interface-acl-augmentation"; + uses vpp-classifier-acl:vpp-acl-attributes; + } + + augment /if:interfaces-state/if:interface { + ext:augment-identifier "vpp-interface-acl-state-augmentation"; + uses vpp-classifier-acl:vpp-acl-attributes; + } +} \ No newline at end of file diff --git a/vpp-classifier/api/src/main/yang/vpp-subinterface-acl.yang b/vpp-classifier/api/src/main/yang/vpp-subinterface-acl.yang new file mode 100644 index 000000000..892a64586 --- /dev/null +++ b/vpp-classifier/api/src/main/yang/vpp-subinterface-acl.yang @@ -0,0 +1,36 @@ +module vpp-subinterface-acl { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:subinterface:acl"; + prefix "vpp-subifc-acl"; + + revision "2016-12-14" { + description + "Initial revision of vpp-acl model."; + } + + import ietf-interfaces { + prefix "if"; + } + + import vpp-vlan { + prefix "vpp-vlan"; + } + + import vpp-classifier-acl { + prefix "vpp-classifier-acl"; + } + + import yang-ext { + prefix "ext"; + } + + augment /if:interfaces/if:interface/vpp-vlan:sub-interfaces/vpp-vlan:sub-interface { + ext:augment-identifier "vpp-subinterface-acl-augmentation"; + uses vpp-classifier-acl:vpp-acl-attributes; + } + + augment /if:interfaces-state/if:interface/vpp-vlan:sub-interfaces/vpp-vlan:sub-interface { + ext:augment-identifier "vpp-subinterface-acl-state-augmentation"; + uses vpp-classifier-acl:vpp-acl-attributes; + } +} \ No newline at end of file diff --git a/vpp-classifier/asciidoc/Readme.adoc b/vpp-classifier/asciidoc/Readme.adoc new file mode 100644 index 000000000..91c67d506 --- /dev/null +++ b/vpp-classifier/asciidoc/Readme.adoc @@ -0,0 +1,3 @@ += vpp-classifier-aggregator + +Overview of vpp-classifier-aggregator \ No newline at end of file diff --git a/vpp-classifier/impl/asciidoc/Readme.adoc b/vpp-classifier/impl/asciidoc/Readme.adoc new file mode 100644 index 000000000..862bbfcd0 --- /dev/null +++ b/vpp-classifier/impl/asciidoc/Readme.adoc @@ -0,0 +1,9 @@ += vpp-classifier-impl + +Overview of vpp-classifier-impl + +== Modules +* VppClassifierModule - Defines logic to manipulate classifier tables +* VppClassifierAclModule - Defines utilities to work with classifier acl's +* InterfaceClassifierAclModule - Enables classifier acl's on interfaces +* SubInterfaceClassifierAclModule - Enables classifier acl's on sub-interfaces \ No newline at end of file diff --git a/vpp-classifier/impl/pom.xml b/vpp-classifier/impl/pom.xml new file mode 100644 index 000000000..92c0a6f3b --- /dev/null +++ b/vpp-classifier/impl/pom.xml @@ -0,0 +1,131 @@ + + + + + + io.fd.hc2vpp.common + vpp-impl-parent + 1.17.04-SNAPSHOT + ../../vpp-common/vpp-impl-parent + + + 4.0.0 + + io.fd.hc2vpp.vpp.classifier + vpp-classifier-impl + 1.17.04-SNAPSHOT + + + + + io.fd.hc2vpp.vpp.classifier + vpp-classifier-api + 1.17.04-SNAPSHOT + + + + + io.fd.hc2vpp.v3po + v3po-api + ${project.version} + + + + + com.google.inject + guice + + + net.jmob + guice.conf + + + com.google.inject.extensions + guice-multibindings + + + + + io.fd.honeycomb + translate-spi + ${project.version} + + + io.fd.honeycomb + translate-utils + ${project.version} + + + io.fd.hc2vpp.common + vpp-translate-utils + ${project.version} + + + + + + io.fd.hc2vpp.v3po + v3po2vpp + ${project.version} + + + + + io.fd.vpp + jvpp-core + + + + + + io.fd.hc2vpp.common + vpp-translate-test + ${project.version} + test + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.skinny-framework + skinny-logback + test + + + com.google.inject.extensions + guice-testlib + test + + + org.hamcrest + hamcrest-all + test + + + \ No newline at end of file diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierAclModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierAclModule.java new file mode 100644 index 000000000..cf8a35a85 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierAclModule.java @@ -0,0 +1,39 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.hc2vpp.vpp.classifier.factory.read.InterfaceAclReaderFactory; +import io.fd.hc2vpp.vpp.classifier.factory.write.InterfaceAclWriterFactory; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.write.WriterFactory; + +public class InterfaceClassifierAclModule extends AbstractModule { + + @Override + protected void configure() { + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(InterfaceAclWriterFactory.class); + + // Readers + final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(InterfaceAclReaderFactory.class); + + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierIetfAclModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierIetfAclModule.java new file mode 100644 index 000000000..643abd5c2 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/InterfaceClassifierIetfAclModule.java @@ -0,0 +1,32 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.hc2vpp.vpp.classifier.factory.write.InterfacesClassifierIetfAclWriterFactory; +import io.fd.honeycomb.translate.write.WriterFactory; + +public class InterfaceClassifierIetfAclModule extends AbstractModule{ + + @Override + protected void configure() { + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(InterfacesClassifierIetfAclWriterFactory.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierAclModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierAclModule.java new file mode 100644 index 000000000..018514085 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierAclModule.java @@ -0,0 +1,37 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.hc2vpp.vpp.classifier.factory.read.SubInterfaceAclReaderFactory; +import io.fd.hc2vpp.vpp.classifier.factory.write.SubInterfaceAclWriterFactory; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.write.WriterFactory; + +public class SubInterfaceClassifierAclModule extends AbstractModule{ + @Override + protected void configure() { + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(SubInterfaceAclWriterFactory.class); + + // Readers + final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(SubInterfaceAclReaderFactory.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierIetfAclModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierIetfAclModule.java new file mode 100644 index 000000000..338624bc6 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/SubInterfaceClassifierIetfAclModule.java @@ -0,0 +1,32 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.hc2vpp.vpp.classifier.factory.write.SubInterfacesClassifierIetfAclWriterFactory; +import io.fd.honeycomb.translate.write.WriterFactory; + +public class SubInterfaceClassifierIetfAclModule extends AbstractModule{ + + @Override + protected void configure() { + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(SubInterfacesClassifierIetfAclWriterFactory.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierAclModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierAclModule.java new file mode 100644 index 000000000..3b2cdb975 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierAclModule.java @@ -0,0 +1,46 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.hc2vpp.vpp.classifier.factory.write.AclWriterFactory; +import io.fd.hc2vpp.vpp.classifier.provider.EgressIetfAClWriterProvider; +import io.fd.hc2vpp.vpp.classifier.provider.IngressIetfAClWriterProvider; +import io.fd.hc2vpp.vpp.classifier.write.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.IngressIetfAclWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VppClassifierAclModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(VppClassifierAclModule.class); + + @Override + protected void configure() { + // Utils + bind(IngressIetfAclWriter.class).toProvider(IngressIetfAClWriterProvider.class); + bind(EgressIetfAclWriter.class).toProvider(EgressIetfAClWriterProvider.class); + + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(AclWriterFactory.class); + + LOG.info("Module VppClassifierAcl module successfully configured"); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModule.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModule.java new file mode 100644 index 000000000..088df72c2 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModule.java @@ -0,0 +1,55 @@ +/* + * 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.vpp.classifier; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManagerImpl; +import io.fd.hc2vpp.vpp.classifier.factory.read.VppClassifierReaderFactory; +import io.fd.hc2vpp.vpp.classifier.factory.write.VppClassifierHoneycombWriterFactory; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.write.WriterFactory; +import net.jmob.guice.conf.core.ConfigurationModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VppClassifierModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(VppClassifierModule.class); + + @Override + protected void configure() { + LOG.debug("Installing VppClassifierAcl module"); + install(ConfigurationModule.create()); + + bind(VppClassifierContextManager.class) + .annotatedWith(Names.named("classify-table-context")) + .toInstance(new VppClassifierContextManagerImpl("classify-table-")); + + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(VppClassifierHoneycombWriterFactory.class); + + final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(VppClassifierReaderFactory.class); + + // Expose vpp-classfier-context interfaces in operational data + readerFactoryBinder.addBinding().to(VppClassifierContextManagerImpl.ContextsReaderFactory.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManager.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManager.java new file mode 100644 index 000000000..b30f1ee55 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManager.java @@ -0,0 +1,106 @@ +/* + * 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.vpp.classifier.context; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; + +/** + * Manages metadata for vpp-classifier + */ +public interface VppClassifierContextManager { + + /** + * Creates metadata for classify table. + * + * @param id classify table index + * @param name classify table name + * @param classifierNode name of VPP node the table is defined for + * @param ctx mapping context providing context data for current transaction + */ + void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, + @Nonnull final MappingContext ctx); + + /** + * Check whether metadata for given classify table metadata is present. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + boolean containsTable(@Nonnull String name, @Nonnull final MappingContext ctx); + + /** + * Returns classify table index associated with the given name. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return integer index value matching supplied classify table name + * @throws IllegalArgumentException if classify table was not found + */ + int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Retrieves classify table name for given id. If not present, artificial name will be generated. + * + * @param id classify table index + * @param ctx mapping context providing context data for current transaction + * @return classify table name matching supplied index + */ + String getTableName(final int id, @Nonnull final MappingContext ctx); + + /** + * Returns name of the base vpp node associated with the classify table. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return name of VPP node the table is defined for + */ + Optional getTableBaseNode(final String name, @Nonnull final MappingContext ctx); + + /** + * Removes classify table metadata from current context. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + */ + void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Adds relative node index to node name mapping for given classify table. + * + * @param tableName classify table name + * @param nodeIndex index of a vpp node, relative to table's base node + * @param nodeName name of a vpp node + * @param ctx mapping context providing context data for current transaction + */ + void addNodeName(@Nonnull String tableName, final int nodeIndex, @Nonnull final String nodeName, + @Nonnull final MappingContext ctx); + + /** + * Retrieves node name associated with the given classify table and node index. + * + * @param tableIndex classify table index + * @param nodeIndex relative index of a vpp node + * @param ctx mapping context providing context data for current transaction + * @return name of vpp node + */ + Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx); +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImpl.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImpl.java new file mode 100644 index 000000000..a74746864 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImpl.java @@ -0,0 +1,181 @@ +/* + * 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.vpp.classifier.context; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.inject.Inject; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.BindingBrokerReader; +import java.util.List; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.inject.Named; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Facade on top of {@link MappingContext} that manages {@link ClassifyTableContext}. + */ +public final class VppClassifierContextManagerImpl implements VppClassifierContextManager { + private static final Collector SINGLE_ITEM_COLLECTOR = + RWUtils.singleItemCollector(); + + @VisibleForTesting + static final InstanceIdentifier + VPP_CLASSIFIER_CONTEXT_IID = KeyedInstanceIdentifier.create(VppClassifierContext.class); + private final String artificialNamePrefix; + + /** + * Creates new VppClassifierContextManagerImpl. + * + * @param artificialNamePrefix artificial name to be used to generate names for classify tables without existing + * metadata + */ + public VppClassifierContextManagerImpl(@Nonnull final String artificialNamePrefix) { + this.artificialNamePrefix = + Preconditions.checkNotNull(artificialNamePrefix, "artificialNamePrefix should not be null"); + } + + private KeyedInstanceIdentifier getMappingIid(final String name) { + return VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(name)); + } + + @Override + public void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, + @Nonnull final MappingContext ctx) { + final KeyedInstanceIdentifier mappingIid = getMappingIid(name); + final ClassifyTableContextBuilder tableCtx = new ClassifyTableContextBuilder().setIndex(id).setName(name); + if (classifierNode != null) { + tableCtx.setClassifierNodeName(classifierNode.getValue()); + } + ctx.put(mappingIid, tableCtx.build()); + } + + @Override + public boolean containsTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + return read.isPresent(); + } + + @Override + public int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + checkArgument(read.isPresent(), "No mapping stored for name: %s", name); + return read.get().getIndex(); + } + + @Override + public String getTableName(final int id, @Nonnull final MappingContext ctx) { + if (!containsName(id, ctx)) { + final String artificialName = getArtificialName(id); + addTable(id, artificialName, null, ctx); + } + + final Optional read = ctx.read(VPP_CLASSIFIER_CONTEXT_IID); + checkState(read.isPresent(), "VppClassifierContext for index: %s is not present. But should be", id); + + return read.get().getClassifyTableContext().stream() + .filter(t -> t.getIndex().equals(id)) + .collect(SINGLE_ITEM_COLLECTOR).getName(); + } + + private boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { + final Optional read = mappingContext.read(VPP_CLASSIFIER_CONTEXT_IID); + return read.isPresent() + ? read.get().getClassifyTableContext().stream().anyMatch(t -> t.getIndex().equals(index)) + : false; + } + + @Override + public Optional getTableBaseNode(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + if (read.isPresent()) { + return Optional.fromNullable(read.get().getClassifierNodeName()); + } + return Optional.absent(); + } + + @Override + public void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { + ctx.delete(getMappingIid(name)); + } + + @Override + public void addNodeName(@Nonnull final String tableName, final int nodeIndex, + @Nonnull final String nodeName, + @Nonnull final MappingContext ctx) { + final KeyedInstanceIdentifier iid = + getMappingIid(tableName).child(NodeContext.class, new NodeContextKey(nodeName)); + ctx.put(iid, new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build()); + } + + @Override + public Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx) { + if (!containsName(tableIndex, ctx)) { + return Optional.absent(); + } + final String tableName = getTableName(tableIndex, ctx); + final Optional tableCtx = ctx.read(getMappingIid(tableName)); + final List nodeContext = tableCtx.get().getNodeContext(); + if (nodeContext == null) { + return Optional.absent(); + } + return Optional.fromNullable(nodeContext.stream() + .filter(n -> n.getIndex().equals(nodeIndex)) + .findFirst() + .map(nodes -> nodes.getName()) + .orElse(null)); + } + + private String getArtificialName(final int index) { + return artificialNamePrefix + index; + } + + public static final class ContextsReaderFactory implements ReaderFactory { + + @Inject + @Named("honeycomb-context") + private DataBroker contextBindingBrokerDependency; + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + registry.add(new BindingBrokerReader<>(VPP_CLASSIFIER_CONTEXT_IID, + contextBindingBrokerDependency, + LogicalDatastoreType.OPERATIONAL, VppClassifierContextBuilder.class)); + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/InterfaceAclReaderFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/InterfaceAclReaderFactory.java new file mode 100644 index 000000000..f11a475f2 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/InterfaceAclReaderFactory.java @@ -0,0 +1,76 @@ +/* + * 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.vpp.classifier.factory.read; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.read.acl.AclCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericInitReader; +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.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceAclReaderFactory implements ReaderFactory{ + + private static final InstanceIdentifier IFC_ID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class); + private static final InstanceIdentifier VPP_IFC_AUG_ID = + IFC_ID.augmentation(VppInterfaceAclStateAugmentation.class); + + @Inject + private FutureJVppCore jvpp; + + @Inject + @Named("interface-context") + private NamingContext ifcNamingContext; + + @Inject + @Named("classify-table-context") + private VppClassifierContextManager classifyTableContext; + + @Override + public void init(@Nonnull ModifiableReaderRegistryBuilder registry) { + // Acl augmentation(structural) + registry.addStructuralReader(VPP_IFC_AUG_ID, VppInterfaceAclStateAugmentationBuilder.class); + // Acl(Structural) + final InstanceIdentifier aclIid = VPP_IFC_AUG_ID.child(Acl.class); + registry.addStructuralReader(aclIid, AclBuilder.class); + // Ingress(Subtree) + final InstanceIdentifier ingressIdRelative = InstanceIdentifier.create(Ingress.class); + registry.subtreeAdd( + Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), + ingressIdRelative.child(Ip6Acl.class)), + new GenericInitReader(aclIid.child(Ingress.class), + new AclCustomizer(jvpp, ifcNamingContext, classifyTableContext))); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/SubInterfaceAclReaderFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/SubInterfaceAclReaderFactory.java new file mode 100644 index 000000000..f93e0e79b --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/SubInterfaceAclReaderFactory.java @@ -0,0 +1,83 @@ +/* + * 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.vpp.classifier.factory.read; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.read.acl.SubInterfaceAclCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericInitReader; +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.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclReaderFactory implements ReaderFactory { + + static final InstanceIdentifier IFC_STATE_ID = + InstanceIdentifier.create(InterfacesState.class); + static final InstanceIdentifier IFC_ID = IFC_STATE_ID.child(Interface.class); + + private static final InstanceIdentifier SUB_IFC_AUG_ID = + IFC_ID.augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class) + .augmentation(VppSubinterfaceAclStateAugmentation.class); + + @Inject + private FutureJVppCore jvpp; + + @Inject + @Named("interface-context") + private NamingContext ifcNamingContext; + + @Inject + @Named("classify-table-context") + private VppClassifierContextManager classifyTableContext; + + @Override + public void init(@Nonnull ModifiableReaderRegistryBuilder registry) { + // Aug readed(Structural) + registry.addStructuralReader(SUB_IFC_AUG_ID, VppSubinterfaceAclStateAugmentationBuilder.class); + // Acl(Structural) + final InstanceIdentifier aclIid = SUB_IFC_AUG_ID.child(Acl.class); + registry.addStructuralReader(aclIid, AclBuilder.class); + // Ingress(Subtree) + final InstanceIdentifier ingressIdRelative = InstanceIdentifier.create(Ingress.class); + registry.subtreeAdd( + Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), + ingressIdRelative.child(Ip6Acl.class)), + new GenericInitReader<>(aclIid.child(Ingress.class), + new SubInterfaceAclCustomizer(jvpp, ifcNamingContext, classifyTableContext))); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/VppClassifierReaderFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/VppClassifierReaderFactory.java new file mode 100644 index 000000000..46c6e6a6f --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/read/VppClassifierReaderFactory.java @@ -0,0 +1,60 @@ +/* + * 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.vpp.classifier.factory.read; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.read.ClassifySessionReader; +import io.fd.hc2vpp.vpp.classifier.read.ClassifyTableReader; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +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.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VppClassifierReaderFactory implements ReaderFactory { + + private final FutureJVppCore jvpp; + private final VppClassifierContextManager classifyCtx; + + @Inject + public VppClassifierReaderFactory(final FutureJVppCore jvpp, + @Named("classify-table-context") final VppClassifierContextManager classifyCtx) { + this.jvpp = jvpp; + this.classifyCtx = classifyCtx; + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + // VppClassifierState + final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppClassifierState.class); + registry.addStructuralReader(vppStateId, VppClassifierStateBuilder.class); + // ClassifyTable + final InstanceIdentifier classTblId = vppStateId.child(ClassifyTable.class); + registry.add(new GenericInitListReader<>(classTblId, new ClassifyTableReader(jvpp, classifyCtx))); + // ClassifySession + final InstanceIdentifier classSesId = classTblId.child(ClassifySession.class); + registry.add(new GenericListReader<>(classSesId, new ClassifySessionReader(jvpp, classifyCtx))); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/AclWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/AclWriterFactory.java new file mode 100644 index 000000000..5a13db274 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/AclWriterFactory.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.vpp.classifier.factory.write; + +import com.google.common.collect.Sets; +import io.fd.hc2vpp.vpp.classifier.write.acl.IetfAclWriter; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +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.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class AclWriterFactory implements WriterFactory { + + public static final InstanceIdentifier ACL_ID = + InstanceIdentifier.create(AccessLists.class).child(Acl.class); + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + + final InstanceIdentifier aclIdRelative = InstanceIdentifier.create(Acl.class); + + final InstanceIdentifier aceId = aclIdRelative.child(AccessListEntries.class).child(Ace.class); + final InstanceIdentifier actionsId = aceId.child(Actions.class); + final InstanceIdentifier matchesId = aceId.child(Matches.class); + final InstanceIdentifier aceIpAndEthId = matchesId.child(AceIpAndEthNodes.class); + final InstanceIdentifier srcPortId = matchesId.child((Class)SourcePortRange.class); + final InstanceIdentifier dstPortId = matchesId.child((Class)DestinationPortRange.class); + + registry.subtreeAddBefore(Sets.newHashSet(aceId, actionsId, matchesId, aceIpAndEthId, srcPortId, dstPortId), + new GenericListWriter<>(ACL_ID, new IetfAclWriter()), + Sets.newHashSet(InterfacesClassifierIetfAclWriterFactory.IETF_ACL_ID, SubInterfacesClassifierIetfAclWriterFactory.SUBIF_IETF_ACL_ID)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfaceAclWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfaceAclWriterFactory.java new file mode 100644 index 000000000..bc3bc495d --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfaceAclWriterFactory.java @@ -0,0 +1,77 @@ +/* + * 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.vpp.classifier.factory.write; + +import static io.fd.hc2vpp.vpp.classifier.factory.write.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; +import static io.fd.hc2vpp.vpp.classifier.factory.write.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.AclCustomizer; +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.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceAclWriterFactory implements WriterFactory { + + private static final InstanceIdentifier IFC_ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class); + private static final InstanceIdentifier VPP_IFC_ACL_ID = + IFC_ID.augmentation(VppInterfaceAclAugmentation.class); + static final InstanceIdentifier ACL_ID = VPP_IFC_ACL_ID.child(Acl.class); + private static final InstanceIdentifier INGRESS_ACL_ID = ACL_ID.child(Ingress.class); + + @Inject + private FutureJVppCore jvpp; + + @Inject + @Named("interface-context") + private NamingContext ifcNamingContext; + + @Inject + @Named("classify-table-context") + private VppClassifierContextManager classifyTableContext; + + + @Override + public void init(@Nonnull ModifiableWriterRegistryBuilder registry) { + // Ingress (execute after classify table and session writers) + // also handles L2Acl, Ip4Acl and Ip6Acl: + final InstanceIdentifier ingressId = InstanceIdentifier.create(Ingress.class); + registry + .subtreeAddAfter( + Sets.newHashSet(ingressId.child(L2Acl.class), ingressId.child(Ip4Acl.class), + ingressId.child(Ip6Acl.class)), + new GenericWriter<>(INGRESS_ACL_ID, + new AclCustomizer(jvpp, ifcNamingContext, classifyTableContext)), + Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfacesClassifierIetfAclWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfacesClassifierIetfAclWriterFactory.java new file mode 100644 index 000000000..48d782dd2 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/InterfacesClassifierIetfAclWriterFactory.java @@ -0,0 +1,81 @@ +/* + * 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.vpp.classifier.factory.write; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.IngressIetfAclWriter; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class InterfacesClassifierIetfAclWriterFactory implements WriterFactory { + + public static final InstanceIdentifier IFC_ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class); + public static final InstanceIdentifier VPP_IFC_AUG_ID = + IFC_ID.augmentation(VppInterfaceAclAugmentation.class); + public static final InstanceIdentifier IETF_ACL_ID = VPP_IFC_AUG_ID.child(IetfAcl.class); + public static final InstanceIdentifier INGRESS_IETF_ACL_ID = IETF_ACL_ID.child(Ingress.class); + public static final InstanceIdentifier EGRESS_IETF_ACL_ID = IETF_ACL_ID.child(Egress.class); + + private final IngressIetfAclWriter ingressAclWriter; + private final EgressIetfAclWriter egressAclWriter; + private final NamingContext ifcNamingContext; + + @Inject + public InterfacesClassifierIetfAclWriterFactory(final IngressIetfAclWriter ingressAclWriter, + final EgressIetfAclWriter egressAclWriter, + @Named("interface-context") final NamingContext interfaceContextDependency) { + this.ingressAclWriter = ingressAclWriter; + this.egressAclWriter = egressAclWriter; + this.ifcNamingContext = interfaceContextDependency; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Ingress IETF-ACL, also handles AccessLists and Acl: + final InstanceIdentifier accessListsIdIngress = + InstanceIdentifier.create(Ingress.class).child(AccessLists.class); + final InstanceIdentifier aclIdIngress = accessListsIdIngress.child(Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdIngress, aclIdIngress), + new GenericWriter<>(INGRESS_IETF_ACL_ID, + new io.fd.hc2vpp.vpp.classifier.write.acl.ingress.IetfAclCustomizer(ingressAclWriter, ifcNamingContext))); + + // Ingress IETF-ACL, also handles AccessLists and Acl: + final InstanceIdentifier accessListsIdEgress = + InstanceIdentifier.create(Egress.class).child(AccessLists.class); + final InstanceIdentifier aclIdEgress = accessListsIdEgress.child(Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdEgress, aclIdEgress), + new GenericWriter<>(EGRESS_IETF_ACL_ID, + new io.fd.hc2vpp.vpp.classifier.write.acl.egress.IetfAclCustomizer(egressAclWriter, ifcNamingContext))); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfaceAclWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfaceAclWriterFactory.java new file mode 100644 index 000000000..f95cf718e --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfaceAclWriterFactory.java @@ -0,0 +1,78 @@ +/* + * 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.vpp.classifier.factory.write; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.factory.InterfacesWriterFactory; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.SubInterfaceAclCustomizer; +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.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclWriterFactory implements WriterFactory { + + public static final InstanceIdentifier SUB_IFC_AUG_ID = + InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); + public static final InstanceIdentifier SUB_IFC_ID = + SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); + public static final InstanceIdentifier SUB_IF_ACL_AUG_ID = + SUB_IFC_ID.augmentation(VppSubinterfaceAclAugmentation.class); + + public static final InstanceIdentifier SUBIF_ACL_ID = SUB_IF_ACL_AUG_ID.child(Acl.class); + public static final InstanceIdentifier SUBIF_INGRESS_ACL_ID = SUBIF_ACL_ID.child(Ingress.class); + + @Inject + private FutureJVppCore jvpp; + + @Inject + @Named("interface-context") + private NamingContext ifcNamingContext; + + @Inject + @Named("classify-table-context") + private VppClassifierContextManager classifyTableContext; + + @Override + public void init(@Nonnull ModifiableWriterRegistryBuilder registry) { + // Ingress (execute after classify table and session writers) + // also handles L2Acl, Ip4Acl and Ip6Acl: + final InstanceIdentifier aclId = InstanceIdentifier.create(Ingress.class); + registry + .subtreeAddAfter( + Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)), + new GenericWriter<>(SUBIF_INGRESS_ACL_ID, + new SubInterfaceAclCustomizer(jvpp, ifcNamingContext, classifyTableContext)), + Sets.newHashSet(VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID, + VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfacesClassifierIetfAclWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfacesClassifierIetfAclWriterFactory.java new file mode 100644 index 000000000..c04c3642f --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/SubInterfacesClassifierIetfAclWriterFactory.java @@ -0,0 +1,89 @@ +/* + * 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.vpp.classifier.factory.write; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.factory.InterfacesWriterFactory; +import io.fd.hc2vpp.vpp.classifier.write.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.IngressIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.SubInterfaceIetfAclCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class SubInterfacesClassifierIetfAclWriterFactory implements WriterFactory { + + public static final InstanceIdentifier SUB_IFC_AUG_ID = + InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); + public static final InstanceIdentifier SUB_IFC_ID = + SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); + + public static final InstanceIdentifier SUB_IFC_ACL_AUG_ID = + SUB_IFC_ID.augmentation(VppSubinterfaceAclAugmentation.class); + + public static final InstanceIdentifier SUBIF_IETF_ACL_ID = SUB_IFC_ACL_AUG_ID.child(IetfAcl.class); + public static final InstanceIdentifier SUBIF_INGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child(Ingress.class); + public static final InstanceIdentifier SUBIF_EGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child(Egress.class); + + private final IngressIetfAclWriter ingressAclWriter; + private final EgressIetfAclWriter egressAclWriter; + private final NamingContext ifcContext; + + @Inject + public SubInterfacesClassifierIetfAclWriterFactory(final IngressIetfAclWriter ingressAclWriter, + final EgressIetfAclWriter egressAclWriter, + @Named("interface-context") final NamingContext ifcContext) { + this.ingressAclWriter = ingressAclWriter; + this.egressAclWriter = egressAclWriter; + this.ifcContext = ifcContext; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Ingress IETF-ACL, also handles AccessLists and Acl: + final InstanceIdentifier accessListsIdIngress = + InstanceIdentifier.create(Ingress.class).child(AccessLists.class); + final InstanceIdentifier aclIdIngress = accessListsIdIngress.child(Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdIngress, aclIdIngress), + new GenericWriter<>(SUBIF_INGRESS_IETF_ACL_ID, + new SubInterfaceIetfAclCustomizer(ingressAclWriter, ifcContext))); + + // Egress IETF-ACL, also handles AccessLists and Acl: + final InstanceIdentifier accessListsIdEgress = + InstanceIdentifier.create(Egress.class).child(AccessLists.class); + final InstanceIdentifier aclIdEgress = accessListsIdEgress.child(Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdEgress, aclIdEgress), + new GenericWriter<>(SUBIF_EGRESS_IETF_ACL_ID, + new io.fd.hc2vpp.vpp.classifier.write.acl.egress.SubInterfaceIetfAclCustomizer( + egressAclWriter, ifcContext))); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/VppClassifierHoneycombWriterFactory.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/VppClassifierHoneycombWriterFactory.java new file mode 100644 index 000000000..cf34e910c --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/factory/write/VppClassifierHoneycombWriterFactory.java @@ -0,0 +1,64 @@ +/* + * 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.vpp.classifier.factory.write; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.write.ClassifySessionWriter; +import io.fd.hc2vpp.vpp.classifier.write.ClassifyTableWriter; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +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.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VppClassifierHoneycombWriterFactory implements WriterFactory { + + public static final InstanceIdentifier CLASSIFY_TABLE_ID = + InstanceIdentifier.create(VppClassifier.class).child(ClassifyTable.class); + + public static final InstanceIdentifier CLASSIFY_SESSION_ID = + CLASSIFY_TABLE_ID.child(ClassifySession.class); + + private final FutureJVppCore jvpp; + private final VppClassifierContextManager classifyTableContext; + + @Inject + public VppClassifierHoneycombWriterFactory(@Nonnull final FutureJVppCore jvpp, + @Named("classify-table-context") @Nonnull final VppClassifierContextManager classifyTableContext) { + this.jvpp = jvpp; + this.classifyTableContext = classifyTableContext; + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + // Ordering here is: First create table, then create sessions and then assign as ACL + // ClassifyTable + registry.addBefore( + new GenericListWriter<>(CLASSIFY_TABLE_ID, new ClassifyTableWriter(jvpp, classifyTableContext)), + CLASSIFY_SESSION_ID); + // ClassifyTableSession + registry.addBefore( + new GenericListWriter<>(CLASSIFY_SESSION_ID, new ClassifySessionWriter(jvpp, classifyTableContext)), + InterfaceAclWriterFactory.ACL_ID); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/EgressIetfAClWriterProvider.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/EgressIetfAClWriterProvider.java new file mode 100644 index 000000000..afba2118e --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/EgressIetfAClWriterProvider.java @@ -0,0 +1,39 @@ +/* + * 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.vpp.classifier.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManagerImpl; +import io.fd.hc2vpp.vpp.classifier.write.acl.egress.EgressIetfAclWriter; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; + +public class EgressIetfAClWriterProvider implements Provider { + + private final FutureJVppCore jvpp; + + @Inject + public EgressIetfAClWriterProvider(final FutureJVppCore jvpp) { + this.jvpp = jvpp; + } + + @Override + public EgressIetfAclWriter get() { + return new EgressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Egress)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/IngressIetfAClWriterProvider.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/IngressIetfAClWriterProvider.java new file mode 100644 index 000000000..ef6c01347 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/provider/IngressIetfAClWriterProvider.java @@ -0,0 +1,39 @@ +/* + * 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.vpp.classifier.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManagerImpl; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.IngressIetfAclWriter; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; + +public class IngressIetfAClWriterProvider implements Provider { + + private final FutureJVppCore jvpp; + + @Inject + public IngressIetfAClWriterProvider(final FutureJVppCore jvpp) { + this.jvpp = jvpp; + } + + @Override + public IngressIetfAclWriter get() { + return new IngressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Ingress)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReader.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReader.java new file mode 100644 index 000000000..4b985538e --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReader.java @@ -0,0 +1,212 @@ +/* + * 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.vpp.classifier.read; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.primitives.UnsignedInts; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +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; + +/** + * Reader customizer responsible for classify session read.
to VPP.
Equivalent to invoking {@code vppctl show + * class table verbose} command. + */ +public class ClassifySessionReader extends FutureJVppCustomizer + implements ListReaderCustomizer, + InterfaceDataTranslator, VppNodeReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionReader.class); + static final String CACHE_KEY = ClassifySessionReader.class.getName(); + + private final VppClassifierContextManager classifyTableContext; + + public ClassifySessionReader(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((ClassifyTableBuilder) builder).setClassifySession(readData); + } + + @Nonnull + @Override + public ClassifySessionBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new ClassifySessionBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySessionBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for classify session: {}", id); + + final ClassifySessionKey key = id.firstKeyOf(ClassifySession.class); + Preconditions.checkArgument(key != null, "could not find ClassifySession key in {}", id); + + final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); + final byte[] match = DatatypeConverter.parseHexBinary(key.getMatch().getValue().replace(":", "")); + final Optional classifySession = + findClassifySessionDetailsByMatch(classifySessionDump, match); + + if (classifySession.isPresent()) { + final ClassifySessionDetails detail = classifySession.get(); + final Optional node = + readVppNode(detail.tableId, detail.hitNextIndex, classifyTableContext, ctx.getMappingContext(), LOG); + if (node.isPresent()) { + builder.setHitNext(node.get()); + } else { + builder.setHitNext(new VppNode(new VppNodeName("unknown"))); // TODO(HC2VPP-9): remove this workaround + } + if (detail.opaqueIndex != ~0) { + // value is specified: + builder.setOpaqueIndex(readOpaqueIndex(detail.tableId, detail.opaqueIndex, ctx.getMappingContext())); + } + builder.setAdvance(detail.advance); + builder.setMatch(key.getMatch()); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for classify session {} successfully read: {}", id, builder.build()); + } + } + } + + private OpaqueIndex readOpaqueIndex(final int tableIndex, final int opaqueIndex, final MappingContext ctx) { + // We first try to map the value to a vpp node, if that fails, simply wrap the u32 value + // TODO: HONEYCOMB-118 the approach might fail if the opaqueIndex contains small value that collides + // with some of the adjacent nodes + + final Optional node = readVppNode(tableIndex, opaqueIndex, classifyTableContext, ctx, LOG); + if (node.isPresent()) { + return new OpaqueIndex(node.get()); + } else { + return new OpaqueIndex(UnsignedInts.toLong(opaqueIndex)); + } + } + + @Nullable + private ClassifySessionDetailsReplyDump dumpClassifySessions(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) + throws ReadFailedException { + final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); + Preconditions.checkArgument(tableKey != null, "could not find ClassifyTable key in {}", id); + + final String cacheKey = CACHE_KEY + tableKey; + + ClassifySessionDetailsReplyDump classifySessionDump = + (ClassifySessionDetailsReplyDump) ctx.getModificationCache().get(cacheKey); + if (classifySessionDump != null) { + LOG.debug("Classify sessions is present in cache: {}", cacheKey); + return classifySessionDump; + } + + final String tableName = tableKey.getName(); + Preconditions.checkState(classifyTableContext.containsTable(tableName, ctx.getMappingContext()), + "Reading classify sessions for table {}, but table index could not be found in the classify table context", + tableName); + final int tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); + LOG.debug("Dumping classify sessions for classify table id={}", tableId); + + + final ClassifySessionDump dumpRequest = new ClassifySessionDump(); + dumpRequest.tableId = tableId; + final int timeOut = 30; // there can be many session with current ietf-acl implementation (could be probably + // removed after fixing HONEYCOMB-247) + classifySessionDump = + getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id, timeOut); + + if (classifySessionDump != null) { + // update the cache: + ctx.getModificationCache().put(cacheKey, classifySessionDump); + } + + return classifySessionDump; + } + + private static Optional findClassifySessionDetailsByMatch( + @Nullable final ClassifySessionDetailsReplyDump classifySessionDump, @Nonnull final byte[] match) { + if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { + final List details = classifySessionDump.classifySessionDetails; + final List filteredSessions = details.stream() + .filter(singleDetail -> Arrays.equals(singleDetail.match, match)).collect(Collectors.toList()); + if (filteredSessions.isEmpty()) { + return Optional.absent(); + } else if (filteredSessions.size() == 1) { + return Optional.of(filteredSessions.get(0)); + } else { + throw new IllegalStateException(String.format( + "Found %d classify sessions witch given match. Single session expected.", + filteredSessions.size())); + } + } + return Optional.absent(); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading list of keys for classify sessions: {}", id); + + final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); + if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { + return classifySessionDump.classifySessionDetails.stream() + .map(detail -> new ClassifySessionKey(new HexString(printHexBinary(detail.match)))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReader.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReader.java new file mode 100644 index 000000000..27d3e1075 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReader.java @@ -0,0 +1,177 @@ +/* + * 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.vpp.classifier.read; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.primitives.UnsignedInts; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +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.vpp.jvpp.core.dto.ClassifyTableIds; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Arrays; +import java.util.Collections; +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.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +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; + +/** + * Reader customizer responsible for classify table read.
to VPP.
Equivalent to invoking {@code vppctl show + * class table} command. + */ +public class ClassifyTableReader extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, VppNodeReader, + MacTranslator, InterfaceDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableReader.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifyTableReader(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((VppClassifierStateBuilder) builder).setClassifyTable(readData); + } + + @Nonnull + @Override + public ClassifyTableBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new ClassifyTableBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTableBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for classify table: {}", id); + + final ClassifyTableKey key = id.firstKeyOf(ClassifyTable.class); + Preconditions.checkArgument(key != null, "could not find ClassifyTable key in {}", id); + final ClassifyTableInfo request = new ClassifyTableInfo(); + + final String tableName = key.getName(); + if (!classifyTableContext.containsTable(tableName, ctx.getMappingContext())) { + LOG.debug("Could not find classify table {} in the naming context", tableName); + return; + } + request.tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); + + + final ClassifyTableInfoReply reply = + getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); + + // mandatory values: + builder.setName(tableName); + builder.setKey(key); + builder.setNbuckets(UnsignedInts.toLong(reply.nbuckets)); + builder.setSkipNVectors(UnsignedInts.toLong(reply.skipNVectors)); + + // optional value read from context + final Optional tableBaseNode = + classifyTableContext.getTableBaseNode(tableName, ctx.getMappingContext()); + if (tableBaseNode.isPresent()) { + builder.setClassifierNode(new VppNodeName(tableBaseNode.get())); + } + + final Optional node = + readVppNode(reply.tableId, reply.missNextIndex, classifyTableContext, ctx.getMappingContext(), LOG); + if (node.isPresent()) { + builder.setMissNext(node.get()); + } else { + builder.setMissNext(new VppNode(new VppNodeName("unknown"))); // TODO(HC2VPP-9): remove this workaround + } + builder.setMask(new HexString(printHexBinary(reply.mask))); + builder.setActiveSessions(UnsignedInts.toLong(reply.activeSessions)); + + if (reply.nextTableIndex != ~0) { + // next table index is present: + builder.setNextTable(classifyTableContext.getTableName(reply.nextTableIndex, ctx.getMappingContext())); + } + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for classify table {} successfully read: {}", id, builder.build()); + } + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + LOG.debug("Reading list of keys for classify tables: {}", id); + + final ClassifyTableIdsReply classifyTableIdsReply = + getReplyForRead(getFutureJVpp().classifyTableIds(new ClassifyTableIds()).toCompletableFuture(), + id); + if (classifyTableIdsReply.ids != null) { + return Arrays.stream(classifyTableIdsReply.ids).mapToObj(i -> { + final String tableName = classifyTableContext.getTableName(i, context.getMappingContext()); + LOG.trace("Classify table with name: {} and index: {} found in VPP", tableName, i); + return new ClassifyTableKey(tableName); + }).collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder(readValue) + .setName(readValue.getName()) + .build()); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InstanceIdentifier.create(VppClassifier.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey(id.firstKeyOf(ClassifyTable.class).getName())); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/VppNodeReader.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/VppNodeReader.java new file mode 100644 index 000000000..8fe4786bc --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/VppNodeReader.java @@ -0,0 +1,46 @@ +/* + * 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.vpp.classifier.read; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.slf4j.Logger; + +interface VppNodeReader { + + /** + * Converts vpp node index to YANG representation of vpp node. + * + * @param nodeIndex index of vpp node treated as signed integer. + * @return vpp node representation + */ + default Optional readVppNode(final int tableIndex, final int nodeIndex, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final Logger log) { + final PacketHandlingAction action = PacketHandlingAction.forValue(nodeIndex); + if (action == null) { + return vppClassifierContextManager.getNodeName(tableIndex, nodeIndex, ctx) + .transform(nodeName -> new VppNode(new VppNodeName(nodeName))); + } + return Optional.of(new VppNode(action)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizer.java new file mode 100644 index 000000000..6d5fde4e5 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizer.java @@ -0,0 +1,119 @@ +/* + * 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.vpp.classifier.read.acl; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +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.RWUtils; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +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.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +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; + +/** + * Customizer for reading ingress ACLs enabled on given interface. + */ +public class AclCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public AclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(jvpp); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { + ((AclBuilder) parentBuilder).setIngress(readValue); + } + + @Nonnull + @Override + public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new IngressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final IngressBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for interface ACL: {}", id); + final InterfaceKey interfaceKey = id.firstKeyOf(Interface.class); + checkArgument(interfaceKey != null, "No parent interface key found"); + + final ClassifyTableByInterface request = new ClassifyTableByInterface(); + request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext()); + + final ClassifyTableByInterfaceReply reply = + getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + + builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Ingress readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new IngressBuilder() + .setL2Acl(readValue.getL2Acl()) + .setIp4Acl(readValue.getIp4Acl()) + .setIp6Acl(readValue.getIp6Acl()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAclAugmentation.class) + .child(Acl.class) + .child(Ingress.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclReader.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclReader.java new file mode 100644 index 000000000..7c74a330b --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclReader.java @@ -0,0 +1,60 @@ +/* + * 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.vpp.classifier.read.acl; + +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2AclBuilder; + +interface AclReader { + + @Nonnull + default L2Acl readL2Acl(final int l2TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (l2TableId == ~0) { + return null; + } + return new L2AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(l2TableId, mappingContext)).build(); + } + + @Nonnull + default Ip4Acl readIp4Acl(final int ip4TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (ip4TableId == ~0) { + return null; + } + return new Ip4AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(ip4TableId, mappingContext)).build(); + } + + @Nonnull + default Ip6Acl readIp6Acl(final int ip6TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (ip6TableId == ~0) { + return null; + } + return new Ip6AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(ip6TableId, mappingContext)).build(); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizer.java new file mode 100644 index 000000000..a2671f15e --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizer.java @@ -0,0 +1,122 @@ +/* + * 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.vpp.classifier.read.acl; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +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.RWUtils; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +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.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +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; + +/** + * Customizer for reading ingress ACLs enabled on given sub-interface. + */ +public class SubInterfaceAclCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(jvpp); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { + ((AclBuilder) parentBuilder).setIngress(readValue); + } + + @Nonnull + @Override + public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new IngressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final IngressBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for sub-interface ACL: {}", id); + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + checkArgument(parentInterfacekey != null, "No parent interface key found"); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + checkArgument(subInterfacekey != null, "No sub-interface key found"); + final String subInterfaceName = + getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + + final ClassifyTableByInterface request = new ClassifyTableByInterface(); + request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + + final ClassifyTableByInterfaceReply reply = + getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + + builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final Ingress readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), readValue); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .augmentation(VppSubinterfaceAclAugmentation.class) + .child(Acl.class) + .child(Ingress.class); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java new file mode 100644 index 000000000..00e858955 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java @@ -0,0 +1,165 @@ +/* + * 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.vpp.classifier.write; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +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.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for classify session create/delete.
Sends {@code classify_add_del_session} message + * to VPP.
Equivalent to invoking {@code vppctl classify table} command. + */ +public class ClassifySessionWriter extends VppNodeWriter + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionWriter.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifySessionWriter(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Creating classify session: iid={} dataAfter={}", id, dataAfter); + try { + classifyAddDelSession(true, id, dataAfter, writeContext); + LOG.debug("Successfully created classify session: iid={} dataAfter={}", id, dataAfter); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataBefore, + @Nonnull final ClassifySession dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Classify session update is not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing classify session: iid={} dataBefore={}", id, dataBefore); + try { + classifyAddDelSession(false, id, dataBefore, writeContext); + LOG.debug("Successfully removed classify session: iid={} dataBefore={}", id, dataBefore); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private void classifyAddDelSession(final boolean isAdd, @Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession classifySession, + @Nonnull final WriteContext writeContext) + throws VppBaseCallException, WriteFailedException { + final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); + Preconditions.checkArgument(tableKey != null, "could not find classify table key in {}", id); + + final String tableName = tableKey.getName(); + Preconditions.checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), + "Could not find classify table index for {} in the classify table context", tableName); + final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); + + final ClassifyTable classifyTable = + getClassifyTable(writeContext, id.firstIdentifierOf(ClassifyTable.class), isAdd); + final int hitNextIndex = getNodeIndex(classifySession.getHitNext(), classifyTable, classifyTableContext, + writeContext.getMappingContext(), id); + final int opaqueIndex = + getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); + + final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() + .classifyAddDelSession( + getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); + + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + } + + private ClassifyTable getClassifyTable(final WriteContext writeContext, + @Nonnull final InstanceIdentifier id, + final boolean isAdd) { + final Optional classifyTable; + if (isAdd) { + classifyTable = writeContext.readAfter(id); + } else { + classifyTable = writeContext.readBefore(id); + } + return classifyTable.get(); + } + + private ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, + @Nonnull final ClassifySession classifySession, + final int tableIndex, + final int hitNextIndex, + final int opaqueIndex) { + ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = booleanToByte(isAdd); + request.tableIndex = tableIndex; + request.hitNextIndex = hitNextIndex; + request.opaqueIndex = opaqueIndex; + + // default 0: + request.advance = classifySession.getAdvance(); + + request.match = DatatypeConverter.parseHexBinary(classifySession.getMatch().getValue().replace(":", "")); + return request; + } + + private int getOpaqueIndex(@Nullable final OpaqueIndex opaqueIndex, final ClassifyTable classifyTable, + final MappingContext ctx, final InstanceIdentifier id) + throws VppBaseCallException, WriteFailedException { + if (opaqueIndex == null) { + return ~0; // value not specified + } + if (opaqueIndex.getUint32() != null) { + return opaqueIndex.getUint32().intValue(); + } else { + return getNodeIndex(opaqueIndex.getVppNode(), classifyTable, classifyTableContext, ctx, id); + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriter.java new file mode 100644 index 000000000..a88620b35 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriter.java @@ -0,0 +1,150 @@ +/* + * 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.vpp.classifier.write; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +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.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for classify table create/delete.
Sends {@code classify_add_del_table} message to + * VPP.
Equivalent to invoking {@code vppctl classify table} command. + */ +public class ClassifyTableWriter extends VppNodeWriter + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableWriter.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifyTableWriter(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Creating classify table: iid={} dataAfter={}", id, dataAfter); + try { + final int newTableIndex = + classifyAddDelTable(true, id, dataAfter, ~0 /* value not present */, + writeContext.getMappingContext()); + + // Add classify table name <-> vpp index mapping to the naming context: + classifyTableContext.addTable(newTableIndex, dataAfter.getName(), dataAfter.getClassifierNode(), + writeContext.getMappingContext()); + LOG.debug("Successfully created classify table(id={]): iid={} dataAfter={}", newTableIndex, id, dataAfter); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataBefore, @Nonnull final ClassifyTable dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Classify table update is not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing classify table: iid={} dataBefore={}", id, dataBefore); + final String tableName = dataBefore.getName(); + Preconditions.checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), + "Removing classify table {}, but index could not be found in the classify table context", tableName); + + final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); + try { + classifyAddDelTable(false, id, dataBefore, tableIndex, writeContext.getMappingContext()); + + // Remove deleted interface from interface context: + classifyTableContext.removeTable(dataBefore.getName(), writeContext.getMappingContext()); + LOG.debug("Successfully removed classify table(id={]): iid={} dataAfter={}", tableIndex, id, dataBefore); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private int classifyAddDelTable(final boolean isAdd, @Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable table, final int tableId, final MappingContext ctx) + throws VppBaseCallException, WriteFailedException { + + final int missNextIndex = + getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); + + final CompletionStage createClassifyTableReplyCompletionStage = + getFutureJVpp() + .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); + + final ClassifyAddDelTableReply reply = + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + return reply.newTableIndex; + } + + private ClassifyAddDelTable getClassifyAddDelTableRequest(final boolean isAdd, final int tableIndex, + @Nonnull final ClassifyTable table, + final int missNextIndex, + @Nonnull final MappingContext ctx) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = booleanToByte(isAdd); + request.tableIndex = tableIndex; + + // mandatory, all u32 values are permitted: + request.nbuckets = table.getNbuckets().intValue(); + request.memorySize = table.getMemorySize().intValue(); + request.skipNVectors = table.getSkipNVectors().intValue(); + + // mandatory + request.missNextIndex = missNextIndex; + + final String nextTable = table.getNextTable(); + if (isAdd && nextTable != null) { + request.nextTableIndex = classifyTableContext.getTableIndex(nextTable, ctx); + } else { + request.nextTableIndex = ~0; // value not specified + } + request.mask = DatatypeConverter.parseHexBinary(table.getMask().getValue().replace(":", "")); + checkArgument(request.mask.length % 16 == 0, "Number of mask bytes must be multiple of 16."); + request.matchNVectors = request.mask.length / 16; + + return request; + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/VppNodeWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/VppNodeWriter.java new file mode 100644 index 000000000..c513e8cd7 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/VppNodeWriter.java @@ -0,0 +1,80 @@ +/* + * 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.vpp.classifier.write; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.GetNextIndex; +import io.fd.vpp.jvpp.core.dto.GetNextIndexReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +abstract class VppNodeWriter extends FutureJVppCustomizer implements JvppReplyConsumer { + + protected VppNodeWriter(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + protected int getNodeIndex(@Nonnull final VppNode node, @Nonnull final ClassifyTable classifyTable, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) + throws VppBaseCallException, WriteFailedException { + if (node.getPacketHandlingAction() != null) { + return node.getPacketHandlingAction().getIntValue(); + } else { + return nodeNameToIndex(classifyTable, node.getVppNodeName().getValue(), vppClassifierContextManager, ctx, + id); + } + } + + private int nodeNameToIndex(@Nonnull final ClassifyTable classifyTable, @Nonnull final String nextNodeName, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) + throws WriteFailedException { + checkArgument(classifyTable != null && classifyTable.getClassifierNode() != null, + "to use relative node names, table classifier node needs to be provided"); + final GetNextIndex request = new GetNextIndex(); + request.nodeName = classifyTable.getClassifierNode().getValue().getBytes(); + request.nextName = nextNodeName.getBytes(); + final CompletionStage getNextIndexCompletionStage = + getFutureJVpp().getNextIndex(request); + + final GetNextIndexReply reply; + try { + reply = getReplyForRead(getNextIndexCompletionStage.toCompletableFuture(), id); + + // vpp does not provide relative node index to node name conversion (https://jira.fd.io/browse/VPP-219) + // as a workaround we need to add mapping to vpp-classfier-context + vppClassifierContextManager.addNodeName(classifyTable.getName(), reply.nextIndex, nextNodeName, ctx); + } catch (ReadFailedException e) { + throw new WriteFailedException(id, String.format("Failed to get node index for %s relative to %s", + nextNodeName, classifyTable.getClassifierNode()), e); + } + return reply.nextIndex; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/IetfAclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/IetfAclWriter.java new file mode 100644 index 000000000..41ca796e7 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/IetfAclWriter.java @@ -0,0 +1,105 @@ +/* + * 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.vpp.classifier.write.acl; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.Optional; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +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.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for Access Control Lists management. Does not send any messages to VPP. All the config + * data are stored in HC and used when acl is assigned/unassigned to/from an interface. + * + * ACLs that are currently assigned to an interface cannot be updated/deleted. + */ +public class IetfAclWriter implements ListWriterCustomizer { + + public static final InstanceIdentifier ACL_ID = + InstanceIdentifier.create(AccessLists.class); + + private static final Logger LOG = LoggerFactory.getLogger(IetfAclWriter.class); + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Creating ACL: iid={} dataAfter={}", id, dataAfter); + + // no vpp call, just updates DataTree + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, + @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Updating ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); + + if (isAssigned(dataAfter, writeContext)) { + throw new WriteFailedException(id, + String.format("Failed to update data at %s: acl %s is already assigned", id, dataAfter)); + } + + LOG.debug("Updating unassigned ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); + + // no vpp call, just updates DataTree + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Deleting ACL: iid={} dataBefore={}", id, dataBefore); + + if (isAssigned(dataBefore, writeContext)) { + throw new WriteFailedException(id, + String.format("Failed to delete data at %s: acl %s is already assigned", id, dataBefore)); + } + + LOG.debug("Deleting unassigned ACL: iid={} dataBefore={}", id, dataBefore); + + // no vpp call, just updates DataTree + } + + private static boolean isAssigned(@Nonnull final Acl acl, + @Nonnull final WriteContext writeContext) { + final String aclName = acl.getAclName(); + final Class aclType = acl.getAclType(); + final Interfaces interfaces = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class)).get(); + + return interfaces.getInterface().stream() + .map(i -> Optional.ofNullable(i.getAugmentation(VppInterfaceAclAugmentation.class)) + .map(aug -> aug.getIetfAcl()) + .map(ietfAcl -> ietfAcl.getIngress()) + .map(ingress -> ingress.getAccessLists()) + .map(accessLists -> accessLists.getAcl())) + .flatMap(iacl -> iacl.isPresent() + ? iacl.get().stream() + : Stream.empty()) + .filter(assignedAcl -> aclName.equals(assignedAcl.getName()) && aclType.equals(assignedAcl.getType())) + .findFirst().isPresent(); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AbstractIetfAclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AbstractIetfAclWriter.java new file mode 100644 index 000000000..59d314c03 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AbstractIetfAclWriter.java @@ -0,0 +1,252 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +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.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.matches.AceType; +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.ace.type.AceEth; +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.ace.type.AceIp; +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.ace.type.ace.ip.AceIpVersion; +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.ace.type.ace.ip.ace.ip.version.AceIpv4; +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.ace.type.ace.ip.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyConsumer, AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractIetfAclWriter.class); + protected static final int NOT_DEFINED = -1; + protected final FutureJVppCore jvpp; + + private Map> aceWriters = new HashMap<>(); + + public AbstractIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { + this.jvpp = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); + aceWriters.put(AclType.ETH, new AceEthWriter()); + aceWriters.put(AclType.IP4, new AceIp4Writer()); + aceWriters.put(AclType.IP6, new AceIp6Writer()); + aceWriters.put(AclType.ETH_AND_IP, new AceIpAndEthWriter()); + } + + private static Stream aclToAceStream(@Nonnull final Acl assignedAcl, + @Nonnull final WriteContext writeContext) { + final String aclName = assignedAcl.getName(); + final Class aclType = assignedAcl.getType(); + + // ietf-acl updates are handled first, so we use writeContext.readAfter + final Optional + aclOptional = + writeContext.readAfter(io.fd.hc2vpp.vpp.classifier.write.acl.IetfAclWriter.ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, + new AclKey(aclName, aclType))); + checkArgument(aclOptional.isPresent(), "Acl lists not configured"); + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl + acl = aclOptional.get(); + + final AccessListEntries accessListEntries = acl.getAccessListEntries(); + checkArgument(accessListEntries != null, "access list entries not configured"); + + return accessListEntries.getAce().stream(); + } + + protected void removeClassifyTables(@Nonnull final InstanceIdentifier id, @Nonnull final MappingEntry entry) + throws WriteFailedException { + removeClassifyTable(id, entry.getL2TableId()); + removeClassifyTable(id, entry.getIp4TableId()); + removeClassifyTable(id, entry.getIp6TableId()); + } + + private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) + throws WriteFailedException { + + if (tableIndex == -1) { + return; // classify table id is absent + } + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.delChain = 1; + request.tableIndex = tableIndex; + final CompletionStage cs = jvpp.classifyAddDelTable(request); + getReplyForDelete(cs.toCompletableFuture(), id); + } + + protected static boolean appliesToIp4Path(final Ace ace) { + final AceType aceType = ace.getMatches().getAceType(); + final AclType aclType = AclType.fromAce(ace); + if (aclType == AclType.IP4) { + return true; + } + if (aclType == AclType.ETH) { + return true; // L2 only rules are possible for IP4 traffic + } + if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType).getAceIpAndEthNodes() + .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4) { + return true; + } + return false; + } + + protected static boolean appliesToIp6Path(final Ace ace) { + final AceType aceType = ace.getMatches().getAceType(); + final AclType aclType = AclType.fromAce(ace); + if (aclType == AclType.IP6) { + return true; + } + if (aclType == AclType.ETH) { + return true; // L2 only rules are possible for IP6 traffic + } + if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType).getAceIpAndEthNodes() + .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv6) { + return true; + } + return false; + } + + protected static List getACEs(@Nonnull final List acls, @Nonnull final WriteContext writeContext, + final Predicate filter) { + return acls.stream().flatMap(acl -> aclToAceStream(acl, writeContext)).filter(filter) + .collect(Collectors.toList()); + } + + protected int writeAces(final InstanceIdentifier id, final List aces, + final AccessLists.DefaultAction defaultAction, final InterfaceMode mode, + final int vlanTags) throws WriteFailedException { + if (aces.isEmpty()) { + return NOT_DEFINED; + } + + int nextTableIndex = configureDefaultAction(id, defaultAction); + final ListIterator iterator = aces.listIterator(aces.size()); + while (iterator.hasPrevious()) { + final Ace ace = iterator.previous(); + LOG.trace("Processing ACE: {}", ace); + + final AceWriter aceWriter = + aceWriters.get(AclType.fromAce(ace)); + if (aceWriter == null) { + LOG.warn("AceProcessor for {} not registered. Skipping ACE.", ace.getClass()); + } else { + final AceType aceType = ace.getMatches().getAceType(); + final PacketHandling action = ace.getActions().getPacketHandling(); + final ClassifyAddDelTable ctRequest = aceWriter.createTable(aceType, mode, nextTableIndex, vlanTags); + nextTableIndex = createClassifyTable(id, ctRequest); + final List sessionRequests = + aceWriter.createSession(action, aceType, mode, nextTableIndex, vlanTags); + for (ClassifyAddDelSession csRequest : sessionRequests) { + createClassifySession(id, csRequest); + } + } + } + return nextTableIndex; + } + + private int configureDefaultAction(@Nonnull final InstanceIdentifier id, + final AccessLists.DefaultAction defaultAction) + throws WriteFailedException { + ClassifyAddDelTable ctRequest = createTable(-1); + if (AccessLists.DefaultAction.Permit.equals(defaultAction)) { + ctRequest.missNextIndex = -1; + } else { + ctRequest.missNextIndex = 0; + } + ctRequest.mask = new byte[16]; + ctRequest.skipNVectors = 0; + ctRequest.matchNVectors = 1; + return createClassifyTable(id, ctRequest); + } + + private int createClassifyTable(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyAddDelTable request) + throws WriteFailedException { + final CompletionStage cs = jvpp.classifyAddDelTable(request); + + final ClassifyAddDelTableReply reply = getReplyForWrite(cs.toCompletableFuture(), id); + return reply.newTableIndex; + } + + private void createClassifySession(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyAddDelSession request) + throws WriteFailedException { + final CompletionStage cs = jvpp.classifyAddDelSession(request); + + getReplyForWrite(cs.toCompletableFuture(), id); + } + + private enum AclType { + ETH, IP4, IP6, ETH_AND_IP; + + @Nonnull + private static AclType fromAce(final Ace ace) { + AclType result = null; + final AceType aceType; + try { + aceType = ace.getMatches().getAceType(); + if (aceType instanceof AceEth) { + result = ETH; + } else if (aceType instanceof AceIp) { + final AceIpVersion aceIpVersion = ((AceIp) aceType).getAceIpVersion(); + if (aceIpVersion == null) { + throw new IllegalArgumentException("Incomplete ACE (ip-version was not provided): " + ace); + } + if (aceIpVersion instanceof AceIpv4) { + result = IP4; + } else if (aceIpVersion instanceof AceIpv6) { + result = IP6; + } + } else if (aceType instanceof AceIpAndEth) { + result = ETH_AND_IP; + } + } catch (NullPointerException e) { + throw new IllegalArgumentException("Incomplete ACE: " + ace, e); + } + if (result == null) { + throw new IllegalArgumentException(String.format("Not supported ace type %s", aceType)); + } + return result; + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriter.java new file mode 100644 index 000000000..2a88239cc --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriter.java @@ -0,0 +1,85 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import com.google.common.annotations.VisibleForTesting; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.matches.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceEthWriter implements AceWriter, AclTranslator, L2AclTranslator { + + @VisibleForTesting + static final int MATCH_N_VECTORS = 1; + private static final Logger LOG = LoggerFactory.getLogger(AceEthWriter.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceEth aceEth, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + final ClassifyAddDelTable request = createTable(nextTableIndex); + + request.mask = new byte[16]; + boolean aceIsEmpty = + destinationMacAddressMask(aceEth.getDestinationMacAddressMask(), aceEth.getDestinationMacAddress(), + request); + aceIsEmpty &= + sourceMacAddressMask(aceEth.getSourceMacAddressMask(), aceEth.getSourceMacAddress(), request); + + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceEth.toString())); + } + + request.skipNVectors = 0; + request.matchNVectors = MATCH_N_VECTORS; + + LOG.debug("ACE rule={} translated to table={}.", aceEth, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceEth aceEth, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + + request.match = new byte[16]; + boolean noMatch = destinationMacAddressMatch(aceEth.getDestinationMacAddress(), request); + noMatch &= sourceMacAddressMatch(aceEth.getSourceMacAddress(), request); + + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define neither source nor destination MAC address", + aceEth.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceEth, request); + return Collections.singletonList(request); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4Writer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4Writer.java new file mode 100644 index 000000000..0ae1315a8 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4Writer.java @@ -0,0 +1,94 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.annotations.VisibleForTesting; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.matches.ace.type.AceIp; +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.ace.type.ace.ip.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceIp4Writer implements AceWriter, AclTranslator, Ip4AclTranslator { + + @VisibleForTesting + static final int MATCH_N_VECTORS = 3; // number of 16B vectors + private static final int TABLE_MASK_LENGTH = 48; + private static final Logger LOG = LoggerFactory.getLogger(AceIp4Writer.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); + final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); + + final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + request.skipNVectors = 0; // match entire L2 and L3 header + request.matchNVectors = MATCH_N_VECTORS; + request.mask = new byte[TABLE_MASK_LENGTH]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean aceIsEmpty = ip4Mask(baseOffset, mode, aceIp, ipVersion, request); + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", aceIp, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); + final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); + + final List portPairs = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[TABLE_MASK_LENGTH]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean noMatch = ip4Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); + requests.add(request); + } + return requests; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6Writer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6Writer.java new file mode 100644 index 000000000..2004d4e06 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6Writer.java @@ -0,0 +1,99 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.matches.ace.type.AceIp; +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.ace.type.ace.ip.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceIp6Writer implements AceWriter, AclTranslator, Ip6AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); + final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); + + final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + request.skipNVectors = 0; // match entire L2 and L3 header + request.mask = new byte[getTableMaskLength(vlanTags)]; + request.matchNVectors = request.mask.length/16; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean aceIsEmpty = ip6Mask(baseOffset, mode, aceIp, ipVersion, request); + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", aceIp, request); + return request; + } + + private static int getTableMaskLength(final int vlanTags) { + if (vlanTags == 2) { + return 80; + } else { + return 64; + } + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); + final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); + final List portPairs = + PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); + + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[getTableMaskLength(vlanTags)]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean noMatch = ip6Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); + requests.add(request); + } + return requests; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriter.java new file mode 100644 index 000000000..8efe3564e --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriter.java @@ -0,0 +1,132 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.AceIpVersion; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv6; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class AceIpAndEthWriter + implements AceWriter, AclTranslator, L2AclTranslator, Ip4AclTranslator, Ip6AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AceIpAndEthWriter.class); + + private static int maskLength(@Nonnull final AceIpAndEth ace, final int vlanTags) { + if (ace.getAceIpAndEthNodes().getAceIpVersion() != null) { + if (ace.getAceIpAndEthNodes().getAceIpVersion() instanceof AceIpv4) { + return 48; + } else { + return vlanTags == 2 + ? 80 + : 64; + } + } + return 16; + } + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIpAndEth ace, @Nullable final InterfaceMode mode, + final int nextTableIndex, final int vlanTags) { + final AceIpAndEthNodes nodes = ace.getAceIpAndEthNodes(); + final int numberOfSessions = PortPair.fromRange(nodes.getSourcePortRange(), nodes.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + final int maskLength = maskLength(ace, vlanTags); + request.mask = new byte[maskLength]; + request.skipNVectors = 0; + request.matchNVectors = maskLength / 16; + + boolean aceIsEmpty = + destinationMacAddressMask(nodes.getDestinationMacAddressMask(), nodes.getDestinationMacAddress(), request); + aceIsEmpty &= sourceMacAddressMask(nodes.getSourceMacAddressMask(), nodes.getSourceMacAddress(), request); + + // if we use classifier API, we need to know ip version (fields common for ip4 and ip6 have different offsets): + final AceIpVersion aceIpVersion = nodes.getAceIpVersion(); + checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); + + final int baseOffset = getVlanTagsLen(vlanTags); + if (aceIpVersion instanceof AceIpv4) { + final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; + aceIsEmpty &= ip4Mask(baseOffset, mode, nodes, ipVersion, request); + } else if (aceIpVersion instanceof AceIpv6) { + final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; + aceIsEmpty &= ip6Mask(baseOffset, mode, nodes, ipVersion, request); + } else { + throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); + } + + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", ace.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", ace, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIpAndEth ace, + @Nullable final InterfaceMode mode, final int tableIndex, + final int vlanTags) { + final AceIpAndEthNodes nodes = ace.getAceIpAndEthNodes(); + final List portPairs = PortPair.fromRange(nodes.getSourcePortRange(), nodes.getDestinationPortRange()); + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[maskLength(ace, vlanTags)]; + + boolean noMatch = destinationMacAddressMatch(nodes.getDestinationMacAddress(), request); + noMatch &= sourceMacAddressMatch(nodes.getSourceMacAddress(), request); + + final AceIpVersion aceIpVersion = nodes.getAceIpVersion(); + checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); + + final int baseOffset = getVlanTagsLen(vlanTags); + if (aceIpVersion instanceof AceIpv4) { + final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; + noMatch &= ip4Match(baseOffset, mode, nodes, ipVersion, pair.getSrc(), pair.getDst(), request); + } else if (aceIpVersion instanceof AceIpv6) { + final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; + noMatch &= ip6Match(baseOffset, mode, nodes, ipVersion, pair.getSrc(), pair.getDst(), request); + } else { + throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); + } + + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", ace.toString())); + } + LOG.debug("ACE action={}, rule={} translated to session={}.", action, ace, request); + requests.add(request); + } + return requests; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceWriter.java new file mode 100644 index 000000000..228527f69 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceWriter.java @@ -0,0 +1,54 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.matches.AceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; + +/** + * Writer responsible for translation of ietf-acl model ACEs to VPP's classify tables and sessions. + * + * @param type of access control list entry + */ +interface AceWriter { + /** + * @param ace access list entry + * @param mode interface mode (L2/L3) + * @param nextTableIndex index of the next classify table in chain + * @param vlanTags number of vlan tags + */ + @Nonnull + ClassifyAddDelTable createTable(@Nonnull final T ace, @Nullable final InterfaceMode mode, final int nextTableIndex, + final int vlanTags); + + /** + * @param action to be taken when packet does match the specified ace + * @param ace access list entry + * @param mode interface mode (L2/L3) + * @param tableIndex index of corresponding classify table + * @param vlanTags number of vlan tags + */ + @Nonnull + List createSession(@Nonnull final PacketHandling action, @Nonnull T ace, + @Nullable final InterfaceMode mode, final int tableIndex, final int vlanTags); +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManager.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManager.java new file mode 100644 index 000000000..ed7960dd9 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManager.java @@ -0,0 +1,53 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; + +/** + * Manages interface metadata for ietf-acl model. + */ +public interface AclTableContextManager { + + /** + * Obtains mapping entry for given interface. + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + * @return ietf-acl metadata for given interface + */ + Optional getEntry(final int index, @Nonnull final MappingContext mappingContext); + + /** + * Adds mapping entry. + * + * @param entry to be added + * @param mappingContext mapping context providing context data for current transaction + */ + void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext); + + /** + * Removes entry for given interface (if present). + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + */ + void removeEntry(final int index, @Nonnull final MappingContext mappingContext); +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImpl.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImpl.java new file mode 100644 index 000000000..16848acfd --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImpl.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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +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.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.AclMappingEntryCtxAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.AclMappingEntryContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@ThreadSafe +public class AclTableContextManagerImpl implements AclTableContextManager { + + private MappingTable.Direction direction; + + public AclTableContextManagerImpl(@Nonnull final MappingTable.Direction direction) { + this.direction = checkNotNull(direction, "direction should not be null"); + } + + @Nonnull + @Override + public synchronized Optional getEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getId(swIfIndex)); + } + + @Override + public synchronized void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext) { + mappingContext.put(getId(entry.getIndex()), entry); + } + + @Override + public synchronized void removeEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + mappingContext.delete(getId(swIfIndex)); + } + + @VisibleForTesting + protected InstanceIdentifier getId(final int index) { + return InstanceIdentifier.create(Contexts.class) + .augmentation(AclMappingEntryCtxAugmentation.class) + .child(AclMappingEntryContext.class) + .child(MappingTable.class, new MappingTableKey(direction)) + .child(MappingEntry.class, new MappingEntryKey(index)); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTranslator.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTranslator.java new file mode 100644 index 000000000..e75d0af24 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTranslator.java @@ -0,0 +1,74 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import javax.annotation.Nonnegative; +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.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.Permit; + +/** + * Utility that helps translating of ietf-acl model ACEs to VPP's classify tables and sessions. + */ +interface AclTranslator { + int TABLE_MEM_SIZE = 8 * 1024; + int VLAN_TAG_LEN = 4; + + default ClassifyAddDelTable createTable(final int nextTableIndex) { + return createTable(nextTableIndex, 1); + } + + default ClassifyAddDelTable createTable(final int nextTableIndex, @Nonnegative final int numberOfSessions) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = 1; + request.tableIndex = -1; // value not present + request.nbuckets = numberOfSessions; + request.nextTableIndex = nextTableIndex; + + + // TODO: HONEYCOMB-181 minimise memory used by classify tables (we create a lot of them to make ietf-acl model + // mapping more convenient): + // according to https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers#Creating_a_classifier_table, + // classify table needs 16*(1 + match_n_vectors) bytes, but this does not quite work, + // so setting 8K +1k*numberOfSessions for now + checkArgument(numberOfSessions>0, "negative numberOfSessions %s", numberOfSessions); + request.memorySize = TABLE_MEM_SIZE+1024*(numberOfSessions-1); + request.missNextIndex = -1; // value not set, but anyway it is ignored for tables in chain + return request; + } + + default ClassifyAddDelSession createSession(@Nonnull final PacketHandling action, final int tableIndex) { + final ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = 1; + request.tableIndex = tableIndex; + request.opaqueIndex = ~0; // value not used + + if (action instanceof Permit) { + request.hitNextIndex = -1; + } // deny (0) is default value + + return request; + } + + default int getVlanTagsLen(final int vlanTags) { + return vlanTags * VLAN_TAG_LEN; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/IetfAclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/IetfAclWriter.java new file mode 100644 index 000000000..7f31dc06d --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/IetfAclWriter.java @@ -0,0 +1,47 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.List; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public interface IetfAclWriter { + default void write(@Nonnull final InstanceIdentifier id, final int ifIndex, @Nonnull final List acls, + final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + write(id, ifIndex, acls, defaultAction, mode, writeContext, 0, mappingContext); + } + + void write(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final List acls, + final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException; + + void deleteAcl(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final MappingContext mappingContext) + throws WriteFailedException; +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip4AclTranslator.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip4AclTranslator.java new file mode 100644 index 000000000..ad70fd844 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip4AclTranslator.java @@ -0,0 +1,149 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import com.google.common.primitives.Ints; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +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.packet.fields.rev160708.AclIpHeaderFields; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; + +interface Ip4AclTranslator extends Ipv4Translator { + int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) + int DSCP_OFFSET = 15; + int DSCP_MASK = 0xfc; + + int IP_PROTOCOL_OFFSET = ETHER_TYPE_OFFSET + 11; + int IP_PROTOCOL_MASK = 0xff; + + int IP4_LEN = 4; + int IP4_MASK_BIT_LENGTH = 32; + int SRC_IP_OFFSET = ETHER_TYPE_OFFSET + 14; + int DST_IP_OFFSET = SRC_IP_OFFSET + IP4_LEN; + int SRC_PORT_OFFSET = DST_IP_OFFSET + IP4_LEN; + int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; + + default boolean ip4Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv4HeaderFields ip4, final ClassifyAddDelTable request) { + boolean aceIsEmpty = true; + if (InterfaceMode.L2.equals(mode)) { + // in L2 mode we need to match ether type + request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; + request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; + } + if (header.getDscp() != null) { + aceIsEmpty = false; + request.mask[baseOffset + DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits + } + if (header.getProtocol() != null) { // Internet Protocol number + aceIsEmpty = false; + request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; + } + if (ip4.getSourceIpv4Network() != null) { + aceIsEmpty = false; + System.arraycopy(Impl.toByteMask(ip4.getSourceIpv4Network()), 0, request.mask, + baseOffset + SRC_IP_OFFSET, IP4_LEN); + } + if (ip4.getDestinationIpv4Network() != null) { + aceIsEmpty = false; + System.arraycopy(Impl.toByteMask(ip4.getDestinationIpv4Network()), 0, request.mask, + baseOffset + DST_IP_OFFSET, IP4_LEN); + } + return aceIsEmpty; + } + + default boolean ip4Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv4HeaderFields ip4, final Integer srcPort, + final Integer dstPort, final ClassifyAddDelSession request) { + boolean noMatch = true; + if (InterfaceMode.L2.equals(mode)) { + // match IP4 etherType (0x0800) + request.match[baseOffset + ETHER_TYPE_OFFSET] = 0x08; + request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = 0x00; + } + if (header.getDscp() != null) { + noMatch = false; + request.match[baseOffset + DSCP_OFFSET] = (byte) (DSCP_MASK & (header.getDscp().getValue() << 2)); + } + if (header.getProtocol() != null) { // Internet Protocol number + noMatch = false; + request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); + } + if (srcPort != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); + request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); + request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); + } + if (ip4.getSourceIpv4Network() != null) { + noMatch = false; + System.arraycopy(Impl.toMatchValue(ip4.getSourceIpv4Network()), 0, request.match, + baseOffset + SRC_IP_OFFSET, IP4_LEN); + + } + if (ip4.getDestinationIpv4Network() != null) { + noMatch = false; + System.arraycopy(Impl.toMatchValue(ip4.getDestinationIpv4Network()), 0, request.match, + baseOffset + DST_IP_OFFSET, IP4_LEN); + + } + return noMatch; + } + + class Impl { + private static byte[] toByteMask(final int prefixLength) { + final long mask = ((1L << prefixLength) - 1) << (IP4_MASK_BIT_LENGTH - prefixLength); + return Ints.toByteArray((int) mask); + } + + private static byte[] toByteMask(final Ipv4Prefix ipv4Prefix) { + final int prefixLength = Byte.valueOf(ipv4Prefix.getValue().split("/")[1]); + return toByteMask(prefixLength); + } + + private static byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { + final String[] split = ipv4Prefix.getValue().split("/"); + final byte[] addressBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(split[0]); + final byte[] mask = Impl.toByteMask(Byte.valueOf(split[1])); + for (int i = 0; i < addressBytes.length; ++i) { + addressBytes[i] &= mask[i]; + } + return addressBytes; + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip6AclTranslator.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip6AclTranslator.java new file mode 100644 index 000000000..f11a3d6a3 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/Ip6AclTranslator.java @@ -0,0 +1,182 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.BitSet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; +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.classifier.acl.rev161214.InterfaceMode; + +interface Ip6AclTranslator { + + int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) + int IP_VERSION_OFFSET = ETHER_TYPE_OFFSET + 2; + int DSCP_MASK1 = 0x0f; + int DSCP_MASK2 = 0xc0; + int IP_PROTOCOL_OFFSET = IP_VERSION_OFFSET + 6; + int IP_PROTOCOL_MASK = 0xff; + int IP6_LEN = 16; + int SRC_IP_OFFSET = IP_VERSION_OFFSET + 8; + int DST_IP_OFFSET = SRC_IP_OFFSET + IP6_LEN; + int SRC_PORT_OFFSET = DST_IP_OFFSET + IP6_LEN; + int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; + + default boolean ip6Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv6HeaderFields ip6, final ClassifyAddDelTable request) { + boolean aceIsEmpty = true; + if (InterfaceMode.L2.equals(mode)) { + // in L2 mode we need to match ether type + request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; + request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; + } + if (header.getDscp() != null) { + aceIsEmpty = false; + // DCSP (bits 4-9 of IP6 header) + request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1; + request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2; + } + if (header.getProtocol() != null) { // Internet Protocol number + aceIsEmpty = false; + request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; + } + if (ip6.getFlowLabel() != null) { + aceIsEmpty = false; + // bits 12-31 + request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) 0x0f; + request.mask[baseOffset + IP_VERSION_OFFSET + 2] = (byte) 0xff; + request.mask[baseOffset + IP_VERSION_OFFSET + 3] = (byte) 0xff; + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; + } + if (ip6.getSourceIpv6Network() != null) { + aceIsEmpty = false; + final byte[] mask = Impl.toByteMask(ip6.getSourceIpv6Network()); + System.arraycopy(mask, 0, request.mask, baseOffset + SRC_IP_OFFSET, mask.length); + } + if (ip6.getDestinationIpv6Network() != null) { + aceIsEmpty = false; + final byte[] mask = Impl.toByteMask(ip6.getDestinationIpv6Network()); + System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length); + } + return aceIsEmpty; + } + + default boolean ip6Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv6HeaderFields ip6, final Integer srcPort, final Integer dstPort, final ClassifyAddDelSession request) { + boolean noMatch = true; + if (InterfaceMode.L2.equals(mode)) { + // match IP6 etherType (0x86dd) + request.match[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0x86; + request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xdd; + } + if (header.getDscp() != null) { + noMatch = false; + final int dcsp = header.getDscp().getValue(); + // set bits 4-9 of IP6 header: + request.match[baseOffset + IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dcsp >> 2)); + request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dcsp << 6)); + } + if (header.getProtocol() != null) { // Internet Protocol number + noMatch = false; + request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); + } + if (ip6.getFlowLabel() != null) { + noMatch = false; + final int flowLabel = ip6.getFlowLabel().getValue().intValue(); + // bits 12-31 + request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16)); + request.match[baseOffset + IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8)); + request.match[baseOffset + IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel); + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); + request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); + request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); + } + if (ip6.getSourceIpv6Network() != null) { + noMatch = false; + final byte[] match = Impl.toMatchValue(ip6.getSourceIpv6Network()); + System.arraycopy(match, 0, request.match, baseOffset + SRC_IP_OFFSET, IP6_LEN); + } + if (ip6.getDestinationIpv6Network() != null) { + noMatch = false; + final byte[] match = Impl.toMatchValue(ip6.getDestinationIpv6Network()); + System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN); + } + return noMatch; + } + + class Impl { + private static final int IP6_MASK_BIT_LENGTH = 128; + + private static byte[] toByteMask(final int prefixLength) { + final BitSet mask = new BitSet(IP6_MASK_BIT_LENGTH); + mask.set(0, prefixLength, true); + if (prefixLength < IP6_MASK_BIT_LENGTH) { + mask.set(prefixLength, IP6_MASK_BIT_LENGTH, false); + } + return mask.toByteArray(); + } + + private static byte[] toByteMask(final Ipv6Prefix ipv6Prefix) { + final int prefixLength = Short.valueOf(ipv6Prefix.getValue().split("/")[1]); + return toByteMask(prefixLength); + } + + private static byte[] toMatchValue(final Ipv6Prefix ipv6Prefix) { + final String[] split = ipv6Prefix.getValue().split("/"); + final byte[] addressBytes; + try { + addressBytes = InetAddress.getByName(split[0]).getAddress(); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid IP6 address", e); + } + final byte[] mask = toByteMask(Short.valueOf(split[1])); + int pos = 0; + for (; pos < mask.length; ++pos) { + addressBytes[pos] &= mask[pos]; + } + // mask can be shorter that address, so we need to clear rest of the address: + for (; pos < addressBytes.length; ++pos) { + addressBytes[pos] = 0; + } + return addressBytes; + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/L2AclTranslator.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/L2AclTranslator.java new file mode 100644 index 000000000..7addf28da --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/L2AclTranslator.java @@ -0,0 +1,90 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; + +interface L2AclTranslator extends MacTranslator { + + default boolean destinationMacAddressMask(final MacAddress dstMask, final MacAddress dstAddress, + final ClassifyAddDelTable request) { + // destination-mac-address or destination-mac-address-mask is present => + // ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00 + if (dstMask != null) { + final List parts = COLON_SPLITTER.splitToList(dstMask.getValue()); + int i = 0; + for (String part : parts) { + request.mask[i++] = parseHexByte(part); + } + return false; + } else if (dstAddress != null) { + for (int i = 0; i < 6; ++i) { + request.mask[i] = (byte) 0xff; + } + return false; + } + return true; + } + + default boolean sourceMacAddressMask(final MacAddress srcMask, final MacAddress srcAddress, + final ClassifyAddDelTable request) { + // source-mac-address or source-mac-address-mask => + // 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00 + if (srcMask != null) { + final List parts = COLON_SPLITTER.splitToList(srcMask.getValue()); + int i = 6; + for (String part : parts) { + request.mask[i++] = parseHexByte(part); + } + return false; + } else if (srcAddress != null) { + for (int i = 6; i < 12; ++i) { + request.mask[i] = (byte) 0xff; + } + return false; + } + return true; + } + + default boolean destinationMacAddressMatch(final MacAddress dstAddress, final ClassifyAddDelSession request) { + if (dstAddress != null) { + final List parts = COLON_SPLITTER.splitToList(dstAddress.getValue()); + int i = 0; + for (String part : parts) { + request.match[i++] = parseHexByte(part); + } + return false; + } + return true; + } + + default boolean sourceMacAddressMatch(final MacAddress srcAddress, final ClassifyAddDelSession request) { + if (srcAddress != null) { + final List parts = COLON_SPLITTER.splitToList(srcAddress.getValue()); + int i = 6; + for (String part : parts) { + request.match[i++] = parseHexByte(part); + } + return false; + } + return true; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPair.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPair.java new file mode 100644 index 000000000..339102117 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPair.java @@ -0,0 +1,126 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; +import javax.annotation.Nullable; +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.SourcePortRange; + +/** + * Utility that produces cartesian product out of src and dst port ranges (used to translate ranges into + * list of classify sessions). + */ +final class PortPair { + private final Integer src; + private final Integer dst; + + PortPair(@Nullable final Integer src, @Nullable final Integer dst) { + this.src = src; + this.dst = dst; + } + + Integer getSrc() { + return src; + } + + Integer getDst() { + return dst; + } + + @Override + public String toString() { + return "(" + src + "," + dst + ")"; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final PortPair that = (PortPair) o; + if (!Objects.equals(src, that.src)) { + return false; + } + if (!Objects.equals(dst, that.dst)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return Objects.hash(src, dst); + } + + static List fromRange(final SourcePortRange srcRange, + final DestinationPortRange dstRange) { + final List result = new ArrayList<>(); + if (srcRange == null && dstRange == null) { + result.add(new PortPair(null, null)); + } else if (srcRange != null && dstRange == null) { + processSingleRange(result, srcRange.getLowerPort(), srcRange.getUpperPort(), PortPair::new); + } else if (srcRange == null && dstRange != null) { + processSingleRange(result, dstRange.getLowerPort(), dstRange.getUpperPort(), + (dst, src) -> new PortPair(src, dst)); + } else { + processDoubleRange(result, srcRange, dstRange); + } + return result; + } + + private static void processSingleRange(final List result, + final PortNumber lowerPort, + final PortNumber upperPort, + final BiFunction f) { + int low = lowerPort.getValue(); // mandatory + int hi = low; + if (upperPort != null) { + hi = upperPort.getValue(); + } + for (; low <= hi; ++low) { + result.add(f.apply(low, null)); + } + } + + private static void processDoubleRange(final List result, final SourcePortRange srcRange, + final DestinationPortRange dstRange) { + int srcL = srcRange.getLowerPort().getValue(); + int srcH = srcL; + if (srcRange.getUpperPort() != null) { + srcH = srcRange.getUpperPort().getValue(); + } + int dstL = dstRange.getLowerPort().getValue(); + int dstH = dstL; + if (dstRange.getUpperPort() != null) { + dstH = dstRange.getUpperPort().getValue(); + } + for (int i=srcL; i <= srcH; ++i) { + for (int j=dstL; j <= dstH; ++j) { + result.add(new PortPair(i, j)); + } + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriter.java new file mode 100644 index 000000000..c279722af --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriter.java @@ -0,0 +1,120 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AbstractIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.Matches; +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.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class EgressIetfAclWriter extends AbstractIetfAclWriter { + private final AclTableContextManager aclCtx; + + public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { + super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); + } + + @Override + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); + unassignClassifyTables(id, swIfIndex); + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); + } + + private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final int swIfIndex) + throws WriteFailedException { + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.swIfIndex = swIfIndex; + request.ip4TableIndex = NOT_DEFINED; + request.ip6TableIndex = NOT_DEFINED; + request.otherTableIndex = NOT_DEFINED; + request.isInput = 0; // egress + final CompletionStage cs = jvpp.classifySetInterfaceL2Tables(request); + getReplyForDelete(cs.toCompletableFuture(), id); + } + + @Override + public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); + checkArgument(InterfaceMode.L2.equals(mode), "Writing egress Acls is supported only in L2 mode"); + + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; // egress + request.swIfIndex = swIfIndex; + + // applied to packets according to their ether type + final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); + request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); + final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); + request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); + final List aces = getACEs(acls, writeContext, EgressIetfAclWriter::isNotIpRule); + request.otherTableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); + + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.otherTableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.classifySetInterfaceL2Tables(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } + } + + private static boolean isNotIpRule(final Ace ace) { + final Matches matches = ace.getMatches(); + checkArgument(matches != null, "Incomplete ACE: %s", ace); + return matches.getAceType() instanceof AceEth; + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizer.java new file mode 100644 index 000000000..1d457ac52 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizer.java @@ -0,0 +1,85 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.IetfAclWriter; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IetfAclCustomizer implements WriterCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); + private final IetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public IetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Adding egress ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + if (!InterfaceMode.L2.equals(accessLists.getMode())) { + LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); + return; + } + + aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizer.java new file mode 100644 index 000000000..9873a3143 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizer.java @@ -0,0 +1,105 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.IetfAclWriter; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); + private final IetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public SubInterfaceIetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + final Optional subInterfaceOptional = + writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); + checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); + final SubInterface subInterface = subInterfaceOptional.get(); + + if (!InterfaceMode.L2.equals(accessLists.getMode())) { + LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); + return; + } + + aclWriter + .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("Sub-interface ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("Sub-interface ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclCustomizer.java new file mode 100644 index 000000000..fb2c2180d --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclCustomizer.java @@ -0,0 +1,83 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +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.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs on given interface based on low lever classfier model. + */ +public class AclCustomizer extends FutureJVppCustomizer implements WriterCustomizer, AclWriter { + + private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public AclCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(vppApi); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(false, id, dataBefore, writeContext); + } + + private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + + LOG.debug("Setting ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); + + inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, ifIndex, classifyTableContext, + writeContext.getMappingContext()); + LOG.debug("Successfully set ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclWriter.java new file mode 100644 index 000000000..7a3e5c5a0 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/AclWriter.java @@ -0,0 +1,73 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.AclBaseAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +interface AclWriter extends ByteDataTranslator, JvppReplyConsumer { + + default void inputAclSetInterface(@Nonnull final FutureJVppCore futureJVppCore, final boolean isAdd, + @Nonnull final InstanceIdentifier id, @Nonnull final AclBaseAttributes acl, + @Nonnegative final int ifIndex, + @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = booleanToByte(isAdd); + request.swIfIndex = ifIndex; + request.l2TableIndex = ~0; // skip + request.ip4TableIndex = ~0; // skip + request.ip6TableIndex = ~0; // skip + + final L2Acl l2Acl = acl.getL2Acl(); + if (l2Acl != null) { + final String tableName = checkNotNull(l2Acl.getClassifyTable(), "L2 classify table is null"); + request.l2TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + final Ip4Acl ip4Acl = acl.getIp4Acl(); + if (ip4Acl != null) { + final String tableName = checkNotNull(ip4Acl.getClassifyTable(), "IPv4 classify table is null"); + request.ip4TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + final Ip6Acl ip6Acl = acl.getIp6Acl(); + if (ip6Acl != null) { + final String tableName = checkNotNull(ip6Acl.getClassifyTable(), "IPv6 classify table is null"); + request.ip6TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + + final CompletionStage inputAclSetInterfaceReplyCompletionStage = + futureJVppCore.inputAclSetInterface(request); + + getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizer.java new file mode 100644 index 000000000..842c1596f --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizer.java @@ -0,0 +1,89 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs for given interface (as defined in ietf-acl model). + * + * The customizer assumes it owns classify table management for interfaces where ietf-acl container is present. Using + * low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported and + * can result in unpredictable behaviour. + */ +public class IetfAclCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); + private final IngressIetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public IetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, + @Nonnull final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Adding ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IngressIetfAclWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IngressIetfAclWriter.java new file mode 100644 index 000000000..42b18aeb8 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IngressIetfAclWriter.java @@ -0,0 +1,118 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AbstractIetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class IngressIetfAclWriter extends AbstractIetfAclWriter { + private final AclTableContextManager aclCtx; + + public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { + super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); + } + + @Override + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); + unassignClassifyTables(id, entry); + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); + } + + private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, + @Nonnull final MappingEntry entry) + throws WriteFailedException { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 0; + request.swIfIndex = entry.getIndex(); + request.l2TableIndex = entry.getL2TableId(); + request.ip4TableIndex = entry.getIp4TableId(); + request.ip6TableIndex = entry.getIp6TableId(); + final CompletionStage inputAclSetInterfaceReplyCompletionStage = + jvpp.inputAclSetInterface(request); + getReplyForDelete(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + } + + @Override + public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); + + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 1; + request.swIfIndex = swIfIndex; + request.l2TableIndex = NOT_DEFINED; + request.ip4TableIndex = NOT_DEFINED; + request.ip6TableIndex = NOT_DEFINED; + + if (InterfaceMode.L2.equals(mode)) { + final List aces = getACEs(acls, writeContext, ace -> true); + request.l2TableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); + } else { + final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); + request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); + final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); + request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); + } + + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.l2TableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.inputAclSetInterface(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizer.java new file mode 100644 index 000000000..d864a9811 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizer.java @@ -0,0 +1,93 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +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.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs on given sub-interface. + */ +public class SubInterfaceAclCustomizer extends FutureJVppCustomizer + implements WriterCustomizer, AclWriter { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(vppApi); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(false, id, dataBefore, writeContext); + } + + private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + final String subInterfaceName = SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + + LOG.debug("Setting ACL(isAdd={}) on sub-interface={}(id={}): {}", + isAdd, subInterfaceName, subInterfaceIndex, acl); + inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, subInterfaceIndex, classifyTableContext, + writeContext.getMappingContext()); + LOG.debug("Successfully set ACL(isAdd={}) on sub-interface={}(id={}): {}", + isAdd, subInterfaceName, subInterfaceIndex, acl); + } +} diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizer.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizer.java new file mode 100644 index 000000000..6f161b858 --- /dev/null +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizer.java @@ -0,0 +1,108 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs for given sub-interface (as defined in ietf-acl model). + * + * The customizer assumes it owns classify table management for sub-interfaces where ietf-acl container is present. + * Using low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported + * and can result in unpredictable behaviour. + */ +public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); + private final IngressIetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public SubInterfaceIetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, + @Nonnull final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + final Optional subInterfaceOptional = + writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); + checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); + final SubInterface subInterface = subInterfaceOptional.get(); + + aclWriter + .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("Sub-interface ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("Sub-interface ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); + } +} diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModuleTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModuleTest.java new file mode 100644 index 000000000..3b51a6dca --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/VppClassifierModuleTest.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.vpp.classifier; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.empty; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.HashSet; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + +public class VppClassifierModuleTest { + + @Bind + @Mock + private FutureJVppCore futureJVppCore; + + @Named("interface-context") + @Bind + private NamingContext ifcContext; + + @Bind + @Mock + @Named("honeycomb-context") + private DataBroker contextBindingBrokerDependency; + + @Inject + private Set writerFactories = new HashSet<>(); + + @Before + public void setUp() { + initMocks(this); + ifcContext = new NamingContext("interface-", "interface-context"); + Guice.createInjector( + new VppClassifierModule(), + new VppClassifierAclModule(), + new InterfaceClassifierAclModule(), + new InterfaceClassifierIetfAclModule(), + new SubInterfaceClassifierAclModule(), + new SubInterfaceClassifierIetfAclModule(), + BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testWriterFactories() throws Exception { + assertThat(writerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of writers does exist, etc.) + final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(); + writerFactories.stream().forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + } + +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImplTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImplTest.java new file mode 100644 index 000000000..7b05ac208 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/context/VppClassifierContextManagerImplTest.java @@ -0,0 +1,163 @@ +/* + * 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.vpp.classifier.context; + +import static io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManagerImpl.VPP_CLASSIFIER_CONTEXT_IID; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import java.util.Arrays; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class VppClassifierContextManagerImplTest { + + private static final int TABLE_ID_0 = 0; + private static final String TABLE_NAME_0 = "table0"; + private static final KeyedInstanceIdentifier TABLE_IID_0 = + VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(TABLE_NAME_0)); + + private static final int TABLE_ID_1 = 1; + private static final String TABLE_NAME_1 = "table1"; + + private VppClassifierContextManagerImpl vppClassfierContext; + + @Mock + private MappingContext ctx; + + @Before + public void setUp() throws Exception { + initMocks(this); + vppClassfierContext = new VppClassifierContextManagerImpl("classify-table-"); + } + + @Test + public void testAddTable() throws Exception { + final String classfierNodeName = "node123"; + vppClassfierContext.addTable(TABLE_ID_0, TABLE_NAME_0, new VppNodeName(classfierNodeName), ctx); + verify(ctx).put(TABLE_IID_0, table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName)); + } + + @Test + public void testContainsTable() throws Exception { + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.absent()); + assertFalse(vppClassfierContext.containsTable(TABLE_NAME_0, ctx)); + } + + @Test + public void testGetTableIndex() throws Exception { + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0))); + assertEquals(TABLE_ID_0, vppClassfierContext.getTableIndex(TABLE_NAME_0, ctx)); + } + + @Test + public void testGetTableName() throws Exception { + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)) + .thenReturn(Optional.of(context(table(TABLE_ID_0, TABLE_NAME_0), table(TABLE_ID_1, TABLE_NAME_1)))); + assertEquals(TABLE_NAME_0, (vppClassfierContext.getTableName(TABLE_ID_0, ctx))); + } + + @Test + public void testGetTableBaseNode() throws Exception { + final String classfierNodeName = "node123"; + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName))); + vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx); + assertEquals(Optional.of(classfierNodeName), (vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx))); + } + + @Test + public void testRemoveTable() throws Exception { + vppClassfierContext.removeTable(TABLE_NAME_0, ctx); + verify(ctx).delete(TABLE_IID_0); + } + + @Test + public void testAddNodeName() throws Exception { + final String nodeName = "node123"; + final int nodeIndex = 1; + + vppClassfierContext.addNodeName(TABLE_NAME_0, nodeIndex, nodeName, ctx); + verify(ctx).put( + TABLE_IID_0.child(NodeContext.class, new NodeContextKey(nodeName)), + node(nodeName, nodeIndex) + ); + } + + @Test + public void testGetNonExistingNodeName() throws Exception { + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(table(TABLE_ID_1, TABLE_NAME_1)))); + assertFalse(vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx).isPresent()); + } + + @Test + public void testGetNodeNameMissingNodeCtx() throws Exception { + final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa"); + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); + assertEquals(Optional.absent(), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); + } + + @Test + public void testGetNodeName() throws Exception { + final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa", node("node123", 123)); + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); + assertEquals(Optional.of("node123"), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); + } + + private VppClassifierContext context(ClassifyTableContext... tables) { + VppClassifierContextBuilder context = new VppClassifierContextBuilder(); + context.setClassifyTableContext(Arrays.asList(tables)); + return context.build(); + } + + private static ClassifyTableContext table(final Integer id, final String name) { + return table(id, name, null); + } + + private static ClassifyTableContext table(final Integer id, final String name, final String classfierNodeName, + final NodeContext... nodeContexts) { + final ClassifyTableContextBuilder builder = + new ClassifyTableContextBuilder().setIndex(id).setName(name).setClassifierNodeName(classfierNodeName); + + if (nodeContexts.length > 0) { + builder.setNodeContext(Arrays.asList(nodeContexts)); + } + + return builder.build(); + } + + private NodeContext node(final String nodeName, final int nodeIndex) { + return new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build(); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReaderTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReaderTest.java new file mode 100644 index 000000000..c2ea534e9 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifySessionReaderTest.java @@ -0,0 +1,117 @@ +/* + * 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.vpp.classifier.read; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifySessionReaderTest extends + ListReaderCustomizerTest { + + private static final String MATCH_1 = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + private static final String MATCH_2 = "00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00"; + + private static final int TABLE_INDEX = 1; + private static final String TABLE_NAME = "table1"; + + @Mock + private VppClassifierContextManager classifierContext; + + public ClassifySessionReaderTest() { + super(ClassifySession.class, ClassifyTableBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new ClassifySessionReader(api, classifierContext); + } + + private static InstanceIdentifier getClassifySessionId(final String tableName, + final String match) { + return InstanceIdentifier.create(VppClassifierState.class) + .child(ClassifyTable.class, new ClassifyTableKey(tableName)) + .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); + } + + @Test + public void testReadWithCache() throws ReadFailedException { + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); + final ClassifySessionBuilder builder = mock(ClassifySessionBuilder.class); + final ModificationCache cache = new ModificationCache(); + final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); + final ClassifySessionDetails details = new ClassifySessionDetails(); + details.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + dump.classifySessionDetails = Collections.singletonList(details); + cache.put(ClassifySessionReader.CACHE_KEY + id.firstKeyOf(ClassifyTable.class), dump); + when(ctx.getModificationCache()).thenReturn(cache); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); + final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); + final ClassifySessionDetails details1 = new ClassifySessionDetails(); + details1.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + final ClassifySessionDetails details2 = new ClassifySessionDetails(); + details2.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x07, 0x00, 0x00, 0x00, 0x00}; + dump.classifySessionDetails = Arrays.asList(details1, details2); + doReturn(future(dump)).when(api).classifySessionDump(ArgumentMatchers.any(ClassifySessionDump.class)); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + + final List allIds = getCustomizer().getAllIds(id, ctx); + assertEquals(2, allIds.size()); + assertEquals(MATCH_1, allIds.get(0).getMatch().getValue()); + assertEquals(MATCH_2, allIds.get(1).getMatch().getValue()); + } + +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReaderTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReaderTest.java new file mode 100644 index 000000000..75b6dd783 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/ClassifyTableReaderTest.java @@ -0,0 +1,126 @@ +/* + * 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.vpp.classifier.read; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; +import java.util.List; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifyTableReaderTest extends + ListReaderCustomizerTest { + + private static final int TABLE_INDEX_1 = 1; + private static final String TABLE_NAME_1 = "table1"; + private static final int TABLE_INDEX_2 = 2; + private static final String TABLE_NAME_2 = "table2"; + + @Mock + private VppClassifierContextManager classifierContext; + + public ClassifyTableReaderTest() { + super(ClassifyTable.class, VppClassifierStateBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new ClassifyTableReader(api, classifierContext); + } + + private static InstanceIdentifier getClassifyTableId(final String name) { + return InstanceIdentifier.create(VppClassifierState.class) + .child(ClassifyTable.class, new ClassifyTableKey(name)); + } + + private static ClassifyTableInfoReply generateClassifyTableInfoReply() { + final ClassifyTableInfoReply reply = new ClassifyTableInfoReply(); + reply.tableId = TABLE_INDEX_1; + reply.nbuckets = 2; + reply.skipNVectors = 0; + reply.matchNVectors = 1; + reply.nextTableIndex = ~0; + reply.missNextIndex = ~0; + reply.mask = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return reply; + } + + private void verifyClasifyTableRead(final ClassifyTableBuilder builder) { + verify(builder).setName(TABLE_NAME_1); + verify(builder).setNbuckets(2L); + verify(builder, times(0)).setNextTable(ArgumentMatchers.anyString()); + verify(builder).setMissNext(new VppNode(PacketHandlingAction.Permit)); + verify(builder).setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); + verify(builder).setActiveSessions(0L); + } + + @Test + public void testRead() throws ReadFailedException { + doReturn(future(generateClassifyTableInfoReply())).when(api).classifyTableInfo(ArgumentMatchers.any(ClassifyTableInfo.class)); + + when(classifierContext.containsTable(TABLE_NAME_1, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME_1, mappingContext)).thenReturn(TABLE_INDEX_1); + when(classifierContext.getTableBaseNode(TABLE_NAME_1, mappingContext)).thenReturn(Optional.absent()); + + final ClassifyTableBuilder builder = mock(ClassifyTableBuilder.class); + getCustomizer().readCurrentAttributes(getClassifyTableId(TABLE_NAME_1), builder, ctx); + + verifyClasifyTableRead(builder); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final ClassifyTableIdsReply reply = new ClassifyTableIdsReply(); + reply.ids = new int[] {1, 2}; + doReturn(future(reply)).when(api).classifyTableIds(ArgumentMatchers.any(ClassifyTableIds.class)); + + when(classifierContext.getTableName(TABLE_INDEX_1, mappingContext)).thenReturn(TABLE_NAME_1); + when(classifierContext.getTableName(TABLE_INDEX_2, mappingContext)).thenReturn(TABLE_NAME_2); + + final List allIds = getCustomizer().getAllIds(getClassifyTableId(TABLE_NAME_1), ctx); + + assertEquals(reply.ids.length, allIds.size()); + assertEquals(TABLE_NAME_1, allIds.get(0).getName()); + assertEquals(TABLE_NAME_2, allIds.get(1).getName()); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizerTest.java new file mode 100644 index 000000000..6ce12c871 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/AclCustomizerTest.java @@ -0,0 +1,99 @@ +/* + * 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.vpp.classifier.read.acl; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclCustomizerTest extends ReaderCustomizerTest { + + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceAclStateAugmentation.class).child(Acl.class).child(Ingress.class); + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private NamingContext interfaceContext; + + @Mock + private VppClassifierContextManager classifyTableContext; + + public AclCustomizerTest() { + super(Ingress.class, AclBuilder.class); + } + + @Override + public void setUp() { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new AclCustomizer(api, interfaceContext, classifyTableContext); + } + + @Test + public void testRead() throws ReadFailedException { + final IngressBuilder builder = mock(IngressBuilder.class); + + final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); + reply.l2TableId = TABLE_INDEX; + reply.ip4TableId = ~0; + reply.ip6TableId = ~0; + when(api.classifyTableByInterface(any())).thenReturn(future(reply)); + + when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); + + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + verify(builder).setL2Acl(new L2AclBuilder().setClassifyTable(TABLE_NAME).build()); + verify(builder).setIp4Acl(null); + verify(builder).setIp6Acl(null); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizerTest.java new file mode 100644 index 000000000..0481a83db --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/read/acl/SubInterfaceAclCustomizerTest.java @@ -0,0 +1,111 @@ +/* + * 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.vpp.classifier.read.acl; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclCustomizerTest extends ReaderCustomizerTest { + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUB_IF_NAME = "local0.1"; + private static final long SUB_IF_ID = 1; + private static final int SUB_IF_INDEX = 11; + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) + .augmentation(VppSubinterfaceAclStateAugmentation.class) + .child(Acl.class).child(Ingress.class); + + private NamingContext interfaceContext; + + @Mock + private VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizerTest() { + super(Ingress.class, AclBuilder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new SubInterfaceAclCustomizer(api, interfaceContext, classifyTableContext); + } + + @Test + public void testRead() throws ReadFailedException { + final IngressBuilder builder = mock(IngressBuilder.class); + + final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); + reply.swIfIndex = SUB_IF_INDEX; + reply.l2TableId = ~0; + reply.ip4TableId = TABLE_INDEX; + reply.ip6TableId = TABLE_INDEX; + when(api.classifyTableByInterface(any())).thenReturn(future(reply)); + + when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); + + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + verify(builder).setL2Acl(null); + verify(builder).setIp4Acl(new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build()); + verify(builder).setIp6Acl(new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build()); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java new file mode 100644 index 000000000..49e172fac --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java @@ -0,0 +1,178 @@ +/* + * 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.vpp.classifier.write; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifySessionWriterTest extends WriterCustomizerTest { + + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + private static final int SESSION_INDEX = 456; + @Mock + private VppClassifierContextManager classfierContext; + private ClassifySessionWriter customizer; + + private static ClassifySession generateClassifySession(final long opaqueIndex, final String match) { + final ClassifySessionBuilder builder = new ClassifySessionBuilder(); + builder.setOpaqueIndex(new OpaqueIndex(opaqueIndex)); + builder.setHitNext(new VppNode(PacketHandlingAction.Deny)); + builder.setAdvance(123); + builder.setMatch(new HexString(match)); + return builder.build(); + } + + private static InstanceIdentifier getClassifySessionId(final String tableName, + final String match) { + return InstanceIdentifier.create(VppClassifier.class) + .child(ClassifyTable.class, new ClassifyTableKey(tableName)) + .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); + } + + private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, + final int sessionIndex) { + final ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = isAdd; + request.tableIndex = tableIndex; + request.opaqueIndex = sessionIndex; + request.hitNextIndex = 0; + request.advance = 123; + request.match = + new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return request; + } + + @Override + public void setUpTest() throws Exception { + customizer = new ClassifySessionWriter(api, classfierContext); + + when(classfierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classfierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + + final ClassifyTable table = mock(ClassifyTable.class); + when(table.getClassifierNode()).thenReturn(new VppNodeName("ip4-classifier")); + when(writeContext.readAfter(ArgumentMatchers.any())).thenReturn(Optional.of(table)); + when(writeContext.readBefore(ArgumentMatchers.any())).thenReturn(Optional.of(table)); + } + + private void whenClassifyAddDelSessionThenSuccess() { + doReturn(future(new ClassifyAddDelSessionReply())).when(api) + .classifyAddDelSession(ArgumentMatchers.any(ClassifyAddDelSession.class)); + } + + private void whenClassifyAddDelSessionThenFailure() { + doReturn(failedFuture()).when(api).classifyAddDelSession(ArgumentMatchers.any(ClassifyAddDelSession.class)); + } + + @Test + public void testCreate() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenSuccess(); + + customizer.writeCurrentAttributes(id, classifySession, writeContext); + + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); + } + + @Test + public void testCreateFailed() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenFailure(); + + try { + customizer.writeCurrentAttributes(id, classifySession, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + customizer.updateCurrentAttributes(null, null, null, writeContext); + } + + @Test + public void testDelete() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenSuccess(); + + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriterTest.java new file mode 100644 index 000000000..2a8b3db66 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifyTableWriterTest.java @@ -0,0 +1,182 @@ +/* + * 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.vpp.classifier.write; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifyTableWriterTest extends WriterCustomizerTest { + + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + + @Mock + private VppClassifierContextManager classifierContext; + + private ClassifyTableWriter customizer; + + private static ClassifyTable generateClassifyTable(final String name) { + final ClassifyTableBuilder builder = new ClassifyTableBuilder(); + builder.setName(name); + builder.setClassifierNode(new VppNodeName("ip4-classifier")); + builder.setKey(new ClassifyTableKey(name)); + builder.setSkipNVectors(0L); + builder.setNbuckets(2L); + builder.setMemorySize(2L << 20); + builder.setMissNext(new VppNode(PacketHandlingAction.Permit)); + builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); + return builder.build(); + } + + private static InstanceIdentifier getClassifyTableId(final String name) { + return InstanceIdentifier.create(VppClassifier.class) + .child(ClassifyTable.class, new ClassifyTableKey(name)); + } + + private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd) { + return generateClassifyAddDelTable(isAdd, -1); + } + + private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = isAdd; + request.tableIndex = tableIndex; + request.nbuckets = 2; + request.memorySize = 2 << 20; + request.skipNVectors = 0; + request.matchNVectors = 1; + request.nextTableIndex = ~0; + request.missNextIndex = ~0; + request.mask = + new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return request; + } + + @Override + public void setUpTest() throws Exception { + customizer = new ClassifyTableWriter(api, classifierContext); + } + + private void whenClassifyAddDelTableThenSuccess() { + final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply(); + reply.newTableIndex = TABLE_INDEX; + doReturn(future(reply)).when(api).classifyAddDelTable(ArgumentMatchers.any(ClassifyAddDelTable.class)); + } + + private void whenClassifyAddDelTableThenFailure() { + doReturn(failedFuture()).when(api).classifyAddDelTable(ArgumentMatchers.any(ClassifyAddDelTable.class)); + } + + @Test + public void testCreate() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + whenClassifyAddDelTableThenSuccess(); + + customizer.writeCurrentAttributes(id, classifyTable, writeContext); + + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); + verify(classifierContext) + .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); + } + + @Test + public void testCreateFailed() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + whenClassifyAddDelTableThenFailure(); + + try { + customizer.writeCurrentAttributes(id, classifyTable, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); + verify(classifierContext, times(0)) + .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testDelete() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + whenClassifyAddDelTableThenSuccess(); + + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + whenClassifyAddDelTableThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclCustomizerTest.java new file mode 100644 index 000000000..55d5587c9 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclCustomizerTest.java @@ -0,0 +1,153 @@ +/* + * 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.vpp.classifier.write.acl; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.hc2vpp.vpp.classifier.write.acl.ingress.AclCustomizer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.L2AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final int ACL_TABLE_INDEX = 0; + private static final String ACL_TABLE_NAME = "table0"; + @Mock + private VppClassifierContextManager classifyTableContext; + private AclCustomizer customizer; + + private static InputAclSetInterface generateInputAclSetInterface(final byte isAdd, final int ifIndex, + final int l2TableIndex) { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = isAdd; + request.l2TableIndex = l2TableIndex; + request.ip4TableIndex = ~0; + request.ip6TableIndex = ~0; + request.swIfIndex = ifIndex; + return request; + } + + @Override + public void setUpTest() { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + customizer = new AclCustomizer(api, new NamingContext("generatedInterfaceName", IFC_TEST_INSTANCE), + classifyTableContext); + } + + private InstanceIdentifier getAclId(final String name) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( + VppInterfaceAclAugmentation.class).child(Acl.class).child(Ingress.class); + } + + private Ingress generateAcl(final String tableName) { + final IngressBuilder builder = new IngressBuilder(); + final L2Acl l2Acl = new L2AclBuilder().setClassifyTable(tableName).build(); + builder.setL2Acl(l2Acl); + return builder.build(); + } + + private void whenInputAclSetInterfaceThenSuccess() { + doReturn(future(new InputAclSetInterfaceReply())).when(api) + .inputAclSetInterface(any(InputAclSetInterface.class)); + } + + private void whenInputAclSetInterfaceThenFailure() { + doReturn(failedFuture()).when(api).inputAclSetInterface(any(InputAclSetInterface.class)); + } + + @Test + public void testCreate() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenSuccess(); + + customizer.writeCurrentAttributes(id, acl, writeContext); + + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); + } + + @Test + public void testCreateFailed() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenFailure(); + + try { + customizer.writeCurrentAttributes(id, acl, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testDelete() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenSuccess(); + + customizer.deleteCurrentAttributes(id, acl, writeContext); + + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, acl, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclWriterTest.java new file mode 100644 index 000000000..fbd7b5342 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/AclWriterTest.java @@ -0,0 +1,103 @@ +/* + * 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.vpp.classifier.write.acl; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +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.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclWriterTest extends WriterCustomizerTest { + + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(ACL_NAME, ACL_TYPE)); + + @Mock + private Acl acl; + private IetfAclWriter customizer; + + @Override + public void setUpTest() { + customizer = new IetfAclWriter(); + when(acl.getAclName()).thenReturn(ACL_NAME); + doReturn(ACL_TYPE).when(acl).getAclType(); + } + + private void defineInterfacesContext(final List interfaces) { + when(writeContext.readAfter(InstanceIdentifier.create(Interfaces.class))).thenReturn(Optional.of( + new InterfacesBuilder().setInterface(interfaces).build() + )); + } + + @Test + public void testWrite() throws Exception { + customizer.writeCurrentAttributes(IID, acl, writeContext); + } + + @Test + public void testUpdate() throws WriteFailedException { + defineInterfacesContext(Collections.emptyList()); + customizer.updateCurrentAttributes(IID, acl, acl, writeContext); + } + + @Test + public void testDelete() throws WriteFailedException { + defineInterfacesContext(Collections.emptyList()); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + } + + @Test(expected = WriteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + final Interface iface = new InterfaceBuilder().addAugmentation(VppInterfaceAclAugmentation.class, + new VppInterfaceAclAugmentationBuilder().setIetfAcl( + new IetfAclBuilder().setIngress( + new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder().setName(ACL_NAME).setType(ACL_TYPE).build()) + ).build() + ).build() + ).build() + ).build() + ).build(); + defineInterfacesContext(Collections.singletonList(iface)); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriterTest.java new file mode 100644 index 000000000..a9b47e060 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceEthWriterTest.java @@ -0,0 +1,94 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +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.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.matches.ace.type.AceEth; +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.ace.type.AceEthBuilder; +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.classifier.acl.rev161214.InterfaceMode; + +public class AceEthWriterTest { + + private AceEthWriter writer; + private PacketHandling action; + private AceEth aceEth; + + @Before + public void setUp() { + initMocks(this); + writer = new AceEthWriter(); + action = new DenyBuilder().setDeny(true).build(); + aceEth = new AceEthBuilder() + .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) + .setDestinationMacAddressMask(new MacAddress("ff:ff:ff:ff:ff:ff")) + .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) + .setSourceMacAddressMask(new MacAddress("ff:ff:ff:00:00:00")) + .build(); + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceEth, InterfaceMode.L2, nextTableIndex, 0); + + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(AceEthWriter.MATCH_N_VECTORS, request.matchNVectors); + assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // destination MAC: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + // source MAC: + (byte) 0xff, (byte) 0xff, (byte) 0xff, 0, 0, 0, + 0, 0, 0, 0 + }; + assertArrayEquals(expectedMask, request.mask); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceEth, InterfaceMode.L2, tableIndex, 0).get(0); + + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // destination MAC: + (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, + // source MAC: + (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, + 0, 0, 0, 0 + }; + assertArrayEquals(expectedMatch, request.match); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4WriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4WriterTest.java new file mode 100644 index 000000000..5064bb1f7 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp4WriterTest.java @@ -0,0 +1,189 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTranslator.VLAN_TAG_LEN; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +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.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.matches.ace.type.AceIp; +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.ace.type.AceIpBuilder; +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.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +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.PortNumber; +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.SourcePortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; + +public class AceIp4WriterTest { + + private AceIp4Writer writer; + private PacketHandling action; + private AceIp aceIp; + + @Before + public void setUp() throws Exception { + initMocks(this); + writer = new AceIp4Writer(); + action = new DenyBuilder().setDeny(true).build(); + aceIp = new AceIpBuilder() + .setProtocol((short) 132) + .setDscp(new Dscp((short) 11)) + .setAceIpVersion(new AceIpv4Builder() + .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")) + .setDestinationIpv4Network(new Ipv4Prefix("1.2.4.5/24")) + .build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build(); + } + + private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(AceIp4Writer.MATCH_N_VECTORS, request.matchNVectors); + assertEquals(AceIp4Writer.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp: + (byte) 0x00, (byte) 0xfc, + // protocol: + 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, 0, 0, + // source address: + -1, -1, -1, -1, + // destination address: + -1, -1, -1, 0, + // source and destination port: + -1, -1, -1, -1, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMask[12] = (byte) 0xff; + expectedMask[13] = (byte) 0xff; + } + AceIpWriterTestUtils + .assertArrayEqualsWithOffset(expectedMask, expectedMask.length, request.mask, vlanTags * VLAN_TAG_LEN); + + } + + private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp: + 0, (byte) 0x2c, + // protocol (132): + 0, 0, 0, 0, 0, 0, 0, (byte) 132, 0, 0, + // source address: + 1, 2, 3, 4, + // destination address: + 1, 2, 4, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMatch[12] = (byte) 0x08; + expectedMatch[13] = (byte) 0x00; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, expectedMatch.length, request.match, vlanTags * VLAN_TAG_LEN); + + } + + @Test + public void testCreateTable() throws Exception { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, false); + } + + @Test + public void testCreateTableForL2Interface() throws Exception { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, true); + } + + @Test + public void testCreateTable1VlanTag() throws Exception { + final int nextTableIndex = 42; + final int vlanTags = 1; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateTable2VlanTags() throws Exception { + final int nextTableIndex = 42; + final int vlanTags = 2; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession() throws Exception { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, false); + } + + @Test + public void testCreateClassifySessionForL2Interface() throws Exception { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, true); + } + + @Test + public void testCreateClassifySession1VlanTag() throws Exception { + final int tableIndex = 123; + final int vlanTags = 1; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession2VlanTags() throws Exception { + final int tableIndex = 123; + final int vlanTags = 2; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + + verifySessionRequest(request, tableIndex, vlanTags, false); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6WriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6WriterTest.java new file mode 100644 index 000000000..4fee862a7 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIp6WriterTest.java @@ -0,0 +1,200 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +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.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.matches.ace.type.AceIp; +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.ace.type.AceIpBuilder; +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.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +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.DestinationPortRangeBuilder; +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.classifier.acl.rev161214.InterfaceMode; + +public class AceIp6WriterTest { + + private AceIp6Writer writer; + private PacketHandling action; + private AceIp aceIp; + + @Before + public void setUp() { + initMocks(this); + writer = new AceIp6Writer(); + action = new DenyBuilder().setDeny(true).build(); + aceIp = new AceIpBuilder() + .setProtocol((short) 132) + .setDscp(new Dscp((short) 11)) + .setAceIpVersion(new AceIpv6Builder() + .setFlowLabel(new Ipv6FlowLabel(123L)) + .setSourceIpv6Network(new Ipv6Prefix("2001:db8:85a3:8d3:1319:8a2e:370:7348/128")) + .setDestinationIpv6Network(new Ipv6Prefix("fe80:1234:5678:abcd:ef01::/64")) + .build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build(); + } + + + private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(vlanTags == 2 ? 5 : 4, request.matchNVectors); + assertEquals(AceIp6Writer.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp, flow: + (byte) 0x0f, (byte) 0xcf, (byte) 0xff, (byte) 0xff, + // protocol: + 0, 0, (byte) 0xff, 0, + // source address: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + // destination address: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + 0, 0, 0, 0, 0, 0, 0, 0, + // source and destination port: + -1, -1, -1, -1, + // padding to multiple of 16B: + 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMask[12] = (byte) 0xff; + expectedMask[13] = (byte) 0xff; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMask, vlanTags == 2 ? 80 : 64, request.mask, vlanTags * AclTranslator.VLAN_TAG_LEN); + } + + private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp(11), flow(123): + (byte) 0x02, (byte) 0xc0, (byte) 0x00, (byte) 0x7b, + // protocol (132): + 0, 0, (byte) 132, 0, + // source address: + (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, (byte) 0x08, (byte) 0xd3, + (byte) 0x13, (byte) 0x19, (byte) 0x8a, (byte) 0x2e, (byte) 0x03, (byte) 0x70, (byte) 0x73, (byte) 0x48, + // destination address: + (byte) 0xfe, (byte) 0x80, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0xab, (byte) 0xcd, + 0, 0, 0, 0, 0, 0, 0, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding to multiple of 16B: + 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMatch[12] = (byte) 0x86; + expectedMatch[13] = (byte) 0xdd; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, vlanTags == 2 ? 80 : 64, request.match, vlanTags * AclTranslator.VLAN_TAG_LEN); + + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, false); + } + + @Test + public void testCreateTableForL2Interface() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, true); + } + + @Test + public void testCreateTable1VlanTag() { + final int nextTableIndex = 42; + final int vlanTags = 1; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateTable2VlanTags() { + final int nextTableIndex = 42; + final int vlanTags = 2; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, false); + } + + @Test + public void testCreateClassifySessionForL2Interface() { + final int tableIndex = 123; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, true); + } + + @Test + public void testCreateClassifySession1VlanTag() { + final int tableIndex = 123; + final int vlanTags = 1; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession2VlanTags() { + final int tableIndex = 123; + final int vlanTags = 2; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriterTest.java new file mode 100644 index 000000000..56cad9140 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpAndEthWriterTest.java @@ -0,0 +1,124 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +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.DenyBuilder; +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.PortNumber; +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.SourcePortRangeBuilder; +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.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEthBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpAndEthNodesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.and.eth.nodes.ace.ip.version.AceIpv4Builder; + +public class AceIpAndEthWriterTest { + + private AceIpAndEthWriter writer; + private PacketHandling action; + private AceIpAndEth ace; + + @Before + public void setUp() { + initMocks(this); + writer = new AceIpAndEthWriter(); + action = new DenyBuilder().setDeny(true).build(); + ace = new AceIpAndEthBuilder().setAceIpAndEthNodes(new AceIpAndEthNodesBuilder() + .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) + .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) + .setAceIpVersion(new AceIpv4Builder() + .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")).build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build()).build(); + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(ace, InterfaceMode.L2, nextTableIndex, 0); + + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(3, request.matchNVectors); + assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // destination MAC: + -1, -1, -1, -1, -1, -1, + // source MAC: + -1, -1, -1, -1, -1, -1, + // ether type: + -1, -1, + // IP header + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // source address: + -1, -1, -1, -1, + // destination address: + 0, 0, 0, 0, + // source and destination port: + -1, -1, -1, -1, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assertArrayEquals(expectedMask, request.mask); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, ace, InterfaceMode.L2, tableIndex, 0).get(0); + + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // destination MAC: + (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, + // source MAC: + (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, + // ether type (IP4): + 0x08, 0, + // IP header + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // source address: + 1, 2, 3, 4, + // destination address: + 0, 0, 0, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assertArrayEquals(expectedMatch, request.match); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpWriterTestUtils.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpWriterTestUtils.java new file mode 100644 index 000000000..257840169 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AceIpWriterTestUtils.java @@ -0,0 +1,34 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.junit.Assert.assertArrayEquals; + +final class AceIpWriterTestUtils { + + private AceIpWriterTestUtils() { + throw new UnsupportedOperationException("This utility class cannot be instantiated"); + } + + protected static void assertArrayEqualsWithOffset(final byte[] baseExpected, final int expectedLength, final byte[] actual, + final int offset) { + byte[] expected = new byte[expectedLength]; + System.arraycopy(baseExpected, 0, expected, offset, Math.min(baseExpected.length, expectedLength-offset)); + + assertArrayEquals(expected, actual); + } +} diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImplTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImplTest.java new file mode 100644 index 000000000..f2b73b44b --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/AclTableContextManagerImplTest.java @@ -0,0 +1,62 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.honeycomb.translate.MappingContext; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; + +public class AclTableContextManagerImplTest { + + private AclTableContextManagerImpl ctx; + @Mock + private MappingContext mappingContext; + private static final int INDEX = 42; + + @Before + public void setUp() throws Exception { + initMocks(this); + ctx = new AclTableContextManagerImpl(MappingTable.Direction.Ingress); + } + + @Test + public void testAddEntry() throws Exception { + final MappingEntry entry = + new MappingEntryBuilder().setL2TableId(1).setIp4TableId(2).setIp6TableId(3).setIndex(INDEX).build(); + ctx.addEntry(entry, mappingContext); + verify(mappingContext).put(ctx.getId(INDEX), entry); + } + + @Test + public void testRemoveEntry() throws Exception { + ctx.removeEntry(INDEX, mappingContext); + verify(mappingContext).delete(ctx.getId(INDEX)); + } + + @Test + public void testReadEntry() throws Exception { + ctx.getEntry(INDEX, mappingContext); + verify(mappingContext).read(ctx.getId(INDEX)); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPairTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPairTest.java new file mode 100644 index 000000000..9126d8c01 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/common/PortPairTest.java @@ -0,0 +1,114 @@ +/* + * 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.vpp.classifier.write.acl.common; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; + +import java.util.List; +import org.junit.Test; +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; + +public class PortPairTest { + + @Test + public void testSingleSrc() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final List portPairs = PortPair.fromRange(src, null); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(123, null))); + } + + @Test + public void testSrcRange() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(123)) + .setUpperPort(new PortNumber(125)).build(); + final List portPairs = PortPair.fromRange(src, null); + assertThat(portPairs, hasSize(3)); + assertThat(portPairs, contains(new PortPair(123, null), new PortPair(124, null), new PortPair(125, null))); + } + + @Test + public void testSrcRangeWithDst() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(123)) + .setUpperPort(new PortNumber(125)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(111)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(3)); + assertThat(portPairs, contains(new PortPair(123, 111), new PortPair(124, 111), new PortPair(125, 111))); + } + + @Test + public void testSingleDst() { + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final List portPairs = PortPair.fromRange(null, dst); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(null, 123))); + } + + @Test + public void testDstRange() { + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(10)) + .setUpperPort(new PortNumber(11)).build(); + final List portPairs = PortPair.fromRange(null, dst); + assertThat(portPairs, hasSize(2)); + assertThat(portPairs, contains(new PortPair(null, 10), new PortPair(null, 11))); + } + + @Test + public void testDstRangeWithSrc() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(111)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(10)) + .setUpperPort(new PortNumber(11)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(2)); + assertThat(portPairs, contains(new PortPair(111, 10), new PortPair(111, 11))); + } + + @Test + public void testSinglePair() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(321)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(123, 321))); + } + + @Test + public void testCartesianProduct() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(1)) + .setUpperPort(new PortNumber(2)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(1)) + .setUpperPort(new PortNumber(3)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(6)); + assertThat(portPairs, + contains(new PortPair(1, 1), new PortPair(1, 2), new PortPair(1, 3), new PortPair(2, 1), new PortPair(2, 2), + new PortPair(2, 3))); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriterTest.java new file mode 100644 index 000000000..911350562 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/EgressIetfAclWriterTest.java @@ -0,0 +1,152 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManager; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +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.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.MatchesBuilder; +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.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +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.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.EgressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EgressIetfAclWriterTest extends WriterCustomizerTest { + + private static final int IF_INDEX = 1; + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + private EgressIetfAclWriter writer; + @Mock + private AclTableContextManager aclCtx; + @Mock + private InstanceIdentifier id; + + private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { + final ClassifyAddDelTable reply = new ClassifyAddDelTable(); + reply.tableIndex = tableIndex; + reply.delChain = 1; + return reply; + } + + @Override + protected void setUpTest() throws Exception { + writer = new EgressIetfAclWriter(api, aclCtx); + } + + private ClassifySetInterfaceL2Tables classifySetInterfaceL2TablesRequest() { + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + request.otherTableIndex = -1; + request.swIfIndex = IF_INDEX; + return request; + } + + @Test + public void testDeleteAcl() throws Exception { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); + when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(IF_INDEX) + .setL2TableId(1) + .setIp4TableId(2) + .setIp6TableId(3) + .build())); + + writer.deleteAcl(id, IF_INDEX, mappingContext); + + verify(api).classifySetInterfaceL2Tables(classifySetInterfaceL2TablesRequest()); + verify(api).classifyAddDelTable(classifyAddDelTable(1)); + verify(api).classifyAddDelTable(classifyAddDelTable(2)); + verify(api).classifyAddDelTable(classifyAddDelTable(3)); + verify(aclCtx).removeEntry(IF_INDEX, mappingContext); + } + + @Test + public void testWrite() throws Exception { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); + when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); + + final Egress + acl = new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(InterfaceMode.L2).build() + ).build(); + + final AccessLists accessLists = acl.getAccessLists(); + + when(writeContext.readAfter(any())).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Collections.singletonList(new AceBuilder() + .setMatches(new MatchesBuilder().setAceType( + new AceIpBuilder() + .setAceIpVersion(new AceIpv4Builder().build()) + .setProtocol((short) 1) + .build() + ).build()) + .setActions(new ActionsBuilder().setPacketHandling(new PermitBuilder().build()).build()) + .build())).build() + ).build() + + )); + + writer.write(id, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, mappingContext); + + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; + request.swIfIndex = IF_INDEX; + request.otherTableIndex = -1; + request.ip4TableIndex = 0; + request.ip6TableIndex = -1; + verify(api).classifySetInterfaceL2Tables(request); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizerTest.java new file mode 100644 index 000000000..96e638548 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/IetfAclCustomizerTest.java @@ -0,0 +1,114 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.IetfAclWriter; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.MixedAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.EgressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IetfAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + VppInterfaceAclAugmentation.class).child(IetfAcl.class).child(Egress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = MixedAcl.class; + + @Mock + private IetfAclWriter aclWriter; + private IetfAclCustomizer customizer; + + private static Egress acl(final InterfaceMode mode) { + return new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(mode) + .build() + ).build(); + } + + @Override + protected void setUpTest() { + customizer = new IetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + } + + private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { + verify(aclWriter) + .write(IID, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, mappingContext); + } + + private void verifyDelete() throws WriteFailedException { + verify(aclWriter).deleteAcl(IID, IF_INDEX, mappingContext); + } + + @Test + public void testWriteL3() throws Exception { + customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); + verifyZeroInteractions(aclWriter); + } + + @Test + public void testWriteL2() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.writeCurrentAttributes(IID, acl, writeContext); + verifyWrite(acl.getAccessLists()); + } + + @Test + public void testUpdate() throws Exception { + final Egress aclBefore = acl(InterfaceMode.L3); + final Egress aclAfter = acl(InterfaceMode.L2); + customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); + verifyDelete(); + verifyWrite(aclAfter.getAccessLists()); + } + + @Test + public void testDelete() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + verifyDelete(); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizerTest.java new file mode 100644 index 000000000..2370c25b6 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/egress/SubInterfaceIetfAclCustomizerTest.java @@ -0,0 +1,133 @@ +/* + * 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.vpp.classifier.write.acl.egress; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.IetfAclWriter; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.MixedAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.EgressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.0"; + private static final int SUBIF_INDEX = 11; + private static final long SUBIF_ID = 0; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)) + .augmentation(VppSubinterfaceAclAugmentation.class) + .child(IetfAcl.class).child(Egress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = MixedAcl.class; + + @Mock + private IetfAclWriter aclWriter; + private SubInterfaceIetfAclCustomizer customizer; + + private static Egress acl(final InterfaceMode mode) { + return new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(mode) + .build() + ).build(); + } + + @Override + protected void setUpTest() { + customizer = new SubInterfaceIetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + + + when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( + new SubInterfaceBuilder().build() + )); + } + + private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { + verify(aclWriter) + .write(IID, SUBIF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, 0, mappingContext); + } + + private void verifyDelete() throws WriteFailedException { + verify(aclWriter).deleteAcl(IID, SUBIF_INDEX, mappingContext); + } + + @Test + public void testWriteL3() throws Exception { + customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); + verifyZeroInteractions(aclWriter); + } + + @Test + public void testWriteL2() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.writeCurrentAttributes(IID, acl, writeContext); + verifyWrite(acl.getAccessLists()); + } + + @Test + public void testUpdate() throws Exception { + final Egress aclBefore = acl(InterfaceMode.L3); + final Egress aclAfter = acl(InterfaceMode.L2); + customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); + verifyDelete(); + verifyWrite(aclAfter.getAccessLists()); + } + + @Test + public void testDelete() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + verifyDelete(); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizerTest.java new file mode 100644 index 000000000..58f7ea1a2 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/IetfAclCustomizerTest.java @@ -0,0 +1,205 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +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.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.MatchesBuilder; +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.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +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.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp._interface.acl.rev161214.VppInterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IetfAclCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + VppInterfaceAclAugmentation.class).child(IetfAcl.class).child(Ingress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + @Mock + private AclTableContextManager aclCtx; + + private IetfAclCustomizer customizer; + private Ingress acl; + private int DENY = 0; + private int PERMIT = -1; + + private static Ace ace(final PacketHandling action) { + return new AceBuilder() + .setMatches(new MatchesBuilder().setAceType( + new AceIpBuilder() + .setAceIpVersion(new AceIpv6Builder().build()) + .setProtocol((short) 1) + .build() + ).build()) + .setActions(new ActionsBuilder().setPacketHandling(action).build()) + .build(); + } + + private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = IF_INDEX; + request.l2TableIndex = 1; + request.ip4TableIndex = 2; + request.ip6TableIndex = 3; + return request; + } + + private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { + final ClassifyAddDelTable reply = new ClassifyAddDelTable(); + reply.tableIndex = tableIndex; + reply.delChain = 1; + return reply; + } + + private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = IF_INDEX; + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = 0; + return request; + } + + @Override + protected void setUpTest() { + customizer = new IetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + acl = new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).build() + ).build(); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); + + when(writeContext.readAfter(any())).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Arrays.asList(ace(permit()), ace(permit()), ace(deny()) + )).build() + ).build() + + )); + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + + customizer.writeCurrentAttributes(IID, acl, writeContext); + + final InOrder inOrder = Mockito.inOrder(api); + inOrder.verify(api).classifyAddDelTable(argThat(actionOnMissEquals(DENY))); // default action + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(DENY))); // last deny ACE + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); + inOrder.verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); // assignment + } + + private ArgumentMatcher actionOnMissEquals(final int action) { + return table -> table.missNextIndex == action; + } + + private ArgumentMatcher actionOnHitEquals(final int action) { + return session -> session.hitNextIndex == action; + } + + private Deny deny() { + return new DenyBuilder().build(); + } + + private Permit permit() { + return new PermitBuilder().build(); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(IF_INDEX) + .setL2TableId(1) + .setIp4TableId(2) + .setIp6TableId(3) + .build())); + + customizer.deleteCurrentAttributes(IID, acl, writeContext); + + final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); + expectedRequest.swIfIndex = IF_INDEX; + verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); + verify(api).classifyAddDelTable(classifyAddDelTable(1)); + verify(api).classifyAddDelTable(classifyAddDelTable(2)); + verify(api).classifyAddDelTable(classifyAddDelTable(3)); + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizerTest.java new file mode 100644 index 000000000..b606b71cc --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceAclCustomizerTest.java @@ -0,0 +1,143 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.0"; + private static final int SUBIF_INDEX = 11; + private static final long SUBIF_ID = 0; + private static final String TABLE_NAME = "table0"; + private static final int TABLE_INDEX = 123; + + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)) + .augmentation(VppSubinterfaceAclAugmentation.class) + .child(Acl.class).child(Ingress.class); + + @Mock + private VppClassifierContextManager classifyTableContext; + + private SubInterfaceAclCustomizer customizer; + + @Override + protected void setUpTest() throws Exception { + customizer = new SubInterfaceAclCustomizer(api, new NamingContext("prefix", IFC_TEST_INSTANCE), + classifyTableContext); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + when(classifyTableContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + } + + @Test + public void testCreate() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); + verify(api).inputAclSetInterface(expectedIp4AclRequest()); + } + + @Test(expected = WriteFailedException.class) + public void testCreateFailed() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws WriteFailedException { + customizer.updateCurrentAttributes(IID, ip4Acl(), ip6Acl(), writeContext); + } + + @Test + public void testDelete() throws Exception { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + customizer.deleteCurrentAttributes(IID, ip6Acl(), writeContext); + verify(api).inputAclSetInterface(expectedIp6AclRequest()); + } + + @Test(expected = WriteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(IID, ip4Acl(), writeContext); + } + + private Ingress ip4Acl() { + final IngressBuilder builder = new IngressBuilder(); + final Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build(); + builder.setIp4Acl(acl); + return builder.build(); + } + + private InputAclSetInterface expectedIp4AclRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = TABLE_INDEX; + request.ip6TableIndex = -1; + request.swIfIndex = SUBIF_INDEX; + return request; + } + + private Ingress ip6Acl() { + final IngressBuilder builder = new IngressBuilder(); + final Ip6Acl acl = new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build(); + builder.setIp6Acl(acl); + return builder.build(); + } + + private InputAclSetInterface expectedIp6AclRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 0; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = TABLE_INDEX; + request.swIfIndex = SUBIF_INDEX; + return request; + } +} \ No newline at end of file diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizerTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizerTest.java new file mode 100644 index 000000000..d6e7d4010 --- /dev/null +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/acl/ingress/SubInterfaceIetfAclCustomizerTest.java @@ -0,0 +1,158 @@ +/* + * 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.vpp.classifier.write.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.vpp.classifier.write.acl.IetfAclWriter; +import io.fd.hc2vpp.vpp.classifier.write.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.acl.rev161214.vpp.acl.attributes.ietf.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.subinterface.acl.rev161214.VppSubinterfaceAclAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.123"; + private static final int SUBIF_INDEX = 2; + private static final long SUB_IF_ID = 123; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) + .augmentation(VppSubinterfaceAclAugmentation.class) + .child(IetfAcl.class).child(Ingress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + private SubInterfaceIetfAclCustomizer customizer; + private Ingress acl; + + @Mock + private AclTableContextManager aclCtx; + + private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = SUBIF_INDEX; + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + return request; + } + + private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = SUBIF_INDEX; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + return request; + } + + @Override + protected void setUpTest() { + customizer = + new SubInterfaceIetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + + acl = new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).build() + ).build(); + } + + @Test + public void testDelete() throws WriteFailedException { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + when(aclCtx.getEntry(SUBIF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(SUBIF_INDEX) + .setL2TableId(-1) + .setIp4TableId(-1) + .setIp6TableId(-1) + .build())); + + customizer.deleteCurrentAttributes(IID, acl, writeContext); + + final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); + expectedRequest.swIfIndex = SUBIF_INDEX; + verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); + } + + @Test + public void testWrite() throws WriteFailedException { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + + when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( + new SubInterfaceBuilder().build() + )); + + when(writeContext.readAfter(IetfAclWriter.ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, + new AclKey(ACL_NAME, ACL_TYPE)))).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Collections.emptyList()).build() + ).build() + )); + + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + + customizer.writeCurrentAttributes(IID, acl, writeContext); + + verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); + } +} \ No newline at end of file diff --git a/vpp-classifier/pom.xml b/vpp-classifier/pom.xml new file mode 100644 index 000000000..0ff49b6a7 --- /dev/null +++ b/vpp-classifier/pom.xml @@ -0,0 +1,36 @@ + + + + + + io.fd.honeycomb.common + honeycomb-parent + 1.17.04-SNAPSHOT + + 4.0.0 + + io.fd.hc2vpp.vpp.classifier + vpp-classifier-aggregator + pom + + + api + impl + + \ No newline at end of file diff --git a/vpp-classifier/vpp_classifier_postman_collection.json b/vpp-classifier/vpp_classifier_postman_collection.json new file mode 100644 index 000000000..4777f86fd --- /dev/null +++ b/vpp-classifier/vpp_classifier_postman_collection.json @@ -0,0 +1,263 @@ +{ + "id": "5f48ebd9-e156-043d-48a5-00da9142c738", + "name": "Vpp Classifier ACl Collection", + "description": "", + "order": [], + "folders": [ + { + "owner": "658985", + "lastUpdatedBy": "658985", + "lastRevision": 967405087, + "id": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "name": "ACL", + "description": "", + "order": [ + "b5c46425-e432-25e6-5fe0-4d212f42c0fe", + "1a02c8e5-5a14-9ee9-398c-f069d62a9dee", + "2cc814a0-5eca-857d-b647-b8b9627a1ee2", + "49bbb895-48f4-a78f-d4f3-9a8169824391", + "fe6f32a1-6c05-8d15-d795-c854ea6c7dbd", + "2f01b177-0649-a3c2-17da-7aec9a0f8074", + "3deb9342-0574-63a8-5880-1824afdf8953", + "5d311a46-aed2-3e58-793e-24c8053b8dba", + "7584ee44-de47-97b6-4f0d-4989aa04787f", + "f92b2685-3801-c771-7002-36b96ecd679e", + "9b33cd88-8be2-e232-5d5e-fa90d2613ac2", + "78dc955d-2113-c90b-c54c-7528ae463526" + ] + } + ], + "timestamp": 1488184412015, + "owner": "658985", + "public": false, + "requests": [ + { + "id": "1a02c8e5-5a14-9ee9-398c-f069d62a9dee", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/operational/vpp-classifier:vpp-classifier-state/", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183841509, + "name": "Get classify tables - oper", + "description": "Shows classify tables configured in the VPP.\n\nCorresponds to:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "2cc814a0-5eca-857d-b647-b8b9627a1ee2", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table0", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183851373, + "name": "Add classify table0", + "description": "Adds classify table0. Corresponding vpp cli command:\n\nvppctl classify table mask l2 src\n\nTo verify invoke:\n\nvppctl sh class table verbose\n\nor:\n\nvat# classify_table_info table_id 0", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "{\n \"classify-table\": [\n {\n \"name\": \"table0\",\n \"nbuckets\": \"2\",\n \"memory_size\": \"1048576\",\n \"miss_next\": \"permit\",\n \"mask\": \"00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00\"\n }\n ]\n}" + }, + { + "id": "2f01b177-0649-a3c2-17da-7aec9a0f8074", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table0/classify-session/00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183887727, + "name": "Add classify session", + "description": "Adds classify session to table0. Corresponding vpp cli command:\n\nvppctl classify session acl-hit-next deny opaque-index 0 table-index 0 match l2 src 01:02:03:04:05:06\n\nTo verify invoke:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "{\n \"classify-session\": [\n {\n \"hit_next\": \"deny\",\n \"match\": \"00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00\"\n }\n ]\n}" + }, + { + "id": "3deb9342-0574-63a8-5880-1824afdf8953", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table0/classify-session/00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183895189, + "name": "Add another classify session", + "description": "Adds second classify session to table0. Corresponding vpp cli command:\n\nvppctl classify session acl-hit-next deny opaque-index 0 table-index 0 match l2 src 01:02:03:04:05:07\n\nTo verify invoke:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "{\n \"classify-session\": [\n {\n \"hit_next\": \"deny\",\n \"match\": \"00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00\"\n }\n ]\n}" + }, + { + "id": "49bbb895-48f4-a78f-d4f3-9a8169824391", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/operational/vpp-classifier:vpp-classifier-state/classify-table/table0", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183870073, + "name": "Get classify table - oper", + "description": "Shows classify table 0 operational state.\n\nCorresponds to:\n\nvat# classify_table_info table_id 0", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "5d311a46-aed2-3e58-793e-24c8053b8dba", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/local0/vpp-interface-acl:acl", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488184203115, + "name": "Enable L2 and Ipv4 ACL on local0 interface", + "description": "Enables L2 and Ipv4 ACL on local0. Corresponding vpp cli commands:\n\nset int input acl intfc local0 l2-table 0\n\nset int input acl intfc local0 ip4-table 0\n\nTo verify invoke:\n\nvppctl show inacl type l2\n\nthen:\n\nvppctl show inacl type ip4", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "{\n \"vpp-interface-acl:acl\": {\n \t\"ingress\":{\n \t\t\"l2-acl\": {\n \"classify-table\": \"table0\"\n },\n \"ip4-acl\": {\n \"classify-table\": \"table0\"\n }\t\t\n \t}\n \n }\n}" + }, + { + "id": "7584ee44-de47-97b6-4f0d-4989aa04787f", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/local0/vpp-interface-acl:acl", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488184365057, + "name": "Disable ACL on local0 interface", + "description": "Disables ACL on local0. To verify invoke:\n\nvppctl show inacl type l2\n\nand:\n\nvppctl show inacl type ip4", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "78dc955d-2113-c90b-c54c-7528ae463526", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table1", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488184388131, + "name": "Remove classify table1", + "description": "Removes classify table1. Corresponds to the following command:\n\nvppctl classify table del table 1\n\nTo verify invoke:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "9b33cd88-8be2-e232-5d5e-fa90d2613ac2", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table0", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488184380564, + "name": "Remove classify table0", + "description": "Removes classify table0. Corresponds to the following command:\n\nvppctl classify table del table 0\n\nTo verify invoke:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "b5c46425-e432-25e6-5fe0-4d212f42c0fe", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183829071, + "name": "Get classify tables - cfg", + "description": "Shows classify table configuration.", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "f92b2685-3801-c771-7002-36b96ecd679e", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table0/classify-session/00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488184372640, + "name": "Remove classify session", + "description": "Removes classify session. To verify invoke:\n\nvppctl sh class table verbose", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "" + }, + { + "id": "fe6f32a1-6c05-8d15-d795-c854ea6c7dbd", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/vpp-classifier:vpp-classifier/classify-table/table1", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488183879955, + "name": "Add classify table1", + "description": "Adds classify table1 chained to classify table0.\n\nCorresponding vpp cli command:\n\nvppctl classify table mask l2 dst next-table 0\n\nTo verify invoke:\n\nvppctl sh class table verbose\n\nor:\n\nvat# classify_table_info table_id 1", + "collectionId": "5f48ebd9-e156-043d-48a5-00da9142c738", + "folder": "f3f79eb2-7264-9f3f-9a5f-b5a1fc50e743", + "rawModeData": "{\n \"classify-table\": [\n {\n \"name\": \"table1\",\n \"next_table\": \"table0\",\n \"nbuckets\": \"2\",\n \"memory_size\": \"1048576\",\n \"miss_next\": \"permit\",\n \"mask\": \"ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00\"\n }\n ]\n}" + } + ] +} \ No newline at end of file diff --git a/vpp-integration/minimal-distribution/pom.xml b/vpp-integration/minimal-distribution/pom.xml index d6f773dd6..ddf707687 100644 --- a/vpp-integration/minimal-distribution/pom.xml +++ b/vpp-integration/minimal-distribution/pom.xml @@ -39,13 +39,19 @@ 1.17.04-SNAPSHOT 1.17.04-SNAPSHOT 1.17.04-SNAPSHOT + 1.17.04-SNAPSHOT io.fd.hc2vpp.common.integration.VppCommonModule, io.fd.hc2vpp.lisp.LispModule, io.fd.hc2vpp.v3po.V3poModule, - // io.fd.hc2vpp.v3po.ClassifierIetfAclModule, + io.fd.hc2vpp.vpp.classifier.VppClassifierModule, + io.fd.hc2vpp.vpp.classifier.InterfaceClassifierAclModule, + io.fd.hc2vpp.vpp.classifier.SubInterfaceClassifierAclModule, + // io.fd.hc2vpp.vpp.classifier.VppClassifierAclModule, + // io.fd.hc2vpp.vpp.classifier.InterfaceClassifierIetfAclModule, + // io.fd.hc2vpp.vpp.classifier.SubInterfaceClassifierIetfAclModule, io.fd.hc2vpp.nat.NatModule, io.fd.hc2vpp.routing.RoutingModule, io.fd.hc2vpp.acl.AclModule, @@ -91,6 +97,11 @@ v3po2vpp ${v3po.version}
+ + io.fd.hc2vpp.vpp.classifier + vpp-classifier-impl + ${vpp.classifier.version} + io.fd.hc2vpp.lisp lisp2vpp -- cgit 1.2.3-korg