fea: ipsec tunnel cli.

This commit is contained in:
Daniel Ding
2024-06-17 14:32:32 +08:00
parent 7c27b06b4e
commit 8799004044
20 changed files with 489 additions and 372 deletions

View File

@@ -29,21 +29,15 @@ func Commands(app *api.App) {
app.Before = Before app.Before = Before
User{}.Commands(app) User{}.Commands(app)
ACL{}.Commands(app) ACL{}.Commands(app)
Qos{}.Commands(app)
Device{}.Commands(app) Device{}.Commands(app)
Lease{}.Commands(app) Lease{}.Commands(app)
Config{}.Commands(app) Config{}.Commands(app)
Point{}.Commands(app)
VPNClient{}.Commands(app)
Link{}.Commands(app)
Server{}.Commands(app) Server{}.Commands(app)
Network{}.Commands(app) Network{}.Commands(app)
PProf{}.Commands(app) PProf{}.Commands(app)
VxLAN{}.Commands(app) IPSec{}.Commands(app)
Version{}.Commands(app) Version{}.Commands(app)
Log{}.Commands(app) Log{}.Commands(app)
Guest{}.Commands(app) Guest{}.Commands(app)
Knock{}.Commands(app) Knock{}.Commands(app)
Output{}.Commands(app)
Route{}.Commands(app)
} }

121
cmd/api/v5/ipsec.go Normal file
View File

@@ -0,0 +1,121 @@
package v5
import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2"
)
type IPSec struct {
Cmd
}
func (o IPSec) Commands(app *api.App) {
tunnel := IPSecTunnel{}
app.Command(&cli.Command{
Name: "ipsec",
Usage: "IPSec configuration",
Subcommands: []*cli.Command{
tunnel.Commands(),
},
})
}
type IPSecTunnel struct {
Cmd
}
func (o IPSecTunnel) Url(prefix string) string {
return prefix + "/api/network/ipsec/tunnel"
}
func (o IPSecTunnel) Add(c *cli.Context) error {
output := &schema.IPSecTunnel{
Right: c.String("remote"),
Secret: c.String("secret"),
Transport: c.String("transport"),
LeftId: c.String("localid"),
RightId: c.String("remoteid"),
LeftPort: c.Int("localport"),
RightPort: c.Int("remoteport"),
}
url := o.Url(c.String("url"))
clt := o.NewHttp(c.String("token"))
if err := clt.PostJSON(url, output, nil); err != nil {
return err
}
return nil
}
func (o IPSecTunnel) Remove(c *cli.Context) error {
output := &schema.IPSecTunnel{
Right: c.String("remote"),
Transport: c.String("transport"),
}
url := o.Url(c.String("url"))
clt := o.NewHttp(c.String("token"))
if err := clt.DeleteJSON(url, output, nil); err != nil {
return err
}
return nil
}
func (o IPSecTunnel) Tmpl() string {
return `# total {{ len . }}
{{ps -15 "Right"}} {{ps -15 "Transport"}} {{ps -15 "Secret"}} {{ps -15 "Port"}} {{ps -15 "Connection"}}
{{- range . }}
{{ps -15 .Right}} {{ps -15 .Transport }} {{ps -15 .Secret}} {{.LeftPort}}-{{.RightPort}} {{.LeftId}}-{{.RightId}}
{{- end }}
`
}
func (o IPSecTunnel) List(c *cli.Context) error {
url := o.Url(c.String("url"))
clt := o.NewHttp(c.String("token"))
var items []schema.IPSecTunnel
if err := clt.GetJSON(url, &items); err != nil {
return err
}
return o.Out(items, c.String("format"), o.Tmpl())
}
func (o IPSecTunnel) Commands() *cli.Command {
return &cli.Command{
Name: "tunnel",
Aliases: []string{"tun"},
Usage: "IPSec Tunnel configuration",
Subcommands: []*cli.Command{
{
Name: "add",
Usage: "Add a tunnel for the network",
Flags: []cli.Flag{
&cli.StringFlag{Name: "remote", Required: true},
&cli.StringFlag{Name: "remoteid"},
&cli.IntFlag{Name: "remoteport"},
&cli.StringFlag{Name: "transport", Required: true},
&cli.StringFlag{Name: "secret", Required: true},
&cli.StringFlag{Name: "localid"},
&cli.IntFlag{Name: "localport"},
},
Action: o.Add,
},
{
Name: "remove",
Usage: "Remove a tunnel from the network",
Aliases: []string{"rm"},
Flags: []cli.Flag{
&cli.StringFlag{Name: "remote", Required: true},
&cli.StringFlag{Name: "transport", Required: true},
},
Action: o.Remove,
},
{
Name: "list",
Usage: "Display all tunnel of the network",
Aliases: []string{"ls"},
Flags: []cli.Flag{},
Action: o.List,
},
},
}
}

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@@ -34,7 +33,7 @@ func (u Link) List(c *cli.Context) error {
if err := clt.GetJSON(url, &items); err != nil { if err := clt.GetJSON(url, &items); err != nil {
return err return err
} }
name := c.String("network") name := c.String("name")
if len(name) > 0 { if len(name) > 0 {
tmp := items[:0] tmp := items[:0]
for _, obj := range items { for _, obj := range items {
@@ -47,21 +46,17 @@ func (u Link) List(c *cli.Context) error {
return u.Out(items, c.String("format"), u.Tmpl()) return u.Out(items, c.String("format"), u.Tmpl())
} }
func (u Link) Commands(app *api.App) { func (u Link) Commands() *cli.Command {
app.Command(&cli.Command{ return &cli.Command{
Name: "link", Name: "link",
Aliases: []string{"ln"}, Usage: "Link connect to others",
Usage: "Link connect to others",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "list", Name: "list",
Usage: "Display all links", Usage: "Display all links",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: u.List,
&cli.StringFlag{Name: "network"},
},
Action: u.List,
}, },
}, },
}) }
} }

View File

