blob: 7a69a5b9cc3372365a35836c95ed1b9a78a3ace4 [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05303 *
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.isis.controller.impl;
17
18import org.jboss.netty.buffer.ChannelBuffer;
19import org.jboss.netty.channel.Channel;
20import org.jboss.netty.channel.ChannelHandlerContext;
21import org.jboss.netty.handler.codec.frame.FrameDecoder;
22import org.onlab.packet.MacAddress;
23import org.onosproject.isis.controller.IsisMessage;
24import org.onosproject.isis.io.isispacket.IsisMessageReader;
25import org.onosproject.isis.io.util.IsisConstants;
26import org.onosproject.isis.io.util.IsisUtil;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import java.util.LinkedList;
31import java.util.List;
32
33/**
34 * Decodes an ISIS message from a Channel, for use in a netty pipeline.
35 */
36public class IsisMessageDecoder extends FrameDecoder {
37
38 private static final Logger log = LoggerFactory.getLogger(IsisMessageDecoder.class);
39
40 @Override
41 protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
42 log.debug("IsisMessageDecoder::Message received <:> length {}", buffer.readableBytes());
43 if (!channel.isConnected()) {
44 log.info("Channel is not connected.");
45 return null;
46 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053047 IsisMessageReader messageReader = new IsisMessageReader();
48 List<IsisMessage> isisMessageList = new LinkedList<>();
49 int dataLength = buffer.readableBytes();
50 while (buffer.readableBytes() >= IsisConstants.MINIMUM_FRAME_LEN) {
51 ChannelBuffer payload = buffer.readBytes(IsisConstants.MINIMUM_FRAME_LEN);
52 ChannelBuffer ethernetHeader = payload.readBytes(IsisUtil.ETHER_HEADER_LEN);
53 //Read the Source MAC address from ethernet header at the 6th position
54 MacAddress sourceMac = getSourceMac(ethernetHeader);
55 //Strip 17 byte ethernet header and get the ISIS data buffer
56 ChannelBuffer isisDataBuffer = payload.readBytes(payload.readableBytes());
57 int readableBytes = isisDataBuffer.readableBytes();
58 IsisMessage message = messageReader.readFromBuffer(isisDataBuffer);
59 //Last 7 bytes is metadata. ie. interface MAC address and interface index.
60 if (message != null) {
61 if (isisDataBuffer.readableBytes() >= IsisConstants.METADATA_LEN) {
62 //Sets the source MAC
63 message.setSourceMac(sourceMac);
64 isisDataBuffer.readerIndex(readableBytes - IsisConstants.METADATA_LEN);
65 log.debug("IsisMessageDecoder::Reading metadata <:> length {}", isisDataBuffer.readableBytes());
66 byte[] macBytes = new byte[IsisUtil.SIX_BYTES];
67 isisDataBuffer.readBytes(macBytes, 0, IsisUtil.SIX_BYTES);
68 MacAddress macAddress = MacAddress.valueOf(macBytes);
69 int interfaceIndex = isisDataBuffer.readByte();
70 message.setInterfaceMac(macAddress);
71 message.setInterfaceIndex(interfaceIndex);
72 }
73 isisMessageList.add(message);
74 }
75 }
Jon Hallcbd1b392017-01-18 20:15:44 -080076 return (!isisMessageList.isEmpty()) ? isisMessageList : null;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053077 }
78
79 /**
80 * Gets the source MAC address from the ethernet header.
81 *
82 * @param ethHeader ethernet header bytes
83 * @return MAC address of the source router
84 */
85 private MacAddress getSourceMac(ChannelBuffer ethHeader) {
86 //Source MAC is at position 6 to 11 (6 bytes)
87 ethHeader.skipBytes(IsisUtil.SIX_BYTES);
88 MacAddress sourceMac = MacAddress.valueOf(ethHeader.readBytes(IsisUtil.SIX_BYTES).array());
89
90 return sourceMac;
91 }
92}