Bug 8228: Metadata service fix 85/54985/3
authorMichal Cmarada <mcmarada@cisco.com>
Thu, 13 Apr 2017 14:23:20 +0000 (16:23 +0200)
committerMichal Cmarada <mcmarada@cisco.com>
Thu, 13 Apr 2017 14:23:20 +0000 (16:23 +0200)
This is a hack to fix metadata service connectivity in openstack,
once IPprefix rules are fully supported in gbp we shall implement it
correctly.

- fixes Metadata service connectivity in FDS L3 scenario for openstack
- adding configuration file for metadata IP prefix setup

Change-Id: I9d42f1da4d845d3a5aeaf676c80ebc99034346fa
Signed-off-by: Michal Cmarada <mcmarada@cisco.com>
18 files changed:
artifacts/pom.xml
features/features-groupedpolicy/pom.xml
features/features-groupedpolicy/src/main/features/features.xml
features/odl-groupbasedpolicy-neutronmapper/pom.xml
features/odl-groupbasedpolicy-neutronmapper/src/main/feature/features.xml
neutron-mapper/pom.xml
neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java
neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml
neutron-mapper/src/main/resources/startup.cfg [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapperTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java

index e8fd81e4feb8631c363865153f76c1d4e8f3d8ae..5e9a4e6543c196ad18f1cdcd77b39cf68b970f9b 100755 (executable)
         <groupId>${project.groupId}</groupId>
         <artifactId>neutron-mapper</artifactId>
         <version>${project.version}</version>
-        <type>xml</type>
+        <type>cfg</type>
         <classifier>config</classifier>
       </dependency>
       <dependency>
index a83e1a096e28d3d483c3f117df3b7223cb24a6ff..0f16c2d4a9aac0f2ffb75ac7b393cf128d699a09 100644 (file)
         <dependency>
             <groupId>org.opendaylight.groupbasedpolicy</groupId>
             <artifactId>neutron-mapper</artifactId>
-            <type>xml</type>
+            <type>cfg</type>
             <classifier>config</classifier>
         </dependency>
         <dependency>
index b1da6aebc7bff6b21f39dcca15173ca3534f83c2..df5008a589f69302250b0a2450a2d262f239477f 100755 (executable)
         <bundle>mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}</bundle>
         <configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
-        <configfile finalname="${config.configfile.directory}/15-neutron-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/xml/config</configfile>
+        <configfile finalname="/etc/org.opendaylight.groupbasedpolicy.neutron.mapper.startup.cfg">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/cfg/config</configfile>
     </feature>
 
     <!--
index 79c93acfef860890f211cfe48cbd15e9ecfad1cc..20d3e62e0e7fa99ed63b3deb54a806340d66f254 100644 (file)
@@ -77,9 +77,9 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>neutron-mapper</artifactId>
-            <type>xml</type>
+            <type>cfg</type>
             <classifier>config</classifier>
             <scope>runtime</scope>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>
index b1a9f2ce086468497193332344981c668897482e..2de85b41219b3a8dd7b16c6afb192cffafc60c1e 100644 (file)
@@ -12,6 +12,5 @@
           xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
     <feature name="odl-groupbasedpolicy-neutronmapper" version="${project.version}">
         <configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
-        <configfile finalname="${config.configfile.directory}/15-neutron-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/xml/config</configfile>
     </feature>
-</features>
\ No newline at end of file
+</features>
index f39cb271017bd119fe9c41d2dbf355ce0ba1555b..70ace7e284739c5e07fadb87a6ba35c818941dfd 100644 (file)
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/startup.cfg</file>
+                  <type>cfg</type>
+                  <classifier>config</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
-</project>
\ No newline at end of file
+</project>
index 9b25add6a9b3ee1a9712efb11a91d800bbcf90cb..e7a6d2cd89cd2c530b27a363679e9dcda4aa5753 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.config.yang.config.neutron_mapper.impl;
 
+import java.util.regex.Pattern;
+
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -19,6 +21,8 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
 import org.slf4j.Logger;
@@ -33,15 +37,35 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
     private final DataBroker dataBroker;
     private final ClusterSingletonServiceProvider clusterSingletonService;
     private final RpcProviderRegistry rpcBroker;