@@ -86,20 +86,26 @@ func (u Network) Save(c *cli.Context) error {
} }
func (u Network) Commands(app *api.App) { func (u Network) Commands(app *api.App) {
point := Point{}
client := VPNClient{}
route := Route{}
link := Link{}
openvpn := OpenVpn{} openvpn := OpenVpn{}
output := Output{}
qos := Qos{}
app.Command(&cli.Command{ app.Command(&cli.Command{
Name: "network", Name: "network",
Aliases: []string{"net"}, Aliases: []string{"net"},
Usage: "Logical network", Flags: []cli.Flag{
&cli.StringFlag{Name: "name", Value: ""},
},
Usage: "Logical network",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "list", Name: "list",
Usage: "Display all network", Usage: "Display all network",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Action: u.List, Action: u.List,
Flags: []cli.Flag{
&cli.StringFlag{Name: "name"},
},
}, },
{ {
Name: "add", Name: "add",
@@ -113,60 +119,21 @@ func (u Network) Commands(app *api.App) {
Name: "remove", Name: "remove",
Usage: "Remove the network", Usage: "Remove the network",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Flags: []cli.Flag{ Action: u.Remove,
&cli.StringFlag{Name: "name"},
},
Action: u.Remove,
}, },
{ {
Name: "save", Name: "save",
Usage: "Save the network", Usage: "Save the network",
Aliases: []string{"sa"}, Aliases: []string{"sa"},
Flags: []cli.Flag{ Action: u.Save,
&cli.StringFlag{Name: "name", Value: ""},
},
Action: u.Save,
}, },
point.Commands(),
qos.Commands(),
client.Commands(),
openvpn.Commands(), openvpn.Commands(),
output.Commands(),
route.Commands(),
link.Commands(),
}, },
}) })
} }
type OpenVpn struct {
Cmd
}
func (o OpenVpn) Url(prefix, name string) string {
return prefix + "/api/network/" + name + "/openvpn/restart"
}
func (o OpenVpn) Restart(c *cli.Context) error {
network := c.String("network")
url := o.Url(c.String("url"), network)
clt := o.NewHttp(c.String("token"))
if err := clt.PostJSON(url, nil, nil); err != nil {
return err
}
return nil
}
func (o OpenVpn) Commands() *cli.Command {
return &cli.Command{
Name: "openvpn",
Usage: "control openvpn",
Aliases: []string{"ov"},
Subcommands: []*cli.Command{
{
Name: "restart",
Usage: "restart openvpn for the network",
Aliases: []string{"ro"},
Flags: []cli.Flag{
&cli.StringFlag{Name: "network", Required: true},
},
Action: o.Restart,
},
},
}
}

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@@ -28,13 +27,13 @@ func (u VPNClient) Tmpl() string {
} }
func (u VPNClient) List(c *cli.Context) error { func (u VPNClient) List(c *cli.Context) error {
url := u.Url(c.String("url"), c.String("network")) url := u.Url(c.String("url"), c.String("name"))
clt := u.NewHttp(c.String("token")) clt := u.NewHttp(c.String("token"))
var items []schema.VPNClient var items []schema.VPNClient
if err := clt.GetJSON(url, &items); err != nil { if err := clt.GetJSON(url, &items); err != nil {
return err return err
} }
name := c.String("network") name := c.String("name")
if len(name) > 0 { if len(name) > 0 {
tmp := items[:0] tmp := items[:0]
for _, obj := range items { for _, obj := range items {
@@ -47,21 +46,52 @@ func (u VPNClient) List(c *cli.Context) error {
return u.Out(items, c.String("format"), u.Tmpl()) return u.Out(items, c.String("format"), u.Tmpl())
} }
func (u VPNClient) Commands(app *api.App) { func (u VPNClient) Commands() *cli.Command {
app.Command(&cli.Command{ return &cli.Command{
Name: "client", Name: "client",
Aliases: []string{"cl"}, Usage: "Clients by OpenVPN",
Usage: "Connected client by OpenVPN",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "list", Name: "list",
Usage: "Display all clients", Usage: "Display all clients",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: u.List,
&cli.StringFlag{Name: "network"},
},
Action: u.List,
}, },
}, },
}) }
}
type OpenVpn struct {
Cmd
}
func (o OpenVpn) Url(prefix, name string) string {
return prefix + "/api/network/" + name + "/openvpn/restart"
}
func (o OpenVpn) Restart(c *cli.Context) error {
network := c.String("name")
url := o.Url(c.String("url"), network)
clt := o.NewHttp(c.String("token"))
if err := clt.PostJSON(url, nil, nil); err != nil {
return err
}
return nil
}
func (o OpenVpn) Commands() *cli.Command {
return &cli.Command{
Name: "openvpn",
Usage: "Control OpenVPN",
Subcommands: []*cli.Command{
{
Name: "restart",
Usage: "restart openvpn for the network",
Aliases: []string{"ro"},
Action: o.Restart,
},
},
}
} }

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/libol" "github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@@ -16,7 +15,7 @@ func (o Output) Url(prefix, name string) string {
} }
func (o Output) Add(c *cli.Context) error { func (o Output) Add(c *cli.Context) error {
network := c.String("network") network := c.String("name")
if len(network) == 0 { if len(network) == 0 {
return libol.NewErr("invalid network") return libol.NewErr("invalid network")
} }
@@ -37,7 +36,7 @@ func (o Output) Add(c *cli.Context) error {
} }
func (o Output) Remove(c *cli.Context) error { func (o Output) Remove(c *cli.Context) error {
network := c.String("network") network := c.String("name")
if len(network) == 0 { if len(network) == 0 {
return libol.NewErr("invalid network") return libol.NewErr("invalid network")
} }
@@ -54,7 +53,7 @@ func (o Output) Remove(c *cli.Context) error {
} }
func (o Output) Save(c *cli.Context) error { func (o Output) Save(c *cli.Context) error {
network := c.String("network") network := c.String("name")
url := o.Url(c.String("url"), network) url := o.Url(c.String("url"), network)
clt := o.NewHttp(c.String("token")) clt := o.NewHttp(c.String("token"))
@@ -75,7 +74,7 @@ func (o Output) Tmpl() string {
} }
func (o Output) List(c *cli.Context) error { func (o Output) List(c *cli.Context) error {
url := o.Url(c.String("url"), c.String("network")) url := o.Url(c.String("url"), c.String("name"))
clt := o.NewHttp(c.String("token")) clt := o.NewHttp(c.String("token"))
var items []schema.Output var items []schema.Output
if err := clt.GetJSON(url, &items); err != nil { if err := clt.GetJSON(url, &items); err != nil {
@@ -84,23 +83,19 @@ func (o Output) List(c *cli.Context) error {
return o.Out(items, c.String("format"), o.Tmpl()) return o.Out(items, c.String("format"), o.Tmpl())
} }
func (o Output) Commands(app *api.App) { func (o Output) Commands() *cli.Command {
app.Command(&cli.Command{ return &cli.Command{
Name: "output", Name: "output",
Aliases: []string{"op"}, Usage: "Output configuration",
Usage: "Output configuration",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "add", Name: "add",
Usage: "Add an output for the network", Usage: "Add an output for the network",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{Name: "network"}, &cli.StringFlag{Name: "remote", Required: true},
&cli.StringFlag{Name: "remote"},
&cli.IntFlag{Name: "segment"}, &cli.IntFlag{Name: "segment"},
&cli.StringFlag{Name: "protocol"}, &cli.StringFlag{Name: "protocol"},
&cli.StringFlag{Name: "dstport"}, &cli.StringFlag{Name: "dstport"},
//&cli.StringFlag{Name: "connection"},
&cli.StringFlag{Name: "secret"},
}, },
Action: o.Add, Action: o.Add,
}, },
@@ -109,8 +104,7 @@ func (o Output) Commands(app *api.App) {
Usage: "Remove an output from the network", Usage: "Remove an output from the network",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{Name: "network"}, &cli.StringFlag{Name: "device", Required: true},
&cli.StringFlag{Name: "device"},
}, },
Action: o.Remove, Action: o.Remove,
}, },
@@ -118,20 +112,14 @@ func (o Output) Commands(app *api.App) {
Name: "list", Name: "list",
Usage: "Display all outputs of the network", Usage: "Display all outputs of the network",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: o.List,
&cli.StringFlag{Name: "network", Required: true},
},
Action: o.List,
}, },
{ {
Name: "save", Name: "save",
Usage: "Save all outputs", Usage: "Save all outputs",
Aliases: []string{"sa"}, Aliases: []string{"sa"},
Flags: []cli.Flag{ Action: o.Save,
&cli.StringFlag{Name: "network", Required: true},
},
Action: o.Save,
}, },
}, },
}) }
} }

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@@ -34,7 +33,7 @@ func (u Point) List(c *cli.Context) error {
if err := clt.GetJSON(url, &items); err != nil { if err := clt.GetJSON(url, &items); err != nil {
return err return err
} }
name := c.String("network") name := c.String("name")
if len(name) > 0 { if len(name) > 0 {
tmp := items[:0] tmp := items[:0]
for _, obj := range items { for _, obj := range items {
@@ -47,21 +46,17 @@ func (u Point) List(c *cli.Context) error {
return u.Out(items, c.String("format"), u.Tmpl()) return u.Out(items, c.String("format"), u.Tmpl())
} }
func (u Point) Commands(app *api.App) { func (u Point) Commands() *cli.Command {
app.Command(&cli.Command{ return &cli.Command{
Name: "point", Name: "point",
Aliases: []string{"ap"}, Usage: "Point accessed to switch",
Usage: "Point accessed to switch",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "list", Name: "list",
Usage: "Display all points", Usage: "Display all points",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: u.List,
&cli.StringFlag{Name: "network"},
},
Action: u.List,
}, },
}, },
}) }
} }

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@@ -10,18 +9,15 @@ type Qos struct {
Cmd Cmd
} }
func (q Qos) Commands(app *api.App) { func (q Qos) Commands() *cli.Command {
rule := QosRule{} rule := QosRule{}
app.Command(&cli.Command{ return &cli.Command{
Name: "qos", Name: "qos",
Usage: "qos for client in network", Usage: "QoS for client in network",
Flags: []cli.Flag{
&cli.StringFlag{Name: "name", Aliases: []string{"n"}},
},
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
rule.Commands(), rule.Commands(),
}, },
}) }
} }
type QosRule struct { type QosRule struct {

View File

@@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/libol" "github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@@ -16,7 +15,7 @@ func (r Route) Url(prefix, name string) string {
} }
func (r Route) Add(c *cli.Context) error { func (r Route) Add(c *cli.Context) error {
network := c.String("network") network := c.String("name")
if len(network) == 0 { if len(network) == 0 {
return libol.NewErr("invalid network") return libol.NewErr("invalid network")
} }
@@ -35,7 +34,7 @@ func (r Route) Add(c *cli.Context) error {
} }
func (r Route) Remove(c *cli.Context) error { func (r Route) Remove(c *cli.Context) error {
network := c.String("network") network := c.String("name")
if len(network) == 0 { if len(network) == 0 {
return libol.NewErr("invalid network") return libol.NewErr("invalid network")
} }
@@ -54,7 +53,7 @@ func (r Route) Remove(c *cli.Context) error {
} }
func (r Route) Save(c *cli.Context) error { func (r Route) Save(c *cli.Context) error {
network := c.String("network") network := c.String("name")
url := r.Url(c.String("url"), network) url := r.Url(c.String("url"), network)
clt := r.NewHttp(c.String("token")) clt := r.NewHttp(c.String("token"))
@@ -75,7 +74,7 @@ func (r Route) Tmpl() string {
} }
func (r Route) List(c *cli.Context) error { func (r Route) List(c *cli.Context) error {
url := r.Url(c.String("url"), c.String("network")) url := r.Url(c.String("url"), c.String("name"))
clt := r.NewHttp(c.String("token")) clt := r.NewHttp(c.String("token"))
var items []schema.PrefixRoute var items []schema.PrefixRoute
if err := clt.GetJSON(url, &items); err != nil { if err := clt.GetJSON(url, &items); err != nil {
@@ -84,18 +83,16 @@ func (r Route) List(c *cli.Context) error {
return r.Out(items, c.String("format"), r.Tmpl()) return r.Out(items, c.String("format"), r.Tmpl())
} }
func (r Route) Commands(app *api.App) { func (r Route) Commands() *cli.Command {
app.Command(&cli.Command{ return &cli.Command{
Name: "route", Name: "route",
Aliases: []string{"op"}, Usage: "Route configuration",
Usage: "Route configuration",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
{ {
Name: "add", Name: "add",
Usage: "Add a route for the network", Usage: "Add a route for the network",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{Name: "network", Required: true}, &cli.StringFlag{Name: "prefix", Required: true},
&cli.StringFlag{Name: "prefix"},
&cli.StringFlag{Name: "nexthop"}, &cli.StringFlag{Name: "nexthop"},
&cli.IntFlag{Name: "metric"}, &cli.IntFlag{Name: "metric"},
&cli.StringFlag{Name: "mode"}, &cli.StringFlag{Name: "mode"},
@@ -107,8 +104,7 @@ func (r Route) Commands(app *api.App) {
Usage: "Remove a route from the network", Usage: "Remove a route from the network",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{Name: "network", Required: true}, &cli.StringFlag{Name: "prefix", Required: true},
&cli.StringFlag{Name: "prefix"},
&cli.StringFlag{Name: "nexthop"}, &cli.StringFlag{Name: "nexthop"},
}, },
Action: r.Remove, Action: r.Remove,
@@ -117,20 +113,14 @@ func (r Route) Commands(app *api.App) {
Name: "list", Name: "list",
Usage: "Display all outputs of the network", Usage: "Display all outputs of the network",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: r.List,
&cli.StringFlag{Name: "network", Required: true},
},
Action: r.List,
}, },
{ {
Name: "save", Name: "save",
Usage: "Save all routes", Usage: "Save all routes",
Aliases: []string{"sa"}, Aliases: []string{"sa"},
Flags: []cli.Flag{ Action: r.Save,
&cli.StringFlag{Name: "network", Required: true},
},
Action: r.Save,
}, },
}, },
}) }
} }

View File

@@ -1,54 +0,0 @@
package v5
import (
"github.com/luscis/openlan/cmd/api"
"github.com/luscis/openlan/pkg/schema"
"github.com/urfave/cli/v2"
)
type VxLAN struct {
Cmd
}
func (u VxLAN) Url(prefix, name string) string {
if name == "" {
return prefix + "/api/vxlan"
} else {
return prefix + "/api/vxlan/" + name
}
}
func (u VxLAN) Tmpl() string {
return `# total {{ len . }}
{{ps -16 "name"}} {{ps -15 "bridge"}} {{ ps -16 "address" }} {{ps -16 "vni"}} {{ps -16 "local"}} {{ps -22 "remote"}}
{{- range . }}
{{ps -16 .UUID}} {{pt .AliveTime | ps -8}} {{ ps -8 .Device}} {{ps -16 .Alias}} {{ps -8 .User}} {{ps -22 .Remote}}
{{- end }}
`
}
func (u VxLAN) List(c *cli.Context) error {
url := u.Url(c.String("url"), "")
clt := u.NewHttp(c.String("token"))
var items []schema.VxLAN
if err := clt.GetJSON(url, &items); err != nil {
return err
}
return u.Out(items, c.String("format"), u.Tmpl())
}
func (u VxLAN) Commands(app *api.App) {
app.Command(&cli.Command{
Name: "vxlan",
Aliases: []string{"vx"},
Usage: "VxLAN configuration",
Subcommands: []*cli.Command{
{
Name: "list",
Usage: "Display all vxlan",
Aliases: []string{"ls"},
Action: u.List,
},
},
})
}

View File

@@ -70,7 +70,7 @@ type Qoser interface {
type Outputer interface { type Outputer interface {
AddOutput(data schema.Output) AddOutput(data schema.Output)
DelOutput(device string) DelOutput(data schema.Output)
SaveOutput() SaveOutput()
} }

60
pkg/api/ipsec.go Executable file
View File

@@ -0,0 +1,60 @@
package api
import (
"net/http"
"github.com/gorilla/mux"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema"
)
type IPSec struct {
Switcher Switcher
}
func (h IPSec) Router(router *mux.Router) {
router.HandleFunc("/api/network/ipsec/tunnel", h.Get).Methods("GET")
router.HandleFunc("/api/network/ipsec/tunnel", h.Post).Methods("POST")
router.HandleFunc("/api/network/ipsec/tunnel", h.Delete).Methods("DELETE")
}
func (h IPSec) Get(w http.ResponseWriter, r *http.Request) {
libol.Debug("IPSec.Get %s")
tunnels := make([]schema.IPSecTunnel, 0, 1024)
if Call.secer == nil {
http.Error(w, "network is nil", http.StatusBadRequest)
return
}
Call.secer.ListTunnels(func(obj schema.IPSecTunnel) {
tunnels = append(tunnels, obj)
})
ResponseJson(w, tunnels)
}
func (h IPSec) Post(w http.ResponseWriter, r *http.Request) {
tun := &schema.IPSecTunnel{}
if err := GetData(r, tun); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if Call.secer == nil {
http.Error(w, "network is nil", http.StatusBadRequest)
return
}
Call.secer.AddTunnel(*tun)
ResponseMsg(w, 0, "")
}
func (h IPSec) Delete(w http.ResponseWriter, r *http.Request) {
tun := &schema.IPSecTunnel{}
if err := GetData(r, tun); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if Call.secer == nil {
http.Error(w, "network is nil", http.StatusBadRequest)
return
}
Call.secer.DelTunnel(*tun)
ResponseMsg(w, 0, "")
}

View File

@@ -78,7 +78,7 @@ func (h Output) Delete(w http.ResponseWriter, r *http.Request) {
http.Error(w, "network not found", http.StatusBadRequest) http.Error(w, "network not found", http.StatusBadRequest)
return return
} }
worker.DelOutput(output.Device) worker.DelOutput(*output)
ResponseMsg(w, 0, "") ResponseMsg(w, 0, "")
} }

View File

@@ -24,4 +24,5 @@ func Add(router *mux.Router, switcher Switcher) {
Output{Switcher: switcher}.Router(router) Output{Switcher: switcher}.Router(router)
ACL{}.Router(router) ACL{}.Router(router)
Route{Switcher: switcher}.Router(router) Route{Switcher: switcher}.Router(router)
IPSec{}.Router(router)
} }

View File

@@ -6,10 +6,10 @@ type IPSecTunnel struct {
Name string `json:"-"` Name string `json:"-"`
Left string `json:"local"` Left string `json:"local"`
LeftId string `json:"localid"` LeftId string `json:"localid"`
LeftPort string `json:"localport"` LeftPort int `json:"localport"`
Right string `json:"remote"` Right string `json:"remote"`
RightId string `json:"remoteid"` RightId string `json:"remoteid"`
RightPort string `json:"remoteport"` RightPort int `json:"remoteport"`
Transport string `json:"transport"` Transport string `json:"transport"`
Secret string `json:"secret"` Secret string `json:"secret"`
} }
@@ -36,10 +36,27 @@ func (s *IPSecSpecifies) Correct() {
} }
} }
func (s *IPSecSpecifies) AddTunnel(data *IPSecTunnel) { func (s *IPSecSpecifies) FindTunnel(value *IPSecTunnel) (*IPSecTunnel, int) {
for index, obj := range s.Tunnels {
if obj.Id() == value.Id() {
return obj, index
}
}
return nil, -1
} }
func (s *IPSecSpecifies) DelTunnel(data *IPSecTunnel) { func (s *IPSecSpecifies) AddTunnel(value *IPSecTunnel) bool {
_, find := s.FindTunnel(value)
if find == -1 {
s.Tunnels = append(s.Tunnels, value)
}
return find == -1
}
func (s *IPSecSpecifies) DelTunnel(value *IPSecTunnel) (*IPSecTunnel, bool) {
obj, find := s.FindTunnel(value)
if find != -1 {
s.Tunnels = append(s.Tunnels[:find], s.Tunnels[find+1:]...)
}
return obj, find != -1
} }

