mirror of
https://github.com/luscis/openlan.git
synced 2025-10-06 00:57:03 +08:00
fea: support rate limit.
This commit is contained in:
@@ -39,4 +39,5 @@ func Commands(app *api.App) {
|
||||
Version{}.Commands(app)
|
||||
Log{}.Commands(app)
|
||||
ZTrust{}.Commands(app)
|
||||
Rate{}.Commands(app)
|
||||
}
|
||||
|
92
cmd/api/v5/rate.go
Executable file
92
cmd/api/v5/rate.go
Executable file
@@ -0,0 +1,92 @@
|
||||
package v5
|
||||
|
||||
import (
|
||||
"github.com/luscis/openlan/cmd/api"
|
||||
"github.com/luscis/openlan/pkg/schema"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type Rate struct {
|
||||
Cmd
|
||||
}
|
||||
|
||||
func (u Rate) Url(prefix, name string) string {
|
||||
return prefix + "/api/interface/" + name + "/rate"
|
||||
}
|
||||
|
||||
func (u Rate) Tmpl() string {
|
||||
return `# total {{ len . }}
|
||||
{{ps -16 "device"}} {{ps -8 "speed"}}
|
||||
{{- range . }}
|
||||
{{ps -16 .Device}} {{pi .Speed}}
|
||||
{{- end }}
|
||||
`
|
||||
}
|
||||
|
||||
func (u Rate) List(c *cli.Context) error {
|
||||
url := u.Url(c.String("url"), "")
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
var items []schema.Rate
|
||||
if err := clt.GetJSON(url, &items); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.Out(items, c.String("format"), u.Tmpl())
|
||||
}
|
||||
|
||||
func (u Rate) Add(c *cli.Context) error {
|
||||
name := c.String("device")
|
||||
rate := &schema.Rate{
|
||||
Device: name,
|
||||
Speed: c.Int("speed"),
|
||||
}
|
||||
url := u.Url(c.String("url"), name)
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
if err := clt.PostJSON(url, rate, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u Rate) Remove(c *cli.Context) error {
|
||||
name := c.String("device")
|
||||
|
||||
url := u.Url(c.String("url"), name)
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
if err := clt.DeleteJSON(url, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u Rate) Commands(app *api.App) {
|
||||
app.Command(&cli.Command{
|
||||
Name: "rate",
|
||||
Usage: "Rate Limit",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "Display all rate limits",
|
||||
Aliases: []string{"ls"},
|
||||
Action: u.List,
|
||||
},
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "Add a rate limit",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "device", Required: true},
|
||||
&cli.StringFlag{Name: "speed", Required: true},
|
||||
},
|
||||
Action: u.Add,
|
||||
},
|
||||
{
|
||||
Name: "remove",
|
||||
Usage: "Remove a rate limit",
|
||||
Aliases: []string{"rm"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "device", Required: true},
|
||||
},
|
||||
Action: u.Remove,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
@@ -9,6 +9,11 @@ import (
|
||||
"github.com/luscis/openlan/pkg/schema"
|
||||
)
|
||||
|
||||
type Rater interface {
|
||||
AddRate(device string, mbit int)
|
||||
DelRate(device string)
|
||||
}
|
||||
|
||||
type Switcher interface {
|
||||
UUID() string
|
||||
UpTime() int64
|
||||
@@ -20,6 +25,7 @@ type Switcher interface {
|
||||
AddNetwork(network string)
|
||||
DelNetwork(network string)
|
||||
SaveNetwork(network string)
|
||||
Rater
|
||||
}
|
||||
|
||||
func NewWorkerSchema(s Switcher) schema.Worker {
|
||||
@@ -89,8 +95,6 @@ type Super interface {
|
||||
Start(v Switcher)
|
||||
Stop()
|
||||
Reload(v Switcher)
|
||||
DoZTrust()
|
||||
UndoZTrust()
|
||||
}
|
||||
|
||||
type Networker interface {
|
||||
@@ -108,6 +112,8 @@ type Networker interface {
|
||||
Qoser() Qoser
|
||||
ACLer() ACLer
|
||||
FindHoper() FindHoper
|
||||
DoZTrust()
|
||||
UndoZTrust()
|
||||
}
|
||||
|
||||
type IPSecer interface {
|
||||
|
35
pkg/api/rate.go
Executable file
35
pkg/api/rate.go
Executable file
@@ -0,0 +1,35 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/luscis/openlan/pkg/schema"
|
||||
)
|
||||
|
||||
type Rate struct {
|
||||
Switcher Switcher
|
||||
}
|
||||
|
||||
func (h Rate) Router(router *mux.Router) {
|
||||
router.HandleFunc("/api/interface/{id}/rate", h.Post).Methods("POST")
|
||||
router.HandleFunc("/api/interface/{id}/rate", h.Delete).Methods("DELETE")
|
||||
}
|
||||
|
||||
func (h Rate) Post(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
device := vars["id"]
|
||||
|
||||
rate := &schema.Rate{}
|
||||
if err := GetData(r, rate); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
h.Switcher.AddRate(device, rate.Speed)
|
||||
}
|
||||
|
||||
func (h Rate) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
device := vars["id"]
|
||||
h.Switcher.DelRate(device)
|
||||
}
|
@@ -14,7 +14,6 @@ func Add(router *mux.Router, switcher Switcher) {
|
||||
Device{}.Router(router)
|
||||
VPNClient{}.Router(router)
|
||||
PProf{}.Router(router)
|
||||
VxLAN{}.Router(router)
|
||||
Config{Switcher: switcher}.Router(router)
|
||||
Version{}.Router(router)
|
||||
Log{}.Router(router)
|
||||
@@ -26,4 +25,5 @@ func Add(router *mux.Router, switcher Switcher) {
|
||||
Route{Switcher: switcher}.Router(router)
|
||||
IPSec{}.Router(router)
|
||||
FindHop{}.Router(router)
|
||||
Rate{Switcher: switcher}.Router(router)
|
||||
}
|
||||
|
@@ -1,20 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type VxLAN struct {
|
||||
Switcher Switcher
|
||||
}
|
||||
|
||||
func (l VxLAN) Router(router *mux.Router) {
|
||||
router.HandleFunc("/api/vxlan", l.List).Methods("GET")
|
||||
router.HandleFunc("/api/vxlan/{id}", l.List).Methods("GET")
|
||||
}
|
||||
|
||||
func (l VxLAN) List(w http.ResponseWriter, r *http.Request) {
|
||||
ResponseJson(w, nil)
|
||||
}
|
6
pkg/schema/rate.go
Normal file
6
pkg/schema/rate.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package schema
|
||||
|
||||
type Rate struct {
|
||||
Device string `json:"device"`
|
||||
Speed int `json:"speed"` // Mbit
|
||||
}
|
@@ -2,6 +2,7 @@ package cswitch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -599,3 +600,21 @@ func (v *Switch) Reload() {
|
||||
func (v *Switch) Save() {
|
||||
v.cfg.Save()
|
||||
}
|
||||
|
||||
func (v *Switch) AddRate(device string, mbit int) {
|
||||
kbits := fmt.Sprintf("%dMbit", mbit)
|
||||
burst := "64Kb"
|
||||
latency := "400ms"
|
||||
|
||||
out, err := libol.Exec("tc", "qdisc", "add", "dev", device, "root", "tbf", "rate", kbits, "burst", burst, "latency", latency)
|
||||
if err != nil {
|
||||
v.out.Warn("Switch.AddRate: %s %d %s", device, mbit, out)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Switch) DelRate(device string) {
|
||||
out, err := libol.Exec("tc", "qdisc", "del", "dev", device, "root")
|
||||
if err != nil {
|
||||
v.out.Warn("Switch.AddRate: %s %s", device, out)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user