package routingtable import ( "fmt" "github.com/pkg/errors" "net/netip" ) type Address struct { Addr netip.Addr Prefix netip.Prefix } type Hop struct { Cost uint32 VipAsStr string } type RoutingTable map[Address]Hop const ( STATIC_COST uint32 = 4294967295 // 2^32 - 1 ) // TODO: consider making this take in arguments, such as a config file func New() *RoutingTable { var table = make(RoutingTable) return &table } //func Initialize(config lnxconfig.IPConfig) error { // if len(os.Args) != 2 { // fmt.Printf("Usage: %s \n", os.Args[0]) // os.Exit(1) // } // fileName := os.Args[1] // // lnxConfig, err := lnxconfig.ParseConfig(fileName) // if err != nil { // panic(err) // } // // // make and populate routing table // table = make(map[Address]Route) // for _, iface := range lnxConfig.Interfaces { // var address = Address{iface.AssignedIP, iface.AssignedPrefix} // var route = Route{Address{iface.AssignedIP, iface.AssignedPrefix}, 0, iface.AssignedPrefix} // table[address] = route // } // // //} func AddRoute(srcAddr Address, cost uint32, addrAsStr string, tableReference *RoutingTable) error { if _, ok := (*tableReference)[srcAddr]; ok { return errors.New("Route already exists") } (*tableReference)[srcAddr] = Hop{cost, addrAsStr} return nil } func RemoveRoute(dest Address, table *RoutingTable) error { if _, ok := (*table)[dest]; !ok { return errors.New("Route doesn't exist") } delete(*table, dest) return nil } // TODO: implement this with most specific prefix matching func Route(dest Address, table *RoutingTable) (Hop, error) { // get the most specific route for address, route := range *table { if address.Prefix.Contains(dest.Addr) { return route, nil } } return Hop{}, errors.New("Route doesn't exist") } func SprintRoutingTable(table *RoutingTable) string { message := "" for address, route := range *table { message += fmt.Sprintf("%s/%d\t%d\n", address.Addr, address.Prefix, route.Cost) } return message }