org.opendaylight.openflowjava.protocol.impl.util.OF10ActionsDeserializer.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.openflowjava.protocol.impl.util.OF10ActionsDeserializer.java

Source

/*
 * Copyright (c) 2013 Pantheon Technologies s.r.o. 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.openflowjava.protocol.impl.util;

import io.netty.buffer.ByteBuf;

import java.util.ArrayList;
import java.util.List;

import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Enqueue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlDst;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlSrc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwDst;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwSrc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTos;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpDst;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpSrc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanPcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
import org.opendaylight.yangtools.yang.binding.Augmentation;

import com.google.common.base.Joiner;

/**
 * Deserializes ofp_action (OpenFlow v1.0) structures
 * @author michal.polkorab
 */
public abstract class OF10ActionsDeserializer {

    private static final byte PADDING_IN_SET_VLAN_VID_ACTION = 2;
    private static final byte PADDING_IN_SET_VLAN_PCP_ACTION = 3;
    private static final byte PADDING_IN_STRIP_VLAN_ACTION = 4;
    private static final byte PADDING_IN_SET_DL_ACTION = 6;
    private static final byte PADDING_IN_NW_TOS_ACTION = 3;
    private static final byte PADDING_IN_TP_ACTION = 2;
    private static final byte PADDING_IN_ENQUEUE_ACTION = 6;

    /**
     * Creates list of actions (OpenFlow v1.0) from ofp_action structures
     * @param input input ByteBuf
     * @return ActionsList list of actions
     */
    public static List<Action> createActionsList(ByteBuf input) {
        List<Action> actions = new ArrayList<>();
        while (input.readableBytes() > 0) {
            int type = input.readUnsignedShort();
            input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
            actions.add(decodeAction(input, type));
        }
        return actions;
    }

    /**
     * Creates list of actions (OpenFlow v1.0) from ofp_action structures, which are not the last structure
     * in message
     * @param input input ByteBuf
     * @param actionsLength length of actions
     * @return ActionsList list of actions
     */
    public static List<Action> createActionsList(ByteBuf input, int actionsLength) {
        List<Action> actions = new ArrayList<>();
        int currentLength = 0;
        while (currentLength < actionsLength) {
            int type = input.readUnsignedShort();
            currentLength += input.readUnsignedShort();
            actions.add(decodeAction(input, type));
        }
        return actions;
    }

    private static Action decodeAction(ByteBuf input, int type) {
        ActionBuilder actionsBuilder = new ActionBuilder();
        Action actionsList = null;
        switch (type) {
        case 0:
            actionsList = createOutputAction(input, actionsBuilder);
            break;
        case 1:
            actionsList = createSetVlanVidAction(input, actionsBuilder);
            break;
        case 2:
            actionsList = createVlanPcpAction(input, actionsBuilder);
            break;
        case 3:
            actionsList = createStripVlanAction(input, actionsBuilder);
            break;
        case 4:
            actionsList = createSetDlSrcAction(input, actionsBuilder);
            break;
        case 5:
            actionsList = createSetDlDstAction(input, actionsBuilder);
            break;
        case 6:
            actionsList = createSetNwSrcAction(input, actionsBuilder);
            break;
        case 7:
            actionsList = createSetNwDstAction(input, actionsBuilder);
            break;
        case 8:
            actionsList = createSetNwTosAction(input, actionsBuilder);
            break;
        case 9:
            actionsList = createSetTpSrcAction(input, actionsBuilder);
            break;
        case 10:
            actionsList = createSetTpDstAction(input, actionsBuilder);
            break;
        case 11:
            actionsList = createEnqueueAction(input, actionsBuilder);
            break;
        case 0xFFFF:
            actionsList = createExperimenterAction(input, actionsBuilder);
            break;
        default:
            break;
        }
        return actionsList;
    }

    /**
     * @param in input ByteBuf
     * @param builder 
     * @return ActionList
     */
    public static Action createOutputAction(ByteBuf in, ActionBuilder builder) {
        builder.setType(Output.class);
        createPortAugmentation(in, builder);
        MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
        maxLen.setMaxLength(in.readUnsignedShort());
        builder.addAugmentation(MaxLengthAction.class, maxLen.build());
        return builder.build();
    }

