mirror of
https://github.com/luscis/openlan.git
synced 2025-10-11 03:20:06 +08:00
fix: vxlan support openvpn
This commit is contained in:
@@ -50,7 +50,7 @@ networks:
|
|||||||
# docker exec -it powerdns_auth_1 bash
|
# docker exec -it powerdns_auth_1 bash
|
||||||
## ZONE
|
## ZONE
|
||||||
# pdnsutil create-zone luscis.io
|
# pdnsutil create-zone luscis.io
|
||||||
# pdnsutil add-record luscis.io @ NS admin.ns.luscis.io
|
# pdnsutil add-record luscis.io @ NS ns1.luscis.io
|
||||||
|
|
||||||
## A
|
## A
|
||||||
# pdnsutil add-record luscis.io a0 A 192.168.0.88
|
# pdnsutil add-record luscis.io a0 A 192.168.0.88
|
||||||
@@ -58,13 +58,13 @@ networks:
|
|||||||
|
|
||||||
## A
|
## A
|
||||||
# pdnsutil create-zone jump.io
|
# pdnsutil create-zone jump.io
|
||||||
# pdnsutil add-record jump.io @ NS admin.ns.jump.io
|
# pdnsutil add-record jump.io @ NS ns1.jump.io
|
||||||
# pdnsutil add-record jump.io a86 A 192.168.0.86
|
# pdnsutil add-record jump.io a86 A 192.168.0.86
|
||||||
|
|
||||||
|
|
||||||
## PTR
|
## PTR
|
||||||
# pdnsutil create-zone 168.192.in-addr.arpa
|
# pdnsutil create-zone 168.192.in-addr.arpa
|
||||||
# pdnsutil add-record 168.192.in-addr.arpa 84.0 PTR a0.luscis.io
|
# pdnsutil add-record 168.192.in-addr.arpa 84.0 PTR a0.luscis.io
|
||||||
# pdnsutil add-record 168.192.in-addr.arpa @ NS admin.ns.168.192.in-addr.arpa
|
# pdnsutil add-record 168.192.in-addr.arpa @ NS ns1.168.192.in-addr.arpa
|
||||||
# pdnsutil list-zone 168.192.in-addr.arpa
|
# pdnsutil list-zone 168.192.in-addr.arpa
|
||||||
|
|
||||||
|
@@ -50,6 +50,7 @@ type Networker interface {
|
|||||||
Reload(v Switcher)
|
Reload(v Switcher)
|
||||||
Provider() string
|
Provider() string
|
||||||
ZTruster() ZTruster
|
ZTruster() ZTruster
|
||||||
|
IfAddr() string
|
||||||
}
|
}
|
||||||
|
|
||||||
var workers = make(map[string]Networker)
|
var workers = make(map[string]Networker)
|
||||||
|
@@ -5,12 +5,16 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/luscis/openlan/pkg/api"
|
"github.com/luscis/openlan/pkg/api"
|
||||||
|
"github.com/luscis/openlan/pkg/cache"
|
||||||
co "github.com/luscis/openlan/pkg/config"
|
co "github.com/luscis/openlan/pkg/config"
|
||||||
"github.com/luscis/openlan/pkg/libol"
|
"github.com/luscis/openlan/pkg/libol"
|
||||||
|
"github.com/luscis/openlan/pkg/models"
|
||||||
cn "github.com/luscis/openlan/pkg/network"
|
cn "github.com/luscis/openlan/pkg/network"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
|
nl "github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewNetworker(c *co.Network) api.Networker {
|
func NewNetworker(c *co.Network) api.Networker {
|
||||||
@@ -64,6 +68,34 @@ func (w *WorkerImpl) Provider() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) Initialize() {
|
func (w *WorkerImpl) Initialize() {
|
||||||
|
n := models.Network{
|
||||||
|
Name: w.cfg.Name,
|
||||||
|
IpStart: w.cfg.Subnet.Start,
|
||||||
|
IpEnd: w.cfg.Subnet.End,
|
||||||
|
Netmask: w.cfg.Subnet.Netmask,
|
||||||
|
IfAddr: w.cfg.Bridge.Address,
|
||||||
|
Routes: make([]*models.Route, 0, 2),
|
||||||
|
}
|
||||||
|
for _, rt := range w.cfg.Routes {
|
||||||
|
if rt.NextHop == "" {
|
||||||
|
w.out.Warn("WorkerImpl.Initialize: %s noNextHop", rt.Prefix)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
rte := models.NewRoute(rt.Prefix, w.IfAddr(), rt.Mode)
|
||||||
|
if rt.Metric > 0 {
|
||||||
|
rte.Metric = rt.Metric
|
||||||
|
}
|
||||||
|
if rt.NextHop != "" {
|
||||||
|
rte.Origin = rt.NextHop
|
||||||
|
}
|
||||||
|
n.Routes = append(n.Routes, rte)
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.Network.Add(&n)
|
||||||
|
|
||||||
|
w.updateVPN()
|
||||||
|
w.createVPN()
|
||||||
|
|
||||||
if w.cfg.Dhcp == "enable" {
|
if w.cfg.Dhcp == "enable" {
|
||||||
w.dhcp = NewDhcp(&co.Dhcp{
|
w.dhcp = NewDhcp(&co.Dhcp{
|
||||||
Name: w.cfg.Name,
|
Name: w.cfg.Name,
|
||||||
@@ -71,18 +103,23 @@ func (w *WorkerImpl) Initialize() {
|
|||||||
Bridge: w.cfg.Bridge,
|
Bridge: w.cfg.Bridge,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
w.fire = cn.NewFireWallTable(w.cfg.Name)
|
w.fire = cn.NewFireWallTable(w.cfg.Name)
|
||||||
|
|
||||||
if out, err := w.setV.Clear(); err != nil {
|
if out, err := w.setV.Clear(); err != nil {
|
||||||
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
||||||
}
|
}
|
||||||
if out, err := w.setR.Clear(); err != nil {
|
if out, err := w.setR.Clear(); err != nil {
|
||||||
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
||||||
}
|
}
|
||||||
w.newVPN()
|
|
||||||
if w.cfg.ZTrust == "enable" {
|
if w.cfg.ZTrust == "enable" {
|
||||||
w.ztrust = NewZTrust(w.cfg.Name, 30)
|
w.ztrust = NewZTrust(w.cfg.Name, 30)
|
||||||
w.ztrust.Initialize()
|
w.ztrust.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.forwardSubnet()
|
||||||
|
w.forwardVPN()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) AddPhysical(bridge string, vlan int, output string) {
|
func (w *WorkerImpl) AddPhysical(bridge string, vlan int, output string) {
|
||||||
@@ -167,21 +204,70 @@ func (w *WorkerImpl) AddOutput(bridge string, port *LinuxPort) {
|
|||||||
w.AddPhysical(bridge, port.vlan, port.link)
|
w.AddPhysical(bridge, port.vlan, port.link)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) loadRoutes() {
|
||||||
|
// install routes
|
||||||
|
cfg := w.cfg
|
||||||
|
w.out.Debug("WorkerImpl.LoadRoute: %v", cfg.Routes)
|
||||||
|
ifAddr := w.IfAddr()
|
||||||
|
for _, rt := range cfg.Routes {
|
||||||
|
_, dst, err := net.ParseCIDR(rt.Prefix)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ifAddr == rt.NextHop && rt.MultiPath == nil {
|
||||||
|
// route's next-hop is local not install again.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nlrt := nl.Route{Dst: dst}
|
||||||
|
for _, hop := range rt.MultiPath {
|
||||||
|
nxhe := &nl.NexthopInfo{
|
||||||
|
Hops: hop.Weight,
|
||||||
|
Gw: net.ParseIP(hop.NextHop),
|
||||||
|
}
|
||||||
|
nlrt.MultiPath = append(nlrt.MultiPath, nxhe)
|
||||||
|
}
|
||||||
|
if rt.MultiPath == nil {
|
||||||
|
nlrt.Gw = net.ParseIP(rt.NextHop)
|
||||||
|
nlrt.Priority = rt.Metric
|
||||||
|
}
|
||||||
|
w.out.Debug("WorkerImpl.LoadRoute: %s", nlrt.String())
|
||||||
|
promise := &libol.Promise{
|
||||||
|
First: time.Second * 2,
|
||||||
|
MaxInt: time.Minute,
|
||||||
|
MinInt: time.Second * 10,
|
||||||
|
}
|
||||||
|
rt_c := rt
|
||||||
|
promise.Go(func() error {
|
||||||
|
if err := nl.RouteReplace(&nlrt); err != nil {
|
||||||
|
w.out.Warn("WorkerImpl.LoadRoute: %v %s", nlrt, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.out.Info("WorkerImpl.LoadRoute: %v success", rt_c.String())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) Start(v api.Switcher) {
|
func (w *WorkerImpl) Start(v api.Switcher) {
|
||||||
cfg, vpn := w.GetCfgs()
|
cfg, vpn := w.GetCfgs()
|
||||||
fire := w.fire
|
fire := w.fire
|
||||||
|
|
||||||
w.out.Info("WorkerImpl.Start")
|
w.out.Info("WorkerImpl.Start")
|
||||||
|
|
||||||
|
w.loadRoutes()
|
||||||
|
|
||||||
if cfg.Acl != "" {
|
if cfg.Acl != "" {
|
||||||
fire.Mangle.Pre.AddRule(cn.IpRule{
|
fire.Mangle.Pre.AddRule(cn.IpRule{
|
||||||
Input: cfg.Bridge.Name,
|
Input: cfg.Bridge.Name,
|
||||||
Jump: cfg.Acl,
|
Jump: cfg.Acl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fire.Filter.For.AddRule(cn.IpRule{
|
fire.Filter.For.AddRule(cn.IpRule{
|
||||||
Input: cfg.Bridge.Name,
|
Input: cfg.Bridge.Name,
|
||||||
Output: cfg.Bridge.Name,
|
Output: cfg.Bridge.Name,
|
||||||
})
|
})
|
||||||
|
|
||||||
if cfg.Bridge.Mss > 0 {
|
if cfg.Bridge.Mss > 0 {
|
||||||
// forward to remote
|
// forward to remote
|
||||||
fire.Mangle.Post.AddRule(cn.IpRule{
|
fire.Mangle.Post.AddRule(cn.IpRule{
|
||||||
@@ -202,6 +288,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
|||||||
SetMss: cfg.Bridge.Mss,
|
SetMss: cfg.Bridge.Mss,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, output := range cfg.Outputs {
|
for _, output := range cfg.Outputs {
|
||||||
port := &LinuxPort{
|
port := &LinuxPort{
|
||||||
name: output.Interface,
|
name: output.Interface,
|
||||||
@@ -210,6 +297,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
|||||||
w.AddOutput(cfg.Bridge.Name, port)
|
w.AddOutput(cfg.Bridge.Name, port)
|
||||||
w.outputs = append(w.outputs, port)
|
w.outputs = append(w.outputs, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(w.dhcp == nil) {
|
if !(w.dhcp == nil) {
|
||||||
w.dhcp.Start()
|
w.dhcp.Start()
|
||||||
fire.Nat.Post.AddRule(cn.IpRule{
|
fire.Nat.Post.AddRule(cn.IpRule{
|
||||||
@@ -219,6 +307,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
|||||||
Comment: "Default Gateway for DHCP",
|
Comment: "Default Gateway for DHCP",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(w.vpn == nil) {
|
if !(w.vpn == nil) {
|
||||||
w.vpn.Start()
|
w.vpn.Start()
|
||||||
}
|
}
|
||||||
@@ -236,6 +325,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
|||||||
Comment: "Goto Zero Trust",
|
Comment: "Goto Zero Trust",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fire.Start()
|
fire.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,24 +375,53 @@ func (w *WorkerImpl) DelOutput(bridge string, port *LinuxPort) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) unloadRoutes() {
|
||||||
|
cfg := w.cfg
|
||||||
|
for _, rt := range cfg.Routes {
|
||||||
|
_, dst, err := net.ParseCIDR(rt.Prefix)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nlRt := nl.Route{Dst: dst}
|
||||||
|
if rt.MultiPath == nil {
|
||||||
|
nlRt.Gw = net.ParseIP(rt.NextHop)
|
||||||
|
nlRt.Priority = rt.Metric
|
||||||
|
}
|
||||||
|
w.out.Debug("WorkerImpl.UnLoadRoute: %s", nlRt.String())
|
||||||
|
if err := nl.RouteDel(&nlRt); err != nil {
|
||||||
|
w.out.Warn("WorkerImpl.UnLoadRoute: %s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w.out.Info("WorkerImpl.UnLoadRoute: %v", rt.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) Stop() {
|
func (w *WorkerImpl) Stop() {
|
||||||
w.out.Info("WorkerImpl.Stop")
|
w.out.Info("WorkerImpl.Stop")
|
||||||
|
|
||||||
w.fire.Stop()
|
w.fire.Stop()
|
||||||
|
|
||||||
if !(w.vpn == nil || w.ztrust == nil) {
|
if !(w.vpn == nil || w.ztrust == nil) {
|
||||||
w.ztrust.Stop()
|
w.ztrust.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(w.vpn == nil) {
|
if !(w.vpn == nil) {
|
||||||
w.vpn.Stop()
|
w.vpn.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(w.dhcp == nil) {
|
if !(w.dhcp == nil) {
|
||||||
w.dhcp.Stop()
|
w.dhcp.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, output := range w.outputs {
|
for _, output := range w.outputs {
|
||||||
w.DelOutput(w.cfg.Bridge.Name, output)
|
w.DelOutput(w.cfg.Bridge.Name, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.outputs = nil
|
w.outputs = nil
|
||||||
w.setR.Destroy()
|
w.setR.Destroy()
|
||||||
w.setV.Destroy()
|
w.setV.Destroy()
|
||||||
|
|
||||||
|
w.unloadRoutes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) String() string {
|
func (w *WorkerImpl) String() string {
|
||||||
@@ -322,6 +441,27 @@ func (w *WorkerImpl) Config() *co.Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) Subnet() string {
|
func (w *WorkerImpl) Subnet() string {
|
||||||
|
cfg := w.cfg
|
||||||
|
|
||||||
|
ipAddr := cfg.Bridge.Address
|
||||||
|
ipMask := cfg.Subnet.Netmask
|
||||||
|
if ipAddr == "" {
|
||||||
|
ipAddr = cfg.Subnet.Start
|
||||||
|
}
|
||||||
|
if ipAddr == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := ipAddr
|
||||||
|
if ipMask != "" {
|
||||||
|
prefix := libol.Netmask2Len(ipMask)
|
||||||
|
ifAddr := strings.SplitN(ipAddr, "/", 2)[0]
|
||||||
|
addr = fmt.Sprintf("%s/%d", ifAddr, prefix)
|
||||||
|
}
|
||||||
|
if _, inet, err := net.ParseCIDR(addr); err == nil {
|
||||||
|
return inet.String()
|
||||||
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,12 +551,19 @@ func (w *WorkerImpl) GetCfgs() (*co.Network, *co.OpenVPN) {
|
|||||||
return cfg, vpn
|
return cfg, vpn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) updateVPN(routes []string) {
|
func (w *WorkerImpl) updateVPN() {
|
||||||
cfg, vpn := w.GetCfgs()
|
cfg, vpn := w.GetCfgs()
|
||||||
if cfg == nil {
|
if vpn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
routes := vpn.Routes
|
||||||
|
routes = append(routes, vpn.Subnet) // add subnet of VPN self.
|
||||||
|
if addr := w.Subnet(); addr != "" {
|
||||||
|
w.out.Info("WorkerImpl.updateVPN subnet %s", addr)
|
||||||
|
routes = append(routes, addr)
|
||||||
|
}
|
||||||
|
|
||||||
for _, rt := range cfg.Routes {
|
for _, rt := range cfg.Routes {
|
||||||
addr := rt.Prefix
|
addr := rt.Prefix
|
||||||
if addr == "0.0.0.0/0" {
|
if addr == "0.0.0.0/0" {
|
||||||
@@ -460,7 +607,36 @@ func (w *WorkerImpl) forwardVPN() {
|
|||||||
w.toMasq_r(vpn.Subnet, w.setV.Name, "From VPN")
|
w.toMasq_r(vpn.Subnet, w.setV.Name, "From VPN")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) newVPN() {
|
func (w *WorkerImpl) forwardSubnet() {
|
||||||
|
cfg, vpn := w.GetCfgs()
|
||||||
|
br := cfg.Bridge
|
||||||
|
ifAddr := strings.SplitN(br.Address, "/", 2)[0]
|
||||||
|
if ifAddr == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
subnet := w.Subnet()
|
||||||
|
// Enable MASQUERADE, and FORWARD it.
|
||||||
|
w.toRelated(br.Name, "Accept related")
|
||||||
|
for _, rt := range cfg.Routes {
|
||||||
|
if rt.MultiPath != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if rt.Prefix == "0.0.0.0/0" {
|
||||||
|
w.setR.Add("0.0.0.0/1")
|
||||||
|
w.setR.Add("128.0.0.0/1")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w.setR.Add(rt.Prefix)
|
||||||
|
}
|
||||||
|
w.toForward_r(br.Name, subnet, w.setR.Name, "To route")
|
||||||
|
if vpn != nil {
|
||||||
|
w.toMasq_s(w.setR.Name, vpn.Subnet, "To VPN")
|
||||||
|
}
|
||||||
|
w.toMasq_r(subnet, w.setR.Name, "To Masq")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) createVPN() {
|
||||||
_, vpn := w.GetCfgs()
|
_, vpn := w.GetCfgs()
|
||||||
if vpn == nil {
|
if vpn == nil {
|
||||||
return
|
return
|
||||||
@@ -474,3 +650,7 @@ func (w *WorkerImpl) newVPN() {
|
|||||||
func (w *WorkerImpl) ZTruster() api.ZTruster {
|
func (w *WorkerImpl) ZTruster() api.ZTruster {
|
||||||
return w.ztrust
|
return w.ztrust
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) IfAddr() string {
|
||||||
|
return strings.SplitN(w.cfg.Bridge.Address, "/", 2)[0]
|
||||||
|
}
|
||||||
|
@@ -1,16 +1,12 @@
|
|||||||
package cswitch
|
package cswitch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/luscis/openlan/pkg/api"
|
"github.com/luscis/openlan/pkg/api"
|
||||||
"github.com/luscis/openlan/pkg/cache"
|
"github.com/luscis/openlan/pkg/cache"
|
||||||
co "github.com/luscis/openlan/pkg/config"
|
co "github.com/luscis/openlan/pkg/config"
|
||||||
"github.com/luscis/openlan/pkg/libol"
|
"github.com/luscis/openlan/pkg/libol"
|
||||||
"github.com/luscis/openlan/pkg/models"
|
|
||||||
cn "github.com/luscis/openlan/pkg/network"
|
cn "github.com/luscis/openlan/pkg/network"
|
||||||
nl "github.com/vishvananda/netlink"
|
nl "github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
@@ -38,91 +34,21 @@ func NewOpenLANWorker(c *co.Network) *OpenLANWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OpenLANWorker) updateVPN() {
|
|
||||||
_, vpn := w.GetCfgs()
|
|
||||||
if vpn == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
routes := vpn.Routes
|
|
||||||
routes = append(routes, vpn.Subnet)
|
|
||||||
if addr := w.Subnet(); addr != "" {
|
|
||||||
w.out.Info("OpenLANWorker.updateVPN subnet %s", addr)
|
|
||||||
routes = append(routes, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WorkerImpl.updateVPN(routes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) forwardSubnet() {
|
|
||||||
cfg, vpn := w.GetCfgs()
|
|
||||||
br := cfg.Bridge
|
|
||||||
ifAddr := strings.SplitN(br.Address, "/", 2)[0]
|
|
||||||
if ifAddr == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
subnet := w.Subnet()
|
|
||||||
// Enable MASQUERADE, and FORWARD it.
|
|
||||||
w.toRelated(br.Name, "Accept related")
|
|
||||||
for _, rt := range cfg.Routes {
|
|
||||||
if rt.MultiPath != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if rt.Prefix == "0.0.0.0/0" {
|
|
||||||
w.setR.Add("0.0.0.0/1")
|
|
||||||
w.setR.Add("128.0.0.0/1")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
w.setR.Add(rt.Prefix)
|
|
||||||
}
|
|
||||||
w.toForward_r(br.Name, subnet, w.setR.Name, "To route")
|
|
||||||
if vpn != nil {
|
|
||||||
w.toMasq_s(w.setR.Name, vpn.Subnet, "To VPN")
|
|
||||||
}
|
|
||||||
w.toMasq_r(subnet, w.setR.Name, "To Masq")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) Initialize() {
|
func (w *OpenLANWorker) Initialize() {
|
||||||
brCfg := w.cfg.Bridge
|
brCfg := w.cfg.Bridge
|
||||||
n := models.Network{
|
name := w.cfg.Name
|
||||||
Name: w.cfg.Name,
|
|
||||||
IpStart: w.cfg.Subnet.Start,
|
|
||||||
IpEnd: w.cfg.Subnet.End,
|
|
||||||
Netmask: w.cfg.Subnet.Netmask,
|
|
||||||
IfAddr: w.cfg.Bridge.Address,
|
|
||||||
Routes: make([]*models.Route, 0, 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rt := range w.cfg.Routes {
|
|
||||||
if rt.NextHop == "" {
|
|
||||||
w.out.Warn("OpenLANWorker.Initialize: %s noNextHop", rt.Prefix)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rte := models.NewRoute(rt.Prefix, w.IfAddr(), rt.Mode)
|
|
||||||
if rt.Metric > 0 {
|
|
||||||
rte.Metric = rt.Metric
|
|
||||||
}
|
|
||||||
if rt.NextHop != "" {
|
|
||||||
rte.Origin = rt.NextHop
|
|
||||||
}
|
|
||||||
n.Routes = append(n.Routes, rte)
|
|
||||||
}
|
|
||||||
cache.Network.Add(&n)
|
|
||||||
for _, ht := range w.cfg.Hosts {
|
for _, ht := range w.cfg.Hosts {
|
||||||
lease := cache.Network.AddLease(ht.Hostname, ht.Address, n.Name)
|
lease := cache.Network.AddLease(ht.Hostname, ht.Address, name)
|
||||||
if lease != nil {
|
if lease != nil {
|
||||||
lease.Type = "static"
|
lease.Type = "static"
|
||||||
lease.Network = w.cfg.Name
|
lease.Network = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.bridge = cn.NewBridger(brCfg.Provider, brCfg.Name, brCfg.IPMtu)
|
w.bridge = cn.NewBridger(brCfg.Provider, brCfg.Name, brCfg.IPMtu)
|
||||||
|
|
||||||
w.updateVPN()
|
|
||||||
w.WorkerImpl.Initialize()
|
w.WorkerImpl.Initialize()
|
||||||
|
|
||||||
w.forwardSubnet()
|
|
||||||
w.forwardVPN()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OpenLANWorker) LoadLinks() {
|
func (w *OpenLANWorker) LoadLinks() {
|
||||||
@@ -142,71 +68,6 @@ func (w *OpenLANWorker) UnLoadLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OpenLANWorker) LoadRoutes() {
|
|
||||||
// install routes
|
|
||||||
cfg := w.cfg
|
|
||||||
w.out.Debug("OpenLANWorker.LoadRoute: %v", cfg.Routes)
|
|
||||||
ifAddr := w.IfAddr()
|
|
||||||
for _, rt := range cfg.Routes {
|
|
||||||
_, dst, err := net.ParseCIDR(rt.Prefix)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ifAddr == rt.NextHop && rt.MultiPath == nil {
|
|
||||||
// route's next-hop is local not install again.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
nlrt := nl.Route{Dst: dst}
|
|
||||||
for _, hop := range rt.MultiPath {
|
|
||||||
nxhe := &nl.NexthopInfo{
|
|
||||||
Hops: hop.Weight,
|
|
||||||
Gw: net.ParseIP(hop.NextHop),
|
|
||||||
}
|
|
||||||
nlrt.MultiPath = append(nlrt.MultiPath, nxhe)
|
|
||||||
}
|
|
||||||
if rt.MultiPath == nil {
|
|
||||||
nlrt.Gw = net.ParseIP(rt.NextHop)
|
|
||||||
nlrt.Priority = rt.Metric
|
|
||||||
}
|
|
||||||
w.out.Debug("OpenLANWorker.LoadRoute: %s", nlrt.String())
|
|
||||||
promise := &libol.Promise{
|
|
||||||
First: time.Second * 2,
|
|
||||||
MaxInt: time.Minute,
|
|
||||||
MinInt: time.Second * 10,
|
|
||||||
}
|
|
||||||
rt_c := rt
|
|
||||||
promise.Go(func() error {
|
|
||||||
if err := nl.RouteReplace(&nlrt); err != nil {
|
|
||||||
w.out.Warn("OpenLANWorker.LoadRoute: %v %s", nlrt, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.out.Info("OpenLANWorker.LoadRoute: %v success", rt_c.String())
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) UnLoadRoutes() {
|
|
||||||
cfg := w.cfg
|
|
||||||
for _, rt := range cfg.Routes {
|
|
||||||
_, dst, err := net.ParseCIDR(rt.Prefix)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
nlRt := nl.Route{Dst: dst}
|
|
||||||
if rt.MultiPath == nil {
|
|
||||||
nlRt.Gw = net.ParseIP(rt.NextHop)
|
|
||||||
nlRt.Priority = rt.Metric
|
|
||||||
}
|
|
||||||
w.out.Debug("OpenLANWorker.UnLoadRoute: %s", nlRt.String())
|
|
||||||
if err := nl.RouteDel(&nlRt); err != nil {
|
|
||||||
w.out.Warn("OpenLANWorker.UnLoadRoute: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
w.out.Info("OpenLANWorker.UnLoadRoute: %v", rt.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) UpBridge(cfg *co.Bridge) {
|
func (w *OpenLANWorker) UpBridge(cfg *co.Bridge) {
|
||||||
master := w.bridge
|
master := w.bridge
|
||||||
// new it and configure address
|
// new it and configure address
|
||||||
@@ -276,7 +137,6 @@ func (w *OpenLANWorker) Start(v api.Switcher) {
|
|||||||
w.out.Info("OpenLANWorker.Start")
|
w.out.Info("OpenLANWorker.Start")
|
||||||
w.UpBridge(w.cfg.Bridge)
|
w.UpBridge(w.cfg.Bridge)
|
||||||
w.LoadLinks()
|
w.LoadLinks()
|
||||||
w.LoadRoutes()
|
|
||||||
w.WorkerImpl.Start(v)
|
w.WorkerImpl.Start(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +164,6 @@ func (w *OpenLANWorker) closePeer(cfg *co.Bridge) {
|
|||||||
func (w *OpenLANWorker) Stop() {
|
func (w *OpenLANWorker) Stop() {
|
||||||
w.out.Info("OpenLANWorker.Close")
|
w.out.Info("OpenLANWorker.Close")
|
||||||
w.WorkerImpl.Stop()
|
w.WorkerImpl.Stop()
|
||||||
w.UnLoadRoutes()
|
|
||||||
w.UnLoadLinks()
|
w.UnLoadLinks()
|
||||||
w.startTime = 0
|
w.startTime = 0
|
||||||
w.downBridge(w.cfg.Bridge)
|
w.downBridge(w.cfg.Bridge)
|
||||||
@@ -343,36 +202,10 @@ func (w *OpenLANWorker) DelLink(addr string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OpenLANWorker) Subnet() string {
|
|
||||||
cfg := w.cfg
|
|
||||||
|
|
||||||
ipAddr := cfg.Bridge.Address
|
|
||||||
ipMask := cfg.Subnet.Netmask
|
|
||||||
if ipAddr == "" {
|
|
||||||
ipAddr = cfg.Subnet.Start
|
|
||||||
}
|
|
||||||
if ipAddr != "" {
|
|
||||||
addr := ipAddr
|
|
||||||
if ipMask != "" {
|
|
||||||
prefix := libol.Netmask2Len(ipMask)
|
|
||||||
ifAddr := strings.SplitN(ipAddr, "/", 2)[0]
|
|
||||||
addr = fmt.Sprintf("%s/%d", ifAddr, prefix)
|
|
||||||
}
|
|
||||||
if _, inet, err := net.ParseCIDR(addr); err == nil {
|
|
||||||
return inet.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) Bridge() cn.Bridger {
|
func (w *OpenLANWorker) Bridge() cn.Bridger {
|
||||||
return w.bridge
|
return w.bridge
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OpenLANWorker) IfAddr() string {
|
|
||||||
return strings.SplitN(w.cfg.Bridge.Address, "/", 2)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *OpenLANWorker) Reload(v api.Switcher) {
|
func (w *OpenLANWorker) Reload(v api.Switcher) {
|
||||||
w.Stop()
|
w.Stop()
|
||||||
w.Initialize()
|
w.Initialize()
|
||||||
|
@@ -1,13 +1,8 @@
|
|||||||
package cswitch
|
package cswitch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/luscis/openlan/pkg/api"
|
"github.com/luscis/openlan/pkg/api"
|
||||||
co "github.com/luscis/openlan/pkg/config"
|
co "github.com/luscis/openlan/pkg/config"
|
||||||
"github.com/luscis/openlan/pkg/libol"
|
|
||||||
nl "github.com/vishvananda/netlink"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RouterWorker struct {
|
type RouterWorker struct {
|
||||||
@@ -23,93 +18,9 @@ func NewRouterWorker(c *co.Network) *RouterWorker {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RouterWorker) updateVPN() {
|
|
||||||
spec := w.spec
|
|
||||||
_, vpn := w.GetCfgs()
|
|
||||||
if vpn == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
routes := vpn.Routes
|
|
||||||
routes = append(routes, vpn.Subnet)
|
|
||||||
for _, sub := range spec.Subnets {
|
|
||||||
w.out.Info("RouterWorker.updateVPN subnet %s", sub.CIDR)
|
|
||||||
routes = append(routes, sub.CIDR)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WorkerImpl.updateVPN(routes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *RouterWorker) Initialize() {
|
func (w *RouterWorker) Initialize() {
|
||||||
w.updateVPN()
|
|
||||||
w.WorkerImpl.Initialize()
|
w.WorkerImpl.Initialize()
|
||||||
|
|
||||||
w.Forward()
|
w.Forward()
|
||||||
w.forwardVPN()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *RouterWorker) LoadRoutes() {
|
|
||||||
// install routes
|
|
||||||
cfg := w.cfg
|
|
||||||
w.out.Debug("RouterWorker.LoadRoute: %v", cfg.Routes)
|
|
||||||
for _, rt := range cfg.Routes {
|
|
||||||
_, dst, err := net.ParseCIDR(rt.Prefix)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if rt.NextHop == "" && rt.MultiPath == nil {
|
|
||||||
// route's next-hop is local not install again.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
nlrt := nl.Route{Dst: dst}
|
|
||||||
for _, hop := range rt.MultiPath {
|
|
||||||
nxhe := &nl.NexthopInfo{
|
|
||||||
Hops: hop.Weight,
|
|
||||||
Gw: net.ParseIP(hop.NextHop),
|
|
||||||
}
|
|
||||||
nlrt.MultiPath = append(nlrt.MultiPath, nxhe)
|
|
||||||
}
|
|
||||||
if rt.MultiPath == nil {
|
|
||||||
nlrt.Gw = net.ParseIP(rt.NextHop)
|
|
||||||
nlrt.Priority = rt.Metric
|
|
||||||
}
|
|
||||||
w.out.Debug("RouterWorker.LoadRoute: %s", nlrt.String())
|
|
||||||
promise := &libol.Promise{
|
|
||||||
First: time.Second * 2,
|
|
||||||
MaxInt: time.Minute,
|
|
||||||
MinInt: time.Second * 10,
|
|
||||||
}
|
|
||||||
rt_c := rt
|
|
||||||
promise.Go(func() error {
|
|
||||||
if err := nl.RouteReplace(&nlrt); err != nil {
|
|
||||||
w.out.Warn("RouterWorker.LoadRoute: %v %s", nlrt, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.out.Info("RouterWorker.LoadRoute: %v success", rt_c.String())
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *RouterWorker) UnLoadRoutes() {
|
|
||||||
cfg := w.cfg
|
|
||||||
for _, rt := range cfg.Routes {
|
|
||||||
_, dst, err := net.ParseCIDR(rt.Prefix)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
nlRt := nl.Route{Dst: dst}
|
|
||||||
if rt.MultiPath == nil {
|
|
||||||
nlRt.Gw = net.ParseIP(rt.NextHop)
|
|
||||||
nlRt.Priority = rt.Metric
|
|
||||||
}
|
|
||||||
w.out.Debug("RouterWorker.UnLoadRoute: %s", nlRt.String())
|
|
||||||
if err := nl.RouteDel(&nlRt); err != nil {
|
|
||||||
w.out.Warn("RouterWorker.UnLoadRoute: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
w.out.Info("RouterWorker.UnLoadRoute: %v", rt.String())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RouterWorker) Forward() {
|
func (w *RouterWorker) Forward() {
|
||||||
@@ -129,13 +40,11 @@ func (w *RouterWorker) Forward() {
|
|||||||
|
|
||||||
func (w *RouterWorker) Start(v api.Switcher) {
|
func (w *RouterWorker) Start(v api.Switcher) {
|
||||||
w.uuid = v.UUID()
|
w.uuid = v.UUID()
|
||||||
w.LoadRoutes()
|
|
||||||
w.WorkerImpl.Start(v)
|
w.WorkerImpl.Start(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RouterWorker) Stop() {
|
func (w *RouterWorker) Stop() {
|
||||||
w.WorkerImpl.Stop()
|
w.WorkerImpl.Stop()
|
||||||
w.UnLoadRoutes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RouterWorker) Reload(v api.Switcher) {
|
func (w *RouterWorker) Reload(v api.Switcher) {
|
||||||
|
Reference in New Issue
Block a user