return getOvsdbPortMetadata(ingressPort, ovsdbTopology);
}
public OvsdbPortMetadata getOvsdbPortMetadata(Uuid ingressPort, Topology ovsdbTopology) {
- LOG.info("Extract ovsdb port details for neutron port {}", ingressPort.getValue());
+ LOG.debug("Extract ovsdb port details for neutron port {} from Topology {}",
+ ingressPort.getValue(), ovsdbTopology);
OvsdbPortMetadata ovsdbPortMetadata = new OvsdbPortMetadata();
OvsdbBridgeAugmentation bridgeAugmentation = null;
if (ovsdbTopology != null) {
OvsdbTerminationPointAugmentation tpAugmentation
= tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
List<InterfaceExternalIds> externalIds = tpAugmentation.getInterfaceExternalIds();
- for (InterfaceExternalIds externalId : externalIds) {
- if(externalId.getExternalIdValue().equals(ingressPort.getValue())) {
- ovsdbPortMetadata.setOvsdbPort(tpAugmentation);
+ if (externalIds != null ) {
+ for (InterfaceExternalIds externalId : externalIds) {
+ if(externalId.getExternalIdValue().equals(ingressPort.getValue())) {
+ LOG.info("OVSDB port found for neutron port {} : {}", ingressPort, tpAugmentation);
+ ovsdbPortMetadata.setOvsdbPort(tpAugmentation);
+ break;
+ }
+ }
+ if (ovsdbPortMetadata.getOvsdbPort() != null) {
break;
}
}
- if (ovsdbPortMetadata.getOvsdbPort() != null) {
- break;
- }
}
}
if (ovsdbPortMetadata.getOvsdbPort() != null) {
} else {
LOG.warn("OVSDB Operational topology not avaialble.");
}
- LOG.info("Neutron port's {} respective Ovsdb metadata {}", ovsdbPortMetadata);
+ LOG.info("Neutron port's {} respective Ovsdb metadata {}", ingressPort, ovsdbPortMetadata);
return ovsdbPortMetadata;
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public void addAclFlowClassifier(Acl aclFlowClassifier) {
InstanceIdentifier<Acl> aclIid = getAclPath(aclFlowClassifier.getKey());
LOG.info("Write ACL FlowClassifier {} to config data store at {}",aclFlowClassifier, aclIid);
- mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, aclIid, aclFlowClassifier);
+ mdsalPutWrapper(LogicalDatastoreType.CONFIGURATION, aclIid, aclFlowClassifier);
}
public void updateAclFlowClassifier(Acl aclFlowClassifier) {
public void addServiceFunction(ServiceFunction sf) {
InstanceIdentifier<ServiceFunction> sfIid = getSFPath(sf.getKey());
LOG.info("Write Service Function {} to config data store at {}",sf, sfIid);
- mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, sfIid, sf);
+ mdsalPutWrapper(LogicalDatastoreType.CONFIGURATION, sfIid, sf);
}
public void updateServiceFunction(ServiceFunction sf) {
public void addServiceFunctionForwarder(ServiceFunctionForwarder sff) {
InstanceIdentifier<ServiceFunctionForwarder> sffIid = getSFFPath(sff.getKey());
LOG.info("Write Service Function Forwarder {} to config data store at {}",sff, sffIid);
- mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, sffIid, sff);
+ mdsalPutWrapper(LogicalDatastoreType.CONFIGURATION, sffIid, sff);
}
public void addServiceFunctionChain(ServiceFunctionChain sfc) {
InstanceIdentifier<ServiceFunctionChain> sfcIid = getSFCPath(sfc.getKey());
LOG.info("Write Service Function Chain {} to config data store at {}",sfc, sfcIid);
- mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, sfcIid, sfc);
+ mdsalPutWrapper(LogicalDatastoreType.CONFIGURATION, sfcIid, sfc);
}
public void removeServiceFunctionChain(ServiceFunctionChainKey sfcKey) {
public void addServiceFunctionPath(ServiceFunctionPath sfp) {
InstanceIdentifier<ServiceFunctionPath> sfpIid = getSFPPath(sfp.getKey());
LOG.info("Write Service Function Path {} to config data store at {}",sfp, sfpIid);
- mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, sfpIid, sfp);
+ mdsalPutWrapper(LogicalDatastoreType.CONFIGURATION, sfpIid, sfp);
+ }
+
+ private <D extends DataObject> void mdsalPutWrapper(LogicalDatastoreType dataStore, InstanceIdentifier<D> iid, D data) {
+ try {
+ mdsalUtils.put(dataStore, iid, data);
+ } catch (Exception e) {
+ LOG.error("Exception while putting data in data store {} : {}",iid, data, e);
+ }
}
}
*/
package org.opendaylight.netvirt.openstack.sfc.translator.portchain;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
/**
* OpenDaylight Neutron Port Chain yang models data change listener
private static final InstanceIdentifier<PortChain> portChainIid =
InstanceIdentifier.create(Neutron.class).child(PortChains.class).child(PortChain.class);
+ private final ExecutorService eventProcessor;
private final SfcMdsalHelper sfcMdsalHelper;
private final NeutronMdsalHelper neutronMdsalHelper;
private final OvsdbMdsalHelper ovsdbMdsalHelper;
public NeutronPortChainListener(DataBroker db, RenderedServicePathService rspService) {
super(db,new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, portChainIid));
- sfcMdsalHelper = new SfcMdsalHelper(db);
- neutronMdsalHelper = new NeutronMdsalHelper(db);
- ovsdbMdsalHelper = new OvsdbMdsalHelper(db);
+ this.sfcMdsalHelper = new SfcMdsalHelper(db);
+ this.neutronMdsalHelper = new NeutronMdsalHelper(db);
+ this.ovsdbMdsalHelper = new OvsdbMdsalHelper(db);
this.rspService = rspService;
+ ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Port-Chain-Event-Processor").build();
+ this.eventProcessor = Executors.newSingleThreadExecutor(threadFactory);
}
/**
* @param newPortChain - new PortChain
*/
@Override
- public void add(InstanceIdentifier<PortChain> path, PortChain newPortChain) {
+ public void add(final InstanceIdentifier<PortChain> path, final PortChain newPortChain) {
processPortChain(newPortChain);
+ eventProcessor.submit(new Runnable() {
+ @Override
+ public void run() {
+ processPortChain(newPortChain);
+ }
+ });
}
private void processPortChain(PortChain newPortChain) {
List<PortPair> portPairList = new ArrayList<>();
portPairGroupList.add(ppg);
for(Uuid ppUuid : ppg.getPortPairs()) {
- PortPair pp = neutronMdsalHelper.getNeutronPortPair(ppgUuid);
+ PortPair pp = neutronMdsalHelper.getNeutronPortPair(ppUuid);
if (pp != null) {
portPairList.add(pp);
//NOTE:Assuming that ingress and egress port is same.
Port neutronPort = neutronMdsalHelper.getNeutronPort(pp.getIngress());
if (neutronPort != null) {
- portPairToNeutronPortMap.put(ppgUuid, neutronPort);
+ portPairToNeutronPortMap.put(pp.getIngress(), neutronPort);
}
}
}
//Build the SFF Builder from port pair group
ServiceFunctionForwarderBuilder sffBuilder =
PortPairGroupTranslator.buildServiceFunctionForwarder(ppg,portPairList, metadataList);
-
+ LOG.info("SFF generated for Port Pair Group {} :: {}",ppg, sffBuilder);
//Check if SFF already exist
ServiceFunctionForwarder existingSff =
sfcMdsalHelper.getExistingSFF(sffBuilder.getIpMgmtAddress().getIpv4Address().getValue());
sffBuilder.build());
if (sfBuilder != null) {
+ LOG.info("Service Function generated for the Port Pair {} :: {}", portPair, sfBuilder);
//Write the Service Function to SFC data store.
sfcMdsalHelper.addServiceFunction(sfBuilder.build());
//Update the Service Function Dictionary of SFF
for (ServiceFunctionBuilder sf : portPairSFList) {
PortPairGroupTranslator.buildServiceFunctionDictonary(sffBuilder, sf.build());
+ LOG.info("Updating Service Function dictionary of SFF {} for SF {}", sffBuilder, sf);
}
// Send SFF create request
LOG.info("Add Service Function Forwarder {} for Port Pair Group {}", sffBuilder.build(), ppg);
//Write SFC to data store
if (sfc != null) {
+ LOG.info("Add service function chain {}", sfc);
sfcMdsalHelper.addServiceFunctionChain(sfc);
} else {
LOG.warn("Service Function Chain building failed for Port Chain {}", newPortChain);
ServiceFunctionPath sfp = PortChainTranslator.buildServiceFunctionPath(sfc);
//Write SFP to data store
if (sfp != null) {
+ LOG.info("Add service function path {}", sfp);
sfcMdsalHelper.addServiceFunctionPath(sfp);
} else {
LOG.warn("Service Function Path building failed for Service Chain {}", sfc);
//Call Create Rendered Service Path RPC call
if (rpInput != null) {
+ LOG.info("Call RPC for creating RSP :{}", rpInput);
Future<RpcResult<CreateRenderedPathOutput>> result = this.rspService.createRenderedPath(rpInput);
try {
result.get();
import com.google.common.base.Preconditions;
import org.opendaylight.netvirt.openstack.sfc.translator.OvsdbMdsalHelper;
import org.opendaylight.netvirt.openstack.sfc.translator.OvsdbPortMetadata;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SnName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.Open;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocatorKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
private static final AtomicInteger counter = new AtomicInteger(0);
private static final String SFF_DEFAULT_NAME = "sff";
+ private static final String SFF_DPL_SUFFIX = "-dpl";
public static ServiceFunctionForwarderBuilder buildServiceFunctionForwarder(
PortPairGroup portPairGroup,
//Set management ip, same to the ovsdb node ip
sffBuilder.setIpMgmtAddress(sffLocator.getIp());
-
+ sffDplBuilder.setName(new SffDataPlaneLocatorName(sffBuilder.getName().getValue() + SFF_DPL_SUFFIX));
+ sffDplBuilder.setKey(new SffDataPlaneLocatorKey(sffDplBuilder.getName()));
sffDataPlaneLocator.add(sffDplBuilder.build());
//set SFF key
sffBuilder.setKey(new ServiceFunctionForwarderKey(sffBuilder.getName()));
//NOTE: fail mode is set to Open by default
sfdBuilder.setFailmode(Open.class);
+ sfdList.add(sfdBuilder.build());
//TODO: set interface name list
- for (Iterator<ServiceFunctionDictionary> sfdItr = sffBuilder.getServiceFunctionDictionary().iterator();sfdItr
- .hasNext();) {
- ServiceFunctionDictionary sfd = sfdItr.next();
- if (sfd.getName().equals(sfdBuilder.getName())) {
- LOG.info("Existing SF dictionary {} found in SFF {}, removing the SF dictionary", sfd.getName(),
- sffBuilder.getName());
- sfdItr.remove();
- break;
- }
- }
- sfdList.add(sfdBuilder.build());
-
if (sffBuilder.getServiceFunctionDictionary() != null) {
+ for (Iterator<ServiceFunctionDictionary> sfdItr = sffBuilder.getServiceFunctionDictionary().iterator();sfdItr
+ .hasNext();) {
+ ServiceFunctionDictionary sfd = sfdItr.next();
+ if (sfd.getName().equals(sfdBuilder.getName())) {
+ LOG.info("Existing SF dictionary {} found in SFF {}, removing the SF dictionary", sfd.getName(),
+ sffBuilder.getName());
+ sfdItr.remove();
+ break;
+ }
+ }
sffBuilder.getServiceFunctionDictionary().addAll(sfdList);
} else {
sffBuilder.setServiceFunctionDictionary(sfdList);
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.sfc.rev160511.port.pair.attributes.ServiceFunctionParameters;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.sfc.rev160511.sfc.attributes.port.pair.groups.PortPairGroup;
//Set locator type
if (neutronPort != null) {
+ List<FixedIps> fixedIps = neutronPort.getFixedIps();
List<AllowedAddressPairs> attachedIpAddresses = neutronPort.getAllowedAddressPairs();
- //Pick up the first ip address
IpAddress ipAddress;
- if (attachedIpAddresses != null && !attachedIpAddresses.isEmpty()) {
+ if (fixedIps != null && !fixedIps.isEmpty()){
+ ipAddress = fixedIps.get(0).getIpAddress();
+ sfLocator.setIp(ipAddress);
+
+ } else if (attachedIpAddresses != null && !attachedIpAddresses.isEmpty()) {
+ //Pick up the first ip address
ipAddress = attachedIpAddresses.get(0).getIpAddress().getIpAddress();
sfLocator.setIp(ipAddress);
- sfLocator.setPort(new PortNumber(SF_LOCATOR_PORT));
} else {
LOG.warn("No ip address attached to Neutron Port {} related to Port Pair {}", neutronPort, portPair);
//Ideally we should exit here, because without IP address OpenDaylight SFC won't be able to find the
//respective overlay. But if user passes additional parameter through service_function_param
//that can be leveraged here. Parameter passed through service_function_param will take precedence.
}
+ sfLocator.setPort(new PortNumber(SF_LOCATOR_PORT));
} else {
LOG.warn("Neutron port mapped to Port pair ingress/egress port is not found : {}", portPair);
}
//But if user pass specific param using service_function_parameters, set/override it accordingly
- for(ServiceFunctionParameters sfParam : sfParams) {
- if (sfParam.getServiceFunctionParameter().equals(NSH_AWARE_PARAM)) {
- serviceFunctionBuilder.setNshAware(new Boolean(sfParam.getServiceFunctionParameterValue()));
- }
- //There is by default type set to port pair group name, override it if user pass it specific type
- if (sfParam.getServiceFunctionParameter().equals(SF_TYPE_PARAM)) {
- serviceFunctionBuilder.setType(new SftTypeName(sfParam.getServiceFunctionParameterValue()));
- }
- if (sfParam.getServiceFunctionParameter().equals(DPL_TRANSPORT_PARAM)) {
- Class transportTypeClass
- = DPL_TRANSPORT_TYPE.get(sfParam.getServiceFunctionParameterValue());
- sfDataPlaneLocatorBuilder.setTransport(transportTypeClass);
- }
- if (sfParam.getServiceFunctionParameter().equals(DPL_IP_PARAM)) {
- IpAddress ipAddress = new IpAddress(new Ipv4Address(sfParam.getServiceFunctionParameterValue()));
- sfLocator.setIp(ipAddress);
- }
- if (sfParam.getServiceFunctionParameter().equals(DPL_PORT_PARAM)) {
- sfLocator.setPort(new PortNumber(new Integer(sfParam.getServiceFunctionParameterValue())));
- }
- if (sfParam.getServiceFunctionParameter().equals(SFF_NAME_PARAM)) {
- sfDataPlaneLocatorBuilder.setServiceFunctionForwarder(
- new SffName(sfParam.getServiceFunctionParameterValue()));
+ if (sfParams != null) {
+ for(ServiceFunctionParameters sfParam : sfParams) {
+ if (sfParam.getServiceFunctionParameter().equals(NSH_AWARE_PARAM)) {
+ serviceFunctionBuilder.setNshAware(new Boolean(sfParam.getServiceFunctionParameterValue()));
+ }
+ //There is by default type set to port pair group name, override it if user pass it specific type
+ if (sfParam.getServiceFunctionParameter().equals(SF_TYPE_PARAM)) {
+ serviceFunctionBuilder.setType(new SftTypeName(sfParam.getServiceFunctionParameterValue()));
+ }
+ if (sfParam.getServiceFunctionParameter().equals(DPL_TRANSPORT_PARAM)) {
+ Class transportTypeClass
+ = DPL_TRANSPORT_TYPE.get(sfParam.getServiceFunctionParameterValue());
+ sfDataPlaneLocatorBuilder.setTransport(transportTypeClass);
+ }
+ if (sfParam.getServiceFunctionParameter().equals(DPL_IP_PARAM)) {
+ IpAddress ipAddress = new IpAddress(new Ipv4Address(sfParam.getServiceFunctionParameterValue()));
+ sfLocator.setIp(ipAddress);
+ }
+ if (sfParam.getServiceFunctionParameter().equals(DPL_PORT_PARAM)) {
+ sfLocator.setPort(new PortNumber(new Integer(sfParam.getServiceFunctionParameterValue())));
+ }
+ if (sfParam.getServiceFunctionParameter().equals(SFF_NAME_PARAM)) {
+ sfDataPlaneLocatorBuilder.setServiceFunctionForwarder(
+ new SffName(sfParam.getServiceFunctionParameterValue()));
+ }
}
}