-
Notifications
You must be signed in to change notification settings - Fork 0
/
rfc5880.go
2628 lines (2053 loc) · 115 KB
/
rfc5880.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package bfd
import (
"math/rand"
"sync/atomic"
"time"
)
type state uint8
const (
AdminDown state = 0
Down state = 1
Init state = 2
Up state = 3
)
func loop(recv <-chan ControlPacket, xmit chan<- ControlPacket, localDiscr uint32, up *atomic.Bool) {
var tx uint32 = 200 // ms
var rx uint32 = 100 // ms
bfd := stateVariables{
SessionState: Down,
LocalDiscr: localDiscr,
DesiredMinTxInterval: tx * 1000, // convert to BFD timer unit (μs)
RequiredMinRxInterval: rx * 1000, // convert to BFD timer unit (μs)
DetectMult: 5,
LocalDiag: 1,
_intervalTime: time.Duration(tx * 1000), // convert to BFD timer unit (μs)
_detectionTime: 1000000, // 1s (1m microseconds)
}
intervalTimer := time.NewTimer(bfd._intervalTime * time.Microsecond)
detectionTimer := time.NewTimer(bfd._detectionTime * time.Microsecond)
defer func() {
intervalTimer.Stop()
detectionTimer.Stop()
}()
var last ControlPacket
for {
if up != nil {
up.Store(bfd.SessionState == Up)
}
select {
case <-detectionTimer.C:
//bfd.SessionState = Down
//bfd.LocalDiag = 1
//last = nil
return
case <-intervalTimer.C:
last = setControlPacketContents(bfd, false, false)
xmit <- last
if bfd._intervalTime > 0 {
intervalTimer.Reset(bfd._intervalTime * time.Microsecond)
}
case p, ok := <-recv:
if !ok {
return
}
var cp ControlPacket
bfd, cp, ok = receptionOfBFDControlPackets(bfd, p, last)
if ok {
if !detectionTimer.Stop() {
<-detectionTimer.C
}
detectionTimer.Reset(bfd._detectionTime * time.Microsecond)
}
if len(last) < 24 {
if !intervalTimer.Stop() {
<-intervalTimer.C
}
// fire now so timer can be reset to negotiated interval
intervalTimer.Reset(1)
}
// we may need to send an immediate response packet
if cp != nil {
last = cp
xmit <- last
}
}
}
}
type stateVariables struct {
_intervalTime time.Duration
_detectionTime time.Duration
SessionState state
RemoteSessionState state
LocalDiscr uint32
RemoteDiscr uint32
LocalDiag uint8
DesiredMinTxInterval uint32
RequiredMinRxInterval uint32
RemoteMinRxInterval uint32
DemandMode bool
RemoteDemandMode bool
DetectMult uint8
AuthType int
//RcvAuthSeq
//XmitAuthSeq
//AuthSeqKnown
}
//func ntohls(n []byte) uint32 { return ntohl([4]byte{n[0], n[1], n[2], n[3]}) }
func ntohl(n [4]byte) uint32 {
return uint32(n[0])<<24 |
uint32(n[1])<<16 |
uint32(n[2])<<8 |
uint32(n[3])
}
func htonls(n uint32) []byte { r := htonl(n); return r[:] }
func htonl(n uint32) (r [4]byte) {
r[0] = byte(n >> 24)
r[1] = byte(n >> 16)
r[2] = byte(n >> 8)
r[3] = byte(n)
return
}
func ternary(c bool, t, f int) int {
if c {
return t
}
return f
}
func diff(a, b []byte) bool {
var x, y [24]byte
if len(a) < 24 || len(b) < 24 {
return true
}
copy(x[:], a[:])
copy(y[:], b[:])
x[1] &= 0xcf // mask off poll+final
y[1] &= 0xcf // mask off poll+final
return x != y
}
type ControlPacket []byte
func (b ControlPacket) version() uint8 { return b[0] >> 5 }
func (b ControlPacket) diag() uint8 { return b[0] & 31 }
func (b ControlPacket) state() state { return state(b[1] >> 6) }
func (b ControlPacket) poll() bool { return b[1]&32 > 0 }
func (b ControlPacket) final() bool { return b[1]&16 > 0 }
func (b ControlPacket) cpi() bool { return b[1]&8 > 0 }
func (b ControlPacket) authentication() bool { return b[1]&4 > 0 }
func (b ControlPacket) demand() bool { return b[1]&2 > 0 }
func (b ControlPacket) multipoint() bool { return b[1]&1 > 0 }
func (b ControlPacket) detectMult() uint8 { return b[2] }
func (b ControlPacket) length() uint8 { return b[3] }
func (b ControlPacket) myDiscriminator() uint32 { return ntohl([4]byte(b[4:8])) }
func (b ControlPacket) yourDiscriminator() uint32 { return ntohl([4]byte(b[8:12])) }
func (b ControlPacket) desiredMinTxInterval() uint32 { return ntohl([4]byte(b[12:16])) }
func (b ControlPacket) requiredMinRxInterval() uint32 { return ntohl([4]byte(b[16:20])) }
func (b ControlPacket) requiredMinEchoRxInterval() uint32 { return ntohl([4]byte(b[20:24])) }
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | My Discriminator |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Your Discriminator |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Desired Min TX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Required Min RX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Required Min Echo RX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Internet Engineering Task Force (IETF) D. Katz
// Request for Comments: 5880 D. Ward
// Category: Standards Track Juniper Networks
// ISSN: 2070-1721 June 2010
// Bidirectional Forwarding Detection (BFD)
// Abstract
// This document describes a protocol intended to detect faults in the
// bidirectional path between two forwarding engines, including
// interfaces, data link(s), and to the extent possible the forwarding
// engines themselves, with potentially very low latency. It operates
// independently of media, data protocols, and routing protocols.
// Status of This Memo
// This is an Internet Standards Track document.
// This document is a product of the Internet Engineering Task Force
// (IETF). It represents the consensus of the IETF community. It has
// received public review and has been approved for publication by the
// Internet Engineering Steering Group (IESG). Further information on
// Internet Standards is available in Section 2 of RFC 5741.
// Information about the current status of this document, any errata,
// and how to provide feedback on it may be obtained at
// http://www.rfc-editor.org/info/rfc5880.
// Copyright Notice
// Copyright (c) 2010 IETF Trust and the persons identified as the
// document authors. All rights reserved.
// This document is subject to BCP 78 and the IETF Trust's Legal
// Provisions Relating to IETF Documents
// (http://trustee.ietf.org/license-info) in effect on the date of
// publication of this document. Please review these documents
// carefully, as they describe your rights and restrictions with respect
// to this document. Code Components extracted from this document must
// include Simplified BSD License text as described in Section 4.e of
// the Trust Legal Provisions and are provided without warranty as
// described in the Simplified BSD License.
// Table of Contents
// 1. Introduction ....................................................3
// 1.1. Conventions Used in This Document ..........................4
// 2. Design ..........................................................4
// 3. Protocol Overview ...............................................5
// 3.1. Addressing and Session Establishment .......................5
// 3.2. Operating Modes ............................................5
// 4. BFD Control Packet Format .......................................7
// 4.1. Generic BFD Control Packet Format ..........................7
// 4.2. Simple Password Authentication Section Format .............11
// 4.3. Keyed MD5 and Meticulous Keyed MD5 Authentication
// Section Format ............................................11
// 4.4. Keyed SHA1 and Meticulous Keyed SHA1
// Authentication Section Format .............................13
// 5. BFD Echo Packet Format .........................................14
// 6. Elements of Procedure ..........................................14
// 6.1. Overview ..................................................14
// 6.2. BFD State Machine .........................................16
// 6.3. Demultiplexing and the Discriminator Fields ...............17
// 6.4. The Echo Function and Asymmetry ...........................18
// 6.5. The Poll Sequence .........................................19
// 6.6. Demand Mode ...............................................19
// 6.7. Authentication ............................................21
// 6.7.1. Enabling and Disabling Authentication ..............21
// 6.7.2. Simple Password Authentication .....................22
// 6.7.3. Keyed MD5 and Meticulous Keyed MD5 Authentication ..23
// 6.7.4. Keyed SHA1 and Meticulous Keyed SHA1
// Authentication .....................................25
// 6.8. Functional Specifics ......................................27
// 6.8.1. State Variables ....................................27
// 6.8.2. Timer Negotiation ..................................30
// 6.8.3. Timer Manipulation .................................31
// 6.8.4. Calculating the Detection Time .....................32
// 6.8.5. Detecting Failures with the Echo Function ..........33
// 6.8.6. Reception of BFD Control Packets ...................33
// 6.8.7. Transmitting BFD Control Packets ...................36
// 6.8.8. Reception of BFD Echo Packets ......................39
// 6.8.9. Transmission of BFD Echo Packets ...................39
// 6.8.10. Min Rx Interval Change ............................40
// 6.8.11. Min Tx Interval Change ............................40
// 6.8.12. Detect Multiplier Change ..........................40
// 6.8.13. Enabling or Disabling The Echo Function ...........40
// 6.8.14. Enabling or Disabling Demand Mode .................40
// 6.8.15. Forwarding Plane Reset ............................41
// 6.8.16. Administrative Control ............................41
// 6.8.17. Concatenated Paths ................................41
// 6.8.18. Holding Down Sessions .............................42
// 7. Operational Considerations .....................................43
// 8. IANA Considerations ............................................44
// 9. Security Considerations ........................................45
// 10. References ....................................................46
// 10.1. Normative References .....................................46
// 10.2. Informative References ...................................47
// Appendix A. Backward Compatibility (Non-Normative) ................48
// Appendix B. Contributors ..........................................48
// Appendix C. Acknowledgments .......................................49
// 1. Introduction
// An increasingly important feature of networking equipment is the
// rapid detection of communication failures between adjacent systems,
// in order to more quickly establish alternative paths. Detection can
// come fairly quickly in certain circumstances when data link hardware
// comes into play (such as Synchronous Optical Network (SONET) alarms).
// However, there are media that do not provide this kind of signaling
// (such as Ethernet), and some media may not detect certain kinds of
// failures in the path, for example, failing interfaces or forwarding
// engine components.
// Networks use relatively slow "Hello" mechanisms, usually in routing
// protocols, to detect failures when there is no hardware signaling to
// help out. The time to detect failures ("Detection Times") available
// in the existing protocols are no better than a second, which is far
// too long for some applications and represents a great deal of lost
// data at gigabit rates. Furthermore, routing protocol Hellos are of
// no help when those routing protocols are not in use, and the
// semantics of detection are subtly different -- they detect a failure
// in the path between the two routing protocol engines.
// The goal of Bidirectional Forwarding Detection (BFD) is to provide
// low-overhead, short-duration detection of failures in the path
// between adjacent forwarding engines, including the interfaces, data
// link(s), and, to the extent possible, the forwarding engines
// themselves.
// An additional goal is to provide a single mechanism that can be used
// for liveness detection over any media, at any protocol layer, with a
// wide range of Detection Times and overhead, to avoid a proliferation
// of different methods.
// This document specifies the details of the base protocol. The use of
// some mechanisms are application dependent and are specified in a
// separate series of application documents. These issues are so noted.
// Note that many of the exact mechanisms are implementation dependent
// and will not affect interoperability, and are thus outside the scope
// of this specification. Those issues are so noted.
// 1.1. Conventions Used in This Document
// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
// "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
// document are to be interpreted as described in RFC 2119 [KEYWORDS].
// 2. Design
// BFD is designed to detect failures in communication with a forwarding
// plane next hop. It is intended to be implemented in some component
// of the forwarding engine of a system, in cases where the forwarding
// and control engines are separated. This not only binds the protocol
// more to the forwarding plane, but decouples the protocol from the
// fate of the routing protocol engine, making it useful in concert with
// various "graceful restart" mechanisms for those protocols. BFD may
// also be implemented in the control engine, though doing so may
// preclude the detection of some kinds of failures.
// BFD operates on top of any data protocol (network layer, link layer,
// tunnels, etc.) being forwarded between two systems. It is always
// run in a unicast, point-to-point mode. BFD packets are carried as
// the payload of whatever encapsulating protocol is appropriate for the
// medium and network. BFD may be running at multiple layers in a
// system. The context of the operation of any particular BFD session
// is bound to its encapsulation.
// BFD can provide failure detection on any kind of path between
// systems, including direct physical links, virtual circuits, tunnels,
// MPLS Label Switched Paths (LSPs), multihop routed paths, and
// unidirectional links (so long as there is some return path, of
// course). Multiple BFD sessions can be established between the same
// pair of systems when multiple paths between them are present in at
// least one direction, even if a lesser number of paths are available
// in the other direction (multiple parallel unidirectional links or
// MPLS LSPs, for example).
// The BFD state machine implements a three-way handshake, both when
// establishing a BFD session and when tearing it down for any reason,
// to ensure that both systems are aware of the state change.
// BFD can be abstracted as a simple service. The service primitives
// provided by BFD are to create, destroy, and modify a session, given
// the destination address and other parameters. BFD in return provides
// a signal to its clients indicating when the BFD session goes up or
// down.
// 3. Protocol Overview
// BFD is a simple Hello protocol that, in many respects, is similar to
// the detection components of well-known routing protocols. A pair of
// systems transmit BFD packets periodically over each path between the
// two systems, and if a system stops receiving BFD packets for long
// enough, some component in that particular bidirectional path to the
// neighboring system is assumed to have failed. Under some conditions,
// systems may negotiate not to send periodic BFD packets in order to
// reduce overhead.
// A path is only declared to be operational when two-way communication
// has been established between systems, though this does not preclude
// the use of unidirectional links.
// A separate BFD session is created for each communications path and
// data protocol in use between two systems.
// Each system estimates how quickly it can send and receive BFD packets
// in order to come to an agreement with its neighbor about how rapidly
// detection of failure will take place. These estimates can be
// modified in real time in order to adapt to unusual situations. This
// design also allows for fast systems on a shared medium with a slow
// system to be able to more rapidly detect failures between the fast
// systems while allowing the slow system to participate to the best of
// its ability.
// 3.1. Addressing and Session Establishment
// A BFD session is established based on the needs of the application
// that will be making use of it. It is up to the application to
// determine the need for BFD, and the addresses to use -- there is no
// discovery mechanism in BFD. For example, an OSPF [OSPF]
// implementation may request a BFD session to be established to a
// neighbor discovered using the OSPF Hello protocol.
// 3.2. Operating Modes
// BFD has two operating modes that may be selected, as well as an
// additional function that can be used in combination with the two
// modes.
// The primary mode is known as Asynchronous mode. In this mode, the
// systems periodically send BFD Control packets to one another, and if
// a number of those packets in a row are not received by the other
// system, the session is declared to be down.
// The second mode is known as Demand mode. In this mode, it is assumed
// that a system has an independent way of verifying that it has
// connectivity to the other system. Once a BFD session is established,
// such a system may ask the other system to stop sending BFD Control
// packets, except when the system feels the need to verify connectivity
// explicitly, in which case a short sequence of BFD Control packets is
// exchanged, and then the far system quiesces. Demand mode may operate
// independently in each direction, or simultaneously.
// An adjunct to both modes is the Echo function. When the Echo
// function is active, a stream of BFD Echo packets is transmitted in
// such a way as to have the other system loop them back through its
// forwarding path. If a number of packets of the echoed data stream
// are not received, the session is declared to be down. The Echo
// function may be used with either Asynchronous or Demand mode. Since
// the Echo function is handling the task of detection, the rate of
// periodic transmission of Control packets may be reduced (in the case
// of Asynchronous mode) or eliminated completely (in the case of Demand
// mode).
// Pure Asynchronous mode is advantageous in that it requires half as
// many packets to achieve a particular Detection Time as does the Echo
// function. It is also used when the Echo function cannot be supported
// for some reason.
// The Echo function has the advantage of truly testing only the
// forwarding path on the remote system. This may reduce round-trip
// jitter and thus allow more aggressive Detection Times, as well as
// potentially detecting some classes of failure that might not
// otherwise be detected.
// The Echo function may be enabled individually in each direction. It
// is enabled in a particular direction only when the system that loops
// the Echo packets back signals that it will allow it, and when the
// system that sends the Echo packets decides it wishes to.
// Demand mode is useful in situations where the overhead of a periodic
// protocol might prove onerous, such as a system with a very large
// number of BFD sessions. It is also useful when the Echo function is
// being used symmetrically. Demand mode has the disadvantage that
// Detection Times are essentially driven by the heuristics of the
// system implementation and are not known to the BFD protocol. Demand
// mode may not be used when the path round-trip time is greater than
// the desired Detection Time, or the protocol will fail to work
// properly. See section 6.6 for more details.
// 4. BFD Control Packet Format
// 4.1. Generic BFD Control Packet Format
// BFD Control packets are sent in an encapsulation appropriate to the
// environment. The specific encapsulation is outside of the scope of
// this specification. See the appropriate application document for
// encapsulation details.
// The BFD Control packet has a Mandatory Section and an optional
// Authentication Section. The format of the Authentication Section, if
// present, is dependent on the type of authentication in use.
// The Mandatory Section of a BFD Control packet has the following
// format:
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | My Discriminator |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Your Discriminator |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Desired Min TX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Required Min RX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Required Min Echo RX Interval |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// An optional Authentication Section MAY be present:
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Type | Auth Len | Authentication Data... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Version (Vers)
// The version number of the protocol. This document defines
// protocol version 1.
// Diagnostic (Diag)
// A diagnostic code specifying the local system's reason for the
// last change in session state. Values are:
// 0 -- No Diagnostic
// 1 -- Control Detection Time Expired
// 2 -- Echo Function Failed
// 3 -- Neighbor Signaled Session Down
// 4 -- Forwarding Plane Reset
// 5 -- Path Down
// 6 -- Concatenated Path Down
// 7 -- Administratively Down
// 8 -- Reverse Concatenated Path Down
// 9-31 -- Reserved for future use
// This field allows remote systems to determine the reason that the
// previous session failed, for example.
// State (Sta)
// The current BFD session state as seen by the transmitting system.
// Values are:
// 0 -- AdminDown
// 1 -- Down
// 2 -- Init
// 3 -- Up
// Poll (P)
// If set, the transmitting system is requesting verification of
// connectivity, or of a parameter change, and is expecting a packet
// with the Final (F) bit in reply. If clear, the transmitting
// system is not requesting verification.
// Final (F)
// If set, the transmitting system is responding to a received BFD
// Control packet that had the Poll (P) bit set. If clear, the
// transmitting system is not responding to a Poll.
// Control Plane Independent (C)
// If set, the transmitting system's BFD implementation does not
// share fate with its control plane (in other words, BFD is
// implemented in the forwarding plane and can continue to function
// through disruptions in the control plane). If clear, the
// transmitting system's BFD implementation shares fate with its
// control plane.
// The use of this bit is application dependent and is outside the
// scope of this specification. See specific application
// specifications for details.
// Authentication Present (A)
// If set, the Authentication Section is present and the session is
// to be authenticated (see section 6.7 for details).
// Demand (D)
// If set, Demand mode is active in the transmitting system (the
// system wishes to operate in Demand mode, knows that the session is
// Up in both directions, and is directing the remote system to cease
// the periodic transmission of BFD Control packets). If clear,
// Demand mode is not active in the transmitting system.
// Multipoint (M)
// This bit is reserved for future point-to-multipoint extensions to
// BFD. It MUST be zero on both transmit and receipt.
// Detect Mult
// Detection time multiplier. The negotiated transmit interval,
// multiplied by this value, provides the Detection Time for the
// receiving system in Asynchronous mode.
// Length
// Length of the BFD Control packet, in bytes.
// My Discriminator
// A unique, nonzero discriminator value generated by the
// transmitting system, used to demultiplex multiple BFD sessions
// between the same pair of systems.
// Your Discriminator
// The discriminator received from the corresponding remote system.
// This field reflects back the received value of My Discriminator,
// or is zero if that value is unknown.
// Desired Min TX Interval
// This is the minimum interval, in microseconds, that the local
// system would like to use when transmitting BFD Control packets,
// less any jitter applied (see section 6.8.2). The value zero is
// reserved.
// Required Min RX Interval
// This is the minimum interval, in microseconds, between received
// BFD Control packets that this system is capable of supporting,
// less any jitter applied by the sender (see section 6.8.2). If
// this value is zero, the transmitting system does not want the
// remote system to send any periodic BFD Control packets.
// Required Min Echo RX Interval
// This is the minimum interval, in microseconds, between received
// BFD Echo packets that this system is capable of supporting, less
// any jitter applied by the sender (see section 6.8.9). If this
// value is zero, the transmitting system does not support the
// receipt of BFD Echo packets.
// Auth Type
// The authentication type in use, if the Authentication Present (A)
// bit is set.
// 0 - Reserved
// 1 - Simple Password
// 2 - Keyed MD5
// 3 - Meticulous Keyed MD5
// 4 - Keyed SHA1
// 5 - Meticulous Keyed SHA1
// 6-255 - Reserved for future use
// Auth Len
// The length, in bytes, of the authentication section, including the
// Auth Type and Auth Len fields.
// 4.2. Simple Password Authentication Section Format
// If the Authentication Present (A) bit is set in the header, and the
// Authentication Type field contains 1 (Simple Password), the
// Authentication Section has the following format:
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Type | Auth Len | Auth Key ID | Password... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Auth Type
// The Authentication Type, which in this case is 1 (Simple
// Password).
// Auth Len
// The length of the Authentication Section, in bytes. For Simple
// Password authentication, the length is equal to the password
// length plus three.
// Auth Key ID
// The authentication key ID in use for this packet. This allows
// multiple keys to be active simultaneously.
// Password
// The simple password in use on this session. The password is a
// binary string, and MUST be from 1 to 16 bytes in length. The
// password MUST be encoded and configured according to section
// 6.7.2.
// 4.3. Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format
// The use of MD5-based authentication is strongly discouraged.
// However, it is documented here for compatibility with existing
// implementations.
// If the Authentication Present (A) bit is set in the header, and the
// Authentication Type field contains 2 (Keyed MD5) or 3 (Meticulous
// Keyed MD5), the Authentication Section has the following format:
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Type | Auth Len | Auth Key ID | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Key/Digest... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Auth Type
// The Authentication Type, which in this case is 2 (Keyed MD5) or 3
// (Meticulous Keyed MD5).
// Auth Len
// The length of the Authentication Section, in bytes. For Keyed MD5
// and Meticulous Keyed MD5 authentication, the length is 24.
// Auth Key ID
// The authentication key ID in use for this packet. This allows
// multiple keys to be active simultaneously.
// Reserved
// This byte MUST be set to zero on transmit, and ignored on receipt.
// Sequence Number
// The sequence number for this packet. For Keyed MD5
// Authentication, this value is incremented occasionally. For
// Meticulous Keyed MD5 Authentication, this value is incremented for
// each successive packet transmitted for a session. This provides
// protection against replay attacks.
// Auth Key/Digest
// This field carries the 16-byte MD5 digest for the packet. When
// the digest is calculated, the shared MD5 key is stored in this
// field, padded to 16 bytes with trailing zero bytes if needed. The
// shared key MUST be encoded and configured to section 6.7.3.
// 4.4. Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format
// If the Authentication Present (A) bit is set in the header, and the
// Authentication Type field contains 4 (Keyed SHA1) or 5 (Meticulous
// Keyed SHA1), the Authentication Section has the following format:
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Type | Auth Len | Auth Key ID | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Auth Key/Hash... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Auth Type
// The Authentication Type, which in this case is 4 (Keyed SHA1) or 5
// (Meticulous Keyed SHA1).
// Auth Len
// The length of the Authentication Section, in bytes. For Keyed
// SHA1 and Meticulous Keyed SHA1 authentication, the length is 28.
// Auth Key ID
// The authentication key ID in use for this packet. This allows
// multiple keys to be active simultaneously.
// Reserved
// This byte MUST be set to zero on transmit and ignored on receipt.
// Sequence Number
// The sequence number for this packet. For Keyed SHA1
// Authentication, this value is incremented occasionally. For
// Meticulous Keyed SHA1 Authentication, this value is incremented
// for each successive packet transmitted for a session. This
// provides protection against replay attacks.
// Auth Key/Hash
// This field carries the 20-byte SHA1 hash for the packet. When the
// hash is calculated, the shared SHA1 key is stored in this field,
// padded to a length of 20 bytes with trailing zero bytes if needed.
// The shared key MUST be encoded and configured to section 6.7.4.
// 5. BFD Echo Packet Format
// BFD Echo packets are sent in an encapsulation appropriate to the
// environment. See the appropriate application documents for the
// specifics of particular environments.
// The payload of a BFD Echo packet is a local matter, since only the
// sending system ever processes the content. The only requirement is
// that sufficient information is included to demultiplex the received
// packet to the correct BFD session after it is looped back to the
// sender. The contents are otherwise outside the scope of this
// specification.
// Some form of authentication SHOULD be included, since Echo packets
// may be spoofed.
// 6. Elements of Procedure
// This section discusses the normative requirements of the protocol in
// order to achieve interoperability. It is important for implementors
// to enforce only the requirements specified in this section, as
// misguided pedantry has been proven by experience to affect
// interoperability adversely.
// Remember that all references of the form "bfd.Xx" refer to internal
// state variables (defined in section 6.8.1), whereas all references to
// "the Xxx field" refer to fields in the protocol packets themselves
// (defined in section 4).
// 6.1. Overview
// A system may take either an Active role or a Passive role in session
// initialization. A system taking the Active role MUST send BFD
// Control packets for a particular session, regardless of whether it
// has received any BFD packets for that session. A system taking the
// Passive role MUST NOT begin sending BFD packets for a particular
// session until it has received a BFD packet for that session, and thus
// has learned the remote system's discriminator value. At least one
// system MUST take the Active role (possibly both). The role that a
// system takes is specific to the application of BFD, and is outside
// the scope of this specification.
// A session begins with the periodic, slow transmission of BFD Control
// packets. When bidirectional communication is achieved, the BFD
// session becomes Up.
// Once the BFD session is Up, a system can choose to start the Echo
// function if it desires and the other system signals that it will
// allow it. The rate of transmission of Control packets is typically
// kept low when the Echo function is active.
// If the Echo function is not active, the transmission rate of Control
// packets may be increased to a level necessary to achieve the
// Detection Time requirements for the session.
// Once the session is Up, a system may signal that it has entered
// Demand mode, and the transmission of BFD Control packets by the
// remote system ceases. Other means of implying connectivity are used
// to keep the session alive. If either system wishes to verify
// bidirectional connectivity, it can initiate a short exchange of BFD
// Control packets (a "Poll Sequence"; see section 6.5) to do so.
// If Demand mode is not active, and no Control packets are received in
// the calculated Detection Time (see section 6.8.4), the session is
// declared Down. This is signaled to the remote end via the State
// (Sta) field in outgoing packets.
// If sufficient Echo packets are lost, the session is declared Down in
// the same manner. See section 6.8.5.
// If Demand mode is active and no appropriate Control packets are
// received in response to a Poll Sequence, the session is declared Down
// in the same manner. See section 6.6.
// If the session goes Down, the transmission of Echo packets (if any)
// ceases, and the transmission of Control packets goes back to the slow
// rate.
// Once a session has been declared Down, it cannot come back up until
// the remote end first signals that it is down (by leaving the Up
// state), thus implementing a three-way handshake.
// A session MAY be kept administratively down by entering the AdminDown
// state and sending an explanatory diagnostic code in the Diagnostic
// field.
// 6.2. BFD State Machine
// The BFD state machine is quite straightforward. There are three
// states through which a session normally proceeds: two for
// establishing a session (Init and Up) and one for tearing down a
// session (Down). This allows a three-way handshake for both session
// establishment and session teardown (assuring that both systems are
// aware of all session state changes). A fourth state (AdminDown)
// exists so that a session can be administratively put down
// indefinitely.
// Each system communicates its session state in the State (Sta) field
// in the BFD Control packet, and that received state, in combination
// with the local session state, drives the state machine.
// Down state means that the session is down (or has just been created).
// A session remains in Down state until the remote system indicates
// that it agrees that the session is down by sending a BFD Control
// packet with the State field set to anything other than Up. If that
// packet signals Down state, the session advances to Init state; if
// that packet signals Init state, the session advances to Up state.
// Semantically, Down state indicates that the forwarding path is
// unavailable, and that appropriate actions should be taken by the
// applications monitoring the state of the BFD session. A system MAY
// hold a session in Down state indefinitely (by simply refusing to
// advance the session state). This may be done for operational or
// administrative reasons, among others.
// Init state means that the remote system is communicating, and the
// local system desires to bring the session up, but the remote system
// does not yet realize it. A session will remain in Init state until
// either a BFD Control Packet is received that is signaling Init or Up
// state (in which case the session advances to Up state) or the
// Detection Time expires, meaning that communication with the remote
// system has been lost (in which case the session advances to Down
// state).
// Up state means that the BFD session has successfully been
// established, and implies that connectivity between the systems is
// working. The session will remain in the Up state until either
// connectivity fails or the session is taken down administratively. If
// either the remote system signals Down state or the Detection Time
// expires, the session advances to Down state.
// AdminDown state means that the session is being held administratively
// down. This causes the remote system to enter Down state, and remain
// there until the local system exits AdminDown state. AdminDown state
// has no semantic implications for the availability of the forwarding
// path.
// The following diagram provides an overview of the state machine.
// Transitions involving AdminDown state are deleted for clarity (but
// are fully specified in sections 6.8.6 and 6.8.16). The notation on
// each arc represents the state of the remote system (as received in
// the State field in the BFD Control packet) or indicates the
// expiration of the Detection Timer.
// +--+
// | | UP, ADMIN DOWN, TIMER
// | V
// DOWN +------+ INIT
// +------------| |------------+
// | | DOWN | |
// | +-------->| |<--------+ |
// | | +------+ | |
// | | | |
// | | ADMIN DOWN,| |
// | |ADMIN DOWN, DOWN,| |
// | |TIMER TIMER| |
// V | | V
// +------+ +------+
// +----| | | |----+
// DOWN| | INIT |--------------------->| UP | |INIT, UP
// +--->| | INIT, UP | |<---+
// +------+ +------+
// 6.3. Demultiplexing and the Discriminator Fields
// Since multiple BFD sessions may be running between two systems, there
// needs to be a mechanism for demultiplexing received BFD packets to
// the proper session.
// Each system MUST choose an opaque discriminator value that identifies
// each session, and which MUST be unique among all BFD sessions on the
// system. The local discriminator is sent in the My Discriminator
// field in the BFD Control packet, and is echoed back in the Your
// Discriminator field of packets sent from the remote end.
// Once the remote end echoes back the local discriminator, all further
// received packets are demultiplexed based on the Your Discriminator
// field only (which means that, among other things, the source address
// field can change or the interface over which the packets are received
// can change, but the packets will still be associated with the proper
// session).
// The method of demultiplexing the initial packets (in which Your
// Discriminator is zero) is application dependent, and is thus outside
// the scope of this specification.
// Note that it is permissible for a system to change its discriminator
// during a session without affecting the session state, since only that
// system uses its discriminator for demultiplexing purposes (by having
// the other system reflect it back). The implications on an
// implementation for changing the discriminator value is outside the
// scope of this specification.
// 6.4. The Echo Function and Asymmetry
// The Echo function can be run independently in each direction between
// a pair of systems. For whatever reason, a system may advertise that
// it is willing to receive (and loop back) Echo packets, but may not
// wish to ever send any. The fact that a system is sending Echo