/*
* Copyright (c) 2015 Hewlett-Packard Development Company, L.P. 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.nic.of.renderer.utils;
import org.opendaylight.controller.liblldp.EtherTypes;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.EthernetMatchFields;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestination;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.ProtocolMatchFieldsBuilder;
/**
* Contains methods creating flow part for ARP flow.
*/
public class FlowUtils {
/**
* The number of bits in IP ECN field.
*/
private static final int NBITS_IP_ECN = 2;
/**
* A mask value which represents valid bits in an DSCP value for
* IP protocol.
*/
private static final short MASK_IP_DSCP = 0x3f;
private FlowUtils() {
}
/**
* Creates {@link EthernetMatch} containing ARP ether-type and the given destination MAC address
* @return EthernetMatch
*/
public static EthernetMatch createEthernetMatch() {
return new EthernetMatchBuilder().setEthernetType(
new EthernetTypeBuilder().setType(new EtherType(Long.valueOf(EtherTypes.ARP.intValue()))).build())
.build();
}
/**
* Creates {@link ArpMatch} containing Reply ARP operation, THA and TPA for the given target
* address and SPA for the given sender protocol address
*/
// public static ArpMatch createArpMatch() {
// return new ArpMatchBuilder().setArpOp(ArpOperation.REPLY.intValue()).build();
// }
/**
* Creates {@link Action} representing output to the controller
* @param order the order for the action
* @return Action
*/
public static Action createSendToControllerAction(int order) {
return new ActionBuilder().setOrder(order)
.setKey(new ActionKey(order))
.setAction(
new OutputActionCaseBuilder().setOutputAction(
new OutputActionBuilder().setMaxLength(0xffff)
.setOutputNodeConnector(new Uri(OutputPortValues.CONTROLLER.toString()))
.build()).build())
.build();
}
/**
* @param order An integer representing the order of the Action
* withinin the table.
* @return Action with an order
*/
public static Action createOutputNormal(int order) {
return new ActionBuilder().setOrder(order)
.setKey(new ActionKey(order))
.setAction(
new OutputActionCaseBuilder().setOutputAction(
new OutputActionBuilder().setMaxLength(0xffff)
.setOutputNodeConnector(new Uri(OutputPortValues.NORMAL.toString()))
.build()).build())
.build();
}
/**
* Create OF action to perform MPLS push or pop label
* @param order An integer representing the order of the Action
* within the table.
* @param popLabel true for MPLS pop action
* @return Action containing MPLS informations
*/
public static Action createMPLSAction(int order, boolean popLabel) {
Action action = null;
ActionBuilder ab = new ActionBuilder();
if (popLabel) {
PopMplsActionBuilder popMplsActionBuilder = new PopMplsActionBuilder();
// EthernetType will change based on the packet resulting after the topmost MPLS header has been removed
popMplsActionBuilder.setEthernetType(EtherTypes.IPv4.intValue());
ab.setOrder(order).setKey(new ActionKey(order)).setAction(new PopMplsActionCaseBuilder().setPopMplsAction(popMplsActionBuilder.build()).build());
action = ab.build();
} else {
PushMplsActionBuilder pushMplsActionBuilder = new PushMplsActionBuilder();
// EthernetType of MPLS tag
pushMplsActionBuilder.setEthernetType(EtherTypes.MPLSUCAST.intValue());
ab.setOrder(order).setKey(new ActionKey(order)).setAction(new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsActionBuilder.build()).build());
action = ab.build();
}
return action;
}
/**
* Create OF action to set the set_field with mpls label
* @param order An integer representing the order of the Action
* within the table.
* @param label MPLS label value
* @param bos Bottom of Stack value
* @return Action with an Order, Label and Bottom of Stack value
*/
public static Action createSetFieldMPLSLabelAction(int order, Long label, Short bos) {
Action action = null;
ActionBuilder ab = new ActionBuilder();
ProtocolMatchFieldsBuilder matchFieldsBuilder = new ProtocolMatchFieldsBuilder().setMplsLabel(label).setMplsBos(bos);
ab.setOrder(order).setKey(new ActionKey(order)).setAction(new SetFieldCaseBuilder().
setSetField(new SetFieldBuilder().setProtocolMatchFields(matchFieldsBuilder.build()).build()).build());
action = ab.build();
return action;
}
/**
* Create OF action to output to a specific port
* @param order An integer representing the order of the Action
* within the table.
* @param outputPort OVS port to output the packet to
* @return Action with Order and Output port
*/
public static Action createOutputToPort(int order, String outputPort) {
return new ActionBuilder().setOrder(order)
.setKey(new ActionKey(order))
.setAction(new OutputActionCaseBuilder()
.setOutputAction(new OutputActionBuilder()
.setMaxLength(0xffff)
.setOutputNodeConnector(new Uri(outputPort))
.build())
.build())
.build();
}
/**
* @param order An integer representing the order of the Action
* within the table.
* @param dscp A DSCP value
* @return Action with an order
*/
public static Action createQosNormal(int order, Dscp dscp) {
short dscpValue = dscp.getValue();
Integer tos = Integer.valueOf(dscpToTos(dscpValue));
SetNwTosAction nw = new SetNwTosActionBuilder().setTos(tos).build();
return new ActionBuilder().setOrder(order)
.setKey(new ActionKey(order))
.setAction(new SetNwTosActionCaseBuilder()
.setSetNwTosAction(nw)
.build())
.build();
}
/**
* Convert the given IP DSCP value into a TOS value.
*
* @param dscpValue A DSCP value.
* @return A TOS value.
*/
public static int dscpToTos(short dscpValue) {
return ((dscpValue & MASK_IP_DSCP) << NBITS_IP_ECN);
}
/**
*
* @param order An integer representing the order of the Action
* within the table.
* @param macAddress Destination MAC address
* @return Action with an order
*/
public static Action createSetFieldDestinationMacAddress(int order, String macAddress) {
Action action;
ActionBuilder ab = new ActionBuilder();
MacAddress address = MacAddress.getDefaultInstance(macAddress);
EthernetDestination destination = new EthernetDestinationBuilder().setAddress(address).build();
EthernetMatchBuilder builder = new EthernetMatchBuilder();
builder.setEthernetDestination(destination);
EthernetMatch ethernetMatch = builder.build();
SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
setFieldBuilder.setEthernetMatch(ethernetMatch);
SetField setField = setFieldBuilder.build();
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action acction = new SetFieldCaseBuilder().
setSetField(setField).build();
ab.setOrder(order).setKey(new ActionKey(order)).setAction(acction);
action = ab.build();
return action;
}
}