Added fixed DHCP security rules, which will be added on a VM create.
[ovsdb.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / services / IngressAclService.java
index 33bf1f033c245b80baadcba966a4316e98973e46..9828a27fe6aeed9e70aaf0b7926f53cb14fc17ee 100644 (file)
@@ -12,11 +12,11 @@ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 import java.math.BigInteger;
 import java.util.List;
 
-import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
-import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
-import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
@@ -33,12 +33,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
 
-public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider {
+public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
 
     static final Logger logger = LoggerFactory.getLogger(IngressAclService.class);
 
@@ -51,7 +53,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
     }
 
     @Override
-    public void programPortSecurityACL(Node node, Long dpid, String segmentationId, String attachedMac,
+    public void programPortSecurityACL(Long dpid, String segmentationId, String attachedMac,
             long localPort, NeutronSecurityGroup securityGroup) {
 
         logger.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
@@ -206,6 +208,15 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         }
     }
 
+    @Override
+    public void programFixedSecurityACL(Long dpid, String segmentationId, String dhcpMacAddress,
+          long localPort, boolean isLastPortinSubnet, boolean isComputePort, boolean write){
+         //If this port is the only port in the compute node add the DHCP server rule.
+        if (isLastPortinSubnet && isComputePort ) {
+            ingressACLDHCPAllowServerTraffic(dpid, segmentationId,dhcpMacAddress, write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
+        }
+    }
+
     public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
             Integer securityRulePortMin, Integer protoPortMatchPriority) {
 
@@ -219,7 +230,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                                                               Constants.TCP_SYN, segmentationId).build());
 
         logger.debug("ingressACLTcpSyn MatchBuilder contains:  {}", flowBuilder.getMatch());
-        String flowId = "UcastOut_ACL2" + segmentationId + "_" + attachedMac + securityRulePortMin;
+        String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
         // Add Flow Attributes
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
@@ -368,7 +379,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                 attachedMac, Constants.TCP_SYN, segmentationId).build());
 
         logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
-        String flowId = "PortSec_TCP_Syn_Default_Drop_" + attachedMac;
+        String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
         flowBuilder.setStrict(false);
@@ -461,4 +472,66 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
             removeFlow(flowBuilder, nodeBuilder);
         }
     }
+
+    /**
+     * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
+     *
+     * @param dpidLong the dpid
+     * @param segmentationId the segmentation id
+     * @param dhcpMacAddress the DHCP server mac address
+     * @param write is write or delete
+     * @param protoPortMatchPriority the priority
+     */
+    private void ingressACLDHCPAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
+            boolean write, Integer protoPortMatchPriority) {
+
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createDHCPServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build());
+        logger.debug("ingressACLDHCPAllowServerTraffic: MatchBuilder contains: {}", flowBuilder.getMatch());
+        String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(this.getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+    @Override
+    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+        super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
+    }
+
+    @Override
+    public void setDependencies(Object impl) {
+
+    }
 }