View File

@@ -22,7 +22,7 @@ type Network struct {
Acl string `json:"acl,omitempty"` Acl string `json:"acl,omitempty"`
Specifies interface{} `json:"specifies,omitempty"` Specifies interface{} `json:"specifies,omitempty"`
Dhcp string `json:"dhcp,omitempty"` Dhcp string `json:"dhcp,omitempty"`
Outputs []Output `json:"outputs,omitempty"` Outputs []*Output `json:"outputs,omitempty"`
ZTrust string `json:"ztrust,omitempty"` ZTrust string `json:"ztrust,omitempty"`
Qos string `json:"qos,omitempty"` Qos string `json:"qos,omitempty"`
Namespace string `json:"namespace,omitempty"` Namespace string `json:"namespace,omitempty"`
@@ -185,3 +185,56 @@ func (n *Network) SaveNextGroup() {
func (n *Network) Reload() { func (n *Network) Reload() {
} }
func (n *Network) FindRoute(value PrefixRoute) (PrefixRoute, int) {
for i, obj := range n.Routes {
if value.Prefix == obj.Prefix {
return obj, i
}
}
return PrefixRoute{}, -1
}
func (n *Network) AddRoute(value PrefixRoute) bool {
_, index := n.FindRoute(value)
if index == -1 {
n.Routes = append(n.Routes, value)
}
return index == -1
}
func (n *Network) DelRoute(value PrefixRoute) (PrefixRoute, bool) {
obj, index := n.FindRoute(value)
if index != -1 {
n.Routes = append(n.Routes[:index], n.Routes[index+1:]...)
}
return obj, index != -1
}
func (n *Network) FindOutput(value *Output) (*Output, int) {
for i, obj := range n.Outputs {
if value.Link != "" && value.Link == obj.Link {
return obj, i
}
if value.Link == "" && value.Id() == obj.Id() {
return obj, i
}
}
return nil, -1
}
func (n *Network) AddOutput(value *Output) bool {
_, index := n.FindOutput(value)
if index == -1 {
n.Outputs = append(n.Outputs, value)
}
return index == -1
}
func (n *Network) DelOutput(value *Output) (*Output, bool) {
obj, index := n.FindOutput(value)
if index != -1 {
n.Outputs = append(n.Outputs[:index], n.Outputs[index+1:]...)
}
return obj, index != -1
}

View File

@@ -1,5 +1,7 @@
package config package config
import "fmt"
type Output struct { type Output struct {
Segment int `json:"segment"` Segment int `json:"segment"`
Protocol string `json:"protocol,omitempty"` // gre, vxlan, etc. Protocol string `json:"protocol,omitempty"` // gre, vxlan, etc.
@@ -8,3 +10,21 @@ type Output struct {
Link string `json:"link,omitempty"` // link name Link string `json:"link,omitempty"` // link name
Secret string `json:"secret"` Secret string `json:"secret"`
} }
func (o *Output) Id() string {
return fmt.Sprintf("%s-%s-%d", o.Protocol, o.Remote, o.Segment)
}
func (o *Output) GenName() {
if o.Link == "" {
if o.Protocol == "gre" {
o.Link = fmt.Sprintf("%s%d", "gre", o.Segment)
} else if o.Protocol == "vxlan" {
o.Link = fmt.Sprintf("%s%d", "vxlan", o.Segment)
} else if o.Segment > 0 {
o.Link = fmt.Sprintf("%s.%d", o.Remote, o.Segment)
} else {
o.Link = o.Remote
}
}
}

View File

@@ -3,10 +3,10 @@ package schema
type IPSecTunnel struct { type IPSecTunnel struct {
Left string `json:"local"` Left string `json:"local"`
LeftId string `json:"localid"` LeftId string `json:"localid"`
LeftPort string `json:"localport"` LeftPort int `json:"localport"`
Right string `json:"remote"` Right string `json:"remote"`
RightId string `json:"remoteid"` RightId string `json:"remoteid"`
RightPort string `json:"remoteport"` RightPort int `json:"remoteport"`
Transport string `json:"transport"` Transport string `json:"transport"`
Secret string `json:"secret"` Secret string `json:"secret"`
} }

View File

@@ -113,35 +113,35 @@ func (w *IPSecWorker) startConn(name string) {
}) })
} }
func (w *IPSecWorker) addTunnel(tunnel *co.IPSecTunnel) error { func (w *IPSecWorker) addTunnel(tun *co.IPSecTunnel) error {
connTmpl := "" connTmpl := ""
secTmpl := "" secTmpl := ""
name := tunnel.Name name := tun.Name
if tunnel.Transport == "vxlan" { if tun.Transport == "vxlan" {
connTmpl = vxlanTmpl connTmpl = vxlanTmpl
secTmpl = secretTmpl secTmpl = secretTmpl
} else if tunnel.Transport == "gre" { } else if tun.Transport == "gre" {
connTmpl = greTmpl connTmpl = greTmpl
secTmpl = secretTmpl secTmpl = secretTmpl
} }
if secTmpl != "" { if secTmpl != "" {
if err := w.saveSec(name+".secrets", secTmpl, tunnel); err != nil { if err := w.saveSec(name+".secrets", secTmpl, tun); err != nil {
w.out.Error("WorkerImpl.AddTunnel %s", err) w.out.Error("WorkerImpl.AddTunnel %s", err)
return err return err
} }
libol.Exec("ipsec", "auto", "--rereadsecrets") libol.Exec("ipsec", "auto", "--rereadsecrets")
} }
if connTmpl != "" { if connTmpl != "" {
if err := w.saveSec(name+".conf", connTmpl, tunnel); err != nil { if err := w.saveSec(name+".conf", connTmpl, tun); err != nil {
w.out.Error("WorkerImpl.AddTunnel %s", err) w.out.Error("WorkerImpl.AddTunnel %s", err)
return err return err
} }
if tunnel.Transport == "vxlan" { if tun.Transport == "vxlan" {
w.startConn(name + "-c1") w.startConn(name + "-c1")
w.startConn(name + "-c2") w.startConn(name + "-c2")
} else if tunnel.Transport == "gre" { } else if tun.Transport == "gre" {
w.startConn(name + "-c1") w.startConn(name + "-c1")
} }
} }
@@ -152,17 +152,17 @@ func (w *IPSecWorker) addTunnel(tunnel *co.IPSecTunnel) error {
func (w *IPSecWorker) Start(v api.Switcher) { func (w *IPSecWorker) Start(v api.Switcher) {
w.uuid = v.UUID() w.uuid = v.UUID()
w.out.Info("IPSecWorker.Start") w.out.Info("IPSecWorker.Start")
for _, tunnel := range w.spec.Tunnels { for _, tun := range w.spec.Tunnels {
w.addTunnel(tunnel) w.addTunnel(tun)
} }
} }
func (w *IPSecWorker) removeTunnel(tunnel *co.IPSecTunnel) error { func (w *IPSecWorker) removeTunnel(tun *co.IPSecTunnel) error {
name := tunnel.Name name := tun.Name
if tunnel.Transport == "vxlan" { if tun.Transport == "vxlan" {
libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c1") libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c1")
libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c2") libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c2")
} else if tunnel.Transport == "gre" { } else if tun.Transport == "gre" {
libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c1") libol.Exec("ipsec", "auto", "--delete", "--asynchronous", name+"-c1")
} }
@@ -184,8 +184,8 @@ func (w *IPSecWorker) removeTunnel(tunnel *co.IPSecTunnel) error {
func (w *IPSecWorker) Stop() { func (w *IPSecWorker) Stop() {
w.out.Info("IPSecWorker.Stop") w.out.Info("IPSecWorker.Stop")
for _, tunnel := range w.spec.Tunnels { for _, tun := range w.spec.Tunnels {
w.removeTunnel(tunnel) w.removeTunnel(tun)
} }
} }
@@ -198,12 +198,18 @@ func (w *IPSecWorker) Reload(v api.Switcher) {
func (w *IPSecWorker) AddTunnel(data schema.IPSecTunnel) { func (w *IPSecWorker) AddTunnel(data schema.IPSecTunnel) {
cfg := &co.IPSecTunnel{ cfg := &co.IPSecTunnel{
Left: data.Left, Left: data.Left,
LeftPort: data.LeftPort,
LeftId: data.LeftId,
Right: data.Right, Right: data.Right,
RightPort: data.RightPort,
RightId: data.RightId,
Secret: data.Secret, Secret: data.Secret,
Transport: data.Transport, Transport: data.Transport,
} }
w.spec.AddTunnel(cfg) cfg.Correct()
w.addTunnel(cfg) if w.spec.AddTunnel(cfg) {
w.addTunnel(cfg)
}
} }
func (w *IPSecWorker) DelTunnel(data schema.IPSecTunnel) { func (w *IPSecWorker) DelTunnel(data schema.IPSecTunnel) {
@@ -213,10 +219,24 @@ func (w *IPSecWorker) DelTunnel(data schema.IPSecTunnel) {
Secret: data.Secret, Secret: data.Secret,
Transport: data.Transport, Transport: data.Transport,
} }
w.removeTunnel(cfg) cfg.Correct()
w.spec.DelTunnel(cfg) if _, removed := w.spec.DelTunnel(cfg); removed {
w.removeTunnel(cfg)
}
} }
func (w *IPSecWorker) ListTunnels(call func(obj schema.IPSecTunnel)) { func (w *IPSecWorker) ListTunnels(call func(obj schema.IPSecTunnel)) {
for _, tun := range w.spec.Tunnels {
obj := schema.IPSecTunnel{
Left: tun.Left,
LeftId: tun.LeftId,
LeftPort: tun.LeftPort,
Right: tun.Right,
RightId: tun.RightId,
RightPort: tun.RightPort,
Secret: tun.Secret,
Transport: tun.Transport,
}
call(obj)
}
} }

View File

@@ -32,42 +32,11 @@ func NewNetworker(c *co.Network) api.Networker {
return obj return obj
} }
func toLinkName(protocol, remote string, segment int) string {
if protocol == "gre" {
return fmt.Sprintf("%s%d", "gre", segment)
}
if protocol == "vxlan" {
return fmt.Sprintf("%s%d", "vxlan", segment)
}
if segment > 0 {
return fmt.Sprintf("%s.%d", remote, segment)
}
return remote
}
type LinuxPort struct {
output co.Output
link string
}
func (l *LinuxPort) String() string {
return fmt.Sprintf("%s:%s:%d", l.output.Protocol, l.output.Remote, l.output.Segment)
}
func (l *LinuxPort) GenName() {
if l.link != "" {
return
}
out := l.output
l.link = toLinkName(out.Protocol, out.Remote, out.Segment)
}
type WorkerImpl struct { type WorkerImpl struct {
uuid string uuid string
cfg *co.Network cfg *co.Network
out *libol.SubLogger out *libol.SubLogger
dhcp *Dhcp dhcp *Dhcp
outputs []*LinuxPort
fire *cn.FireWallTable fire *cn.FireWallTable
setR *cn.IPSet setR *cn.IPSet
setV *cn.IPSet setV *cn.IPSet
@@ -184,70 +153,67 @@ func (w *WorkerImpl) AddPhysical(bridge string, output string) {
} }
} }
func (w *WorkerImpl) addOutput(bridge string, port *LinuxPort) { func (w *WorkerImpl) addOutput(bridge string, port *co.Output) {
cfg := port.output
mtu := 0 mtu := 0
if cfg.Protocol == "gre" { if port.Protocol == "gre" {
mtu = 1450 mtu = 1450
link := &nl.Gretap{ link := &nl.Gretap{
IKey: uint32(cfg.Segment), IKey: uint32(port.Segment),
OKey: uint32(cfg.Segment), OKey: uint32(port.Segment),
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
Name: port.link, Name: port.Link,
MTU: mtu, MTU: mtu,
}, },
Local: libol.ParseAddr("0.0.0.0"), Local: libol.ParseAddr("0.0.0.0"),
Remote: libol.ParseAddr(cfg.Remote), Remote: libol.ParseAddr(port.Remote),
PMtuDisc: 1, PMtuDisc: 1,
} }
if err := nl.LinkAdd(link); err != nil { if err := nl.LinkAdd(link); err != nil {
w.out.Error("WorkerImpl.LinkAdd %s %s", port.String(), err) w.out.Error("WorkerImpl.LinkAdd %s %s", port.Id(), err)
return return
} }
} else if cfg.Protocol == "vxlan" { } else if port.Protocol == "vxlan" {
dport := 8472 dport := 8472
if cfg.DstPort > 0 { if port.DstPort > 0 {
dport = cfg.DstPort dport = port.DstPort
} }
mtu = 1450 mtu = 1450
link := &nl.Vxlan{ link := &nl.Vxlan{
VxlanId: cfg.Segment, VxlanId: port.Segment,
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
TxQLen: -1, TxQLen: -1,
Name: port.link, Name: port.Link,
MTU: mtu, MTU: mtu,
}, },
Group: libol.ParseAddr(cfg.Remote), Group: libol.ParseAddr(port.Remote),
Port: dport, Port: dport,
} }
if err := nl.LinkAdd(link); err != nil { if err := nl.LinkAdd(link); err != nil {
w.out.Error("WorkerImpl.LinkAdd %s %s", port.String(), err) w.out.Error("WorkerImpl.LinkAdd %s %s", port.Id(), err)
return return
} }
} else { } else {
link, err := nl.LinkByName(cfg.Remote) link, err := nl.LinkByName(port.Remote)
if link == nil { if link == nil {
w.out.Error("WorkerImpl.addOutput %s %s", cfg.Remote, err) w.out.Error("WorkerImpl.addOutput %s %s", port.Remote, err)
return return
} }
if err := nl.LinkSetUp(link); err != nil { if err := nl.LinkSetUp(link); err != nil {
w.out.Warn("WorkerImpl.addOutput %s %s", cfg.Remote, err) w.out.Warn("WorkerImpl.addOutput %s %s", port.Remote, err)
} }
if cfg.Segment > 0 { if port.Segment > 0 {
subLink := &nl.Vlan{ subLink := &nl.Vlan{
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
Name: port.link, Name: port.Link,
ParentIndex: link.Attrs().Index, ParentIndex: link.Attrs().Index,
}, },
VlanId: cfg.Segment, VlanId: port.Segment,
} }
if err := nl.LinkAdd(subLink); err != nil { if err := nl.LinkAdd(subLink); err != nil {
w.out.Error("WorkerImpl.linkAdd %s %s", subLink.Name, err) w.out.Error("WorkerImpl.linkAdd %s %s", subLink.Name, err)
return return
} }
} else {
port.link = cfg.Remote
} }
} }
@@ -260,16 +226,16 @@ func (w *WorkerImpl) addOutput(bridge string, port *LinuxPort) {
out := &models.Output{ out := &models.Output{
Network: w.cfg.Name, Network: w.cfg.Name,
NewTime: time.Now().Unix(), NewTime: time.Now().Unix(),
Protocol: cfg.Protocol, Protocol: port.Protocol,
Remote: cfg.Remote, Remote: port.Remote,
Segment: cfg.Segment, Segment: port.Segment,
Secret: cfg.Secret, Secret: port.Secret,
Device: port.link, Device: port.Link,
} }
cache.Output.Add(port.link, out) cache.Output.Add(port.Link, out)
w.out.Info("WorkerImpl.addOutput %s %s", port.link, port.String()) w.out.Info("WorkerImpl.addOutput %s %s", port.Link, port.Id())
w.AddPhysical(bridge, port.link) w.AddPhysical(bridge, port.Link)
} }
func (w *WorkerImpl) loadRoute(rt co.PrefixRoute) { func (w *WorkerImpl) loadRoute(rt co.PrefixRoute) {
@@ -401,12 +367,8 @@ func (w *WorkerImpl) Start(v api.Switcher) {
} }
for _, output := range cfg.Outputs { for _, output := range cfg.Outputs {
port := &LinuxPort{ output.GenName()
output: output, w.addOutput(cfg.Bridge.Name, output)
}
port.GenName()
w.addOutput(cfg.Bridge.Name, port)
w.outputs = append(w.outputs, port)
} }
if !(w.dhcp == nil) { if !(w.dhcp == nil) {
@@ -481,37 +443,36 @@ func (w *WorkerImpl) DelPhysical(bridge string, output string) {
} }
} }
func (w *WorkerImpl) delOutput(bridge string, port *LinuxPort) { func (w *WorkerImpl) delOutput(bridge string, port *co.Output) {
cfg := port.output w.out.Info("WorkerImpl.delOutput %s", port.Link)
w.out.Info("WorkerImpl.delOutput %s %s", port.link, port.String())
cache.Output.Del(port.link) cache.Output.Del(port.Link)
w.DelPhysical(bridge, port.link) w.DelPhysical(bridge, port.Link)
if cfg.Protocol == "gre" { if port.Protocol == "gre" {
link := &nl.Gretap{ link := &nl.Gretap{
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
Name: port.link, Name: port.Link,
}, },
} }
if err := nl.LinkDel(link); err != nil { if err := nl.LinkDel(link); err != nil {
w.out.Error("WorkerImpl.LinkDel %s %s", link.Name, err) w.out.Error("WorkerImpl.LinkDel %s %s", link.Name, err)
return return
} }
} else if cfg.Protocol == "vxlan" { } else if port.Protocol == "vxlan" {
link := &nl.Vxlan{ link := &nl.Vxlan{
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
Name: port.link, Name: port.Link,
}, },
} }
if err := nl.LinkDel(link); err != nil { if err := nl.LinkDel(link); err != nil {
w.out.Error("WorkerImpl.LinkDel %s %s", link.Name, err) w.out.Error("WorkerImpl.LinkDel %s %s", link.Name, err)
return return
} }
} else if port.output.Segment > 0 { } else if port.Segment > 0 {
link := &nl.Vlan{ link := &nl.Vlan{
LinkAttrs: nl.LinkAttrs{ LinkAttrs: nl.LinkAttrs{
Name: port.link, Name: port.Link,
}, },
} }
@@ -584,10 +545,9 @@ func (w *WorkerImpl) Stop() {
w.vrf.Down() w.vrf.Down()
} }
for _, output := range w.outputs { for _, output := range w.cfg.Outputs {
w.delOutput(w.cfg.Bridge.Name, output) w.delOutput(w.cfg.Bridge.Name, output)
} }
w.outputs = nil
w.acl.Stop() w.acl.Stop()
@@ -1001,31 +961,18 @@ func (w *WorkerImpl) correctRoute(route *schema.PrefixRoute) co.PrefixRoute {
Mode: route.Mode, Mode: route.Mode,
Metric: route.Metric, Metric: route.Metric,
} }
rt.CorrectRoute(w.IfAddr()) rt.CorrectRoute(w.IfAddr())
return rt return rt
} }
func (w *WorkerImpl) findRoute(rt co.PrefixRoute) (co.PrefixRoute, int) {
for i, ert := range w.cfg.Routes {
if ert.Prefix == rt.Prefix {
return ert, i
}
}
return co.PrefixRoute{}, -1
}
func (w *WorkerImpl) AddRoute(route *schema.PrefixRoute, switcher api.Switcher) error { func (w *WorkerImpl) AddRoute(route *schema.PrefixRoute, switcher api.Switcher) error {
rt := w.correctRoute(route) rt := w.correctRoute(route)
if _, index := w.findRoute(rt); index != -1 { if !w.cfg.AddRoute(rt) {
w.out.Warn("WorkerImpl.AddRoute: route exist") w.out.Info("WorkerImpl.AddRoute: %s route exist", route.Prefix)
return nil return nil
} }
w.cfg.Routes = append(w.cfg.Routes, rt)
w.out.Info("WorkerImpl.AddRoute: %v", rt) w.out.Info("WorkerImpl.AddRoute: %v", rt)
w.addIpSet(rt) w.addIpSet(rt)
if inet, err := libol.ParseNet(rt.Prefix); err == nil { if inet, err := libol.ParseNet(rt.Prefix); err == nil {
w.addVPNSet(inet.String()) w.addVPNSet(inet.String())
@@ -1034,19 +981,17 @@ func (w *WorkerImpl) AddRoute(route *schema.PrefixRoute, switcher api.Switcher)
w.addCacheRoute(rt) w.addCacheRoute(rt)
w.addVPNRoute(rt) w.addVPNRoute(rt)
w.loadRoute(rt) w.loadRoute(rt)
return nil return nil
} }
func (w *WorkerImpl) DelRoute(route *schema.PrefixRoute, switcher api.Switcher) error { func (w *WorkerImpl) DelRoute(route *schema.PrefixRoute, switcher api.Switcher) error {
correctRt := w.correctRoute(route) correctRt := w.correctRoute(route)
delRt, index := w.findRoute(correctRt) delRt, removed := w.cfg.DelRoute(correctRt)
if index == -1 { if !removed {
w.out.Warn("WorkerImpl.DelRoute: route not found") w.out.Info("WorkerImpl.DelRoute: %s not found", route.Prefix)
return nil return nil
} }
w.cfg.Routes = append(w.cfg.Routes[:index], w.cfg.Routes[index+1:]...)
w.delIpSet(delRt) w.delIpSet(delRt)
if inet, err := libol.ParseNet(delRt.Prefix); err == nil { if inet, err := libol.ParseNet(delRt.Prefix); err == nil {
w.delVPNSet(inet.String()) w.delVPNSet(inet.String())
@@ -1055,7 +1000,6 @@ func (w *WorkerImpl) DelRoute(route *schema.PrefixRoute, switcher api.Switcher)
w.delCacheRoute(delRt) w.delCacheRoute(delRt)
w.delVPNRoute(delRt) w.delVPNRoute(delRt)
w.unloadRoute(delRt) w.unloadRoute(delRt)
return nil return nil
} }
@@ -1085,48 +1029,28 @@ func (w *WorkerImpl) ACLer() api.ACLer {
} }
func (w *WorkerImpl) AddOutput(data schema.Output) { func (w *WorkerImpl) AddOutput(data schema.Output) {
output := co.Output{ output := &co.Output{
Segment: data.Segment, Segment: data.Segment,
Protocol: data.Protocol, Protocol: data.Protocol,
Remote: data.Remote, Remote: data.Remote,
DstPort: data.DstPort, DstPort: data.DstPort,
Secret: data.Secret, Secret: data.Secret,
} }
w.cfg.Outputs = append(w.cfg.Outputs, output) if !w.cfg.AddOutput(output) {
port := &LinuxPort{ w.out.Info("WorkerImple.AddOutput %s already existed", output.Id())
output: output,
}
port.GenName()
w.addOutput(w.cfg.Bridge.Name, port)
w.outputs = append(w.outputs, port)
}
func (w *WorkerImpl) DelOutput(device string) {
var port *LinuxPort
for _, v := range w.outputs {
if v.link == device {
port = v
break
}
}
if port == nil {
return return
} }
Outputs := make([]co.Output, 0, len(w.cfg.Outputs)) output.GenName()
for _, v := range w.cfg.Outputs { w.addOutput(w.cfg.Bridge.Name, output)
if v != port.output { }
Outputs = append(Outputs, v)
} func (w *WorkerImpl) DelOutput(data schema.Output) {
output, removed := w.cfg.DelOutput(&co.Output{Link: data.Device})
if !removed {
w.out.Info("WorkerImpl.DelOutput: %s not found", output.Id())
return
} }
w.cfg.Outputs = Outputs w.delOutput(w.cfg.Bridge.Name, output)
w.delOutput(w.cfg.Bridge.Name, port)
outputs := make([]*LinuxPort, 0, len(w.outputs))
for _, v := range w.outputs {
if v != port {
outputs = append(outputs, v)
}
}
w.outputs = outputs
} }
func (w *WorkerImpl) SaveOutput() { func (w *WorkerImpl) SaveOutput() {