}
private void processInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) {
- BigInteger dpId = portAfter.getDpId();
List<AllowedAddressPairs> addedAaps = AclServiceUtils
.getUpdatedAllowedAddressPairs(portAfter.getAllowedAddressPairs(), portBefore.getAllowedAddressPairs());
List<AllowedAddressPairs> deletedAaps = AclServiceUtils
programAclWithAllowedAddress(portAfter, addedAaps, Action.UPDATE, NwConstants.ADD_FLOW);
updateRemoteAclFilterTable(portAfter, portAfter.getSecurityGroups(), addedAaps, NwConstants.ADD_FLOW);
}
- updateArpForAllowedAddressPairs(dpId, portAfter.getLPortTag(), deletedAaps, portAfter.getAllowedAddressPairs());
if (portAfter.getSubnetIpPrefixes() != null && portBefore.getSubnetIpPrefixes() == null) {
programBroadcastRules(portAfter, NwConstants.ADD_FLOW);
}
int lportTag = port.getLPortTag();
LOG.debug("Applying ACL Allowed Address on DpId {}, lportTag {}, Action {}", dpId, lportTag, action);
String portId = port.getInterfaceId();
- programAntiSpoofingRules(port, "", allowedAddresses, action, addOrRemove);
+ programAntiSpoofingRules(port, allowedAddresses, action, addOrRemove);
programAclPortSpecificFixedRules(dpId, allowedAddresses, lportTag, portId, action, addOrRemove);
if (action == Action.ADD || action == Action.REMOVE) {
programAclRules(port, port.getSecurityGroups(), addOrRemove);
* Programs the anti-spoofing rules.
*
* @param port the acl interface
- * @param dhcpMacAddress the dhcp mac address.
* @param allowedAddresses the allowed addresses
* @param action add/modify/remove action
* @param addOrRemove addorRemove
*/
- protected abstract void programAntiSpoofingRules(AclInterface port, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, 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);
+ protected abstract void programAntiSpoofingRules(AclInterface port, List<AllowedAddressPairs> allowedAddresses,
+ Action action, int addOrRemove);
/**
* Programs broadcast rules.
}
@Override
- protected void programAntiSpoofingRules(AclInterface port, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
+ protected void programAntiSpoofingRules(AclInterface port, List<AllowedAddressPairs> allowedAddresses,
+ Action action, int addOrRemove) {
LOG.info("{} programAntiSpoofingRules for port {}, AAPs={}, action={}, addOrRemove={}", this.directionString,
port.getInterfaceId(), allowedAddresses, action, addOrRemove);
BigInteger dpid = port.getDpId();
int lportTag = port.getLPortTag();
- if (action == Action.ADD || action == Action.REMOVE) {
- Set<MacAddress> aapMacs =
- allowedAddresses.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
- egressAclDhcpAllowClientTraffic(dpid, aapMacs, lportTag, addOrRemove);
- egressAclDhcpv6AllowClientTraffic(dpid, aapMacs, lportTag, addOrRemove);
- egressAclDhcpDropServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove);
- egressAclDhcpv6DropServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove);
+ if (action != Action.UPDATE) {
+ egressAclDhcpDropServerTraffic(dpid, lportTag, addOrRemove);
+ egressAclDhcpv6DropServerTraffic(dpid, lportTag, addOrRemove);
egressAclIcmpv6DropRouterAdvts(dpid, lportTag, addOrRemove);
egressAclIcmpv6AllowedList(dpid, lportTag, addOrRemove);
-
- programArpRule(dpid, allowedAddresses, lportTag, addOrRemove);
programL2BroadcastAllowRule(port, addOrRemove);
}
- }
+ List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(allowedAddresses);
- @Override
- protected void updateArpForAllowedAddressPairs(BigInteger dpId, int lportTag, List<AllowedAddressPairs> deletedAAP,
- List<AllowedAddressPairs> addedAAP) {
- // Remove common allowedAddrPairIPs to avoid delete and add of ARP flows having same MAC and IP
- deletedAAP.removeAll(addedAAP);
- programArpRule(dpId, deletedAAP, lportTag, NwConstants.DEL_FLOW);
- programArpRule(dpId, addedAAP, lportTag, NwConstants.ADD_FLOW);
+ egressAclDhcpAllowClientTraffic(dpid, filteredAAPs, lportTag, addOrRemove);
+ egressAclDhcpv6AllowClientTraffic(dpid, filteredAAPs, lportTag, addOrRemove);
+ programArpRule(dpid, filteredAAPs, lportTag, addOrRemove);
}
@Override
@Override
protected void programGotoClassifierTableRules(BigInteger dpId, List<AllowedAddressPairs> aaps, int lportTag,
int addOrRemove) {
- for (AllowedAddressPairs aap : aaps) {
+ List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(aaps);
+ for (AllowedAddressPairs aap : filteredAAPs) {
IpPrefixOrAddress attachIp = aap.getIpAddress();
MacAddress mac = aap.getMacAddress();
* Anti-spoofing rule to block the Ipv4 DHCP server traffic from the port.
*
* @param dpId the dpId
- * @param dhcpMacAddress the Dhcp mac address
* @param lportTag the lport tag
* @param addOrRemove add/remove the flow.
*/
- protected void egressAclDhcpDropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
- int addOrRemove) {
+ protected void egressAclDhcpDropServerTraffic(BigInteger dpId, int lportTag, int addOrRemove) {
List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_SERVER_PORT_IPV4,
AclConstants.DHCP_CLIENT_PORT_IPV4, lportTag, serviceMode);
- String flowName = "Egress_DHCP_Server_v4" + dpId + "_" + lportTag + "_" + dhcpMacAddress + "_Drop_";
+ String flowName = "Egress_DHCP_Server_v4" + dpId + "_" + lportTag + "_Drop_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY,
"ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches, Collections.emptyList(), addOrRemove);
}
* Anti-spoofing rule to block the Ipv6 DHCP server traffic from the port.
*
* @param dpId the dpId
- * @param dhcpMacAddress the Dhcp mac address
* @param lportTag the lport tag
* @param addOrRemove add/remove the flow.
*/
- protected void egressAclDhcpv6DropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
- int addOrRemove) {
+ protected void egressAclDhcpv6DropServerTraffic(BigInteger dpId, int lportTag, int addOrRemove) {
List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_SERVER_PORT_IPV6,
AclConstants.DHCP_CLIENT_PORT_IPV6, lportTag, serviceMode);
- String flowName = "Egress_DHCP_Server_v6" + "_" + dpId + "_" + lportTag + "_" + dhcpMacAddress + "_Drop_";
+ String flowName = "Egress_DHCP_Server_v6" + "_" + dpId + "_" + lportTag + "_Drop_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY,
"ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches, Collections.emptyList(), addOrRemove);
}
}
/**
- * Add rule to ensure only DHCP server traffic from the specified mac is
- * allowed.
+ * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
*
* @param dpId the dpid
- * @param aapMacs the AAP mac addresses
+ * @param allowedAddresses the allowed addresses
* @param lportTag the lport tag
* @param addOrRemove whether to add or remove the flow
*/
- private void egressAclDhcpAllowClientTraffic(BigInteger dpId, Set<MacAddress> aapMacs, int lportTag,
- int addOrRemove) {
+ private void egressAclDhcpAllowClientTraffic(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses,
+ int lportTag, int addOrRemove) {
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
- for (MacAddress aapMac : aapMacs) {
+ for (AllowedAddressPairs aap : allowedAddresses) {
+ if (!AclServiceUtils.isIPv4Address(aap)) {
+ continue;
+ }
List<MatchInfoBase> matches = new ArrayList<>();
matches.addAll(AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_CLIENT_PORT_IPV4,
AclConstants.DHCP_SERVER_PORT_IPV4, lportTag, serviceMode));
- matches.add(new MatchEthernetSource(aapMac));
+ matches.add(new MatchEthernetSource(aap.getMacAddress()));
- String flowName = "Egress_DHCP_Client_v4" + dpId + "_" + lportTag + "_" + aapMac.getValue() + "_Permit_";
+ String flowName =
+ "Egress_DHCP_Client_v4" + dpId + "_" + lportTag + "_" + aap.getMacAddress().getValue() + "_Permit_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY,
"ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
* allowed.
*
* @param dpId the dpid
- * @param aapMacs the AAP mac addresses
+ * @param allowedAddresses the allowed addresses
* @param lportTag the lport tag
* @param addOrRemove whether to add or remove the flow
*/
- private void egressAclDhcpv6AllowClientTraffic(BigInteger dpId, Set<MacAddress> aapMacs, int lportTag,
- int addOrRemove) {
+ private void egressAclDhcpv6AllowClientTraffic(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses,
+ int lportTag, int addOrRemove) {
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
- for (MacAddress aapMac : aapMacs) {
+ for (AllowedAddressPairs aap : allowedAddresses) {
+ if (AclServiceUtils.isIPv4Address(aap)) {
+ continue;
+ }
List<MatchInfoBase> matches = new ArrayList<>();
matches.addAll(AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_CLIENT_PORT_IPV6,
AclConstants.DHCP_SERVER_PORT_IPV6, lportTag, serviceMode));
- matches.add(new MatchEthernetSource(aapMac));
+ matches.add(new MatchEthernetSource(aap.getMacAddress()));
- String flowName = "Egress_DHCP_Client_v6" + "_" + dpId + "_" + lportTag + "_" + aapMac.getValue()
- + "_Permit_";
+ String flowName = "Egress_DHCP_Client_v6" + "_" + dpId + "_" + lportTag + "_"
+ + aap.getMacAddress().getValue() + "_Permit_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY,
"ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
}
@Override
- protected void programAntiSpoofingRules(AclInterface port, String dhcpMacAddress,
+ protected void programAntiSpoofingRules(AclInterface port,
List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
LOG.info("{} programAntiSpoofingRules for port {}, AAPs={}, action={}, addOrRemove={}", this.directionString,
port.getInterfaceId(), allowedAddresses, action, addOrRemove);
BigInteger dpid = port.getDpId();
int lportTag = port.getLPortTag();
if (action == Action.ADD || action == Action.REMOVE) {
- ingressAclDhcpAllowServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove,
- AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
- ingressAclDhcpv6AllowServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove,
- AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
+ ingressAclDhcpAllowServerTraffic(dpid, lportTag, addOrRemove, AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
+ ingressAclDhcpv6AllowServerTraffic(dpid, lportTag, addOrRemove, AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
ingressAclIcmpv6AllowedTraffic(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
protected void programRemoteAclTableFlow(BigInteger dpId, Integer aclTag, AllowedAddressPairs aap,
int addOrRemove) {
* allowed.
*
* @param dpId the dpid
- * @param dhcpMacAddress the DHCP server mac address
* @param lportTag the lport tag
* @param addOrRemove is write or delete
* @param protoPortMatchPriority the priority
*/
- protected void ingressAclDhcpAllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
- int addOrRemove, int protoPortMatchPriority) {
+ protected void ingressAclDhcpAllowServerTraffic(BigInteger dpId, int lportTag, int addOrRemove,
+ int protoPortMatchPriority) {
final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_SERVER_PORT_IPV4,
AclConstants.DHCP_CLIENT_PORT_IPV4, lportTag, serviceMode);
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
- String flowName = "Ingress_DHCP_Server_v4" + dpId + "_" + lportTag + "_" + dhcpMacAddress + "_Permit_";
+ String flowName = "Ingress_DHCP_Server_v4" + dpId + "_" + lportTag + "_Permit_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_SERVER_MATCH_PRIORITY, "ACL", 0, 0,
AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
* allowed.
*
* @param dpId the dpid
- * @param dhcpMacAddress the DHCP server mac address
* @param lportTag the lport tag
* @param addOrRemove is write or delete
* @param protoPortMatchPriority the priority
*/
- protected void ingressAclDhcpv6AllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
- int addOrRemove, Integer protoPortMatchPriority) {
+ protected void ingressAclDhcpv6AllowServerTraffic(BigInteger dpId, int lportTag, int addOrRemove,
+ Integer protoPortMatchPriority) {
final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_SERVER_PORT_IPV6,
AclConstants.DHCP_CLIENT_PORT_IPV6, lportTag, serviceMode);
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
- String flowName =
- "Ingress_DHCP_Server_v6" + "_" + dpId + "_" + lportTag + "_" + "_" + dhcpMacAddress + "_Permit_";
+ String flowName = "Ingress_DHCP_Server_v6" + "_" + dpId + "_" + lportTag + "_Permit_";
syncFlow(dpId, getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_DHCP_SERVER_MATCH_PRIORITY, "ACL", 0, 0,
AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
import com.google.common.net.InetAddresses;
import com.google.common.util.concurrent.ListenableFuture;
import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
return instructions;
}
+ public static List<AllowedAddressPairs> excludeMulticastAAPs(List<AllowedAddressPairs> allowedAddresses) {
+ List<AllowedAddressPairs> filteredAAPs = new ArrayList<>();
+ for (AllowedAddressPairs allowedAddress : allowedAddresses) {
+ InetAddress inetAddr = getInetAddress(allowedAddress.getIpAddress());
+ if (inetAddr != null && !inetAddr.isMulticastAddress()) {
+ filteredAAPs.add(allowedAddress);
+ }
+ }
+ return filteredAAPs;
+ }
+
+ private static InetAddress getInetAddress(IpPrefixOrAddress ipPrefixOrAddress) {
+ InetAddress inetAddress = null;
+ String addr = null;
+
+ IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
+ if (ipPrefix != null) {
+ addr = String.valueOf(ipPrefix.getValue()).split("/")[0];
+ } else {
+ IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
+ if (ipAddress == null) {
+ LOG.error("Invalid address : {}", ipPrefixOrAddress);
+ return null;
+ } else {
+ addr = String.valueOf(ipAddress.getValue());
+ }
+ }
+ try {
+ inetAddress = InetAddress.getByName(addr);
+ } catch (UnknownHostException e) {
+ LOG.error("Invalid address : {}", addr, e.getMessage());
+ return null;
+ }
+ return inetAddress;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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.netvirt.aclservice.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
+
+/**
+ * Unit tests for AclServiceUtils.
+ *
+ */
+public class AclServiceUtilsTest {
+
+ @Test
+ public void testExcludeMulticastAAPs() {
+ List<AllowedAddressPairs> inputAAPs = new ArrayList<>();
+ buildInputAAP(inputAAPs, "1.1.1.1/32");// non-multicast Ipv4Prefix
+ buildInputAAP(inputAAPs, "2.2.2.2");// non-multicast Ipv4Address
+ buildInputAAP(inputAAPs, "2001:db8:85a3:0:0:8a2e:370:7334"); // non-multicast Ipv6Address
+ buildInputAAP(inputAAPs, "2002:db8:85a3::8a2e:370:7334/8"); // non-multicast Ipv6Prefix
+
+ List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(inputAAPs);
+ assertNotNull(filteredAAPs);
+ assertEquals(inputAAPs, filteredAAPs);
+ inputAAPs.clear();
+
+ buildInputAAP(inputAAPs, "224.0.0.0/24");// multicast Ipv4Prefix
+ buildInputAAP(inputAAPs, "224.4.2.2");// multicast Ipv4Address
+ buildInputAAP(inputAAPs, "FF01:0:0:0:0:0:0:1"); // multicast Ipv6Address
+ buildInputAAP(inputAAPs, "FF01::DB8:0:0/96"); // multicast Ipv6Prefix
+
+ filteredAAPs = AclServiceUtils.excludeMulticastAAPs(inputAAPs);
+ assertNotNull(filteredAAPs);
+ assertEquals(0, filteredAAPs.size());
+ inputAAPs.clear();
+
+ buildInputAAP(inputAAPs, "224.4.2.2");// multicast Ipv4Address
+ buildInputAAP(inputAAPs, "3.3.3.3");// non-multicast Ipv4Address
+ buildInputAAP(inputAAPs, "2001:db8:85a3:0:0:8a2e:370:7335"); // non-multicast Ipv6Address
+ buildInputAAP(inputAAPs, "FF01:0:0:0:0:0:0:2"); // multicast Ipv6Address
+
+ List<AllowedAddressPairs> tempAAPs = new ArrayList<>();
+ tempAAPs.add(buildAAp("3.3.3.3"));
+ tempAAPs.add(buildAAp("2001:db8:85a3:0:0:8a2e:370:7335"));
+
+ filteredAAPs = AclServiceUtils.excludeMulticastAAPs(inputAAPs);
+ assertNotNull(filteredAAPs);
+ assertEquals(2, filteredAAPs.size());
+ assertEquals(tempAAPs, filteredAAPs);
+ inputAAPs.clear();
+ }
+
+ private void buildInputAAP(List<AllowedAddressPairs> inputAAPs, String addr) {
+ inputAAPs.add(buildAAp(addr));
+ }
+
+ private AllowedAddressPairs buildAAp(String addr) {
+ AllowedAddressPairsBuilder aapb = new AllowedAddressPairsBuilder();
+ aapb.setIpAddress(new IpPrefixOrAddress(addr.toCharArray()));
+ aapb.setMacAddress(new MacAddress("AA:BB:CC:DD:EE:FF"));
+ return aapb.build();
+ }
+}