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.
// 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)
}
// Remove removes entry from the routing table.
// 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)
}
// 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.
func (r *router) Update(opts ...EntryOption) error {
func (r *router) Update(opts ...RouteOption) error {
return r.table.Update(opts...)
}
// 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
}

View File

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

View File

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

View File

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

View File

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