Search in sources :

Example 96 with Actions

use of org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions in project genius by opendaylight.

the class InterfaceManagerConfigurationTest method checkVlanRpcs.

private void checkVlanRpcs() throws Exception {
    // 1. Test dpn-id fetching from interface
    GetDpidFromInterfaceInput dpidFromInterfaceInput = new GetDpidFromInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetDpidFromInterfaceOutput>> dpidFromInterfaceOutput = odlInterfaceRpcService.getDpidFromInterface(dpidFromInterfaceInput);
    Assert.assertEquals(DpnFromInterfaceOutput.newDpnFromInterfaceOutput(), dpidFromInterfaceOutput.get().getResult());
    // 3. Test egress actions fetching for interface
    GetEgressActionsForInterfaceInput egressActionsForInterfaceInput = new GetEgressActionsForInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetEgressActionsForInterfaceOutput>> egressActionsForInterfaceOutput = odlInterfaceRpcService.getEgressActionsForInterface(egressActionsForInterfaceInput);
    assertEqualBeans(EgressActionsForInterfaceOutput.newEgressActionsForInterfaceOutput(), egressActionsForInterfaceOutput.get().getResult());
    // 4. Test egress instructions fetching for interface
    GetEgressInstructionsForInterfaceInput egressInstructionsForInterfaceInput = new GetEgressInstructionsForInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> egressInstructionsForInterfaceOutput = odlInterfaceRpcService.getEgressInstructionsForInterface(egressInstructionsForInterfaceInput);
    assertEqualBeans(EgressInstructionsForInterfaceOutput.newEgressInstructionsForInterfaceOutput(), egressInstructionsForInterfaceOutput.get().getResult());
    // 5. Test interface fetching from if-index
    /* FIXME can be tested only once ResourceBatchingManager becomes testable
        GetInterfaceFromIfIndexInput interfaceFromIfIndexInput = new GetInterfaceFromIfIndexInputBuilder()
                .setIfIndex(1).build();
        Future<RpcResult<GetInterfaceFromIfIndexOutput>> interfaceFromIfIndexOutput = odlInterfaceRpcService
            .getInterfaceFromIfIndex(interfaceFromIfIndexInput);
        assertEqualBeans(InterfaceFromIfIndexOutput.newInterfaceFromIfIndexOutput(),
                interfaceFromIfIndexOutput.get().getResult());*/
    // 6. Test interface type fetching from interface-name
    GetInterfaceTypeInput interfaceTypeInput = new GetInterfaceTypeInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetInterfaceTypeOutput>> interfaceTypeOutput = odlInterfaceRpcService.getInterfaceType(interfaceTypeInput);
    assertEqualBeans(InterfaceTypeOutput.newInterfaceTypeOutput(), interfaceTypeOutput.get().getResult());
    // 7. Test get nodeconnector-id from interface-name
    GetNodeconnectorIdFromInterfaceInput nodeconnectorIdFromInterfaceInput = new GetNodeconnectorIdFromInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetNodeconnectorIdFromInterfaceOutput>> nodeconnectorIdFromInterfaceOutput = odlInterfaceRpcService.getNodeconnectorIdFromInterface(nodeconnectorIdFromInterfaceInput);
    assertEqualBeans(NodeconnectorIdFromInterfaceOutput.newNodeconnectorIdFromInterfaceOutput(), nodeconnectorIdFromInterfaceOutput.get().getResult());
    // 8. Test get port details from interface-name
    GetPortFromInterfaceInput portFromInterfaceInput = new GetPortFromInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
    Future<RpcResult<GetPortFromInterfaceOutput>> portFromInterfaceOutput = odlInterfaceRpcService.getPortFromInterface(portFromInterfaceInput);
    assertEqualBeans(PortFromInterfaceOutput.newPortFromInterfaceOutput(), portFromInterfaceOutput.get().getResult());
}
Also used : GetDpidFromInterfaceInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput) GetDpidFromInterfaceInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder) GetEgressActionsForInterfaceInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder) GetEgressInstructionsForInterfaceInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceInput) GetNodeconnectorIdFromInterfaceInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceInputBuilder) RpcResult(org.opendaylight.yangtools.yang.common.RpcResult) GetPortFromInterfaceInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput) GetPortFromInterfaceInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder) GetInterfaceTypeInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeInput) GetInterfaceTypeInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeInputBuilder) GetEgressActionsForInterfaceInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput) GetNodeconnectorIdFromInterfaceInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceInput) GetEgressInstructionsForInterfaceInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceInputBuilder)