    private static Action createSetVlanVidAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetVlanVid.class);
        VlanVidActionBuilder vlanBuilder = new VlanVidActionBuilder();
        vlanBuilder.setVlanVid(input.readUnsignedShort());
        input.skipBytes(PADDING_IN_SET_VLAN_VID_ACTION);
        builder.addAugmentation(VlanVidAction.class, vlanBuilder.build());
        return builder.build();
    }

    private static Action createVlanPcpAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetVlanPcp.class);
        VlanPcpActionBuilder vlanBuilder = new VlanPcpActionBuilder();
        vlanBuilder.setVlanPcp(input.readUnsignedByte());
        input.skipBytes(PADDING_IN_SET_VLAN_PCP_ACTION);
        builder.addAugmentation(VlanPcpAction.class, vlanBuilder.build());
        return builder.build();
    }

    private static Action createStripVlanAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(StripVlan.class);
        input.skipBytes(PADDING_IN_STRIP_VLAN_ACTION);
        return builder.build();
    }

    private static Action createSetDlSrcAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetDlSrc.class);
        builder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));
        return builder.build();
    }

    private static Action createSetDlDstAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetDlDst.class);
        builder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));
        return builder.build();
    }

    private static DlAddressAction createDlAugmentationAndPad(ByteBuf input) {
        DlAddressActionBuilder dlBuilder = new DlAddressActionBuilder();
        byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
        input.readBytes(address);
        dlBuilder.setDlAddress(new MacAddress(ByteBufUtils.macAddressToString(address)));
        input.skipBytes(PADDING_IN_SET_DL_ACTION);
        return dlBuilder.build();
    }

    private static Action createSetNwSrcAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetNwSrc.class);
        builder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));
        return builder.build();
    }

    private static Action createSetNwDstAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetNwDst.class);
        builder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));
        return builder.build();
    }

    private static Augmentation<Action> createNwAddressAugmentationAndPad(ByteBuf input) {
        IpAddressActionBuilder ipBuilder = new IpAddressActionBuilder();
        List<String> groups = new ArrayList<>();
        for (int i = 0; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) {
            groups.add(Short.toString(input.readUnsignedByte()));
        }
        Joiner joiner = Joiner.on(".");
        ipBuilder.setIpAddress(new Ipv4Address(joiner.join(groups)));
        return ipBuilder.build();
    }

    private static Action createSetNwTosAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetNwTos.class);
        NwTosActionBuilder tosBuilder = new NwTosActionBuilder();
        tosBuilder.setNwTos(input.readUnsignedByte());
        builder.addAugmentation(NwTosAction.class, tosBuilder.build());
        input.skipBytes(PADDING_IN_NW_TOS_ACTION);
        return builder.build();
    }

    private static Action createSetTpSrcAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetTpSrc.class);
        createPortAugmentation(input, builder);
        input.skipBytes(PADDING_IN_TP_ACTION);
        return builder.build();
    }

    private static Action createSetTpDstAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(SetTpDst.class);
        createPortAugmentation(input, builder);
        input.skipBytes(PADDING_IN_TP_ACTION);
        return builder.build();
    }

    private static void createPortAugmentation(ByteBuf input, ActionBuilder actionBuilder) {
        PortActionBuilder portBuilder = new PortActionBuilder();
        portBuilder.setPort(new PortNumber((long) input.readUnsignedShort()));
        actionBuilder.addAugmentation(PortAction.class, portBuilder.build());
    }

    private static Action createEnqueueAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(Enqueue.class);
        createPortAugmentation(input, builder);
        input.skipBytes(PADDING_IN_ENQUEUE_ACTION);
        QueueIdActionBuilder queueBuilder = new QueueIdActionBuilder();
        queueBuilder.setQueueId(input.readUnsignedInt());
        builder.addAugmentation(QueueIdAction.class, queueBuilder.build());
        return builder.build();
    }

    private static Action createExperimenterAction(ByteBuf input, ActionBuilder builder) {
        builder.setType(Experimenter.class);
        ExperimenterActionBuilder expBuilder = new ExperimenterActionBuilder();
        expBuilder.setExperimenter(input.readUnsignedInt());
        builder.addAugmentation(ExperimenterAction.class, expBuilder.build());
        return builder.build();
    }

}