blob: 38e979cd19bfb98edb7dd7268d8a2cd173e99b04 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070018package net.onrc.onos.core.packet;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080019
20import java.nio.ByteBuffer;
21
22/**
23 * This class is a Rapid Spanning Tree Protocol
Ray Milkeyb41100a2014-04-10 10:42:15 -070024 * Bridge Protocol Data Unit.
Ray Milkey269ffb92014-04-03 14:43:30 -070025 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026 * @author alexreimers
27 */
28public class BPDU extends BasePacket {
29 public enum BPDUType {
30 CONFIG,
31 TOPOLOGY_CHANGE;
32 }
Ray Milkey269ffb92014-04-03 14:43:30 -070033
Pavlin Radoslavov53ad5e32014-04-10 14:24:26 -070034 private static final long DEST_MAC = 0x0180c2000000L; // 01-80-c2-00-00-00
Ray Milkey269ffb92014-04-03 14:43:30 -070035
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080036 // TODO - check this for RSTP
37 private LLC llcHeader;
38 private short protocolId = 0;
39 private byte version = 0;
40 private byte type;
41 private byte flags;
42 private byte[] rootBridgeId;
43 private int rootPathCost;
44 private byte[] senderBridgeId; // switch cluster MAC
45 private short portId; // port it was transmitted from
46 private short messageAge; // 256ths of a second
47 private short maxAge; // 256ths of a second
48 private short helloTime; // 256ths of a second
49 private short forwardDelay; // 256ths of a second
Ray Milkey269ffb92014-04-03 14:43:30 -070050
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080051 public BPDU(BPDUType type) {
52 rootBridgeId = new byte[8];
53 senderBridgeId = new byte[8];
Ray Milkey269ffb92014-04-03 14:43:30 -070054
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080055 llcHeader = new LLC();
56 llcHeader.setDsap((byte) 0x42);
57 llcHeader.setSsap((byte) 0x42);
58 llcHeader.setCtrl((byte) 0x03);
Ray Milkey269ffb92014-04-03 14:43:30 -070059
60 switch (type) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080061 case CONFIG:
62 this.type = 0x0;
63 break;
64 case TOPOLOGY_CHANGE:
65 this.type = (byte) 0x80; // 1000 0000
66 break;
67 default:
68 this.type = 0;
69 break;
70 }
71 }
Ray Milkey269ffb92014-04-03 14:43:30 -070072
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080073 @Override
74 public byte[] serialize() {
75 byte[] data;
76 // TODO check these
Ray Milkey269ffb92014-04-03 14:43:30 -070077 if (type == 0x0) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080078 // config
79 data = new byte[38];
80 } else {
81 // topology change
82 data = new byte[7]; // LLC + TC notification
83 }
Ray Milkey269ffb92014-04-03 14:43:30 -070084
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080085 ByteBuffer bb = ByteBuffer.wrap(data);
86 // Serialize the LLC header
87 byte[] llc = llcHeader.serialize();
88 bb.put(llc, 0, llc.length);
89 bb.putShort(protocolId);
90 bb.put(version);
91 bb.put(type);
Ray Milkey269ffb92014-04-03 14:43:30 -070092
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080093 if (type == 0x0) {
94 bb.put(flags);
95 bb.put(rootBridgeId, 0, rootBridgeId.length);
96 bb.putInt(rootPathCost);
97 bb.put(senderBridgeId, 0, senderBridgeId.length);
98 bb.putShort(portId);
99 bb.putShort(messageAge);
100 bb.putShort(maxAge);
101 bb.putShort(helloTime);
102 bb.putShort(forwardDelay);
103 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700104
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800105 return data;
106 }
107
108 @Override
109 public IPacket deserialize(byte[] data, int offset, int length) {
110 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
Ray Milkey269ffb92014-04-03 14:43:30 -0700111
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800112 // LLC header
113 llcHeader.deserialize(data, offset, 3);
Ray Milkey269ffb92014-04-03 14:43:30 -0700114
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800115 this.protocolId = bb.getShort();
116 this.version = bb.get();
117 this.type = bb.get();
Ray Milkey269ffb92014-04-03 14:43:30 -0700118
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800119 // These fields only exist if it's a configuration BPDU
120 if (this.type == 0x0) {
121 this.flags = bb.get();
122 bb.get(rootBridgeId, 0, 6);
123 this.rootPathCost = bb.getInt();
124 bb.get(this.senderBridgeId, 0, 6);
125 this.portId = bb.getShort();
126 this.messageAge = bb.getShort();
127 this.maxAge = bb.getShort();
128 this.helloTime = bb.getShort();
129 this.forwardDelay = bb.getShort();
130 }
131 // TODO should we set other fields to 0?
Ray Milkey269ffb92014-04-03 14:43:30 -0700132
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800133 return this;
134 }
135
136 public long getDestMac() {
Pavlin Radoslavov53ad5e32014-04-10 14:24:26 -0700137 return DEST_MAC;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800138 }
139}