+    private IpPrefix metadataIpPrefix;
+    private int metadataPort;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private NeutronMapper mapper;
 
     public NeutronMapperInstance(final DataBroker dataBroker,
                                  final RpcProviderRegistry rpcBroker,
-                                 final ClusterSingletonServiceProvider clusterSingletonService) {
+                                 final ClusterSingletonServiceProvider clusterSingletonService,
+                                 final String metadataIp,
+                                 final String metadataPort) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.rpcBroker = Preconditions.checkNotNull(rpcBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
+        try {
+            this.metadataIpPrefix = new IpPrefix(new Ipv4Prefix(Preconditions.checkNotNull(metadataIp)));
+            this.metadataPort = Integer.parseInt(Preconditions.checkNotNull(metadataPort));
+            LOG.trace("Resolved Metadata IP prefix: {}", metadataIpPrefix);
+        } catch (Exception ex) {
+
+            if (ex instanceof NumberFormatException) {
+                LOG.warn("Metadata port cannot be resolved. Provided value: {}. Continue without support for metadata.",
+                    metadataPort);
+            } else {
+                LOG.warn("MetadataIP could not be resolved. Provided value: {}. Continue without support for metadata.",
+                    metadataIp);
+            }
+            this.metadataIpPrefix = null;
+        }
+
     }
 
     public void instantiate() {
@@ -54,7 +78,7 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
         LOG.info("Instantiating {}", this.getClass().getSimpleName());
         final EndpointService epService = rpcBroker.getRpcService(EndpointService.class);
         final BaseEndpointService baseEndpointService = rpcBroker.getRpcService(BaseEndpointService.class);
-        mapper = new NeutronMapper(dataBroker, epService, baseEndpointService);
+        mapper = new NeutronMapper(dataBroker, epService, baseEndpointService, metadataIpPrefix, metadataPort);
     }
 
     @Override
index f1cd873f3f6a60eae27c55c0f3b418c5c0287471..1b623971797363ece5fb95197aec4c020d579b93 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSubnetAwa
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
@@ -104,10 +105,10 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>,
     private Neutron neutronBefore;
     private Neutron neutronAfter;
 
-    public NeutronMapper(DataBroker dataProvider, EndpointService epService,
-            BaseEndpointService baseEpService) {
+    public NeutronMapper(DataBroker dataProvider, EndpointService epService, BaseEndpointService baseEpService,
+        @Nullable IpPrefix metadataIpPrefix, long metadataPort) {
         EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService);
-        networkAware = new NeutronNetworkAware(dataProvider);
+        networkAware = new NeutronNetworkAware(dataProvider, metadataIpPrefix, metadataPort);
         securityRuleAware = new NeutronSecurityRuleAware(dataProvider);
         securityGroupAware = new NeutronSecurityGroupAware(dataProvider, securityRuleAware);
         subnetAware = new NeutronSubnetAware(dataProvider, epRegistrator);
index 6a33eb3709377885d4c43d2ee78f7a55e85db3b9..5ce0b774c391a84edce458bce0df285baa61cbb5 100755 (executable)
@@ -175,6 +175,30 @@ public class NetworkService {
      */
     public static final ConsumerNamedSelector MGMT_CONTRACT_CONSUMER_SELECTOR;
 
+    // ########### METADATA management
+    private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME =
+        new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME =
+        new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER");
+    private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
+    private static final Description METADATA_CONTRACT_DESC =
+        new Description("Allow METADATA management communication between server and client.");
+
+    /**
+     * Id of {@link #METADATA_CONTRACT}
+     */
+    public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572");
+    /**
+     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
+     * communication
+     * between Client and Server.
+     */
+    public static final Contract METADATA_CONTRACT;
+    /**
+     * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT}
+     */
+    public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR;
+
     // ########### NETWORK-SERVICE ENDPOINT-GROUP
     private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
     private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
@@ -194,6 +218,8 @@ public class NetworkService {
         DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT);
         MGMT_CONTRACT = createContractMgmt();
         MGMT_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(MGMT_CONTRACT);
+        METADATA_CONTRACT = createContractMetadata();
+        METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT);
         EPG = createNetworkServiceEpg();
     }
 
@@ -201,9 +227,11 @@ public class NetworkService {
         ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
         ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
         ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT);
+        ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT);
         return new EndpointGroupBuilder().setId(EPG_ID)
             .setName(NETWORK_SERVICE_EPG_NAME)
-            .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector))
+            .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector,
+                metadataProviderSelector))
             .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
             .setDescription(NETWORK_SERVICE_EPG_DESC)
             .build();
@@ -282,6 +310,26 @@ public class NetworkService {
             .build();
     }
 
