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.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
15 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
16 import org.opendaylight.ovsdb.openstack.netvirt.translator.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;
49 private static final int PORT_RANGE_MIN = 1;
50 private static final int PORT_RANGE_MAX = 65535;
52 public IngressAclService() {
53 super(Service.INGRESS_ACL);
56 public IngressAclService(Service service) {
61 public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
62 long localPort, NeutronSecurityGroup securityGroup,
63 List<Neutron_IPs> srcAddressList, boolean write) {
65 LOG.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
66 if (securityGroup == null || securityGroup.getSecurityRules() == null) {
70 List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
71 /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
72 for (NeutronSecurityRule portSecurityRule : portSecurityList) {
74 * Neutron Port Security Acl "ingress" and "IPv4"
75 * Check that the base conditions for flow based Port Security are true:
76 * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
77 * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
78 * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
82 if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
83 && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
84 LOG.debug("Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
85 if (null == portSecurityRule.getSecurityRuleProtocol()) {
86 ingressAclIPv4(dpid, segmentationId, attachedMac,
87 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
88 } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
89 //Remote Security group is selected
90 List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
91 .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
92 if (null != remoteSrcAddressList) {
93 for (Neutron_IPs vmIp :remoteSrcAddressList ) {
94 switch (portSecurityRule.getSecurityRuleProtocol()) {
96 ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule,
97 vmIp.getIpAddress(),write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
100 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,
101 vmIp.getIpAddress(), write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
103 case MatchUtils.ICMP:
104 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule,
105 vmIp.getIpAddress(), write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
108 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
115 switch (portSecurityRule.getSecurityRuleProtocol()) {
117 ingressAclTcp(dpid, segmentationId, attachedMac,
118 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
121 ingressAclUdp(dpid, segmentationId, attachedMac,
122 portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
124 case MatchUtils.ICMP:
125 ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
126 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
129 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
134 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
135 * TODO Some part of the code will be used when conntrack is supported
137 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
138 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
139 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
140 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
141 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
142 .equalsIgnoreCase("0.0.0.0/0"))) {
143 LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
144 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
145 portSecurityRule.getSecurityRulePortMax(),
146 portSecurityRule.getSecurityRuleRemoteIpPrefix());
147 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
148 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
150 ingressACLTcpPortWithPrefix(dpid, segmentationId,
151 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
152 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
156 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
158 /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
159 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
160 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
161 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
162 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
163 .equalsIgnoreCase("0.0.0.0/0"))) {
164 LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
165 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
166 portSecurityRule.getSecurityRulePortMax(),
167 portSecurityRule.getSecurityRuleRemoteIpPrefix());
168 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
169 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
171 ingressACLTcpPortWithPrefix(dpid, segmentationId,
172 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
173 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
177 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
179 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
180 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
181 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
182 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
183 LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
184 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
185 portSecurityRule.getSecurityRulePortMax(),
186 portSecurityRule.getSecurityRuleRemoteIpPrefix());
187 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
189 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
190 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
194 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
196 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
197 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
198 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
199 (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
200 !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
201 .equalsIgnoreCase("0.0.0.0/0"))) {
202 LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
203 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
204 portSecurityRule.getSecurityRulePortMax(),
205 portSecurityRule.getSecurityRuleRemoteIpPrefix());
206 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
207 ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
208 portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
212 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
214 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
215 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
216 !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
217 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
218 LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
219 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
220 portSecurityRule.getSecurityRulePortMax(),
221 portSecurityRule.getSecurityRuleRemoteIpPrefix());
222 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
224 ingressACLTcpSyn(dpid, segmentationId,
225 attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
226 Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
230 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
232 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
233 !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
234 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
235 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
236 LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
237 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
238 portSecurityRule.getSecurityRulePortMax(),
239 portSecurityRule.getSecurityRuleRemoteIpPrefix());
240 ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
241 Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
242 ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
243 portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
247 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
249 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
250 String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
251 String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
252 ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
253 String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
254 .equalsIgnoreCase("0.0.0.0/0"))) {
255 LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
256 portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
257 portSecurityRule.getSecurityRulePortMax(),
258 portSecurityRule.getSecurityRuleRemoteIpPrefix());
259 // No need to drop until UDP/ICMP are implemented
260 // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
261 handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
262 portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
265 LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
271 public void programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
272 long localPort, boolean isLastPortinSubnet,
273 boolean isComputePort, boolean write) {
274 //If this port is the only port in the compute node add the DHCP server rule.
275 if (isLastPortinSubnet && isComputePort ) {
276 ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
277 write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
282 * Allows IPv4 packet ingress to the destination mac address.
283 * @param dpidLong the dpid
284 * @param segmentationId the segementation id
285 * @param dstMac the destination mac address
286 * @param write add or remove
287 * @param protoPortMatchPriority the protocol match priority.
289 private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
290 boolean write, Integer protoPortMatchPriority ) {
291 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
292 MatchBuilder matchBuilder = new MatchBuilder();
293 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
294 String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
295 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
296 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
300 * Creates a ingress match to the dst macaddress. If src address is specified
301 * source specific match will be created. Otherwise a match with a CIDR will
303 * @param dpidLong the dpid
304 * @param segmentationId the segmentation id
305 * @param dstMac the destination mac address.
306 * @param portSecurityRule the security rule in the SG
307 * @param srcAddress the destination IP address
308 * @param write add or delete
309 * @param protoPortMatchPriority the protocol match priroty
311 private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
312 NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
313 Integer protoPortMatchPriority ) {
315 MatchBuilder matchBuilder = new MatchBuilder();
316 FlowBuilder flowBuilder = new FlowBuilder();
317 String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
318 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
320 /* Custom TCP Match*/
321 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
322 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
323 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
324 portSecurityRule.getSecurityRulePortMin());
327 if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
328 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
329 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
330 portSecurityRule.getSecurityRulePortMax()+ "_";
331 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
333 /*TODO TCP PortRange Match*/
337 if (null != srcAddress) {
338 flowId = flowId + srcAddress;
339 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
340 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
342 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
343 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
344 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
345 new Ipv4Prefix(portSecurityRule
346 .getSecurityRuleRemoteIpPrefix()),null);
348 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
349 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
350 flowId = flowId + "_Permit";
351 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
356 * Creates a ingress match to the dst macaddress. If src address is specified
357 * source specific match will be created. Otherwise a match with a CIDR will
359 * @param dpidLong the dpid
360 * @param segmentationId the segmentation id
361 * @param dstMac the destination mac address.
362 * @param portSecurityRule the security rule in the SG
363 * @param srcAddress the destination IP address
364 * @param write add or delete
365 * @param protoPortMatchPriority the protocol match priroty
367 private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
368 NeutronSecurityRule portSecurityRule, String srcAddress,
369 boolean write, Integer protoPortMatchPriority ) {
370 MatchBuilder matchBuilder = new MatchBuilder();
371 String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
372 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
374 /* Custom UDP Match */
375 if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
376 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
377 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
378 portSecurityRule.getSecurityRulePortMin());
381 if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
382 && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
383 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
384 portSecurityRule.getSecurityRulePortMax()+ "_";
385 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
387 /*TODO TCP PortRange Match*/
391 if (null != srcAddress) {
392 flowId = flowId + srcAddress;
393 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
394 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
396 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
397 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
398 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
399 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
401 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
402 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
403 flowId = flowId + "_Permit";
404 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
409 * Creates a ingress match to the dst macaddress. If src address is specified
410 * source specific match will be created. Otherwise a match with a CIDR will
412 * @param dpidLong the dpid
413 * @param segmentationId the segmentation id
414 * @param dstMac the destination mac address.
415 * @param portSecurityRule the security rule in the SG
416 * @param srcAddress the destination IP address
417 * @param write add or delete
418 * @param protoPortMatchPriority the protocol match priority
420 private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
421 NeutronSecurityRule portSecurityRule, String srcAddress,
422 boolean write, Integer protoPortMatchPriority) {
424 MatchBuilder matchBuilder = new MatchBuilder();
425 FlowBuilder flowBuilder = new FlowBuilder();
426 String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_"
427 + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
428 + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";;
429 matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
430 matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
431 portSecurityRule.getSecurityRulePortMin().shortValue(),
432 portSecurityRule.getSecurityRulePortMax().shortValue());
433 if (null != srcAddress) {
434 flowId = flowId + srcAddress;
435 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
436 MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
438 } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
439 flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
440 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
441 new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
443 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
444 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
445 flowId = flowId + "_Permit";
446 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
449 public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
450 Integer securityRulePortMin, Integer protoPortMatchPriority) {
452 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
453 PortNumber tcpPort = new PortNumber(securityRulePortMin);
454 MatchBuilder matchBuilder = new MatchBuilder();
455 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
456 FlowBuilder flowBuilder = new FlowBuilder();
458 flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
459 Constants.TCP_SYN, segmentationId).build());
461 LOG.debug("ingressACLTcpSyn MatchBuilder contains: {}", flowBuilder.getMatch());
462 String flowId = "UcastOut_ACL2_" + segmentationId + "_" + attachedMac + securityRulePortMin;
463 // Add Flow Attributes
464 flowBuilder.setId(new FlowId(flowId));
465 FlowKey key = new FlowKey(new FlowId(flowId));
466 flowBuilder.setStrict(false);
467 flowBuilder.setPriority(protoPortMatchPriority);
468 flowBuilder.setBarrier(true);
469 flowBuilder.setTableId(this.getTable());
470 flowBuilder.setKey(key);
471 flowBuilder.setFlowName(flowId);
472 flowBuilder.setHardTimeout(0);
473 flowBuilder.setIdleTimeout(0);
476 // Instantiate the Builders for the OF Actions and Instructions
477 InstructionsBuilder isb = new InstructionsBuilder();
478 List<Instruction> instructionsList = Lists.newArrayList();
480 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
482 ib.setKey(new InstructionKey(0));
483 instructionsList.add(ib.build());
484 isb.setInstruction(instructionsList);
486 LOG.debug("Instructions are: {}", ib.getInstruction());
487 // Add InstructionsBuilder to FlowBuilder
488 flowBuilder.setInstructions(isb.build());
489 writeFlow(flowBuilder, nodeBuilder);
491 removeFlow(flowBuilder, nodeBuilder);
495 public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
496 boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
497 Integer protoPortPrefixMatchPriority) {
499 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
500 PortNumber tcpPort = new PortNumber(securityRulePortMin);
502 MatchBuilder matchBuilder = new MatchBuilder();
503 NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
504 FlowBuilder flowBuilder = new FlowBuilder();
505 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
507 flowBuilder.setMatch(MatchUtils
508 .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
509 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
511 LOG.debug(" MatchBuilder contains: {}", flowBuilder.getMatch());
512 String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
513 securityRulePortMin + securityRuleIpPrefix;
514 // Add Flow Attributes
515 flowBuilder.setId(new FlowId(flowId));
516 FlowKey key = new FlowKey(new FlowId(flowId));
517 flowBuilder.setStrict(false);
518 flowBuilder.setPriority(protoPortPrefixMatchPriority);
519 flowBuilder.setBarrier(true);
520 flowBuilder.setTableId(this.getTable());
521 flowBuilder.setKey(key);
522 flowBuilder.setFlowName(flowId);
523 flowBuilder.setHardTimeout(0);
524 flowBuilder.setIdleTimeout(0);
527 // Instantiate the Builders for the OF Actions and Instructions
528 InstructionsBuilder isb = new InstructionsBuilder();
530 List<Instruction> instructionsList = Lists.newArrayList();
531 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
533 ib.setKey(new InstructionKey(0));
534 instructionsList.add(ib.build());
535 isb.setInstruction(instructionsList);
537 LOG.debug("Instructions contain: {}", ib.getInstruction());
538 // Add InstructionsBuilder to FlowBuilder
539 flowBuilder.setInstructions(isb.build());
540 writeFlow(flowBuilder, nodeBuilder);
542 removeFlow(flowBuilder, nodeBuilder);
546 public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
547 String securityRuleProtcol, Integer protoMatchPriority) {
549 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
551 MatchBuilder matchBuilder = new MatchBuilder();
552 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
553 FlowBuilder flowBuilder = new FlowBuilder();
555 flowBuilder.setMatch(MatchUtils
556 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
557 flowBuilder.setMatch(MatchUtils
558 .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
559 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
561 String flowId = "UcastOut_" + segmentationId + "_" +
562 attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
563 // Add Flow Attributes
564 flowBuilder.setId(new FlowId(flowId));
565 FlowKey key = new FlowKey(new FlowId(flowId));
566 flowBuilder.setStrict(false);
567 flowBuilder.setPriority(protoMatchPriority);
568 flowBuilder.setBarrier(true);
569 flowBuilder.setTableId(this.getTable());
570 flowBuilder.setKey(key);
571 flowBuilder.setFlowName(flowId);
572 flowBuilder.setHardTimeout(0);
573 flowBuilder.setIdleTimeout(0);
576 // Instantiate the Builders for the OF Actions and Instructions
577 InstructionsBuilder isb = new InstructionsBuilder();
578 List<Instruction> instructionsList = Lists.newArrayList();
580 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
582 ib.setKey(new InstructionKey(1));
583 instructionsList.add(ib.build());
584 isb.setInstruction(instructionsList);
585 LOG.debug("Instructions contain: {}", ib.getInstruction());
587 // Add InstructionsBuilder to FlowBuilder
588 flowBuilder.setInstructions(isb.build());
589 writeFlow(flowBuilder, nodeBuilder);
591 removeFlow(flowBuilder, nodeBuilder);
596 public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
597 int priority, boolean write) {
599 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
600 MatchBuilder matchBuilder = new MatchBuilder();
601 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
602 FlowBuilder flowBuilder = new FlowBuilder();
604 flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
605 attachedMac, Constants.TCP_SYN, segmentationId).build());
607 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
608 String flowId = "PortSec_TCP_Syn_Default_Drop_" + segmentationId + "_" + attachedMac;
609 flowBuilder.setId(new FlowId(flowId));
610 FlowKey key = new FlowKey(new FlowId(flowId));
611 flowBuilder.setStrict(false);
612 flowBuilder.setPriority(priority);
613 flowBuilder.setBarrier(true);
614 flowBuilder.setTableId(this.getTable());
615 flowBuilder.setKey(key);
616 flowBuilder.setFlowName(flowId);
617 flowBuilder.setHardTimeout(0);
618 flowBuilder.setIdleTimeout(0);
621 // Instantiate the Builders for the OF Actions and Instructions
622 InstructionBuilder ib = new InstructionBuilder();
623 InstructionsBuilder isb = new InstructionsBuilder();
625 // Instructions List Stores Individual Instructions
626 List<Instruction> instructions = Lists.newArrayList();
628 // Set the Output Port/Iface
629 InstructionUtils.createDropInstructions(ib);
631 ib.setKey(new InstructionKey(0));
632 instructions.add(ib.build());
634 // Add InstructionBuilder to the Instruction(s)Builder List
635 isb.setInstruction(instructions);
636 LOG.debug("Instructions contain: {}", ib.getInstruction());
637 // Add InstructionsBuilder to FlowBuilder
638 flowBuilder.setInstructions(isb.build());
639 writeFlow(flowBuilder, nodeBuilder);
641 removeFlow(flowBuilder, nodeBuilder);
645 public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
646 boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
647 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
648 Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
649 MatchBuilder matchBuilder = new MatchBuilder();
650 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
651 FlowBuilder flowBuilder = new FlowBuilder();
653 flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
655 if (securityRuleIpPrefix != null) {
656 flowBuilder.setMatch(MatchUtils
657 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
660 flowBuilder.setMatch(MatchUtils
661 .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
665 LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
666 String flowId = "IngressProto_ACL_" + segmentationId + "_" +
667 attachedMac + "_Permit_" + securityRuleIpPrefix;
668 // Add Flow Attributes
669 flowBuilder.setId(new FlowId(flowId));
670 FlowKey key = new FlowKey(new FlowId(flowId));
671 flowBuilder.setStrict(false);
672 flowBuilder.setPriority(protoPortMatchPriority);
673 flowBuilder.setBarrier(true);
674 flowBuilder.setTableId(this.getTable());
675 flowBuilder.setKey(key);
676 flowBuilder.setFlowName(flowId);
677 flowBuilder.setHardTimeout(0);
678 flowBuilder.setIdleTimeout(0);
681 // Instantiate the Builders for the OF Actions and Instructions
682 InstructionBuilder ib = new InstructionBuilder();
683 InstructionsBuilder isb = new InstructionsBuilder();
684 List<Instruction> instructionsList = Lists.newArrayList();
686 ib = this.getMutablePipelineInstructionBuilder();
688 ib.setKey(new InstructionKey(0));
689 instructionsList.add(ib.build());
690 isb.setInstruction(instructionsList);
692 LOG.debug("Instructions contain: {}", ib.getInstruction());
693 // Add InstructionsBuilder to FlowBuilder
694 flowBuilder.setInstructions(isb.build());
695 writeFlow(flowBuilder, nodeBuilder);
697 removeFlow(flowBuilder, nodeBuilder);
702 * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
704 * @param dpidLong the dpid
705 * @param segmentationId the segmentation id
706 * @param dhcpMacAddress the DHCP server mac address
707 * @param write is write or delete
708 * @param protoPortMatchPriority the priority
710 private void ingressAclDhcpAllowServerTraffic(Long dpidLong, String segmentationId, String dhcpMacAddress,
711 boolean write, Integer protoPortMatchPriority) {
713 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
714 MatchBuilder matchBuilder = new MatchBuilder();
715 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
716 MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
717 LOG.debug("ingressAclDHCPAllowServerTraffic: MatchBuilder contains: {}", matchBuilder);
718 String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
719 syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
723 * Add or remove flow to the node.
725 * @param flowId the the flow id
726 * @param nodeBuilder the node builder
727 * @param matchBuilder the matchbuilder
728 * @param protoPortMatchPriority the protocol priority
729 * @param write whether it is a write
730 * @param drop whether it is a drop or forward
732 private void syncFlow(String flowId, NodeBuilder nodeBuilder,
733 MatchBuilder matchBuilder,Integer protoPortMatchPriority,
734 boolean write,boolean drop) {
735 FlowBuilder flowBuilder = new FlowBuilder();
736 flowBuilder.setMatch(matchBuilder.build());
737 flowBuilder.setId(new FlowId(flowId));
738 FlowKey key = new FlowKey(new FlowId(flowId));
739 flowBuilder.setStrict(false);
740 flowBuilder.setPriority(protoPortMatchPriority);
741 flowBuilder.setBarrier(true);
742 flowBuilder.setTableId(this.getTable());
743 flowBuilder.setKey(key);
744 flowBuilder.setFlowName(flowId);
745 flowBuilder.setHardTimeout(0);
746 flowBuilder.setIdleTimeout(0);
749 // Instantiate the Builders for the OF Actions and Instructions
750 InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
752 InstructionUtils.createDropInstructions(ib);
755 InstructionsBuilder isb = new InstructionsBuilder();
756 List<Instruction> instructionsList = Lists.newArrayList();
757 ib.setKey(new InstructionKey(0));
758 instructionsList.add(ib.build());
759 isb.setInstruction(instructionsList);
760 flowBuilder.setInstructions(isb.build());
761 writeFlow(flowBuilder, nodeBuilder);
763 removeFlow(flowBuilder, nodeBuilder);
769 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
770 super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
771 securityServicesManager =
772 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
776 public void setDependencies(Object impl) {