OpenSDN source code
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)
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
mpl::list< VersionAndDiagnostic, Flags, DetectionTimeMultiplier, Length, SenderDiscriminator, ReceiverDiscriminator, DesiredMinTxInterval, RequiredMinRxInterval, RequiredMinEchoRXInterval > Sequence
Accessor< ControlPacket, int, &ControlPacket::detection_time_multiplier > Setter
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
static const int kFinallOffset
static const int kAuthenticationPresentOffset
static const int kControlPlaneIndependentOffset
static const int kStateOffset
static const int kPollOffset
static const int kMultipointOffset
static const int kDemandOffset
static const int kSize
static const int kStateBitmask
Accessor< ControlPacket, int, &ControlPacket::length > Setter
static bool Verifier(const void *obj, const uint8_t *data, size_t size, ParseContext *context)
static const int kSize
Accessor< ControlPacket, uint32_t, &ControlPacket::receiver_discriminator > Setter
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
Accessor< ControlPacket, uint32_t, &ControlPacket::sender_discriminator > Setter
static const int kSupportedVersion
static const int kVersionBitmask
static bool Verifier(const ControlPacket *obj, const uint8_t *data, size_t size, ParseContext *context)
static const int kDiagnosticBitmask
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
Definition: bfd_client.h:9
ControlPacket * ParseControlPacket(const uint8_t *data, size_t size)
ResultCode
Definition: bfd_common.h:41
@ kResultCode_Ok
Definition: bfd_common.h:42
@ kResultCode_InvalidPacket
Definition: bfd_common.h:45
@ kResultCode_NotImplemented
Definition: bfd_common.h:46
BFDState
Definition: bfd_common.h:21
@ kUp
Definition: bfd_common.h:22
int EncodeControlPacket(const ControlPacket *msg, uint8_t *data, size_t size)
Diagnostic
Definition: bfd_common.h:49
@ kDiagnosticFirstInvalid
Definition: bfd_common.h:59
const int kMinimalPacketLength
Definition: bfd_common.cc:41
bool operator==(const ControlPacket &p1, const ControlPacket &p2)
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
TimeInterval desired_min_tx_interval
BFD::Diagnostic diagnostic
TimeInterval required_min_rx_interval
BFD::Discriminator receiver_discriminator
BFD::Discriminator sender_discriminator
TimeInterval required_min_echo_rx_interval
ResultCode Verify() const
std::string toString() const
static uint32_t get(const ControlPacket *obj)
static void set(ControlPacket *obj, uint32_t value)
static uint8_t get(const ControlPacket *obj)
static void set(ControlPacket *obj, uint8_t value)
static uint32_t get(const ControlPacket *obj)
static void set(ControlPacket *obj, uint32_t value)
static uint32_t get(const ControlPacket *obj)
static void set(ControlPacket *obj, uint32_t value)
static void set(ControlPacket *obj, uint8_t value)
static uint8_t get(const ControlPacket *obj)