+    private static Contract createContractMetadata() {
+        Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out);
+        Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In);
+        Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
+        Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
+        Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
+        Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
+
+        Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME)
+            .setOrder(0)
+            .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule,
+                clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
+                serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
+            .build();
+        return new ContractBuilder().setId(METADATA_CONTRACT_ID)
+            .setSubject(ImmutableList.of(subject))
+            .setDescription(METADATA_CONTRACT_DESC)
+            .build();
+    }
+
     private static Rule createRuleAllow(ClassifierName classifierName, Direction direction) {
         ClassifierName name =
                 new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue());
@@ -340,6 +388,21 @@ public class NetworkService {
                 clause, true);
     }
 
+    /**
+     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
+     * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}.
+     *
+     * @param tenantId location of {@link #METADATA_CONTRACT}
+     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
+     * @param wTx transaction where entities are written
+     */
+    public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
+        WriteTransaction wTx) {
+        Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()),
+            clause, true);
+    }
+
     private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
         ConsumerMatchers consumerMatchers = null;
         ProviderMatchers providerMatchers = null;
@@ -381,8 +444,8 @@ public class NetworkService {
      * @param tenantId location of network-service entities
      * @param wTx transaction where network-service entities are written
      */
-    public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) {
-        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances();
+    public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) {
+        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances(metadataPort);
         for (ClassifierInstance ci : classifierInstances) {
             wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
                     true);
@@ -396,6 +459,8 @@ public class NetworkService {
                 true);
         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, MGMT_CONTRACT_ID), MGMT_CONTRACT,
                 true);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT,
+                true);
         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
     }
 
