mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-09-26 02:21:03 +02:00
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package routing
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
type routeSyncer struct {
|
|
routeTableStateMap map[string]*netlink.Route
|
|
injectedRoutesSyncPeriod time.Duration
|
|
mutex sync.Mutex
|
|
routeReplacer func(route *netlink.Route) error
|
|
}
|
|
|
|
// addInjectedRoute adds a route to the route map that is regularly synced to the kernel's routing table
|
|
func (rs *routeSyncer) addInjectedRoute(dst *net.IPNet, route *netlink.Route) {
|
|
rs.mutex.Lock()
|
|
defer rs.mutex.Unlock()
|
|
klog.V(3).Infof("Adding route for destination: %s", dst)
|
|
rs.routeTableStateMap[dst.String()] = route
|
|
}
|
|
|
|
// delInjectedRoute delete a route from the route map that is regularly synced to the kernel's routing table
|
|
func (rs *routeSyncer) delInjectedRoute(dst *net.IPNet) {
|
|
rs.mutex.Lock()
|
|
defer rs.mutex.Unlock()
|
|
if _, ok := rs.routeTableStateMap[dst.String()]; ok {
|
|
klog.V(3).Infof("Removing route for destination: %s", dst)
|
|
delete(rs.routeTableStateMap, dst.String())
|
|
}
|
|
}
|
|
|
|
// syncLocalRouteTable iterates over the local route state map and syncs all routes to the kernel's routing table
|
|
func (rs *routeSyncer) syncLocalRouteTable() {
|
|
rs.mutex.Lock()
|
|
defer rs.mutex.Unlock()
|
|
klog.V(2).Infof("Running local route table synchronization")
|
|
for _, route := range rs.routeTableStateMap {
|
|
klog.V(3).Infof("Syncing route: %s -> %s via %s", route.Src, route.Dst, route.Gw)
|
|
err := rs.routeReplacer(route)
|
|
if err != nil {
|
|
klog.Errorf("Route could not be replaced due to : " + err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
// run starts a goroutine that calls syncLocalRouteTable on interval injectedRoutesSyncPeriod
|
|
func (rs *routeSyncer) run(stopCh <-chan struct{}, wg *sync.WaitGroup) {
|
|
// Start route synchronization routine
|
|
wg.Add(1)
|
|
go func(stopCh <-chan struct{}, wg *sync.WaitGroup) {
|
|
defer wg.Done()
|
|
t := time.NewTicker(rs.injectedRoutesSyncPeriod)
|
|
defer t.Stop()
|
|
for {
|
|
select {
|
|
case <-t.C:
|
|
rs.syncLocalRouteTable()
|
|
case <-stopCh:
|
|
klog.Infof("Shutting down local route synchronization")
|
|
return
|
|
}
|
|
}
|
|
}(stopCh, wg)
|
|
}
|
|
|
|
// newRouteSyncer creates a new routeSyncer that, when run, will sync routes kept in its local state table every
|
|
// syncPeriod
|
|
func newRouteSyncer(syncPeriod time.Duration) *routeSyncer {
|
|
rs := routeSyncer{}
|
|
rs.routeTableStateMap = make(map[string]*netlink.Route)
|
|
rs.injectedRoutesSyncPeriod = syncPeriod
|
|
rs.mutex = sync.Mutex{}
|
|
// We substitute the RouteReplace function here so that we can easily monkey patch it in our unit tests
|
|
rs.routeReplacer = netlink.RouteReplace
|
|
return &rs
|
|
}
|