mpls.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package icmp
  5. // A MPLSLabel represents a MPLS label stack entry.
  6. type MPLSLabel struct {
  7. Label int // label value
  8. TC int // traffic class; formerly experimental use
  9. S bool // bottom of stack
  10. TTL int // time to live
  11. }
  12. const (
  13. classMPLSLabelStack = 1
  14. typeIncomingMPLSLabelStack = 1
  15. )
  16. // A MPLSLabelStack represents a MPLS label stack.
  17. type MPLSLabelStack struct {
  18. Class int // extension object class number
  19. Type int // extension object sub-type
  20. Labels []MPLSLabel
  21. }
  22. // Len implements the Len method of Extension interface.
  23. func (ls *MPLSLabelStack) Len(proto int) int {
  24. return 4 + (4 * len(ls.Labels))
  25. }
  26. // Marshal implements the Marshal method of Extension interface.
  27. func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {
  28. b := make([]byte, ls.Len(proto))
  29. if err := ls.marshal(proto, b); err != nil {
  30. return nil, err
  31. }
  32. return b, nil
  33. }
  34. func (ls *MPLSLabelStack) marshal(proto int, b []byte) error {
  35. l := ls.Len(proto)
  36. b[0], b[1] = byte(l>>8), byte(l)
  37. b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack
  38. off := 4
  39. for _, ll := range ls.Labels {
  40. b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)
  41. b[off+2] |= byte(ll.TC << 1 & 0x0e)
  42. if ll.S {
  43. b[off+2] |= 0x1
  44. }
  45. b[off+3] = byte(ll.TTL)
  46. off += 4
  47. }
  48. return nil
  49. }
  50. func parseMPLSLabelStack(b []byte) (Extension, error) {
  51. ls := &MPLSLabelStack{
  52. Class: int(b[2]),
  53. Type: int(b[3]),
  54. }
  55. for b = b[4:]; len(b) >= 4; b = b[4:] {
  56. ll := MPLSLabel{
  57. Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,
  58. TC: int(b[2]&0x0e) >> 1,
  59. TTL: int(b[3]),
  60. }
  61. if b[2]&0x1 != 0 {
  62. ll.S = true
  63. }
  64. ls.Labels = append(ls.Labels, ll)
  65. }
  66. return ls, nil
  67. }