github.com/polevpn/netstack@v1.10.9/tcpip/transport/raw/raw_packet_list.go (about) 1 package raw 2 3 // ElementMapper provides an identity mapping by default. 4 // 5 // This can be replaced to provide a struct that maps elements to linker 6 // objects, if they are not the same. An ElementMapper is not typically 7 // required if: Linker is left as is, Element is left as is, or Linker and 8 // Element are the same type. 9 type rawPacketElementMapper struct{} 10 11 // linkerFor maps an Element to a Linker. 12 // 13 // This default implementation should be inlined. 14 // 15 //go:nosplit 16 func (rawPacketElementMapper) linkerFor(elem *rawPacket) *rawPacket { return elem } 17 18 // List is an intrusive list. Entries can be added to or removed from the list 19 // in O(1) time and with no additional memory allocations. 20 // 21 // The zero value for List is an empty list ready to use. 22 // 23 // To iterate over a list (where l is a List): 24 // for e := l.Front(); e != nil; e = e.Next() { 25 // // do something with e. 26 // } 27 // 28 // +stateify savable 29 type rawPacketList struct { 30 head *rawPacket 31 tail *rawPacket 32 } 33 34 // Reset resets list l to the empty state. 35 func (l *rawPacketList) Reset() { 36 l.head = nil 37 l.tail = nil 38 } 39 40 // Empty returns true iff the list is empty. 41 func (l *rawPacketList) Empty() bool { 42 return l.head == nil 43 } 44 45 // Front returns the first element of list l or nil. 46 func (l *rawPacketList) Front() *rawPacket { 47 return l.head 48 } 49 50 // Back returns the last element of list l or nil. 51 func (l *rawPacketList) Back() *rawPacket { 52 return l.tail 53 } 54 55 // PushFront inserts the element e at the front of list l. 56 func (l *rawPacketList) PushFront(e *rawPacket) { 57 rawPacketElementMapper{}.linkerFor(e).SetNext(l.head) 58 rawPacketElementMapper{}.linkerFor(e).SetPrev(nil) 59 60 if l.head != nil { 61 rawPacketElementMapper{}.linkerFor(l.head).SetPrev(e) 62 } else { 63 l.tail = e 64 } 65 66 l.head = e 67 } 68 69 // PushBack inserts the element e at the back of list l. 70 func (l *rawPacketList) PushBack(e *rawPacket) { 71 rawPacketElementMapper{}.linkerFor(e).SetNext(nil) 72 rawPacketElementMapper{}.linkerFor(e).SetPrev(l.tail) 73 74 if l.tail != nil { 75 rawPacketElementMapper{}.linkerFor(l.tail).SetNext(e) 76 } else { 77 l.head = e 78 } 79 80 l.tail = e 81 } 82 83 // PushBackList inserts list m at the end of list l, emptying m. 84 func (l *rawPacketList) PushBackList(m *rawPacketList) { 85 if l.head == nil { 86 l.head = m.head 87 l.tail = m.tail 88 } else if m.head != nil { 89 rawPacketElementMapper{}.linkerFor(l.tail).SetNext(m.head) 90 rawPacketElementMapper{}.linkerFor(m.head).SetPrev(l.tail) 91 92 l.tail = m.tail 93 } 94 95 m.head = nil 96 m.tail = nil 97 } 98 99 // InsertAfter inserts e after b. 100 func (l *rawPacketList) InsertAfter(b, e *rawPacket) { 101 a := rawPacketElementMapper{}.linkerFor(b).Next() 102 rawPacketElementMapper{}.linkerFor(e).SetNext(a) 103 rawPacketElementMapper{}.linkerFor(e).SetPrev(b) 104 rawPacketElementMapper{}.linkerFor(b).SetNext(e) 105 106 if a != nil { 107 rawPacketElementMapper{}.linkerFor(a).SetPrev(e) 108 } else { 109 l.tail = e 110 } 111 } 112 113 // InsertBefore inserts e before a. 114 func (l *rawPacketList) InsertBefore(a, e *rawPacket) { 115 b := rawPacketElementMapper{}.linkerFor(a).Prev() 116 rawPacketElementMapper{}.linkerFor(e).SetNext(a) 117 rawPacketElementMapper{}.linkerFor(e).SetPrev(b) 118 rawPacketElementMapper{}.linkerFor(a).SetPrev(e) 119 120 if b != nil { 121 rawPacketElementMapper{}.linkerFor(b).SetNext(e) 122 } else { 123 l.head = e 124 } 125 } 126 127 // Remove removes e from l. 128 func (l *rawPacketList) Remove(e *rawPacket) { 129 prev := rawPacketElementMapper{}.linkerFor(e).Prev() 130 next := rawPacketElementMapper{}.linkerFor(e).Next() 131 132 if prev != nil { 133 rawPacketElementMapper{}.linkerFor(prev).SetNext(next) 134 } else { 135 l.head = next 136 } 137 138 if next != nil { 139 rawPacketElementMapper{}.linkerFor(next).SetPrev(prev) 140 } else { 141 l.tail = prev 142 } 143 } 144 145 // Entry is a default implementation of Linker. Users can add anonymous fields 146 // of this type to their structs to make them automatically implement the 147 // methods needed by List. 148 // 149 // +stateify savable 150 type rawPacketEntry struct { 151 next *rawPacket 152 prev *rawPacket 153 } 154 155 // Next returns the entry that follows e in the list. 156 func (e *rawPacketEntry) Next() *rawPacket { 157 return e.next 158 } 159 160 // Prev returns the entry that precedes e in the list. 161 func (e *rawPacketEntry) Prev() *rawPacket { 162 return e.prev 163 } 164 165 // SetNext assigns 'entry' as the entry that follows e in the list. 166 func (e *rawPacketEntry) SetNext(elem *rawPacket) { 167 e.next = elem 168 } 169 170 // SetPrev assigns 'entry' as the entry that precedes e in the list. 171 func (e *rawPacketEntry) SetPrev(elem *rawPacket) { 172 e.prev = elem 173 }