Changed default router table modifications. Entry is now Route.

This commit is contained in:
Milos Gajdos 2019-06-10 13:34:23 +01:00
parent 459f4c8387
commit da18ea4ab5
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F
5 changed files with 95 additions and 96 deletions

View File

@ -48,24 +48,24 @@ func (r *router) Options() Options {
// Add adds new entry into routing table with given options. // Add adds new entry into routing table with given options.
// It returns error if the entry could not be added. // It returns error if the entry could not be added.
func (r *router) Add(e Entry) error { func (r *router) Add(e Route) error {
return r.table.Add(e) return r.table.Add(e)
} }
// Remove removes entry from the routing table. // Remove removes entry from the routing table.
// It returns error if either the entry could not be removed or it does not exist. // It returns error if either the entry could not be removed or it does not exist.
func (r *router) Remove(e Entry) error { func (r *router) Remove(e Route) error {
return r.table.Remove(e) return r.table.Remove(e)
} }
// Update updates an entry in the router's routing table // Update updates an entry in the router's routing table
// It returns error if the entry was not found or it failed to be updated. // It returns error if the entry was not found or it failed to be updated.
func (r *router) Update(opts ...EntryOption) error { func (r *router) Update(opts ...RouteOption) error {
return r.table.Update(opts...) return r.table.Update(opts...)
} }
// Lookup makes a query lookup and returns all matching entries // Lookup makes a query lookup and returns all matching entries
func (r *router) Lookup(q Query) ([]*Entry, error) { func (r *router) Lookup(q Query) ([]*Route, error) {
return nil, ErrNotImplemented return nil, ErrNotImplemented
} }

View File

@ -4,14 +4,14 @@ package router
type AddPolicy int type AddPolicy int
const ( const (
// Override overrides existing routing table entry // Override overrides existing routing table route
OverrideIfExists AddPolicy = iota OverrideIfExists AddPolicy = iota
// ErrIfExists returns error if the entry already exists // ErrIfExists returns error if the route already exists
ErrIfExists ErrIfExists
) )
// EntryOptions defines micro network routing table entry options // RouteOptions defines micro network routing table route options
type EntryOptions struct { type RouteOptions struct {
// DestAddr is destination address // DestAddr is destination address
DestAddr string DestAddr string
// Hop is the next route hop // Hop is the next route hop
@ -21,69 +21,69 @@ type EntryOptions struct {
SrcAddr string SrcAddr string
// Metric is route cost metric // Metric is route cost metric
Metric int Metric int
// Policy defines entry addition policy // Policy defines route addition policy
Policy AddPolicy Policy AddPolicy
} }
// DestAddr sets destination address // DestAddr sets destination address
func DestAddr(a string) EntryOption { func DestAddr(a string) RouteOption {
return func(o *EntryOptions) { return func(o *RouteOptions) {
o.DestAddr = a o.DestAddr = a
} }
} }
// Hop allows to set the route entry options // Hop allows to set the route route options
func Hop(r Router) EntryOption { func Hop(r Router) RouteOption {
return func(o *EntryOptions) { return func(o *RouteOptions) {
o.Hop = r o.Hop = r
} }
} }
// SrcAddr sets source address // SrcAddr sets source address
func SrcAddr(a string) EntryOption { func SrcAddr(a string) RouteOption {
return func(o *EntryOptions) { return func(o *RouteOptions) {
o.SrcAddr = a o.SrcAddr = a
} }
} }
// Metric sets entry metric // Metric sets route metric
func Metric(m int) EntryOption { func Metric(m int) RouteOption {
return func(o *EntryOptions) { return func(o *RouteOptions) {
o.Metric = m o.Metric = m
} }
} }
// AddEntryPolicy sets add entry policy // RoutePolicy sets add route policy
func AddEntryPolicy(p AddPolicy) EntryOption { func RoutePolicy(p AddPolicy) RouteOption {
return func(o *EntryOptions) { return func(o *RouteOptions) {
o.Policy = p o.Policy = p
} }
} }
// Entry is routing table entry // Route is routing table route
type Entry interface { type Route interface {
// Options returns entry options // Options returns route options
Options() EntryOptions Options() RouteOptions
} }
type entry struct { type route struct {
opts EntryOptions opts RouteOptions
} }
// NewEntry returns new routing table entry // NewRoute returns new routing table route
func NewEntry(opts ...EntryOption) Entry { func NewRoute(opts ...RouteOption) Route {
eopts := EntryOptions{} eopts := RouteOptions{}
for _, o := range opts { for _, o := range opts {
o(&eopts) o(&eopts)
} }
return &entry{ return &route{
opts: eopts, opts: eopts,
} }
} }
// Options returns entry options // Options returns route options
func (e *entry) Options() EntryOptions { func (r *route) Options() RouteOptions {
return e.opts return r.opts
} }

View File

@ -13,7 +13,7 @@ const (
// QueryOptions allow to define routing table query options // QueryOptions allow to define routing table query options
type QueryOptions struct { type QueryOptions struct {
// Route allows to set route options // Route allows to set route options
Route *EntryOptions Route *RouteOptions
// Service is micro service name // Service is micro service name
Service string Service string
// Policy defines query lookup policy // Policy defines query lookup policy
@ -22,8 +22,8 @@ type QueryOptions struct {
Count int Count int
} }
// EntryOpts allows to set the route query options // RouteOpts allows to set the route query options
func EntryOpts(r *EntryOptions) QueryOption { func RouteOpts(r *RouteOptions) QueryOption {
return func(o *QueryOptions) { return func(o *QueryOptions) {
o.Route = r o.Route = r
} }
@ -36,8 +36,8 @@ func Service(s string) QueryOption {
} }
} }
// QueryLookupPolicy allows to define query lookup policy // QueryPolicy allows to define query lookup policy
func QueryLookupPolicy(p LookupPolicy) QueryOption { func QueryPolicy(p LookupPolicy) QueryOption {
return func(o *QueryOptions) { return func(o *QueryOptions) {
o.Policy = p o.Policy = p
} }

View File

@ -8,13 +8,13 @@ type Router interface {
// Options returns Router options // Options returns Router options
Options() Options Options() Options
// Add adds new entry into routing table // Add adds new entry into routing table
Add(Entry) error Add(Route) error
// Remove removes entry from the routing table // Remove removes entry from the routing table
Remove(Entry) error Remove(Route) error
// Update updates entry in the routing table // Update updates entry in the routing table
Update(...EntryOption) error Update(...RouteOption) error
// Lookup queries the routing table and returns matching entries // Lookup queries the routing table and returns matching entries
Lookup(Query) ([]*Entry, error) Lookup(Query) ([]*Route, error)
// Table returns routing table // Table returns routing table
Table() Table Table() Table
// Address returns the router bind adddress // Address returns the router bind adddress
@ -34,8 +34,8 @@ type RIB interface {
// Option used by the router // Option used by the router
type Option func(*Options) type Option func(*Options)
// EntryOption is used to define routing entry options // RouteOption is used to define routing table entry options
type EntryOption func(*EntryOptions) type RouteOption func(*RouteOptions)
// QueryOption is used to define query options // QueryOption is used to define query options
type QueryOption func(*QueryOptions) type QueryOption func(*QueryOptions)

View File

@ -3,6 +3,7 @@ package router
import ( import (
"errors" "errors"
"fmt" "fmt"
"hash"
"hash/fnv" "hash/fnv"
"strings" "strings"
"sync" "sync"
@ -22,13 +23,13 @@ var (
// Table is routing table // Table is routing table
type Table interface { type Table interface {
// Add adds new route to the table // Add adds new route to the table
Add(Entry) error Add(Route) error
// Remove removes route from the table // Remove removes route from the table
Remove(Entry) error Remove(Route) error
// Update updates route in the table // Update updates route in the table
Update(...EntryOption) error Update(...RouteOption) error
// Lookup looks up routes in the table // Lookup looks up routes in the table
Lookup(Query) ([]Entry, error) Lookup(Query) ([]Route, error)
// Size returns the size of the table // Size returns the size of the table
Size() int Size() int
// String prints the routing table // String prints the routing table
@ -39,35 +40,37 @@ type Table interface {
// It maps service name to routes // It maps service name to routes
type table struct { type table struct {
// m stores routing table map // m stores routing table map
m map[string]map[uint64]Entry m map[uint64]Route
// h is a hasher hashes route entries
h hash.Hash64
sync.RWMutex sync.RWMutex
} }
// NewTable creates new routing table and returns it // NewTable creates new routing table and returns it
func NewTable() Table { func NewTable() Table {
h := fnv.New64()
h.Reset()
return &table{ return &table{
m: make(map[string]map[uint64]Entry), m: make(map[uint64]Route),
h: h,
} }
} }
// Add adds new routing entry // Add adds new routing entry
func (t *table) Add(e Entry) error { func (t *table) Add(r Route) error {
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
destAddr := e.Options().DestAddr sum := t.hash(r)
h := fnv.New64()
h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address()))
if _, ok := t.m[destAddr]; !ok { if _, ok := t.m[sum]; !ok {
// create new map for DestAddr routes t.m[sum] = r
t.m[destAddr] = make(map[uint64]Entry)
t.m[destAddr][h.Sum64()] = e
return nil return nil
} }
if _, ok := t.m[destAddr][h.Sum64()]; ok && e.Options().Policy == OverrideIfExists { if _, ok := t.m[sum]; ok && r.Options().Policy == OverrideIfExists {
t.m[destAddr][h.Sum64()] = e t.m[sum] = r
return nil return nil
} }
@ -75,41 +78,36 @@ func (t *table) Add(e Entry) error {
} }
// Remove removes entry from the routing table // Remove removes entry from the routing table
func (t *table) Remove(e Entry) error { func (t *table) Remove(r Route) error {
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
destAddr := e.Options().DestAddr sum := t.hash(r)
h := fnv.New64()
h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address()))
if _, ok := t.m[destAddr]; !ok { if _, ok := t.m[sum]; !ok {
return ErrRouteNotFound return ErrRouteNotFound
} else {
delete(t.m[destAddr], h.Sum64())
return nil
} }
delete(t.m, sum)
return nil return nil
} }
// Update updates routing entry // Update updates routing entry
func (t *table) Update(opts ...EntryOption) error { func (t *table) Update(opts ...RouteOption) error {
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
e := NewEntry(opts...) r := NewRoute(opts...)
destAddr := e.Options().DestAddr sum := t.hash(r)
h := fnv.New64()
h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address()))
if _, ok := t.m[destAddr]; !ok { if _, ok := t.m[sum]; !ok {
return ErrRouteNotFound return ErrRouteNotFound
} }
if _, ok := t.m[destAddr][h.Sum64()]; ok { if _, ok := t.m[sum]; ok {
t.m[destAddr][h.Sum64()] = e t.m[sum] = r
return nil return nil
} }
@ -117,7 +115,7 @@ func (t *table) Update(opts ...EntryOption) error {
} }
// Lookup looks up entry in the routing table // Lookup looks up entry in the routing table
func (t *table) Lookup(q Query) ([]Entry, error) { func (t *table) Lookup(q Query) ([]Route, error) {
return nil, ErrNotImplemented return nil, ErrNotImplemented
} }
@ -141,25 +139,26 @@ func (t *table) String() string {
table := tablewriter.NewWriter(sb) table := tablewriter.NewWriter(sb)
table.SetHeader([]string{"Dest", "Hop", "Src", "Metric"}) table.SetHeader([]string{"Dest", "Hop", "Src", "Metric"})
var destAddr, prevAddr string for _, route := range t.m {
strRoute := []string{
for _, entries := range t.m { route.Options().DestAddr,
for _, entry := range entries { route.Options().Hop.Address(),
destAddr = entry.Options().DestAddr fmt.Sprintf("%d", route.Options().SrcAddr),
// we want to avoid printing the same dest address fmt.Sprintf("%d", route.Options().Metric),
if prevAddr == destAddr {
destAddr = ""
}
strEntry := []string{
destAddr,
entry.Options().Hop.Address(),
fmt.Sprintf("%d", entry.Options().SrcAddr),
fmt.Sprintf("%d", entry.Options().Metric),
}
table.Append(strEntry)
prevAddr = destAddr
} }
table.Append(strRoute)
} }
return sb.String() return sb.String()
} }
func (t *table) hash(r Route) uint64 {
srcAddr := r.Options().SrcAddr
destAddr := r.Options().DestAddr
routerAddr := r.Options().Hop.Address()
t.h.Reset()
t.h.Write([]byte(srcAddr + destAddr + routerAddr))
return t.h.Sum64()
}