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 (portSecurityRule == null ||
89 portSecurityRule.getSecurityRuleEthertype() == null ||
90 portSecurityRule.getSecurityRuleDirection() == null) {
94 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
95 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
96 LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
97 if (null != portSecurityRule.getSecurityRemoteGroupID()) {
98 //Remote Security group is selected
99 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
100 .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
101 if (null != remoteSrcAddressList) {
102 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
103 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
104 portSecurityRule, vmIp, write);
107 securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
109 securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
114 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
115 portSecurityRule, null, write);
118 securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
120 securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
130 public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
131 long localPort, NeutronSecurityRule portSecurityRule,
132 Neutron_IPs vmIp, boolean write) {
133 if (null == portSecurityRule.getSecurityRuleProtocol()) {
134 ingressAclIPv4(dpid, segmentationId, attachedMac,
135 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
137 String ipaddress = null;
139 ipaddress = vmIp.getIpAddress();
141 switch (portSecurityRule.getSecurityRuleProtocol()) {
143 LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
144 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
145 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
148 LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
149 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
150 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
152 case MatchUtils.ICMP:
153 LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
154 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
155 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
158 LOG.error("programPortSecurityRule: Protocol not supported", portSecurityRule);
165 public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
166 long localPort, boolean isLastPortinSubnet,
167 boolean isComputePort, boolean write) {
168 //If this port is the only port in the compute node add the DHCP server rule.
169 if (isLastPortinSubnet && isComputePort ) {
170 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
171 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
176 * Allows IPv4 packet ingress to the destination mac address.
177 * @param dpidLong the dpid
178 * @param segmentationId the segementation id
179 * @param dstMac the destination mac address
180 * @param write add or remove
181 * @param protoPortMatchPriority the protocol match priority.
183 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
184 boolean write, Integer protoPortMatchPriority ) {
185 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
186 MatchBuilder matchBuilder = new MatchBuilder();
187 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
188 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
189 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
190 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
194 * Creates a ingress match to the dst macaddress. If src address is specified
195 * source specific match will be created. Otherwise a match with a CIDR will
197 * @param dpidLong the dpid
198 * @param segmentationId the segmentation id
199 * @param dstMac the destination mac address.
200 * @param portSecurityRule the security rule in the SG
201 * @param srcAddress the destination IP address
202 * @param write add or delete
203 * @param protoPortMatchPriority the protocol match priroty
205 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
206 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
207 Integer protoPortMatchPriority ) {
209 MatchBuilder matchBuilder = new MatchBuilder();
210 FlowBuilder flowBuilder = new FlowBuilder();
211 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
212 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
214 /* Custom TCP Match*/
215 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
216 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
217 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
218 portSecurityRule.getSecurityRulePortMin());
221 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
222 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
223 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
224 + portSecurityRule.getSecurityRulePortMax() + "_";
225 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
227 /*TODO TCP PortRange Match*/
231 if (null != srcAddress) {
232 flowId = flowId + srcAddress;
233 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
234 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
236 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
237 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
238 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
239 new Ipv4Prefix(portSecurityRule
240 .getSecurityRuleRemoteIpPrefix()),null);
242 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
243 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
244 flowId = flowId + "_Permit";
245 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
250 * Creates a ingress match to the dst macaddress. If src address is specified
251 * source specific match will be created. Otherwise a match with a CIDR will
253 * @param dpidLong the dpid
254 * @param segmentationId the segmentation id
255 * @param dstMac the destination mac address.
256 * @param portSecurityRule the security rule in the SG
257 * @param srcAddress the destination IP address
258 * @param write add or delete
259 * @param protoPortMatchPriority the protocol match priroty
261 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
262 NeutronSecurityRule portSecurityRule, String srcAddress,
263 boolean write, Integer protoPortMatchPriority ) {
264 MatchBuilder matchBuilder = new MatchBuilder();
265 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
266 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
268 /* Custom UDP Match */
269 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
270 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
271 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
272 portSecurityRule.getSecurityRulePortMin());
275 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
276 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
277 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
278 + portSecurityRule.getSecurityRulePortMax() + "_";
279 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
281 /*TODO TCP PortRange Match*/
285 if (null != srcAddress) {
286 flowId = flowId + srcAddress;
287 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
288 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
290 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
291 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
292 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
293 new Ipv4Prefix(portSecurityRule
294 .getSecurityRuleRemoteIpPrefix()),null);
296 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
297 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
298 flowId = flowId + "_Permit";
299 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
304 * Creates a ingress match to the dst macaddress. If src address is specified
305 * source specific match will be created. Otherwise a match with a CIDR will
307 * @param dpidLong the dpid
308 * @param segmentationId the segmentation id
309 * @param dstMac the destination mac address.
310 * @param portSecurityRule the security rule in the SG
311 * @param srcAddress the destination IP address
312 * @param write add or delete
313 * @param protoPortMatchPriority the protocol match priority
315 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
316 NeutronSecurityRule portSecurityRule, String srcAddress,
317 boolean write, Integer protoPortMatchPriority) {
319 MatchBuilder matchBuilder = new MatchBuilder();
320 FlowBuilder flowBuilder = new FlowBuilder();
321 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_"
322 + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
323 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
324 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
325 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
326 portSecurityRule.getSecurityRulePortMin().shortValue(),
327 portSecurityRule.getSecurityRulePortMax().shortValue());
328 if (null != srcAddress) {
329 flowId = flowId + srcAddress;
330 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
331 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
332 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
333 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
334 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
335 new Ipv4Prefix(portSecurityRule
336 .getSecurityRuleRemoteIpPrefix()),null);
338 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
339 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
340 flowId = flowId + "_Permit";
341 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
345 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
346 Integer securityRulePortMin, Integer protoPortMatchPriority) {
348 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
349 PortNumber tcpPort = new PortNumber(securityRulePortMin);
350 MatchBuilder matchBuilder = new MatchBuilder();
351 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
352 FlowBuilder flowBuilder = new FlowBuilder();
354 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
355 Constants.TCP_SYN, segmentationId).build());
357 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
358 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
359 // Add Flow Attributes
360 flowBuilder.setId(new FlowId(flowId));
361 FlowKey key = new FlowKey(new FlowId(flowId));
362 flowBuilder.setStrict(false);
363 flowBuilder.setPriority(protoPortMatchPriority);
364 flowBuilder.setBarrier(true);
365 flowBuilder.setTableId(this.getTable());
366 flowBuilder.setKey(key);
367 flowBuilder.setFlowName(flowId);
368 flowBuilder.setHardTimeout(0);
369 flowBuilder.setIdleTimeout(0);
372 // Instantiate the Builders for the OF Actions and Instructions
373 InstructionsBuilder isb = new InstructionsBuilder();
374 List<Instruction> instructionsList = Lists.newArrayList();
376 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
378 ib.setKey(new InstructionKey(0));
379 instructionsList.add(ib.build());
380 isb.setInstruction(instructionsList);
382 LOG.debug("Instructions are: {}", ib.getInstruction());
383 // Add InstructionsBuilder to FlowBuilder
384 flowBuilder.setInstructions(isb.build());
385 writeFlow(flowBuilder, nodeBuilder);
387 removeFlow(flowBuilder, nodeBuilder);
391 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
392 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
393 Integer protoPortPrefixMatchPriority) {
395 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
396 PortNumber tcpPort = new PortNumber(securityRulePortMin);
398 MatchBuilder matchBuilder = new MatchBuilder();
399 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
400 FlowBuilder flowBuilder = new FlowBuilder();
401 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
403 flowBuilder.setMatch(MatchUtils
404 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
405 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
407 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
408 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
409 securityRulePortMin + securityRuleIpPrefix;
410 // Add Flow Attributes
411 flowBuilder.setId(new FlowId(flowId));
412 FlowKey key = new FlowKey(new FlowId(flowId));
413 flowBuilder.setStrict(false);
414 flowBuilder.setPriority(protoPortPrefixMatchPriority);
415 flowBuilder.setBarrier(true);
416 flowBuilder.setTableId(this.getTable());
417 flowBuilder.setKey(key);
418 flowBuilder.setFlowName(flowId);
419 flowBuilder.setHardTimeout(0);
420 flowBuilder.setIdleTimeout(0);
423 // Instantiate the Builders for the OF Actions and Instructions
424 InstructionsBuilder isb = new InstructionsBuilder();
426 List<Instruction> instructionsList = Lists.newArrayList();
427 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
429 ib.setKey(new InstructionKey(0));
430 instructionsList.add(ib.build());
431 isb.setInstruction(instructionsList);
433 LOG.debug("Instructions contain: {}", ib.getInstruction());
434 // Add InstructionsBuilder to FlowBuilder
435 flowBuilder.setInstructions(isb.build());
436 writeFlow(flowBuilder, nodeBuilder);
438 removeFlow(flowBuilder, nodeBuilder);
442 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
443 String securityRuleProtcol, Integer protoMatchPriority) {
445 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
447 MatchBuilder matchBuilder = new MatchBuilder();
448 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
449 FlowBuilder flowBuilder = new FlowBuilder();
451 flowBuilder.setMatch(MatchUtils
452 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
453 flowBuilder.setMatch(MatchUtils
454 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
455 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
457 String flowId = "UcastOut_" + segmentationId + "_" +
458 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
459 // Add Flow Attributes
460 flowBuilder.setId(new FlowId(flowId));
461 FlowKey key = new FlowKey(new FlowId(flowId));
462 flowBuilder.setStrict(false);
463 flowBuilder.setPriority(protoMatchPriority);
464 flowBuilder.setBarrier(true);
465 flowBuilder.setTableId(this.getTable());
466 flowBuilder.setKey(key);
467 flowBuilder.setFlowName(flowId);
468 flowBuilder.setHardTimeout(0);
469 flowBuilder.setIdleTimeout(0);
472 // Instantiate the Builders for the OF Actions and Instructions
473 InstructionsBuilder isb = new InstructionsBuilder();
474 List<Instruction> instructionsList = Lists.newArrayList();
476 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
478 ib.setKey(new InstructionKey(1));
479 instructionsList.add(ib.build());
480 isb.setInstruction(instructionsList);
481 LOG.debug("Instructions contain: {}", ib.getInstruction());
483 // Add InstructionsBuilder to FlowBuilder
484 flowBuilder.setInstructions(isb.build());
485 writeFlow(flowBuilder, nodeBuilder);
487 removeFlow(flowBuilder, nodeBuilder);
492 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
493 int priority, boolean write) {
495 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
496 MatchBuilder matchBuilder = new MatchBuilder();
497 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
498 FlowBuilder flowBuilder = new FlowBuilder();
500 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
501 attachedMac, Constants.TCP_SYN, segmentationId).build());
503 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
504 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
505 flowBuilder.setId(new FlowId(flowId));
506 FlowKey key = new FlowKey(new FlowId(flowId));
507 flowBuilder.setStrict(false);
508 flowBuilder.setPriority(priority);
509 flowBuilder.setBarrier(true);
510 flowBuilder.setTableId(this.getTable());
511 flowBuilder.setKey(key);
512 flowBuilder.setFlowName(flowId);
513 flowBuilder.setHardTimeout(0);
514 flowBuilder.setIdleTimeout(0);
517 // Instantiate the Builders for the OF Actions and Instructions
518 InstructionBuilder ib = new InstructionBuilder();
519 InstructionsBuilder isb = new InstructionsBuilder();
521 // Instructions List Stores Individual Instructions
522 List<Instruction> instructions = Lists.newArrayList();
524 // Set the Output Port/Iface
525 InstructionUtils.createDropInstructions(ib);
527 ib.setKey(new InstructionKey(0));
528 instructions.add(ib.build());
530 // Add InstructionBuilder to the Instruction(s)Builder List
531 isb.setInstruction(instructions);
532 LOG.debug("Instructions contain: {}", ib.getInstruction());
533 // Add InstructionsBuilder to FlowBuilder
534 flowBuilder.setInstructions(isb.build());
535 writeFlow(flowBuilder, nodeBuilder);
537 removeFlow(flowBuilder, nodeBuilder);
541 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
542 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
543 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
544 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
545 MatchBuilder matchBuilder = new MatchBuilder();
546 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
547 FlowBuilder flowBuilder = new FlowBuilder();
549 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
551 if (securityRuleIpPrefix != null) {
552 flowBuilder.setMatch(MatchUtils
553 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
556 flowBuilder.setMatch(MatchUtils
557 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
561 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
562 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
563 attachedMac + "_Permit_" + securityRuleIpPrefix;
564 // Add Flow Attributes
565 flowBuilder.setId(new FlowId(flowId));
566 FlowKey key = new FlowKey(new FlowId(flowId));
567 flowBuilder.setStrict(false);
568 flowBuilder.setPriority(protoPortMatchPriority);
569 flowBuilder.setBarrier(true);
570 flowBuilder.setTableId(this.getTable());
571 flowBuilder.setKey(key);
572 flowBuilder.setFlowName(flowId);
573 flowBuilder.setHardTimeout(0);
574 flowBuilder.setIdleTimeout(0);
577 // Instantiate the Builders for the OF Actions and Instructions
578 InstructionBuilder ib = new InstructionBuilder();
579 InstructionsBuilder isb = new InstructionsBuilder();
580 List<Instruction> instructionsList = Lists.newArrayList();
582 ib = this.getMutablePipelineInstructionBuilder();
584 ib.setKey(new InstructionKey(0));
585 instructionsList.add(ib.build());
586 isb.setInstruction(instructionsList);
588 LOG.debug("Instructions contain: {}", ib.getInstruction());
589 // Add InstructionsBuilder to FlowBuilder
590 flowBuilder.setInstructions(isb.build());
591 writeFlow(flowBuilder, nodeBuilder);
593 removeFlow(flowBuilder, nodeBuilder);
598 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
600 * @param dpidLong the dpid
601 * @param segmentationId the segmentation id
602 * @param dhcpMacAddress the DHCP server mac address
603 * @param write is write or delete
604 * @param protoPortMatchPriority the priority
606 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
607 boolean write, Integer protoPortMatchPriority) {
609 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
610 MatchBuilder matchBuilder = new MatchBuilder();
611 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
612 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
613 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
614 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
615 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
619 * Add or remove flow to the node.
621 * @param flowId the the flow id
622 * @param nodeBuilder the node builder
623 * @param matchBuilder the matchbuilder
624 * @param protoPortMatchPriority the protocol priority
625 * @param write whether it is a write
626 * @param drop whether it is a drop or forward
628 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
629 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
630 boolean write,boolean drop) {
631 FlowBuilder flowBuilder = new FlowBuilder();
632 flowBuilder.setMatch(matchBuilder.build());
633 flowBuilder.setId(new FlowId(flowId));
634 FlowKey key = new FlowKey(new FlowId(flowId));
635 flowBuilder.setStrict(false);
636 flowBuilder.setPriority(protoPortMatchPriority);
637 flowBuilder.setBarrier(true);
638 flowBuilder.setTableId(this.getTable());
639 flowBuilder.setKey(key);
640 flowBuilder.setFlowName(flowId);
641 flowBuilder.setHardTimeout(0);
642 flowBuilder.setIdleTimeout(0);
645 // Instantiate the Builders for the OF Actions and Instructions
646 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
648 InstructionUtils.createDropInstructions(ib);
651 InstructionsBuilder isb = new InstructionsBuilder();
652 List<Instruction> instructionsList = Lists.newArrayList();
653 ib.setKey(new InstructionKey(0));
654 instructionsList.add(ib.build());
655 isb.setInstruction(instructionsList);
656 flowBuilder.setInstructions(isb.build());
657 writeFlow(flowBuilder, nodeBuilder);
659 removeFlow(flowBuilder, nodeBuilder);
665 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
666 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
667 securityServicesManager =
668 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
669 securityGroupCacheManger =
670 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
674 public void setDependencies(Object impl) {