mirror of
https://github.com/luscis/openlan.git
synced 2025-10-06 00:57:03 +08:00
fea: support list/add/del/save output (#48)
This commit is contained in:
@@ -47,4 +47,5 @@ func Commands(app *api.App) {
|
|||||||
Log{}.Commands(app)
|
Log{}.Commands(app)
|
||||||
Guest{}.Commands(app)
|
Guest{}.Commands(app)
|
||||||
Knock{}.Commands(app)
|
Knock{}.Commands(app)
|
||||||
|
Output{}.Commands(app)
|
||||||
}
|
}
|
||||||
|
@@ -144,6 +144,21 @@ func (u Config) Check(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check output config
|
||||||
|
out.Info("%15s: %s", "check", "output")
|
||||||
|
pattern = filepath.Join(dir, "switch", "output", "*.json")
|
||||||
|
if files, err := filepath.Glob(pattern); err == nil {
|
||||||
|
for _, file := range files {
|
||||||
|
var obj []config.Output
|
||||||
|
if err := libol.UnmarshalLoad(&obj, file); err != nil {
|
||||||
|
out.Warn("%15s: %s", filepath.Base(file), err)
|
||||||
|
} else {
|
||||||
|
out.Info("%15s: %s", filepath.Base(file), "success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
135
cmd/api/v5/output.go
Normal file
135
cmd/api/v5/output.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package v5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/luscis/openlan/cmd/api"
|
||||||
|
"github.com/luscis/openlan/pkg/libol"
|
||||||
|
"github.com/luscis/openlan/pkg/schema"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Output struct {
|
||||||
|
Cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Url(prefix, name string) string {
|
||||||
|
return prefix + "/api/network/" + name + "/output"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Add(c *cli.Context) error {
|
||||||
|
network := c.String("network")
|
||||||
|
if len(network) == 0 {
|
||||||
|
return libol.NewErr("invalid network")
|
||||||
|
}
|
||||||
|
output := &schema.Output{
|
||||||
|
Network: network,
|
||||||
|
Remote: c.String("remote"),
|
||||||
|
Segment: c.Int("segment"),
|
||||||
|
Protocol: c.String("protocol"),
|
||||||
|
}
|
||||||
|
url := o.Url(c.String("url"), network)
|
||||||
|
clt := o.NewHttp(c.String("token"))
|
||||||
|
if err := clt.PostJSON(url, output, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Remove(c *cli.Context) error {
|
||||||
|
network := c.String("network")
|
||||||
|
if len(network) == 0 {
|
||||||
|
return libol.NewErr("invalid network")
|
||||||
|
}
|
||||||
|
output := &schema.Output{
|
||||||
|
Network: network,
|
||||||
|
Device: c.String("device"),
|
||||||
|
}
|
||||||
|
url := o.Url(c.String("url"), network)
|
||||||
|
clt := o.NewHttp(c.String("token"))
|
||||||
|
if err := clt.DeleteJSON(url, output, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Save(c *cli.Context) error {
|
||||||
|
network := c.String("network")
|
||||||
|
url := o.Url(c.String("url"), network)
|
||||||
|
|
||||||
|
clt := o.NewHttp(c.String("token"))
|
||||||
|
if err := clt.PutJSON(url, nil, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Tmpl() string {
|
||||||
|
return `# total {{ len . }}
|
||||||
|
{{ps -24 "network"}} {{ps -15 "protocol"}} {{ps -15 "Remote"}} {{ps -15 "segment"}} {{ps -15 "device"}}
|
||||||
|
{{- range . }}
|
||||||
|
{{ps -24 .Network}} {{ps -15 .Protocol}} {{ps -15 .Remote}} {{pi -15 .Segment }} {{ps -15 .Device}}
|
||||||
|
{{- end }}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) List(c *cli.Context) error {
|
||||||
|
url := o.Url(c.String("url"), c.String("network"))
|
||||||
|
clt := o.NewHttp(c.String("token"))
|
||||||
|
var items []schema.Output
|
||||||
|
if err := clt.GetJSON(url, &items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return o.Out(items, c.String("format"), o.Tmpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Output) Commands(app *api.App) {
|
||||||
|
app.Command(&cli.Command{
|
||||||
|
Name: "output",
|
||||||
|
Aliases: []string{"op"},
|
||||||
|
Usage: "Output configuration",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "add",
|
||||||
|
Usage: "Add an output for the network",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "network"},
|
||||||
|
&cli.StringFlag{Name: "remote"},
|
||||||
|
&cli.IntFlag{Name: "segment"},
|
||||||
|
&cli.StringFlag{Name: "protocol"},
|
||||||
|
//&cli.StringFlag{Name: "connection"},
|
||||||
|
//&cli.StringFlag{Name: "secret"},
|
||||||
|
//&cli.StringFlag{Name: "auth"},
|
||||||
|
},
|
||||||
|
Action: o.Add,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "remove",
|
||||||
|
Usage: "Remove an output from the network",
|
||||||
|
Aliases: []string{"rm"},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "network"},
|
||||||
|
&cli.StringFlag{Name: "device"},
|
||||||
|
},
|
||||||
|
Action: o.Remove,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "Display all outputs of the network",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "network", Required: true},
|
||||||
|
},
|
||||||
|
Action: o.List,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "save",
|
||||||
|
Usage: "Save all outputs",
|
||||||
|
Aliases: []string{"sa"},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "network", Required: true},
|
||||||
|
},
|
||||||
|
Action: o.Save,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@@ -45,22 +45,5 @@
|
|||||||
},
|
},
|
||||||
"acl": "acl-100",
|
"acl": "acl-100",
|
||||||
"dhcp": "enable",
|
"dhcp": "enable",
|
||||||
"namespace": "example",
|
"namespace": "example"
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"segment": 43,
|
|
||||||
"remote": "3.3.3.5",
|
|
||||||
"dstport": 8899,
|
|
||||||
"protocol": "vxlan"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"segment": 55,
|
|
||||||
"remote": "3.3.3.3",
|
|
||||||
"protocol": "gre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"segment": 23,
|
|
||||||
"remote": "enp2s2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@@ -12,21 +12,5 @@
|
|||||||
"startAt": "192.168.55.100",
|
"startAt": "192.168.55.100",
|
||||||
"endAt": "192.168.55.130"
|
"endAt": "192.168.55.130"
|
||||||
},
|
},
|
||||||
"dhcp": "enable",
|
"dhcp": "enable"
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"segment": 43,
|
|
||||||
"remote": "3.3.3.5",
|
|
||||||
"protocol": "vxlan"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"segment": 55,
|
|
||||||
"remote": "3.3.3.3",
|
|
||||||
"protocol": "gre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"segment": 23,
|
|
||||||
"remote": "enp2s2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
17
dist/rootfs/etc/openlan/switch/output/example.json.example
vendored
Normal file
17
dist/rootfs/etc/openlan/switch/output/example.json.example
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"segment": 43,
|
||||||
|
"remote": "3.3.3.5",
|
||||||
|
"dstport": 8899,
|
||||||
|
"protocol": "vxlan"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"segment": 55,
|
||||||
|
"remote": "3.3.3.3",
|
||||||
|
"protocol": "gre"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"segment": 23,
|
||||||
|
"remote": "enp2s2"
|
||||||
|
}
|
||||||
|
]
|
@@ -36,7 +36,7 @@ OpenLAN软件包含下面部分:
|
|||||||
{
|
{
|
||||||
"protocol": "tcp",
|
"protocol": "tcp",
|
||||||
"crypt": {
|
"crypt": {
|
||||||
"algo": "aes-128", ## 支持xor,aes-128,aes-192等对称加密算法
|
"algorithm": "aes-128", ## 支持xor,aes-128,aes-192等对称加密算法
|
||||||
"secret": "ea64d5b0c96c"
|
"secret": "ea64d5b0c96c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,12 @@ type Qoser interface {
|
|||||||
Save()
|
Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Outputer interface {
|
||||||
|
AddOutput(segment int, protocol, Remote string)
|
||||||
|
DelOutput(device string)
|
||||||
|
SaveOutput()
|
||||||
|
}
|
||||||
|
|
||||||
type Networker interface {
|
type Networker interface {
|
||||||
String() string
|
String() string
|
||||||
ID() string
|
ID() string
|
||||||
@@ -70,6 +76,7 @@ type Networker interface {
|
|||||||
Qoser() Qoser
|
Qoser() Qoser
|
||||||
IfAddr() string
|
IfAddr() string
|
||||||
ACLer() ACLer
|
ACLer() ACLer
|
||||||
|
Outputer
|
||||||
}
|
}
|
||||||
|
|
||||||
var workers = make(map[string]Networker)
|
var workers = make(map[string]Networker)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@@ -17,6 +18,8 @@ type Output struct {
|
|||||||
func (h Output) Router(router *mux.Router) {
|
func (h Output) Router(router *mux.Router) {
|
||||||
router.HandleFunc("/api/network/{id}/output", h.Get).Methods("GET")
|
router.HandleFunc("/api/network/{id}/output", h.Get).Methods("GET")
|
||||||
router.HandleFunc("/api/network/{id}/output", h.Post).Methods("POST")
|
router.HandleFunc("/api/network/{id}/output", h.Post).Methods("POST")
|
||||||
|
router.HandleFunc("/api/network/{id}/output", h.Delete).Methods("DELETE")
|
||||||
|
router.HandleFunc("/api/network/{id}/output", h.Save).Methods("PUT")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h Output) Get(w http.ResponseWriter, r *http.Request) {
|
func (h Output) Get(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -35,5 +38,65 @@ func (h Output) Get(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h Output) Post(w http.ResponseWriter, r *http.Request) {
|
func (h Output) Post(w http.ResponseWriter, r *http.Request) {
|
||||||
ResponseJson(w, "outputs")
|
output := &schema.Output{}
|
||||||
|
if err := GetData(r, output); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cs := h.Switcher.Config()
|
||||||
|
if cs.Network == nil {
|
||||||
|
http.Error(w, "switch has no network can not add output", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
network := cs.GetNetwork(output.Network)
|
||||||
|
if network == nil {
|
||||||
|
http.Error(w, fmt.Sprintf("switch has no network with %s can not add output", output.Network), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
worker := GetWorker(output.Network)
|
||||||
|
if worker == nil {
|
||||||
|
http.Error(w, "Network not found", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
worker.AddOutput(output.Segment, output.Protocol, output.Remote)
|
||||||
|
ResponseMsg(w, 0, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Output) Delete(w http.ResponseWriter, r *http.Request) {
|
||||||
|
output := &schema.Output{}
|
||||||
|
if err := GetData(r, output); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cs := h.Switcher.Config()
|
||||||
|
if cs.Network == nil {
|
||||||
|
http.Error(w, "switch has no network can not del output", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
network := cs.GetNetwork(output.Network)
|
||||||
|
if network == nil {
|
||||||
|
http.Error(w, fmt.Sprintf("switch has no network with %s can not del output", output.Network), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
worker := GetWorker(output.Network)
|
||||||
|
if worker == nil {
|
||||||
|
http.Error(w, "Network not found", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
worker.DelOutput(output.Device)
|
||||||
|
ResponseMsg(w, 0, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Output) Save(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
id := vars["id"]
|
||||||
|
|
||||||
|
worker := GetWorker(id)
|
||||||
|
if worker == nil {
|
||||||
|
http.Error(w, "Network not found", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
worker.SaveOutput()
|
||||||
|
|
||||||
|
ResponseJson(w, "success")
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,6 @@ func Add(router *mux.Router, switcher Switcher) {
|
|||||||
OpenAPI{}.Router(router)
|
OpenAPI{}.Router(router)
|
||||||
ZTrust{}.Router(router)
|
ZTrust{}.Router(router)
|
||||||
QosApi{}.Router(router)
|
QosApi{}.Router(router)
|
||||||
Output{}.Router(router)
|
Output{Switcher: switcher}.Router(router)
|
||||||
ACL{}.Router(router)
|
ACL{}.Router(router)
|
||||||
}
|
}
|
||||||
|
@@ -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"`
|
Outputs []Output `json:"outputs,omitempty"`
|
||||||
ZTrust string `json:"ztrust"`
|
ZTrust string `json:"ztrust"`
|
||||||
Qos string `json:"qos,omitempty"`
|
Qos string `json:"qos,omitempty"`
|
||||||
Namespace string `json:"namespace"`
|
Namespace string `json:"namespace"`
|
||||||
@@ -122,15 +122,26 @@ func (n *Network) LoadRoute() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Network) LoadOutput() {
|
||||||
|
file := n.Dir("output", n.Name+".json")
|
||||||
|
if err := libol.FileExist(file); err == nil {
|
||||||
|
if err := libol.UnmarshalLoad(&n.Outputs, file); err != nil {
|
||||||
|
libol.Error("Network.LoadOutput... %n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Network) Save() {
|
func (n *Network) Save() {
|
||||||
obj := *n
|
obj := *n
|
||||||
obj.Routes = nil
|
obj.Routes = nil
|
||||||
obj.Links = nil
|
obj.Links = nil
|
||||||
|
obj.Outputs = nil
|
||||||
if err := libol.MarshalSave(&obj, obj.File, true); err != nil {
|
if err := libol.MarshalSave(&obj, obj.File, true); err != nil {
|
||||||
libol.Error("Network.Save %s %s", obj.Name, err)
|
libol.Error("Network.Save %s %s", obj.Name, err)
|
||||||
}
|
}
|
||||||
n.SaveRoute()
|
n.SaveRoute()
|
||||||
n.SaveLink()
|
n.SaveLink()
|
||||||
|
n.SaveOutput()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Network) SaveRoute() {
|
func (n *Network) SaveRoute() {
|
||||||
@@ -153,6 +164,16 @@ func (n *Network) SaveLink() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Network) SaveOutput() {
|
||||||
|
file := n.Dir("output", n.Name+".json")
|
||||||
|
if n.Outputs == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := libol.MarshalSave(n.Outputs, file, true); err != nil {
|
||||||
|
libol.Error("Network.SaveOutput %s %s", n.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Network) Reload() {
|
func (n *Network) Reload() {
|
||||||
switch n.Provider {
|
switch n.Provider {
|
||||||
case "esp":
|
case "esp":
|
||||||
|
@@ -187,6 +187,7 @@ func (s *Switch) LoadNetwork() {
|
|||||||
}
|
}
|
||||||
obj.LoadLink()
|
obj.LoadLink()
|
||||||
obj.LoadRoute()
|
obj.LoadRoute()
|
||||||
|
obj.LoadOutput()
|
||||||
s.Network = append(s.Network, obj)
|
s.Network = append(s.Network, obj)
|
||||||
}
|
}
|
||||||
s.Format()
|
s.Format()
|
||||||
|
@@ -153,7 +153,7 @@ func (w *WorkerImpl) AddPhysical(bridge string, output string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) AddOutput(bridge string, port *LinuxPort) {
|
func (w *WorkerImpl) addOutput(bridge string, port *LinuxPort) {
|
||||||
cfg := port.cfg
|
cfg := port.cfg
|
||||||
out := &models.Output{
|
out := &models.Output{
|
||||||
Network: w.cfg.Name,
|
Network: w.cfg.Name,
|
||||||
@@ -210,11 +210,11 @@ func (w *WorkerImpl) AddOutput(bridge string, port *LinuxPort) {
|
|||||||
} else {
|
} else {
|
||||||
link, err := nl.LinkByName(cfg.Remote)
|
link, err := nl.LinkByName(cfg.Remote)
|
||||||
if link == nil {
|
if link == nil {
|
||||||
w.out.Error("WorkerImpl.AddOutput %s %s", cfg.Remote, err)
|
w.out.Error("WorkerImpl.addOutput %s %s", cfg.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", cfg.Remote, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Segment > 0 {
|
if cfg.Segment > 0 {
|
||||||
@@ -246,7 +246,7 @@ func (w *WorkerImpl) AddOutput(bridge string, port *LinuxPort) {
|
|||||||
out.Device = port.link
|
out.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.String())
|
||||||
w.AddPhysical(bridge, port.link)
|
w.AddPhysical(bridge, port.link)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ func (w *WorkerImpl) Start(v api.Switcher) {
|
|||||||
port := &LinuxPort{
|
port := &LinuxPort{
|
||||||
cfg: output,
|
cfg: output,
|
||||||
}
|
}
|
||||||
w.AddOutput(cfg.Bridge.Name, port)
|
w.addOutput(cfg.Bridge.Name, port)
|
||||||
w.outputs = append(w.outputs, port)
|
w.outputs = append(w.outputs, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,9 +425,9 @@ func (w *WorkerImpl) DelPhysical(bridge string, output string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerImpl) DelOutput(bridge string, port *LinuxPort) {
|
func (w *WorkerImpl) delOutput(bridge string, port *LinuxPort) {
|
||||||
cfg := port.cfg
|
cfg := port.cfg
|
||||||
w.out.Info("WorkerImpl.DelOutput %s %s", port.link, port.String())
|
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)
|
||||||
@@ -513,7 +513,7 @@ func (w *WorkerImpl) 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
|
||||||
|
|
||||||
@@ -811,3 +811,49 @@ func (w *WorkerImpl) IfAddr() string {
|
|||||||
func (w *WorkerImpl) ACLer() api.ACLer {
|
func (w *WorkerImpl) ACLer() api.ACLer {
|
||||||
return w.acl
|
return w.acl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) AddOutput(segment int, protocol, Remote string) {
|
||||||
|
output := co.Output{
|
||||||
|
Segment: segment,
|
||||||
|
Protocol: protocol,
|
||||||
|
Remote: Remote,
|
||||||
|
}
|
||||||
|
w.cfg.Outputs = append(w.cfg.Outputs, output)
|
||||||
|
port := &LinuxPort{
|
||||||
|
cfg: output,
|
||||||
|
}
|
||||||
|
w.addOutput(w.cfg.Bridge.Name, port)
|
||||||
|
w.outputs = append(w.outputs, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) DelOutput(device string) {
|
||||||
|
var linuxport *LinuxPort
|
||||||
|
for _, v := range w.outputs {
|
||||||
|
if v.link == device {
|
||||||
|
linuxport = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if linuxport == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Outputs := make([]co.Output, 0, len(w.cfg.Outputs))
|
||||||
|
for _, v := range w.cfg.Outputs {
|
||||||
|
if v != linuxport.cfg {
|
||||||
|
Outputs = append(Outputs, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.cfg.Outputs = Outputs
|
||||||
|
w.delOutput(w.cfg.Bridge.Name, linuxport)
|
||||||
|
outputs := make([]*LinuxPort, 0, len(w.outputs))
|
||||||
|
for _, v := range w.outputs {
|
||||||
|
if v != linuxport {
|
||||||
|
outputs = append(outputs, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.outputs = outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorkerImpl) SaveOutput() {
|
||||||
|
w.cfg.SaveOutput()
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user