2019-06-06 23:29:24 +01:00
|
|
|
package router
|
|
|
|
|
2019-06-26 16:03:19 +01:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/olekukonko/tablewriter"
|
|
|
|
)
|
|
|
|
|
2019-06-09 23:09:38 +01:00
|
|
|
// LookupPolicy defines query policy
|
|
|
|
type LookupPolicy int
|
2019-06-06 23:29:24 +01:00
|
|
|
|
|
|
|
const (
|
2019-06-26 16:03:19 +01:00
|
|
|
// DiscardIfNone discards query when no route is found
|
|
|
|
DiscardIfNone LookupPolicy = iota
|
2019-06-09 23:09:38 +01:00
|
|
|
// ClosestMatch returns closest match to supplied query
|
2019-06-06 23:29:24 +01:00
|
|
|
ClosestMatch
|
|
|
|
)
|
|
|
|
|
2019-06-18 18:33:05 +01:00
|
|
|
// String returns human representation of LookupPolicy
|
|
|
|
func (lp LookupPolicy) String() string {
|
|
|
|
switch lp {
|
2019-06-26 16:03:19 +01:00
|
|
|
case DiscardIfNone:
|
2019-06-18 18:33:05 +01:00
|
|
|
return "DISCARD"
|
|
|
|
case ClosestMatch:
|
|
|
|
return "CLOSEST"
|
|
|
|
default:
|
|
|
|
return "UNKNOWN"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:28:47 +02:00
|
|
|
// QueryOption sets routing table query options
|
2019-06-13 12:09:49 +01:00
|
|
|
type QueryOption func(*QueryOptions)
|
|
|
|
|
2019-06-13 23:28:47 +02:00
|
|
|
// QueryOptions are routing table query options
|
2019-06-06 23:29:24 +01:00
|
|
|
type QueryOptions struct {
|
2019-06-19 21:22:14 +01:00
|
|
|
// Destination is destination address
|
|
|
|
Destination string
|
2019-06-26 16:03:19 +01:00
|
|
|
// Router is router address
|
|
|
|
Router string
|
2019-06-19 21:22:14 +01:00
|
|
|
// Network is network address
|
2019-06-12 22:30:42 +01:00
|
|
|
Network string
|
2019-06-19 21:22:14 +01:00
|
|
|
// Metric is route metric
|
|
|
|
Metric int
|
2019-06-13 23:28:47 +02:00
|
|
|
// Policy is query lookup policy
|
2019-06-09 23:09:38 +01:00
|
|
|
Policy LookupPolicy
|
2019-06-06 23:29:24 +01:00
|
|
|
}
|
|
|
|
|
2019-06-19 21:22:14 +01:00
|
|
|
// QueryDestination sets query destination address
|
|
|
|
func QueryDestination(a string) QueryOption {
|
2019-06-06 23:29:24 +01:00
|
|
|
return func(o *QueryOptions) {
|
2019-06-19 21:22:14 +01:00
|
|
|
o.Destination = a
|
2019-06-06 23:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-12 22:30:42 +01:00
|
|
|
// QueryNetwork sets query network address
|
|
|
|
func QueryNetwork(a string) QueryOption {
|
2019-06-06 23:29:24 +01:00
|
|
|
return func(o *QueryOptions) {
|
2019-06-12 22:30:42 +01:00
|
|
|
o.Network = a
|
2019-06-06 23:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-19 21:22:14 +01:00
|
|
|
// QueryRouter sets query gateway address
|
2019-06-26 16:03:19 +01:00
|
|
|
func QueryRouter(r string) QueryOption {
|
2019-06-16 23:09:59 +01:00
|
|
|
return func(o *QueryOptions) {
|
2019-06-19 21:22:14 +01:00
|
|
|
o.Router = r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// QueryMetric sets query metric
|
|
|
|
func QueryMetric(m int) QueryOption {
|
|
|
|
return func(o *QueryOptions) {
|
|
|
|
o.Metric = m
|
2019-06-16 23:09:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:28:47 +02:00
|
|
|
// QueryPolicy sets query policy
|
2019-06-19 21:22:14 +01:00
|
|
|
// NOTE: this might be renamed to filter or some such
|
2019-06-12 22:30:42 +01:00
|
|
|
func QueryPolicy(p LookupPolicy) QueryOption {
|
2019-06-09 23:19:56 +01:00
|
|
|
return func(o *QueryOptions) {
|
2019-06-12 22:30:42 +01:00
|
|
|
o.Policy = p
|
2019-06-09 23:19:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:28:47 +02:00
|
|
|
// Query is routing table query
|
2019-06-06 23:29:24 +01:00
|
|
|
type Query interface {
|
|
|
|
// Options returns query options
|
|
|
|
Options() QueryOptions
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:28:47 +02:00
|
|
|
// query is a basic implementation of Query
|
2019-06-06 23:29:24 +01:00
|
|
|
type query struct {
|
|
|
|
opts QueryOptions
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewQuery creates new query and returns it
|
|
|
|
func NewQuery(opts ...QueryOption) Query {
|
2019-06-12 22:30:42 +01:00
|
|
|
// default options
|
2019-06-19 21:22:14 +01:00
|
|
|
// NOTE: by default we use DefaultNetworkMetric
|
2019-06-12 22:30:42 +01:00
|
|
|
qopts := QueryOptions{
|
2019-06-19 21:22:14 +01:00
|
|
|
Destination: "*",
|
2019-06-26 16:03:19 +01:00
|
|
|
Router: "*",
|
2019-06-19 21:22:14 +01:00
|
|
|
Network: "*",
|
|
|
|
Metric: DefaultNetworkMetric,
|
2019-06-26 16:03:19 +01:00
|
|
|
Policy: DiscardIfNone,
|
2019-06-12 22:30:42 +01:00
|
|
|
}
|
2019-06-06 23:29:24 +01:00
|
|
|
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&qopts)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &query{
|
|
|
|
opts: qopts,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Options returns query options
|
|
|
|
func (q *query) Options() QueryOptions {
|
|
|
|
return q.opts
|
|
|
|
}
|
2019-06-26 16:03:19 +01:00
|
|
|
|
|
|
|
// String prints routing table query in human readable form
|
|
|
|
func (q query) String() string {
|
|
|
|
// this will help us build routing table string
|
|
|
|
sb := &strings.Builder{}
|
|
|
|
|
|
|
|
// create nice table printing structure
|
|
|
|
table := tablewriter.NewWriter(sb)
|
|
|
|
table.SetHeader([]string{"Destination", "Router", "Network", "Metric", "Policy"})
|
|
|
|
|
|
|
|
strQuery := []string{
|
|
|
|
q.opts.Destination,
|
|
|
|
q.opts.Router,
|
|
|
|
q.opts.Network,
|
|
|
|
fmt.Sprintf("%d", q.opts.Metric),
|
|
|
|
fmt.Sprintf("%s", q.opts.Policy),
|
|
|
|
}
|
|
|
|
table.Append(strQuery)
|
|
|
|
|
|
|
|
// render table into sb
|
|
|
|
table.Render()
|
|
|
|
|
|
|
|
return sb.String()
|
|
|
|
}
|