OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bfd_control_packet.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
3  */
4 
6 
7 #include <string>
8 #include <list>
9 #include <boost/mpl/list.hpp>
10 
11 #include "base/proto.h"
12 
13 namespace BFD {
14 
15 class VersionAndDiagnostic: public ProtoElement<VersionAndDiagnostic> {
16  public:
17  static const int kSize = 1;
18 
19  static const int kVersionBitmask = 0xE0;
20  static const int kVersionOffset = 5;
21  static const int kDiagnosticBitmask = 0x1F;
22  static const int kSupportedVersion = 1;
23 
24  static bool Verifier(const ControlPacket *obj, const uint8_t *data,
25  size_t size, ParseContext *context) {
26  uint8_t value = get_value(data, 1);
27  return ((value & kVersionBitmask) >>
30  }
31 
32  typedef struct {
33  static void set(ControlPacket *obj, uint8_t value) {
34  obj->diagnostic = (Diagnostic) (value & kDiagnosticBitmask);
35  }
36 
37  static uint8_t get(const ControlPacket *obj) {
38  return obj->diagnostic | (kSupportedVersion << kVersionOffset);
39  }
40  } Setter;
41 };
42 
43 class Flags: public ProtoElement<Flags> {
44  public:
45  static const int kSize = 1;
46 
47  static const int kStateBitmask = 0xC0;
48  static const int kStateOffset = 6;
49  static const int kPollOffset = 5;
50  static const int kFinallOffset = 4;
51  static const int kControlPlaneIndependentOffset = 3;
52  static const int kAuthenticationPresentOffset = 2;
53  static const int kDemandOffset = 1;
54  static const int kMultipointOffset = 0;
55 
56  typedef struct {
57  static void set(ControlPacket *obj, uint8_t value) {
58  obj->state = (BFDState) ((value & kStateBitmask)
59  >> kStateOffset);
60  obj->poll = value & (1 << kPollOffset);
61  obj->final = value & (1 << kFinallOffset);
62  obj->control_plane_independent = value &
64  obj->authentication_present = value &
66  obj->demand = value & (1 << kDemandOffset);
67  obj->multipoint = value & (1 << kMultipointOffset);
68  }
69 
70  static uint8_t get(const ControlPacket *obj) {
71  return (obj->state << kStateOffset) | (obj->poll << kPollOffset)
72  | (obj->final << kFinallOffset)
73  | (obj->control_plane_independent
75  | (obj->authentication_present
77  | (obj->demand << kDemandOffset)
78  | (obj->multipoint << kMultipointOffset);
79  }
80  } Setter;
81 };
82 
83 class DetectionTimeMultiplier: public ProtoElement<DetectionTimeMultiplier> {
84  public:
85  typedef Accessor<ControlPacket, int,
87 
88  static const int kSize = 1;
89 
90  static bool Verifier(const ControlPacket *obj, const uint8_t *data,
91  size_t size, ParseContext *context) {
92  uint8_t value = get_value(data, 1);
93  return value > 0;
94  }
95 };
96 
97 class Length: public ProtoElement<Length> {
98  public:
100 
101  static const int kSize = 1;
102 
103  static bool Verifier(const void *obj, const uint8_t *data, size_t size,
104  ParseContext *context) {
105  uint8_t value = get_value(data, 1);
106  return value == kMinimalPacketLength;
107  }
108 };
109 
110 class SenderDiscriminator: public ProtoElement<SenderDiscriminator> {
111  public:
112  typedef Accessor<ControlPacket, uint32_t,
114 
115  static const int kSize = 4;
116 
117  static bool Verifier(const ControlPacket *obj, const uint8_t *data,
118  size_t size, ParseContext *context) {
119  uint32_t value = get_value(data, 4);
120  return value > 0;
121  }
122 };
123 
124 class ReceiverDiscriminator: public ProtoElement<ReceiverDiscriminator> {
125  public:
126  typedef Accessor<ControlPacket, uint32_t,
128 
129  static const int kSize = 4;
130 };
131 
132 class DesiredMinTxInterval: public ProtoElement<DesiredMinTxInterval> {
133  public:
134  typedef struct {
135  static void set(ControlPacket *obj, uint32_t value) {
137  boost::posix_time::microseconds(value);
138  }
139 
140  static uint32_t get(const ControlPacket *obj) {
141  return obj->desired_min_tx_interval.total_microseconds();
142  }
143  } Setter;
144 
145  static const int kSize = 4;
146 };
147 
148 class RequiredMinRxInterval: public ProtoElement<RequiredMinRxInterval> {
149  public:
150  typedef struct {
151  static void set(ControlPacket *obj, uint32_t value) {
153  boost::posix_time::microseconds(value);
154  }
155 
156  static uint32_t get(const ControlPacket *obj) {
157  return obj->required_min_rx_interval.total_microseconds();
158  }
159  } Setter;
160 
161  static const int kSize = 4;
162 };
163 
165  public ProtoElement<RequiredMinEchoRXInterval> {
166  public:
167  typedef struct {
168  static void set(ControlPacket *obj, uint32_t value) {
170  boost::posix_time::microseconds(value);
171  }
172 
173  static uint32_t get(const ControlPacket *obj) {
174  return obj->required_min_echo_rx_interval.total_microseconds();
175  }
176  } Setter;
177 
178  static const int kSize = 4;
179 };
180 
181 class ControlPacketMessage: public ProtoSequence<ControlPacketMessage> {
182  public:
187 };
188 
189 std::string ControlPacket::toString() const {
190  std::ostringstream out;
191  out << "Length: " << length << "\n";
192  out << "Diagnostic: " << diagnostic << "\n";
193  out << "State: " << state << "\n";
194  out << "Poll: " << poll << "\n";
195  out << "Final: " << final << "\n";
196  out << "ControlPlaneIndependent: " << control_plane_independent << "\n";
197  out << "AuthenticationPresent: " << authentication_present << "\n";
198  out << "Demand: " << demand << "\n";
199  out << "Multipoint: " << multipoint << "\n";
200  out << "DetectionTimeMultiplier: " << detection_time_multiplier << "\n";
201  out << "SenderDiscriminator: 0x"
202  << std::hex << sender_discriminator << "\n";
203  out << "ReceiverDiscriminator: 0x" << std::hex << receiver_discriminator
204  << "\n";
205  out << "DesiredMinTxInterval: " << desired_min_tx_interval << "\n";
206  out << "RequiredMinRxInterval: " << required_min_rx_interval << "\n";
207  out << "RequiredMinEchoRXInterval: "
209  return out.str();
210 }
211 
213  if (multipoint)
215 
218 
219  if (receiver_discriminator == 0 && state == kUp)
221 
222  if (poll && final)
224 
225  return kResultCode_Ok;
226 }
227 
228 ControlPacket* ParseControlPacket(const uint8_t *data, size_t size) {
229  ParseContext context;
230  int result = ControlPacketMessage::Parse(data, size, &context,
231  new ControlPacket());
232  if (result < 0 || (size_t)result != size) {
233  return NULL;
234  }
235  return static_cast<ControlPacket *>(context.release());
236 }
237 
238 int EncodeControlPacket(const ControlPacket *msg, uint8_t *data, size_t size) {
239  EncodeContext context;
240  return ControlPacketMessage::Encode(&context, msg, data, size);
241 }
242 
243 bool operator==(const ControlPacket &p1, const ControlPacket &p2) {
244  return p1.poll == p2.poll && p1.final == p2.final
247  && p1.demand == p2.demand && p1.multipoint == p2.multipoint
249  && p1.length == p2.length
252  && p1.diagnostic == p2.diagnostic && p1.state == p2.state
257 }
258 } // namespace BFD
static void set(ControlPacket *obj, uint8_t value)
int EncodeControlPacket(const ControlPacket *msg, uint8_t *data, size_t size)
static const int kControlPlaneIndependentOffset
ResultCode Verify() const
std::string toString() const
static void set(ControlPacket *obj, uint32_t value)
Accessor< ControlPacket, uint32_t,&ControlPacket::sender_discriminator > Setter
Accessor< ControlPacket, int,&ControlPacket::length > Setter
static const int kVersionBitmask
static const int kFinallOffset
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
static const int kDemandOffset
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static bool Verifier(const void *obj, const uint8_t *data, size_t size, ParseContext *context)
Diagnostic
Definition: bfd_common.h:49
Accessor< ControlPacket, uint32_t,&ControlPacket::receiver_discriminator > Setter
static const int kSize
static const int kDiagnosticBitmask
static void set(ControlPacket *obj, uint8_t value)
BFD::Discriminator sender_discriminator
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
BFD::Discriminator receiver_discriminator
TimeInterval required_min_rx_interval
static const int kSize
static const int kAuthenticationPresentOffset
bool operator==(const ControlPacket &p1, const ControlPacket &p2)
ResultCode
Definition: bfd_common.h:41
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
const int kMinimalPacketLength
Definition: bfd_common.cc:41
BFD::Diagnostic diagnostic
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
BFDState
Definition: bfd_common.h:21
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
mpl::list< VersionAndDiagnostic, Flags, DetectionTimeMultiplier, Length, SenderDiscriminator, ReceiverDiscriminator, DesiredMinTxInterval, RequiredMinRxInterval, RequiredMinEchoRXInterval > Sequence
static void set(ControlPacket *obj, uint32_t value)
static const int kStateOffset
TimeInterval required_min_echo_rx_interval
TimeInterval desired_min_tx_interval
static const int kPollOffset
static const int kStateBitmask
static void set(ControlPacket *obj, uint32_t value)
Accessor< ControlPacket, int,&ControlPacket::detection_time_multiplier > Setter
static const int kSupportedVersion
ControlPacket * ParseControlPacket(const uint8_t *data, size_t size)
static const int kMultipointOffset