import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.SalPortService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
SalGroupService, //
SalFlowService, //
SalMeterService, //
+ SalPortService, //
PacketProcessingService, //
OpendaylightGroupStatisticsService, //
OpendaylightMeterStatisticsService, //
@Override
public Future<RpcResult<UpdateMeterOutput>> updateMeter(UpdateMeterInput input);
+
+ @Override
+ public Future<RpcResult<GetPortOutput>> getPort();
+
+ @Override
+ public Future<RpcResult<UpdatePortOutput>> updatePort(UpdatePortInput input);
}
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
return new TransactionId(bigIntXid);
}
+
+ @Override
+ public Future<RpcResult<GetPortOutput>> getPort() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<UpdatePortOutput>> updatePort(UpdatePortInput input) {
+ PortModInput ofPortModInput = null ;
+ RpcResult<UpdatePortOutput> rpcResultFromOFLib = null ;
+
+
+ // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
+ // the request can be routed through any connection to the switch
+
+ SwitchConnectionDistinguisher cookie = null ;
+
+ // NSF sends a list of port and the ModelDrivenSwitch will
+ // send one port at a time towards the switch ( mutiple RPCs calls)
+ List<Port> inputPorts = input.getUpdatedPort().getPort().getPort() ;
+
+ // Get the Xid. The same Xid has to be sent in all the RPCs
+ Long Xid = sessionContext.getNextXid();
+
+ for( Port inputPort : inputPorts) {
+
+ // Convert the UpdateGroupInput to GroupModInput
+ ofPortModInput = PortConvertor.toPortModInput(inputPort, version) ;
+
+ // Insert the Xid ( transaction Id) before calling the RPC on the OFLibrary
+
+ PortModInputBuilder mdInput = new PortModInputBuilder();
+ mdInput.setXid(Xid);
+ mdInput.setVersion(ofPortModInput.getVersion()) ;
+ mdInput.setPortNo(ofPortModInput.getPortNo()) ;
+ mdInput.setMaskV10(ofPortModInput.getMaskV10()) ;
+ mdInput.setMask(ofPortModInput.getMask()) ;
+ mdInput.setHwAddress(ofPortModInput.getHwAddress());
+ mdInput.setConfigV10(ofPortModInput.getConfigV10()) ;
+ mdInput.setConfig(ofPortModInput.getConfig()) ;
+ mdInput.setAdvertiseV10(ofPortModInput.getAdvertiseV10()) ;
+ mdInput.setAdvertise(ofPortModInput.getAdvertise()) ;
+
+ LOG.debug("Calling the PortMod RPC method on MessageDispatchService");
+ Future<RpcResult<UpdatePortOutput>> resultFromOFLib = messageService.portMod(ofPortModInput, cookie) ;
+
+ try {
+ rpcResultFromOFLib = resultFromOFLib.get();
+ } catch( Exception ex ) {
+ LOG.error( " Error while getting result for updatePort RPC" + ex.getMessage());
+ }
+
+ // The Future response value for all the RPCs except the last one is ignored
+
+ }
+
+ //Extract the Xid only from the Future for the last RPC and
+ // send it back to the NSF
+ UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult() ;
+
+ UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder() ;
+ updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId()) ;
+ UpdatePortOutput result = updatePortOutput.build();
+
+ Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
+ RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
+
+ LOG.debug("Returning the Update Group RPC result to MD-SAL");
+ return Futures.immediateFuture(rpcResult);
+
+ }
}
}
if (ipv6Match.getIpv6Label() != null) {
- // verify
matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
matchEntriesBuilder.setHasMask(false);
matchEntriesBuilder.setOxmMatchField(Ipv6Flabel.class);
if (protocolMatchFields.getPbb() != null) {
matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
- // verify
matchEntriesBuilder.setHasMask(false);
matchEntriesBuilder.setOxmMatchField(PbbIsid.class);
IsidMatchEntryBuilder isidBuilder = new IsidMatchEntryBuilder();
}
private static void addIpv6PrefixAugmentation(MatchEntriesBuilder builder, Ipv6Prefix address) {
- // TODO: bug
String[] addressParts = address.getValue().split(PREFIX_SEPARATOR);
Integer prefix = null;
if (addressParts.length == 2) {
ipv6AddressBuilder.setIpv6Address(ipv6Address);
builder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());
if (prefix != null) {
- addMaskAugmentation(builder, ByteBuffer.allocate(2).putInt(prefix).array());
+ addMaskAugmentation(builder, convertIpv6PrefixToByteArray(prefix));
+ }
+ }
+
+ private static byte[] convertIpv6PrefixToByteArray(int prefix) {
+ // TODO: Temporary fix. Has performance impacts.
+ byte[] mask = new byte[16];
+ int oneCount = prefix;
+ for (int count = 0; count < 16; count++) {
+ int byteBits = 0;
+ if (oneCount >= 8) {
+ byteBits = 8;
+ oneCount = oneCount - 8;
+ } else {
+ byteBits = oneCount;
+ oneCount = 0;
+ }
+
+ mask[count] = (byte) (256 - Math.pow(2, 8 - byteBits));
}
+ return mask;
}
private static void addMetadataAugmentation(MatchEntriesBuilder builder, BigInteger metadata) {
builder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());
if (prefix != 0) {
int mask = 0xffffffff << (32 - prefix);
- byte[] maskBytes = new byte[4];
-
- for (int currByte = 3; currByte >= 0; --currByte) {
- maskBytes[currByte] = 0;
- maskBytes[currByte] |= ((mask >>> 8 * (3 - currByte)) & (0xff));
- }
+ byte[] maskBytes = new byte[] { (byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8),
+ (byte) mask };
addMaskAugmentation(builder, maskBytes);
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
import org.opendaylight.yangtools.yang.common.RpcResult;
* any connection
* @return - the future
*/
- Future<RpcResult<java.lang.Void>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie);
+ Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie);
/**
* send role request message to switch
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
}
@Override
- public Future<RpcResult<Void>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
- return getConnectionAdapter(cookie).portMod(input);
+ public Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
+
+ LOG.debug("Calling OFLibrary portMod");
+ Future<RpcResult<Void>> response = getConnectionAdapter(cookie).portMod(input);
+
+ // Send the same Xid back to caller - ModelDrivenSwitch
+ UpdatePortOutputBuilder portModOutput = new UpdatePortOutputBuilder();
+ String stringXid =input.getXid().toString();
+ BigInteger bigIntXid = new BigInteger( stringXid );
+ portModOutput.setTransactionId(new TransactionId(bigIntXid));
+ UpdatePortOutput result = portModOutput.build();
+ Collection<RpcError> errors = Collections.emptyList();
+ RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
+
+ LOG.debug("Returning to ModelDrivenSwitch for portMod RPC");
+ return Futures.immediateFuture(rpcResult);
}
@Override
import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemovedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
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.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
if (ofMatch != null) {
salFlowRemoved.setMatch(fromMatch(ofMatch));
}
+ salFlowRemoved.setNode(new NodeRef(InventoryDataServiceUtil.identifierFromDatapathId(sc.getFeatures()
+ .getDatapathId())));
list.add(salFlowRemoved.build());
return list;
} else {