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;
12 import com.google.common.collect.Lists;
14 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
15 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
18 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
19 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
20 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
21 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
22 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
23 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
24 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
25 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
26 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
39 import org.osgi.framework.BundleContext;
40 import org.osgi.framework.ServiceReference;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import java.math.BigInteger;
45 import java.util.List;
49 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
51 private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
52 private volatile SecurityServicesManager securityServicesManager;
53 private volatile SecurityGroupCacheManger securityGroupCacheManger;
54 private static final int PORT_RANGE_MIN = 1;
55 private static final int PORT_RANGE_MAX = 65535;
57 public IngressAclService() {
58 super(Service.INGRESS_ACL);
61 public IngressAclService(Service service) {
66 public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
67 long localPort, NeutronSecurityGroup securityGroup,
68 String portUuid, boolean write) {
70 LOG.trace("programPortSecurityGroup neutronSecurityGroup: {} ", securityGroup);
71 if (securityGroup == null || securityGroup.getSecurityRules() == null) {
75 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
76 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
77 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
80 * Neutron Port Security Acl "ingress" and "IPv4"
81 * Check that the base conditions for flow based Port Security are true:
82 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
83 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
84 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
88 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
89 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
90 LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
91 if (null != portSecurityRule.getSecurityRemoteGroupID()) {
92 //Remote Security group is selected
93 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
94 .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
95 if (null != remoteSrcAddressList) {
96 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
97 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
98 portSecurityRule, vmIp, write);
101 securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
103 securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
108 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
109 portSecurityRule, null, write);
112 securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
114 securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
121 public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
122 long localPort, NeutronSecurityRule portSecurityRule,
123 Neutron_IPs vmIp, boolean write) {
124 if (null == portSecurityRule.getSecurityRuleProtocol()) {
125 ingressAclIPv4(dpid, segmentationId, attachedMac,
126 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
128 String ipaddress = null;
130 ipaddress = vmIp.getIpAddress();
132 switch (portSecurityRule.getSecurityRuleProtocol()) {
134 LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
135 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
136 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
139 LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
140 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
141 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
143 case MatchUtils.ICMP:
144 LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
145 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
146 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
149 LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
150 "protocol = ", portSecurityRule.getSecurityRuleProtocol());
151 ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
152 null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
158 private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
159 NeutronSecurityRule portSecurityRule, String srcAddress,
160 boolean write, Integer protoPortMatchPriority) {
162 MatchBuilder matchBuilder = new MatchBuilder();
163 String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
164 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
167 Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
168 proto = protocol.shortValue();
169 flowId = flowId + proto;
170 } catch (NumberFormatException e) {
171 LOG.error("Protocol vlaue conversion failure", e);
173 matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
174 if (null != srcAddress) {
175 flowId = flowId + srcAddress;
176 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
177 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
178 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
179 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
180 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
181 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
183 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
184 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
185 flowId = flowId + "_Permit";
186 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
190 public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
191 long localPort, boolean isLastPortinSubnet,
192 boolean isComputePort, boolean write) {
193 //If this port is the only port in the compute node add the DHCP server rule.
194 if (isLastPortinSubnet && isComputePort ) {
195 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
196 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
201 * Allows IPv4 packet ingress to the destination mac address.
202 * @param dpidLong the dpid
203 * @param segmentationId the segementation id
204 * @param dstMac the destination mac address
205 * @param write add or remove
206 * @param protoPortMatchPriority the protocol match priority.
208 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
209 boolean write, Integer protoPortMatchPriority ) {
210 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
211 MatchBuilder matchBuilder = new MatchBuilder();
212 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
213 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
214 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
215 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
219 * Creates a ingress match to the dst macaddress. If src address is specified
220 * source specific match will be created. Otherwise a match with a CIDR will
222 * @param dpidLong the dpid
223 * @param segmentationId the segmentation id
224 * @param dstMac the destination mac address.
225 * @param portSecurityRule the security rule in the SG
226 * @param srcAddress the destination IP address
227 * @param write add or delete
228 * @param protoPortMatchPriority the protocol match priroty
230 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
231 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
232 Integer protoPortMatchPriority ) {
234 MatchBuilder matchBuilder = new MatchBuilder();
235 FlowBuilder flowBuilder = new FlowBuilder();
236 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
237 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
239 /* Custom TCP Match*/
240 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
241 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
242 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
243 portSecurityRule.getSecurityRulePortMin());
246 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
247 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
248 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
249 + portSecurityRule.getSecurityRulePortMax() + "_";
250 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
252 /*TODO TCP PortRange Match*/
256 if (null != srcAddress) {
257 flowId = flowId + srcAddress;
258 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
259 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
261 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
262 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
263 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
264 new Ipv4Prefix(portSecurityRule
265 .getSecurityRuleRemoteIpPrefix()),null);
267 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
268 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
269 flowId = flowId + "_Permit";
270 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
275 * Creates a ingress match to the dst macaddress. If src address is specified
276 * source specific match will be created. Otherwise a match with a CIDR will
278 * @param dpidLong the dpid
279 * @param segmentationId the segmentation id
280 * @param dstMac the destination mac address.
281 * @param portSecurityRule the security rule in the SG
282 * @param srcAddress the destination IP address
283 * @param write add or delete
284 * @param protoPortMatchPriority the protocol match priroty
286 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
287 NeutronSecurityRule portSecurityRule, String srcAddress,
288 boolean write, Integer protoPortMatchPriority ) {
289 MatchBuilder matchBuilder = new MatchBuilder();
290 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
291 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
293 /* Custom UDP Match */
294 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
295 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
296 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
297 portSecurityRule.getSecurityRulePortMin());
300 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
301 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
302 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
303 + portSecurityRule.getSecurityRulePortMax() + "_";
304 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
306 /*TODO TCP PortRange Match*/
310 if (null != srcAddress) {
311 flowId = flowId + srcAddress;
312 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
313 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
315 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
316 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
317 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
318 new Ipv4Prefix(portSecurityRule
319 .getSecurityRuleRemoteIpPrefix()),null);
321 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
322 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
323 flowId = flowId + "_Permit";
324 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
329 * Creates a ingress match to the dst macaddress. If src address is specified
330 * source specific match will be created. Otherwise a match with a CIDR will
332 * @param dpidLong the dpid
333 * @param segmentationId the segmentation id
334 * @param dstMac the destination mac address.
335 * @param portSecurityRule the security rule in the SG
336 * @param srcAddress the destination IP address
337 * @param write add or delete
338 * @param protoPortMatchPriority the protocol match priority
340 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
341 NeutronSecurityRule portSecurityRule, String srcAddress,
342 boolean write, Integer protoPortMatchPriority) {
344 MatchBuilder matchBuilder = new MatchBuilder();
345 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
346 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
348 /* Custom ICMP Match */
349 if (portSecurityRule.getSecurityRulePortMin() != null &&
350 portSecurityRule.getSecurityRulePortMax() != null) {
351 flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
352 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
353 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
354 portSecurityRule.getSecurityRulePortMin().shortValue(),
355 portSecurityRule.getSecurityRulePortMax().shortValue());
358 flowId = flowId + "all" + "_";
359 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
361 if (null != srcAddress) {
362 flowId = flowId + srcAddress;
363 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
364 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
365 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
366 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
367 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
368 new Ipv4Prefix(portSecurityRule
369 .getSecurityRuleRemoteIpPrefix()),null);
371 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
372 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
373 flowId = flowId + "_Permit";
374 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
378 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
379 Integer securityRulePortMin, Integer protoPortMatchPriority) {
381 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
382 PortNumber tcpPort = new PortNumber(securityRulePortMin);
383 MatchBuilder matchBuilder = new MatchBuilder();
384 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
385 FlowBuilder flowBuilder = new FlowBuilder();
387 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
388 Constants.TCP_SYN, segmentationId).build());
390 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
391 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
392 // Add Flow Attributes
393 flowBuilder.setId(new FlowId(flowId));
394 FlowKey key = new FlowKey(new FlowId(flowId));
395 flowBuilder.setStrict(false);
396 flowBuilder.setPriority(protoPortMatchPriority);
397 flowBuilder.setBarrier(true);
398 flowBuilder.setTableId(this.getTable());
399 flowBuilder.setKey(key);
400 flowBuilder.setFlowName(flowId);
401 flowBuilder.setHardTimeout(0);
402 flowBuilder.setIdleTimeout(0);
405 // Instantiate the Builders for the OF Actions and Instructions
406 InstructionsBuilder isb = new InstructionsBuilder();
407 List<Instruction> instructionsList = Lists.newArrayList();
409 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
411 ib.setKey(new InstructionKey(0));
412 instructionsList.add(ib.build());
413 isb.setInstruction(instructionsList);
415 LOG.debug("Instructions are: {}", ib.getInstruction());
416 // Add InstructionsBuilder to FlowBuilder
417 flowBuilder.setInstructions(isb.build());
418 writeFlow(flowBuilder, nodeBuilder);
420 removeFlow(flowBuilder, nodeBuilder);
424 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
425 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
426 Integer protoPortPrefixMatchPriority) {
428 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
429 PortNumber tcpPort = new PortNumber(securityRulePortMin);
431 MatchBuilder matchBuilder = new MatchBuilder();
432 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
433 FlowBuilder flowBuilder = new FlowBuilder();
434 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
436 flowBuilder.setMatch(MatchUtils
437 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
438 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
440 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
441 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
442 securityRulePortMin + securityRuleIpPrefix;
443 // Add Flow Attributes
444 flowBuilder.setId(new FlowId(flowId));
445 FlowKey key = new FlowKey(new FlowId(flowId));
446 flowBuilder.setStrict(false);
447 flowBuilder.setPriority(protoPortPrefixMatchPriority);
448 flowBuilder.setBarrier(true);
449 flowBuilder.setTableId(this.getTable());
450 flowBuilder.setKey(key);
451 flowBuilder.setFlowName(flowId);
452 flowBuilder.setHardTimeout(0);
453 flowBuilder.setIdleTimeout(0);
456 // Instantiate the Builders for the OF Actions and Instructions
457 InstructionsBuilder isb = new InstructionsBuilder();
459 List<Instruction> instructionsList = Lists.newArrayList();
460 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
462 ib.setKey(new InstructionKey(0));
463 instructionsList.add(ib.build());
464 isb.setInstruction(instructionsList);
466 LOG.debug("Instructions contain: {}", ib.getInstruction());
467 // Add InstructionsBuilder to FlowBuilder
468 flowBuilder.setInstructions(isb.build());
469 writeFlow(flowBuilder, nodeBuilder);
471 removeFlow(flowBuilder, nodeBuilder);
475 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
476 String securityRuleProtcol, Integer protoMatchPriority) {
478 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
480 MatchBuilder matchBuilder = new MatchBuilder();
481 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
482 FlowBuilder flowBuilder = new FlowBuilder();
484 flowBuilder.setMatch(MatchUtils
485 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
486 flowBuilder.setMatch(MatchUtils
487 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
488 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
490 String flowId = "UcastOut_" + segmentationId + "_" +
491 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
492 // Add Flow Attributes
493 flowBuilder.setId(new FlowId(flowId));
494 FlowKey key = new FlowKey(new FlowId(flowId));
495 flowBuilder.setStrict(false);
496 flowBuilder.setPriority(protoMatchPriority);
497 flowBuilder.setBarrier(true);
498 flowBuilder.setTableId(this.getTable());
499 flowBuilder.setKey(key);
500 flowBuilder.setFlowName(flowId);
501 flowBuilder.setHardTimeout(0);
502 flowBuilder.setIdleTimeout(0);
505 // Instantiate the Builders for the OF Actions and Instructions
506 InstructionsBuilder isb = new InstructionsBuilder();
507 List<Instruction> instructionsList = Lists.newArrayList();
509 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
511 ib.setKey(new InstructionKey(1));
512 instructionsList.add(ib.build());
513 isb.setInstruction(instructionsList);
514 LOG.debug("Instructions contain: {}", ib.getInstruction());
516 // Add InstructionsBuilder to FlowBuilder
517 flowBuilder.setInstructions(isb.build());
518 writeFlow(flowBuilder, nodeBuilder);
520 removeFlow(flowBuilder, nodeBuilder);
525 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
526 int priority, boolean write) {
528 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
529 MatchBuilder matchBuilder = new MatchBuilder();
530 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
531 FlowBuilder flowBuilder = new FlowBuilder();
533 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
534 attachedMac, Constants.TCP_SYN, segmentationId).build());
536 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
537 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
538 flowBuilder.setId(new FlowId(flowId));
539 FlowKey key = new FlowKey(new FlowId(flowId));
540 flowBuilder.setStrict(false);
541 flowBuilder.setPriority(priority);
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 InstructionBuilder ib = new InstructionBuilder();
552 InstructionsBuilder isb = new InstructionsBuilder();
554 // Instructions List Stores Individual Instructions
555 List<Instruction> instructions = Lists.newArrayList();
557 // Set the Output Port/Iface
558 InstructionUtils.createDropInstructions(ib);
560 ib.setKey(new InstructionKey(0));
561 instructions.add(ib.build());
563 // Add InstructionBuilder to the Instruction(s)Builder List
564 isb.setInstruction(instructions);
565 LOG.debug("Instructions contain: {}", ib.getInstruction());
566 // Add InstructionsBuilder to FlowBuilder
567 flowBuilder.setInstructions(isb.build());
568 writeFlow(flowBuilder, nodeBuilder);
570 removeFlow(flowBuilder, nodeBuilder);
574 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
575 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
576 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
577 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
578 MatchBuilder matchBuilder = new MatchBuilder();
579 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
580 FlowBuilder flowBuilder = new FlowBuilder();
582 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
584 if (securityRuleIpPrefix != null) {
585 flowBuilder.setMatch(MatchUtils
586 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
589 flowBuilder.setMatch(MatchUtils
590 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
594 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
595 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
596 attachedMac + "_Permit_" + securityRuleIpPrefix;
597 // Add Flow Attributes
598 flowBuilder.setId(new FlowId(flowId));
599 FlowKey key = new FlowKey(new FlowId(flowId));
600 flowBuilder.setStrict(false);
601 flowBuilder.setPriority(protoPortMatchPriority);
602 flowBuilder.setBarrier(true);
603 flowBuilder.setTableId(this.getTable());
604 flowBuilder.setKey(key);
605 flowBuilder.setFlowName(flowId);
606 flowBuilder.setHardTimeout(0);
607 flowBuilder.setIdleTimeout(0);
610 // Instantiate the Builders for the OF Actions and Instructions
611 InstructionBuilder ib = new InstructionBuilder();
612 InstructionsBuilder isb = new InstructionsBuilder();
613 List<Instruction> instructionsList = Lists.newArrayList();
615 ib = this.getMutablePipelineInstructionBuilder();
617 ib.setKey(new InstructionKey(0));
618 instructionsList.add(ib.build());
619 isb.setInstruction(instructionsList);
621 LOG.debug("Instructions contain: {}", ib.getInstruction());
622 // Add InstructionsBuilder to FlowBuilder
623 flowBuilder.setInstructions(isb.build());
624 writeFlow(flowBuilder, nodeBuilder);
626 removeFlow(flowBuilder, nodeBuilder);
631 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
633 * @param dpidLong the dpid
634 * @param segmentationId the segmentation id
635 * @param dhcpMacAddress the DHCP server mac address
636 * @param write is write or delete
637 * @param protoPortMatchPriority the priority
639 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
640 boolean write, Integer protoPortMatchPriority) {
642 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
643 MatchBuilder matchBuilder = new MatchBuilder();
644 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
645 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
646 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
647 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
648 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
652 * Add or remove flow to the node.
654 * @param flowId the the flow id
655 * @param nodeBuilder the node builder
656 * @param matchBuilder the matchbuilder
657 * @param protoPortMatchPriority the protocol priority
658 * @param write whether it is a write
659 * @param drop whether it is a drop or forward
661 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
662 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
663 boolean write,boolean drop) {
664 FlowBuilder flowBuilder = new FlowBuilder();
665 flowBuilder.setMatch(matchBuilder.build());
666 flowBuilder.setId(new FlowId(flowId));
667 FlowKey key = new FlowKey(new FlowId(flowId));
668 flowBuilder.setStrict(false);
669 flowBuilder.setPriority(protoPortMatchPriority);
670 flowBuilder.setBarrier(true);
671 flowBuilder.setTableId(this.getTable());
672 flowBuilder.setKey(key);
673 flowBuilder.setFlowName(flowId);
674 flowBuilder.setHardTimeout(0);
675 flowBuilder.setIdleTimeout(0);
678 // Instantiate the Builders for the OF Actions and Instructions
679 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
681 InstructionUtils.createDropInstructions(ib);
684 InstructionsBuilder isb = new InstructionsBuilder();
685 List<Instruction> instructionsList = Lists.newArrayList();
686 ib.setKey(new InstructionKey(0));
687 instructionsList.add(ib.build());
688 isb.setInstruction(instructionsList);
689 flowBuilder.setInstructions(isb.build());
690 writeFlow(flowBuilder, nodeBuilder);
692 removeFlow(flowBuilder, nodeBuilder);
698 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
699 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
700 securityServicesManager =
701 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
702 securityGroupCacheManger =
703 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
707 public void setDependencies(Object impl) {