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);
102 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
109 switch (portSecurityRule.getSecurityRuleProtocol()) {
111 ingressAclTcp(dpid, segmentationId, attachedMac,
112 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
115 ingressAclUdp(dpid, segmentationId, attachedMac,
116 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
119 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
124 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
125 * TODO Some part of the code will be used when conntrack is supported
127 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
128 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
129 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
130 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
131 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
132 .equalsIgnoreCase("0.0.0.0/0"))) {
133 LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
134 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
135 portSecurityRule.getSecurityRulePortMax(),
136 portSecurityRule.getSecurityRuleRemoteIpPrefix());
137 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
138 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
140 ingressACLTcpPortWithPrefix(dpid, segmentationId,
141 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
142 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
146 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
148 /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
149 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
150 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
151 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
152 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
153 .equalsIgnoreCase("0.0.0.0/0"))) {
154 LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
155 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
156 portSecurityRule.getSecurityRulePortMax(),
157 portSecurityRule.getSecurityRuleRemoteIpPrefix());
158 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
159 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
161 ingressACLTcpPortWithPrefix(dpid, segmentationId,
162 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
163 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
167 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
169 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
170 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
171 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
172 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
173 LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
174 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
175 portSecurityRule.getSecurityRulePortMax(),
176 portSecurityRule.getSecurityRuleRemoteIpPrefix());
177 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
179 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
180 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
184 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
186 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
187 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
188 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
189 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
190 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
191 .equalsIgnoreCase("0.0.0.0/0"))) {
192 LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
193 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
194 portSecurityRule.getSecurityRulePortMax(),
195 portSecurityRule.getSecurityRuleRemoteIpPrefix());
196 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
197 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
198 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
202 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
204 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
205 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
206 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
207 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
208 LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
209 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
210 portSecurityRule.getSecurityRulePortMax(),
211 portSecurityRule.getSecurityRuleRemoteIpPrefix());
212 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
214 ingressACLTcpSyn(dpid, segmentationId,
215 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
216 Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
220 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
222 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
223 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
224 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
225 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
226 LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
227 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
228 portSecurityRule.getSecurityRulePortMax(),
229 portSecurityRule.getSecurityRuleRemoteIpPrefix());
230 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
231 Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
232 ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
233 portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
237 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
239 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
240 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
241 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
242 ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
243 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
244 .equalsIgnoreCase("0.0.0.0/0"))) {
245 LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
246 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
247 portSecurityRule.getSecurityRulePortMax(),
248 portSecurityRule.getSecurityRuleRemoteIpPrefix());
249 // No need to drop until UDP/ICMP are implemented
250 // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
251 handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
252 portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
255 LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
261 public void programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
262 long localPort, boolean isLastPortinSubnet,
263 boolean isComputePort, boolean write) {
264 //If this port is the only port in the compute node add the DHCP server rule.
265 if (isLastPortinSubnet && isComputePort ) {
266 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
267 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
272 * Allows IPv4 packet ingress to the destination mac address.
273 * @param dpidLong the dpid
274 * @param segmentationId the segementation id
275 * @param dstMac the destination mac address
276 * @param write add or remove
277 * @param protoPortMatchPriority the protocol match priority.
279 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
280 boolean write, Integer protoPortMatchPriority ) {
281 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
282 MatchBuilder matchBuilder = new MatchBuilder();
283 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
284 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
285 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
286 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
290 * Creates a ingress match to the dst macaddress. If src address is specified
291 * source specific match will be created. Otherwise a match with a CIDR will
293 * @param dpidLong the dpid
294 * @param segmentationId the segmentation id
295 * @param dstMac the destination mac address.
296 * @param portSecurityRule the security rule in the SG
297 * @param srcAddress the destination IP address
298 * @param write add or delete
299 * @param protoPortMatchPriority the protocol match priroty
301 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
302 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
303 Integer protoPortMatchPriority ) {
305 MatchBuilder matchBuilder = new MatchBuilder();
306 FlowBuilder flowBuilder = new FlowBuilder();
307 String flowId = "Ingress_Custom_Tcp" + segmentationId + "_" + dstMac + "_";
308 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
309 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
310 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
311 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
312 portSecurityRule.getSecurityRulePortMin());
314 /*TODO TCP PortRange Match*/
318 if (null != srcAddress) {
319 flowId = flowId + srcAddress;
320 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
321 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
323 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
324 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
325 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
326 new Ipv4Prefix(portSecurityRule
327 .getSecurityRuleRemoteIpPrefix()),null);
329 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
330 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
331 flowId = flowId + "_Permit_";
332 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
337 * Creates a ingress match to the dst macaddress. If src address is specified
338 * source specific match will be created. Otherwise a match with a CIDR will
340 * @param dpidLong the dpid
341 * @param segmentationId the segmentation id
342 * @param dstMac the destination mac address.
343 * @param portSecurityRule the security rule in the SG
344 * @param srcAddress the destination IP address
345 * @param write add or delete
346 * @param protoPortMatchPriority the protocol match priroty
348 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
349 NeutronSecurityRule portSecurityRule, String srcAddress,
350 boolean write, Integer protoPortMatchPriority ) {
351 MatchBuilder matchBuilder = new MatchBuilder();
352 String flowId = "ingressAclUDP" + segmentationId + "_" + dstMac + "_";
353 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
354 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
355 flowId = flowId + portSecurityRule.getSecurityRulePortMin();
356 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
357 portSecurityRule.getSecurityRulePortMin());
359 /*TODO TCP PortRange Match*/
363 if (null != srcAddress) {
364 flowId = flowId + srcAddress;
365 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
366 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
368 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
369 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
370 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
371 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
373 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
374 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
375 flowId = flowId + "_Permit_";
376 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
380 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
381 Integer securityRulePortMin, Integer protoPortMatchPriority) {
383 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
384 PortNumber tcpPort = new PortNumber(securityRulePortMin);
385 MatchBuilder matchBuilder = new MatchBuilder();
386 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
387 FlowBuilder flowBuilder = new FlowBuilder();
389 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
390 Constants.TCP_SYN, segmentationId).build());
392 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
393 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
394 // Add Flow Attributes
395 flowBuilder.setId(new FlowId(flowId));
396 FlowKey key = new FlowKey(new FlowId(flowId));
397 flowBuilder.setStrict(false);
398 flowBuilder.setPriority(protoPortMatchPriority);
399 flowBuilder.setBarrier(true);
400 flowBuilder.setTableId(this.getTable());
401 flowBuilder.setKey(key);
402 flowBuilder.setFlowName(flowId);
403 flowBuilder.setHardTimeout(0);
404 flowBuilder.setIdleTimeout(0);
407 // Instantiate the Builders for the OF Actions and Instructions
408 InstructionsBuilder isb = new InstructionsBuilder();
409 List<Instruction> instructionsList = Lists.newArrayList();
411 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
413 ib.setKey(new InstructionKey(0));
414 instructionsList.add(ib.build());
415 isb.setInstruction(instructionsList);
417 LOG.debug("Instructions are: {}", ib.getInstruction());
418 // Add InstructionsBuilder to FlowBuilder
419 flowBuilder.setInstructions(isb.build());
420 writeFlow(flowBuilder, nodeBuilder);
422 removeFlow(flowBuilder, nodeBuilder);
426 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
427 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
428 Integer protoPortPrefixMatchPriority) {
430 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
431 PortNumber tcpPort = new PortNumber(securityRulePortMin);
433 MatchBuilder matchBuilder = new MatchBuilder();
434 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
435 FlowBuilder flowBuilder = new FlowBuilder();
436 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
438 flowBuilder.setMatch(MatchUtils
439 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
440 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
442 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
443 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
444 securityRulePortMin + securityRuleIpPrefix;
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(protoPortPrefixMatchPriority);
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();
461 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 contain: {}", ib.getInstruction());
469 // Add InstructionsBuilder to FlowBuilder
470 flowBuilder.setInstructions(isb.build());
471 writeFlow(flowBuilder, nodeBuilder);
473 removeFlow(flowBuilder, nodeBuilder);
477 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
478 String securityRuleProtcol, Integer protoMatchPriority) {
480 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
482 MatchBuilder matchBuilder = new MatchBuilder();
483 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
484 FlowBuilder flowBuilder = new FlowBuilder();
486 flowBuilder.setMatch(MatchUtils
487 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
488 flowBuilder.setMatch(MatchUtils
489 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
490 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
492 String flowId = "UcastOut_" + segmentationId + "_" +
493 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
494 // Add Flow Attributes
495 flowBuilder.setId(new FlowId(flowId));
496 FlowKey key = new FlowKey(new FlowId(flowId));
497 flowBuilder.setStrict(false);
498 flowBuilder.setPriority(protoMatchPriority);
499 flowBuilder.setBarrier(true);
500 flowBuilder.setTableId(this.getTable());
501 flowBuilder.setKey(key);
502 flowBuilder.setFlowName(flowId);
503 flowBuilder.setHardTimeout(0);
504 flowBuilder.setIdleTimeout(0);
507 // Instantiate the Builders for the OF Actions and Instructions
508 InstructionsBuilder isb = new InstructionsBuilder();
509 List<Instruction> instructionsList = Lists.newArrayList();
511 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
513 ib.setKey(new InstructionKey(1));
514 instructionsList.add(ib.build());
515 isb.setInstruction(instructionsList);
516 LOG.debug("Instructions contain: {}", ib.getInstruction());
518 // Add InstructionsBuilder to FlowBuilder
519 flowBuilder.setInstructions(isb.build());
520 writeFlow(flowBuilder, nodeBuilder);
522 removeFlow(flowBuilder, nodeBuilder);
527 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
528 int priority, boolean write) {
530 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
531 MatchBuilder matchBuilder = new MatchBuilder();
532 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
533 FlowBuilder flowBuilder = new FlowBuilder();
535 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
536 attachedMac, Constants.TCP_SYN, segmentationId).build());
538 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
539 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
540 flowBuilder.setId(new FlowId(flowId));
541 FlowKey key = new FlowKey(new FlowId(flowId));
542 flowBuilder.setStrict(false);
543 flowBuilder.setPriority(priority);
544 flowBuilder.setBarrier(true);
545 flowBuilder.setTableId(this.getTable());
546 flowBuilder.setKey(key);
547 flowBuilder.setFlowName(flowId);
548 flowBuilder.setHardTimeout(0);
549 flowBuilder.setIdleTimeout(0);
552 // Instantiate the Builders for the OF Actions and Instructions
553 InstructionBuilder ib = new InstructionBuilder();
554 InstructionsBuilder isb = new InstructionsBuilder();
556 // Instructions List Stores Individual Instructions
557 List<Instruction> instructions = Lists.newArrayList();
559 // Set the Output Port/Iface
560 InstructionUtils.createDropInstructions(ib);
562 ib.setKey(new InstructionKey(0));
563 instructions.add(ib.build());
565 // Add InstructionBuilder to the Instruction(s)Builder List
566 isb.setInstruction(instructions);
567 LOG.debug("Instructions contain: {}", ib.getInstruction());
568 // Add InstructionsBuilder to FlowBuilder
569 flowBuilder.setInstructions(isb.build());
570 writeFlow(flowBuilder, nodeBuilder);
572 removeFlow(flowBuilder, nodeBuilder);
576 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
577 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
578 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
579 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
580 MatchBuilder matchBuilder = new MatchBuilder();
581 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
582 FlowBuilder flowBuilder = new FlowBuilder();
584 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
586 if (securityRuleIpPrefix != null) {
587 flowBuilder.setMatch(MatchUtils
588 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
591 flowBuilder.setMatch(MatchUtils
592 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
596 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
597 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
598 attachedMac + "_Permit_" + securityRuleIpPrefix;
599 // Add Flow Attributes
600 flowBuilder.setId(new FlowId(flowId));
601 FlowKey key = new FlowKey(new FlowId(flowId));
602 flowBuilder.setStrict(false);
603 flowBuilder.setPriority(protoPortMatchPriority);
604 flowBuilder.setBarrier(true);
605 flowBuilder.setTableId(this.getTable());
606 flowBuilder.setKey(key);
607 flowBuilder.setFlowName(flowId);
608 flowBuilder.setHardTimeout(0);
609 flowBuilder.setIdleTimeout(0);
612 // Instantiate the Builders for the OF Actions and Instructions
613 InstructionBuilder ib = new InstructionBuilder();
614 InstructionsBuilder isb = new InstructionsBuilder();
615 List<Instruction> instructionsList = Lists.newArrayList();
617 ib = this.getMutablePipelineInstructionBuilder();
619 ib.setKey(new InstructionKey(0));
620 instructionsList.add(ib.build());
621 isb.setInstruction(instructionsList);
623 LOG.debug("Instructions contain: {}", ib.getInstruction());
624 // Add InstructionsBuilder to FlowBuilder
625 flowBuilder.setInstructions(isb.build());
626 writeFlow(flowBuilder, nodeBuilder);
628 removeFlow(flowBuilder, nodeBuilder);
633 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
635 * @param dpidLong the dpid
636 * @param segmentationId the segmentation id
637 * @param dhcpMacAddress the DHCP server mac address
638 * @param write is write or delete
639 * @param protoPortMatchPriority the priority
641 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
642 boolean write, Integer protoPortMatchPriority) {
644 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
645 MatchBuilder matchBuilder = new MatchBuilder();
646 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
647 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
648 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
649 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
650 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
654 * Add or remove flow to the node.
656 * @param flowId the the flow id
657 * @param nodeBuilder the node builder
658 * @param matchBuilder the matchbuilder
659 * @param protoPortMatchPriority the protocol priority
660 * @param write whether it is a write
661 * @param drop whether it is a drop or forward
663 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
664 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
665 boolean write,boolean drop) {
666 FlowBuilder flowBuilder = new FlowBuilder();
667 flowBuilder.setMatch(matchBuilder.build());
668 flowBuilder.setId(new FlowId(flowId));
669 FlowKey key = new FlowKey(new FlowId(flowId));
670 flowBuilder.setStrict(false);
671 flowBuilder.setPriority(protoPortMatchPriority);
672 flowBuilder.setBarrier(true);
673 flowBuilder.setTableId(this.getTable());
674 flowBuilder.setKey(key);
675 flowBuilder.setFlowName(flowId);
676 flowBuilder.setHardTimeout(0);
677 flowBuilder.setIdleTimeout(0);
680 // Instantiate the Builders for the OF Actions and Instructions
681 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
683 InstructionUtils.createDropInstructions(ib);
686 InstructionsBuilder isb = new InstructionsBuilder();
687 List<Instruction> instructionsList = Lists.newArrayList();
688 ib.setKey(new InstructionKey(0));
689 instructionsList.add(ib.build());
690 isb.setInstruction(instructionsList);
691 flowBuilder.setInstructions(isb.build());
692 writeFlow(flowBuilder, nodeBuilder);
694 removeFlow(flowBuilder, nodeBuilder);
700 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
701 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
702 securityServicesManager =
703 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
707 public void setDependencies(Object impl) {