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);
127 public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
128 long localPort, NeutronSecurityRule portSecurityRule,
129 Neutron_IPs vmIp, boolean write) {
130 if (null == portSecurityRule.getSecurityRuleProtocol()) {
131 ingressAclIPv4(dpid, segmentationId, attachedMac,
132 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
134 String ipaddress = null;
136 ipaddress = vmIp.getIpAddress();
138 switch (portSecurityRule.getSecurityRuleProtocol()) {
140 LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
141 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
142 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
145 LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
146 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
147 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
149 case MatchUtils.ICMP:
150 LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
151 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
152 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
155 LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
156 "protocol = ", portSecurityRule.getSecurityRuleProtocol());
157 ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
158 null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
164 private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
165 NeutronSecurityRule portSecurityRule, String srcAddress,
166 boolean write, Integer protoPortMatchPriority) {
168 MatchBuilder matchBuilder = new MatchBuilder();
169 String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
170 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
173 Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
174 proto = protocol.shortValue();
175 flowId = flowId + proto;
176 } catch (NumberFormatException e) {
177 LOG.error("Protocol vlaue conversion failure", e);
179 matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
180 if (null != srcAddress) {
181 flowId = flowId + srcAddress;
182 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
183 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
184 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
185 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
186 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
187 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
189 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
190 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
191 flowId = flowId + "_Permit";
192 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
196 public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
197 long localPort, boolean isLastPortinSubnet,
198 boolean isComputePort, boolean write) {
199 //If this port is the only port in the compute node add the DHCP server rule.
200 if (isLastPortinSubnet && isComputePort ) {
201 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
202 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
207 * Allows IPv4 packet ingress to the destination mac address.
208 * @param dpidLong the dpid
209 * @param segmentationId the segementation id
210 * @param dstMac the destination mac address
211 * @param write add or remove
212 * @param protoPortMatchPriority the protocol match priority.
214 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
215 boolean write, Integer protoPortMatchPriority ) {
216 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
217 MatchBuilder matchBuilder = new MatchBuilder();
218 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
219 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
220 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
221 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
225 * Creates a ingress match to the dst macaddress. If src address is specified
226 * source specific match will be created. Otherwise a match with a CIDR will
228 * @param dpidLong the dpid
229 * @param segmentationId the segmentation id
230 * @param dstMac the destination mac address.
231 * @param portSecurityRule the security rule in the SG
232 * @param srcAddress the destination IP address
233 * @param write add or delete
234 * @param protoPortMatchPriority the protocol match priroty
236 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
237 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
238 Integer protoPortMatchPriority ) {
240 MatchBuilder matchBuilder = new MatchBuilder();
241 FlowBuilder flowBuilder = new FlowBuilder();
242 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
243 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
245 /* Custom TCP Match*/
246 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
247 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
248 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
249 portSecurityRule.getSecurityRulePortMin());
252 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
253 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
254 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
255 + portSecurityRule.getSecurityRulePortMax() + "_";
256 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
258 /*TODO TCP PortRange Match*/
262 if (null != srcAddress) {
263 flowId = flowId + srcAddress;
264 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
265 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
267 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
268 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
269 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
270 new Ipv4Prefix(portSecurityRule
271 .getSecurityRuleRemoteIpPrefix()),null);
273 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
274 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
275 flowId = flowId + "_Permit";
276 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
281 * Creates a ingress match to the dst macaddress. If src address is specified
282 * source specific match will be created. Otherwise a match with a CIDR will
284 * @param dpidLong the dpid
285 * @param segmentationId the segmentation id
286 * @param dstMac the destination mac address.
287 * @param portSecurityRule the security rule in the SG
288 * @param srcAddress the destination IP address
289 * @param write add or delete
290 * @param protoPortMatchPriority the protocol match priroty
292 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
293 NeutronSecurityRule portSecurityRule, String srcAddress,
294 boolean write, Integer protoPortMatchPriority ) {
295 MatchBuilder matchBuilder = new MatchBuilder();
296 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
297 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
299 /* Custom UDP Match */
300 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
301 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
302 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
303 portSecurityRule.getSecurityRulePortMin());
306 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
307 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
308 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
309 + portSecurityRule.getSecurityRulePortMax() + "_";
310 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
312 /*TODO TCP PortRange Match*/
316 if (null != srcAddress) {
317 flowId = flowId + srcAddress;
318 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
319 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
321 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
322 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
323 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
324 new Ipv4Prefix(portSecurityRule
325 .getSecurityRuleRemoteIpPrefix()),null);
327 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
328 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
329 flowId = flowId + "_Permit";
330 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
335 * Creates a ingress match to the dst macaddress. If src address is specified
336 * source specific match will be created. Otherwise a match with a CIDR will
338 * @param dpidLong the dpid
339 * @param segmentationId the segmentation id
340 * @param dstMac the destination mac address.
341 * @param portSecurityRule the security rule in the SG
342 * @param srcAddress the destination IP address
343 * @param write add or delete
344 * @param protoPortMatchPriority the protocol match priority
346 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
347 NeutronSecurityRule portSecurityRule, String srcAddress,
348 boolean write, Integer protoPortMatchPriority) {
350 MatchBuilder matchBuilder = new MatchBuilder();
351 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
352 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
354 /* Custom ICMP Match */
355 if (portSecurityRule.getSecurityRulePortMin() != null &&
356 portSecurityRule.getSecurityRulePortMax() != null) {
357 flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
358 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
359 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
360 portSecurityRule.getSecurityRulePortMin().shortValue(),
361 portSecurityRule.getSecurityRulePortMax().shortValue());
364 flowId = flowId + "all" + "_";
365 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
367 if (null != srcAddress) {
368 flowId = flowId + srcAddress;
369 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
370 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
371 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
372 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
373 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
374 new Ipv4Prefix(portSecurityRule
375 .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);
384 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
385 Integer securityRulePortMin, Integer protoPortMatchPriority) {
387 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
388 PortNumber tcpPort = new PortNumber(securityRulePortMin);
389 MatchBuilder matchBuilder = new MatchBuilder();
390 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
391 FlowBuilder flowBuilder = new FlowBuilder();
393 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
394 Constants.TCP_SYN, segmentationId).build());
396 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
397 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
398 // Add Flow Attributes
399 flowBuilder.setId(new FlowId(flowId));
400 FlowKey key = new FlowKey(new FlowId(flowId));
401 flowBuilder.setStrict(false);
402 flowBuilder.setPriority(protoPortMatchPriority);
403 flowBuilder.setBarrier(true);
404 flowBuilder.setTableId(this.getTable());
405 flowBuilder.setKey(key);
406 flowBuilder.setFlowName(flowId);
407 flowBuilder.setHardTimeout(0);
408 flowBuilder.setIdleTimeout(0);
411 // Instantiate the Builders for the OF Actions and Instructions
412 InstructionsBuilder isb = new InstructionsBuilder();
413 List<Instruction> instructionsList = Lists.newArrayList();
415 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
417 ib.setKey(new InstructionKey(0));
418 instructionsList.add(ib.build());
419 isb.setInstruction(instructionsList);
421 LOG.debug("Instructions are: {}", ib.getInstruction());
422 // Add InstructionsBuilder to FlowBuilder
423 flowBuilder.setInstructions(isb.build());
424 writeFlow(flowBuilder, nodeBuilder);
426 removeFlow(flowBuilder, nodeBuilder);
430 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
431 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
432 Integer protoPortPrefixMatchPriority) {
434 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
435 PortNumber tcpPort = new PortNumber(securityRulePortMin);
437 MatchBuilder matchBuilder = new MatchBuilder();
438 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
439 FlowBuilder flowBuilder = new FlowBuilder();
440 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
442 flowBuilder.setMatch(MatchUtils
443 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
444 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
446 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
447 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
448 securityRulePortMin + securityRuleIpPrefix;
449 // Add Flow Attributes
450 flowBuilder.setId(new FlowId(flowId));
451 FlowKey key = new FlowKey(new FlowId(flowId));
452 flowBuilder.setStrict(false);
453 flowBuilder.setPriority(protoPortPrefixMatchPriority);
454 flowBuilder.setBarrier(true);
455 flowBuilder.setTableId(this.getTable());
456 flowBuilder.setKey(key);
457 flowBuilder.setFlowName(flowId);
458 flowBuilder.setHardTimeout(0);
459 flowBuilder.setIdleTimeout(0);
462 // Instantiate the Builders for the OF Actions and Instructions
463 InstructionsBuilder isb = new InstructionsBuilder();
465 List<Instruction> instructionsList = Lists.newArrayList();
466 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
468 ib.setKey(new InstructionKey(0));
469 instructionsList.add(ib.build());
470 isb.setInstruction(instructionsList);
472 LOG.debug("Instructions contain: {}", ib.getInstruction());
473 // Add InstructionsBuilder to FlowBuilder
474 flowBuilder.setInstructions(isb.build());
475 writeFlow(flowBuilder, nodeBuilder);
477 removeFlow(flowBuilder, nodeBuilder);
481 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
482 String securityRuleProtcol, Integer protoMatchPriority) {
484 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
486 MatchBuilder matchBuilder = new MatchBuilder();
487 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
488 FlowBuilder flowBuilder = new FlowBuilder();
490 flowBuilder.setMatch(MatchUtils
491 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
492 flowBuilder.setMatch(MatchUtils
493 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
494 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
496 String flowId = "UcastOut_" + segmentationId + "_" +
497 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
498 // Add Flow Attributes
499 flowBuilder.setId(new FlowId(flowId));
500 FlowKey key = new FlowKey(new FlowId(flowId));
501 flowBuilder.setStrict(false);
502 flowBuilder.setPriority(protoMatchPriority);
503 flowBuilder.setBarrier(true);
504 flowBuilder.setTableId(this.getTable());
505 flowBuilder.setKey(key);
506 flowBuilder.setFlowName(flowId);
507 flowBuilder.setHardTimeout(0);
508 flowBuilder.setIdleTimeout(0);
511 // Instantiate the Builders for the OF Actions and Instructions
512 InstructionsBuilder isb = new InstructionsBuilder();
513 List<Instruction> instructionsList = Lists.newArrayList();
515 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
517 ib.setKey(new InstructionKey(1));
518 instructionsList.add(ib.build());
519 isb.setInstruction(instructionsList);
520 LOG.debug("Instructions contain: {}", ib.getInstruction());
522 // Add InstructionsBuilder to FlowBuilder
523 flowBuilder.setInstructions(isb.build());
524 writeFlow(flowBuilder, nodeBuilder);
526 removeFlow(flowBuilder, nodeBuilder);
531 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
532 int priority, boolean write) {
534 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
535 MatchBuilder matchBuilder = new MatchBuilder();
536 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
537 FlowBuilder flowBuilder = new FlowBuilder();
539 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
540 attachedMac, Constants.TCP_SYN, segmentationId).build());
542 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
543 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
544 flowBuilder.setId(new FlowId(flowId));
545 FlowKey key = new FlowKey(new FlowId(flowId));
546 flowBuilder.setStrict(false);
547 flowBuilder.setPriority(priority);
548 flowBuilder.setBarrier(true);
549 flowBuilder.setTableId(this.getTable());
550 flowBuilder.setKey(key);
551 flowBuilder.setFlowName(flowId);
552 flowBuilder.setHardTimeout(0);
553 flowBuilder.setIdleTimeout(0);
556 // Instantiate the Builders for the OF Actions and Instructions
557 InstructionBuilder ib = new InstructionBuilder();
558 InstructionsBuilder isb = new InstructionsBuilder();
560 // Instructions List Stores Individual Instructions
561 List<Instruction> instructions = Lists.newArrayList();
563 // Set the Output Port/Iface
564 InstructionUtils.createDropInstructions(ib);
566 ib.setKey(new InstructionKey(0));
567 instructions.add(ib.build());
569 // Add InstructionBuilder to the Instruction(s)Builder List
570 isb.setInstruction(instructions);
571 LOG.debug("Instructions contain: {}", ib.getInstruction());
572 // Add InstructionsBuilder to FlowBuilder
573 flowBuilder.setInstructions(isb.build());
574 writeFlow(flowBuilder, nodeBuilder);
576 removeFlow(flowBuilder, nodeBuilder);
580 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
581 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
582 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
583 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
584 MatchBuilder matchBuilder = new MatchBuilder();
585 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
586 FlowBuilder flowBuilder = new FlowBuilder();
588 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
590 if (securityRuleIpPrefix != null) {
591 flowBuilder.setMatch(MatchUtils
592 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
595 flowBuilder.setMatch(MatchUtils
596 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
600 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
601 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
602 attachedMac + "_Permit_" + securityRuleIpPrefix;
603 // Add Flow Attributes
604 flowBuilder.setId(new FlowId(flowId));
605 FlowKey key = new FlowKey(new FlowId(flowId));
606 flowBuilder.setStrict(false);
607 flowBuilder.setPriority(protoPortMatchPriority);
608 flowBuilder.setBarrier(true);
609 flowBuilder.setTableId(this.getTable());
610 flowBuilder.setKey(key);
611 flowBuilder.setFlowName(flowId);
612 flowBuilder.setHardTimeout(0);
613 flowBuilder.setIdleTimeout(0);
616 // Instantiate the Builders for the OF Actions and Instructions
617 InstructionBuilder ib = new InstructionBuilder();
618 InstructionsBuilder isb = new InstructionsBuilder();
619 List<Instruction> instructionsList = Lists.newArrayList();
621 ib = this.getMutablePipelineInstructionBuilder();
623 ib.setKey(new InstructionKey(0));
624 instructionsList.add(ib.build());
625 isb.setInstruction(instructionsList);
627 LOG.debug("Instructions contain: {}", ib.getInstruction());
628 // Add InstructionsBuilder to FlowBuilder
629 flowBuilder.setInstructions(isb.build());
630 writeFlow(flowBuilder, nodeBuilder);
632 removeFlow(flowBuilder, nodeBuilder);
637 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
639 * @param dpidLong the dpid
640 * @param segmentationId the segmentation id
641 * @param dhcpMacAddress the DHCP server mac address
642 * @param write is write or delete
643 * @param protoPortMatchPriority the priority
645 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
646 boolean write, Integer protoPortMatchPriority) {
648 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
649 MatchBuilder matchBuilder = new MatchBuilder();
650 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
651 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
652 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
653 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
654 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
658 * Add or remove flow to the node.
660 * @param flowId the the flow id
661 * @param nodeBuilder the node builder
662 * @param matchBuilder the matchbuilder
663 * @param protoPortMatchPriority the protocol priority
664 * @param write whether it is a write
665 * @param drop whether it is a drop or forward
667 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
668 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
669 boolean write,boolean drop) {
670 FlowBuilder flowBuilder = new FlowBuilder();
671 flowBuilder.setMatch(matchBuilder.build());
672 flowBuilder.setId(new FlowId(flowId));
673 FlowKey key = new FlowKey(new FlowId(flowId));
674 flowBuilder.setStrict(false);
675 flowBuilder.setPriority(protoPortMatchPriority);
676 flowBuilder.setBarrier(true);
677 flowBuilder.setTableId(this.getTable());
678 flowBuilder.setKey(key);
679 flowBuilder.setFlowName(flowId);
680 flowBuilder.setHardTimeout(0);
681 flowBuilder.setIdleTimeout(0);
684 // Instantiate the Builders for the OF Actions and Instructions
685 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
687 InstructionUtils.createDropInstructions(ib);
690 InstructionsBuilder isb = new InstructionsBuilder();
691 List<Instruction> instructionsList = Lists.newArrayList();
692 ib.setKey(new InstructionKey(0));
693 instructionsList.add(ib.build());
694 isb.setInstruction(instructionsList);
695 flowBuilder.setInstructions(isb.build());
696 writeFlow(flowBuilder, nodeBuilder);
698 removeFlow(flowBuilder, nodeBuilder);
704 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
705 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
706 securityServicesManager =
707 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
708 securityGroupCacheManger =
709 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
713 public void setDependencies(Object impl) {