/** * Copyright (c) 2015, 2016 NEC Corporation 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.nic.vtn.renderer; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.nic.utils.MdsalUtils; import org.opendaylight.nic.vtn.renderer.VTNRendererUtility.ActionTypeEnum; import org.opendaylight.vtn.manager.util.IpNetwork; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; 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.intent.rev150122.Intent.Status; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.Intent; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.RemoveFlowConditionInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.RemoveFlowConditionInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.SetFlowConditionInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.SetFlowConditionInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.VtnFlowConditions; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowCondition; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.match.fields.VtnEtherMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.match.fields.VtnEtherMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.match.fields.VtnInetMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.match.fields.VtnInetMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.RemoveFlowFilterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.RemoveFlowFilterInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.SetFlowFilterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.SetFlowFilterInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.list.VtnFlowFilter; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.list.VtnFlowFilterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.VtnDropFilterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.VtnDropFilterCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.VtnPassFilterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.VtnPassFilterCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.vtn.drop.filter._case.VtnDropFilterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.filter.rev150907.vtn.flow.filter.type.fields.vtn.flow.filter.type.vtn.pass.filter._case.VtnPassFilterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.mapping.vlan.rev150907.AddVlanMapInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.mapping.vlan.rev150907.AddVlanMapInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName; import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeUpdateMode; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The VTNIntentParser class creates a VTN objects based on the Intents received. */ public class VTNIntentParser { /** * Setting the name for virtual tenant created during first intent request. */ private static final String TENANT_NAME = "vtnRenderer"; /** * Setting the virtual Bridge name created during first intent request. */ private static final String BRIDGE_NAME = "default"; private static final String MATCH_ANY = "match_any"; private static final String DELETE_MATCH_ANY = "match_any_65535"; private static final String FORWARD_FLOWCOND = "F"; private static final String REVERSE_FLOWCOND = "R"; /** * Setting the lowest index value for match_any flow condition used by flow filter. */ private static final int LOW_PRIORITY = 65535; /** * Setting the EtherType value to match only IPV4 packets, in flow condition. */ private static final int ETHER_TYPE = 0x800; private static final Logger LOG = LoggerFactory.getLogger(VTNIntentParser.class); /** * Setting the index of flow filter. */ private int flowFilterIndex = 1; /** * Setting the flow condition forward index. */ private String flowCondFrdIndex; /** * Setting the flow condition revise index. */ private String flowCondRevIndex; /** * Setting the flow condition name. */ private String flowCondName; /** * Setting the index of flow condition. */ private int flowCondIndex = 1; /** * Adding DataBroker instance to store data. */ private DataBroker dataProvider; /** * Instance created for VTNManagerService */ private VTNManagerService vtnManangerService; /** * Instance created for VTNRendererUtility */ private VTNRendererUtility vtnRendererUtility; private static final String FLOW_COND_ER_MESSAGE = "Unable to get flow condition name {}"; public VTNIntentParser(DataBroker dataBroker, VTNManagerService vtn) { this.dataProvider = dataBroker; this.vtnRendererUtility = new VTNRendererUtility(dataProvider); this.vtnManangerService = vtn; } /** * Creates a default Virtual Tenant and default bridge with Vlan mapping and flow condition * * @return {@code true} is returned if the default configuration is created in VTN Manager. */ private boolean isVTNCreated(final boolean isIp, final boolean isMac) { boolean status = createTenant(TENANT_NAME); if (!status) { LOG.error("Tenant creation failed"); return false; } status = setupDefaultBridge(TENANT_NAME, BRIDGE_NAME); if (!status) { LOG.error("Vbridge creation failed"); return false; } /** * Creates a default flow condition */ status = createFlowCond("0.0", "0.0", MATCH_ANY, "M", isIp, isMac); if (!status) { LOG.error("Flow condition creation failed"); return false; } return true; } /** * Delete the default configuration in VTN Manager. * * @return {@code true} is returned if the default configuration is deleted in VTN Manager. */ private boolean isDeleteDefault() { if (deleteTenant(TENANT_NAME)) { return deleteFlowCond(DELETE_MATCH_ANY); } return false; } /** * Creates VTN elements based on the intent action * * @param adressSrc Valid source IP or MAC Address. * @param adressDst Valid destination IP or MAC Address. * @param action Valid Actions. * @param encodeUUID the encodeUUID value of intent ID. * @param intent the intent instance. * @return CompletedSuccess is returned if VTN elements are successfully created. */ public Status rendering(final String adressSrc, final String adressDst, String action, String encodeUUID, Intent intent) { try { boolean isValidIp = vtnRendererUtility.validateSrcDstIP(adressSrc,adressDst); boolean isValidMac = false; if (!isValidIp) { isValidMac = vtnRendererUtility.validateSrcDstMac(adressSrc, adressDst); } if (isValidIp || isValidMac) { if (!isVTNCreated(isValidIp, isValidMac)) { LOG.error("Default VTN configuration creation failed"); return Status.CompletedError; } String condNameSrcDst = constructCondName(adressSrc, adressDst, encodeUUID, true); String condNameDstSrc = constructCondName(adressDst, adressSrc, encodeUUID, false); String whichAction = ActionTypeEnum.fromActionType(action).getLabel(); createFlowCond(adressSrc, adressDst, condNameSrcDst, FORWARD_FLOWCOND, isValidIp, isValidMac); createFlowCond(adressDst, adressSrc, condNameDstSrc, REVERSE_FLOWCOND, isValidIp, isValidMac); createFlowFilter(TENANT_NAME, BRIDGE_NAME, whichAction, flowCondFrdIndex); createFlowFilter(TENANT_NAME, BRIDGE_NAME, whichAction, flowCondRevIndex); createFlowFilter(TENANT_NAME, BRIDGE_NAME, "DROP", MATCH_ANY); LOG.trace("VTN configuration is successfully updated for user Intents."); return Status.CompletedSuccess; } else { LOG.warn("Invalid address is specified in Intent configuration: {}", intent.getId()); return Status.CompletedError; } } catch (Exception e) { LOG.error("Unable to create VTN Objects {}", e); return Status.CompletedError; } } /** * Updates VTN elements based on the intent action * * @param adressSrc Valid source IP or MAC Address. * @param adressDst Valid Destination IP or MAC Address. * @param action Valid Action to update the intent. * @param intentID ID of the updating intent. * @param encodeUUID ID of the encode UUID. * @param intent The intent instance. * @return CompletedSuccess is returned if VTN elements are successfully updated. */ public Status updateRendering(final String adressSrc, final String adressDst, String action, String intentID, String encodeUUID, Intent intent) { String inSrcIP = null; String outSrcIP = null; String inDstIP = null; String outDscIP = null; String inSrcMAC = null; String outSrcMAC = null; String inDscMAC = null; String outDscMAC = null; try { boolean isValidIp = vtnRendererUtility.validateSrcDstIP(adressSrc,adressDst); boolean isValidMac = false; if (!isValidIp) { isValidMac = vtnRendererUtility.validateSrcDstMac(adressSrc, adressDst); } if (isValidIp || isValidMac) { String condNameSrcDst = constructCondName(adressSrc, adressDst, encodeUUID, true); String condNameDstSrc = constructCondName(adressDst, adressSrc, encodeUUID, false); String whichAction = ActionTypeEnum.fromActionType(action).getLabel(); List<VtnFlowMatch> flowMatch = listOfFlowMatch(encodeUUID); for (VtnFlowMatch fm : flowMatch) { if (isValidIp) { VtnInetMatch inet = fm.getVtnInetMatch(); if (inet != null) { IpPrefix src = inet.getSourceNetwork(); inSrcIP = src.toString(); IpPrefix dst = inet.getDestinationNetwork(); inDstIP = dst.toString(); outSrcIP = adressSrc.replace(".", ""); outDscIP = adressDst.replace(".", ""); } } else if (isValidMac) { VtnEtherMatch eth = fm.getVtnEtherMatch(); MacAddress esrc = eth.getSourceAddress(); if (esrc != null) { inSrcMAC = esrc.toString(); MacAddress edst = eth.getDestinationAddress(); inDscMAC = edst.toString(); outSrcMAC = adressSrc.replace(":", ""); outDscMAC = adressDst.replace(":", ""); } } if (validateSrcDstInputs(inSrcIP,outSrcIP,inDstIP,outDscIP) || validateSrcDstInputs(inSrcMAC,outSrcMAC,inDscMAC,outDscMAC) ) { delFlowCondFilter(encodeUUID); // Deleting the flow condition if (isVTNCreated(isValidIp,isValidMac)) { createFlowCond(adressSrc, adressDst, condNameSrcDst, FORWARD_FLOWCOND, isValidIp, isValidMac); createFlowCond(adressDst, adressSrc, condNameDstSrc, REVERSE_FLOWCOND, isValidIp, isValidMac); } } else { delFlowFilterIndex(encodeUUID); // Deleting the flow filter } createFlowFilter(TENANT_NAME, BRIDGE_NAME, whichAction, flowCondFrdIndex); createFlowFilter(TENANT_NAME, BRIDGE_NAME, whichAction, flowCondRevIndex); } return Status.CompletedSuccess; } else { LOG.warn("Invalid address is specified in Intent configuration: {}", intentID); return Status.CompletedError; } } catch (Exception e) { LOG.error("Unable to update VTN Objects {}", e); return Status.CompletedError; } } /** * Delete the flow condition and flow filter associated with a particular intent. * * @param intentID ID of the Deleting intent. */ public void delFlowCondFilter(String intentID) { try { for (VtnFlowCondition flowCondition : readFlowConditions()) { String lclfc = flowCondition.getName().getValue(); String encodeUUID = lclfc.split("_")[0]; String flowfilterindex = lclfc.split("_")[2]; Integer delflowfilterindex = Integer.valueOf(flowfilterindex); if (encodeUUID.equals(intentID)) { deleteFlowCond(lclfc); deleteFlowFilter(delflowfilterindex); } } LOG.trace("Removed VTN configuration associated with the deleted Intent: {}", intentID); List<VtnFlowCondition> flowConditionList = readFlowConditions(); if (flowConditionList.size() == 1) { boolean result = isDeleteDefault(); if (result) { LOG.info("Removed default VTN configuration."); } } } catch (Exception e) { LOG.error("{} : Unable to Delete, {}", intentID, e); } } /** * To get and delete the flow filter index associated with a particular intent. * * @param intentID ID of the Deleting intent. */ private void delFlowFilterIndex(String intentID) { try { for (VtnFlowCondition flowCondition : readFlowConditions()) { String lclfc = flowCondition.getName().getValue(); String encodeUUID = lclfc.split("_")[0]; String flowfilterindex = lclfc.split("_")[2]; Integer delflowfilterindex = Integer.valueOf(flowfilterindex); if (encodeUUID.equals(intentID)) { deleteFlowFilter(delflowfilterindex); } } } catch (Exception e) { LOG.error("{} : Unable to Delete the flow filter, {}", intentID, e); } } /** * This method creates a flow condition name * * @param adressSrc Valid source IP or MAC Address. * @param addressDst Valid Destination IP or MAC Address. * @param encodeUUID encodeUUID value of intent ID. * @param isSrcCond choosing the flow condition name. * @return flow condition name on valid IP Address or MAC Address */ private String constructCondName(final String adressSrc, final String addressDst, final String encodeUUID, boolean isSrcCond) { String condName = null; if (isSrcCond) { condName = encodeUUID + "_" + FORWARD_FLOWCOND; } else { condName = encodeUUID + "_" + REVERSE_FLOWCOND; } return condName; } /** * Create a new tenant in VTN Manager. * * @param tenantName The name of the tenant to be created. * @return {@code true} is returned if tenant is created in VTN Manager. */ private boolean createTenant(String tenantName) { return vtnManangerService.updateTenant(tenantName, VnodeUpdateMode.UPDATE); } /** * Delete the specified tenant in VTN Manager. * * @param tenantName The name of the tenant to be deleted. * @return {@code true} is returned if the tenant is deleted. */ private boolean deleteTenant(String tenantName) { return vtnManangerService.removeTenant(tenantName); } /** * This method creates flow condition * * @param addressSrc Valid source IP or MAC Address. * @param addressDst Valid destination IP or MAC Address. * @param condName Flow condition name that needs to be created. * @param flowDirection defining the flow direction as Forward and Reverse. * @return {@code true} is returned if only flow condition is created in VTN Manager. */ private boolean createFlowCond(final String addressSrc, final String addressDst, String condName, String flowDirection, boolean isValidIp, boolean isValidMac) { int index = 0; if (isFlowCondExist(condName)) { return true ; } if (condName.equalsIgnoreCase(MATCH_ANY)) { index = LOW_PRIORITY; } else { index = flowFilterIndex++; } if (flowDirection.equalsIgnoreCase(FORWARD_FLOWCOND)) { flowCondFrdIndex = condName + "_" + index; flowCondName = flowCondFrdIndex; } else if (flowDirection.equalsIgnoreCase(REVERSE_FLOWCOND)) { flowCondRevIndex = condName + "_" + index; flowCondName = flowCondRevIndex; } else { flowCondName = condName + "_" + index; } try { if (!isFlowCondExist(flowCondName)) { List<VtnFlowMatch> matchList = new ArrayList<VtnFlowMatch>(); VlanId vlanId = new VlanId(0); if (addressSrc.equalsIgnoreCase("0.0")) { MacAddress macAddress = null; VtnEtherMatch ethernetMatch = new VtnEtherMatchBuilder() .setDestinationAddress(macAddress) .setSourceAddress(macAddress) .setVlanId(vlanId) .setVlanPcp(null) .setEtherType(new EtherType(Long.valueOf(ETHER_TYPE))) .build(); VtnFlowMatch flowMatch = new VtnFlowMatchBuilder() .setIndex(flowCondIndex++) .setVtnEtherMatch(ethernetMatch) .build(); matchList.add(flowMatch); } else if (isValidIp ) { matchList = createFlowMatchForIP(addressSrc, addressDst); } else if (isValidMac) { matchList = createFlowMatchForMAC(addressSrc, addressDst); } else { return false; } VnodeName vnodeName = new VnodeName(flowCondName); SetFlowConditionInput fcond = new SetFlowConditionInputBuilder() .setName(vnodeName) .setVtnFlowMatch(matchList) .build(); return vtnManangerService.setFlowCond(fcond); } } catch (UnknownHostException e) { LOG.error("Unable to create Flow Condition {}", e); return false; } return true; } /** * Delete the given flow condition * * @param condName Flow condition name that needs to be deleted. * @return {@code true} on successful deletion */ private boolean deleteFlowCond(String condName) { RemoveFlowConditionInput input = new RemoveFlowConditionInputBuilder() .setName(condName) .build(); return vtnManangerService.unsetFlowCond(input); } /** * This method will return if the bridge already exists, if tenant with same * name already exists false is returned else return true. * * @param condName Flow condition name, that needs to be verified if already exists. * @return {@code false} is returned if flow condition is not present in VTN Manager. */ private boolean isFlowCondExist(String condName) { for (VtnFlowCondition condition : readFlowConditions()) { if (condition.getName().getValue().equals(condName)) { return true; } } return false; } /** * Creates flow filter for the given flow condition * * @param tenantName The VTN tenant name to create the FlowFilter. * @param bridgeName The VTN bridge name to create the FlowFilter. * @param type The type of flow filter that needs to be created. * @param condName The flow condition name to create the Flow Filter. */ private void createFlowFilter(String tenantName, String bridgeName, String type, String condName) { String flowFilterCondName; int index = 0; if (condName.equalsIgnoreCase(MATCH_ANY)) { index = LOW_PRIORITY; flowFilterCondName = condName + "_" + index; } else { flowFilterCondName = condName; String flowfilterindex = flowFilterCondName.split("_")[2]; index = Integer.valueOf(flowfilterindex); } if ("PASS".equalsIgnoreCase(type)) { VtnPassFilterCase pass = new VtnPassFilterCaseBuilder() .setVtnPassFilter(new VtnPassFilterBuilder().build()) .build(); List<VtnFlowFilter> vtnFlowFilterList = new ArrayList<VtnFlowFilter>(); VnodeName vnodeName = new VnodeName(flowFilterCondName); VtnFlowFilter filter = new VtnFlowFilterBuilder() .setIndex(index) .setCondition(vnodeName) .setVtnFlowFilterType(pass) .build(); vtnFlowFilterList.add(filter); SetFlowFilterInput input = new SetFlowFilterInputBuilder() .setTenantName(tenantName) .setBridgeName(bridgeName) .setVtnFlowFilter(vtnFlowFilterList) .build(); vtnManangerService.setFlowFilter(input); } else if ("DROP".equalsIgnoreCase(type)) { VtnDropFilterCase drop = new VtnDropFilterCaseBuilder() .setVtnDropFilter(new VtnDropFilterBuilder().build()) .build(); List<VtnFlowFilter> vtnFlowFilterList = new ArrayList<VtnFlowFilter>(); VnodeName vnodeName = new VnodeName(flowFilterCondName); VtnFlowFilter filter = new VtnFlowFilterBuilder() .setIndex(index) .setCondition(vnodeName) .setVtnFlowFilterType(drop) .build(); vtnFlowFilterList.add(filter); SetFlowFilterInput input = new SetFlowFilterInputBuilder() .setTenantName(tenantName) .setBridgeName(bridgeName) .setVtnFlowFilter(vtnFlowFilterList) .build(); vtnManangerService.setFlowFilter(input); } else { return; } } /** * Delete an Existing flow filter with received ID * * @param index Flow Filter index number to be deleted. * @return {@code true} flow filter is deleted in VTN Manager. */ private boolean deleteFlowFilter(int index) { final List<Integer> indexList = new ArrayList<Integer>(); indexList.add(index); RemoveFlowFilterInput input = new RemoveFlowFilterInputBuilder() .setTenantName(TENANT_NAME) .setBridgeName(BRIDGE_NAME) .setIndices(indexList) .build(); return vtnManangerService.unSetFlowFilter(input); } /** * Create a virtual bridge which on true creates vlanmapping for * the vbridge created. * * @param tenantName The VTN tenant name under which the VTN Bridge should be created. * @param bridgeName Valid VTN bridge name to be created. * @return {@code true} only bridge is created in VTN Manager. */ private boolean setupDefaultBridge(String tenantName, String bridgeName) { VlanId vlanId = new VlanId(0); boolean status = vtnManangerService.updateBridge(tenantName, bridgeName, bridgeName + " description", VnodeUpdateMode.UPDATE); if (status) { AddVlanMapInput input = new AddVlanMapInputBuilder() .setBridgeName(bridgeName) .setTenantName(tenantName) .setVlanId(vlanId) .build(); status = vtnManangerService.setVlanMap(input); } return status; } /** * Iterates over all List until a specified condition name is found that has * the same name as specified in search * * @param search Passing a parameter as encode UUID. * @return {@code false} only if search string is not present in the list */ public boolean containsIntentID(final String search) { try { for (VtnFlowCondition fc : readFlowConditions()) { String lclfc = fc.getName().getValue(); String intentID = lclfc.split("_")[0]; if (intentID.equals(search)) { return true; } } } catch (Exception e) { LOG.error(FLOW_COND_ER_MESSAGE, e); } return false; } /** * Iterates over all List until a specified condition name is found that has * the same name as specified in search * * @param search Passing a parameter as encode UUID. * @return list of flow match based on flow condition name. */ private List<VtnFlowMatch> listOfFlowMatch(final String search) { List<VtnFlowMatch> flow = null; try { for (VtnFlowCondition fc : readFlowConditions()) { String lclfc = fc.getName().getValue(); String intentID = lclfc.split("_")[0]; if (intentID.equals(search)) { flow = fc.getVtnFlowMatch(); return flow; } } } catch (Exception e) { LOG.error(FLOW_COND_ER_MESSAGE, e); } return flow; } /** * Read all the flow conditions from the MD-SAL datastore. * * @return A list of {@link VtnFlowCondition} instances. */ private List<VtnFlowCondition> readFlowConditions() { List<VtnFlowCondition> vlist = new ArrayList<>(); try { InstanceIdentifier<VtnFlowConditions> path = InstanceIdentifier.create(VtnFlowConditions.class); LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL; MdsalUtils mdsal = new MdsalUtils(dataProvider); VtnFlowConditions opt = mdsal.read(oper, path); if (opt != null) { vlist = opt.getVtnFlowCondition(); } if (vlist == null || vlist.isEmpty()) { return Collections.<VtnFlowCondition>emptyList(); } } catch (Exception e) { LOG.error(FLOW_COND_ER_MESSAGE, e); } return vlist; } /** * Validate new Source and exist Source IP Address should not same * for before updating the intent. * * @param inSrc Exist Source Address. * @param outSrc New Source Address. * @param inDst Exist Destination Address. * @param outDsc New Destination Address. * @return {@code true} if new Source and exist Source IP address are not same. */ private boolean validateSrcDstInputs(String inSrc, String outSrc,String inDst,String outDsc ) { return (vtnRendererUtility.validateInSrcOutSrc(inSrc,outSrc) || vtnRendererUtility.validateInSrcOutSrc(inDst,outDsc)); } /** * Create flow match specific to IP Address * * @param addressSrc Valid source IP. * @param addressDst Valid destination IP. * @return list of flow match based on IP Address. */ private List<VtnFlowMatch> createFlowMatchForIP(final String addressSrc, final String addressDst) throws UnknownHostException { List<VtnFlowMatch> matchList = new ArrayList<VtnFlowMatch>(); VlanId vlanId = new VlanId(0); IpNetwork ipaddrSrc = IpNetwork.create(InetAddress.getByName(addressSrc)); IpNetwork ipaddrDst = IpNetwork.create(InetAddress.getByName(addressDst)); MacAddress macAddress = null; VtnInetMatch match = new VtnInetMatchBuilder() .setDestinationNetwork(ipaddrDst.getIpPrefix()) .setSourceNetwork(ipaddrSrc.getIpPrefix()) .setProtocol((short)1) .setDscp(null) .build(); VtnEtherMatch ethernetMatch = new VtnEtherMatchBuilder() .setDestinationAddress(macAddress) .setSourceAddress(macAddress) .setVlanId(vlanId) .setVlanPcp(null) .setEtherType(new EtherType(Long.valueOf(ETHER_TYPE))) .build(); VtnFlowMatch flowMatch = new VtnFlowMatchBuilder() .setIndex(flowCondIndex++) .setVtnEtherMatch(ethernetMatch) .setVtnInetMatch(match) .build(); matchList.add(flowMatch); return matchList; } /** * Create flow match specific to MAC Address. * * @param addressSrc Valid MAC Address. * @param addressDst Valid MAC Address. * @return list of flow match based on MAC Address. */ private List<VtnFlowMatch> createFlowMatchForMAC(final String addressSrc, final String addressDst) { List<VtnFlowMatch> matchList = new ArrayList<VtnFlowMatch>(); VlanId vlanId = new VlanId(0); MacAddress macAddressSrc = new MacAddress(addressSrc); MacAddress macAddressDst = new MacAddress(addressDst); VtnEtherMatch ethernetMatch = new VtnEtherMatchBuilder() .setDestinationAddress(macAddressDst) .setSourceAddress(macAddressSrc) .setVlanId(vlanId) .setVlanPcp(null) .setEtherType(null) .build(); VtnFlowMatch flowMatch = new VtnFlowMatchBuilder() .setIndex(flowCondIndex++) .setVtnEtherMatch(ethernetMatch) .build(); matchList.add(flowMatch); return matchList; } }