blob: f2cbf19113de2a66bab54eb898a64adb2c87ea48 [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
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.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 }
47
48 IsisMessageReader messageReader = new IsisMessageReader();
49 List<IsisMessage> isisMessageList = new LinkedList<>();
50 int dataLength = buffer.readableBytes();
51 while (buffer.readableBytes() >= IsisConstants.MINIMUM_FRAME_LEN) {
52 ChannelBuffer payload = buffer.readBytes(IsisConstants.MINIMUM_FRAME_LEN);
53 ChannelBuffer ethernetHeader = payload.readBytes(IsisUtil.ETHER_HEADER_LEN);
54 //Read the Source MAC address from ethernet header at the 6th position
55 MacAddress sourceMac = getSourceMac(ethernetHeader);
56 //Strip 17 byte ethernet header and get the ISIS data buffer
57 ChannelBuffer isisDataBuffer = payload.readBytes(payload.readableBytes());
58 int readableBytes = isisDataBuffer.readableBytes();
59 IsisMessage message = messageReader.readFromBuffer(isisDataBuffer);
60 //Last 7 bytes is metadata. ie. interface MAC address and interface index.
61 if (message != null) {
62 if (isisDataBuffer.readableBytes() >= IsisConstants.METADATA_LEN) {
63 //Sets the source MAC
64 message.setSourceMac(sourceMac);
65 isisDataBuffer.readerIndex(readableBytes - IsisConstants.METADATA_LEN);
66 log.debug("IsisMessageDecoder::Reading metadata <:> length {}", isisDataBuffer.readableBytes());
67 byte[] macBytes = new byte[IsisUtil.SIX_BYTES];
68 isisDataBuffer.readBytes(macBytes, 0, IsisUtil.SIX_BYTES);
69 MacAddress macAddress = MacAddress.valueOf(macBytes);
70 int interfaceIndex = isisDataBuffer.readByte();
71 message.setInterfaceMac(macAddress);
72 message.setInterfaceIndex(interfaceIndex);
73 }
74 isisMessageList.add(message);
75 }
76 }
77
78 return isisMessageList;
79 }
80
81 /**
82 * Gets the source MAC address from the ethernet header.
83 *
84 * @param ethHeader ethernet header bytes
85 * @return MAC address of the source router
86 */
87 private MacAddress getSourceMac(ChannelBuffer ethHeader) {
88 //Source MAC is at position 6 to 11 (6 bytes)
89 ethHeader.skipBytes(IsisUtil.SIX_BYTES);
90 MacAddress sourceMac = MacAddress.valueOf(ethHeader.readBytes(IsisUtil.SIX_BYTES).array());
91
92 return sourceMac;
93 }
94}