Example 97 with Actions

use of org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions in project genius by opendaylight.

the class ItmManagerRpcService method createTerminatingServiceActions.

@Override
public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
    LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId(), input.getServiceId(), input.getInstruction());
    final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
    int serviceId = input.getServiceId();
    final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
    Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5, String.format("%s:%d", "ITM Flow Entry ", serviceId), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)), mkMatches, input.getInstruction());
    ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
    Futures.addCallback(installFlowResult, new FutureCallback<Void>() {

        @Override
        public void onSuccess(Void voidInstance) {
            result.set(RpcResultBuilder.<Void>success().build());
        }

        @Override
        public void onFailure(Throwable error) {
            String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
            LOG.error("create terminating service actions failed. {}", msg, error);
            result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
        }
    }, MoreExecutors.directExecutor());
    // result.set(RpcResultBuilder.<Void>success().build());
    return result;
}
Also used : MatchInfo(org.opendaylight.genius.mdsalutil.MatchInfo) RpcResult(org.opendaylight.yangtools.yang.common.RpcResult) Flow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow)

Example 98 with Actions

use of org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions in project genius by opendaylight.

the class IfmUtil method getEgressActionInfosForInterface.

/**
 * Returns the list of egress actions for a given interface.
 *
 * @param interfaceInfo the interface to look up
 * @param portNo port number
 * @param ifaceType the type of the interface
 * @param tunnelKey the tunnel key
 * @param actionKeyStart the start for the first key assigned for the new actions
 * @param isDefaultEgress if it is the default egress
 * @param ifIndex interface index
 * @param groupId group Id
 * @return list of actions for the interface
 */
