Fix: enforce packet to go through ingress pipeline inside a node
Change-Id: I04ad1c919a9c82f5526b91d43ba788163da041dd
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index 1be5b35..6352bb2 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -75,6 +75,7 @@
public static final int PRIORITY_DHCP_RULE = 42000;
public static final int PRIORITY_ADMIN_RULE = 32000;
public static final int PRIORITY_ACL_RULE = 31000;
+ public static final int PRIORITY_ACL_INGRESS_RULE = 30000;
public static final int PRIORITY_CT_HOOK_RULE = 30500;
public static final int PRIORITY_CT_RULE = 32000;
public static final int PRIORITY_CT_DROP_RULE = 32500;
@@ -98,8 +99,10 @@
public static final int FLAT_TABLE = 20;
public static final int VTAG_TABLE = 30;
public static final int ARP_TABLE = 35;
- public static final int ACL_TABLE = 40;
- public static final int CT_TABLE = 41;
+ public static final int ACL_EGRESS_TABLE = 40;
+ public static final int ACL_INGRESS_TABLE = 44;
+ public static final int CT_TABLE = 45;
+ public static final int ACL_RECIRC_TABLE = 43;
public static final int JUMP_TABLE = 50;
public static final int ROUTING_TABLE = 60;
public static final int STAT_OUTBOUND_TABLE = 70;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
index 0dc4db7..19e52fc 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
@@ -207,10 +207,10 @@
connectTables(deviceId, Constants.VTAG_TABLE, Constants.ARP_TABLE);
// for ARP and ACL table transition
- connectTables(deviceId, Constants.ARP_TABLE, Constants.ACL_TABLE);
+ connectTables(deviceId, Constants.ARP_TABLE, Constants.ACL_INGRESS_TABLE);
// for ACL and JUMP table transition
- connectTables(deviceId, Constants.ACL_TABLE, Constants.JUMP_TABLE);
+ connectTables(deviceId, Constants.ACL_EGRESS_TABLE, Constants.JUMP_TABLE);
// for JUMP table transition
// we need JUMP table for bypassing routing table which contains large
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index 52eb1ae..3a28831 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -62,6 +62,8 @@
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.SecurityGroup;
import org.openstack4j.model.network.SecurityGroupRule;
@@ -92,11 +94,14 @@
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_INGRESS_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_RECIRC_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.CT_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.ERROR_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.JUMP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ACL_INGRESS_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ACL_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_DROP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_HOOK_RULE;
@@ -288,6 +293,37 @@
ACTION_DROP, PRIORITY_CT_DROP_RULE, install);
}
+ private void initializeAclTable(DeviceId deviceId, boolean install) {
+
+ ExtensionTreatment ctTreatment =
+ niciraConnTrackTreatmentBuilder(driverService, deviceId)
+ .commit(true)
+ .build();
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.extension(ctTreatment, deviceId)
+ .transition(JUMP_TABLE);
+
+ osFlowRuleService.setRule(appId,
+ deviceId,
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_ACL_INGRESS_RULE,
+ ACL_RECIRC_TABLE,
+ install);
+ }
+
+ private void initializeIngressTable(DeviceId deviceId, boolean install) {
+ if (install) {
+ osFlowRuleService.setUpTableMissEntry(deviceId, ACL_INGRESS_TABLE);
+ } else {
+ osFlowRuleService.connectTables(deviceId, ACL_INGRESS_TABLE, JUMP_TABLE);
+ }
+ }
+
private void setSecurityGroupRules(InstancePort instPort,
Port port, boolean install) {
@@ -327,9 +363,9 @@
if (sgRule.getRemoteGroupId() != null && !sgRule.getRemoteGroupId().isEmpty()) {
getRemoteInstPorts(port, sgRule.getRemoteGroupId(), install)
.forEach(rInstPort -> {
- populateSecurityGroupRule(sgRule, instPort, port,
+ populateSecurityGroupRule(sgRule, instPort,
rInstPort.ipAddress().toIpPrefix(), install);
- populateSecurityGroupRule(sgRule, rInstPort, port,
+ populateSecurityGroupRule(sgRule, rInstPort,
instPort.ipAddress().toIpPrefix(), install);
SecurityGroupRule rSgRule =
@@ -339,13 +375,13 @@
.direction(sgRule.getDirection().toUpperCase()
.equals(EGRESS) ? INGRESS : EGRESS)
.build();
- populateSecurityGroupRule(rSgRule, instPort, port,
+ populateSecurityGroupRule(rSgRule, instPort,
rInstPort.ipAddress().toIpPrefix(), install);
- populateSecurityGroupRule(rSgRule, rInstPort, port,
+ populateSecurityGroupRule(rSgRule, rInstPort,
instPort.ipAddress().toIpPrefix(), install);
});
} else {
- populateSecurityGroupRule(sgRule, instPort, port,
+ populateSecurityGroupRule(sgRule, instPort,
sgRule.getRemoteIpPrefix() == null ? IP_PREFIX_ANY :
IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install);
}
@@ -353,11 +389,11 @@
private void populateSecurityGroupRule(SecurityGroupRule sgRule,
InstancePort instPort,
- Port port,
IpPrefix remoteIp,
boolean install) {
Set<TrafficSelector> selectors = buildSelectors(sgRule,
- Ip4Address.valueOf(instPort.ipAddress().toInetAddress()), remoteIp, port);
+ Ip4Address.valueOf(instPort.ipAddress().toInetAddress()),
+ remoteIp, instPort.networkId());
if (selectors == null || selectors.isEmpty()) {
return;
}
@@ -369,18 +405,27 @@
.commit(true)
.build();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .extension(ctTreatment, instPort.deviceId())
- .transition(JUMP_TABLE)
- .build();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
- selectors.forEach(selector ->
- osFlowRuleService.setRule(appId,
- instPort.deviceId(),
- selector, treatment,
- PRIORITY_ACL_RULE,
- ACL_TABLE,
- install));
+ int aclTable;
+ if (sgRule.getDirection().toUpperCase().equals(EGRESS)) {
+ aclTable = ACL_EGRESS_TABLE;
+ tBuilder.transition(ACL_RECIRC_TABLE);
+ } else {
+ aclTable = ACL_INGRESS_TABLE;
+ tBuilder.extension(ctTreatment, instPort.deviceId())
+ .transition(JUMP_TABLE);
+ }
+
+ int finalAclTable = aclTable;
+ selectors.forEach(selector -> {
+ osFlowRuleService.setRule(appId,
+ instPort.deviceId(),
+ selector, tBuilder.build(),
+ PRIORITY_ACL_RULE,
+ finalAclTable,
+ install);
+ });
}
/**
@@ -440,7 +485,7 @@
if (priority == PRIORITY_CT_RULE || priority == PRIORITY_CT_DROP_RULE) {
tableType = CT_TABLE;
} else if (priority == PRIORITY_CT_HOOK_RULE) {
- tableType = ACL_TABLE;
+ tableType = ACL_INGRESS_TABLE;
} else {
log.error("Cannot an appropriate table for the conn track rule.");
}
@@ -488,7 +533,7 @@
private Set<TrafficSelector> buildSelectors(SecurityGroupRule sgRule,
Ip4Address vmIp,
IpPrefix remoteIp,
- Port port) {
+ String netId) {
if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, VM_IP_PREFIX))) {
// do nothing if the remote IP is my IP
return null;
@@ -497,7 +542,7 @@
Set<TrafficSelector> selectorSet = Sets.newHashSet();
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
- buildMatches(sBuilder, sgRule, vmIp, remoteIp, port);
+ buildMatches(sBuilder, sgRule, vmIp, remoteIp, netId);
if (sgRule.getPortRangeMax() != null && sgRule.getPortRangeMin() != null &&
sgRule.getPortRangeMin() < sgRule.getPortRangeMax()) {
@@ -530,9 +575,9 @@
}
private void buildMatches(TrafficSelector.Builder sBuilder,
- SecurityGroupRule sgRule,
- Ip4Address vmIp, IpPrefix remoteIp, Port port) {
- buildTunnelId(sBuilder, port);
+ SecurityGroupRule sgRule, Ip4Address vmIp,
+ IpPrefix remoteIp, String netId) {
+ buildTunnelId(sBuilder, netId);
buildMatchEthType(sBuilder, sgRule.getEtherType());
buildMatchDirection(sBuilder, sgRule.getDirection(), vmIp);
buildMatchProto(sBuilder, sgRule.getProtocol());
@@ -542,9 +587,9 @@
buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection());
}
- private void buildTunnelId(TrafficSelector.Builder sBuilder, Port port) {
- String segId = osNetService.segmentId(port.getNetworkId());
- String netType = osNetService.networkType(port.getNetworkId());
+ private void buildTunnelId(TrafficSelector.Builder sBuilder, String netId) {
+ String segId = osNetService.segmentId(netId);
+ String netType = osNetService.networkType(netId);
if (VLAN.equals(netType)) {
sBuilder.matchVlanId(VlanId.vlanId(segId));
@@ -627,16 +672,20 @@
if (useSecurityGroup) {
osNodeService.completeNodes(COMPUTE).forEach(node -> {
- osFlowRuleService.setUpTableMissEntry(node.intgBridge(), ACL_TABLE);
+ osFlowRuleService.setUpTableMissEntry(node.intgBridge(), ACL_EGRESS_TABLE);
initializeConnTrackTable(node.intgBridge(), true);
+ initializeAclTable(node.intgBridge(), true);
+ initializeIngressTable(node.intgBridge(), true);
});
securityGroupService.securityGroups().forEach(securityGroup ->
securityGroup.getRules().forEach(this::securityGroupRuleAdded));
} else {
osNodeService.completeNodes(COMPUTE).forEach(node -> {
- osFlowRuleService.connectTables(node.intgBridge(), ACL_TABLE, JUMP_TABLE);
+ osFlowRuleService.connectTables(node.intgBridge(), ACL_EGRESS_TABLE, JUMP_TABLE);
initializeConnTrackTable(node.intgBridge(), false);
+ initializeAclTable(node.intgBridge(), false);
+ initializeIngressTable(node.intgBridge(), false);
});
securityGroupService.securityGroups().forEach(securityGroup ->
@@ -780,6 +829,7 @@
}
installSecurityGroupRules(event, instPort);
+ setAclRecircRules(instPort, true);
});
break;
case OPENSTACK_INSTANCE_PORT_VANISHED:
@@ -792,6 +842,7 @@
Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
setSecurityGroupRules(instPort, osPort, false);
removedOsPortStore.remove(instPort.portId());
+ setAclRecircRules(instPort, false);
});
break;
case OPENSTACK_INSTANCE_MIGRATION_ENDED:
@@ -804,6 +855,7 @@
InstancePort revisedInstPort = swapStaleLocation(instPort);
Port port = osNetService.port(instPort.portId());
setSecurityGroupRules(revisedInstPort, port, false);
+ setAclRecircRules(revisedInstPort, false);
});
break;
default:
@@ -820,6 +872,40 @@
setSecurityGroupRules(instPort,
osNetService.port(event.subject().portId()), true));
}
+
+ private void setAclRecircRules(InstancePort instPort, boolean install) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+
+ Network net = osNetService.network(instPort.networkId());
+ NetworkType netType = net.getNetworkType();
+ String segId = net.getProviderSegID();
+
+ switch (netType) {
+ case VXLAN:
+ sBuilder.matchTunnelId(Long.valueOf(segId));
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segId));
+ break;
+ default:
+ break;
+ }
+
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4);
+ sBuilder.matchIPDst(IpPrefix.valueOf(instPort.ipAddress(), VM_IP_PREFIX));
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.transition(ACL_INGRESS_TABLE);
+
+ osFlowRuleService.setRule(
+ appId,
+ instPort.deviceId(),
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_ACL_RULE,
+ ACL_RECIRC_TABLE,
+ install);
+ }
}
private class InternalOpenstackPortListener implements OpenstackNetworkListener {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 196c07d..9bd06ef 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -60,7 +60,7 @@
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.DHCP_TABLE;
@@ -503,7 +503,7 @@
if (ethType == Ethernet.TYPE_ARP) {
tBuilder.transition(ARP_TABLE);
} else if (ethType == Ethernet.TYPE_IPV4) {
- tBuilder.transition(ACL_TABLE);
+ tBuilder.transition(ACL_EGRESS_TABLE);
}
osFlowRuleService.setRule(
@@ -547,7 +547,7 @@
if (ethType == Ethernet.TYPE_ARP) {
tBuilder.transition(ARP_TABLE);
} else if (ethType == Ethernet.TYPE_IPV4) {
- tBuilder.transition(ACL_TABLE);
+ tBuilder.transition(ACL_EGRESS_TABLE);
}
osFlowRuleService.setRule(
@@ -599,7 +599,7 @@
selector,
treatment,
PRIORITY_ADMIN_RULE,
- ACL_TABLE,
+ ACL_EGRESS_TABLE,
install)
);
}
@@ -621,7 +621,7 @@
selector,
treatment,
PRIORITY_ADMIN_RULE,
- ACL_TABLE,
+ ACL_EGRESS_TABLE,
install)
);
}
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManagerTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManagerTest.java
index d1410b2..ed73636 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManagerTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManagerTest.java
@@ -44,7 +44,8 @@
import java.util.Set;
import static org.junit.Assert.assertEquals;
-import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_INGRESS_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.DHCP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.FLAT_TABLE;
@@ -195,8 +196,8 @@
fromToTableMap.put(VTAP_INBOUND_TABLE, DHCP_TABLE);
fromToTableMap.put(DHCP_TABLE, VTAG_TABLE);
fromToTableMap.put(VTAG_TABLE, ARP_TABLE);
- fromToTableMap.put(ARP_TABLE, ACL_TABLE);
- fromToTableMap.put(ACL_TABLE, JUMP_TABLE);
+ fromToTableMap.put(ARP_TABLE, ACL_INGRESS_TABLE);
+ fromToTableMap.put(ACL_EGRESS_TABLE, JUMP_TABLE);
fromToTableMap.put(STAT_OUTBOUND_TABLE, VTAP_OUTBOUND_TABLE);
fromToTableMap.put(VTAP_OUTBOUND_TABLE, FORWARDING_TABLE);
fromToTableMap.put(STAT_FLAT_OUTBOUND_TABLE, VTAP_FLAT_OUTBOUND_TABLE);
diff --git a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java
index c2f4b22..4017fdd 100644
--- a/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java
+++ b/apps/openstacktroubleshoot/app/src/main/java/org/onosproject/openstacktroubleshoot/impl/OpenstackTroubleshootManager.java
@@ -84,7 +84,7 @@
import static org.onosproject.net.flow.FlowEntry.FlowEntryState.ADDED;
import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_SRC;
-import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_EXTERNAL_ROUTER_MAC;
import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_GATEWAY_MAC;
import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
@@ -353,7 +353,7 @@
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder()
.setTunnelId(getSegId(osNetworkService, port))
- .transition(ACL_TABLE);
+ .transition(ACL_EGRESS_TABLE);
osFlowRuleService.setRule(
appId,