/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
import org.opendaylight.groupbasedpolicy.dto.ConditionGroup;
import org.opendaylight.groupbasedpolicy.dto.EgKey;
import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockOfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.MockEndpointManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;
import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({PolicyManager.class, SfcProviderServicePathAPI.class})
public class PolicyEnforcerTest extends MapperUtilsTest {
private static final String SFC_CHAIN = "sfc-chain";
private static final String TCP_DST = "tcp_dst_80";
private static final int sameEpgFlows = 1;
private static final int allowTunnelFlows = 1;
private static final int layer4flowsIPv4 = 1;
private static final int layer4flowsIPv6 = 1;
private NodeConnectorId tunnelId = new NodeConnectorId(NODE_ID.getValue() + ":42");
private NodeConnectorId nodeConnector = new NodeConnectorId(NODE_ID.getValue() + CONNECTOR_0);
// custom mock instances to avoid downcasting of parent's fields
private MockEndpointManager endpointManagerMock;
private MockPolicyManager policyManagerMock;
private MockSwitchManager switchManagerMock;
private MockOfContext ctxMock;
private ActionInstance allowActionInstance;
private ActionInstance chainActionInstance;
@Before
public void init() {
PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true);
endpointManagerMock = new MockEndpointManager();
policyManagerMock = new MockPolicyManager(endpointManagerMock);
switchManagerMock = new MockSwitchManager();
ctxMock = new MockOfContext(null, policyManagerMock, switchManagerMock, endpointManagerMock, null);
table = new PolicyEnforcer(ctxMock, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER());
ServiceFunctionPath path = new ServiceFunctionPathBuilder().setName(new SfpName("sfp-name"))
.setServiceChainName(new SfcName(SFC_CHAIN))
.setSymmetric(true)
.build();
ServiceFunctionPaths paths =
new ServiceFunctionPathsBuilder().setServiceFunctionPath(ImmutableList.of(path)).build();
PowerMockito.mockStatic(SfcProviderServicePathAPI.class);
when(SfcProviderServicePathAPI.readAllServiceFunctionPaths()).thenReturn(paths);
allowActionInstance = new ActionInstanceBuilder().setName(new ActionName("allow"))
.setActionDefinitionId(new AllowAction().getId())
.build();
ParameterValue pv = new ParameterValueBuilder().setName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME))
.setStringValue(SFC_CHAIN)
.build();
chainActionInstance = new ActionInstanceBuilder().setName(new ActionName("chain"))
.setActionDefinitionId(new ChainAction().getId())
.setParameterValue(ImmutableList.of(pv))
.build();
switchManagerMock
.addSwitch(NODE_ID, tunnelId,
Collections
.emptySet(),
new OfOverlayNodeConfigBuilder()
.setTunnel(ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
.setTunnelType(TunnelTypeVxlan.class)
.setNodeConnectorId(tunnelId)
.build()))
.build());
}
@Test
public void test_SameEg() throws Exception {
EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
ep1Builder.setL2Context(L2BD_ID);
Endpoint ep1 = ep1Builder.build();
endpointManagerMock.addEndpoint(ep1);
EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
ep2Builder.setL2Context(L2BD_ID);
Endpoint ep2 = ep2Builder.build();
endpointManagerMock.addEndpoint(ep2);
ctxMock.addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
.setContract(ImmutableList.of(baseContract(null).build())).build()).build());
ofWriter = new OfWriter();
table.sync(ep1, ofWriter);
assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
.isEmpty());
int count = 0;
for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()) {
if (isAllowSameEpg(f)) {
count++;
}
}
assertEquals(sameEpgFlows, count);
int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
assertEquals(totalFlows, ofWriter
.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
}
@Test
public void test_DifferentEg() throws Exception {
int totalFlows = sameEpgFlows + allowTunnelFlows;
assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(null).build()), allowActionInstance));
// one layer4 flow for each direction
totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build()), allowActionInstance));
totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build()), allowActionInstance));
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build()), allowActionInstance));
}
@Test
public void test_Rules() throws Exception {
Rule rule1 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
.build();
Rule rule2 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
.build();
Rule rule3 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
.setClassifierRef(createClassifierRefs(
ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
.build();
Rule rule4 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
.build();
int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), allowActionInstance));
// one layer4 flow for each direction
totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), allowActionInstance));
// only one ether_type for out direction
totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + layer4flowsIPv6;
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), allowActionInstance));
totalFlows = sameEpgFlows + allowTunnelFlows;
assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), allowActionInstance));
}
@Test
public void test_Rules_ChainAction() throws Exception {
Rule rule1 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
.build();
Rule rule2 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
.build();
Rule rule3 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
.setClassifierRef(createClassifierRefs(
ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
.build();
Rule rule4 = new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
.setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
.build();
assertEquals(2,
doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), chainActionInstance));
assertEquals(2,
doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), chainActionInstance));
assertEquals(2,
doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), chainActionInstance));
assertEquals(2,
doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), chainActionInstance));
}
private int doTestDifferentEg(List<Subject> subjects, ActionInstance actionInstance) throws Exception {
EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
ep1Builder.setL2Context(L2BD_ID);
Endpoint ep1 = ep1Builder.build();
endpointManagerMock.addEndpoint(ep1);
EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
ep2Builder.setL2Context(L2BD_ID);
Endpoint ep2 = ep2Builder.build();
endpointManagerMock.addEndpoint(ep2);
TenantBuilder tb = buildTenant(actionInstance);
ctxMock.addTenant(tb.setPolicy(
new PolicyBuilder(tb.getPolicy()).setContract(ImmutableList.of(baseContract(subjects).build())).build())
.build());
ofWriter = new OfWriter();
table.sync(ep1, ofWriter);
assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
.isEmpty());
int count = 0;
for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()) {
if (isAllowSameEpg(f)) {
count++;
} else if (f.getMatch() != null && Objects.equals(tunnelId, f.getMatch().getInPort())) {
assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))), f.getInstructions());
count++;
} else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
&& Objects.equals(FlowUtils.IPv4,
f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
&& f.getMatch().getIpMatch() != null
&& Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
&& f.getMatch().getLayer4Match() != null
&& (Objects.equals(new PortNumber(80),
((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
|| Objects.equals(new PortNumber(80),
((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
count++;
} else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
&& Objects.equals(FlowUtils.IPv6,
f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
&& f.getMatch().getIpMatch() != null
&& Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
&& f.getMatch().getLayer4Match() != null
&& (Objects.equals(new PortNumber(80),
((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
|| Objects.equals(new PortNumber(80),
((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
count++;
}
}
return count;
}
@Test
public void test_Conditions() throws Exception {
Condition cond1 = new ConditionBuilder().setName(new ConditionName("cond1")).build();
Condition cond2 = new ConditionBuilder().setName(new ConditionName("cond2")).build();
EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
ep1Builder.setL2Context(L2BD_ID);
ep1Builder.setCondition(ImmutableList.of(cond1.getName())).build();
Endpoint ep1 = ep1Builder.build();
endpointManagerMock.addEndpoint(ep1);
EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
ep2Builder.setL2Context(L2BD_ID);
ep2Builder.setCondition(ImmutableList.of(cond1.getName(), cond2.getName())).build();
Endpoint ep2 = ep2Builder.build();
endpointManagerMock.addEndpoint(ep2);
TenantBuilder tb = buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
.setContract(ImmutableList.of(new ContractBuilder().setId(CONTRACT_ID)
.setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
.setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
.setConsumerMatchers(new ConsumerMatchersBuilder().setConditionMatcher(
ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m1"))
.setCondition(ImmutableList.of(cond1, cond2))
.setMatchType(MatchType.Any)
.build()))
.build())
.setProviderMatchers(new ProviderMatchersBuilder()
.setConditionMatcher(
ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m2"))
.setCondition(ImmutableList.of(cond1, cond2))
.setMatchType(MatchType.All)
.build()))
.build())
.build()))
.build()))
.build());
ctxMock.addTenant(tb.build());
PolicyInfo policy = ctxMock.getCurrentPolicy();
List<ConditionName> ep1c = endpointManagerMock.getConditionsForEndpoint(ep1);
ConditionGroup cg1 = policy.getEgCondGroup(new EgKey(tb.getId(), ep1.getEndpointGroup()), ep1c);
List<ConditionName> ep2c = endpointManagerMock.getConditionsForEndpoint(ep2);
ConditionGroup cg2 = policy.getEgCondGroup(new EgKey(tb.getId(), ep2.getEndpointGroup()), ep2c);
int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);
int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);
int eg1Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(), ep1.getEndpointGroup());
int eg2Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(), ep2.getEndpointGroup());
assertNotEquals(cg1Id, cg2Id);
MatchBuilder mb = new MatchBuilder();
FlowUtils.addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, (long) eg1Id),
RegMatch.of(NxmNxReg1.class, (long) cg1Id), RegMatch.of(NxmNxReg2.class, (long) eg2Id),
RegMatch.of(NxmNxReg3.class, (long) cg2Id));
int count = 0;
ofWriter = new OfWriter();
table.sync(ep1, ofWriter);
// one layer4 flow for each direction
int dropAllFlow = 1;
int arpFlows = 1;
int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow;
assertEquals(totalFlows, ofWriter
.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()) {
if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null) {
count++;
}
}
// flows with ether_type match
totalFlows = layer4flowsIPv4 + layer4flowsIPv6 + arpFlows;
assertEquals(totalFlows, count);
}
private boolean isAllowSameEpg(Flow flow) {
// flow has to have exactly 2 registers set, namely NxmNxReg0 and NxmNxReg2
// (these register values don't have to be equal)
boolean res = false;
if (flow != null && flow.getMatch() != null) {
GeneralAugMatchNodesNodeTableFlow genAug =
flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
if (genAug != null) {
List<ExtensionList> extensions = genAug.getExtensionList();
if (extensions != null && extensions.size() == 2) {
Long reg0 = null;
Long reg2 = null;
for (ExtensionList extensionList : extensions) {
Class<? extends ExtensionKey> extensionKey = extensionList.getExtensionKey();
Extension extension = extensionList.getExtension();
if (extensionKey != null && extension != null) {
NxAugMatchNodesNodeTableFlow nxAugMatch =
extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
if (nxAugMatch != null && nxAugMatch.getNxmNxReg() != null) {
if (extensionKey.equals(NxmNxReg0Key.class)) {
reg0 = nxAugMatch.getNxmNxReg().getValue();
} else if (extensionKey.equals(NxmNxReg2Key.class)) {
reg2 = nxAugMatch.getNxmNxReg().getValue();
}
}
}
}
if (reg0 != null && reg2 != null) {
res = true;
}
}
}
}
return res;
}
private ContractBuilder baseContract(List<Subject> subjects) {
ContractBuilder contractBuilder = new ContractBuilder().setId(CONTRACT_ID).setSubject(subjects);
if (subjects == null) {
return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
.setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
.build()));
}
List<SubjectName> subjectNames = new ArrayList<>();
for (Subject subject : subjects) {
subjectNames.add(subject.getName());
}
return contractBuilder.setClause(ImmutableList
.of(new ClauseBuilder().setName(new ClauseName("test")).setSubjectRefs(subjectNames).build()));
}
private SubjectBuilder baseSubject(Direction direction) {
return new SubjectBuilder().setName(new SubjectName("s1"))
.setRule(ImmutableList.of(new RuleBuilder()
.setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
.setClassifierRef(ImmutableList.of(new ClassifierRefBuilder().setName(new ClassifierName(TCP_DST))
.setDirection(direction)
.setInstanceName(new ClassifierName(TCP_DST))
.build()))
.build()));
}
private Subject createSubject(String name, List<Rule> rules) {
return new SubjectBuilder().setName(new SubjectName(name)).setRule(rules).build();
}
private List<ClassifierRef> createClassifierRefs(Map<String, Direction> refNamesAndDirections) {
List<ClassifierRef> refs = new ArrayList<>();
for (String refName : refNamesAndDirections.keySet()) {
refs.add(new ClassifierRefBuilder().setName(new ClassifierName(refName))
.setDirection(refNamesAndDirections.get(refName))
.setInstanceName(new ClassifierName(refName))
.build());
}
return refs;
}
}