2 * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
11 import com.google.common.collect.Lists;
13 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
14 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
15 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
17 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
18 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
19 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
20 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
21 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
22 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
23 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
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;
53 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
54 private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
55 private volatile SecurityServicesManager securityServicesManager;
56 private volatile SecurityGroupCacheManger securityGroupCacheManger;
57 private static final int PORT_RANGE_MIN = 1;
58 private static final int PORT_RANGE_MAX = 65535;
60 public IngressAclService() {
61 super(Service.INGRESS_ACL);
64 public IngressAclService(Service service) {
69 public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
70 long localPort, NeutronSecurityGroup securityGroup,
71 String portUuid, boolean write) {
73 LOG.trace("programPortSecurityGroup neutronSecurityGroup: {} ", securityGroup);
74 if (securityGroup == null || securityGroup.getSecurityRules() == null) {
78 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
79 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
80 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
83 * Neutron Port Security Acl "ingress" and "IPv4"
84 * Check that the base conditions for flow based Port Security are true:
85 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
86 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
87 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
91 if (portSecurityRule == null ||
92 portSecurityRule.getSecurityRuleEthertype() == null ||
93 portSecurityRule.getSecurityRuleDirection() == null) {
97 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
98 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
99 LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
100 if (null != portSecurityRule.getSecurityRemoteGroupID()) {
101 //Remote Security group is selected
102 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
103 .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
104 if (null != remoteSrcAddressList) {
105 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
106 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
107 portSecurityRule, vmIp, write);
110 securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
112 securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
117 programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
118 portSecurityRule, null, write);
121 securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
123 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 InetAddress address = InetAddress.getByName(ipaddress);
142 // TODO: remove this when ipv6 support is implemented
143 if (address instanceof Inet6Address) {
144 LOG.debug("Skipping ip address {}. IPv6 support is not yet implemented.", address);
147 } catch (UnknownHostException e) {
148 LOG.warn("Invalid ip address {}", ipaddress, e);
153 if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
154 String ipPrefixStr = portSecurityRule.getSecurityRuleRemoteIpPrefix();
156 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(ipPrefixStr);
157 // TODO: remove this when ipv6 support is implemented
158 if (ipPrefix.getIpv6Prefix() != null) {
159 LOG.debug("Skipping ip prefix {}. IPv6 support is not yet implemented.", ipPrefix);
162 } catch (IllegalArgumentException e) {
163 LOG.warn("Invalid ip prefix {}", ipPrefixStr, e);
168 switch (portSecurityRule.getSecurityRuleProtocol()) {
170 LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
171 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
172 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
175 LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
176 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
177 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
179 case MatchUtils.ICMP:
180 LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
181 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
182 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
185 LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
186 "protocol = ", portSecurityRule.getSecurityRuleProtocol());
187 ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
188 null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
194 private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
195 NeutronSecurityRule portSecurityRule, String srcAddress,
196 boolean write, Integer protoPortMatchPriority) {
198 MatchBuilder matchBuilder = new MatchBuilder();
199 String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
200 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
203 Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
204 proto = protocol.shortValue();
205 flowId = flowId + proto;
206 } catch (NumberFormatException e) {
207 LOG.error("Protocol vlaue conversion failure", e);
209 matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
210 if (null != srcAddress) {
211 flowId = flowId + srcAddress;
212 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
213 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
214 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
215 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
216 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
217 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
219 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
220 flowId = flowId + "_Permit";
221 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
225 public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
226 long localPort, boolean isLastPortinSubnet,
227 boolean isComputePort, boolean write) {
228 //If this port is the only port in the compute node add the DHCP server rule.
229 if (isLastPortinSubnet && isComputePort ) {
230 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
231 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
236 * Allows IPv4 packet ingress to the destination mac address.
237 * @param dpidLong the dpid
238 * @param segmentationId the segementation id
239 * @param dstMac the destination mac address
240 * @param write add or remove
241 * @param protoPortMatchPriority the protocol match priority.
243 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
244 boolean write, Integer protoPortMatchPriority ) {
245 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
246 MatchBuilder matchBuilder = new MatchBuilder();
247 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
248 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
249 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
253 * Creates a ingress match to the dst macaddress. If src address is specified
254 * source specific match will be created. Otherwise a match with a CIDR will
256 * @param dpidLong the dpid
257 * @param segmentationId the segmentation id
258 * @param dstMac the destination mac address.
259 * @param portSecurityRule the security rule in the SG
260 * @param srcAddress the destination IP address
261 * @param write add or delete
262 * @param protoPortMatchPriority the protocol match priroty
264 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
265 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
266 Integer protoPortMatchPriority ) {
267 boolean portRange = false;
268 MatchBuilder matchBuilder = new MatchBuilder();
269 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
270 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
272 /* Custom TCP Match*/
273 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
274 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
275 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
276 portSecurityRule.getSecurityRulePortMin());
279 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
280 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
281 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
282 + portSecurityRule.getSecurityRulePortMax() + "_";
283 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
288 if (null != srcAddress) {
289 flowId = flowId + srcAddress;
290 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
291 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
293 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
294 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
295 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
296 new Ipv4Prefix(portSecurityRule
297 .getSecurityRuleRemoteIpPrefix()),null);
299 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
301 Map<Integer, Integer> portMaskMap = MatchUtils
302 .getLayer4MaskForRange(portSecurityRule.getSecurityRulePortMin(),
303 portSecurityRule.getSecurityRulePortMax());
304 for (Integer port: portMaskMap.keySet()) {
305 String rangeflowId = flowId + port + "_" + portMaskMap.get(port) + "_";
306 rangeflowId = rangeflowId + "_Permit";
307 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
308 0, port, portMaskMap.get(port));
309 syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
312 flowId = flowId + "_Permit";
313 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
318 * Creates a ingress match to the dst macaddress. If src address is specified
319 * source specific match will be created. Otherwise a match with a CIDR will
321 * @param dpidLong the dpid
322 * @param segmentationId the segmentation id
323 * @param dstMac the destination mac address.
324 * @param portSecurityRule the security rule in the SG
325 * @param srcAddress the destination IP address
326 * @param write add or delete
327 * @param protoPortMatchPriority the protocol match priroty
329 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
330 NeutronSecurityRule portSecurityRule, String srcAddress,
331 boolean write, Integer protoPortMatchPriority ) {
332 boolean portRange = false;
333 MatchBuilder matchBuilder = new MatchBuilder();
334 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
335 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
337 /* Custom UDP Match */
338 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
339 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
340 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
341 portSecurityRule.getSecurityRulePortMin());
344 if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
345 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
346 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
347 + portSecurityRule.getSecurityRulePortMax() + "_";
348 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
353 if (null != srcAddress) {
354 flowId = flowId + srcAddress;
355 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
356 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
358 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
359 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
360 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
361 new Ipv4Prefix(portSecurityRule
362 .getSecurityRuleRemoteIpPrefix()),null);
364 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
366 Map<Integer, Integer> portMaskMap = MatchUtils
367 .getLayer4MaskForRange(portSecurityRule.getSecurityRulePortMin(),
368 portSecurityRule.getSecurityRulePortMax());
369 for (Integer port: portMaskMap.keySet()) {
370 String rangeflowId = flowId + port + "_" + portMaskMap.get(port) + "_";
371 rangeflowId = rangeflowId + "_Permit";
372 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.UDP_SHORT,
373 0, port, portMaskMap.get(port));
374 syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
377 flowId = flowId + "_Permit";
378 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
383 * Creates a ingress match to the dst macaddress. If src address is specified
384 * source specific match will be created. Otherwise a match with a CIDR will
386 * @param dpidLong the dpid
387 * @param segmentationId the segmentation id
388 * @param dstMac the destination mac address.
389 * @param portSecurityRule the security rule in the SG
390 * @param srcAddress the destination IP address
391 * @param write add or delete
392 * @param protoPortMatchPriority the protocol match priority
394 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
395 NeutronSecurityRule portSecurityRule, String srcAddress,
396 boolean write, Integer protoPortMatchPriority) {
398 MatchBuilder matchBuilder = new MatchBuilder();
399 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
400 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
402 /* Custom ICMP Match */
403 if (portSecurityRule.getSecurityRulePortMin() != null &&
404 portSecurityRule.getSecurityRulePortMax() != null) {
405 flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
406 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
407 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
408 portSecurityRule.getSecurityRulePortMin().shortValue(),
409 portSecurityRule.getSecurityRulePortMax().shortValue());
412 flowId = flowId + "all" + "_";
413 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
415 if (null != srcAddress) {
416 flowId = flowId + srcAddress;
417 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
418 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
419 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
420 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
421 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
422 new Ipv4Prefix(portSecurityRule
423 .getSecurityRuleRemoteIpPrefix()),null);
425 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
426 flowId = flowId + "_Permit";
427 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
431 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
432 Integer securityRulePortMin, Integer protoPortMatchPriority) {
434 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
435 PortNumber tcpPort = new PortNumber(securityRulePortMin);
436 MatchBuilder matchBuilder = new MatchBuilder();
437 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
438 FlowBuilder flowBuilder = new FlowBuilder();
440 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
441 Constants.TCP_SYN, segmentationId).build());
443 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
444 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
445 // Add Flow Attributes
446 flowBuilder.setId(new FlowId(flowId));
447 FlowKey key = new FlowKey(new FlowId(flowId));
448 flowBuilder.setStrict(false);
449 flowBuilder.setPriority(protoPortMatchPriority);
450 flowBuilder.setBarrier(true);
451 flowBuilder.setTableId(this.getTable());
452 flowBuilder.setKey(key);
453 flowBuilder.setFlowName(flowId);
454 flowBuilder.setHardTimeout(0);
455 flowBuilder.setIdleTimeout(0);
458 // Instantiate the Builders for the OF Actions and Instructions
459 InstructionsBuilder isb = new InstructionsBuilder();
460 List<Instruction> instructionsList = Lists.newArrayList();
462 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
464 ib.setKey(new InstructionKey(0));
465 instructionsList.add(ib.build());
466 isb.setInstruction(instructionsList);
468 LOG.debug("Instructions are: {}", ib.getInstruction());
469 // Add InstructionsBuilder to FlowBuilder
470 flowBuilder.setInstructions(isb.build());
471 writeFlow(flowBuilder, nodeBuilder);
473 removeFlow(flowBuilder, nodeBuilder);
477 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
478 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
479 Integer protoPortPrefixMatchPriority) {
481 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
482 PortNumber tcpPort = new PortNumber(securityRulePortMin);
484 MatchBuilder matchBuilder = new MatchBuilder();
485 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
486 FlowBuilder flowBuilder = new FlowBuilder();
487 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
489 flowBuilder.setMatch(MatchUtils
490 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
491 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
493 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
494 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
495 securityRulePortMin + securityRuleIpPrefix;
496 // Add Flow Attributes
497 flowBuilder.setId(new FlowId(flowId));
498 FlowKey key = new FlowKey(new FlowId(flowId));
499 flowBuilder.setStrict(false);
500 flowBuilder.setPriority(protoPortPrefixMatchPriority);
501 flowBuilder.setBarrier(true);
502 flowBuilder.setTableId(this.getTable());
503 flowBuilder.setKey(key);
504 flowBuilder.setFlowName(flowId);
505 flowBuilder.setHardTimeout(0);
506 flowBuilder.setIdleTimeout(0);
509 // Instantiate the Builders for the OF Actions and Instructions
510 InstructionsBuilder isb = new InstructionsBuilder();
512 List<Instruction> instructionsList = Lists.newArrayList();
513 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
515 ib.setKey(new InstructionKey(0));
516 instructionsList.add(ib.build());
517 isb.setInstruction(instructionsList);
519 LOG.debug("Instructions contain: {}", ib.getInstruction());
520 // Add InstructionsBuilder to FlowBuilder
521 flowBuilder.setInstructions(isb.build());
522 writeFlow(flowBuilder, nodeBuilder);
524 removeFlow(flowBuilder, nodeBuilder);
528 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
529 String securityRuleProtcol, Integer protoMatchPriority) {
531 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
533 MatchBuilder matchBuilder = new MatchBuilder();
534 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
535 FlowBuilder flowBuilder = new FlowBuilder();
537 flowBuilder.setMatch(MatchUtils
538 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
539 flowBuilder.setMatch(MatchUtils
540 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
541 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
543 String flowId = "UcastOut_" + segmentationId + "_" +
544 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
545 // Add Flow Attributes
546 flowBuilder.setId(new FlowId(flowId));
547 FlowKey key = new FlowKey(new FlowId(flowId));
548 flowBuilder.setStrict(false);
549 flowBuilder.setPriority(protoMatchPriority);
550 flowBuilder.setBarrier(true);
551 flowBuilder.setTableId(this.getTable());
552 flowBuilder.setKey(key);
553 flowBuilder.setFlowName(flowId);
554 flowBuilder.setHardTimeout(0);
555 flowBuilder.setIdleTimeout(0);
558 // Instantiate the Builders for the OF Actions and Instructions
559 InstructionsBuilder isb = new InstructionsBuilder();
560 List<Instruction> instructionsList = Lists.newArrayList();
562 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
564 ib.setKey(new InstructionKey(1));
565 instructionsList.add(ib.build());
566 isb.setInstruction(instructionsList);
567 LOG.debug("Instructions contain: {}", ib.getInstruction());
569 // Add InstructionsBuilder to FlowBuilder
570 flowBuilder.setInstructions(isb.build());
571 writeFlow(flowBuilder, nodeBuilder);
573 removeFlow(flowBuilder, nodeBuilder);
578 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
579 int priority, boolean write) {
581 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
582 MatchBuilder matchBuilder = new MatchBuilder();
583 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
584 FlowBuilder flowBuilder = new FlowBuilder();
586 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
587 attachedMac, Constants.TCP_SYN, segmentationId).build());
589 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
590 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
591 flowBuilder.setId(new FlowId(flowId));
592 FlowKey key = new FlowKey(new FlowId(flowId));
593 flowBuilder.setStrict(false);
594 flowBuilder.setPriority(priority);
595 flowBuilder.setBarrier(true);
596 flowBuilder.setTableId(this.getTable());
597 flowBuilder.setKey(key);
598 flowBuilder.setFlowName(flowId);
599 flowBuilder.setHardTimeout(0);
600 flowBuilder.setIdleTimeout(0);
603 // Instantiate the Builders for the OF Actions and Instructions
604 InstructionBuilder ib = new InstructionBuilder();
605 InstructionsBuilder isb = new InstructionsBuilder();
607 // Instructions List Stores Individual Instructions
608 List<Instruction> instructions = Lists.newArrayList();
610 // Set the Output Port/Iface
611 InstructionUtils.createDropInstructions(ib);
613 ib.setKey(new InstructionKey(0));
614 instructions.add(ib.build());
616 // Add InstructionBuilder to the Instruction(s)Builder List
617 isb.setInstruction(instructions);
618 LOG.debug("Instructions contain: {}", ib.getInstruction());
619 // Add InstructionsBuilder to FlowBuilder
620 flowBuilder.setInstructions(isb.build());
621 writeFlow(flowBuilder, nodeBuilder);
623 removeFlow(flowBuilder, nodeBuilder);
627 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
628 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
629 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
630 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
631 MatchBuilder matchBuilder = new MatchBuilder();
632 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
633 FlowBuilder flowBuilder = new FlowBuilder();
635 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
637 if (securityRuleIpPrefix != null) {
638 flowBuilder.setMatch(MatchUtils
639 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
642 flowBuilder.setMatch(MatchUtils
643 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
647 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
648 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
649 attachedMac + "_Permit_" + securityRuleIpPrefix;
650 // Add Flow Attributes
651 flowBuilder.setId(new FlowId(flowId));
652 FlowKey key = new FlowKey(new FlowId(flowId));
653 flowBuilder.setStrict(false);
654 flowBuilder.setPriority(protoPortMatchPriority);
655 flowBuilder.setBarrier(true);
656 flowBuilder.setTableId(this.getTable());
657 flowBuilder.setKey(key);
658 flowBuilder.setFlowName(flowId);
659 flowBuilder.setHardTimeout(0);
660 flowBuilder.setIdleTimeout(0);
663 // Instantiate the Builders for the OF Actions and Instructions
664 InstructionBuilder ib = new InstructionBuilder();
665 InstructionsBuilder isb = new InstructionsBuilder();
666 List<Instruction> instructionsList = Lists.newArrayList();
668 ib = this.getMutablePipelineInstructionBuilder();
670 ib.setKey(new InstructionKey(0));
671 instructionsList.add(ib.build());
672 isb.setInstruction(instructionsList);
674 LOG.debug("Instructions contain: {}", ib.getInstruction());
675 // Add InstructionsBuilder to FlowBuilder
676 flowBuilder.setInstructions(isb.build());
677 writeFlow(flowBuilder, nodeBuilder);
679 removeFlow(flowBuilder, nodeBuilder);
684 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
686 * @param dpidLong the dpid
687 * @param segmentationId the segmentation id
688 * @param dhcpMacAddress the DHCP server mac address
689 * @param write is write or delete
690 * @param protoPortMatchPriority the priority
692 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
693 boolean write, Integer protoPortMatchPriority) {
695 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
696 MatchBuilder matchBuilder = new MatchBuilder();
697 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
698 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
699 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
703 * Add or remove flow to the node.
705 * @param flowName the the flow id
706 * @param nodeBuilder the node builder
707 * @param matchBuilder the matchbuilder
708 * @param priority the protocol priority
709 * @param write whether it is a write
710 * @param drop whether it is a drop or forward
712 private void syncFlow(String flowName, NodeBuilder nodeBuilder,
713 MatchBuilder matchBuilder, Integer priority,
714 boolean write, boolean drop) {
715 FlowBuilder flowBuilder = new FlowBuilder();
716 flowBuilder.setMatch(matchBuilder.build());
717 FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
720 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
722 InstructionUtils.createDropInstructions(ib);
725 InstructionsBuilder isb = new InstructionsBuilder();
726 List<Instruction> instructionsList = Lists.newArrayList();
727 ib.setKey(new InstructionKey(0));
728 instructionsList.add(ib.build());
729 isb.setInstruction(instructionsList);
730 flowBuilder.setInstructions(isb.build());
731 writeFlow(flowBuilder, nodeBuilder);
733 removeFlow(flowBuilder, nodeBuilder);
738 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
739 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
740 securityServicesManager =
741 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
742 securityGroupCacheManger =
743 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
747 public void setDependencies(Object impl) {