2019-07-26 01:19:05 +03:00
|
|
|
package router
|
2019-06-18 20:33:05 +03:00
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupOption sets routing table query options
|
|
|
|
type LookupOption func(*LookupOptions)
|
2019-06-13 14:09:49 +03:00
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupOptions are routing table query options
|
2020-08-15 01:51:52 +03:00
|
|
|
// TODO replace with Filter(Route) bool
|
2020-08-21 11:23:01 +03:00
|
|
|
type LookupOptions struct {
|
2019-10-09 19:13:52 +03:00
|
|
|
// Address of the service
|
|
|
|
Address string
|
2019-07-09 17:45:42 +03:00
|
|
|
// Gateway is route gateway
|
|
|
|
Gateway string
|
2019-06-19 23:22:14 +03:00
|
|
|
// Network is network address
|
2019-06-13 00:30:42 +03:00
|
|
|
Network string
|
2019-08-28 01:08:35 +03:00
|
|
|
// Router is router id
|
|
|
|
Router string
|
2020-08-15 01:51:52 +03:00
|
|
|
// Link to query
|
|
|
|
Link string
|
2019-06-07 01:29:24 +03:00
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupAddress sets service to query
|
|
|
|
func LookupAddress(a string) LookupOption {
|
|
|
|
return func(o *LookupOptions) {
|
2019-10-09 19:13:52 +03:00
|
|
|
o.Address = a
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupGateway sets gateway address to query
|
|
|
|
func LookupGateway(g string) LookupOption {
|
|
|
|
return func(o *LookupOptions) {
|
2019-07-09 17:45:42 +03:00
|
|
|
o.Gateway = g
|
2019-06-07 01:29:24 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupNetwork sets network name to query
|
|
|
|
func LookupNetwork(n string) LookupOption {
|
|
|
|
return func(o *LookupOptions) {
|
2019-07-09 17:45:42 +03:00
|
|
|
o.Network = n
|
2019-06-19 23:22:14 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupRouter sets router id to query
|
|
|
|
func LookupRouter(r string) LookupOption {
|
|
|
|
return func(o *LookupOptions) {
|
2019-08-28 01:08:35 +03:00
|
|
|
o.Router = r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// LookupLink sets the link to query
|
|
|
|
func LookupLink(link string) LookupOption {
|
|
|
|
return func(o *LookupOptions) {
|
2020-08-15 01:51:52 +03:00
|
|
|
o.Link = link
|
2020-01-16 15:48:36 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 11:23:01 +03:00
|
|
|
// NewLookup creates new query and returns it
|
|
|
|
func NewLookup(opts ...LookupOption) LookupOptions {
|
2019-06-13 00:30:42 +03:00
|
|
|
// default options
|
2020-08-21 11:23:01 +03:00
|
|
|
qopts := LookupOptions{
|
2020-08-15 01:51:52 +03:00
|
|
|
Address: "*",
|
|
|
|
Gateway: "*",
|
|
|
|
Network: "*",
|
|
|
|
Router: "*",
|
|
|
|
Link: DefaultLink,
|
2019-06-13 00:30:42 +03:00
|
|
|
}
|
2019-06-07 01:29:24 +03:00
|
|
|
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&qopts)
|
|
|
|
}
|
|
|
|
|
2019-10-09 19:13:52 +03:00
|
|
|
return qopts
|
2019-06-07 01:29:24 +03:00
|
|
|
}
|
2020-08-21 11:23:01 +03:00
|
|
|
|
|
|
|
// isMatch checks if the route matches given query options
|
|
|
|
func isMatch(route Route, address, gateway, network, rtr, link string) bool {
|
|
|
|
// matches the values provided
|
|
|
|
match := func(a, b string) bool {
|
|
|
|
if a == "*" || b == "*" || a == b {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// a simple struct to hold our values
|
|
|
|
type compare struct {
|
|
|
|
a string
|
|
|
|
b string
|
|
|
|
}
|
|
|
|
|
|
|
|
// compare the following values
|
|
|
|
values := []compare{
|
|
|
|
{gateway, route.Gateway},
|
|
|
|
{network, route.Network},
|
|
|
|
{rtr, route.Router},
|
|
|
|
{address, route.Address},
|
|
|
|
{link, route.Link},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range values {
|
|
|
|
// attempt to match each value
|
|
|
|
if !match(v.a, v.b) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// filterRoutes finds all the routes for given network and router and returns them
|
|
|
|
func Filter(routes []Route, opts LookupOptions) []Route {
|
|
|
|
address := opts.Address
|
|
|
|
gateway := opts.Gateway
|
|
|
|
network := opts.Network
|
|
|
|
rtr := opts.Router
|
|
|
|
link := opts.Link
|
|
|
|
|
|
|
|
// routeMap stores the routes we're going to advertise
|
|
|
|
routeMap := make(map[string][]Route)
|
|
|
|
|
|
|
|
for _, route := range routes {
|
|
|
|
if isMatch(route, address, gateway, network, rtr, link) {
|
|
|
|
// add matchihg route to the routeMap
|
|
|
|
routeKey := route.Service + "@" + route.Network
|
|
|
|
routeMap[routeKey] = append(routeMap[routeKey], route)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var results []Route
|
|
|
|
|
|
|
|
for _, route := range routeMap {
|
|
|
|
results = append(results, route...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return results
|
|
|
|
}
|