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 java.math.BigInteger;
12 import java.util.List;
14 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
15 import org.opendaylight.neutron.spi.NeutronSecurityRule;
16 import org.opendaylight.neutron.spi.Neutron_IPs;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
21 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
22 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
23 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
24 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
25 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
38 import org.osgi.framework.BundleContext;
39 import org.osgi.framework.ServiceReference;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import com.google.common.collect.Lists;
45 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
47 private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
48 private volatile SecurityServicesManager securityServicesManager;
50 public IngressAclService() {
51 super(Service.INGRESS_ACL);
54 public IngressAclService(Service service) {
59 public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
60 long localPort, NeutronSecurityGroup securityGroup,
61 List<Neutron_IPs> srcAddressList, boolean write) {
63 LOG.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
64 if (securityGroup == null || securityGroup.getSecurityRules() == null) {
68 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
69 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
70 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
72 * Neutron Port Security Acl "ingress" and "IPv4"
73 * Check that the base conditions for flow based Port Security are true:
74 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
75 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
76 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
80 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
81 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
82 LOG.debug("Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
83 if (null == portSecurityRule.getSecurityRuleProtocol()) {
84 ingressAclIPv4(dpid, segmentationId, attachedMac,
85 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
86 } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
87 //Remote Security group is selected
88 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
89 .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
90 if (null != remoteSrcAddressList) {
91 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
92 switch (portSecurityRule.getSecurityRuleProtocol()) {
94 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
95 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
98 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
99 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
101 case MatchUtils.ICMP:
102 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, vmIp.getIpAddress(),
103 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
106 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
113 switch (portSecurityRule.getSecurityRuleProtocol()) {
115 ingressAclTcp(dpid, segmentationId, attachedMac,
116 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
119 ingressAclUdp(dpid, segmentationId, attachedMac,
120 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
122 case MatchUtils.ICMP:
123 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
124 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
127 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
132 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
133 * TODO Some part of the code will be used when conntrack is supported
135 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
136 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
137 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
138 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
139 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
140 .equalsIgnoreCase("0.0.0.0/0"))) {
141 LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
142 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
143 portSecurityRule.getSecurityRulePortMax(),
144 portSecurityRule.getSecurityRuleRemoteIpPrefix());
145 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
146 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
148 ingressACLTcpPortWithPrefix(dpid, segmentationId,
149 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
150 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
154 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
156 /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
157 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
158 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
159 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
160 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
161 .equalsIgnoreCase("0.0.0.0/0"))) {
162 LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
163 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
164 portSecurityRule.getSecurityRulePortMax(),
165 portSecurityRule.getSecurityRuleRemoteIpPrefix());
166 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
167 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
169 ingressACLTcpPortWithPrefix(dpid, segmentationId,
170 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
171 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
175 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
177 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
178 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
179 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
180 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
181 LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
182 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
183 portSecurityRule.getSecurityRulePortMax(),
184 portSecurityRule.getSecurityRuleRemoteIpPrefix());
185 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
187 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
188 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
192 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
194 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
195 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
196 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
197 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
198 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
199 .equalsIgnoreCase("0.0.0.0/0"))) {
200 LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
201 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
202 portSecurityRule.getSecurityRulePortMax(),
203 portSecurityRule.getSecurityRuleRemoteIpPrefix());
204 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
205 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
206 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
210 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
212 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
213 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
214 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
215 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
216 LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
217 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
218 portSecurityRule.getSecurityRulePortMax(),
219 portSecurityRule.getSecurityRuleRemoteIpPrefix());
220 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
222 ingressACLTcpSyn(dpid, segmentationId,
223 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
224 Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
228 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
230 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
231 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
232 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
233 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
234 LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
235 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
236 portSecurityRule.getSecurityRulePortMax(),
237 portSecurityRule.getSecurityRuleRemoteIpPrefix());
238 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
239 Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
240 ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
241 portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
245 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
247 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
248 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
249 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
250 ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
251 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
252 .equalsIgnoreCase("0.0.0.0/0"))) {
253 LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
254 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
255 portSecurityRule.getSecurityRulePortMax(),
256 portSecurityRule.getSecurityRuleRemoteIpPrefix());
257 // No need to drop until UDP/ICMP are implemented
258 // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
259 handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
260 portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
263 LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
269 public void programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
270 long localPort, boolean isLastPortinSubnet,
271 boolean isComputePort, boolean write) {
272 //If this port is the only port in the compute node add the DHCP server rule.
273 if (isLastPortinSubnet && isComputePort ) {
274 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
275 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
280 * Allows IPv4 packet ingress to the destination mac address.
281 * @param dpidLong the dpid
282 * @param segmentationId the segementation id
283 * @param dstMac the destination mac address
284 * @param write add or remove
285 * @param protoPortMatchPriority the protocol match priority.
287 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
288 boolean write, Integer protoPortMatchPriority ) {
289 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
290 MatchBuilder matchBuilder = new MatchBuilder();
291 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
292 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
293 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
294 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
298 * Creates a ingress match to the dst macaddress. If src address is specified
299 * source specific match will be created. Otherwise a match with a CIDR will
301 * @param dpidLong the dpid
302 * @param segmentationId the segmentation id
303 * @param dstMac the destination mac address.
304 * @param portSecurityRule the security rule in the SG
305 * @param srcAddress the destination IP address
306 * @param write add or delete
307 * @param protoPortMatchPriority the protocol match priroty
309 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
310 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
311 Integer protoPortMatchPriority ) {
313 MatchBuilder matchBuilder = new MatchBuilder();
314 FlowBuilder flowBuilder = new FlowBuilder();
315 String flowId = "Ingress_Custom_Tcp" + segmentationId + "_" + dstMac + "_";
316 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
317 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
318 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
319 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
320 portSecurityRule.getSecurityRulePortMin());
322 /*TODO TCP PortRange Match*/
326 if (null != srcAddress) {
327 flowId = flowId + srcAddress;
328 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
329 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
331 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
332 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
333 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
334 new Ipv4Prefix(portSecurityRule
335 .getSecurityRuleRemoteIpPrefix()),null);
337 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
338 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
339 flowId = flowId + "_Permit_";
340 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
345 * Creates a ingress match to the dst macaddress. If src address is specified
346 * source specific match will be created. Otherwise a match with a CIDR will
348 * @param dpidLong the dpid
349 * @param segmentationId the segmentation id
350 * @param dstMac the destination mac address.
351 * @param portSecurityRule the security rule in the SG
352 * @param srcAddress the destination IP address
353 * @param write add or delete
354 * @param protoPortMatchPriority the protocol match priroty
356 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
357 NeutronSecurityRule portSecurityRule, String srcAddress,
358 boolean write, Integer protoPortMatchPriority ) {
359 MatchBuilder matchBuilder = new MatchBuilder();
360 String flowId = "ingressAclUDP" + segmentationId + "_" + dstMac + "_";
361 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
362 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
363 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
364 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
365 portSecurityRule.getSecurityRulePortMin());
367 /*TODO TCP PortRange Match*/
371 if (null != srcAddress) {
372 flowId = flowId + srcAddress;
373 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
374 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
376 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
377 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
378 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
379 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
381 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
382 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
383 flowId = flowId + "_Permit_";
384 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
389 * Creates a ingress match to the dst macaddress. If src address is specified
390 * source specific match will be created. Otherwise a match with a CIDR will
392 * @param dpidLong the dpid
393 * @param segmentationId the segmentation id
394 * @param dstMac the destination mac address.
395 * @param portSecurityRule the security rule in the SG
396 * @param srcAddress the destination IP address
397 * @param write add or delete
398 * @param protoPortMatchPriority the protocol match priority
400 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
401 NeutronSecurityRule portSecurityRule, String srcAddress,
402 boolean write, Integer protoPortMatchPriority) {
404 MatchBuilder matchBuilder = new MatchBuilder();
405 FlowBuilder flowBuilder = new FlowBuilder();
406 String flowId = "ingressAclICMP" + segmentationId + "_" + dstMac;
407 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
408 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
409 portSecurityRule.getSecurityRulePortMin().shortValue(),
410 portSecurityRule.getSecurityRulePortMax().shortValue());
411 if (null != srcAddress) {
412 flowId = flowId + srcAddress;
413 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
414 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
416 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
417 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
418 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
419 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
421 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
422 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
423 flowId = flowId + "_Permit_";
424 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
427 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
428 Integer securityRulePortMin, Integer protoPortMatchPriority) {
430 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
431 PortNumber tcpPort = new PortNumber(securityRulePortMin);
432 MatchBuilder matchBuilder = new MatchBuilder();
433 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
434 FlowBuilder flowBuilder = new FlowBuilder();
436 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
437 Constants.TCP_SYN, segmentationId).build());
439 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
440 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
441 // Add Flow Attributes
442 flowBuilder.setId(new FlowId(flowId));
443 FlowKey key = new FlowKey(new FlowId(flowId));
444 flowBuilder.setStrict(false);
445 flowBuilder.setPriority(protoPortMatchPriority);
446 flowBuilder.setBarrier(true);
447 flowBuilder.setTableId(this.getTable());
448 flowBuilder.setKey(key);
449 flowBuilder.setFlowName(flowId);
450 flowBuilder.setHardTimeout(0);
451 flowBuilder.setIdleTimeout(0);
454 // Instantiate the Builders for the OF Actions and Instructions
455 InstructionsBuilder isb = new InstructionsBuilder();
456 List<Instruction> instructionsList = Lists.newArrayList();
458 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
460 ib.setKey(new InstructionKey(0));
461 instructionsList.add(ib.build());
462 isb.setInstruction(instructionsList);
464 LOG.debug("Instructions are: {}", ib.getInstruction());
465 // Add InstructionsBuilder to FlowBuilder
466 flowBuilder.setInstructions(isb.build());
467 writeFlow(flowBuilder, nodeBuilder);
469 removeFlow(flowBuilder, nodeBuilder);
473 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
474 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
475 Integer protoPortPrefixMatchPriority) {
477 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
478 PortNumber tcpPort = new PortNumber(securityRulePortMin);
480 MatchBuilder matchBuilder = new MatchBuilder();
481 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
482 FlowBuilder flowBuilder = new FlowBuilder();
483 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
485 flowBuilder.setMatch(MatchUtils
486 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
487 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
489 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
490 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
491 securityRulePortMin + securityRuleIpPrefix;
492 // Add Flow Attributes
493 flowBuilder.setId(new FlowId(flowId));
494 FlowKey key = new FlowKey(new FlowId(flowId));
495 flowBuilder.setStrict(false);
496 flowBuilder.setPriority(protoPortPrefixMatchPriority);
497 flowBuilder.setBarrier(true);
498 flowBuilder.setTableId(this.getTable());
499 flowBuilder.setKey(key);
500 flowBuilder.setFlowName(flowId);
501 flowBuilder.setHardTimeout(0);
502 flowBuilder.setIdleTimeout(0);
505 // Instantiate the Builders for the OF Actions and Instructions
506 InstructionsBuilder isb = new InstructionsBuilder();
508 List<Instruction> instructionsList = Lists.newArrayList();
509 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
511 ib.setKey(new InstructionKey(0));
512 instructionsList.add(ib.build());
513 isb.setInstruction(instructionsList);
515 LOG.debug("Instructions contain: {}", ib.getInstruction());
516 // Add InstructionsBuilder to FlowBuilder
517 flowBuilder.setInstructions(isb.build());
518 writeFlow(flowBuilder, nodeBuilder);
520 removeFlow(flowBuilder, nodeBuilder);
524 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
525 String securityRuleProtcol, Integer protoMatchPriority) {
527 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
529 MatchBuilder matchBuilder = new MatchBuilder();
530 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
531 FlowBuilder flowBuilder = new FlowBuilder();
533 flowBuilder.setMatch(MatchUtils
534 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
535 flowBuilder.setMatch(MatchUtils
536 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
537 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
539 String flowId = "UcastOut_" + segmentationId + "_" +
540 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
541 // Add Flow Attributes
542 flowBuilder.setId(new FlowId(flowId));
543 FlowKey key = new FlowKey(new FlowId(flowId));
544 flowBuilder.setStrict(false);
545 flowBuilder.setPriority(protoMatchPriority);
546 flowBuilder.setBarrier(true);
547 flowBuilder.setTableId(this.getTable());
548 flowBuilder.setKey(key);
549 flowBuilder.setFlowName(flowId);
550 flowBuilder.setHardTimeout(0);
551 flowBuilder.setIdleTimeout(0);
554 // Instantiate the Builders for the OF Actions and Instructions
555 InstructionsBuilder isb = new InstructionsBuilder();
556 List<Instruction> instructionsList = Lists.newArrayList();
558 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
560 ib.setKey(new InstructionKey(1));
561 instructionsList.add(ib.build());
562 isb.setInstruction(instructionsList);
563 LOG.debug("Instructions contain: {}", ib.getInstruction());
565 // Add InstructionsBuilder to FlowBuilder
566 flowBuilder.setInstructions(isb.build());
567 writeFlow(flowBuilder, nodeBuilder);
569 removeFlow(flowBuilder, nodeBuilder);
574 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
575 int priority, boolean write) {
577 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
578 MatchBuilder matchBuilder = new MatchBuilder();
579 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
580 FlowBuilder flowBuilder = new FlowBuilder();
582 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
583 attachedMac, Constants.TCP_SYN, segmentationId).build());
585 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
586 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
587 flowBuilder.setId(new FlowId(flowId));
588 FlowKey key = new FlowKey(new FlowId(flowId));
589 flowBuilder.setStrict(false);
590 flowBuilder.setPriority(priority);
591 flowBuilder.setBarrier(true);
592 flowBuilder.setTableId(this.getTable());
593 flowBuilder.setKey(key);
594 flowBuilder.setFlowName(flowId);
595 flowBuilder.setHardTimeout(0);
596 flowBuilder.setIdleTimeout(0);
599 // Instantiate the Builders for the OF Actions and Instructions
600 InstructionBuilder ib = new InstructionBuilder();
601 InstructionsBuilder isb = new InstructionsBuilder();
603 // Instructions List Stores Individual Instructions
604 List<Instruction> instructions = Lists.newArrayList();
606 // Set the Output Port/Iface
607 InstructionUtils.createDropInstructions(ib);
609 ib.setKey(new InstructionKey(0));
610 instructions.add(ib.build());
612 // Add InstructionBuilder to the Instruction(s)Builder List
613 isb.setInstruction(instructions);
614 LOG.debug("Instructions contain: {}", ib.getInstruction());
615 // Add InstructionsBuilder to FlowBuilder
616 flowBuilder.setInstructions(isb.build());
617 writeFlow(flowBuilder, nodeBuilder);
619 removeFlow(flowBuilder, nodeBuilder);
623 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
624 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
625 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
626 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
627 MatchBuilder matchBuilder = new MatchBuilder();
628 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
629 FlowBuilder flowBuilder = new FlowBuilder();
631 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
633 if (securityRuleIpPrefix != null) {
634 flowBuilder.setMatch(MatchUtils
635 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
638 flowBuilder.setMatch(MatchUtils
639 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
643 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
644 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
645 attachedMac + "_Permit_" + securityRuleIpPrefix;
646 // Add Flow Attributes
647 flowBuilder.setId(new FlowId(flowId));
648 FlowKey key = new FlowKey(new FlowId(flowId));
649 flowBuilder.setStrict(false);
650 flowBuilder.setPriority(protoPortMatchPriority);
651 flowBuilder.setBarrier(true);
652 flowBuilder.setTableId(this.getTable());
653 flowBuilder.setKey(key);
654 flowBuilder.setFlowName(flowId);
655 flowBuilder.setHardTimeout(0);
656 flowBuilder.setIdleTimeout(0);
659 // Instantiate the Builders for the OF Actions and Instructions
660 InstructionBuilder ib = new InstructionBuilder();
661 InstructionsBuilder isb = new InstructionsBuilder();
662 List<Instruction> instructionsList = Lists.newArrayList();
664 ib = this.getMutablePipelineInstructionBuilder();
666 ib.setKey(new InstructionKey(0));
667 instructionsList.add(ib.build());
668 isb.setInstruction(instructionsList);
670 LOG.debug("Instructions contain: {}", ib.getInstruction());
671 // Add InstructionsBuilder to FlowBuilder
672 flowBuilder.setInstructions(isb.build());
673 writeFlow(flowBuilder, nodeBuilder);
675 removeFlow(flowBuilder, nodeBuilder);
680 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
682 * @param dpidLong the dpid
683 * @param segmentationId the segmentation id
684 * @param dhcpMacAddress the DHCP server mac address
685 * @param write is write or delete
686 * @param protoPortMatchPriority the priority
688 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
689 boolean write, Integer protoPortMatchPriority) {
691 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
692 MatchBuilder matchBuilder = new MatchBuilder();
693 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
694 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
695 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
696 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
697 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
701 * Add or remove flow to the node.
703 * @param flowId the the flow id
704 * @param nodeBuilder the node builder
705 * @param matchBuilder the matchbuilder
706 * @param protoPortMatchPriority the protocol priority
707 * @param write whether it is a write
708 * @param drop whether it is a drop or forward
710 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
711 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
712 boolean write,boolean drop) {
713 FlowBuilder flowBuilder = new FlowBuilder();
714 flowBuilder.setMatch(matchBuilder.build());
715 flowBuilder.setId(new FlowId(flowId));
716 FlowKey key = new FlowKey(new FlowId(flowId));
717 flowBuilder.setStrict(false);
718 flowBuilder.setPriority(protoPortMatchPriority);
719 flowBuilder.setBarrier(true);
720 flowBuilder.setTableId(this.getTable());
721 flowBuilder.setKey(key);
722 flowBuilder.setFlowName(flowId);
723 flowBuilder.setHardTimeout(0);
724 flowBuilder.setIdleTimeout(0);
727 // Instantiate the Builders for the OF Actions and Instructions
728 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
730 InstructionUtils.createDropInstructions(ib);
733 InstructionsBuilder isb = new InstructionsBuilder();
734 List<Instruction> instructionsList = Lists.newArrayList();
735 ib.setKey(new InstructionKey(0));
736 instructionsList.add(ib.build());
737 isb.setInstruction(instructionsList);
738 flowBuilder.setInstructions(isb.build());
739 writeFlow(flowBuilder, nodeBuilder);
741 removeFlow(flowBuilder, nodeBuilder);
747 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
748 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
749 securityServicesManager =
750 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
754 public void setDependencies(Object impl) {