// The following suppression is for javac, not for checkstyle
@SuppressWarnings("fallthrough")
@SuppressFBWarnings("SF_SWITCH_FALLTHROUGH")
public static List<ActionInfo> getEgressActionInfosForInterface(Interface interfaceInfo, String portNo, InterfaceInfo.InterfaceType ifaceType, Long tunnelKey, int actionKeyStart, boolean isDefaultEgress, int ifIndex, long groupId) {
    List<ActionInfo> result = new ArrayList<>();
    switch(ifaceType) {
        case MPLS_OVER_GRE:
        // fall through
        case GRE_TRUNK_INTERFACE:
            if (!isDefaultEgress) {
                // stores the value coming from a VXLAN tunnel
                if (tunnelKey == null) {
                    tunnelKey = 0L;
                }
            }
        // fall through
        case VXLAN_TRUNK_INTERFACE:
            if (!isDefaultEgress) {
                if (tunnelKey != null) {
                    result.add(new ActionSetFieldTunnelId(actionKeyStart++, BigInteger.valueOf(tunnelKey)));
                }
            } else {
                // For OF Tunnels default egress actions need to set tunnelIps
                IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class);
                if (BooleanUtils.isTrue(ifTunnel.isTunnelRemoteIpFlow() && ifTunnel.getTunnelDestination() != null)) {
                    result.add(new ActionSetTunnelDestinationIp(actionKeyStart++, ifTunnel.getTunnelDestination()));
                }
                if (BooleanUtils.isTrue(ifTunnel.isTunnelSourceIpFlow() && ifTunnel.getTunnelSource() != null)) {
                    result.add(new ActionSetTunnelSourceIp(actionKeyStart++, ifTunnel.getTunnelSource()));
                }
            }
        // fall through
        case VLAN_INTERFACE:
            if (isDefaultEgress) {
                IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
                LOG.trace("get egress actions for l2vlan interface: {}", vlanIface);
                boolean isVlanTransparent = false;
                int vlanVid = 0;
                if (vlanIface != null) {
                    vlanVid = vlanIface.getVlanId() == null ? 0 : vlanIface.getVlanId().getValue();
                    isVlanTransparent = vlanIface.getL2vlanMode() == IfL2vlan.L2vlanMode.Transparent;
                }
                if (vlanVid != 0 && !isVlanTransparent) {
                    result.add(new ActionPushVlan(actionKeyStart++));
                    result.add(new ActionSetFieldVlanVid(actionKeyStart++, vlanVid));
                }
                result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
            } else {
                addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
            }
            break;
        case LOGICAL_GROUP_INTERFACE:
            if (isDefaultEgress) {
                result.add(new ActionGroup(groupId));
            } else {
                addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
            }
            break;
        default:
            LOG.warn("Interface Type {} not handled yet", ifaceType);
            break;
    }
    return result;
}
Also used : ActionSetTunnelDestinationIp(org.opendaylight.genius.mdsalutil.actions.ActionSetTunnelDestinationIp) ArrayList(java.util.ArrayList) IfTunnel(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel) ActionSetFieldVlanVid(org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid) ActionInfo(org.opendaylight.genius.mdsalutil.ActionInfo) ActionSetFieldTunnelId(org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId) ActionPushVlan(org.opendaylight.genius.mdsalutil.actions.ActionPushVlan) Uri(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri) ActionSetTunnelSourceIp(org.opendaylight.genius.mdsalutil.actions.ActionSetTunnelSourceIp) ActionGroup(org.opendaylight.genius.mdsalutil.actions.ActionGroup) ActionOutput(org.opendaylight.genius.mdsalutil.actions.ActionOutput) IfL2vlan(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 99 with Actions

use of org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions in project genius by opendaylight.

the class AlivenessProtocolHandlerLLDP method startMonitoringTask.

@Override
public void startMonitoringTask(MonitoringInfo monitorInfo) {
    String sourceInterface;
    EndpointType source = monitorInfo.getSource().getEndpointType();
    if (source instanceof Interface) {
        Interface intf = (Interface) source;
        sourceInterface = intf.getInterfaceName();
    } else {
        LOG.warn("Invalid source endpoint. Could not retrieve source interface to send LLDP Packet");
        return;
    }
    // Get Mac Address for the source interface
    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState;
    try {
        interfaceState = getInterfaceFromOperDS(sourceInterface);
    } catch (ReadFailedException e) {
        LOG.error("getInterfaceFromOperDS failed for sourceInterface: {}", sourceInterface, e);
        return;
    }
    Optional<byte[]> optSourceMac = getMacAddress(interfaceState);
    if (!optSourceMac.isPresent()) {
        LOG.error("Could not read mac address for the source interface {} from the Inventory. " + "LLDP packet cannot be send.", sourceInterface);
        return;
    }
    byte[] sourceMac = optSourceMac.get();
    String lowerLayerIf = interfaceState.getLowerLayerIf().get(0);
    NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
    long nodeId = Long.parseLong(getDpnFromNodeConnectorId(nodeConnectorId));
    long portNum = Long.parseLong(getPortNoFromNodeConnectorId(nodeConnectorId));
    Ethernet ethenetLLDPPacket = makeLLDPPacket(Long.toString(nodeId), portNum, sourceMac, sourceInterface);
    try {
        List<ActionInfo> actions = getInterfaceActions(interfaceState, portNum);
        if (actions.isEmpty()) {
            LOG.error("No interface actions to send packet out over interface {}", sourceInterface);
            return;
        }
        TransmitPacketInput transmitPacketInput = MDSALUtil.getPacketOut(actions, ethenetLLDPPacket.serialize(), nodeId, MDSALUtil.getNodeConnRef(BigInteger.valueOf(nodeId), "0xfffffffd"));
        addErrorLogging(packetProcessingService.transmitPacket(transmitPacketInput), LOG, "transmitPacket() failed: {}", transmitPacketInput);
    } catch (InterruptedException | ExecutionException | PacketException e) {
        LOG.error("Error while sending LLDP Packet", e);
    }
}
Also used : Collections(java.util.Collections) NodeConnectorId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId) ActionInfo(org.opendaylight.genius.mdsalutil.ActionInfo) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException) EndpointType(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.EndpointType) ExecutionException(java.util.concurrent.ExecutionException) ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) Ethernet(org.opendaylight.genius.mdsalutil.packet.Ethernet) TransmitPacketInput(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput) Interface(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface)