@@ -403,7 +468,7 @@ public class NetworkService {
      * @return All classifier-instances used in {@link #DHCP_CONTRACT}, {@link #DNS_CONTRACT} and
      *         {@link #MGMT_CONTRACT}
      */
-    public static Set<ClassifierInstance> getAllClassifierInstances() {
+    public static Set<ClassifierInstance> getAllClassifierInstances(long metadataPort) {
         HashSet<ClassifierInstance> cis = new HashSet<>();
         cis.add(createDhcpIpv4ClientServer());
         cis.add(createDhcpIpv4ServerClient());
@@ -424,6 +489,9 @@ public class NetworkService {
         cis.add(createSshTcpIpv6ClientServer());
         cis.add(createIcmpIpv4());
         cis.add(createIcmpIpv6());
+        // METADATA
+        cis.add(createMetadataIpv4ClientServer(metadataPort));
+        cis.add(createMetadataIpv4ServerClient(metadataPort));
 
         return cis;
     }
@@ -575,6 +643,25 @@ public class NetworkService {
             .build();
     }
 
+    // ###################### METADATA
+    private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) {
+        return new ClassifierInstanceBuilder().setName(METADATA_CLIENT_TO_SERVER_NAME)
+            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
+            .setParameterValue(
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null,
+                    dstPort))
+            .build();
+    }
+
+    private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) {
+        return new ClassifierInstanceBuilder().setName(METADATA_SERVER_TO_CLIENT_NAME)
+            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
+            .setParameterValue(
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE,
+                    srcPort, null))
+            .build();
+    }
+
     private static List<ParameterValue> createParams(long etherType, long proto, @Nullable Long srcPort,
             @Nullable Long dstPort) {
         List<ParameterValue> params = new ArrayList<>();
index bd2a45faaa7abaddfe05cdd5481be721c38b2704..c7d7ca2b0a015c3748b96a5fca24346ed8ea0b72 100644 (file)
@@ -12,6 +12,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.annotation.Nullable;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -24,6 +26,7 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
@@ -56,10 +59,14 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
     public static final InstanceIdentifier<Network> NETWORK_WILDCARD_IID =
             InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();
     private final DataBroker dataProvider;
-    private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
+    private final Set<TenantId> tenantsWithRouterAndNetworkServiceEntities = new HashSet<>();
+    private final IpPrefix metadataIpPrefix;
+    private final long metadataPort;
 
-    public NeutronNetworkAware(DataBroker dataProvider) {
+    public NeutronNetworkAware(DataBroker dataProvider, @Nullable IpPrefix metadataIpPrefix, long metadataPort) {
         this.dataProvider = checkNotNull(dataProvider);
+        this.metadataIpPrefix = metadataIpPrefix;
+        this.metadataPort = metadataPort;
     }
 
     @Override
@@ -99,9 +106,9 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
 
         createTenantNetworkDomains(network, tenantId, rwTx);
 
-        if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
-            tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
-            NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
+        if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) {
+            tenantsWithRouterAndNetworkServiceEntities.add(tenantId);
+            NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataPort);
             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
             NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
@@ -109,6 +116,11 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
+            if (metadataIpPrefix != null) {
+                NetworkService.writeMetadataClauseWithConsProvEic(tenantId, metadataIpPrefix, rwTx);
+                NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.METADATA_CONTRACT_CONSUMER_SELECTOR,
+                    rwTx);
+            }
         }
         if (!NetworkUtils.getPhysicalNetwork(network).isEmpty() && !NetworkUtils.getSegmentationId(network).isEmpty()) {
             addProviderPhysicalNetworkMapping(tenantId, ctxId, NetworkUtils.getSegmentationId(network), rwTx);
index e06639d7b5294816b0b3c45d7caaae9dc8c30fe1..ed69af45fb4e5557111984c0f9e6abe0d00306bd 100644 (file)
@@ -1,16 +1,26 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
            odl:use-default-for-reference-types="true">
 
     <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
     <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
     <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
+    <cm:property-placeholder persistent-id="org.opendaylight.groupbasedpolicy.neutron.mapper.startup" update-strategy="none">
+        <cm:default-properties>
+            <cm:property name="metadata-ip" value="169.254.169.254/32"/>
+            <cm:property name="metadata-port" value="80"/>
+        </cm:default-properties>
+    </cm:property-placeholder>
+
     <bean id="neutronMapper" class="org.opendaylight.controller.config.yang.config.neutron_mapper.impl.NeutronMapperInstance"
           init-method="instantiate" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="rpcRegistry"/>
         <argument ref="clusterSingletonService"/>
+        <argument value="${metadata-ip}"/>
+        <argument value="${metadata-port}"/>
     </bean>
-</blueprint>
\ No newline at end of file
+</blueprint>
diff --git a/neutron-mapper/src/main/resources/startup.cfg b/neutron-mapper/src/main/resources/startup.cfg
new file mode 100644 (file)
index 0000000..4fa71dd
--- /dev/null
@@ -0,0 +1,13 @@
+# INITIAL NEUTRON MAPPER CONFIGURATION
+#
+# Uncomment lines on the bottom of this file to change default values of neutron
+# mapper bundle config. The file should be placed to karaf_root_dir/etc
+#
+# To explicitly specify which IP prefix should be used for metadata
+# service in openstack, uncomment and modify following line.
+# Specifying one IP for metadata service is currently supported.
+#metadata-ip = 169.254.169.254/32
+
+# To explicitly specify which port should be used for metadata
+# service in openstack, uncomment and modify following line.
+#metadata-port = 80
index 059ef8d08e3b12006823da545be68245428f072a..5525dd436afc733f9f5f4c453f62e005473a3258 100644 (file)
@@ -27,12 +27,13 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronNetworkAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+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.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
@@ -61,9 +62,10 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
     private final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
     private final Uuid networkUuid2 = new Uuid("dddddddd-dddd-dddd-dddd-ddddddddddd2");
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
-    private RpcProviderRegistry rpcProvider;
     private EndpointService epService;
     private BaseEndpointService baseEpService;
 
@@ -84,7 +86,7 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
         epService = mock(EndpointService.class);
         baseEpService = mock(BaseEndpointService.class);
 
-        mapper = new NeutronMapper(dataBroker, epService, baseEpService);
+        mapper = new NeutronMapper(dataBroker, epService, baseEpService, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
 
         networkL3Extension = new NetworkL3ExtensionBuilder().setExternal(true).build();
 
@@ -117,7 +119,8 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
     @Test
     public void testConstructor() throws IOException {
         DataBroker dataBrokerSpy = spy(dataBroker);
-        NeutronMapper other = new NeutronMapper(dataBrokerSpy, epService, baseEpService);
+        NeutronMapper other = new NeutronMapper(dataBrokerSpy, epService, baseEpService, METADATA_IP_PREFIX,
+            METADATA_IPV4_SERVER_PORT);
 
         verify(dataBrokerSpy).registerDataTreeChangeListener(new DataTreeIdentifier<>(
                 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), other);
index fc2bb82bab3f15dd0008998ab1c0a201db4583bd..121476820d5fc42575c17fb18868f7150776e2cf 100644 (file)
@@ -55,6 +55,13 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
     private static final String ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME = "ICMP_IPV4_BETWEEN_SERVER_CLIENT";
     private static final String ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME = "ICMP_IPV6_BETWEEN_SERVER_CLIENT";
 
+    // metadata
+    private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
+    private static final String METADATA_SERVER_TO_CLIENT_NAME = "METADATA_FROM_SERVER_TO_CLIENT";
+    private static final String METADATA_CLIENT_TO_SERVER_NAME = "METADATA_FROM_CLIENT_TO_SERVER";
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private final IpPrefix metadataIpv4Prefix = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
+
     private final String tenantId = "00000000-0000-0000-0000-000000000001";
     private final IpPrefix ipv4Prefix = new IpPrefix(new Ipv4Prefix("170.0.0.1/8"));
     private final IpPrefix ipv6Prefix = new IpPrefix(new Ipv6Prefix("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128"));
@@ -131,12 +138,64 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
                 clauseNameIpV6);
     }
 
+
+    @Test
+    public void testWriteMgmtClauseWithConsProvEicIpv4() throws Exception {
+        // ipv4
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        NetworkService.writeMgmtClauseWithConsProvEic(new TenantId(tenantId), ipv4Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV4 = MGMT_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + ipv4Prefix.getIpv4Prefix().getValue();
+        clauseNameIpV4 = clauseNameIpV4.replace('/', '_');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue(),
+            clauseNameIpV4);
+    }
+
+    @Test
+    public void testWriteMgmtClauseWithConsProvEicIpv6() throws Exception {
+        // ipv6
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        NetworkService.writeMgmtClauseWithConsProvEic(new TenantId(tenantId), ipv6Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV6 = MGMT_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + ipv6Prefix.getIpv6Prefix().getValue();
+        clauseNameIpV6 = clauseNameIpV6.replace('/', '_').replace(':', '.');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue(),
+            clauseNameIpV6);
+    }
+
+    @Test
+    public void testWriteMetadataClauseWithConsProvEicIpv4() throws Exception {
+        // ipv4
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        NetworkService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV4 = METADATA_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + metadataIpv4Prefix.getIpv4Prefix().getValue();
+        clauseNameIpV4 = clauseNameIpV4.replace('/', '_');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue(),
+            clauseNameIpV4);
+    }
+
     @Test
     public void testWriteNetworkServiceEntitiesToTenant() throws Exception {
         // write everything
         DataBroker dataBroker = getDataBroker();
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
-        NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx);
+        NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx, METADATA_IPV4_SERVER_PORT);
         rwTx.submit().get();
 
         // read classifier instances
