List<AllowedAddressPairs> deletedAllowedAddressPairs =
AclServiceUtils.getUpdatedAllowedAddressPairs(portBefore.getAllowedAddressPairs(),
portAfter.getAllowedAddressPairs());
- if (addedAllowedAddressPairs != null && !addedAllowedAddressPairs.isEmpty()) {
- programAclWithAllowedAddress(dpId, addedAllowedAddressPairs, portAfter.getLPortTag(),
- portAfter.getSecurityGroups(), Action.UPDATE, NwConstants.ADD_FLOW, portAfter.getInterfaceId());
- }
if (deletedAllowedAddressPairs != null && !deletedAllowedAddressPairs.isEmpty()) {
programAclWithAllowedAddress(dpId, deletedAllowedAddressPairs, portAfter.getLPortTag(),
portAfter.getSecurityGroups(), Action.UPDATE, NwConstants.DEL_FLOW, portAfter.getInterfaceId());
}
+ if (addedAllowedAddressPairs != null && !addedAllowedAddressPairs.isEmpty()) {
+ programAclWithAllowedAddress(dpId, addedAllowedAddressPairs, portAfter.getLPortTag(),
+ portAfter.getSecurityGroups(), Action.UPDATE, NwConstants.ADD_FLOW, portAfter.getInterfaceId());
+ }
+ updateArpForAllowedAddressPairs(dpId, portAfter.getLPortTag(), deletedAllowedAddressPairs,
+ portAfter.getAllowedAddressPairs());
updateAclInterfaceInCache(portBefore);
// Have to delete and add all rules because there can be following scenario: Interface1 with SG1, Interface2
protected abstract void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action, int addOrRemove);
+ /**
+ * Update arp for allowed address pairs.
+ *
+ * @param dpId the dp id
+ * @param lportTag the lport tag
+ * @param deletedAAP the deleted allowed address pairs
+ * @param addedAAP the added allowed address pairs
+ */
+ protected abstract void updateArpForAllowedAddressPairs(BigInteger dpId, int lportTag,
+ List<AllowedAddressPairs> deletedAAP, List<AllowedAddressPairs> addedAAP);
+
/**
* Program the default specific rules.
*
package org.opendaylight.netvirt.aclservice;
import com.google.common.util.concurrent.ListenableFuture;
-
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
+import java.util.stream.Collectors;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
egressAclDhcpv6DropServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove);
egressAclIcmpv6DropRouterAdvts(dpid, lportTag, addOrRemove);
egressAclIcmpv6AllowedList(dpid, lportTag, addOrRemove);
+
+ programArpRule(dpid, allowedAddresses, lportTag, addOrRemove);
}
- programArpRule(dpid, allowedAddresses, lportTag, addOrRemove);
+ }
+
+ @Override
+ protected void updateArpForAllowedAddressPairs(BigInteger dpId, int lportTag, List<AllowedAddressPairs> deletedAAP,
+ List<AllowedAddressPairs> addedAAP) {
+ Set<MacAddress> deletedAAPmacs =
+ deletedAAP.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
+ Set<MacAddress> addedAAPmacs = addedAAP.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
+
+ // Remove common macs to avoid delete and add of ARP flows having same MAC.
+ deletedAAPmacs.removeAll(addedAAPmacs);
+
+ programArpRule(dpId, deletedAAPmacs, lportTag, NwConstants.DEL_FLOW);
+ programArpRule(dpId, addedAAPmacs, lportTag, NwConstants.ADD_FLOW);
}
@Override
}
/**
- * Adds the rule to allow arp packets.
+ * Program arp rule.
*
- * @param dpId the dpId
+ * @param dpId the dp id
* @param allowedAddresses the allowed addresses
* @param lportTag the lport tag
* @param addOrRemove whether to add or remove the flow
*/
protected void programArpRule(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses, int lportTag,
int addOrRemove) {
- for (AllowedAddressPairs allowedAddress : allowedAddresses) {
- MacAddress attachMac = allowedAddress.getMacAddress();
+ // Collecting macs as a set to avoid duplicate
+ Set<MacAddress> macs = allowedAddresses.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
+ programArpRule(dpId, macs, lportTag, addOrRemove);
+ }
+
+ /**
+ * Adds the rule to allow arp packets.
+ *
+ * @param dpId the dpId
+ * @param macs the set of MACs
+ * @param lportTag the lport tag
+ * @param addOrRemove whether to add or remove the flow
+ */
+ protected void programArpRule(BigInteger dpId, Set<MacAddress> macs, int lportTag, int addOrRemove) {
+ for (MacAddress mac : macs) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.add(MatchEthernetType.ARP);
- matches.add(new MatchArpSha(attachMac));
+ matches.add(new MatchArpSha(mac));
matches.add(buildLPortTagMatch(lportTag));
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(new ArrayList<>());
- String flowName = "Egress_ARP_" + dpId + "_" + lportTag + "_" + attachMac.getValue();
+ String flowName = "Egress_ARP_" + dpId + "_" + lportTag + "_" + mac.getValue();
syncFlow(dpId, NwConstants.INGRESS_ACL_TABLE, flowName,
AclConstants.PROTO_ARP_TRAFFIC_MATCH_PRIORITY, "ACL", 0, 0,
AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
ingressAclDhcpv6AllowServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove,
AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
ingressAclIcmpv6AllowedTraffic(dpid, lportTag, addOrRemove);
+
+ programArpRule(dpid, lportTag, addOrRemove);
}
- programArpRule(dpid, lportTag, addOrRemove);
+ }
+
+ @Override
+ protected void updateArpForAllowedAddressPairs(BigInteger dpId, int lportTag, List<AllowedAddressPairs> deletedAAP,
+ List<AllowedAddressPairs> addedAAP) {
+ // Nothing to do for port update as ingress ARP flow is based only on lportTag
+
}
@Override
@Override
void newInterfaceWithAapIpv4AllCheck() {
- // TODO Auto-generated method stub
+ // Not applicable as it is specific to IPv4 testing
+ }
+
+ @Override
+ void newInterfaceWithAapCheck() {
+ // TODO: To be handled
+
}
}
void newInterfaceWithAapIpv4AllCheck() {
assertFlowsInAnyOrder(ipv4statefulentries.aapWithIpv4AllFlows());
}
+
+ @Override
+ void newInterfaceWithAapCheck() {
+ assertFlowsInAnyOrder(ipv4statefulentries.aapFlows());
+ }
}
@Override
void newInterfaceWithAapIpv4AllCheck() {
- // TODO Auto-generated method stub
+ // TODO: To be handled
+
+ }
+
+ @Override
+ void newInterfaceWithAapCheck() {
+ // TODO: To be handled
}
abstract void newInterfaceWithAapIpv4AllCheck();
+ @Test
+ public void newInterfaceWithAap() throws Exception {
+ LOG.info("newInterfaceWithAap test - start");
+
+ // AAP with same MAC and different IP
+ AllowedAddressPairs aapWithSameMac = buildAap("10.0.0.100/32", PORT_MAC_2);
+ // AAP with different MAC and different IP
+ AllowedAddressPairs aapWithDifferentMac = buildAap("10.0.0.101/32", "0D:AA:D8:42:30:A4");
+
+ newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
+ newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
+ Arrays.asList(AAP_PORT_2, aapWithSameMac, aapWithDifferentMac));
+
+ prepareInterfaceWithIcmpAcl();
+ // When
+ putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
+ putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
+
+ asyncEventsWaiter.awaitEventsConsumption();
+
+ // Then
+ newInterfaceWithAapCheck();
+ LOG.info("newInterfaceWithAap test - end");
+ }
+
+ abstract void newInterfaceWithAapCheck();
+
protected void assertFlowsInAnyOrder(Iterable<FlowEntity> expectedFlows) {
asyncEventsWaiter.awaitEventsConsumption();
coordinatorEventsWaiter.awaitEventsConsumption();
*/
package org.opendaylight.netvirt.aclservice.tests
+import org.opendaylight.genius.mdsalutil.FlowEntity
+import org.opendaylight.genius.mdsalutil.MetaDataUtil
+import org.opendaylight.genius.mdsalutil.NwConstants
+import org.opendaylight.genius.mdsalutil.actions.ActionDrop
import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit
-import org.opendaylight.genius.mdsalutil.actions.ActionDrop
-import org.opendaylight.genius.mdsalutil.FlowEntity
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions
import org.opendaylight.genius.mdsalutil.matches.MatchArpSha
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination
import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol
import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination
import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source
+import org.opendaylight.genius.mdsalutil.matches.MatchMetadata
import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort
import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState
+import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTcpDestinationPort
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchUdpDestinationPort
-import org.opendaylight.genius.mdsalutil.MetaDataUtil
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress
-
-import org.opendaylight.genius.mdsalutil.matches.MatchArpSha
-import org.opendaylight.genius.mdsalutil.NwConstants
-import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6
-import org.opendaylight.genius.mdsalutil.matches.MatchMetadata
class FlowEntryObjectsStateful extends FlowEntryObjectsBase {
+ aapIpv4AllFlowsPort2
}
+ protected def aapFlows() {
+ icmpFlows()
+ + aapRemoteFlowsPort1
+ // TODO: Temporarily adding duplicate flows to make TC pass. It needs to be removed later.
+ + aapRemoteFlowsPort1
+ + aapFlowsPort2
+ }
+
protected def aapIpv4AllFlowsPort2() {
#[
new FlowEntity(123bi) => [
]
}
+ protected def aapRemoteFlowsPort1() {
+ #[
+ remoteIngressFlowsPort("10.0.0.100"),
+ remoteIngressFlowsPort("10.0.0.101"),
+
+ remoteEgressFlowsPort("10.0.0.100"),
+ remoteEgressFlowsPort("10.0.0.101")
+ ]
+ }
+
+ protected def aapFlowsPort2() {
+ #[
+ new FlowEntity(123bi) => [
+ cookie = 110100480bi
+ flowId = "Egress_Fixed_Conntrk_123_0D:AA:D8:42:30:F4_10.0.0.100/32_Recirc"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxConntrack(2, 0, 0, 5000, NwConstants.INGRESS_ACL_REMOTE_ACL_TABLE)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:F4")),
+ new MatchEthernetType(2048L),
+ new MatchIpv4Source("10.0.0.100", "32")
+ ]
+ priority = 61010
+ tableId = NwConstants.INGRESS_ACL_TABLE
+ ],
+ new FlowEntity(123bi) => [
+ cookie = 110100480bi
+ flowId = "Ingress_Fixed_Conntrk_123_0D:AA:D8:42:30:F4_10.0.0.100/32_Recirc"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxConntrack(2, 0, 0, 5000, NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetType(2048L),
+ new MatchEthernetDestination(new MacAddress("0D:AA:D8:42:30:F4")),
+ new MatchEthernetType(2048L),
+ new MatchIpv4Destination("10.0.0.100", "32")
+ ]
+ priority = 61010
+ tableId = NwConstants.EGRESS_ACL_TABLE
+ ],
+ new FlowEntity(123bi) => [
+ cookie = 110100480bi
+ flowId = "Egress_Fixed_Conntrk_123_0D:AA:D8:42:30:A4_10.0.0.101/32_Recirc"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxConntrack(2, 0, 0, 5000, NwConstants.INGRESS_ACL_REMOTE_ACL_TABLE)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:A4")),
+ new MatchEthernetType(2048L),
+ new MatchIpv4Source("10.0.0.101", "32")
+ ]
+ priority = 61010
+ tableId = NwConstants.INGRESS_ACL_TABLE
+ ],
+ new FlowEntity(123bi) => [
+ cookie = 110100480bi
+ flowId = "Ingress_Fixed_Conntrk_123_0D:AA:D8:42:30:A4_10.0.0.101/32_Recirc"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxConntrack(2, 0, 0, 5000, NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetType(2048L),
+ new MatchEthernetDestination(new MacAddress("0D:AA:D8:42:30:A4")),
+ new MatchEthernetType(2048L),
+ new MatchIpv4Destination("10.0.0.101", "32")
+ ]
+ priority = 61010
+ tableId = NwConstants.EGRESS_ACL_TABLE
+ ],
+ new FlowEntity(123bi) => [
+ cookie = 110100480bi
+ flowId = "Egress_ARP_123_987_0D:AA:D8:42:30:A4"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetType(2054L),
+ new MatchArpSha(new MacAddress("0D:AA:D8:42:30:A4")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 63010
+ tableId = NwConstants.INGRESS_ACL_TABLE
+ ]
+ ]
+ }
+
protected def fixedConntrackIngressFlowsPort1() {
#[
new FlowEntity(123bi) => [
*/
package org.opendaylight.netvirt.aclservice.tests
+import org.opendaylight.genius.mdsalutil.FlowEntity
+import org.opendaylight.genius.mdsalutil.MetaDataUtil
+import org.opendaylight.genius.mdsalutil.actions.ActionDrop
import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit
-import org.opendaylight.genius.mdsalutil.actions.ActionDrop
-import org.opendaylight.genius.mdsalutil.FlowEntity
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetSource
import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Destination
import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Source
import org.opendaylight.genius.mdsalutil.matches.MatchMetadata
-import org.opendaylight.genius.mdsalutil.MetaDataUtil
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState
+import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTcpDestinationPort
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchUdpDestinationPort
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress
-
-import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6
class FlowEntryObjectsStatefulIPv6 extends FlowEntryObjectsStateful {
*/
package org.opendaylight.netvirt.aclservice.tests
+import org.opendaylight.genius.mdsalutil.FlowEntity
+import org.opendaylight.genius.mdsalutil.MetaDataUtil
import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit
-import org.opendaylight.genius.mdsalutil.FlowEntity
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions
-import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata
-import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable
import org.opendaylight.genius.mdsalutil.matches.MatchArpSha
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType
import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv4
import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol
import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination
import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source
+import org.opendaylight.genius.mdsalutil.matches.MatchMetadata
import org.opendaylight.genius.mdsalutil.matches.MatchTcpFlags
import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort
import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState
+import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTcpDestinationPort
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchUdpDestinationPort
-import org.opendaylight.genius.mdsalutil.MetaDataUtil
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress
-
-import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6
-import org.opendaylight.genius.mdsalutil.matches.MatchMetadata
class FlowEntryObjectsStateless extends FlowEntryObjectsBase {
idCacheMap.put("TCP_DESTINATION_80_65535_remoteACL_id_85cc3048-abc3-43cc-89b3-377341426ac5Egress98785cc3048-abc3-43cc-89b3-377341426ac6", 61010);
idCacheMap.put("85cc3048-abc3-43cc-89b3-377341426ac5", 1 << 1);
idCacheMap.put("85cc3048-abc3-43cc-89b3-377341426ac8", 2 << 1);
+ idCacheMap.put("ICMP_V4_DESTINATION_23__ipv4_remoteACL_interface_aap_0D:AA:D8:42:30:F4_10.0.0.100/32Egress98785cc3048-abc3-43cc-89b3-377341426ac6", 1027);
+ idCacheMap.put("ICMP_V4_DESTINATION_23__ipv4_remoteACL_interface_aap_0D:AA:D8:42:30:A4_10.0.0.101/32Egress98785cc3048-abc3-43cc-89b3-377341426ac6", 1028);
}
public static Integer getId(String key) {