Example 100 with Actions

use of org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions in project genius by opendaylight.

the class ArpUtilImpl method sendArpResponse.

@Override
public Future<RpcResult<Void>> sendArpResponse(SendArpResponseInput input) {
    LOG.trace("sendArpResponse rpc invoked");
    BigInteger dpnId;
    byte[] payload;
    byte[] srcMac;
    try {
        String interfaceName = input.getInterface();
        GetPortFromInterfaceOutput portResult = getPortFromInterface(interfaceName);
        checkNotNull(portResult);
        dpnId = portResult.getDpid();
        Long portid = portResult.getPortno();
        NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId, portid.toString());
        checkArgument(null != dpnId && !BigInteger.ZERO.equals(dpnId), ArpConstants.DPN_NOT_FOUND_ERROR, interfaceName);
        checkNotNull(ref, ArpConstants.NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
        LOG.trace("sendArpRequest received dpnId {} out interface {}", dpnId, interfaceName);
        byte[] srcIpBytes = getIpAddressBytes(input.getSrcIpaddress());
        byte[] dstIpBytes = getIpAddressBytes(input.getDstIpaddress());
        if (input.getSrcMacaddress() == null) {
            srcMac = portResult.getPhyAddress().getBytes("UTF-8");
        } else {
            String macAddr = input.getSrcMacaddress().getValue();
            srcMac = HexEncode.bytesFromHexString(macAddr);
        }
        byte[] dstMac = NWUtil.parseMacAddress(input.getDstMacaddress().getValue());
        checkNotNull(srcIpBytes, ArpConstants.FAILED_TO_GET_SRC_IP_FOR_INTERFACE, interfaceName);
        payload = ArpPacketUtil.getPayload(ArpConstants.ARP_RESPONSE_OP, srcMac, srcIpBytes, dstMac, dstIpBytes);
        List<Action> actions = getEgressAction(interfaceName);
        sendPacketOutWithActions(dpnId, payload, ref, actions);
        LOG.debug("Sent ARP response for IP {}, from source MAC {} to target MAC {} and target IP {} via dpnId {}", input.getSrcIpaddress().getIpv4Address().getValue(), HexEncode.bytesToHexStringFormat(srcMac), HexEncode.bytesToHexStringFormat(dstMac), input.getDstIpaddress().getIpv4Address().getValue(), dpnId);
    } catch (UnknownHostException | PacketException | InterruptedException | UnsupportedEncodingException | ExecutionException e) {
        LOG.error("failed to send arp response for {}: ", input.getSrcIpaddress(), e);
        return RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, e.getMessage(), e).buildFuture();
    }
    RpcResultBuilder<Void> rpcResultBuilder = RpcResultBuilder.success();
    return Futures.immediateFuture(rpcResultBuilder.build());
}
Also used : NodeConnectorRef(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef) Action(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action) UnknownHostException(java.net.UnknownHostException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException) BigInteger(java.math.BigInteger) GetPortFromInterfaceOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

ArrayList (java.util.ArrayList)139 Action (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action)86 Action (org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action)45 ActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder)42 Test (org.junit.Test)40 PushVlanActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder)33 GroupActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder)32 PopMplsActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder)32 PopPbbActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.pbb.action._case.PopPbbActionBuilder)32 PopVlanActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder)32 PushMplsActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder)32 PushPbbActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.pbb.action._case.PushPbbActionBuilder)32 PortNumber (org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber)29 ByteBuf (io.netty.buffer.ByteBuf)28 ExecutionException (java.util.concurrent.ExecutionException)28 Instruction (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction)27 ActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder)26 OutputActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder)24 SetMplsTtlActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.mpls.ttl.action._case.SetMplsTtlActionBuilder)22 SetNwTtlActionBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.ttl.action._case.SetNwTtlActionBuilder)22