/** * Copyright (c) 2015 Cisco Systems, Inc. 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.openflowplugin.impl.statistics.services; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.impl.services.RequestInputUtils; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder; final class GroupFeaturesService extends AbstractCompatibleStatService { private static final MultipartRequestGroupFeaturesCase GROUP_FEAT_CASE = new MultipartRequestGroupFeaturesCaseBuilder().build(); public GroupFeaturesService(RequestContextStack requestContextStack, DeviceContext deviceContext, AtomicLong compatibilityXidSeed) { super(requestContextStack, deviceContext, compatibilityXidSeed); } @Override protected OfHeader buildRequest(final Xid xid, final GetGroupFeaturesInput input) { final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader( MultipartType.OFPMPGROUPFEATURES, xid.getValue(), getVersion()); mprInput.setMultipartRequestBody(GROUP_FEAT_CASE); return mprInput.build(); } @Override public GetGroupFeaturesOutput buildTxCapableResult(TransactionId emulatedTxId) { return new GetGroupFeaturesOutputBuilder().setTransactionId(emulatedTxId).build(); } @Override public GroupFeaturesUpdated transformToNotification(List result, TransactionId emulatedTxId) { final int mpSize = result.size(); Preconditions.checkArgument(mpSize == 1, "unexpected (!=1) mp-reply size received: {}", mpSize); GroupFeaturesUpdatedBuilder notification = new GroupFeaturesUpdatedBuilder(); notification.setId(getDeviceContext().getDeviceState().getNodeId()); notification.setMoreReplies(Boolean.FALSE); notification.setTransactionId(emulatedTxId); MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) result.get(0).getMultipartReplyBody(); MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures(); notification.setGroupTypesSupported(extractSupportedGroupTypes(replyBody.getTypes())); notification.setMaxGroups(replyBody.getMaxGroups()); notification.setGroupCapabilitiesSupported(extractSupportedCapabilities(replyBody.getCapabilities())); notification.setActions(extractGroupActionsSupportBitmap(replyBody.getActionsBitmap())); return notification.build(); } @VisibleForTesting static List> extractSupportedCapabilities(GroupCapabilities capabilities) { List> supportedCapabilities = new ArrayList<>(); if (capabilities.isOFPGFCCHAINING()) { supportedCapabilities.add(Chaining.class); } if (capabilities.isOFPGFCCHAININGCHECKS()) { supportedCapabilities.add(ChainingChecks.class); } if (capabilities.isOFPGFCSELECTLIVENESS()) { supportedCapabilities.add(SelectLiveness.class); } if (capabilities.isOFPGFCSELECTWEIGHT()) { supportedCapabilities.add(SelectWeight.class); } return supportedCapabilities; } @VisibleForTesting static List> extractSupportedGroupTypes(GroupTypes types) { List> supportedGroups = new ArrayList<>(); if (types.isOFPGTALL()) { supportedGroups.add(GroupAll.class); } if (types.isOFPGTSELECT()) { supportedGroups.add(GroupSelect.class); } if (types.isOFPGTINDIRECT()) { supportedGroups.add(GroupIndirect.class); } if (types.isOFPGTFF()) { supportedGroups.add(GroupFf.class); } return supportedGroups; } @VisibleForTesting static List extractGroupActionsSupportBitmap(final List actionsSupported) { List supportActionByGroups = new ArrayList<>(); for (ActionType supportedActions : actionsSupported) { long supportActionBitmap = 0; supportActionBitmap |= supportedActions.isOFPATOUTPUT() ? (1 << 0) : 0; supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT() ? (1 << 11) : 0; supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN() ? (1 << 12) : 0; supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL() ? (1 << 15) : 0; supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL() ? (1 << 16) : 0; supportActionBitmap |= supportedActions.isOFPATPUSHVLAN() ? (1 << 17) : 0; supportActionBitmap |= supportedActions.isOFPATPOPVLAN() ? (1 << 18) : 0; supportActionBitmap |= supportedActions.isOFPATPUSHMPLS() ? (1 << 19) : 0; supportActionBitmap |= supportedActions.isOFPATPOPMPLS() ? (1 << 20) : 0; supportActionBitmap |= supportedActions.isOFPATSETQUEUE() ? (1 << 21) : 0; supportActionBitmap |= supportedActions.isOFPATGROUP() ? (1 << 22) : 0; supportActionBitmap |= supportedActions.isOFPATSETNWTTL() ? (1 << 23) : 0; supportActionBitmap |= supportedActions.isOFPATDECNWTTL() ? (1 << 24) : 0; supportActionBitmap |= supportedActions.isOFPATSETFIELD() ? (1 << 25) : 0; supportActionBitmap |= supportedActions.isOFPATPUSHPBB() ? (1 << 26) : 0; supportActionBitmap |= supportedActions.isOFPATPOPPBB() ? (1 << 27) : 0; supportActionByGroups.add(Long.valueOf(supportActionBitmap)); } return supportActionByGroups; } }