This commit is contained in:
bluepython508 committed 2026-10-22 12:27:19 +01:00
1 parent 3530afb854
commit 6903fcff27
2146 files changed
+112256 -190703

No files matched your search

+207
View File
@@ -0,0 +1,207 @@
// Copyright (c) 2026 Karl Gaissmaier
// SPDX-License-Identifier: MIT
package golden
import (
"cmp"
"fmt"
"net/netip"
"slices"
)
// Table is a simple and slow route table, implemented as a slice of prefixes
// and values as a golden reference for bart.
type Table[V any] []TableItem[V]
type TableItem[V any] struct {
Pfx netip.Prefix
Val V
}
func (g TableItem[V]) String() string {
return fmt.Sprintf("(%s, %v)", g.Pfx, g.Val)
}
func (t *Table[V]) Insert(pfx netip.Prefix, val V) {
pfx = pfx.Masked()
for i, item := range *t {
if item.Pfx == pfx {
(*t)[i].Val = val // de-dupe
return
}
}
*t = append(*t, TableItem[V]{pfx, val})
}
func (t *Table[V]) Delete(pfx netip.Prefix) (exists bool) {
pfx = pfx.Masked()
for i, item := range *t {
if item.Pfx == pfx {
*t = slices.Delete(*t, i, i+1)
return true
}
}
return false
}
func (t Table[V]) AllSorted() []netip.Prefix {
var result []netip.Prefix
for _, item := range t {
result = append(result, item.Pfx)
}
slices.SortFunc(result, cmpPrefix)
return result
}
func (t Table[V]) Get(pfx netip.Prefix) (val V, ok bool) {
pfx = pfx.Masked()
for _, item := range t {
if item.Pfx == pfx {
return item.Val, true
}
}
return val, false
}
func (t *Table[V]) Update(pfx netip.Prefix, cb func(V, bool) V) (val V) {
pfx = pfx.Masked()
for i, item := range *t {
if item.Pfx == pfx {
// update val
val = cb(item.Val, true)
(*t)[i].Val = val
return val
}
}
// new val
val = cb(val, false)
*t = append(*t, TableItem[V]{pfx, val})
return val
}
func (ta *Table[V]) Union(tb *Table[V]) {
for _, bItem := range *tb {
var match bool
for i, aItem := range *ta {
if aItem.Pfx == bItem.Pfx {
(*ta)[i] = bItem
match = true
break
}
}
if !match {
*ta = append(*ta, bItem)
}
}
}
func (t Table[V]) Lookup(addr netip.Addr) (val V, ok bool) {
bestLen := -1
for _, item := range t {
if item.Pfx.Contains(addr) && item.Pfx.Bits() > bestLen {
val = item.Val
ok = true
bestLen = item.Pfx.Bits()
}
}
return val, ok
}
func (t Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) {
pfx = pfx.Masked()
bestLen := -1
for _, item := range t {
if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() && item.Pfx.Bits() > bestLen {
val = item.Val
ok = true
bestLen = item.Pfx.Bits()
}
}
return val, ok
}
func (t Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool) {
pfx = pfx.Masked()
bestLen := -1
for _, item := range t {
if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() && item.Pfx.Bits() > bestLen {
val = item.Val
lpm = item.Pfx
ok = true
bestLen = item.Pfx.Bits()
}
}
return lpm, val, ok
}
func (t Table[V]) Subnets(pfx netip.Prefix) []netip.Prefix {
pfx = pfx.Masked()
var result []netip.Prefix
for _, item := range t {
if pfx.Overlaps(item.Pfx) && pfx.Bits() <= item.Pfx.Bits() {
result = append(result, item.Pfx)
}
}
slices.SortFunc(result, cmpPrefix)
return result
}
func (t Table[V]) Supernets(pfx netip.Prefix) []netip.Prefix {
pfx = pfx.Masked()
var result []netip.Prefix
for _, item := range t {
if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() {
result = append(result, item.Pfx)
}
}
slices.SortFunc(result, cmpPrefix)
slices.Reverse(result)
return result
}
func (t Table[V]) OverlapsPrefix(pfx netip.Prefix) bool {
pfx = pfx.Masked()
for _, p := range t {
if p.Pfx.Overlaps(pfx) {
return true
}
}
return false
}
func (ta *Table[V]) Overlaps(tb *Table[V]) bool {
for _, aItem := range *ta {
for _, bItem := range *tb {
if aItem.Pfx.Overlaps(bItem.Pfx) {
return true
}
}
}
return false
}
// Sort, inplace by netip.Prefix, all prefixes are in normalized form
func (t *Table[V]) Sort() {
slices.SortFunc(*t, func(a, b TableItem[V]) int {
return cmpPrefix(a.Pfx, b.Pfx)
})
}
// cmpPrefix, helper function, compare func for prefix sort,
// all cidrs are already normalized
func cmpPrefix(a, b netip.Prefix) int {
if cmpAddr := a.Addr().Compare(b.Addr()); cmpAddr != 0 {
return cmpAddr
}
return cmp.Compare(a.Bits(), b.Bits())
}
+129
View File
@@ -0,0 +1,129 @@
// Copyright (c) 2026 Karl Gaissmaier
// SPDX-License-Identifier: MIT
package random
import (
"fmt"
"math/rand/v2"
"net/netip"
)
// mpp is a abbreviation and panics on non masked prefixes.
//
//nolint:gochecknoglobals
var mpp = func(s string) netip.Prefix {
pfx := netip.MustParsePrefix(s)
if pfx == pfx.Masked() {
return pfx
}
panic(fmt.Sprintf("%s is not canonicalized as %s", s, pfx.Masked()))
}
// Prefix returns a randomly generated prefix
func Prefix(prng *rand.Rand) netip.Prefix {
if prng.IntN(2) == 1 {
return Prefix4(prng)
}
return Prefix6(prng)
}
func Prefix4(prng *rand.Rand) netip.Prefix {
bits := prng.IntN(33)
return netip.PrefixFrom(IP4(prng), bits).Masked()
}
func Prefix6(prng *rand.Rand) netip.Prefix {
bits := prng.IntN(129)
return netip.PrefixFrom(IP6(prng), bits).Masked()
}
func IP4(prng *rand.Rand) netip.Addr {
var b [4]byte
for i := range b {
//nolint:gosec // G115: integer overflow conversion uint -> byte
b[i] = byte(prng.UintN(256))
}
return netip.AddrFrom4(b)
}
func IP6(prng *rand.Rand) netip.Addr {
var b [16]byte
for i := range b {
//nolint:gosec // G115: integer overflow conversion uint -> byte
b[i] = byte(prng.UintN(256))
}
return netip.AddrFrom16(b)
}
func IP(prng *rand.Rand) netip.Addr {
if prng.IntN(2) == 1 {
return IP4(prng)
}
return IP6(prng)
}
func RealWorldPrefixes4(prng *rand.Rand, n int) []netip.Prefix {
set := make(map[netip.Prefix]struct{})
pfxs := make([]netip.Prefix, 0, n)
for len(set) < n {
pfx := Prefix4(prng)
// skip too small or too big masks
if pfx.Bits() < 8 || pfx.Bits() > 28 {
continue
}
// skip reserved/experimental ranges (e.g., 240.0.0.0/8)
if pfx.Overlaps(mpp("240.0.0.0/8")) {
continue
}
if _, ok := set[pfx]; !ok {
set[pfx] = struct{}{}
pfxs = append(pfxs, pfx)
}
}
return pfxs
}
func RealWorldPrefixes6(prng *rand.Rand, n int) []netip.Prefix {
set := make(map[netip.Prefix]struct{})
pfxs := make([]netip.Prefix, 0, n)
for len(set) < n {
pfx := Prefix6(prng)
// skip too small or too big masks
if pfx.Bits() < 16 || pfx.Bits() > 56 {
continue
}
// skip non global routes seen in the real world
if !pfx.Overlaps(mpp("2000::/3")) {
continue
}
if pfx.Addr().Compare(mpp("2c0f::/16").Addr()) == 1 {
continue
}
if _, ok := set[pfx]; !ok {
set[pfx] = struct{}{}
pfxs = append(pfxs, pfx)
}
}
return pfxs
}
func RealWorldPrefixes(prng *rand.Rand, n int) []netip.Prefix {
pfxs := make([]netip.Prefix, 0, n)
pfxs = append(pfxs, RealWorldPrefixes4(prng, n/2)...)
pfxs = append(pfxs, RealWorldPrefixes6(prng, n-len(pfxs))...)
prng.Shuffle(len(pfxs), func(i, j int) {
pfxs[i], pfxs[j] = pfxs[j], pfxs[i]
})
return pfxs
}