blob: 948075b8e36edc5c1622189bbd004966b8aa34a9 [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska58de4162015-09-10 16:15:33 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
sanghob35a6192015-04-01 13:05:26 -070016package org.onlab.packet;
17
18import java.nio.ByteBuffer;
sanghob35a6192015-04-01 13:05:26 -070019import java.util.Map;
20
Yuta HIGUCHIbfc2e922017-06-07 21:46:05 -070021import com.google.common.collect.ImmutableMap;
22
Jian Li5fc14292015-12-04 11:30:46 -080023import static com.google.common.base.MoreObjects.toStringHelper;
Jonathan Hart2a655752015-04-07 16:46:33 -070024import static org.onlab.packet.PacketUtils.checkInput;
25
Jian Li5fc14292015-12-04 11:30:46 -080026/**
27 * Representation of an MPLS Packet.
28 */
sanghob35a6192015-04-01 13:05:26 -070029public class MPLS extends BasePacket {
Jonathan Hart2a655752015-04-07 16:46:33 -070030 public static final int HEADER_LENGTH = 4;
31
sanghob35a6192015-04-01 13:05:26 -070032 public static final byte PROTOCOL_IPV4 = 0x1;
33 public static final byte PROTOCOL_MPLS = 0x6;
Yuta HIGUCHIbfc2e922017-06-07 21:46:05 -070034 // mutable for Testing
35 static Map<Byte, Deserializer<? extends IPacket>> protocolDeserializerMap =
36 ImmutableMap.<Byte, Deserializer<? extends IPacket>>builder()
37 .put(PROTOCOL_IPV4, IPv4.deserializer())
38 .put(PROTOCOL_MPLS, MPLS.deserializer())
39 .build();
sanghob35a6192015-04-01 13:05:26 -070040
41 protected int label; //20bits
42 protected byte bos; //1bit
43 protected byte ttl; //8bits
44 protected byte protocol;
45
46 /**
47 * Default constructor that sets the version to 4.
48 */
49 public MPLS() {
50 super();
51 this.bos = 1;
52 this.protocol = PROTOCOL_IPV4;
53 }
54
55 @Override
56 public byte[] serialize() {
57 byte[] payloadData = null;
58 if (payload != null) {
59 payload.setParent(this);
60 payloadData = payload.serialize();
61 }
62
63 byte[] data = new byte[(4 + ((payloadData != null) ? payloadData.length : 0)) ];
64 ByteBuffer bb = ByteBuffer.wrap(data);
65
66 bb.putInt(((this.label & 0x000fffff) << 12) | ((this.bos & 0x1) << 8 | (this.ttl & 0xff)));
67 if (payloadData != null) {
68 bb.put(payloadData);
69 }
70
71 return data;
72 }
73
sanghob35a6192015-04-01 13:05:26 -070074
75 /**
76 * Returns the MPLS label.
77 *
78 * @return MPLS label
79 */
80 public int getLabel() {
81 return label;
82 }
83
84 /**
85 * Sets the MPLS label.
86 *
Thomas Vachuskae10f56b2015-04-15 18:20:08 -070087 * @param label MPLS label
sanghob35a6192015-04-01 13:05:26 -070088 */
89 public void setLabel(int label) {
90 this.label = label;
91 }
92
93 /**
94 * Returns the MPLS TTL of the packet.
95 *
96 * @return MPLS TTL of the packet
97 */
98 public byte getTtl() {
99 return ttl;
100 }
101
102 /**
103 * Sets the MPLS TTL of the packet.
104 *
105 * @param ttl MPLS TTL
106 */
107 public void setTtl(byte ttl) {
108 this.ttl = ttl;
109 }
110
Jonathan Hart2a655752015-04-07 16:46:33 -0700111 /**
112 * Deserializer function for MPLS packets.
113 *
114 * @return deserializer function
115 */
116 public static Deserializer<MPLS> deserializer() {
117 return (data, offset, length) -> {
118 checkInput(data, offset, length, HEADER_LENGTH);
119
120 MPLS mpls = new MPLS();
121 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
122
123 int mplsheader = bb.getInt();
124 mpls.label = ((mplsheader & 0xfffff000) >>> 12);
125 mpls.bos = (byte) ((mplsheader & 0x00000100) >> 8);
126 mpls.ttl = (byte) (mplsheader & 0x000000ff);
127 mpls.protocol = (mpls.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
128
129 Deserializer<? extends IPacket> deserializer;
130 if (protocolDeserializerMap.containsKey(mpls.protocol)) {
131 deserializer = protocolDeserializerMap.get(mpls.protocol);
132 } else {
133 deserializer = Data.deserializer();
134 }
135 mpls.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
136 mpls.payload.setParent(mpls);
137
138 return mpls;
139 };
140 }
Jian Li5fc14292015-12-04 11:30:46 -0800141
142 @Override
143 public String toString() {
144 return toStringHelper(getClass())
145 .add("label", Integer.toString(label))
146 .add("bos", Byte.toString(bos))
147 .add("ttl", Byte.toString(ttl))
148 .add("protocol", Byte.toString(protocol))
149 .toString();
150 }
sanghob35a6192015-04-01 13:05:26 -0700151}