mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-07 22:39:14 +02:00
In case the route management feature is not supported then do not create unnecessary firewall and manager instances. This can happen if the nftables nor iptables is not available on the host OS. - Move the error handling to upper layer - Remove fake, useless implementations of interfaces - Update go-iptables because In Docker the old version can not determine well the path of executable file - update lib to 0.70
126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
//go:build !android
|
|
|
|
package routemanager
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/netbirdio/netbird/iface"
|
|
"github.com/netbirdio/netbird/route"
|
|
)
|
|
|
|
type defaultServerRouter struct {
|
|
mux sync.Mutex
|
|
ctx context.Context
|
|
routes map[string]*route.Route
|
|
firewall firewallManager
|
|
wgInterface *iface.WGIface
|
|
}
|
|
|
|
func newServerRouter(ctx context.Context, wgInterface *iface.WGIface) (serverRouter, error) {
|
|
firewall, err := NewFirewall(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &defaultServerRouter{
|
|
ctx: ctx,
|
|
routes: make(map[string]*route.Route),
|
|
firewall: firewall,
|
|
wgInterface: wgInterface,
|
|
}, nil
|
|
}
|
|
|
|
func (m *defaultServerRouter) updateRoutes(routesMap map[string]*route.Route) error {
|
|
serverRoutesToRemove := make([]string, 0)
|
|
|
|
if len(routesMap) > 0 {
|
|
err := m.firewall.RestoreOrCreateContainers()
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't initialize firewall containers, got err: %v", err)
|
|
}
|
|
}
|
|
|
|
for routeID := range m.routes {
|
|
update, found := routesMap[routeID]
|
|
if !found || !update.IsEqual(m.routes[routeID]) {
|
|
serverRoutesToRemove = append(serverRoutesToRemove, routeID)
|
|
}
|
|
}
|
|
|
|
for _, routeID := range serverRoutesToRemove {
|
|
oldRoute := m.routes[routeID]
|
|
err := m.removeFromServerNetwork(oldRoute)
|
|
if err != nil {
|
|
log.Errorf("unable to remove route id: %s, network %s, from server, got: %v",
|
|
oldRoute.ID, oldRoute.Network, err)
|
|
}
|
|
delete(m.routes, routeID)
|
|
}
|
|
|
|
for id, newRoute := range routesMap {
|
|
_, found := m.routes[id]
|
|
if found {
|
|
continue
|
|
}
|
|
|
|
err := m.addToServerNetwork(newRoute)
|
|
if err != nil {
|
|
log.Errorf("unable to add route %s from server, got: %v", newRoute.ID, err)
|
|
continue
|
|
}
|
|
m.routes[id] = newRoute
|
|
}
|
|
|
|
if len(m.routes) > 0 {
|
|
err := enableIPForwarding()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *defaultServerRouter) removeFromServerNetwork(route *route.Route) error {
|
|
select {
|
|
case <-m.ctx.Done():
|
|
log.Infof("not removing from server network because context is done")
|
|
return m.ctx.Err()
|
|
default:
|
|
m.mux.Lock()
|
|
defer m.mux.Unlock()
|
|
err := m.firewall.RemoveRoutingRules(routeToRouterPair(m.wgInterface.Address().String(), route))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
delete(m.routes, route.ID)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (m *defaultServerRouter) addToServerNetwork(route *route.Route) error {
|
|
select {
|
|
case <-m.ctx.Done():
|
|
log.Infof("not adding to server network because context is done")
|
|
return m.ctx.Err()
|
|
default:
|
|
m.mux.Lock()
|
|
defer m.mux.Unlock()
|
|
err := m.firewall.InsertRoutingRules(routeToRouterPair(m.wgInterface.Address().String(), route))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
m.routes[route.ID] = route
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (m *defaultServerRouter) cleanUp() {
|
|
m.firewall.CleanRoutingRules()
|
|
}
|