package net.floodlightcontroller.util; import org.projectfloodlight.openflow.protocol.OFFactories; import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.oxm.OFOxm; import org.projectfloodlight.openflow.protocol.ver15.OFOxmClassSerializerVer15; import org.projectfloodlight.openflow.types.ArpOpcode; import org.projectfloodlight.openflow.types.EthType; import org.projectfloodlight.openflow.types.ICMPv4Code; import org.projectfloodlight.openflow.types.ICMPv4Type; import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv6Address; import org.projectfloodlight.openflow.types.IPv6FlowLabel; import org.projectfloodlight.openflow.types.IpDscp; import org.projectfloodlight.openflow.types.IpEcn; import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.MacAddress; import org.projectfloodlight.openflow.types.OFBooleanValue; import org.projectfloodlight.openflow.types.OFMetadata; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.OFVlanVidMatch; import org.projectfloodlight.openflow.types.PacketType; import org.projectfloodlight.openflow.types.TransportPort; import org.projectfloodlight.openflow.types.U16; import org.projectfloodlight.openflow.types.U32; import org.projectfloodlight.openflow.types.U64; import org.projectfloodlight.openflow.types.U8; import org.projectfloodlight.openflow.types.VlanPcp; import org.projectfloodlight.openflow.types.VlanVid; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; /** * A handy class to convert OXMs (and NXMs) to and from * their IDs (U32=[class]+[field]+[has_mask]+[length]) * and their string representations. The strings are * defined in {@link net.floodlightcontroller.util.MatchUtils}, * with the exception of some unique NXMs and OpenFlow 1.5 OXMs * not technically supported by Loxi/Floodlight yet. Any NXM * string is prefixed with an "nxm_" followed by the string * used for the corresponding OXM. For example, an ingress port * OXM is "in_port", while the NXM version is "nxm_in_port". * * Any unique NXM without an OXM counterpart is assigned a string * to inform of the NXM. For example, NXM 33, "nxm_pkt_mark", marks * or matches on marked packets as Linux IP tables can do. This is * not supported in the OpenFlow spec, thus the NXM is assigned the * string "nxm_pkt_mark" within this class and does not have a string * predefined in {@link net.floodlightcontroller.util.MatchUtils}. * * Any OXM with the HAS_MASKED bit set will have it's string * representation appended with an "_masked" or the string defined in * the STR_MASKED class variable below. * * As an implementation note, a Google BiMap is used as the storage * mechanism. This allows fast lookup in both directions from U32 to * String or from String back to U32. Note that unique keys AND values * are required in a BiMap. * * @author Ryan Izard, rizard@g.clemson.edu, ryan.izard@bigswitch.com * */ public class OXMUtils { /* * OXM IDs for OpenFlow versions 1.5 and below are the same, * where each version simply adds to the already populated * list of OXM IDs. (IDs don't change b/t OF versions.) * As such, we'll assume OF1.5 here, which includes 1.3. */ /* String constants */ private static final String STR_MASKED = "_masked"; private static final String STR_NXM = "nxm_"; private static final String STR_PKT_REG = "pkt_reg_"; /* Bit shifting constants */ private static final int SHIFT_FIELD = 9; private static final int SHIFT_CLASS = 16; private static final int SHIFT_HAS_MASK = 8; /* Mask present bit */ private static final int MASKED = (1 << SHIFT_HAS_MASK); /* Classes */ private static final int OF_BASIC = (OFOxmClassSerializerVer15.OPENFLOW_BASIC_VAL << SHIFT_CLASS) & 0xFFffFFff; private static final int OF_PKT_REG = (OFOxmClassSerializerVer15.PACKET_REGS_VAL << SHIFT_CLASS) & 0xFFffFFff; private static final int NXM_0 = (OFOxmClassSerializerVer15.NXM_0_VAL << SHIFT_CLASS) & 0xFFffFFff; private static final int NXM_1 = (OFOxmClassSerializerVer15.NXM_1_VAL << SHIFT_CLASS) & 0xFFffFFff; /* The bi-directional map we'll use to make this process more efficient */ private static final BiMap<U32, String> map = HashBiMap.create(); static { /* * OXM header is 4 bytes as follows, where C=oxm_class, * F=oxm_field, M=has_mask, and L=data_length. * * CCCC CCCC CCCC CCCC FFFF FFFM LLLL LLLL * * The OXM class has already been shifted to the proper * position and is represented as an integer (4 bytes), * but we need to shift the OXM field over. The length * does not need to be shifted. * */ /* * OpenFlow Basic OXM Definitions */ map.put(U32.ofRaw(OF_BASIC | (0 << SHIFT_FIELD) | OFPort.ZERO.getLength()), MatchUtils.STR_IN_PORT); map.put(U32.ofRaw(OF_BASIC | (0 << SHIFT_FIELD) | OFPort.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_IN_PORT + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (1 << SHIFT_FIELD) | OFPort.ZERO.getLength()), MatchUtils.STR_IN_PHYS_PORT); map.put(U32.ofRaw(OF_BASIC | (1 << SHIFT_FIELD) | OFPort.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_IN_PHYS_PORT + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (2 << SHIFT_FIELD) | OFMetadata.NONE.getLength()), MatchUtils.STR_METADATA); map.put(U32.ofRaw(OF_BASIC | (2 << SHIFT_FIELD) | OFMetadata.NONE.getLength() * 2 | MASKED), MatchUtils.STR_METADATA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (3 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_DL_DST); map.put(U32.ofRaw(OF_BASIC | (3 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_DL_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (4 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_DL_SRC); map.put(U32.ofRaw(OF_BASIC | (4 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_DL_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (5 << SHIFT_FIELD) | EthType.NONE.getLength()), MatchUtils.STR_DL_TYPE); map.put(U32.ofRaw(OF_BASIC | (5 << SHIFT_FIELD) | EthType.NONE.getLength() * 2 | MASKED), MatchUtils.STR_DL_TYPE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (6 << SHIFT_FIELD) | VlanVid.ZERO.getLength()), MatchUtils.STR_DL_VLAN); map.put(U32.ofRaw(OF_BASIC | (6 << SHIFT_FIELD) | VlanVid.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_DL_VLAN + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (7 << SHIFT_FIELD) | VlanPcp.NONE.getLength()), MatchUtils.STR_DL_VLAN_PCP); map.put(U32.ofRaw(OF_BASIC | (7 << SHIFT_FIELD) | VlanPcp.NONE.getLength() * 2 | MASKED), MatchUtils.STR_DL_VLAN_PCP + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (8 << SHIFT_FIELD) | IpDscp.NONE.getLength()), MatchUtils.STR_NW_DSCP); map.put(U32.ofRaw(OF_BASIC | (8 << SHIFT_FIELD) | IpDscp.NONE.getLength() * 2 | MASKED), MatchUtils.STR_NW_DSCP + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (9 << SHIFT_FIELD) | IpEcn.NONE.getLength()), MatchUtils.STR_NW_ECN); map.put(U32.ofRaw(OF_BASIC | (9 << SHIFT_FIELD) | IpEcn.NONE.getLength() * 2 | MASKED), MatchUtils.STR_NW_ECN + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (10 << SHIFT_FIELD) | IpProtocol.NONE.getLength()), MatchUtils.STR_NW_PROTO); map.put(U32.ofRaw(OF_BASIC | (10 << SHIFT_FIELD) | IpProtocol.NONE.getLength() * 2 | MASKED), MatchUtils.STR_NW_PROTO + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (11 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_NW_SRC); map.put(U32.ofRaw(OF_BASIC | (11 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_NW_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (12 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_NW_DST); map.put(U32.ofRaw(OF_BASIC | (12 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_NW_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (13 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_TCP_SRC); map.put(U32.ofRaw(OF_BASIC | (13 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_TCP_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (14 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_TCP_DST); map.put(U32.ofRaw(OF_BASIC | (14 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_TCP_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (15 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_UDP_SRC); map.put(U32.ofRaw(OF_BASIC | (15 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_UDP_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (16 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_UDP_DST); map.put(U32.ofRaw(OF_BASIC | (16 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_UDP_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (17 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_SCTP_SRC); map.put(U32.ofRaw(OF_BASIC | (17 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_SCTP_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (18 << SHIFT_FIELD) | TransportPort.NONE.getLength()), MatchUtils.STR_SCTP_DST); map.put(U32.ofRaw(OF_BASIC | (18 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), MatchUtils.STR_SCTP_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (19 << SHIFT_FIELD) | ICMPv4Type.NONE.getLength()), MatchUtils.STR_ICMP_TYPE); map.put(U32.ofRaw(OF_BASIC | (19 << SHIFT_FIELD) | ICMPv4Type.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ICMP_TYPE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (20 << SHIFT_FIELD) | ICMPv4Code.NONE.getLength()), MatchUtils.STR_ICMP_CODE); map.put(U32.ofRaw(OF_BASIC | (20 << SHIFT_FIELD) | ICMPv4Code.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ICMP_CODE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (21 << SHIFT_FIELD) | ArpOpcode.NONE.getLength()), MatchUtils.STR_ARP_OPCODE); map.put(U32.ofRaw(OF_BASIC | (21 << SHIFT_FIELD) | ArpOpcode.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ARP_OPCODE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (22 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_ARP_SPA); map.put(U32.ofRaw(OF_BASIC | (22 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ARP_SPA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (23 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_ARP_DPA); map.put(U32.ofRaw(OF_BASIC | (23 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ARP_DPA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (24 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_ARP_SHA); map.put(U32.ofRaw(OF_BASIC | (24 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ARP_SHA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (25 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_ARP_DHA); map.put(U32.ofRaw(OF_BASIC | (25 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_ARP_DHA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (26 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), MatchUtils.STR_IPV6_SRC); map.put(U32.ofRaw(OF_BASIC | (26 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_SRC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (27 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), MatchUtils.STR_IPV6_DST); map.put(U32.ofRaw(OF_BASIC | (27 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_DST + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (28 << SHIFT_FIELD) | IPv6FlowLabel.NONE.getLength()), MatchUtils.STR_IPV6_FLOW_LABEL); map.put(U32.ofRaw(OF_BASIC | (28 << SHIFT_FIELD) | IPv6FlowLabel.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_FLOW_LABEL + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (29 << SHIFT_FIELD) | U8.ZERO.getLength()), MatchUtils.STR_ICMPV6_TYPE); map.put(U32.ofRaw(OF_BASIC | (29 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_ICMPV6_TYPE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (30 << SHIFT_FIELD) | U8.ZERO.getLength()), MatchUtils.STR_ICMPV6_CODE); map.put(U32.ofRaw(OF_BASIC | (30 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_ICMPV6_CODE + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (31 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), MatchUtils.STR_IPV6_ND_TARGET); map.put(U32.ofRaw(OF_BASIC | (31 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_ND_TARGET + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (32 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_IPV6_ND_SLL); map.put(U32.ofRaw(OF_BASIC | (32 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_ND_SLL + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (33 << SHIFT_FIELD) | MacAddress.NONE.getLength()), MatchUtils.STR_IPV6_ND_TLL); map.put(U32.ofRaw(OF_BASIC | (33 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), MatchUtils.STR_IPV6_ND_TLL + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (34 << SHIFT_FIELD) | U32.ZERO.getLength()), MatchUtils.STR_MPLS_LABEL); map.put(U32.ofRaw(OF_BASIC | (34 << SHIFT_FIELD) | U32.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_MPLS_LABEL + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (35 << SHIFT_FIELD) | U8.ZERO.getLength()), MatchUtils.STR_MPLS_TC); map.put(U32.ofRaw(OF_BASIC | (35 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_MPLS_TC + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (36 << SHIFT_FIELD) | OFBooleanValue.TRUE.getLength()), MatchUtils.STR_MPLS_BOS); map.put(U32.ofRaw(OF_BASIC | (36 << SHIFT_FIELD) | OFBooleanValue.TRUE.getLength() * 2 | MASKED), MatchUtils.STR_MPLS_BOS + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (37 << SHIFT_FIELD) | 3 ), MatchUtils.STR_PBB_ISID); map.put(U32.ofRaw(OF_BASIC | (37 << SHIFT_FIELD) | 3 * 2 | MASKED ), MatchUtils.STR_PBB_ISID + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (38 << SHIFT_FIELD) | U64.ZERO.getLength()), MatchUtils.STR_TUNNEL_ID); map.put(U32.ofRaw(OF_BASIC | (38 << SHIFT_FIELD) | U64.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_TUNNEL_ID + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (39 << SHIFT_FIELD) | 2), MatchUtils.STR_IPV6_EXTHDR); map.put(U32.ofRaw(OF_BASIC | (39 << SHIFT_FIELD) | 2 * 2 | MASKED), MatchUtils.STR_IPV6_EXTHDR + STR_MASKED); /* note skip of ID 40 here according to spec */ map.put(U32.ofRaw(OF_BASIC | (41 << SHIFT_FIELD) | 1), MatchUtils.STR_PBB_UCA); map.put(U32.ofRaw(OF_BASIC | (41 << SHIFT_FIELD) | 1 * 2 | MASKED), MatchUtils.STR_PBB_UCA + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (42 << SHIFT_FIELD) | U32.ZERO.getLength()), MatchUtils.STR_TCP_FLAGS); map.put(U32.ofRaw(OF_BASIC | (42 << SHIFT_FIELD) | U32.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_TCP_FLAGS + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (43 << SHIFT_FIELD) | 1), MatchUtils.STR_ACTSET_OUTPUT); map.put(U32.ofRaw(OF_BASIC | (43 << SHIFT_FIELD) | 1 * 2 | MASKED), MatchUtils.STR_ACTSET_OUTPUT + STR_MASKED); map.put(U32.ofRaw(OF_BASIC | (44 << SHIFT_FIELD) | U32.ZERO.getLength()), MatchUtils.STR_PACKET_TYPE); map.put(U32.ofRaw(OF_BASIC | (44 << SHIFT_FIELD) | U32.ZERO.getLength() * 2 | MASKED), MatchUtils.STR_PACKET_TYPE + STR_MASKED); /* * NXM_0 Definitions */ map.put(U32.ofRaw(NXM_0 | (0 << SHIFT_FIELD) | 2 /* old ports are len=2 */), STR_NXM + MatchUtils.STR_IN_PORT); map.put(U32.ofRaw(NXM_0 | (0 << SHIFT_FIELD) | 2 * 2 /* old ports are len=2 */ | MASKED), STR_NXM + MatchUtils.STR_IN_PORT + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (1 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_DL_DST); map.put(U32.ofRaw(NXM_0 | (1 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_DL_DST + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (2 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_DL_SRC); map.put(U32.ofRaw(NXM_0 | (2 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_DL_SRC + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (3 << SHIFT_FIELD) | EthType.NONE.getLength()), STR_NXM + MatchUtils.STR_DL_TYPE); map.put(U32.ofRaw(NXM_0 | (3 << SHIFT_FIELD) | EthType.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_DL_TYPE + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (4 << SHIFT_FIELD) | VlanVid.ZERO.getLength()), STR_NXM + MatchUtils.STR_DL_VLAN); map.put(U32.ofRaw(NXM_0 | (4 << SHIFT_FIELD) | VlanVid.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_DL_VLAN + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (5 << SHIFT_FIELD) | 1), STR_NXM + MatchUtils.STR_NW_TOS); map.put(U32.ofRaw(NXM_0 | (5 << SHIFT_FIELD) | 1 * 2 | MASKED), STR_NXM + MatchUtils.STR_NW_TOS + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (6 << SHIFT_FIELD) | IpProtocol.NONE.getLength()), STR_NXM + MatchUtils.STR_NW_PROTO); map.put(U32.ofRaw(NXM_0 | (6 << SHIFT_FIELD) | IpProtocol.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_NW_PROTO + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (7 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), STR_NXM + MatchUtils.STR_NW_SRC); map.put(U32.ofRaw(NXM_0 | (7 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_NW_SRC + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (8 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), STR_NXM + MatchUtils.STR_NW_DST); map.put(U32.ofRaw(NXM_0 | (8 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_NW_DST + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (9 << SHIFT_FIELD) | TransportPort.NONE.getLength()), STR_NXM + MatchUtils.STR_TCP_SRC); map.put(U32.ofRaw(NXM_0 | (9 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_TCP_SRC + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (10 << SHIFT_FIELD) | TransportPort.NONE.getLength()), STR_NXM + MatchUtils.STR_TCP_DST); map.put(U32.ofRaw(NXM_0 | (10 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_TCP_DST + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (11 << SHIFT_FIELD) | TransportPort.NONE.getLength()), STR_NXM + MatchUtils.STR_UDP_SRC); map.put(U32.ofRaw(NXM_0 | (11 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_UDP_SRC + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (12 << SHIFT_FIELD) | TransportPort.NONE.getLength()), STR_NXM + MatchUtils.STR_UDP_DST); map.put(U32.ofRaw(NXM_0 | (12 << SHIFT_FIELD) | TransportPort.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_UDP_DST + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (13 << SHIFT_FIELD) | U8.ZERO.getLength()), STR_NXM + MatchUtils.STR_ICMP_TYPE); map.put(U32.ofRaw(NXM_0 | (13 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ICMP_TYPE + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (14 << SHIFT_FIELD) | U8.ZERO.getLength()), STR_NXM + MatchUtils.STR_ICMP_CODE); map.put(U32.ofRaw(NXM_0 | (14 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ICMP_CODE + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (15 << SHIFT_FIELD) | ArpOpcode.NONE.getLength()), STR_NXM + MatchUtils.STR_ARP_OPCODE); map.put(U32.ofRaw(NXM_0 | (15 << SHIFT_FIELD) | ArpOpcode.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ARP_OPCODE + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (16 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), STR_NXM + MatchUtils.STR_ARP_SPA); map.put(U32.ofRaw(NXM_0 | (16 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ARP_SPA + STR_MASKED); map.put(U32.ofRaw(NXM_0 | (17 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), STR_NXM + MatchUtils.STR_ARP_DPA); map.put(U32.ofRaw(NXM_0 | (17 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ARP_DPA + STR_MASKED); /* * NXM_1 Definitions */ map.put(U32.ofRaw(NXM_1 | (0 << SHIFT_FIELD) | 4), STR_NXM + "reg_0"); map.put(U32.ofRaw(NXM_1 | (0 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_0" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (1 << SHIFT_FIELD) | 4), STR_NXM + "reg_1"); map.put(U32.ofRaw(NXM_1 | (1 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_1" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (2 << SHIFT_FIELD) | 4), STR_NXM + "reg_2"); map.put(U32.ofRaw(NXM_1 | (2 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_2" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (3 << SHIFT_FIELD) | 4), STR_NXM + "reg_3"); map.put(U32.ofRaw(NXM_1 | (3 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_3" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (4 << SHIFT_FIELD) | 4), STR_NXM + "reg_4"); map.put(U32.ofRaw(NXM_1 | (4 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_4" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (5 << SHIFT_FIELD) | 4), STR_NXM + "reg_5"); map.put(U32.ofRaw(NXM_1 | (5 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_5" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (6 << SHIFT_FIELD) | 4), STR_NXM + "reg_6"); map.put(U32.ofRaw(NXM_1 | (6 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_6" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (7 << SHIFT_FIELD) | 4), STR_NXM + "reg_7"); map.put(U32.ofRaw(NXM_1 | (7 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "reg_7" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (16 << SHIFT_FIELD) | U64.ZERO.getLength()), STR_NXM + MatchUtils.STR_TUNNEL_ID); map.put(U32.ofRaw(NXM_1 | (16 << SHIFT_FIELD) | U64.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_TUNNEL_ID + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (17 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_ARP_SHA); map.put(U32.ofRaw(NXM_1 | (17 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ARP_SHA + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (18 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_ARP_DHA); map.put(U32.ofRaw(NXM_1 | (18 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ARP_DHA + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (19 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_SRC); map.put(U32.ofRaw(NXM_1 | (19 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_SRC + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (20 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_DST); map.put(U32.ofRaw(NXM_1 | (20 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_DST + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (21 << SHIFT_FIELD) | U8.ZERO.getLength()), STR_NXM + MatchUtils.STR_ICMPV6_TYPE); map.put(U32.ofRaw(NXM_1 | (21 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ICMPV6_TYPE + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (22 << SHIFT_FIELD) | U8.ZERO.getLength()), STR_NXM + MatchUtils.STR_ICMPV6_CODE); map.put(U32.ofRaw(NXM_1 | (22 << SHIFT_FIELD) | U8.ZERO.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_ICMPV6_CODE + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (23 << SHIFT_FIELD) | IPv6Address.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_ND_TARGET); map.put(U32.ofRaw(NXM_1 | (23 << SHIFT_FIELD) | IPv6Address.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_ND_TARGET + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (24 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_ND_SLL); map.put(U32.ofRaw(NXM_1 | (24 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_ND_SLL + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (25 << SHIFT_FIELD) | MacAddress.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_ND_TLL); map.put(U32.ofRaw(NXM_1 | (25 << SHIFT_FIELD) | MacAddress.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_ND_TLL + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (26 << SHIFT_FIELD) | 1), STR_NXM + "ip_frag"); map.put(U32.ofRaw(NXM_1 | (26 << SHIFT_FIELD) | 1 * 2 | MASKED), STR_NXM + "ip_frag" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (27 << SHIFT_FIELD) | IPv6FlowLabel.NONE.getLength()), STR_NXM + MatchUtils.STR_IPV6_FLOW_LABEL); map.put(U32.ofRaw(NXM_1 | (27 << SHIFT_FIELD) | IPv6FlowLabel.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_IPV6_FLOW_LABEL + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (28 << SHIFT_FIELD) | IpEcn.NONE.getLength()), STR_NXM + MatchUtils.STR_NW_ECN); map.put(U32.ofRaw(NXM_1 | (28 << SHIFT_FIELD) | IpEcn.NONE.getLength() * 2 | MASKED), STR_NXM + MatchUtils.STR_NW_ECN + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (29 << SHIFT_FIELD) | 1), STR_NXM + "ip_ttl"); map.put(U32.ofRaw(NXM_1 | (29 << SHIFT_FIELD) | 1 * 2 | MASKED), STR_NXM + "ip_ttl" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (30 << SHIFT_FIELD) | 8), STR_NXM + "flow_cookie"); map.put(U32.ofRaw(NXM_1 | (30 << SHIFT_FIELD) | 8 * 2 | MASKED), STR_NXM + "flow_cookie" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (31 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_TUNNEL_IPV4_SRC); map.put(U32.ofRaw(NXM_1 | (31 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_TUNNEL_IPV4_SRC + MASKED); map.put(U32.ofRaw(NXM_1 | (32 << SHIFT_FIELD) | IPv4Address.NONE.getLength()), MatchUtils.STR_TUNNEL_IPV4_DST); map.put(U32.ofRaw(NXM_1 | (32 << SHIFT_FIELD) | IPv4Address.NONE.getLength() * 2 | MASKED), MatchUtils.STR_TUNNEL_IPV4_DST + MASKED); map.put(U32.ofRaw(NXM_1 | (33 << SHIFT_FIELD) | 4), STR_NXM + "pkt_mark"); map.put(U32.ofRaw(NXM_1 | (33 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "pkt_mark" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (34 << SHIFT_FIELD) | 2), STR_NXM + "tcp_flags"); map.put(U32.ofRaw(NXM_1 | (34 << SHIFT_FIELD) | 2 * 2 | MASKED), STR_NXM + "tcp_flags" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (35 << SHIFT_FIELD) | 4), STR_NXM + "internal_dp_hash"); map.put(U32.ofRaw(NXM_1 | (35 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "internal_dp_hash" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (36 << SHIFT_FIELD) | 4), STR_NXM + "internal_recirc_id"); map.put(U32.ofRaw(NXM_1 | (36 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + "internal_recirc_id" + STR_MASKED); map.put(U32.ofRaw(NXM_1 | (37 << SHIFT_FIELD) | 4), STR_NXM + MatchUtils.STR_PBB_ISID); map.put(U32.ofRaw(NXM_1 | (37 << SHIFT_FIELD) | 4 * 2 | MASKED), STR_NXM + MatchUtils.STR_PBB_ISID + STR_MASKED); /* "Register" max number of packet registers */ for (int i = 0; i < 128; i++) { map.put(U32.ofRaw(OF_PKT_REG | (i << SHIFT_FIELD) | 8), STR_PKT_REG + Integer.toString(i)); map.put(U32.ofRaw(OF_PKT_REG | (i << SHIFT_FIELD) | 8 * 2 | MASKED), STR_PKT_REG + Integer.toString(i) + STR_MASKED); } } /** * Converts the U32 of an OXM ID to its string representation as * defined in {@link net.floodlightcontroller.util.MatchUtils.java}. * * Any NXM (not defined in {@link net.floodlightcontroller.util.MatchUtils.java} * is the same as the OXM string with an "nxm_" prefix. * * Any packet register is preceded by a "pkt_reg_" prefix. * * Any OXM or NXM that is masked include a "_masked" postfix. * * @param oxmId, the U32 defining the OXM/NXM as [class]+[field]+[has_mask]+[length] * @return the String representing the OXM/NXM */ public static String oxmIdToString(U32 oxmId) { if (map.containsKey(oxmId)) { return map.get(oxmId); } else { return "Unknown OXM ID: " + oxmId.toString(); } } /** * Converts the string representation of an OXM ID as * defined in {@link net.floodlightcontroller.util.MatchUtils.java} * to its corresponding U32 OXM ID. * * Any NXM (not defined in {@link net.floodlightcontroller.util.MatchUtils.java} * is the same as the OXM string with an "nxm_" prefix. * * Any packet register is preceded by a "pkt_reg_" prefix. * * Any OXM or NXM that is masked include a "_masked" postfix. * * @param oxmString, the string defining the OXM/NXM * @return the U32 representing the OXM/NXM as [class]+[field]+[has_mask]+[length] */ public static U32 oxmStringToId(String oxmString) { if (map.inverse().containsKey(oxmString)) { return map.inverse().get(oxmString); } else { return null; } } /** * Get an unset/default OXM object. * * @param oxmString * @param v * @return */ public static OFOxm<?> oxmStringToOxm(String oxmString, OFVersion v) { OFFactory f = OFFactories.getFactory(v); switch (oxmString) { case MatchUtils.STR_ACTSET_OUTPUT: return f.oxms().actsetOutput(OFPort.ZERO); case MatchUtils.STR_ARP_DHA: return f.oxms().arpTha(MacAddress.NONE); case MatchUtils.STR_ARP_DPA: return f.oxms().arpTpa(IPv4Address.NONE); case MatchUtils.STR_ARP_OPCODE: return f.oxms().arpOp(ArpOpcode.NONE); case MatchUtils.STR_ARP_SHA: return f.oxms().arpSha(MacAddress.NONE); case MatchUtils.STR_ARP_SPA: return f.oxms().arpSpa(IPv4Address.NONE); case MatchUtils.STR_DL_DST: return f.oxms().ethDst(MacAddress.NONE); case MatchUtils.STR_DL_SRC: return f.oxms().ethSrc(MacAddress.NONE); case MatchUtils.STR_DL_TYPE: return f.oxms().ethType(EthType.NONE); case MatchUtils.STR_DL_VLAN: return f.oxms().vlanVid(OFVlanVidMatch.NONE); case MatchUtils.STR_DL_VLAN_PCP: return f.oxms().vlanPcp(VlanPcp.NONE); case MatchUtils.STR_ICMP_CODE: return f.oxms().icmpv4Code(ICMPv4Code.NONE); case MatchUtils.STR_ICMP_TYPE: return f.oxms().icmpv4Type(ICMPv4Type.NONE); case MatchUtils.STR_ICMPV6_CODE: return f.oxms().icmpv6Code(U8.ZERO); case MatchUtils.STR_ICMPV6_TYPE: return f.oxms().icmpv6Type(U8.ZERO); case MatchUtils.STR_IN_PHYS_PORT: return f.oxms().inPhyPort(OFPort.ZERO); case MatchUtils.STR_IN_PORT: return f.oxms().inPort(OFPort.ZERO); case MatchUtils.STR_IPV6_DST: return f.oxms().ipv6Dst(IPv6Address.NONE); case MatchUtils.STR_IPV6_EXTHDR: return f.oxms().ipv6Exthdr(U16.ZERO); case MatchUtils.STR_IPV6_FLOW_LABEL: return f.oxms().ipv6Flabel(IPv6FlowLabel.NONE); case MatchUtils.STR_IPV6_ND_SLL: return f.oxms().ipv6NdSll(MacAddress.NONE); case MatchUtils.STR_IPV6_ND_TARGET: return f.oxms().ipv6NdTarget(IPv6Address.NONE); case MatchUtils.STR_IPV6_ND_TLL: return f.oxms().ipv6NdTll(MacAddress.NONE); case MatchUtils.STR_IPV6_SRC: return f.oxms().ipv6Src(IPv6Address.NONE); case MatchUtils.STR_METADATA: return f.oxms().metadata(OFMetadata.NONE); case MatchUtils.STR_MPLS_BOS: return f.oxms().mplsBos(OFBooleanValue.FALSE); case MatchUtils.STR_MPLS_LABEL: return f.oxms().mplsLabel(U32.ZERO); case MatchUtils.STR_MPLS_TC: return f.oxms().mplsTc(U8.ZERO); case MatchUtils.STR_NW_DSCP: return f.oxms().ipDscp(IpDscp.NONE); case MatchUtils.STR_NW_DST: return f.oxms().ipv4Dst(IPv4Address.NONE); case MatchUtils.STR_NW_ECN: return f.oxms().ipEcn(IpEcn.NONE); case MatchUtils.STR_NW_PROTO: return f.oxms().ipProto(IpProtocol.NONE); case MatchUtils.STR_NW_SRC: return f.oxms().ipv4Src(IPv4Address.NONE); case MatchUtils.STR_NW_TOS: return null; /* should use ECN or DSCP */ case MatchUtils.STR_PACKET_TYPE: return f.oxms().packetType(PacketType.NO_PACKET); case MatchUtils.STR_PBB_ISID: return null; /* TODO not implemented */ case MatchUtils.STR_PBB_UCA: return f.oxms().pbbUca(OFBooleanValue.FALSE); case MatchUtils.STR_SCTP_DST: return f.oxms().sctpDst(TransportPort.NONE); case MatchUtils.STR_SCTP_SRC: return f.oxms().sctpSrc(TransportPort.NONE); case MatchUtils.STR_TCP_DST: return f.oxms().tcpDst(TransportPort.NONE); case MatchUtils.STR_TCP_FLAGS: return f.oxms().tcpFlags(U16.ZERO); case MatchUtils.STR_TCP_SRC: return f.oxms().tcpSrc(TransportPort.NONE); case MatchUtils.STR_TP_DST: case MatchUtils.STR_TP_SRC: return null; /* should use specific transport protocol */ case MatchUtils.STR_TUNNEL_ID: return f.oxms().tunnelId(U64.ZERO); case MatchUtils.STR_TUNNEL_IPV4_DST: return f.oxms().tunnelIpv4Dst(IPv4Address.NONE); case MatchUtils.STR_TUNNEL_IPV4_SRC: return f.oxms().tunnelIpv4Src(IPv4Address.NONE); case MatchUtils.STR_UDP_DST: return f.oxms().udpDst(TransportPort.NONE); case MatchUtils.STR_UDP_SRC: return f.oxms().udpSrc(TransportPort.NONE); default: return null; /* unimplemented */ } } }