blob: 2ee625fbb570aae15e4ce3665dd1c992aa275963 [file] [log] [blame]
Jian Li6bd35102018-06-09 00:18:47 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
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 */
16package org.onosproject.openstacktelemetry.codec;
17
18import org.onlab.packet.IpAddress;
19import org.onlab.packet.IpAddress.Version;
20import org.onlab.packet.IpPrefix;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.TpPort;
23import org.onlab.packet.VlanId;
24import org.onosproject.net.DeviceId;
25import org.onosproject.openstacktelemetry.api.ByteBufferCodec;
26import org.onosproject.openstacktelemetry.api.FlowInfo;
27import org.onosproject.openstacktelemetry.api.StatsInfo;
28import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
29
30import java.nio.ByteBuffer;
31
32/**
33 * FlowInfo ByteBuffer Codec.
34 */
35public class TinaFlowInfoByteBufferCodec extends ByteBufferCodec<FlowInfo> {
36
boyoung2a8549d22018-11-23 20:42:37 +090037 private static final int NUM_RADIX = 16;
Jian Li6bd35102018-06-09 00:18:47 +090038 private static final int MESSAGE_SIZE = 88;
Jian Li0bbbb1c2018-06-22 22:01:17 +090039 private static final String OF_PREFIX = "of:";
Jian Li6bd35102018-06-09 00:18:47 +090040
41 @Override
42 public ByteBuffer encode(FlowInfo flowInfo) {
43
44 ByteBuffer byteBuffer = ByteBuffer.allocate(MESSAGE_SIZE);
Jian Li85573f42018-06-27 22:29:14 +090045 int srcPort = 0;
46 int dstPort = 0;
Jian Li6bd35102018-06-09 00:18:47 +090047
Jian Li0bbbb1c2018-06-22 22:01:17 +090048 String deviceId = flowInfo.deviceId().toString();
49 short switchId = (short) Integer.parseInt(deviceId.substring(3,
boyoung2a8549d22018-11-23 20:42:37 +090050 deviceId.length()), NUM_RADIX);
Jian Li0bbbb1c2018-06-22 22:01:17 +090051
Jian Li85573f42018-06-27 22:29:14 +090052 if (flowInfo.srcPort() != null) {
53 srcPort = flowInfo.srcPort().toInt();
54 }
55
56 if (flowInfo.dstPort() != null) {
57 dstPort = flowInfo.dstPort().toInt();
58 }
59
Jian Li6bd35102018-06-09 00:18:47 +090060 byteBuffer.put(flowInfo.flowType())
Jian Li0bbbb1c2018-06-22 22:01:17 +090061 .putShort(switchId)
Jian Li6bd35102018-06-09 00:18:47 +090062 .putInt(flowInfo.inputInterfaceId())
63 .putInt(flowInfo.outputInterfaceId())
64 .putShort(flowInfo.vlanId().toShort())
65 .put(flowInfo.srcIp().address().toOctets())
66 .put((byte) flowInfo.srcIp().prefixLength())
Jian Li85573f42018-06-27 22:29:14 +090067 .putShort((short) srcPort)
Jian Li6bd35102018-06-09 00:18:47 +090068 .put(flowInfo.dstIp().address().toOctets())
69 .put((byte) flowInfo.dstIp().prefixLength())
Jian Li85573f42018-06-27 22:29:14 +090070 .putShort((short) dstPort)
Jian Li6bd35102018-06-09 00:18:47 +090071 .put(flowInfo.protocol())
72 .put(flowInfo.srcMac().toBytes())
73 .put(flowInfo.dstMac().toBytes());
74
75 TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
76 new TinaStatsInfoByteBufferCodec();
77 byteBuffer.put(statsInfoByteBufferCodec.encode(flowInfo.statsInfo()).array());
78
79 return byteBuffer;
80 }
81
82 @Override
83 public FlowInfo decode(ByteBuffer byteBuffer) {
84
85 byte flowType = byteBuffer.get();
Jian Li0bbbb1c2018-06-22 22:01:17 +090086 String deviceIdStr = String.format("%016x", byteBuffer.getShort());
87 DeviceId deviceId = DeviceId.deviceId(OF_PREFIX + deviceIdStr);
Jian Li6bd35102018-06-09 00:18:47 +090088 int inputInterfaceId = byteBuffer.getInt();
89 int outputInterfaceId = byteBuffer.getInt();
90 VlanId vlanId = VlanId.vlanId(byteBuffer.getShort());
91 IpAddress srcIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
92 int srcPrefixLen = byteBuffer.get();
93 TpPort srcPort = TpPort.tpPort((int) byteBuffer.getShort());
94 IpAddress dstIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
95 int dstPrefixLen = byteBuffer.get();
96 TpPort dstPort = TpPort.tpPort((int) byteBuffer.getShort());
97
98 byte protocol = byteBuffer.get();
99 MacAddress srcMac = MacAddress.valueOf(getMacByteArray(byteBuffer));
100 MacAddress dstMac = MacAddress.valueOf(getMacByteArray(byteBuffer));
101
102 TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
103 new TinaStatsInfoByteBufferCodec();
104 StatsInfo statsInfo = statsInfoByteBufferCodec.decode(byteBuffer);
105
106 return new DefaultFlowInfo.DefaultBuilder()
107 .withFlowType(flowType)
108 .withDeviceId(deviceId)
109 .withInputInterfaceId(inputInterfaceId)
110 .withOutputInterfaceId(outputInterfaceId)
111 .withVlanId(vlanId)
112 .withSrcIp(IpPrefix.valueOf(srcIp, srcPrefixLen))
113 .withSrcPort(srcPort)
114 .withDstIp(IpPrefix.valueOf(dstIp, dstPrefixLen))
115 .withDstPort(dstPort)
116 .withProtocol(protocol)
117 .withSrcMac(srcMac)
118 .withDstMac(dstMac)
119 .withStatsInfo(statsInfo)
120 .build();
121 }
122
123 /**
124 * Obtains IPv4 Octets from ByteBuffer.
125 *
126 * @param buffer byte buffer
127 * @return Ipv4 Octets
128 */
129 private byte[] getIpv4Octets(ByteBuffer buffer) {
130 byte[] octets = new byte[4];
131 for (int i = 0; i < octets.length; i++) {
132 octets[i] = buffer.get();
133 }
134 return octets;
135 }
136
137 /**
138 * Obtains MAC address byte array from ByteBuffer.
139 *
140 * @param buffer byte buffer
141 * @return MAC address byte array
142 */
143 private byte[] getMacByteArray(ByteBuffer buffer) {
144 byte[] array = new byte[6];
145 for (int i = 0; i < array.length; i++) {
146 array[i] = buffer.get();
147 }
148 return array;
149 }
150}