/*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (c) 2014, 2015 Red Hat, 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
- *
- * Authors : Madhu Venugopal
*/
+
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.neutron.spi.Neutron_IPs;
import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+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;
import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
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.PortNumber;
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.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);
+ private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
+ private volatile SecurityServicesManager securityServicesManager;
public IngressAclService() {
super(Service.INGRESS_ACL);
}
@Override
- public boolean isBridgeInPipeline(String nodeId) {
- return true;
- }
+ public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+ long localPort, NeutronSecurityGroup securityGroup,
+ List<Neutron_IPs> srcAddressList, boolean write) {
- @Override
- public void programPortSecurityACL(Node node, Long dpid, String segmentationId, String attachedMac,
- long localPort, NeutronSecurityGroup securityGroup) {
+ LOG.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
+ if (securityGroup == null || securityGroup.getSecurityRules() == null) {
+ return;
+ }
- logger.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
/* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
for (NeutronSecurityRule portSecurityRule : portSecurityList) {
/**
- * Neutron Port Security ACL "ingress" and "IPv4"
- *
+ * Neutron Port Security Acl "ingress" and "IPv4"
* Check that the base conditions for flow based Port Security are true:
* Port Security Rule Direction ("ingress") and Protocol ("IPv4")
* Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
* http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
*
*/
- if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
- portSecurityRule.getSecurityRuleDirection().equalsIgnoreCase("ingress")) {
- logger.debug("ACL Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+
+ if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
+ && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
+ LOG.debug("Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+ if (null == portSecurityRule.getSecurityRuleProtocol()) {
+ ingressAclIPv4(dpid, segmentationId, attachedMac,
+ write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
+ //Remote Security group is selected
+ List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
+ .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
+ if (null != remoteSrcAddressList) {
+ for (Neutron_IPs vmIp :remoteSrcAddressList ) {
+ switch (portSecurityRule.getSecurityRuleProtocol()) {
+ case MatchUtils.TCP:
+ ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
+ write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ case MatchUtils.UDP:
+ ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
+ write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ case MatchUtils.ICMP:
+ ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, vmIp.getIpAddress(),
+ write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ default:
+ LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
+ break;
+ }
+ }
+ }
+ } else {
+ //CIDR is selected
+ switch (portSecurityRule.getSecurityRuleProtocol()) {
+ case MatchUtils.TCP:
+ ingressAclTcp(dpid, segmentationId, attachedMac,
+ portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ case MatchUtils.UDP:
+ ingressAclUdp(dpid, segmentationId, attachedMac,
+ portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ case MatchUtils.ICMP:
+ ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
+ write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+ break;
+ default:
+ LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
+ }
+ }
+
/**
* TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
- */
+ * TODO Some part of the code will be used when conntrack is supported
+
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
(!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
.equalsIgnoreCase("0.0.0.0/0"))) {
- logger.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
/**
* TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
*/
- if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+ /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
(!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
.equalsIgnoreCase("0.0.0.0/0"))) {
- logger.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
continue;
}
- /**
+ *//**
* TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
- */
+ *//*
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
- logger.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
continue;
}
- /**
- * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
- */
+ *//**
+ * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+ *//*
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
(!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
.equalsIgnoreCase("0.0.0.0/0"))) {
- logger.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
continue;
}
- /**
- * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
- */
+ *//**
+ * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
+ *//*
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
- logger.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
continue;
}
- /**
- * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
- */
+ *//**
+ * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
+ *//*
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
!String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
- logger.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
continue;
}
- /**
- * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
- */
+ *//**
+ * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
+ *//*
if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
.equalsIgnoreCase("0.0.0.0/0"))) {
- logger.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+ LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
portSecurityRule.getSecurityRulePortMax(),
portSecurityRule.getSecurityRuleRemoteIpPrefix());
handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
continue;
- }
- logger.debug("Ingress ACL Match combination not found for rule: {}", portSecurityRule);
+ }*/
+ LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
}
}
}
+ @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);
+ }
+ }
+
+ /**
+ * Allows IPv4 packet ingress to the destination mac address.
+ * @param dpidLong the dpid
+ * @param segmentationId the segementation id
+ * @param dstMac the destination mac address
+ * @param write add or remove
+ * @param protoPortMatchPriority the protocol match priority.
+ */
+ private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
+ boolean write, Integer protoPortMatchPriority ) {
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ MatchBuilder matchBuilder = new MatchBuilder();
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+ }
+ /**
+ * Creates a ingress match to the dst macaddress. If src address is specified
+ * source specific match will be created. Otherwise a match with a CIDR will
+ * be created.
+ * @param dpidLong the dpid
+ * @param segmentationId the segmentation id
+ * @param dstMac the destination mac address.
+ * @param portSecurityRule the security rule in the SG
+ * @param srcAddress the destination IP address
+ * @param write add or delete
+ * @param protoPortMatchPriority the protocol match priroty
+ */
+ private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
+ NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
+ Integer protoPortMatchPriority ) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ FlowBuilder flowBuilder = new FlowBuilder();
+ String flowId = "Ingress_Custom_Tcp" + segmentationId + "_" + dstMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+ matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
+ portSecurityRule.getSecurityRulePortMin());
+ } else {
+ /*TODO TCP PortRange Match*/
+
+ }
+
+ if (null != srcAddress) {
+ flowId = flowId + srcAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
+
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ new Ipv4Prefix(portSecurityRule
+ .getSecurityRuleRemoteIpPrefix()),null);
+ }
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ flowId = flowId + "_Permit_";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+ }
+
+ /**
+ * Creates a ingress match to the dst macaddress. If src address is specified
+ * source specific match will be created. Otherwise a match with a CIDR will
+ * be created.
+ * @param dpidLong the dpid
+ * @param segmentationId the segmentation id
+ * @param dstMac the destination mac address.
+ * @param portSecurityRule the security rule in the SG
+ * @param srcAddress the destination IP address
+ * @param write add or delete
+ * @param protoPortMatchPriority the protocol match priroty
+ */
+ private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
+ NeutronSecurityRule portSecurityRule, String srcAddress,
+ boolean write, Integer protoPortMatchPriority ) {
+ MatchBuilder matchBuilder = new MatchBuilder();
+ String flowId = "ingressAclUDP" + segmentationId + "_" + dstMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+ matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
+ portSecurityRule.getSecurityRulePortMin());
+ } else {
+ /*TODO TCP PortRange Match*/
+
+ }
+
+ if (null != srcAddress) {
+ flowId = flowId + srcAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+ }
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ flowId = flowId + "_Permit_";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+ }
+
+ /**
+ * Creates a ingress match to the dst macaddress. If src address is specified
+ * source specific match will be created. Otherwise a match with a CIDR will
+ * be created.
+ * @param dpidLong the dpid
+ * @param segmentationId the segmentation id
+ * @param dstMac the destination mac address.
+ * @param portSecurityRule the security rule in the SG
+ * @param srcAddress the destination IP address
+ * @param write add or delete
+ * @param protoPortMatchPriority the protocol match priority
+ */
+ private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
+ NeutronSecurityRule portSecurityRule, String srcAddress,
+ boolean write, Integer protoPortMatchPriority) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ FlowBuilder flowBuilder = new FlowBuilder();
+ String flowId = "ingressAclICMP" + segmentationId + "_" + dstMac;
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+ portSecurityRule.getSecurityRulePortMin().shortValue(),
+ portSecurityRule.getSecurityRulePortMax().shortValue());
+ if (null != srcAddress) {
+ flowId = flowId + srcAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+ }
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ flowId = flowId + "_Permit_";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
- Integer securityRulePortMin, Integer protoPortMatchPriority) {
+ Integer securityRulePortMin, Integer protoPortMatchPriority) {
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
PortNumber tcpPort = new PortNumber(securityRulePortMin);
flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
Constants.TCP_SYN, segmentationId).build());
- logger.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
- String flowId = "UcastOut_ACL2" + segmentationId + "_" + attachedMac + securityRulePortMin;
+ LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
+ String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
// Add Flow Attributes
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
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();
+ InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
ib.setOrder(0);
ib.setKey(new InstructionKey(0));
instructionsList.add(ib.build());
isb.setInstruction(instructionsList);
- logger.debug("Instructions are: {}", ib.getInstruction());
+ LOG.debug("Instructions are: {}", ib.getInstruction());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
writeFlow(flowBuilder, nodeBuilder);
}
public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
- boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
- Integer protoPortPrefixMatchPriority) {
+ boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
+ Integer protoPortPrefixMatchPriority) {
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
PortNumber tcpPort = new PortNumber(securityRulePortMin);
Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
flowBuilder.setMatch(MatchUtils
- .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
- tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
+ .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
+ tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
- logger.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
+ LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
securityRulePortMin + securityRuleIpPrefix;
// Add Flow Attributes
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();
+ InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
ib.setOrder(0);
ib.setKey(new InstructionKey(0));
instructionsList.add(ib.build());
isb.setInstruction(instructionsList);
- logger.debug("Instructions contain: {}", ib.getInstruction());
+ LOG.debug("Instructions contain: {}", ib.getInstruction());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
writeFlow(flowBuilder, nodeBuilder);
}
public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
- String securityRuleProtcol, Integer protoMatchPriority) {
+ String securityRuleProtcol, Integer protoMatchPriority) {
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setMatch(MatchUtils
- .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
+ .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
flowBuilder.setMatch(MatchUtils
- .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
- logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+ .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+ LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
String flowId = "UcastOut_" + segmentationId + "_" +
attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
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();
+ InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
ib.setOrder(1);
ib.setKey(new InstructionKey(1));
instructionsList.add(ib.build());
isb.setInstruction(instructionsList);
- logger.debug("Instructions contain: {}", ib.getInstruction());
+ LOG.debug("Instructions contain: {}", ib.getInstruction());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
- int priority, boolean write) {
+ int priority, boolean write) {
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
MatchBuilder matchBuilder = new MatchBuilder();
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
- attachedMac, Constants.TCP_SYN, segmentationId).build());
+ attachedMac, Constants.TCP_SYN, segmentationId).build());
- logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
- String flowId = "PortSec_TCP_Syn_Default_Drop_" + attachedMac;
+ LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+ String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setStrict(false);
// Add InstructionBuilder to the Instruction(s)Builder List
isb.setInstruction(instructions);
- logger.debug("Instructions contain: {}", ib.getInstruction());
+ LOG.debug("Instructions contain: {}", ib.getInstruction());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
writeFlow(flowBuilder, nodeBuilder);
}
public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
- boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
-
+ boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
MatchBuilder matchBuilder = new MatchBuilder();
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
- .build());
+ .build());
if (securityRuleIpPrefix != null) {
flowBuilder.setMatch(MatchUtils
- .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
- .build());
+ .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
+ .build());
} else {
flowBuilder.setMatch(MatchUtils
- .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
- .build());
+ .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
+ .build());
}
- logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+ LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
String flowId = "IngressProto_ACL_" + segmentationId + "_" +
attachedMac + "_Permit_" + securityRuleIpPrefix;
// Add Flow Attributes
instructionsList.add(ib.build());
isb.setInstruction(instructionsList);
- logger.debug("Instructions contain: {}", ib.getInstruction());
+ LOG.debug("Instructions contain: {}", ib.getInstruction());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
writeFlow(flowBuilder, nodeBuilder);
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);
+ MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
+ LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
+ String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
+ /**
+ * Add or remove flow to the node.
+ *
+ * @param flowId the the flow id
+ * @param nodeBuilder the node builder
+ * @param matchBuilder the matchbuilder
+ * @param protoPortMatchPriority the protocol priority
+ * @param write whether it is a write
+ * @param drop whether it is a drop or forward
+ */
+ private void syncFlow(String flowId, NodeBuilder nodeBuilder,
+ MatchBuilder matchBuilder,Integer protoPortMatchPriority,
+ boolean write,boolean drop) {
+ FlowBuilder flowBuilder = new FlowBuilder();
+ flowBuilder.setMatch(matchBuilder.build());
+ 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 = this.getMutablePipelineInstructionBuilder();
+ if (drop) {
+ InstructionUtils.createDropInstructions(ib);
+ }
+ ib.setOrder(0);
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructionsList = Lists.newArrayList();
+ ib.setKey(new InstructionKey(0));
+ instructionsList.add(ib.build());
+ isb.setInstruction(instructionsList);
+ 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);
+ securityServicesManager =
+ (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+ }
+
+ @Override
+ public void setDependencies(Object impl) {
+
+ }
}