@@ -158,11 +217,14 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, SSH_IPV6_CLIENT_TO_SERVER_NAME);
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME);
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME);
+        PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_CLIENT_TO_SERVER_NAME);
+        PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_SERVER_TO_CLIENT_NAME);
 
         // read contracts
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DHCP_CONTRACT_ID.getValue());
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DNS_CONTRACT_ID.getValue());
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue());
+        PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue());
 
         // read group id
         PolicyAssert.assertEndpointGroupExists(dataBroker, tenantId, NetworkService.EPG_ID.getValue());
@@ -170,10 +232,11 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
 
     @Test
     public void testGetAllClassifierInstances() {
-        Set<ClassifierInstance> classifierInstances = NetworkService.getAllClassifierInstances();
+        Set<ClassifierInstance> classifierInstances =
+            NetworkService.getAllClassifierInstances(METADATA_IPV4_SERVER_PORT);
         assertNotNull(classifierInstances);
         assertFalse(classifierInstances.isEmpty());
-        assertEquals(classifierInstances.size(), 18);
+        assertEquals(20, classifierInstances.size());
     }
 
 }
index a56822f93fbcdf564c4390e9f2ed561dde73b64c..3cc85f2baeaba649b191f70281356872de6ae51d 100644 (file)
@@ -18,6 +18,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import com.google.common.base.Optional;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -28,6 +29,8 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+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.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
@@ -45,6 +48,8 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
 
     private final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
     private NeutronNetworkAware networkAware;
@@ -80,7 +85,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
             .addAugmentation(NetworkProviderExtension.class, providerExtension)
             .build();
 
-        networkAware = new NeutronNetworkAware(dataBroker);
+        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
     }
 
     @Rule
