mirror of
https://github.com/luscis/openlan.git
synced 2025-10-10 19:10:11 +08:00
fix: vxlan support openvpn
This commit is contained in:
@@ -50,7 +50,7 @@ networks:
|
||||
# docker exec -it powerdns_auth_1 bash
|
||||
## ZONE
|
||||
# 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
|
||||
# pdnsutil add-record luscis.io a0 A 192.168.0.88
|
||||
@@ -58,13 +58,13 @@ networks:
|
||||
|
||||
## A
|
||||
# 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
|
||||
|
||||
|
||||
## PTR
|
||||
# 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 @ 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
|
||||
|
||||
|
@@ -50,6 +50,7 @@ type Networker interface {
|
||||
Reload(v Switcher)
|
||||
Provider() string
|
||||
ZTruster() ZTruster
|
||||
IfAddr() string
|
||||
}
|
||||
|
||||
var workers = make(map[string]Networker)
|
||||
|
@@ -5,12 +5,16 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/luscis/openlan/pkg/api"
|
||||
"github.com/luscis/openlan/pkg/cache"
|
||||
co "github.com/luscis/openlan/pkg/config"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
"github.com/luscis/openlan/pkg/models"
|
||||
cn "github.com/luscis/openlan/pkg/network"
|
||||
"github.com/vishvananda/netlink"
|
||||
nl "github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func NewNetworker(c *co.Network) api.Networker {
|
||||
@@ -64,6 +68,34 @@ func (w *WorkerImpl) Provider() string {
|
||||
}
|
||||
|
||||
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" {
|
||||
w.dhcp = NewDhcp(&co.Dhcp{
|
||||
Name: w.cfg.Name,
|
||||
@@ -71,18 +103,23 @@ func (w *WorkerImpl) Initialize() {
|
||||
Bridge: w.cfg.Bridge,
|
||||
})
|
||||
}
|
||||
|
||||
w.fire = cn.NewFireWallTable(w.cfg.Name)
|
||||
|
||||
if out, err := w.setV.Clear(); err != nil {
|
||||
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
||||
}
|
||||
if out, err := w.setR.Clear(); err != nil {
|
||||
w.out.Error("WorkImpl.Initialize: create ipset: %s %s", out, err)
|
||||
}
|
||||
w.newVPN()
|
||||
|
||||
if w.cfg.ZTrust == "enable" {
|
||||
w.ztrust = NewZTrust(w.cfg.Name, 30)
|
||||
w.ztrust.Initialize()
|
||||
}
|
||||
|
||||
w.forwardSubnet()
|
||||
w.forwardVPN()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
cfg, vpn := w.GetCfgs()
|
||||
fire := w.fire
|
||||
|
||||
w.out.Info("WorkerImpl.Start")
|
||||
|
||||
w.loadRoutes()
|
||||
|
||||
if cfg.Acl != "" {
|
||||
fire.Mangle.Pre.AddRule(cn.IpRule{
|
||||
Input: cfg.Bridge.Name,
|
||||
Jump: cfg.Acl,
|
||||
})
|
||||
}
|
||||
|
||||
fire.Filter.For.AddRule(cn.IpRule{
|
||||
Input: cfg.Bridge.Name,
|
||||
Output: cfg.Bridge.Name,
|
||||
})
|
||||
|
||||
if cfg.Bridge.Mss > 0 {
|
||||
// forward to remote
|
||||
fire.Mangle.Post.AddRule(cn.IpRule{
|
||||
@@ -202,6 +288,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
||||
SetMss: cfg.Bridge.Mss,
|
||||
})
|
||||
}
|
||||
|
||||
for _, output := range cfg.Outputs {
|
||||
port := &LinuxPort{
|
||||
name: output.Interface,
|
||||
@@ -210,6 +297,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
||||
w.AddOutput(cfg.Bridge.Name, port)
|
||||
w.outputs = append(w.outputs, port)
|
||||
}
|
||||
|
||||
if !(w.dhcp == nil) {
|
||||
w.dhcp.Start()
|
||||
fire.Nat.Post.AddRule(cn.IpRule{
|
||||
@@ -219,6 +307,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
||||
Comment: "Default Gateway for DHCP",
|
||||
})
|
||||
}
|
||||
|
||||
if !(w.vpn == nil) {
|
||||
w.vpn.Start()
|
||||
}
|
||||
@@ -236,6 +325,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
||||
Comment: "Goto Zero Trust",
|
||||
})
|
||||
}
|
||||
|
||||
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() {
|
||||
w.out.Info("WorkerImpl.Stop")
|
||||
|
||||
w.fire.Stop()
|
||||
|
||||
if !(w.vpn == nil || w.ztrust == nil) {
|
||||
w.ztrust.Stop()
|
||||
}
|
||||
|
||||
if !(w.vpn == nil) {
|
||||
w.vpn.Stop()
|
||||
}
|
||||
|
||||
if !(w.dhcp == nil) {
|
||||
w.dhcp.Stop()
|
||||
}
|
||||
|
||||
for _, output := range w.outputs {
|
||||
w.DelOutput(w.cfg.Bridge.Name, output)
|
||||
}
|
||||
|
||||
w.outputs = nil
|
||||
w.setR.Destroy()
|
||||
w.setV.Destroy()
|
||||
|
||||
w.unloadRoutes()
|
||||
}
|
||||
|
||||
func (w *WorkerImpl) String() string {
|
||||
@@ -322,6 +441,27 @@ func (w *WorkerImpl) Config() *co.Network {
|
||||
}
|
||||
|
||||
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 ""
|
||||
}
|
||||
|
||||
@@ -411,12 +551,19 @@ func (w *WorkerImpl) GetCfgs() (*co.Network, *co.OpenVPN) {
|
||||
return cfg, vpn
|
||||
}
|
||||
|
||||
func (w *WorkerImpl) updateVPN(routes []string) {
|
||||
func (w *WorkerImpl) updateVPN() {
|
||||
cfg, vpn := w.GetCfgs()
|
||||
if cfg == nil {
|
||||
if vpn == nil {
|
||||
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 {
|
||||
addr := rt.Prefix
|
||||
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")
|
||||
}
|
||||
|
||||
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()
|
||||
if vpn == nil {
|
||||
return
|
||||
@@ -474,3 +650,7 @@ func (w *WorkerImpl) newVPN() {
|
||||
func (w *WorkerImpl) ZTruster() api.ZTruster {
|
||||
return w.ztrust
|
||||
}
|
||||
|
||||
func (w *WorkerImpl) IfAddr() string {
|
||||
return strings.SplitN(w.cfg.Bridge.Address, "/", 2)[0]
|
||||
}
|
||||
|
@@ -1,16 +1,12 @@
|
||||
package cswitch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/luscis/openlan/pkg/api"
|
||||
"github.com/luscis/openlan/pkg/cache"
|
||||
co "github.com/luscis/openlan/pkg/config"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
"github.com/luscis/openlan/pkg/models"
|
||||
cn "github.com/luscis/openlan/pkg/network"
|
||||
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() {
|
||||
brCfg := w.cfg.Bridge
|
||||
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),
|
||||
}
|
||||
name := w.cfg.Name
|
||||
|
||||
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 {
|
||||
lease := cache.Network.AddLease(ht.Hostname, ht.Address, n.Name)
|
||||
lease := cache.Network.AddLease(ht.Hostname, ht.Address, name)
|
||||
if lease != nil {
|
||||
lease.Type = "static"
|
||||
lease.Network = w.cfg.Name
|
||||
lease.Network = name
|
||||
}
|
||||
}
|
||||
|
||||
w.bridge = cn.NewBridger(brCfg.Provider, brCfg.Name, brCfg.IPMtu)
|
||||
|
||||
w.updateVPN()
|
||||
w.WorkerImpl.Initialize()
|
||||
|
||||
w.forwardSubnet()
|
||||
w.forwardVPN()
|
||||
}
|
||||
|
||||
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) {
|
||||
master := w.bridge
|
||||
// new it and configure address
|
||||
@@ -276,7 +137,6 @@ func (w *OpenLANWorker) Start(v api.Switcher) {
|
||||
w.out.Info("OpenLANWorker.Start")
|
||||
w.UpBridge(w.cfg.Bridge)
|
||||
w.LoadLinks()
|
||||
w.LoadRoutes()
|
||||
w.WorkerImpl.Start(v)
|
||||
}
|
||||
|
||||
@@ -304,7 +164,6 @@ func (w *OpenLANWorker) closePeer(cfg *co.Bridge) {
|
||||
func (w *OpenLANWorker) Stop() {
|
||||
w.out.Info("OpenLANWorker.Close")
|
||||
w.WorkerImpl.Stop()
|
||||
w.UnLoadRoutes()
|
||||
w.UnLoadLinks()
|
||||
w.startTime = 0
|
||||
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 {
|
||||
return w.bridge
|
||||
}
|
||||
|
||||
func (w *OpenLANWorker) IfAddr() string {
|
||||
return strings.SplitN(w.cfg.Bridge.Address, "/", 2)[0]
|
||||
}
|
||||
|
||||
func (w *OpenLANWorker) Reload(v api.Switcher) {
|
||||
w.Stop()
|
||||
w.Initialize()
|
||||
|
@@ -1,13 +1,8 @@
|
||||
package cswitch
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/luscis/openlan/pkg/api"
|
||||
co "github.com/luscis/openlan/pkg/config"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
nl "github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
type RouterWorker struct {
|
||||
@@ -23,93 +18,9 @@ func NewRouterWorker(c *co.Network) *RouterWorker {
|
||||
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() {
|
||||
w.updateVPN()
|
||||
w.WorkerImpl.Initialize()
|
||||
|
||||
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() {
|
||||
@@ -129,13 +40,11 @@ func (w *RouterWorker) Forward() {
|
||||
|
||||
func (w *RouterWorker) Start(v api.Switcher) {
|
||||
w.uuid = v.UUID()
|
||||
w.LoadRoutes()
|
||||
w.WorkerImpl.Start(v)
|
||||
}
|
||||
|
||||
func (w *RouterWorker) Stop() {
|
||||
w.WorkerImpl.Stop()
|
||||
w.UnLoadRoutes()
|
||||
}
|
||||
|
||||
func (w *RouterWorker) Reload(v api.Switcher) {
|
||||
|
Reference in New Issue
Block a user