Finish implementing most of the destination mapper table (at least as 73/9173/1
authorRob Adams <readams@readams.net>
Sat, 19 Jul 2014 00:43:07 +0000 (17:43 -0700)
committerRob Adams <readams@readams.net>
Sat, 19 Jul 2014 00:43:07 +0000 (17:43 -0700)
far as I can without extensions)

Change-Id: I03500d8c17687844207d009e421e7b62b8d7c4db
Signed-off-by: Rob Adams <readams@readams.net>
16 files changed:
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/PolicyManager.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/SubjectFeatures.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/SwitchManager.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PortSecurity.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyCache.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolver.java
groupbasedpolicy/src/main/yang/model/policy.yang
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/MockSwitchManager.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PortSecurityTest.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/SourceMapperTest.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/MockPolicyResolver.java

index b7201f764b4100c4cbb360bfe7fc9ea001be0f4d..7b3639ba98da80462f5d04bcfd7f238f2ced0361 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.DestinationMapp
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowTableCtx;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PortSecurity;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.SourceMapper;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
@@ -44,8 +45,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig.LearningMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -115,12 +118,23 @@ public class PolicyManager
         this.switchManager = switchManager;
         this.executor = executor;
 
+        if (dataBroker != null) {
+            WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+            t.put(LogicalDatastoreType.OPERATIONAL, 
+                  InstanceIdentifier
+                      .builder(SubjectFeatureDefinitions.class)
+                      .build(),
+                  SubjectFeatures.OF_OVERLAY_FEATURES);
+            t.commit();
+        }
+
         FlowTableCtx ctx = new FlowTableCtx(dataBroker, rpcRegistry, 
                                             this, policyResolver, switchManager, 
                                             endpointManager, executor);
         flowPipeline = ImmutableList.of(new PortSecurity(ctx),
                                         new SourceMapper(ctx),
-                                        new DestinationMapper(ctx));
+                                        new DestinationMapper(ctx),
+                                        new PolicyEnforcer(ctx));
 
         policyScope = policyResolver.registerListener(this);
         if (switchManager != null)
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/SubjectFeatures.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/SubjectFeatures.java
new file mode 100644 (file)
index 0000000..05c3acd
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Defines the subject features that are supported by the OF overlay renderer
+ */
+public class SubjectFeatures {
+    public static final ActionDefinition ALLOW = 
+            new ActionDefinitionBuilder()
+                .setId(new ActionDefinitionId("f942e8fd-e957-42b7-bd18-f73d11266d17"))
+                .setName(new ActionName("allow"))
+                .setDescription(new Description("Allow the specified traffic to pass"))
+                .build();
+
+    public static final ClassifierDefinition ETHER_TYPE = 
+            new ClassifierDefinitionBuilder()
+                .setId(new ClassifierDefinitionId("79c6fdb2-1e1a-4832-af57-c65baf5c2335"))
+                .setName(new ClassifierName("ether_type"))
+                .setDescription(new Description("Match on the ether type of the traffic"))
+                .setParameter(ImmutableList.of(new ParameterBuilder()
+                    .setName(new ParameterName("type"))
+                    .setDescription(new Description("The ethertype to match against"))
+                    .setType(Type.Int)
+                    .build()))
+                .build();
+
+    public static final ClassifierDefinition IP_PROTO = 
+            new ClassifierDefinitionBuilder()
+                .setId(new ClassifierDefinitionId("79c6fdb2-1e1a-4832-af57-c65baf5c2335"))
+                .setParent(ETHER_TYPE.getId())
+                .setName(new ClassifierName("ip_proto"))
+                .setDescription(new Description("Match on the IP protocol of IP traffic"))
+                .setParameter(ImmutableList.of(new ParameterBuilder()
+                    .setName(new ParameterName("proto"))
+                    .setDescription(new Description("The IP protocol to match against"))
+                    .setType(Type.Int)
+                    .build()))
+                .build();
+
+    public static final ClassifierDefinition UDP_PORT = 
+            new ClassifierDefinitionBuilder()
+                .setId(new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f"))
+                .setParent(IP_PROTO.getId())
+                .setName(new ClassifierName("udp_port"))
+                .setDescription(new Description("Match on the port number of UDP traffic"))
+                .setParameter(ImmutableList.of(new ParameterBuilder()
+                    .setName(new ParameterName("port"))
+                    .setDescription(new Description("The port number to match against"))
+                    .setType(Type.Int)
+                    .build()))
+                .build();
+
+    public static final ClassifierDefinition TCP_PORT = 
+            new ClassifierDefinitionBuilder()
+                .setId(new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f"))
+                .setParent(IP_PROTO.getId())
+                .setName(new ClassifierName("tcp_port"))
+                .setDescription(new Description("Match on the port number of TCP traffic"))
+                .setParameter(ImmutableList.of(new ParameterBuilder()
+                    .setName(new ParameterName("port"))
+                    .setDescription(new Description("The port number to match against"))
+                    .setType(Type.Int)
+                    .build()))
+                .build();
+
+    public static final SubjectFeatureDefinitions OF_OVERLAY_FEATURES =
+            new SubjectFeatureDefinitionsBuilder()
+                .setActionDefinition(ImmutableList.of(ALLOW))
+                .setClassifierDefinition(ImmutableList.of(ETHER_TYPE,
+                                                          IP_PROTO,
+                                                          UDP_PORT,
+                                                          TCP_PORT))
+                .build();
+}
index e9c8ced7668e902e5cf1ea99c60d5034e1316821..af90eb6950e8c42afae4e5d0621337b9cb9fc247 100644 (file)
@@ -391,10 +391,12 @@ public class SwitchManager implements AutoCloseable {
          */
         public SwitchState(NodeId node,
                            NodeConnectorId tunnelPort,
-                           Set<NodeConnectorId> externalPorts) {
+                           Set<NodeConnectorId> externalPorts,
+                           OfOverlayNodeConfig nodeConfig) {
             this.nodeId = node;
             this.tunnelPort = tunnelPort;
             this.externalPorts = externalPorts;
+            this.nodeConfig = nodeConfig;
         }
         
         private void update() {
index 7c818e00871430a67921b129d4947cb14d903a8d..7d7a17191308cb12e6625daaa5d6295be0534bea 100644 (file)
@@ -19,6 +19,10 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
@@ -26,11 +30,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.I
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
@@ -43,7 +51,8 @@ public class DestinationMapper extends FlowTable {
     /**
      * This is the MAC address of the magical router in the sky
      */
-    public static final String ROUTER_MAC = "88:f0:31:b5:12:b5";
+    public static final MacAddress ROUTER_MAC = 
+            new MacAddress("88:f0:31:b5:12:b5");
 
     public DestinationMapper(FlowTableCtx ctx) {
         super(ctx);
@@ -121,8 +130,9 @@ public class DestinationMapper extends FlowTable {
                                  throws Exception {
 
         ArrayList<Instruction> instructions = new ArrayList<>();
+        ArrayList<Instruction> l3instructions = new ArrayList<>();
         int order = 0;
-        
+
         String nextHop;
         if (LocationType.External.equals(ofc.getLocationType())) {
             // XXX - TODO - perform NAT and send to the external network
@@ -130,6 +140,10 @@ public class DestinationMapper extends FlowTable {
             LOG.warn("External endpoints not yet supported");
             return;
         } else {
+            Action setDlSrc = FlowUtils.setDlSrc(ROUTER_MAC);
+            Action setDlDst = FlowUtils.setDlDst(e.getMacAddress());
+            Action decTtl = FlowUtils.decNwTtl();
+
             if (Objects.equals(ofc.getNodeId(), nodeId)) {
                 // this is a local endpoint
                 nextHop = ofc.getNodeConnectorId().getValue();
@@ -138,11 +152,15 @@ public class DestinationMapper extends FlowTable {
                     .setOrder(order++)
                     .setInstruction(FlowUtils.outputActionIns(ofc.getNodeConnectorId()))
                     .build());
+                l3instructions.add(new InstructionBuilder()
+                    .setOrder(order)
+                    .setInstruction(FlowUtils.writeActionIns(setDlSrc,
+                                                             setDlDst,
+                                                             decTtl))
+                    .build());
             } else {
                 // this endpoint is on a different switch; send to the 
                 // appropriate tunnel
-                
-                // XXX - TODO Add action: set tunnel_id from sEPG register
 
                 IpAddress tunDst = 
                         ctx.switchManager.getTunnelIP(ofc.getNodeId());
@@ -165,17 +183,24 @@ public class DestinationMapper extends FlowTable {
                     return;
                 }
                 
+                // XXX - TODO Add action: set tunnel_id from sEPG register
                 instructions.add(new InstructionBuilder()
                     .setOrder(order++)
                     .setInstruction(FlowUtils.outputActionIns(tunPort))
                     .build());
+                l3instructions.add(new InstructionBuilder()
+                    .setOrder(order)
+                    .setInstruction(FlowUtils.writeActionIns(setDlSrc, decTtl))
+                    .build());
+
             }
         }
-        
-        instructions.add(new InstructionBuilder()
+        Instruction gotoTable = new InstructionBuilder()
             .setOrder(order++)
-            .setInstruction(FlowUtils.gotoTable((short)(getTableId()+1)))
-            .build());
+            .setInstruction(FlowUtils.gotoTableIns((short)(getTableId()+1)))
+            .build();
+        instructions.add(gotoTable);
+        l3instructions.add(gotoTable);
 
         FlowId flowid = new FlowId(new StringBuilder()
             .append(e.getL2Context())
@@ -184,19 +209,69 @@ public class DestinationMapper extends FlowTable {
             .append("|")
             .append(nextHop)
             .toString());
-        if (!visit(flowMap, flowid.getValue()))
-            return;
-    
-        FlowBuilder flowb = base()
-            .setId(flowid)
-            .setMatch(new MatchBuilder()
-            .setEthernetMatch(FlowUtils.ethernetMatch(null, 
-                                                      e.getMacAddress(), 
-                                                      null))
-                 .build())
-            .setInstructions(new InstructionsBuilder()
-                .setInstruction(instructions)
-                .build());
-        writeFlow(t, tiid, flowb.build());
+        if (visit(flowMap, flowid.getValue())) {
+            // XXX TODO add match against bridge domain register
+            FlowBuilder flowb = base()
+                .setId(flowid)
+                .setPriority(Integer.valueOf(50))
+                .setMatch(new MatchBuilder()
+                    .setEthernetMatch(FlowUtils.ethernetMatch(null, 
+                                                          e.getMacAddress(), 
+                                                          null))
+                    .build())
+                .setInstructions(new InstructionsBuilder()
+                    .setInstruction(instructions)
+                    .build());
+            
+            writeFlow(t, tiid, flowb.build());
+        }
+        if (e.getL3Address() == null) return;
+        for (L3Address l3a : e.getL3Address()) {
+            if (l3a.getIpAddress() == null || l3a.getL3Context() == null)
+                continue;
+            Layer3Match m = null;
+            Long etherType = null;
+            String ikey = null;
+            if (l3a.getIpAddress().getIpv4Address() != null) {
+                ikey = l3a.getIpAddress().getIpv4Address().getValue();
+                etherType = FlowUtils.IPv4;
+                m = new Ipv4MatchBuilder()
+                    .setIpv4Destination(new Ipv4Prefix(ikey))
+                    .build();
+            } else if (l3a.getIpAddress().getIpv6Address() != null) {
+                ikey = l3a.getIpAddress().getIpv6Address().getValue();
+                etherType = FlowUtils.IPv6;
+                m = new Ipv6MatchBuilder()
+                    .setIpv6Destination(new Ipv6Prefix(ikey))
+                    .build();
+            } else
+                continue;
+
+            flowid = new FlowId(new StringBuilder()
+                .append(l3a.getL3Context())
+                .append("|l3|")
+                .append(l3a.getIpAddress())
+                .append("|")
+                .append(nextHop)
+                .toString());
+            if (visit(flowMap, flowid.getValue())) {
+                // XXX TODO add match against routing domain register
+
+                FlowBuilder flowb = base()
+                    .setId(flowid)
+                    .setPriority(Integer.valueOf(132))
+                    .setMatch(new MatchBuilder()
+                        .setEthernetMatch(FlowUtils.ethernetMatch(null, 
+                                                                  ROUTER_MAC, 
+                                                                  etherType))
+                        .setLayer3Match(m)
+                        .build())
+                    .setInstructions(new InstructionsBuilder()
+                        .setInstruction(l3instructions)
+                        .build());
+                
+                writeFlow(t, tiid, flowb.build());
+            }
+        }
     }
 }
index 1c93bafba64b60bb66c054a201abe4fb081b80d7..ad83cc756fed0a306c2f9442e5fc76e13cddc84f 100644 (file)
@@ -8,12 +8,20 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
+import java.util.ArrayList;
+
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -48,7 +56,19 @@ import com.google.common.collect.ImmutableList;
  * Utilities for constructing OpenFlow flows
  */
 public final class FlowUtils {
-
+    /**
+     * ARP ethertype
+     */
+    protected static final Long ARP = Long.valueOf(0x0806);
+    /**
+     * IPv4 ethertype
+     */
+    protected static final Long IPv4 = Long.valueOf(0x0800);
+    /**
+     * IPv6 ethertype
+     */
+    protected static final Long IPv6 = Long.valueOf(0x86DD);
+    
     /**
      * Creates an Instance Identifier (path) for node with specified id
      *
@@ -62,34 +82,6 @@ public final class FlowUtils {
                 .build();
     }
 
-    /**
-     * Shorten's node child path to node path.
-     *
-     * @param nodeChild child of node, from which we want node path.
-     * @return
-     */
-    public static final InstanceIdentifier<Node> 
-        getNodePath(final InstanceIdentifier<?> nodeChild) {
-        return nodeChild.firstIdentifierOf(Node.class);
-    }
-
-
-    /**
-     * Creates a table path by appending table specific location to node path
-     *
-     * @param nodePath
-     * @param tableKey
-     * @return
-     */
-    public static final InstanceIdentifier<Table> 
-        createTablePath(final InstanceIdentifier<Node> nodePath, 
-                        final TableKey tableKey) {
-        return nodePath.builder()
-                .augmentation(FlowCapableNode.class)
-                .child(Table.class, tableKey)
-                .build();
-    }
-
     /**
      * Creates a table path from a node ID and table ID
      *
@@ -138,12 +130,12 @@ public final class FlowUtils {
         return new InstructionsBuilder()
         .setInstruction(ImmutableList.of(new InstructionBuilder()
             .setOrder(Integer.valueOf(0))
-            .setInstruction(gotoTable(tableId))
+            .setInstruction(gotoTableIns(tableId))
             .build()))
         .build();
     }
     
-    public static Instruction gotoTable(short tableId) {
+    public static Instruction gotoTableIns(short tableId) {
         return new GoToTableCaseBuilder()
             .setGoToTable(new GoToTableBuilder()
                 .setTableId(tableId)
@@ -152,12 +144,22 @@ public final class FlowUtils {
     }
     
     public static Instruction outputActionIns(NodeConnectorId id) {
+        return writeActionIns(outputAction(id));
+    }
+    
+    public static Instruction writeActionIns(Action... actions) {
+        ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
+            = new ArrayList<>();
+        int count = 0;
+        for (Action action : actions) {
+            alist.add(new ActionBuilder()
+                .setOrder(Integer.valueOf(count++))
+                .setAction(action)
+                .build());
+        }
         return new WriteActionsCaseBuilder()
             .setWriteActions(new WriteActionsBuilder()
-                .setAction(ImmutableList.of(new ActionBuilder()
-                    .setOrder(Integer.valueOf(0))
-                    .setAction(outputAction(id))
-                    .build()))
+                .setAction(alist)
                 .build())
             .build();
     }
@@ -192,7 +194,30 @@ public final class FlowUtils {
                 .build())
             .build();
     }
-    
+
+    public static Action setDlSrc(MacAddress mac) {
+        return new SetDlSrcActionCaseBuilder()
+            .setSetDlSrcAction(new SetDlSrcActionBuilder()
+                .setAddress(mac)
+                .build())
+            .build();
+    }
+
+    public static Action setDlDst(MacAddress mac) {
+        return new SetDlDstActionCaseBuilder()
+            .setSetDlDstAction(new SetDlDstActionBuilder()
+                .setAddress(mac)
+                .build())
+            .build();
+    }
+
+    public static Action decNwTtl() {
+        return new DecNwTtlCaseBuilder()
+            .setDecNwTtl(new DecNwTtlBuilder()
+                .build())
+            .build();
+    }
+
     public static EthernetMatch ethernetMatch(MacAddress srcMac, 
                                               MacAddress dstMac,
                                               Long etherType) {
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java
new file mode 100644 (file)
index 0000000..b307791
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Manage the table that enforces policy on the traffic.  Traffic is denied
+ * unless specifically allowed by policy
+ * @author readams
+ */
+public class PolicyEnforcer extends FlowTable {
+    public static final short TABLE_ID = 2;
+
+    public PolicyEnforcer(FlowTableCtx ctx) {
+        super(ctx);
+    }
+
+    @Override
+    public void sync(ReadWriteTransaction t, InstanceIdentifier<Table> tiid,
+                     Map<String, FlowCtx> flowMap, NodeId nodeId, Dirty dirty)
+                             throws Exception {
+        
+    }
+
+    @Override
+    public short getTableId() {
+        return TABLE_ID;
+    }
+
+}
index 8cbedb8aecffbbff32dcedf4c9a88182896d15e5..d19480b21ae386a7b62003e65faa22b5050980e2 100644 (file)
@@ -43,9 +43,6 @@ public class PortSecurity extends FlowTable {
             LoggerFactory.getLogger(PortSecurity.class);
     
     public static final short TABLE_ID = 0;
-    protected static final Long ARP = Long.valueOf(0x0806);
-    protected static final Long IPv4 = Long.valueOf(0x0800);
-    protected static final Long IPv6 = Long.valueOf(0x86DD);
     
     public PortSecurity(FlowTableCtx ctx) {
         super(ctx);
@@ -75,9 +72,9 @@ public class PortSecurity extends FlowTable {
         dropFlow(t, tiid, flowMap, 1, null);
         
         // Drop IP traffic that doesn't match a source IP rule
-        dropFlow(t, tiid, flowMap, 110, ARP);
-        dropFlow(t, tiid, flowMap, 111, IPv4);
-        dropFlow(t, tiid, flowMap, 112, IPv6);
+        dropFlow(t, tiid, flowMap, 110, FlowUtils.ARP);
+        dropFlow(t, tiid, flowMap, 111, FlowUtils.IPv4);
+        dropFlow(t, tiid, flowMap, 112, FlowUtils.IPv6);
 
         for (Endpoint e : ctx.endpointManager.getEndpointsForNode(nodeId)) {
             OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
@@ -182,12 +179,12 @@ public class PortSecurity extends FlowTable {
                     m = new ArpMatchBuilder()
                         .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
                         .build();
-                    etherType = ARP;
+                    etherType = FlowUtils.ARP;
                 } else {
                     m = new Ipv4MatchBuilder()
                         .setIpv4Source(new Ipv4Prefix(ikey))
                         .build();
-                    etherType = IPv4;
+                    etherType = FlowUtils.IPv4;
                 }
             } else if (l3.getIpAddress().getIpv6Address() != null) {
                 if (arp) continue;
@@ -195,7 +192,7 @@ public class PortSecurity extends FlowTable {
                 m = new Ipv6MatchBuilder()
                     .setIpv6Source(new Ipv6Prefix(ikey))
                     .build();
-                etherType = IPv6;
+                etherType = FlowUtils.IPv6;
             } else {
                 continue;
             }
index 21faf4c432acad2c1f5e76a9f93d014e91f2837a..7c93ddfe24065cdc3a183d08c5b5d41288bc9ebf 100644 (file)
@@ -68,6 +68,7 @@ class PolicyCache {
      */
     protected Set<EgKey> getProvidersForConsumer(TenantId tenant,
                                                  EndpointGroupId eg) {
+        if (policy.get() == null) return Collections.emptySet();
         EgKey k = new EgKey(tenant, eg);
         return Collections.unmodifiableSet(policy.get().row(k).keySet());
     }
@@ -79,6 +80,7 @@ class PolicyCache {
      */
     protected Set<EgKey> getConsumersForProvider(TenantId tenant,
                                                  EndpointGroupId eg) {
+        if (policy.get() == null) return Collections.emptySet();
         EgKey k = new EgKey(tenant, eg);
         return Collections.unmodifiableSet(policy.get().column(k).keySet());
     }
@@ -97,14 +99,18 @@ class PolicyCache {
         
         for (Cell<EgKey, EgKey, Policy> cell : newPolicy.cellSet()) {
             Policy newp = cell.getValue();
-            Policy oldp = oldPolicy.get(cell.getRowKey(), cell.getColumnKey());
+            Policy oldp = null;
+            if (oldPolicy != null)
+                oldp = oldPolicy.get(cell.getRowKey(), cell.getColumnKey());
             if (oldp == null || !newp.equals(oldp)) {
                 notifySet.add(cell.getRowKey());
             }
         }
-        for (Cell<EgKey, EgKey, Policy> cell : oldPolicy.cellSet()) {
-            if (!newPolicy.contains(cell.getRowKey(), cell.getColumnKey())) {
-                notifySet.add(cell.getRowKey());
+        if (oldPolicy != null) {
+            for (Cell<EgKey, EgKey, Policy> cell : oldPolicy.cellSet()) {
+                if (!newPolicy.contains(cell.getRowKey(), cell.getColumnKey())) {
+                    notifySet.add(cell.getRowKey());
+                }
             }
         }
         return notifySet;
index b1b2293c09f6cbf792bd4151a0aaadb943b837e4..996f6446ba589138b1f2e5f69ec16df60c1400d0 100644 (file)
@@ -108,11 +108,11 @@ public class PolicyResolver implements AutoCloseable {
     /**
      *  Keep track of the current relevant policy scopes.
      */
-    private CopyOnWriteArrayList<PolicyScope> policyListenerScopes;
+    protected CopyOnWriteArrayList<PolicyScope> policyListenerScopes;
 
     protected ConcurrentMap<TenantId, TenantContext> resolvedTenants;
 
-    private PolicyCache policyCache = new PolicyCache();
+    protected PolicyCache policyCache = new PolicyCache();
 
     public PolicyResolver(DataBroker dataProvider,
                           ScheduledExecutorService executor) {
index e3f54b185e8cc5dc9e35be220e5ee0ed92b6c70c..be432fa3660cfecf3235f4316926077567917c26 100644 (file)
@@ -534,7 +534,7 @@ module policy {
             type gbp-common:description;
         }
 
-        list parameters {
+        list parameter {
             description 
                 "A parameter for the feature that can be 
                  passed in.";
@@ -621,7 +621,7 @@ module policy {
              MAY instead apply the parent subject feature and instead
              raise a nonfatal exception.";
 
-        config true;
+        config false;
 
         list classifier-definition {
             description
index 0c13cec734234fb26cb7c36ab26562374f008dea..1ab9e8d1f72d0b19e148a261a3d13a9d95250a8c 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay;
 
 import java.util.Set;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 
@@ -24,8 +25,10 @@ public class MockSwitchManager extends SwitchManager {
 
     public void addSwitch(NodeId node, 
                           NodeConnectorId tunnelPort,
-                          Set<NodeConnectorId> externalPorts) {
-        SwitchState state = new SwitchState(node, tunnelPort, externalPorts);
+                          Set<NodeConnectorId> externalPorts,
+                          OfOverlayNodeConfig nodeConfig) {
+        SwitchState state = new SwitchState(node, tunnelPort, 
+                                            externalPorts, nodeConfig);
         state.status = SwitchStatus.READY;
         switches.put(node, state);
         for (SwitchListener listener : listeners) {
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java
new file mode 100644 (file)
index 0000000..7c9bb6f
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import static org.junit.Assert.*;
+
+import static org.mockito.Matchers.*;
+
+import static org.mockito.Mockito.*;
+
+public class DestinationMapperTest extends FlowTableTest {
+    protected static final Logger LOG = 
+            LoggerFactory.getLogger(DestinationMapperTest.class);
+
+    NodeConnectorId tunnelId = 
+            new NodeConnectorId(nodeId.getValue() + ":42");
+    NodeConnectorId remoteTunnelId = 
+            new NodeConnectorId(remoteNodeId.getValue() + ":42");
+
+    @Before
+    public void setup() throws Exception {
+        initCtx();
+        table = new DestinationMapper(ctx);
+        super.setup();
+    }
+
+    @Test
+    public void testNoEps() throws Exception {
+        ReadWriteTransaction t = dosync(null);
+        verify(t, never()).put(any(LogicalDatastoreType.class), 
+                               any(InstanceIdentifier.class), 
+                               any(Flow.class));
+    }
+
+    private void verifyDMap(Endpoint remoteEp, 
+                          Endpoint localEp) throws Exception {
+
+        ReadWriteTransaction t = dosync(null);
+        ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
+        verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
+                      any(InstanceIdentifier.class), ac.capture());
+
+        int count = 0;
+        HashMap<String, FlowCtx> flowMap = new HashMap<>();
+        for (Flow f : ac.getAllValues()) {
+            flowMap.put(f.getId().getValue(), new FlowCtx(f));
+            if (Objects.equals(localEp.getMacAddress(),
+                               f.getMatch().getEthernetMatch()
+                                   .getEthernetDestination().getAddress())) {
+                int icount = 0;
+                for (Instruction ins : f.getInstructions().getInstruction()) {
+                    if (ins.getInstruction() instanceof WriteActionsCase) {
+                        assertEquals(FlowUtils.outputActionIns(nodeConnectorId),
+                                     ins.getInstruction());
+                        icount += 1;
+                    } else if (ins.getInstruction() instanceof GoToTableCase) {
+                        assertEquals(FlowUtils.gotoTableIns((short)(table.getTableId()+1)),
+                                     ins.getInstruction());
+                        icount += 1;
+                    }
+                }
+                assertEquals(2, icount);
+                LOG.info("{}", f);
+                count += 1;
+            } else if (Objects.equals(remoteEp.getMacAddress(),
+                                      f.getMatch().getEthernetMatch()
+                                      .getEthernetDestination().getAddress())) {
+                int icount = 0;
+                for (Instruction ins : f.getInstructions().getInstruction()) {
+                    if (ins.getInstruction() instanceof WriteActionsCase) {
+                        assertEquals(FlowUtils.outputActionIns(tunnelId),
+                                     ins.getInstruction());
+                        icount += 1;
+                    } else if (ins.getInstruction() instanceof GoToTableCase) {
+                        assertEquals(FlowUtils.gotoTableIns((short)(table.getTableId()+1)),
+                                     ins.getInstruction());
+                        icount += 1;
+                    }
+                }
+                assertEquals(2, icount);
+                LOG.info("{}", f);
+                count += 1;
+            } else if (Objects.equals(DestinationMapper.ROUTER_MAC, 
+                                      f.getMatch().getEthernetMatch()
+                                          .getEthernetDestination()
+                                          .getAddress())) {
+                if (f.getMatch().getLayer3Match() instanceof Ipv4Match) {
+                    // should be local port with rewrite dlsrc and dldst plus
+                    // ttl decr
+                    Instruction ins = f.getInstructions().getInstruction().get(0);
+                    assertTrue(ins.getInstruction() instanceof WriteActionsCase);
+                    List<Action> actions = 
+                            ((WriteActionsCase)ins.getInstruction()).getWriteActions().getAction();
+                    assertEquals(FlowUtils.setDlSrc(DestinationMapper.ROUTER_MAC),
+                                 actions.get(0).getAction());
+                    assertEquals(FlowUtils.setDlDst(localEp.getMacAddress()),
+                                 actions.get(1).getAction());
+                    assertEquals(FlowUtils.decNwTtl(),
+                                 actions.get(2).getAction());
+                    count += 1;
+                } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) {
+                    // should be remote port with rewrite dlsrc plus
+                    // ttl decr
+                    Instruction ins = f.getInstructions().getInstruction().get(0);
+                    assertTrue(ins.getInstruction() instanceof WriteActionsCase);
+                    List<Action> actions = 
+                            ((WriteActionsCase)ins.getInstruction()).getWriteActions().getAction();
+                    assertEquals(FlowUtils.setDlSrc(DestinationMapper.ROUTER_MAC),
+                                 actions.get(0).getAction());
+                    assertEquals(FlowUtils.decNwTtl(),
+                                 actions.get(1).getAction());
+                    count += 1;
+                }
+            }
+        }
+        assertEquals(4, count);
+
+        t = dosync(flowMap);
+        verify(t, never()).put(any(LogicalDatastoreType.class), 
+                               any(InstanceIdentifier.class), 
+                               any(Flow.class));
+    }
+    
+    @Override
+    protected EndpointBuilder localEP() {
+        return super.localEP()
+            .setL3Address(ImmutableList.of(new L3AddressBuilder()
+                .setL3Context(l3c)
+                .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1")))
+                .build()));
+    }
+    @Override
+    protected EndpointBuilder remoteEP(NodeId remoteNodeId) {
+        return super.remoteEP(remoteNodeId)
+            .setMacAddress(new MacAddress("00:00:00:00:00:02"))
+            .setL3Address(ImmutableList.of(new L3AddressBuilder()
+                .setL3Context(l3c)
+                .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0::10.0.0.2")))
+                .build()));
+    }
+   
+    private void addSwitches() {
+        switchManager.addSwitch(nodeId, tunnelId, 
+                                Collections.<NodeConnectorId>emptySet(),
+                                new OfOverlayNodeConfigBuilder()
+                                    .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
+                                    .build());
+        switchManager.addSwitch(remoteNodeId, remoteTunnelId, 
+                                Collections.<NodeConnectorId>emptySet(),
+                                new OfOverlayNodeConfigBuilder()
+                                    .setTunnelIp(new IpAddress(new Ipv6Address("::1:2:3:4")))
+                                    .build());
+    }
+    
+    @Test
+    public void testSame() throws Exception {
+        Endpoint localEp = localEP().build();
+        endpointManager.addEndpoint(localEp);
+        Endpoint remoteEp = remoteEP(remoteNodeId).build();
+        endpointManager.addEndpoint(remoteEp);
+        addSwitches();
+
+        policyResolver.addTenant(baseTenant().build());
+        verifyDMap(remoteEp, localEp);
+    }
+    
+    @Test
+    public void testDiff() throws Exception {
+        Endpoint localEp = localEP().build();
+        endpointManager.addEndpoint(localEp);
+        Endpoint remoteEp = remoteEP(remoteNodeId)
+            .setEndpointGroup(eg2)
+            .build();
+        endpointManager.addEndpoint(remoteEp);
+        addSwitches();
+
+        policyResolver.addTenant(baseTenant().build());
+        verifyDMap(remoteEp, localEp);
+    }
+   
+}
index 900dd66ae084c5313e0062f8fe6a0a1a2dc01cf0..c10e9de8d0ecca3f86bc6010e2238f3be0f815f1 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockEndpointManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockSwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.SubjectFeatures;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowTableCtx;
 import org.opendaylight.groupbasedpolicy.resolver.MockPolicyResolver;
@@ -22,21 +23,40 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubjectFeatureInstancesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -55,16 +75,22 @@ public class FlowTableTest {
     MockSwitchManager switchManager;
     
     NodeId nodeId = new NodeId("openflow:1");
+    NodeId remoteNodeId = new NodeId("openflow:2");
+    NodeConnectorId nodeConnectorId = 
+            new NodeConnectorId(nodeId.getValue() + ":1");
     InstanceIdentifier<Table> tiid;
     
     L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d");
     L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639");
     L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");
     SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");
+    SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");
     TenantId tid = new TenantId("1118c691-8520-47ad-80b8-4cf5e3fe3302");
     EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");
+    EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");
+    ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f");
     
-    public void initCtx() {
+    protected void initCtx() {
         endpointManager = new MockEndpointManager();
         policyResolver = new MockPolicyResolver();
         policyManager = new MockPolicyManager(policyResolver, endpointManager);
@@ -79,18 +105,30 @@ public class FlowTableTest {
                                null);
     }
     
-    public void setup() throws Exception {
+    protected void setup() throws Exception {
         tiid = FlowUtils.createTablePath(nodeId, 
                                          table.getTableId());
     }
 
-    public TenantBuilder baseTenant() {
+    protected TenantBuilder baseTenant() {
         return new TenantBuilder()
             .setId(tid)
             .setEndpointGroup(ImmutableList.of(new EndpointGroupBuilder()
-                .setId(eg)
-                .setNetworkDomain(sub)
-                .build()))
+                    .setId(eg)
+                    .setNetworkDomain(sub)
+                    .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder()
+                        .setName(new SelectorName("cns1"))
+                        .setContract(ImmutableList.of(cid))
+                        .build()))
+                    .build(),
+                new EndpointGroupBuilder()
+                    .setId(eg2)
+                    .setNetworkDomain(sub2)
+                    .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder()
+                        .setName(new SelectorName("pns1"))
+                        .setContract(ImmutableList.of(cid))
+                        .build()))
+                    .build()))
             .setL3Context(ImmutableList.of(new L3ContextBuilder()
                 .setId(l3c)
                 .build()))
@@ -103,26 +141,76 @@ public class FlowTableTest {
                 .setParent(bd)
                 .build()))
             .setSubnet(ImmutableList.of(new SubnetBuilder()
-                .setId(sub)
-                .setParent(fd)
-                .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.1/24")))
+                    .setId(sub2)
+                    .setParent(fd)
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.1/24")))
+                    .build(),
+                new SubnetBuilder()
+                    .setId(sub)
+                    .setParent(fd)
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.1/24")))
+                    .build()))
+            .setSubjectFeatureInstances(new SubjectFeatureInstancesBuilder()
+                .setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder()
+                     .setName(new ClassifierName("tcp_80"))
+                     .setClassifierDefinitionId(SubjectFeatures.TCP_PORT.getId())
+                     .setParameterValue(ImmutableList.of(new ParameterValueBuilder()
+                          .setName(new ParameterName("port"))
+                          .setIntValue(Long.valueOf(80))
+                          .build()))
+                     .build()))
+                .setActionInstance(ImmutableList.of(new ActionInstanceBuilder()
+                    .setName(new ActionName("allow"))
+                    .setActionDefinitionId(SubjectFeatures.ALLOW.getId())
+                    .build()))
+                .build())
+            .setContract(ImmutableList.of(new ContractBuilder()
+                .setId(cid)
+                .setSubject(ImmutableList.of(new SubjectBuilder()
+                    .setName(new SubjectName("s1"))
+                    .setRule(ImmutableList.of(new RuleBuilder()
+                         .setActionRef(ImmutableList.of(new ActionRefBuilder()
+                             .setName(new ActionName("allow"))
+                             .build()))
+                         .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder()
+                             .setName(new ClassifierName("tcp_80"))
+                             .build()))
+                         .build()))
+                    .build()))
+                .setClause(ImmutableList.of(new ClauseBuilder()
+                     .setName(new ClauseName("test"))
+                     .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
+                     .build()))
                 .build()));
     }
-
-    public EndpointBuilder baseEP() {
-        OfOverlayContext ofc = new OfOverlayContextBuilder()
-            .setNodeId(nodeId)
-            .setNodeConnectorId(new NodeConnectorId(nodeId.getValue() + ":1"))
-            .build();
+    
+    protected EndpointBuilder baseEP() {
         return new EndpointBuilder()
-            .addAugmentation(OfOverlayContext.class, ofc)
             .setL2Context(bd)
             .setTenant(tid)
             .setEndpointGroup(eg)
             .setMacAddress(new MacAddress("00:00:00:00:00:01"));
     }
+
+    protected EndpointBuilder localEP() {
+        OfOverlayContext ofc = new OfOverlayContextBuilder()
+            .setNodeId(nodeId)
+            .setNodeConnectorId(nodeConnectorId)
+            .build();
+        return baseEP()
+            .addAugmentation(OfOverlayContext.class, ofc);
+    }
+
+    protected EndpointBuilder remoteEP(NodeId id) {
+        OfOverlayContext ofc = new OfOverlayContextBuilder()
+            .setNodeId(id)
+            .setNodeConnectorId(new NodeConnectorId(id.getValue() + ":1"))
+            .build();
+        return baseEP()
+            .addAugmentation(OfOverlayContext.class, ofc);
+    }
     
-    public ReadWriteTransaction dosync(Map<String, FlowCtx> flowMap) 
+    protected ReadWriteTransaction dosync(Map<String, FlowCtx> flowMap) 
               throws Exception {
         ReadWriteTransaction t = mock(ReadWriteTransaction.class);
         if (flowMap == null)
index ad955003f025181c12731cb6375fa932c55a8ccf..72f53e72081b15f039fe8a8c3906d919861b675d 100644 (file)
@@ -74,9 +74,9 @@ public class PortSecurityTest extends FlowTableTest {
                         .getEthernetType().getType().getValue();
             }
             if (f.getMatch() == null ||
-                PortSecurity.ARP.equals(etherType) ||
-                PortSecurity.IPv4.equals(etherType) ||
-                PortSecurity.IPv6.equals(etherType)) {
+                FlowUtils.ARP.equals(etherType) ||
+                FlowUtils.IPv4.equals(etherType) ||
+                FlowUtils.IPv6.equals(etherType)) {
                 count += 1;
                 assertEquals(FlowUtils.dropInstructions(),
                              f.getInstructions());
@@ -94,7 +94,8 @@ public class PortSecurityTest extends FlowTableTest {
         switchManager
             .addSwitch(new NodeId("openflow:1"), 
                        new NodeConnectorId("openflow:1:1"), 
-                       ImmutableSet.of(new NodeConnectorId("openflow:1:2")));
+                       ImmutableSet.of(new NodeConnectorId("openflow:1:2")),
+                       null);
 
         ReadWriteTransaction t = dosync(null);
         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
@@ -124,7 +125,7 @@ public class PortSecurityTest extends FlowTableTest {
     @Test
     public void testL2() throws Exception {
         List<L3Address> l3 = Collections.emptyList();
-        Endpoint ep = baseEP()
+        Endpoint ep = localEP()
             .setL3Address(l3)
             .build();
        
@@ -161,7 +162,7 @@ public class PortSecurityTest extends FlowTableTest {
     
     @Test
     public void testL3() throws Exception {
-        Endpoint ep = baseEP()
+        Endpoint ep = localEP()
             .setL3Address(ImmutableList.of(new L3AddressBuilder()
                 .setIpAddress(new IpAddress(new Ipv4Address("10.10.10.10")))
                 .build(),
index 65fad8f76fc5c9143144b1d0c01cc35fb79f5fe7..ea4cbb9211c197a99e2a6f8b5eff05b918d6a2cd 100644 (file)
@@ -41,7 +41,7 @@ public class SourceMapperTest extends FlowTableTest {
     
     @Test
     public void testNoPolicy() throws Exception {
-        endpointManager.addEndpoint(baseEP().build());
+        endpointManager.addEndpoint(localEP().build());
         ReadWriteTransaction t = dosync(null);
         verify(t, never()).put(any(LogicalDatastoreType.class), 
                                any(InstanceIdentifier.class), 
@@ -50,7 +50,7 @@ public class SourceMapperTest extends FlowTableTest {
     
     @Test
     public void testMap() throws Exception {
-        Endpoint ep = baseEP().build();
+        Endpoint ep = localEP().build();
         endpointManager.addEndpoint(ep);
         policyResolver.addTenant(baseTenant().build());
         
@@ -64,7 +64,8 @@ public class SourceMapperTest extends FlowTableTest {
         for (Flow f : ac.getAllValues()) {
             flowMap.put(f.getId().getValue(), new FlowCtx(f));
             if (Objects.equals(ep.getMacAddress(),
-                               f.getMatch().getEthernetMatch().getEthernetSource().getAddress())) {
+                               f.getMatch().getEthernetMatch()
+                                   .getEthernetSource().getAddress())) {
                 // XXX TODO verify register setting in the instructions
                 LOG.info("{}", f);
                 count += 1;
index 108555af5b5a045e811b364716f29d349ee1e883..705d30cd8f6eedf36b47e95b474c13b541264902 100644 (file)
@@ -8,8 +8,11 @@
 
 package org.opendaylight.groupbasedpolicy.resolver;
 
+import org.opendaylight.groupbasedpolicy.resolver.PolicyCache.Policy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
 
+import com.google.common.collect.Table;
+
 
 /**
  * Mock version of policy resolver useful for tests
@@ -27,5 +30,7 @@ public class MockPolicyResolver extends PolicyResolver {
         IndexedTenant it = new IndexedTenant(t);
         context.tenant.set(it);
         resolvedTenants.put(unresolvedTenant.getId(), context);
+        Table<EgKey, EgKey, Policy> policy = resolvePolicy(t);
+        policyCache.updatePolicy(policy, policyListenerScopes);
     }
 }