@@ -89,7 +94,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
     @Test
     public void testConstructor_invalidArgument() throws NullPointerException {
         thrown.expect(NullPointerException.class);
-        new NeutronNetworkAware(null);
+        new NeutronNetworkAware(null, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
     }
 
     @Test
index 683ff807f76bbdcc78da0059a0f847eca73de688..b6e42d545b62e1479051e03279a7d3272729d635 100644 (file)
@@ -33,7 +33,9 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+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.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
@@ -69,6 +71,8 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
     private final Uuid gatewayPortUuid = new Uuid("dddddddd-dddd-dddd-dddd-ddddddddddd1");
     private final IpAddress ipAddress = new IpAddress(new Ipv4Address("10.0.0.2"));
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
     private NeutronRouterAware routerAware;
@@ -108,7 +112,7 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest
                     .thenReturn(futureRpcResult);
         epRegistrator = new EndpointRegistrator(epService, baseEpService);
 
-        networkAware = new NeutronNetworkAware(dataBroker);
+        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
         network = new NetworkBuilder().setTenantId(tenantUuid).setUuid(networkUuid).setName("networkName").build();
 
         routerAware = new NeutronRouterAware(dataBroker, epRegistrator);
index bb7f7dbb13e6de720354db84ea8b9a78e986c905..1eca68663e8331214af4fa0e6dd521880d8507cc 100644 (file)
@@ -23,6 +23,8 @@ import org.slf4j.LoggerFactory;
 class DestinationMapper extends AddressMapper {
 
     private static final Logger LOG = LoggerFactory.getLogger(DestinationMapper.class);
+    private static final String METADATA_IP_PREFIX = "169.254.169.254/32";
+    private static final String IN__METADATA = "In__METADATA";
 
     DestinationMapper(ACE_DIRECTION direction) {
         super(direction);
@@ -41,13 +43,26 @@ class DestinationMapper extends AddressMapper {
             // TODO more parents, when supported
             ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0);
             if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) {
-                LOG.trace("Setting dst IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
-                try {
-                    AccessListUtil.setDestinationL3Address(aclRuleBuilder, parentEp.getAddress());
-                } catch (UnknownHostException e) {
-                    LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
+                // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs
+                // per interface we shall rework this
+                if (aclRuleBuilder.getName().contains(IN__METADATA)) {
+                    LOG.trace("Setting dst IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder);
+                    try {
+                        AccessListUtil.setDestinationL3Address(aclRuleBuilder, METADATA_IP_PREFIX);
+                    } catch (UnknownHostException e) {
+                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX,
                             aclRuleBuilder, e);
+                    }
+                } else {
+                    LOG.trace("Setting dst IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
+                    try {
+                        AccessListUtil.setDestinationL3Address(aclRuleBuilder, parentEp.getAddress());
+                    } catch (UnknownHostException e) {
+                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
+                            aclRuleBuilder, e);
+                    }
                 }
+
             }
         }
     }
index ebaeb361178e2ba926ae1744f1ea1d14791841a2..28b03d8f9825896dd8d214f755e6786991c8ced9 100644 (file)
@@ -23,6 +23,8 @@ import org.slf4j.LoggerFactory;
 class SourceMapper extends AddressMapper {
 
     private static final Logger LOG = LoggerFactory.getLogger(SourceMapper.class);
+    private static final String METADATA_IP_PREFIX = "169.254.169.254/32";
+    private static final String OUT__METADATA = "Out__METADATA";
 
     SourceMapper(ACE_DIRECTION direction) {
         super(direction);
@@ -41,12 +43,24 @@ class SourceMapper extends AddressMapper {
             // TODO more parents
             ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0);
             if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) {
-                LOG.trace("Setting src IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
-                try {
-                    AccessListUtil.setSourceL3Address(aclRuleBuilder, parentEp.getAddress());
-                } catch (UnknownHostException e) {
-                    LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
+                // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs
+                // per interface we shall rework this
+                if (aclRuleBuilder.getName().contains(OUT__METADATA)) {
+                    LOG.trace("Setting src IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder);
+                    try {
+                        AccessListUtil.setSourceL3Address(aclRuleBuilder, METADATA_IP_PREFIX);
+                    } catch (UnknownHostException e) {
+                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX,
                             aclRuleBuilder, e);
+                    }
+                } else {
+                    LOG.trace("Setting src IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
+                    try {
+                        AccessListUtil.setSourceL3Address(aclRuleBuilder, parentEp.getAddress());
+                    } catch (UnknownHostException e) {
+                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
+                            aclRuleBuilder, e);
+                    }
                 }
             }
         }