2 * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
11 import java.math.BigInteger;
12 import java.util.List;
14 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
15 import org.opendaylight.neutron.spi.NeutronSecurityRule;
16 import org.opendaylight.neutron.spi.Neutron_IPs;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
21 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
22 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
23 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
24 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
25 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
38 import org.osgi.framework.BundleContext;
39 import org.osgi.framework.ServiceReference;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import com.google.common.collect.Lists;
45 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
47 private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
48 private volatile SecurityServicesManager securityServicesManager;
50 public IngressAclService() {
51 super(Service.INGRESS_ACL);
54 public IngressAclService(Service service) {
59 public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
60 long localPort, NeutronSecurityGroup securityGroup,
61 List<Neutron_IPs> srcAddressList, boolean write) {
63 LOG.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
64 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
65 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
66 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
68 * Neutron Port Security Acl "ingress" and "IPv4"
69 * Check that the base conditions for flow based Port Security are true:
70 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
71 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
72 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
76 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
77 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
78 LOG.debug("Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
79 if (null == portSecurityRule.getSecurityRuleProtocol()) {
80 ingressAclIPv4(dpid, segmentationId, attachedMac,
81 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
82 } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
83 //Remote Security group is selected
84 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
85 .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
86 if (null != remoteSrcAddressList) {
87 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
88 switch (portSecurityRule.getSecurityRuleProtocol()) {
90 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
91 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
94 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
95 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
98 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, vmIp.getIpAddress(),
99 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
102 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
109 switch (portSecurityRule.getSecurityRuleProtocol()) {
111 ingressAclTcp(dpid, segmentationId, attachedMac,
112 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
115 ingressAclUdp(dpid, segmentationId, attachedMac,
116 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
118 case MatchUtils.ICMP:
119 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
120 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
123 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
128 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
129 * TODO Some part of the code will be used when conntrack is supported
131 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
132 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
133 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
134 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
135 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
136 .equalsIgnoreCase("0.0.0.0/0"))) {
137 LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
138 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
139 portSecurityRule.getSecurityRulePortMax(),
140 portSecurityRule.getSecurityRuleRemoteIpPrefix());
141 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
142 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
144 ingressACLTcpPortWithPrefix(dpid, segmentationId,
145 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
146 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
150 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
152 /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
153 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
154 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
155 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
156 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
157 .equalsIgnoreCase("0.0.0.0/0"))) {
158 LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
159 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
160 portSecurityRule.getSecurityRulePortMax(),
161 portSecurityRule.getSecurityRuleRemoteIpPrefix());
162 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
163 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
165 ingressACLTcpPortWithPrefix(dpid, segmentationId,
166 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
167 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
171 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
173 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
174 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
175 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
176 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
177 LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
178 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
179 portSecurityRule.getSecurityRulePortMax(),
180 portSecurityRule.getSecurityRuleRemoteIpPrefix());
181 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
183 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
184 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
188 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
190 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
191 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
192 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
193 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
194 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
195 .equalsIgnoreCase("0.0.0.0/0"))) {
196 LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
197 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
198 portSecurityRule.getSecurityRulePortMax(),
199 portSecurityRule.getSecurityRuleRemoteIpPrefix());
200 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
201 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
202 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
206 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
208 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
209 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
210 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
211 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
212 LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
213 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
214 portSecurityRule.getSecurityRulePortMax(),
215 portSecurityRule.getSecurityRuleRemoteIpPrefix());
216 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
218 ingressACLTcpSyn(dpid, segmentationId,
219 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
220 Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
224 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
226 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
227 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
228 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
229 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
230 LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
231 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
232 portSecurityRule.getSecurityRulePortMax(),
233 portSecurityRule.getSecurityRuleRemoteIpPrefix());
234 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
235 Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
236 ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
237 portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
241 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
243 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
244 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
245 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
246 ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
247 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
248 .equalsIgnoreCase("0.0.0.0/0"))) {
249 LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
250 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
251 portSecurityRule.getSecurityRulePortMax(),
252 portSecurityRule.getSecurityRuleRemoteIpPrefix());
253 // No need to drop until UDP/ICMP are implemented
254 // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
255 handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
256 portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
259 LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
265 public void programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
266 long localPort, boolean isLastPortinSubnet,
267 boolean isComputePort, boolean write) {
268 //If this port is the only port in the compute node add the DHCP server rule.
269 if (isLastPortinSubnet && isComputePort ) {
270 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
271 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
276 * Allows IPv4 packet ingress to the destination mac address.
277 * @param dpidLong the dpid
278 * @param segmentationId the segementation id
279 * @param dstMac the destination mac address
280 * @param write add or remove
281 * @param protoPortMatchPriority the protocol match priority.
283 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
284 boolean write, Integer protoPortMatchPriority ) {
285 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
286 MatchBuilder matchBuilder = new MatchBuilder();
287 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
288 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
289 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
290 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
294 * Creates a ingress match to the dst macaddress. If src address is specified
295 * source specific match will be created. Otherwise a match with a CIDR will
297 * @param dpidLong the dpid
298 * @param segmentationId the segmentation id
299 * @param dstMac the destination mac address.
300 * @param portSecurityRule the security rule in the SG
301 * @param srcAddress the destination IP address
302 * @param write add or delete
303 * @param protoPortMatchPriority the protocol match priroty
305 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
306 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
307 Integer protoPortMatchPriority ) {
309 MatchBuilder matchBuilder = new MatchBuilder();
310 FlowBuilder flowBuilder = new FlowBuilder();
311 String flowId = "Ingress_Custom_Tcp" + segmentationId + "_" + dstMac + "_";
312 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
313 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
314 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
315 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
316 portSecurityRule.getSecurityRulePortMin());
318 /*TODO TCP PortRange Match*/
322 if (null != srcAddress) {
323 flowId = flowId + srcAddress;
324 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
325 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
327 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
328 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
329 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
330 new Ipv4Prefix(portSecurityRule
331 .getSecurityRuleRemoteIpPrefix()),null);
333 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
334 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
335 flowId = flowId + "_Permit_";
336 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
341 * Creates a ingress match to the dst macaddress. If src address is specified
342 * source specific match will be created. Otherwise a match with a CIDR will
344 * @param dpidLong the dpid
345 * @param segmentationId the segmentation id
346 * @param dstMac the destination mac address.
347 * @param portSecurityRule the security rule in the SG
348 * @param srcAddress the destination IP address
349 * @param write add or delete
350 * @param protoPortMatchPriority the protocol match priroty
352 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
353 NeutronSecurityRule portSecurityRule, String srcAddress,
354 boolean write, Integer protoPortMatchPriority ) {
355 MatchBuilder matchBuilder = new MatchBuilder();
356 String flowId = "ingressAclUDP" + segmentationId + "_" + dstMac + "_";
357 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
358 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
359 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
360 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
361 portSecurityRule.getSecurityRulePortMin());
363 /*TODO TCP PortRange Match*/
367 if (null != srcAddress) {
368 flowId = flowId + srcAddress;
369 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
370 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
372 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
373 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
374 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
375 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
377 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
378 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
379 flowId = flowId + "_Permit_";
380 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
385 * Creates a ingress match to the dst macaddress. If src address is specified
386 * source specific match will be created. Otherwise a match with a CIDR will
388 * @param dpidLong the dpid
389 * @param segmentationId the segmentation id
390 * @param dstMac the destination mac address.
391 * @param portSecurityRule the security rule in the SG
392 * @param srcAddress the destination IP address
393 * @param write add or delete
394 * @param protoPortMatchPriority the protocol match priority
396 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
397 NeutronSecurityRule portSecurityRule, String srcAddress,
398 boolean write, Integer protoPortMatchPriority) {
400 MatchBuilder matchBuilder = new MatchBuilder();
401 FlowBuilder flowBuilder = new FlowBuilder();
402 String flowId = "ingressAclICMP" + segmentationId + "_" + dstMac;
403 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
404 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
405 portSecurityRule.getSecurityRulePortMin().shortValue(),
406 portSecurityRule.getSecurityRulePortMax().shortValue());
407 if (null != srcAddress) {
408 flowId = flowId + srcAddress;
409 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
410 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
412 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
413 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
414 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
415 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
417 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
418 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
419 flowId = flowId + "_Permit_";
420 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
423 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
424 Integer securityRulePortMin, Integer protoPortMatchPriority) {
426 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
427 PortNumber tcpPort = new PortNumber(securityRulePortMin);
428 MatchBuilder matchBuilder = new MatchBuilder();
429 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
430 FlowBuilder flowBuilder = new FlowBuilder();
432 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
433 Constants.TCP_SYN, segmentationId).build());
435 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
436 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
437 // Add Flow Attributes
438 flowBuilder.setId(new FlowId(flowId));
439 FlowKey key = new FlowKey(new FlowId(flowId));
440 flowBuilder.setStrict(false);
441 flowBuilder.setPriority(protoPortMatchPriority);
442 flowBuilder.setBarrier(true);
443 flowBuilder.setTableId(this.getTable());
444 flowBuilder.setKey(key);
445 flowBuilder.setFlowName(flowId);
446 flowBuilder.setHardTimeout(0);
447 flowBuilder.setIdleTimeout(0);
450 // Instantiate the Builders for the OF Actions and Instructions
451 InstructionsBuilder isb = new InstructionsBuilder();
452 List<Instruction> instructionsList = Lists.newArrayList();
454 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
456 ib.setKey(new InstructionKey(0));
457 instructionsList.add(ib.build());
458 isb.setInstruction(instructionsList);
460 LOG.debug("Instructions are: {}", ib.getInstruction());
461 // Add InstructionsBuilder to FlowBuilder
462 flowBuilder.setInstructions(isb.build());
463 writeFlow(flowBuilder, nodeBuilder);
465 removeFlow(flowBuilder, nodeBuilder);
469 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
470 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
471 Integer protoPortPrefixMatchPriority) {
473 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
474 PortNumber tcpPort = new PortNumber(securityRulePortMin);
476 MatchBuilder matchBuilder = new MatchBuilder();
477 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
478 FlowBuilder flowBuilder = new FlowBuilder();
479 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
481 flowBuilder.setMatch(MatchUtils
482 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
483 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
485 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
486 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
487 securityRulePortMin + securityRuleIpPrefix;
488 // Add Flow Attributes
489 flowBuilder.setId(new FlowId(flowId));
490 FlowKey key = new FlowKey(new FlowId(flowId));
491 flowBuilder.setStrict(false);
492 flowBuilder.setPriority(protoPortPrefixMatchPriority);
493 flowBuilder.setBarrier(true);
494 flowBuilder.setTableId(this.getTable());
495 flowBuilder.setKey(key);
496 flowBuilder.setFlowName(flowId);
497 flowBuilder.setHardTimeout(0);
498 flowBuilder.setIdleTimeout(0);
501 // Instantiate the Builders for the OF Actions and Instructions
502 InstructionsBuilder isb = new InstructionsBuilder();
504 List<Instruction> instructionsList = Lists.newArrayList();
505 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
507 ib.setKey(new InstructionKey(0));
508 instructionsList.add(ib.build());
509 isb.setInstruction(instructionsList);
511 LOG.debug("Instructions contain: {}", ib.getInstruction());
512 // Add InstructionsBuilder to FlowBuilder
513 flowBuilder.setInstructions(isb.build());
514 writeFlow(flowBuilder, nodeBuilder);
516 removeFlow(flowBuilder, nodeBuilder);
520 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
521 String securityRuleProtcol, Integer protoMatchPriority) {
523 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
525 MatchBuilder matchBuilder = new MatchBuilder();
526 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
527 FlowBuilder flowBuilder = new FlowBuilder();
529 flowBuilder.setMatch(MatchUtils
530 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
531 flowBuilder.setMatch(MatchUtils
532 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
533 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
535 String flowId = "UcastOut_" + segmentationId + "_" +
536 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
537 // Add Flow Attributes
538 flowBuilder.setId(new FlowId(flowId));
539 FlowKey key = new FlowKey(new FlowId(flowId));
540 flowBuilder.setStrict(false);
541 flowBuilder.setPriority(protoMatchPriority);
542 flowBuilder.setBarrier(true);
543 flowBuilder.setTableId(this.getTable());
544 flowBuilder.setKey(key);
545 flowBuilder.setFlowName(flowId);
546 flowBuilder.setHardTimeout(0);
547 flowBuilder.setIdleTimeout(0);
550 // Instantiate the Builders for the OF Actions and Instructions
551 InstructionsBuilder isb = new InstructionsBuilder();
552 List<Instruction> instructionsList = Lists.newArrayList();
554 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
556 ib.setKey(new InstructionKey(1));
557 instructionsList.add(ib.build());
558 isb.setInstruction(instructionsList);
559 LOG.debug("Instructions contain: {}", ib.getInstruction());
561 // Add InstructionsBuilder to FlowBuilder
562 flowBuilder.setInstructions(isb.build());
563 writeFlow(flowBuilder, nodeBuilder);
565 removeFlow(flowBuilder, nodeBuilder);
570 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
571 int priority, boolean write) {
573 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
574 MatchBuilder matchBuilder = new MatchBuilder();
575 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
576 FlowBuilder flowBuilder = new FlowBuilder();
578 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
579 attachedMac, Constants.TCP_SYN, segmentationId).build());
581 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
582 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
583 flowBuilder.setId(new FlowId(flowId));
584 FlowKey key = new FlowKey(new FlowId(flowId));
585 flowBuilder.setStrict(false);
586 flowBuilder.setPriority(priority);
587 flowBuilder.setBarrier(true);
588 flowBuilder.setTableId(this.getTable());
589 flowBuilder.setKey(key);
590 flowBuilder.setFlowName(flowId);
591 flowBuilder.setHardTimeout(0);
592 flowBuilder.setIdleTimeout(0);
595 // Instantiate the Builders for the OF Actions and Instructions
596 InstructionBuilder ib = new InstructionBuilder();
597 InstructionsBuilder isb = new InstructionsBuilder();
599 // Instructions List Stores Individual Instructions
600 List<Instruction> instructions = Lists.newArrayList();
602 // Set the Output Port/Iface
603 InstructionUtils.createDropInstructions(ib);
605 ib.setKey(new InstructionKey(0));
606 instructions.add(ib.build());
608 // Add InstructionBuilder to the Instruction(s)Builder List
609 isb.setInstruction(instructions);
610 LOG.debug("Instructions contain: {}", ib.getInstruction());
611 // Add InstructionsBuilder to FlowBuilder
612 flowBuilder.setInstructions(isb.build());
613 writeFlow(flowBuilder, nodeBuilder);
615 removeFlow(flowBuilder, nodeBuilder);
619 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
620 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
621 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
622 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
623 MatchBuilder matchBuilder = new MatchBuilder();
624 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
625 FlowBuilder flowBuilder = new FlowBuilder();
627 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
629 if (securityRuleIpPrefix != null) {
630 flowBuilder.setMatch(MatchUtils
631 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
634 flowBuilder.setMatch(MatchUtils
635 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
639 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
640 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
641 attachedMac + "_Permit_" + securityRuleIpPrefix;
642 // Add Flow Attributes
643 flowBuilder.setId(new FlowId(flowId));
644 FlowKey key = new FlowKey(new FlowId(flowId));
645 flowBuilder.setStrict(false);
646 flowBuilder.setPriority(protoPortMatchPriority);
647 flowBuilder.setBarrier(true);
648 flowBuilder.setTableId(this.getTable());
649 flowBuilder.setKey(key);
650 flowBuilder.setFlowName(flowId);
651 flowBuilder.setHardTimeout(0);
652 flowBuilder.setIdleTimeout(0);
655 // Instantiate the Builders for the OF Actions and Instructions
656 InstructionBuilder ib = new InstructionBuilder();
657 InstructionsBuilder isb = new InstructionsBuilder();
658 List<Instruction> instructionsList = Lists.newArrayList();
660 ib = this.getMutablePipelineInstructionBuilder();
662 ib.setKey(new InstructionKey(0));
663 instructionsList.add(ib.build());
664 isb.setInstruction(instructionsList);
666 LOG.debug("Instructions contain: {}", ib.getInstruction());
667 // Add InstructionsBuilder to FlowBuilder
668 flowBuilder.setInstructions(isb.build());
669 writeFlow(flowBuilder, nodeBuilder);
671 removeFlow(flowBuilder, nodeBuilder);
676 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
678 * @param dpidLong the dpid
679 * @param segmentationId the segmentation id
680 * @param dhcpMacAddress the DHCP server mac address
681 * @param write is write or delete
682 * @param protoPortMatchPriority the priority
684 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
685 boolean write, Integer protoPortMatchPriority) {
687 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
688 MatchBuilder matchBuilder = new MatchBuilder();
689 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
690 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
691 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
692 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
693 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
697 * Add or remove flow to the node.
699 * @param flowId the the flow id
700 * @param nodeBuilder the node builder
701 * @param matchBuilder the matchbuilder
702 * @param protoPortMatchPriority the protocol priority
703 * @param write whether it is a write
704 * @param drop whether it is a drop or forward
706 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
707 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
708 boolean write,boolean drop) {
709 FlowBuilder flowBuilder = new FlowBuilder();
710 flowBuilder.setMatch(matchBuilder.build());
711 flowBuilder.setId(new FlowId(flowId));
712 FlowKey key = new FlowKey(new FlowId(flowId));
713 flowBuilder.setStrict(false);
714 flowBuilder.setPriority(protoPortMatchPriority);
715 flowBuilder.setBarrier(true);
716 flowBuilder.setTableId(this.getTable());
717 flowBuilder.setKey(key);
718 flowBuilder.setFlowName(flowId);
719 flowBuilder.setHardTimeout(0);
720 flowBuilder.setIdleTimeout(0);
723 // Instantiate the Builders for the OF Actions and Instructions
724 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
726 InstructionUtils.createDropInstructions(ib);
729 InstructionsBuilder isb = new InstructionsBuilder();
730 List<Instruction> instructionsList = Lists.newArrayList();
731 ib.setKey(new InstructionKey(0));
732 instructionsList.add(ib.build());
733 isb.setInstruction(instructionsList);
734 flowBuilder.setInstructions(isb.build());
735 writeFlow(flowBuilder, nodeBuilder);
737 removeFlow(flowBuilder, nodeBuilder);
743 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
744 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
745 securityServicesManager =
746 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
750 public void setDependencies(Object impl) {