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.IpPrefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
41 import org.osgi.framework.BundleContext;
42 import org.osgi.framework.ServiceReference;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 import java.math.BigInteger;
47 import java.net.Inet6Address;
48 import java.net.InetAddress;
49 import java.net.UnknownHostException;
50 import java.util.List;
54 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
56 private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
57 private volatile SecurityServicesManager securityServicesManager;
58 private volatile SecurityGroupCacheManger securityGroupCacheManger;
59 private static final int PORT_RANGE_MIN = 1;
60 private static final int PORT_RANGE_MAX = 65535;
62 public IngressAclService() {
63 super(Service.INGRESS_ACL);
66 public IngressAclService(Service service) {
71 public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
72 long localPort, NeutronSecurityGroup securityGroup,
73 String portUuid, boolean write) {
75 LOG.trace("programPortSecurityGroup neutronSecurityGroup: {} ", securityGroup);
76 if (securityGroup == null || securityGroup.getSecurityRules() == null) {
80 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
81 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
82 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
85 * Neutron Port Security Acl "ingress" and "IPv4"
86 * Check that the base conditions for flow based Port Security are true:
87 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
88 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
89 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
93 if (portSecurityRule == null ||
94 portSecurityRule.getSecurityRuleEthertype() == null ||
95 portSecurityRule.getSecurityRuleDirection() == null) {
99 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
100 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
101 LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
102 if (null != portSecurityRule.getSecurityRemoteGroupID()) {
103 //Remote Security group is selected
104 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
105 .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
106 if (null != remoteSrcAddressList) {
107 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
108 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
109 portSecurityRule, vmIp, write);
112 securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
114 securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
119 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
120 portSecurityRule, null, write);
123 securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
125 securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
132 public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
133 long localPort, NeutronSecurityRule portSecurityRule,
134 Neutron_IPs vmIp, boolean write) {
135 if (null == portSecurityRule.getSecurityRuleProtocol()) {
136 ingressAclIPv4(dpid, segmentationId, attachedMac,
137 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
139 String ipaddress = null;
141 ipaddress = vmIp.getIpAddress();
143 InetAddress address = InetAddress.getByName(ipaddress);
144 // TODO: remove this when ipv6 support is implemented
145 if (address instanceof Inet6Address) {
146 LOG.debug("Skipping ip address {}. IPv6 support is not yet implemented.", address);
149 } catch (UnknownHostException e) {
150 LOG.warn("Invalid ip address {}", ipaddress, e);
155 if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
156 String ipPrefixStr = portSecurityRule.getSecurityRuleRemoteIpPrefix();
158 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(ipPrefixStr);
159 // TODO: remove this when ipv6 support is implemented
160 if (ipPrefix.getIpv6Prefix() != null) {
161 LOG.debug("Skipping ip prefix {}. IPv6 support is not yet implemented.", ipPrefix);
164 } catch (IllegalArgumentException e) {
165 LOG.warn("Invalid ip prefix {}", ipPrefixStr, e);
170 switch (portSecurityRule.getSecurityRuleProtocol()) {
172 LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
173 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
174 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
177 LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
178 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
179 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
181 case MatchUtils.ICMP:
182 LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
183 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
184 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
187 LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
188 "protocol = ", portSecurityRule.getSecurityRuleProtocol());
189 ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
190 null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
196 private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
197 NeutronSecurityRule portSecurityRule, String srcAddress,
198 boolean write, Integer protoPortMatchPriority) {
200 MatchBuilder matchBuilder = new MatchBuilder();
201 String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
202 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
205 Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
206 proto = protocol.shortValue();
207 flowId = flowId + proto;
208 } catch (NumberFormatException e) {
209 LOG.error("Protocol vlaue conversion failure", e);
211 matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
212 if (null != srcAddress) {
213 flowId = flowId + srcAddress;
214 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
215 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
216 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
217 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
218 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
219 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
221 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
222 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
223 flowId = flowId + "_Permit";
224 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
228 public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
229 long localPort, boolean isLastPortinSubnet,
230 boolean isComputePort, boolean write) {
231 //If this port is the only port in the compute node add the DHCP server rule.
232 if (isLastPortinSubnet && isComputePort ) {
233 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
234 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
239 * Allows IPv4 packet ingress to the destination mac address.
240 * @param dpidLong the dpid
241 * @param segmentationId the segementation id
242 * @param dstMac the destination mac address
243 * @param write add or remove
244 * @param protoPortMatchPriority the protocol match priority.
246 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
247 boolean write, Integer protoPortMatchPriority ) {
248 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
249 MatchBuilder matchBuilder = new MatchBuilder();
250 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
251 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
252 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
253 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
257 * Creates a ingress match to the dst macaddress. If src address is specified
258 * source specific match will be created. Otherwise a match with a CIDR will
260 * @param dpidLong the dpid
261 * @param segmentationId the segmentation id
262 * @param dstMac the destination mac address.
263 * @param portSecurityRule the security rule in the SG
264 * @param srcAddress the destination IP address
265 * @param write add or delete
266 * @param protoPortMatchPriority the protocol match priroty
268 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
269 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
270 Integer protoPortMatchPriority ) {
272 MatchBuilder matchBuilder = new MatchBuilder();
273 FlowBuilder flowBuilder = new FlowBuilder();
274 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
275 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
277 /* Custom TCP Match*/
278 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
279 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
280 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
281 portSecurityRule.getSecurityRulePortMin());
284 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
285 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
286 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
287 + portSecurityRule.getSecurityRulePortMax() + "_";
288 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
290 /*TODO TCP PortRange Match*/
294 if (null != srcAddress) {
295 flowId = flowId + srcAddress;
296 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
297 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
299 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
300 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
301 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
302 new Ipv4Prefix(portSecurityRule
303 .getSecurityRuleRemoteIpPrefix()),null);
305 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
306 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
307 flowId = flowId + "_Permit";
308 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
313 * Creates a ingress match to the dst macaddress. If src address is specified
314 * source specific match will be created. Otherwise a match with a CIDR will
316 * @param dpidLong the dpid
317 * @param segmentationId the segmentation id
318 * @param dstMac the destination mac address.
319 * @param portSecurityRule the security rule in the SG
320 * @param srcAddress the destination IP address
321 * @param write add or delete
322 * @param protoPortMatchPriority the protocol match priroty
324 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
325 NeutronSecurityRule portSecurityRule, String srcAddress,
326 boolean write, Integer protoPortMatchPriority ) {
327 MatchBuilder matchBuilder = new MatchBuilder();
328 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
329 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
331 /* Custom UDP Match */
332 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
333 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
334 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
335 portSecurityRule.getSecurityRulePortMin());
338 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
339 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
340 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
341 + portSecurityRule.getSecurityRulePortMax() + "_";
342 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
344 /*TODO TCP PortRange Match*/
348 if (null != srcAddress) {
349 flowId = flowId + srcAddress;
350 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
351 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
353 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
354 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
355 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
356 new Ipv4Prefix(portSecurityRule
357 .getSecurityRuleRemoteIpPrefix()),null);
359 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
360 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
361 flowId = flowId + "_Permit";
362 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
367 * Creates a ingress match to the dst macaddress. If src address is specified
368 * source specific match will be created. Otherwise a match with a CIDR will
370 * @param dpidLong the dpid
371 * @param segmentationId the segmentation id
372 * @param dstMac the destination mac address.
373 * @param portSecurityRule the security rule in the SG
374 * @param srcAddress the destination IP address
375 * @param write add or delete
376 * @param protoPortMatchPriority the protocol match priority
378 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
379 NeutronSecurityRule portSecurityRule, String srcAddress,
380 boolean write, Integer protoPortMatchPriority) {
382 MatchBuilder matchBuilder = new MatchBuilder();
383 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
384 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
386 /* Custom ICMP Match */
387 if (portSecurityRule.getSecurityRulePortMin() != null &&
388 portSecurityRule.getSecurityRulePortMax() != null) {
389 flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
390 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
391 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
392 portSecurityRule.getSecurityRulePortMin().shortValue(),
393 portSecurityRule.getSecurityRulePortMax().shortValue());
396 flowId = flowId + "all" + "_";
397 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
399 if (null != srcAddress) {
400 flowId = flowId + srcAddress;
401 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
402 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
403 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
404 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
405 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
406 new Ipv4Prefix(portSecurityRule
407 .getSecurityRuleRemoteIpPrefix()),null);
409 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
410 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
411 flowId = flowId + "_Permit";
412 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
416 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
417 Integer securityRulePortMin, Integer protoPortMatchPriority) {
419 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
420 PortNumber tcpPort = new PortNumber(securityRulePortMin);
421 MatchBuilder matchBuilder = new MatchBuilder();
422 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
423 FlowBuilder flowBuilder = new FlowBuilder();
425 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
426 Constants.TCP_SYN, segmentationId).build());
428 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
429 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
430 // Add Flow Attributes
431 flowBuilder.setId(new FlowId(flowId));
432 FlowKey key = new FlowKey(new FlowId(flowId));
433 flowBuilder.setStrict(false);
434 flowBuilder.setPriority(protoPortMatchPriority);
435 flowBuilder.setBarrier(true);
436 flowBuilder.setTableId(this.getTable());
437 flowBuilder.setKey(key);
438 flowBuilder.setFlowName(flowId);
439 flowBuilder.setHardTimeout(0);
440 flowBuilder.setIdleTimeout(0);
443 // Instantiate the Builders for the OF Actions and Instructions
444 InstructionsBuilder isb = new InstructionsBuilder();
445 List<Instruction> instructionsList = Lists.newArrayList();
447 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
449 ib.setKey(new InstructionKey(0));
450 instructionsList.add(ib.build());
451 isb.setInstruction(instructionsList);
453 LOG.debug("Instructions are: {}", ib.getInstruction());
454 // Add InstructionsBuilder to FlowBuilder
455 flowBuilder.setInstructions(isb.build());
456 writeFlow(flowBuilder, nodeBuilder);
458 removeFlow(flowBuilder, nodeBuilder);
462 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
463 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
464 Integer protoPortPrefixMatchPriority) {
466 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
467 PortNumber tcpPort = new PortNumber(securityRulePortMin);
469 MatchBuilder matchBuilder = new MatchBuilder();
470 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
471 FlowBuilder flowBuilder = new FlowBuilder();
472 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
474 flowBuilder.setMatch(MatchUtils
475 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
476 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
478 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
479 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
480 securityRulePortMin + securityRuleIpPrefix;
481 // Add Flow Attributes
482 flowBuilder.setId(new FlowId(flowId));
483 FlowKey key = new FlowKey(new FlowId(flowId));
484 flowBuilder.setStrict(false);
485 flowBuilder.setPriority(protoPortPrefixMatchPriority);
486 flowBuilder.setBarrier(true);
487 flowBuilder.setTableId(this.getTable());
488 flowBuilder.setKey(key);
489 flowBuilder.setFlowName(flowId);
490 flowBuilder.setHardTimeout(0);
491 flowBuilder.setIdleTimeout(0);
494 // Instantiate the Builders for the OF Actions and Instructions
495 InstructionsBuilder isb = new InstructionsBuilder();
497 List<Instruction> instructionsList = Lists.newArrayList();
498 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
500 ib.setKey(new InstructionKey(0));
501 instructionsList.add(ib.build());
502 isb.setInstruction(instructionsList);
504 LOG.debug("Instructions contain: {}", ib.getInstruction());
505 // Add InstructionsBuilder to FlowBuilder
506 flowBuilder.setInstructions(isb.build());
507 writeFlow(flowBuilder, nodeBuilder);
509 removeFlow(flowBuilder, nodeBuilder);
513 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
514 String securityRuleProtcol, Integer protoMatchPriority) {
516 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
518 MatchBuilder matchBuilder = new MatchBuilder();
519 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
520 FlowBuilder flowBuilder = new FlowBuilder();
522 flowBuilder.setMatch(MatchUtils
523 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
524 flowBuilder.setMatch(MatchUtils
525 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
526 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
528 String flowId = "UcastOut_" + segmentationId + "_" +
529 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
530 // Add Flow Attributes
531 flowBuilder.setId(new FlowId(flowId));
532 FlowKey key = new FlowKey(new FlowId(flowId));
533 flowBuilder.setStrict(false);
534 flowBuilder.setPriority(protoMatchPriority);
535 flowBuilder.setBarrier(true);
536 flowBuilder.setTableId(this.getTable());
537 flowBuilder.setKey(key);
538 flowBuilder.setFlowName(flowId);
539 flowBuilder.setHardTimeout(0);
540 flowBuilder.setIdleTimeout(0);
543 // Instantiate the Builders for the OF Actions and Instructions
544 InstructionsBuilder isb = new InstructionsBuilder();
545 List<Instruction> instructionsList = Lists.newArrayList();
547 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
549 ib.setKey(new InstructionKey(1));
550 instructionsList.add(ib.build());
551 isb.setInstruction(instructionsList);
552 LOG.debug("Instructions contain: {}", ib.getInstruction());
554 // Add InstructionsBuilder to FlowBuilder
555 flowBuilder.setInstructions(isb.build());
556 writeFlow(flowBuilder, nodeBuilder);
558 removeFlow(flowBuilder, nodeBuilder);
563 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
564 int priority, boolean write) {
566 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
567 MatchBuilder matchBuilder = new MatchBuilder();
568 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
569 FlowBuilder flowBuilder = new FlowBuilder();
571 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
572 attachedMac, Constants.TCP_SYN, segmentationId).build());
574 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
575 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
576 flowBuilder.setId(new FlowId(flowId));
577 FlowKey key = new FlowKey(new FlowId(flowId));
578 flowBuilder.setStrict(false);
579 flowBuilder.setPriority(priority);
580 flowBuilder.setBarrier(true);
581 flowBuilder.setTableId(this.getTable());
582 flowBuilder.setKey(key);
583 flowBuilder.setFlowName(flowId);
584 flowBuilder.setHardTimeout(0);
585 flowBuilder.setIdleTimeout(0);
588 // Instantiate the Builders for the OF Actions and Instructions
589 InstructionBuilder ib = new InstructionBuilder();
590 InstructionsBuilder isb = new InstructionsBuilder();
592 // Instructions List Stores Individual Instructions
593 List<Instruction> instructions = Lists.newArrayList();
595 // Set the Output Port/Iface
596 InstructionUtils.createDropInstructions(ib);
598 ib.setKey(new InstructionKey(0));
599 instructions.add(ib.build());
601 // Add InstructionBuilder to the Instruction(s)Builder List
602 isb.setInstruction(instructions);
603 LOG.debug("Instructions contain: {}", ib.getInstruction());
604 // Add InstructionsBuilder to FlowBuilder
605 flowBuilder.setInstructions(isb.build());
606 writeFlow(flowBuilder, nodeBuilder);
608 removeFlow(flowBuilder, nodeBuilder);
612 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
613 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
614 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
615 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
616 MatchBuilder matchBuilder = new MatchBuilder();
617 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
618 FlowBuilder flowBuilder = new FlowBuilder();
620 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
622 if (securityRuleIpPrefix != null) {
623 flowBuilder.setMatch(MatchUtils
624 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
627 flowBuilder.setMatch(MatchUtils
628 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
632 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
633 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
634 attachedMac + "_Permit_" + securityRuleIpPrefix;
635 // Add Flow Attributes
636 flowBuilder.setId(new FlowId(flowId));
637 FlowKey key = new FlowKey(new FlowId(flowId));
638 flowBuilder.setStrict(false);
639 flowBuilder.setPriority(protoPortMatchPriority);
640 flowBuilder.setBarrier(true);
641 flowBuilder.setTableId(this.getTable());
642 flowBuilder.setKey(key);
643 flowBuilder.setFlowName(flowId);
644 flowBuilder.setHardTimeout(0);
645 flowBuilder.setIdleTimeout(0);
648 // Instantiate the Builders for the OF Actions and Instructions
649 InstructionBuilder ib = new InstructionBuilder();
650 InstructionsBuilder isb = new InstructionsBuilder();
651 List<Instruction> instructionsList = Lists.newArrayList();
653 ib = this.getMutablePipelineInstructionBuilder();
655 ib.setKey(new InstructionKey(0));
656 instructionsList.add(ib.build());
657 isb.setInstruction(instructionsList);
659 LOG.debug("Instructions contain: {}", ib.getInstruction());
660 // Add InstructionsBuilder to FlowBuilder
661 flowBuilder.setInstructions(isb.build());
662 writeFlow(flowBuilder, nodeBuilder);
664 removeFlow(flowBuilder, nodeBuilder);
669 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
671 * @param dpidLong the dpid
672 * @param segmentationId the segmentation id
673 * @param dhcpMacAddress the DHCP server mac address
674 * @param write is write or delete
675 * @param protoPortMatchPriority the priority
677 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
678 boolean write, Integer protoPortMatchPriority) {
680 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
681 MatchBuilder matchBuilder = new MatchBuilder();
682 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
683 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
684 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
685 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
686 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
690 * Add or remove flow to the node.
692 * @param flowId the the flow id
693 * @param nodeBuilder the node builder
694 * @param matchBuilder the matchbuilder
695 * @param protoPortMatchPriority the protocol priority
696 * @param write whether it is a write
697 * @param drop whether it is a drop or forward
699 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
700 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
701 boolean write,boolean drop) {
702 FlowBuilder flowBuilder = new FlowBuilder();
703 flowBuilder.setMatch(matchBuilder.build());
704 flowBuilder.setId(new FlowId(flowId));
705 FlowKey key = new FlowKey(new FlowId(flowId));
706 flowBuilder.setStrict(false);
707 flowBuilder.setPriority(protoPortMatchPriority);
708 flowBuilder.setBarrier(true);
709 flowBuilder.setTableId(this.getTable());
710 flowBuilder.setKey(key);
711 flowBuilder.setFlowName(flowId);
712 flowBuilder.setHardTimeout(0);
713 flowBuilder.setIdleTimeout(0);
716 // Instantiate the Builders for the OF Actions and Instructions
717 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
719 InstructionUtils.createDropInstructions(ib);
722 InstructionsBuilder isb = new InstructionsBuilder();
723 List<Instruction> instructionsList = Lists.newArrayList();
724 ib.setKey(new InstructionKey(0));
725 instructionsList.add(ib.build());
726 isb.setInstruction(instructionsList);
727 flowBuilder.setInstructions(isb.build());
728 writeFlow(flowBuilder, nodeBuilder);
730 removeFlow(flowBuilder, nodeBuilder);
736 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
737 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
738 securityServicesManager =
739 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
740 securityGroupCacheManger =
741 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
745 public void setDependencies(Object impl) {