This fix enables ACL to permit Broadcast Traffic (Both IP and Non IP).
Related to IP Broadcast, Subnet-Directed Broadcast and All-Subnet
Broadcast traffic on the same network is being allowed subject to one of
the conditions specified below is met:
(a) The ports that want to communicate share the same
remote-secuirty-group
(b) The ports that want to communicate allow the other port's IP Address
in remote-ip-prefix
(c) The ports that want to communicate have securiyt0group with
remote-ip-prefix of 0.0.0.0/0.
IP Broadcast flows configured in VM Ingress ACL table (table 241) is as
below:
all-subnet flow:
cookie=0x6900000, duration=1463.293s, table=241, n_packets=0, n_bytes=0,
priority=61010,ip,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=255.255.255.255
actions=goto_table:242
subnet-directed flow:
cookie=0x6900000, duration=975.798s, table=241, n_packets=0, n_bytes=0,
priority=61010,ip,metadata=0x10000000000/0x1fffff0000000000,
dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=10.1.1.255 actions=goto_table:242
Non IP Broadcast flows (with lower priority than other flows - 61005)
configured in VM Egress(211) and Ingress(241) tables is as below:
cookie=0x6900000, duration=30.298s, table=211, n_packets=0, n_bytes=0,
priority=61005,metadata=0x10000000000/0x1fffff0000000000,
dl_src=fa:16:3e:a9:4d:81 actions=resubmit(,17)
cookie=0x6900000, duration=901.855s, table=241, n_packets=0, n_bytes=0,
priority=61005,dl_dst=ff:ff:ff:ff:ff:ff actions=resubmit(,220)
Below are change details:
- Updated to add a flow to allow broadcast traffic with destination
adddress 255.255.255.255. Changes related to this are in
AclNodeListener.java
- Updated to add flows at port level for subnetwork's broadcast addresses
- Updated to add flows in 211/241 for Non-IP broadcast traffic
- Updated to add ARP/IP/IPv6 default drop flows with lower priority than
respective flows and higher priority than non-ip broadcast flow
- New yang definition introduced in ACL for higher modules (Neutron VPN
in our case) to pass broadcast CIDRs when ACL Interface is created
- NeutronVpn is updated to pass subnet CIDRs when ACL Interface is
created
Change-Id: I71c5040454b3c00af43dcef4f47b5979cd7cf3a5
Signed-off-by: Shashidhar Raja <shashidharr@altencalsoftlabs.com>
import java.util.List;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+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;
/**
/** The allowed address pairs. */
List<AllowedAddressPairs> allowedAddressPairs;
+ /** The IP broadcast CIDRs. */
+ List<IpPrefixOrAddress> subnetIpPrefixes;
+
/** The port is marked for delete. */
Boolean isMarkedForDelete = false;
this.allowedAddressPairs = allowedAddressPairs;
}
+ /**
+ * Gets the Subnet IP Prefix.
+ *
+ * @return the Subnet IP Prefix
+ */
+ public List<IpPrefixOrAddress> getSubnetIpPrefixes() {
+ return subnetIpPrefixes;
+ }
+
+ /**
+ * Sets the Subnet IP Prefix.
+ *
+ * @param subnetIpPrefixes the Subnet IP Prefix
+ */
+ public void setSubnetIpPrefixes(List<IpPrefixOrAddress> subnetIpPrefixes) {
+ this.subnetIpPrefixes = subnetIpPrefixes;
+ }
+
/**
* Retrieve isMarkedForDelete.
* @return the whether it is marked for delete
}
}
}
+
+ container ports-subnet-ip-prefixes {
+ list port-subnet-ip-prefixes {
+ key port-id;
+ leaf port-id {
+ type string;
+ description "Port ID";
+ }
+ leaf-list subnet-ip-prefixes {
+ type ip-prefix-or-address;
+ description "Subnet IP Prefixes of the Port.";
+ }
+ }
+ }
}
}
updateArpForAllowedAddressPairs(dpId, portAfter.getLPortTag(), deletedAllowedAddressPairs,
portAfter.getAllowedAddressPairs());
+ if (portAfter.getSubnetIpPrefixes() != null && portBefore.getSubnetIpPrefixes() == null) {
+ programBroadcastRules(portAfter, NwConstants.ADD_FLOW);
+ }
updateAclInterfaceInCache(portBefore);
// Have to delete and add all rules because there can be following scenario: Interface1 with SG1, Interface2
LOG.debug("Applying ACL Allowed Address on DpId {}, lportTag {}, Action {}", dpId, lportTag, action);
List<Uuid> aclUuidList = port.getSecurityGroups();
String portId = port.getInterfaceId();
- programGeneralFixedRules(dpId, "", allowedAddresses, lportTag, action, addOrRemove);
+ programGeneralFixedRules(port, "", allowedAddresses, action, addOrRemove);
programSpecificFixedRules(dpId, "", allowedAddresses, lportTag, portId, action, addOrRemove);
if (action == Action.ADD || action == Action.REMOVE) {
programAclRules(port, aclUuidList, addOrRemove);
/**
* Program the default anti-spoofing rules.
*
- * @param dpid the dpid
+ * @param port the acl interface
* @param dhcpMacAddress the dhcp mac address.
* @param allowedAddresses the allowed addresses
- * @param lportTag the lport tag
* @param action add/modify/remove action
* @param addOrRemove addorRemove
*/
- protected abstract void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action, int addOrRemove);
+ protected abstract void programGeneralFixedRules(AclInterface port, String dhcpMacAddress,
+ List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove);
/**
* Update arp for allowed address pairs.
protected abstract void programAceRule(AclInterface port, int addOrRemove, String aclName, Ace ace,
List<AllowedAddressPairs> syncAllowedAddresses);
+ /**
+ * Programs broadcast rules.
+ *
+ * @param port the Acl Interface port
+ * @param addOrRemove whether to delete or add flow
+ */
+ protected abstract void programBroadcastRules(AclInterface port, int addOrRemove);
+
/**
* Writes/remove the flow to/from the datastore.
*
}
@Override
- protected void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action, int addOrRemove) {
+ protected void programGeneralFixedRules(AclInterface port, String dhcpMacAddress,
+ List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
LOG.info("programFixedRules : {} default rules.", action == Action.ADD ? "adding" : "removing");
+ 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());
egressAclIcmpv6AllowedList(dpid, lportTag, addOrRemove);
programArpRule(dpid, allowedAddresses, lportTag, addOrRemove);
+ programL2BroadcastAllowRule(port, addOrRemove);
}
}
}
}
+ /**
+ * Programs broadcast rules.
+ *
+ * @param port the Acl Interface port
+ * @param addOrRemove whether to delete or add flow
+ */
+ @Override
+ protected void programBroadcastRules(AclInterface port, int addOrRemove) {
+ programL2BroadcastAllowRule(port, addOrRemove);
+ }
+
+ /**
+ * Programs Non-IP broadcast rules.
+ *
+ * @param port the Acl Interface port
+ * @param addOrRemove whether to delete or add flow
+ */
+ private void programL2BroadcastAllowRule(AclInterface port, int addOrRemove) {
+ BigInteger dpId = port.getDpId();
+ int lportTag = port.getLPortTag();
+ List<AllowedAddressPairs> allowedAddresses = port.getAllowedAddressPairs();
+ Set<MacAddress> macs = allowedAddresses.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
+ for (MacAddress mac : macs) {
+ List<MatchInfoBase> matches = new ArrayList<>();
+ matches.add(new MatchEthernetSource(mac));
+ matches.add(buildLPortTagMatch(lportTag));
+
+ List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(new ArrayList<>());
+
+ String flowName = "Egress_L2Broadcast_" + dpId + "_" + lportTag + "_" + mac.getValue();
+ syncFlow(dpId, NwConstants.INGRESS_ACL_TABLE, flowName,
+ AclConstants.PROTO_L2BROADCAST_TRAFFIC_MATCH_PRIORITY, "ACL", 0, 0, AclConstants.COOKIE_ACL_BASE,
+ matches, instructions, addOrRemove);
+ }
+ }
+
protected MatchInfoBase buildLPortTagMatch(int lportTag) {
return AclServiceUtils.buildLPortTagMatch(lportTag, ServiceModeEgress.class);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
List<AllowedAddressPairs> allowedAddresses, int lportTag, String portId, Action action, int addOrRemove);
@Override
- protected void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action, int addOrRemove) {
+ protected void programGeneralFixedRules(AclInterface port, String dhcpMacAddress,
+ List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
LOG.info("programFixedRules : {} default rules.", action == Action.ADD ? "adding" : "removing");
+ 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);
ingressAclIcmpv6AllowedTraffic(dpid, lportTag, addOrRemove);
programArpRule(dpid, lportTag, addOrRemove);
+ programIpv4BroadcastRule(port, addOrRemove);
}
}
AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
+
+ /**
+ * Programs broadcast rules.
+ *
+ * @param port the Acl Interface port
+ * @param addOrRemove whether to delete or add flow
+ */
+ @Override
+ protected void programBroadcastRules(AclInterface port, int addOrRemove) {
+ programIpv4BroadcastRule(port, addOrRemove);
+ }
+
+ /**
+ * Programs IPv4 broadcast rules.
+ *
+ * @param port the Acl Interface port
+ * @param addOrRemove whether to delete or add flow
+ */
+ private void programIpv4BroadcastRule(AclInterface port, int addOrRemove) {
+ BigInteger dpId = port.getDpId();
+ int lportTag = port.getLPortTag();
+ MatchInfoBase lportMatchInfo = buildLPortTagMatch(lportTag);
+ List<IpPrefixOrAddress> cidrs = port.getSubnetIpPrefixes();
+ if (cidrs != null) {
+ List<String> broadcastAddresses = AclServiceUtils.getIpBroadcastAddresses(cidrs);
+ for (String broadcastAddress : broadcastAddresses) {
+ List<MatchInfoBase> matches =
+ AclServiceUtils.buildBroadcastIpV4Matches(broadcastAddress);
+ matches.add(lportMatchInfo);
+ List<InstructionInfo> instructions = new ArrayList<>();
+ instructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE));
+ String flowName = "Ingress_v4_Broadcast_" + dpId + "_" + lportTag + "_" + broadcastAddress + "_Permit";
+ syncFlow(dpId, NwConstants.EGRESS_ACL_TABLE, flowName,
+ AclConstants.PROTO_MATCH_PRIORITY, "ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+ instructions, addOrRemove);
+ }
+ } else {
+ LOG.error("IP Broadcast CIDRs are missing for port {}", port.getInterfaceId());
+ }
+ }
+
protected MatchInfoBase buildLPortTagMatch(int lportTag) {
return AclServiceUtils.buildLPortTagMatch(lportTag, ServiceModeIngress.class);
}
}
@Override
- protected void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action,
+ protected void programGeneralFixedRules(AclInterface port, String dhcpMacAddress,
+ List<AllowedAddressPairs> allowedAddresses, Action action,
int addOrRemove) {
LOG.debug("transparent egress acl service - do nothing");
}
}
@Override
- protected void programGeneralFixedRules(BigInteger dpid, String dhcpMacAddress,
- List<AllowedAddressPairs> allowedAddresses, int lportTag, Action action,
+ protected void programGeneralFixedRules(AclInterface port, String dhcpMacAddress,
+ List<AllowedAddressPairs> allowedAddresses, Action action,
int addOrRemove) {
LOG.debug("transparent ingress acl service - do nothing");
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
if (aclClusterUtil.isEntityOwner()) {
LOG.debug("On remove event, notify ACL service manager to unbind ACL from interface: {}", port);
aclServiceManager.notify(aclInterface, null, Action.UNBIND);
+ AclServiceUtils.deleteSubnetIpPrefixes(dataBroker, interfaceId);
}
}
AclInterfaceCacheUtil.removeAclInterfaceFromCache(interfaceId);
if (aclInterface != null) {
aclInterface = getOldAclInterfaceObject(aclInterface, aclInPortAfter);
} else {
- aclInterface = addAclInterfaceToCache(interfaceId, aclInPortAfter);
+ List<IpPrefixOrAddress> subnetIpPrefixes = AclServiceUtils.getSubnetIpPrefixes(dataBroker,
+ portAfter.getName());
+ aclInterface = addAclInterfaceToCache(interfaceId, aclInPortAfter, subnetIpPrefixes);
}
AclInterface oldAclInterface = getOldAclInterfaceObject(aclInterface, aclInPortBefore);
oldAclInterface.setInterfaceId(aclInterface.getInterfaceId());
oldAclInterface.setDpId(aclInterface.getDpId());
oldAclInterface.setLPortTag(aclInterface.getLPortTag());
+ oldAclInterface.setSubnetIpPrefixes(aclInterface.getSubnetIpPrefixes());
oldAclInterface.setElanId(aclInterface.getElanId());
oldAclInterface.setVpnId(aclInterface.getVpnId());
protected void add(InstanceIdentifier<Interface> key, Interface port) {
InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
if (aclInPort != null && aclInPort.isPortSecurityEnabled()) {
- AclInterface aclInterface = addAclInterfaceToCache(port.getName(), aclInPort);
+ List<IpPrefixOrAddress> subnetIpPrefixes = AclServiceUtils.getSubnetIpPrefixes(dataBroker, port.getName());
+ AclInterface aclInterface = addAclInterfaceToCache(port.getName(), aclInPort, subnetIpPrefixes);
if (aclClusterUtil.isEntityOwner()) {
LOG.debug("On add event, notify ACL service manager to bind ACL for interface: {}", port);
aclServiceManager.notify(aclInterface, null, Action.BIND);
}
}
- private AclInterface addAclInterfaceToCache(String interfaceId, InterfaceAcl aclInPort) {
- AclInterface aclInterface = buildAclInterfaceState(interfaceId, aclInPort);
+ private AclInterface addAclInterfaceToCache(String interfaceId, InterfaceAcl aclInPort,
+ List<IpPrefixOrAddress> subnetIpPrefixes) {
+ AclInterface aclInterface = buildAclInterfaceState(interfaceId, aclInPort, subnetIpPrefixes);
AclInterfaceCacheUtil.addAclInterfaceToCache(interfaceId, aclInterface);
return aclInterface;
}
- private AclInterface buildAclInterfaceState(String interfaceId, InterfaceAcl aclInPort) {
+ private AclInterface buildAclInterfaceState(String interfaceId, InterfaceAcl aclInPort,
+ List<IpPrefixOrAddress> subnetIpPrefixes) {
AclInterface aclInterface = new AclInterface();
aclInterface.setInterfaceId(interfaceId);
aclInterface.setPortSecurityEnabled(aclInPort.isPortSecurityEnabled());
aclInterface.setSecurityGroups(aclInPort.getSecurityGroups());
aclInterface.setAllowedAddressPairs(aclInPort.getAllowedAddressPairs());
+ aclInterface.setSubnetIpPrefixes(subnetIpPrefixes);
aclInterface.setElanId(AclServiceUtils.getElanIdFromInterface(interfaceId, dataBroker));
aclInterface.setVpnId(AclServiceUtils.getVpnIdFromInterface(dataBroker, interfaceId));
return aclInterface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
AclInterface aclInterface = updateAclInterfaceCache(added);
if (AclServiceUtils.isOfInterest(aclInterface)) {
+ if (aclInterface.getSubnetIpPrefixes() == null) {
+ // For upgrades
+ List<IpPrefixOrAddress> subnetIpPrefixes = AclServiceUtils.getSubnetIpPrefixes(dataBroker,
+ added.getName());
+ aclInterface.setSubnetIpPrefixes(subnetIpPrefixes);
+ }
List<Uuid> aclList = aclInterface.getSecurityGroups();
if (aclList != null) {
aclDataUtil.addAclInterfaceMap(aclList, aclInterface);
securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode);
if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
- addStatefulIngressAclTableMissFlow(dpnId);
- addStatefulEgressAclTableMissFlow(dpnId);
- addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
- NwConstants.ADD_FLOW);
- addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
- NwConstants.ADD_FLOW);
+ addStatefulIngressDefaultFlows(dpnId);
+ addStatefulEgressDefaultFlows(dpnId);
addConntrackDummyLookup(dpnId, NwConstants.ADD_FLOW);
} else if (securityGroupMode == SecurityGroupMode.Transparent) {
addTransparentIngressAclTableMissFlow(dpnId);
}
}
+ private void addStatefulEgressDefaultFlows(BigInteger dpId) {
+ addStatefulEgressAclTableMissFlow(dpId);
+ addConntrackRules(dpId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
+ NwConstants.ADD_FLOW);
+ addStatefulEgressDropFlows(dpId);
+ }
+
/**
* Adds the egress acl table miss flow.
*
LOG.debug("Added Egress ACL Filter Table allow all Flows for dpn {}", dpId);
}
+ private void addStatefulEgressDropFlows(BigInteger dpId) {
+ List<InstructionInfo> dropInstructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
+ List<MatchInfoBase> arpDropMatches = new ArrayList<>();
+ arpDropMatches.add(MatchEthernetType.ARP);
+ FlowEntity antiSpoofingArpDropFlowEntity =
+ MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
+ "Egress ACL Table ARP Drop Flow", AclConstants.PROTO_ARP_TRAFFIC_DROP_PRIORITY,
+ "Egress ACL Table ARP Drop Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, arpDropMatches,
+ dropInstructions);
+ mdsalManager.installFlow(antiSpoofingArpDropFlowEntity);
+
+ List<MatchInfoBase> ipDropMatches = new ArrayList<>();
+ ipDropMatches.add(MatchEthernetType.IPV4);
+ FlowEntity antiSpoofingIpDropFlowEntity =
+ MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
+ "Egress ACL Table IP Drop Flow", AclConstants.PROTO_IP_TRAFFIC_DROP_PRIORITY,
+ "Egress ACL Table IP Drop Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, ipDropMatches,
+ dropInstructions);
+ mdsalManager.installFlow(antiSpoofingIpDropFlowEntity);
+
+ List<MatchInfoBase> ipv6DropMatches = new ArrayList<>();
+ ipv6DropMatches.add(MatchEthernetType.IPV6);
+ FlowEntity antiSpoofingIpv6DropFlowEntity =
+ MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
+ "Egress ACL Table IPv6 Drop Flow", AclConstants.PROTO_IP_TRAFFIC_DROP_PRIORITY,
+ "Egress ACL Table IPv6 Drop Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, ipv6DropMatches,
+ dropInstructions);
+ mdsalManager.installFlow(antiSpoofingIpv6DropFlowEntity);
+ }
+
private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
List<InstructionInfo> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
}
+ private void addStatefulIngressDefaultFlows(BigInteger dpId) {
+ addStatefulIngressAclTableMissFlow(dpId);
+ addConntrackRules(dpId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
+ NwConstants.ADD_FLOW);
+ addStatefulIngressAllowBroadcastFlow(dpId);
+ }
+
/**
* Adds the ingress acl table miss flow.
*
LOG.debug("Added Ingress ACL Remote Table Miss Flows for dpn {}", dpId);
}
+ private void addStatefulIngressAllowBroadcastFlow(BigInteger dpId) {
+ final List<MatchInfoBase> ipBroadcastMatches =
+ AclServiceUtils.buildBroadcastIpV4Matches(AclConstants.IPV4_ALL_SUBNET_BROADCAST_ADDR);
+ List<InstructionInfo> ipBroadcastInstructions = new ArrayList<>();
+ ipBroadcastInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE));
+ String ipBroadcastflowName = "Ingress_v4_Broadcast_" + dpId + "_Permit";
+ FlowEntity ipBroadcastFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
+ ipBroadcastflowName, AclConstants.PROTO_MATCH_PRIORITY, "ACL", 0, 0, AclConstants.COOKIE_ACL_BASE,
+ ipBroadcastMatches, ipBroadcastInstructions);
+ mdsalManager.installFlow(ipBroadcastFlowEntity);
+
+ final List<MatchInfoBase> l2BroadcastMatch = AclServiceUtils.buildL2BroadcastMatches();
+ List<ActionInfo> l2BroadcastActionsInfos = new ArrayList<>();
+ List<InstructionInfo> l2BroadcastInstructions = getDispatcherTableResubmitInstructions(l2BroadcastActionsInfos,
+ NwConstants.EGRESS_LPORT_DISPATCHER_TABLE);
+ String l2BroadcastflowName = "Ingress_L2_Broadcast_" + dpId + "_Permit";
+ FlowEntity l2BroadcastFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
+ l2BroadcastflowName, AclConstants.PROTO_L2BROADCAST_TRAFFIC_MATCH_PRIORITY, "ACL", 0, 0,
+ AclConstants.COOKIE_ACL_BASE, l2BroadcastMatch, l2BroadcastInstructions);
+ mdsalManager.installFlow(l2BroadcastFlowEntity);
+ }
+
private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
"Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
public static final Integer PROTO_DHCP_SERVER_MATCH_PRIORITY = 63010;
public static final Integer PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY = 63010;
public static final Integer PROTO_ARP_TRAFFIC_MATCH_PRIORITY = 63010;
+ public static final Integer PROTO_ARP_TRAFFIC_DROP_PRIORITY = 63009;
+ public static final Integer PROTO_L2BROADCAST_TRAFFIC_MATCH_PRIORITY = 61005;
public static final Integer PROTO_MATCH_PRIORITY = 61010;
- public static final Integer PREFIX_MATCH_PRIORITY = 61009;
+ public static final Integer PROTO_IP_TRAFFIC_DROP_PRIORITY = 61009;
public static final Integer PROTO_PREFIX_MATCH_PRIORITY = 61008;
public static final Integer PROTO_PORT_MATCH_PRIORITY = 61007;
public static final Integer PROTO_PORT_PREFIX_MATCH_PRIORITY = 61007;
public static final String IPV4_ALL_NETWORK = "0.0.0.0/0";
public static final String IPV6_ALL_NETWORK = "::/0";
+ public static final String BROADCAST_MAC = "ff:ff:ff:ff:ff:ff";
+ public static final String IPV4_ALL_SUBNET_BROADCAST_ADDR = "255.255.255.255";
+
public static final long TCP_FLAG_SYN = 1 << 1;
public static final long TCP_FLAG_ACK = 1 << 4;
public static final long TCP_FLAG_SYN_ACK = TCP_FLAG_SYN + TCP_FLAG_ACK;
package org.opendaylight.netvirt.aclservice.utils;
import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.NxMatchInfo;
import org.opendaylight.genius.mdsalutil.matches.MatchArpSpa;
+import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv6;
import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortsSubnetIpPrefixes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
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.ports.subnet.ip.prefixes.PortSubnetIpPrefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
}
}
+ public static <T extends DataObject> void delete(
+ DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ }
+
/**
* Retrieves the acl matching the key from the data store.
*
return matches;
}
+ public static List<MatchInfoBase> buildBroadcastIpV4Matches(String ipAddr) {
+ List<MatchInfoBase> matches = new ArrayList<>(2);
+ matches.add(new MatchEthernetDestination(new MacAddress(AclConstants.BROADCAST_MAC)));
+ matches.addAll(AclServiceUtils.buildIpMatches(new IpPrefixOrAddress(ipAddr.toCharArray()),
+ MatchCriteria.MATCH_DESTINATION));
+ return matches;
+ }
+
+ public static List<MatchInfoBase> buildL2BroadcastMatches() {
+ List<MatchInfoBase> matches = new ArrayList<>();
+ matches.add(new MatchEthernetDestination(new MacAddress(AclConstants.BROADCAST_MAC)));
+ return matches;
+ }
+
/**
* Builds the service id.
*
return dpId;
}
+ public static List<String> getIpBroadcastAddresses(List<IpPrefixOrAddress> cidrs) {
+ List<String> ipBroadcastAddresses = new ArrayList<>();
+ for (IpPrefixOrAddress cidr : cidrs) {
+ IpPrefix cidrIpPrefix = cidr.getIpPrefix();
+ if (cidrIpPrefix != null) {
+ Ipv4Prefix cidrIpv4Prefix = cidrIpPrefix.getIpv4Prefix();
+ if (cidrIpv4Prefix != null) {
+ ipBroadcastAddresses.add(getBroadcastAddressFromCidr(cidrIpv4Prefix.getValue()));
+ }
+ }
+ }
+ return ipBroadcastAddresses;
+ }
+
+ public static String getBroadcastAddressFromCidr(String cidr) {
+ String[] ipaddressValues = cidr.split("/");
+ int address = InetAddresses.coerceToInteger(InetAddresses.forString(ipaddressValues[0]));
+ int cidrPart = Integer.parseInt(ipaddressValues[1]);
+ int netmask = 0;
+ for (int j = 0; j < cidrPart; ++j) {
+ netmask |= (1 << 31 - j);
+ }
+ int network = (address & netmask);
+ int broadcast = network | ~(netmask);
+ return InetAddresses.toAddrString(InetAddresses.fromInteger(broadcast));
+ }
+
/**
* Builds the ip matches.
*
.child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
}
+ public static List<IpPrefixOrAddress> getSubnetIpPrefixes(DataBroker broker, String portId) {
+ InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
+ .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
+ Optional<PortSubnetIpPrefixes> portSubnetIpPrefixes = read(broker, LogicalDatastoreType.OPERATIONAL, id);
+ if (portSubnetIpPrefixes.isPresent()) {
+ return portSubnetIpPrefixes.get().getSubnetIpPrefixes();
+ }
+ return null;
+ }
+
+ public static void deleteSubnetIpPrefixes(DataBroker broker, String portId) {
+ InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
+ .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
+ }
+
public static Long getVpnIdFromInterface(DataBroker broker, String vpnInterfaceName) {
VpnInterface vpnInterface = VpnHelper.getVpnInterface(broker, vpnInterfaceName);
if (vpnInterface != null) {
]
}
- protected def fixedEgressFlowsPort1() {
+ protected def fixedEgressL2BroadcastFlowsPort1() {
#[
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_0D:AA:D8:42:30:F3"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:F3")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
+ ]
+ ]
+ }
+ protected def fixedEgressFlowsPort1() {
+ #[
new FlowEntityBuilder >> [
dpnId = 123bi
cookie = 110100480bi
]
}
+ protected def fixedEgressL2BroadcastFlowsPort2 () {
+ #[
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_0D:AA:D8:42:30:F4"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:F4")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
+ ]
+ ]
+ }
+
protected def fixedEgressFlowsPort2 () {
#[
new FlowEntityBuilder >> [
]
}
+ protected def fixedEgressL2BroadcastFlowsPort3 () {
+ #[
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_0D:AA:D8:42:30:F5"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:F5")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
+ ]
+ ]
+ }
+
protected def fixedEgressFlowsPort3 () {
#[
new FlowEntityBuilder >> [
protected def etherFlows() {
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ etherEgressFlowsPort1
+ fixedConntrackIngressFlowsPort2
+ etherIngressFlowsPort2
+ etherIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ fixedConntrackEgressFlowsPort2
+ etheregressFlowPort2
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ tcpIngressFlowPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ fixedIngressFlowsPort2
+ fixedConntrackIngressFlowsPort2
+ tcpIngressFlowPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ fixedConntrackEgressFlowsPort2
+ tcpEgressFlowPort2
protected def udpFlows() {
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ udpEgressFlowsPort1
+ fixedConntrackIngressFlowsPort2
+ udpIngressFlowsPort2
+ udpIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ fixedConntrackEgressFlowsPort2
+ udpEgressFlowsPort2
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ icmpIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ fixedIngressFlowsPort2
+ fixedConntrackIngressFlowsPort2
+ icmpIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ fixedConntrackEgressFlowsPort2
+ icmpEgressFlowsPort2
fixedIngressFlowsPort1
+fixedConntrackIngressFlowsPort1
+ udpIngressPortRangeFlows
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ tcpEgressRangeFlows
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ udpIngressAllFlows
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ tcpEgressAllFlows
protected def multipleAcl() {
fixedIngressFlowsPort1
+ fixedConntrackIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedConntrackEgressFlowsPort1
+ etherEgressFlowsPort1
+ fixedConntrackIngressFlowsPort2
+ etherIngressFlowsPort2
+ etherIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ fixedConntrackEgressFlowsPort2
+ etheregressFlowPort2
]
priority = 63010
tableId = NwConstants.INGRESS_ACL_TABLE
+ ],
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_0D:AA:D8:42:30:A4"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:A4")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
]
]
}
]
priority = 63010
tableId = 211 as short
+ ],
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_0D:AA:D8:42:30:A4"
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress("0D:AA:D8:42:30:A4")),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
]
]
}
]
priority = 63010
tableId = 211 as short
+ ],
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_" + mac
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress(mac)),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
]
]
}
protected def etherFlows() {
fixedIngressFlowsPort1
+ etherFlowIngressPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ etherFlowEgressPort1
+ fixedIngressFlowsPort2
+ etherIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ etheregressFlowPort2
+ remoteFlows
protected def tcpFlows() {
fixedIngressFlowsPort1
+ tcpIngressFlowPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ tcpEgressFlowPort1
+ fixedIngressFlowsPort2
+ tcpIngressFlowPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ tcpEgressFlowPort2
+ remoteFlows
protected def udpFlows() {
fixedIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ remoteFlows
}
protected def icmpFlows() {
fixedIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ fixedIngressFlowsPort2
+ + fixedEgressL2BroadcastFlowsPort2
+ fixedEgressFlowsPort2
+ remoteFlows
}
protected def dstRangeFlows() {
fixedIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
+ tcpEgressRangeFlows
}
protected def dstAllFlows() {
fixedIngressFlowsPort1
+ + fixedEgressL2BroadcastFlowsPort1
+ fixedEgressFlowsPort1
}
protected def icmpFlowsForTwoAclsHavingSameRules() {
fixedIngressFlowsPort3
+ + fixedEgressL2BroadcastFlowsPort3
+ fixedEgressFlowsPort3
}
]
priority = 63010
tableId = 211 as short
+ ],
+ new FlowEntityBuilder >> [
+ dpnId = 123bi
+ cookie = 110100480bi
+ flowId = "Egress_L2Broadcast_123_987_" + mac
+ flowName = "ACL"
+ instructionInfoList = #[
+ new InstructionApplyActions(#[
+ new ActionNxResubmit(17 as short)
+ ])
+ ]
+ matchInfoList = #[
+ new MatchEthernetSource(new MacAddress(mac)),
+ new MatchMetadata(1085217976614912bi, MetaDataUtil.METADATA_MASK_LPORT_TAG)
+ ]
+ priority = 61005
+ tableId = 211 as short
]
]
}
if (optionalInf.isPresent()) {
InterfaceBuilder interfaceBuilder = new InterfaceBuilder(optionalInf.get());
if (origSecurityEnabled || updatedSecurityEnabled) {
- InterfaceAcl infAcl = handlePortSecurityUpdated(original, update,
+ InterfaceAcl infAcl = handlePortSecurityUpdated(dataBroker, original, update,
origSecurityEnabled, updatedSecurityEnabled, interfaceBuilder).build();
interfaceBuilder.addAugmentation(InterfaceAcl.class, infAcl);
}
});
}
- private static InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal, Port portUpdated, boolean
- origSecurityEnabled, boolean updatedSecurityEnabled, InterfaceBuilder interfaceBuilder) {
+ private static InterfaceAclBuilder handlePortSecurityUpdated(DataBroker dataBroker, Port portOriginal,
+ Port portUpdated, boolean origSecurityEnabled, boolean updatedSecurityEnabled,
+ InterfaceBuilder interfaceBuilder) {
String interfaceName = portUpdated.getUuid().getValue();
InterfaceAclBuilder interfaceAclBuilder = null;
if (origSecurityEnabled != updatedSecurityEnabled) {
interfaceAclBuilder.setPortSecurityEnabled(true);
NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
+ NeutronvpnUtils.populateSubnetIpPrefixes(dataBroker, port);
}
return interfaceBuilder.build();
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortsSubnetIpPrefixes;
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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeGre;
interfaceAclBuilder.setAllowedAddressPairs(aclAllowedAddressPairs);
}
+ protected static void populateSubnetIpPrefixes(DataBroker broker, Port port) {
+ List<IpPrefixOrAddress> subnetIpPrefixes = NeutronvpnUtils.getSubnetIpPrefixes(broker, port);
+ if (subnetIpPrefixes != null) {
+ String portId = port.getUuid().getValue();
+ InstanceIdentifier portSubnetIpPrefixIdentifier =
+ NeutronvpnUtils.buildPortSubnetIpPrefixIdentifier(portId);
+ PortSubnetIpPrefixesBuilder subnetIpPrefixesBuilder = new PortSubnetIpPrefixesBuilder()
+ .setKey(new PortSubnetIpPrefixesKey(portId)).setPortId(portId)
+ .setSubnetIpPrefixes(subnetIpPrefixes);
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portSubnetIpPrefixIdentifier,
+ subnetIpPrefixesBuilder.build());
+ LOG.debug("Created Subnet IP Prefixes for port {}", port.getUuid().getValue());
+ }
+ }
+
+ protected static List<IpPrefixOrAddress> getSubnetIpPrefixes(DataBroker broker, Port port) {
+ List<Uuid> subnetIds = getSubnetIdsFromNetworkId(broker, port.getNetworkId());
+ if (subnetIds == null) {
+ LOG.error("Failed to get Subnet Ids for the Network {}", port.getNetworkId());
+ return null;
+ }
+ List<IpPrefixOrAddress> subnetIpPrefixes = new ArrayList<>();
+ for (Uuid subnetId : subnetIds) {
+ Subnet subnet = getNeutronSubnet(broker, subnetId);
+ if (subnet != null) {
+ subnetIpPrefixes.add(new IpPrefixOrAddress(subnet.getCidr()));
+ }
+ }
+ return subnetIpPrefixes;
+ }
+
protected static Subnet getNeutronSubnet(DataBroker broker, Uuid subnetId) {
Subnet subnet = null;
subnet = subnetMap.get(subnetId);
FloatingIpIdToPortMappingKey(floatingIpId)).build();
}
+ static InstanceIdentifier<PortSubnetIpPrefixes> buildPortSubnetIpPrefixIdentifier(String portId) {
+ InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
+ .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
+ return id;
+ }
+
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,