-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
fea: support add or del acl rule
1 parent
7187561
commit 34c452c
Showing
7 changed files
with
322 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package api | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/gorilla/mux" | ||
"github.com/luscis/openlan/pkg/schema" | ||
) | ||
|
||
type ACL struct { | ||
Switcher Switcher | ||
} | ||
|
||
func (h ACL) Router(router *mux.Router) { | ||
router.HandleFunc("/api/network/{id}/acl", h.List).Methods("GET") | ||
router.HandleFunc("/api/network/{id}/acl", h.Add).Methods("POST") | ||
router.HandleFunc("/api/network/{id}/acl", h.Del).Methods("DELETE") | ||
} | ||
|
||
func (h ACL) List(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.StatusInternalServerError) | ||
return | ||
} | ||
acl := worker.ACLer() | ||
|
||
rules := make([]schema.ACLRule, 0, 1024) | ||
acl.ListRules(func(obj schema.ACLRule) { | ||
rules = append(rules, obj) | ||
}) | ||
|
||
ResponseJson(w, rules) | ||
} | ||
|
||
func (h ACL) Add(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.StatusInternalServerError) | ||
return | ||
} | ||
acl := worker.ACLer() | ||
|
||
rule := &schema.ACLRule{} | ||
if err := GetData(r, rule); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
if err := acl.AddRule(rule); err == nil { | ||
ResponseJson(w, "success") | ||
} else { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
} | ||
|
||
func (h ACL) Del(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.StatusInternalServerError) | ||
return | ||
} | ||
acl := worker.ACLer() | ||
|
||
rule := &schema.ACLRule{} | ||
if err := GetData(r, rule); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
if err := acl.DelRule(rule); err == nil { | ||
ResponseJson(w, "success") | ||
} else { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package cswitch | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/luscis/openlan/pkg/libol" | ||
cn "github.com/luscis/openlan/pkg/network" | ||
"github.com/luscis/openlan/pkg/schema" | ||
) | ||
|
||
type ACLRule struct { | ||
SrcIp string | ||
DstIp string | ||
Proto string // TCP, UDP or ICMP | ||
SrcPort int | ||
DstPort int | ||
Action string // DROP or ACCEPT | ||
rule *cn.IPRule | ||
} | ||
|
||
func (r *ACLRule) Id() string { | ||
return fmt.Sprintf("%s:%s:%s:%d:%d", r.SrcIp, r.DstIp, r.Proto, r.DstPort, r.SrcPort) | ||
} | ||
|
||
func (r *ACLRule) Rule() cn.IPRule { | ||
if r.rule == nil { | ||
r.rule = &cn.IPRule{ | ||
Dest: r.DstIp, | ||
Source: r.SrcIp, | ||
Proto: r.Proto, | ||
Jump: r.Action, | ||
} | ||
if r.DstPort > 0 { | ||
r.rule.DstPort = strconv.Itoa(r.DstPort) | ||
} | ||
if r.SrcPort > 0 { | ||
r.rule.SrcPort = strconv.Itoa(r.SrcPort) | ||
} | ||
} | ||
return *r.rule | ||
} | ||
|
||
type ACL struct { | ||
Name string | ||
Rules map[string]*ACLRule | ||
chain *cn.FireWallChain | ||
out *libol.SubLogger | ||
} | ||
|
||
func NewACL(name string) *ACL { | ||
return &ACL{ | ||
Name: name, | ||
out: libol.NewSubLogger(name), | ||
Rules: make(map[string]*ACLRule, 32), | ||
} | ||
} | ||
|
||
func (a *ACL) Chain() string { | ||
return "ATT_" + a.Name | ||
} | ||
|
||
func (a *ACL) Initialize() { | ||
a.chain = cn.NewFireWallChain(a.Chain(), cn.TRaw, "") | ||
} | ||
|
||
func (a *ACL) Start() { | ||
a.out.Info("ACL.Start") | ||
a.chain.Install() | ||
} | ||
|
||
func (a *ACL) Stop() { | ||
a.out.Info("ACL.Stop") | ||
a.chain.Cancel() | ||
} | ||
|
||
func (a *ACL) AddRule(rule *schema.ACLRule) error { | ||
ar := &ACLRule{ | ||
Proto: rule.Proto, | ||
DstIp: rule.DstIp, | ||
SrcIp: rule.SrcIp, | ||
DstPort: rule.DstPort, | ||
SrcPort: rule.SrcPort, | ||
Action: rule.Action, | ||
} | ||
|
||
a.out.Info("ACL.AddRule %s", ar.Id()) | ||
|
||
if _, ok := a.Rules[ar.Id()]; ok { | ||
return libol.NewErr("AddRule: already existed") | ||
} | ||
|
||
if err := a.chain.AddRuleX(ar.Rule()); err == nil { | ||
a.Rules[ar.Id()] = ar | ||
} else { | ||
a.out.Warn("ACL.AddRule %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *ACL) DelRule(rule *schema.ACLRule) error { | ||
ar := &ACLRule{ | ||
Proto: rule.Proto, | ||
DstIp: rule.DstIp, | ||
SrcIp: rule.SrcIp, | ||
DstPort: rule.DstPort, | ||
SrcPort: rule.SrcPort, | ||
Action: rule.Action, | ||
} | ||
|
||
a.out.Info("ACL.DelRule %s", ar.Id()) | ||
|
||
if _, ok := a.Rules[ar.Id()]; !ok { | ||
return nil | ||
} | ||
|
||
if err := a.chain.DelRuleX(ar.Rule()); err == nil { | ||
delete(a.Rules, ar.Id()) | ||
} else { | ||
a.out.Warn("ACL.DelRule %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *ACL) ListRules(call func(obj schema.ACLRule)) { | ||
for _, rule := range a.Rules { | ||
obj := schema.ACLRule{ | ||
SrcIp: rule.SrcIp, | ||
DstIp: rule.DstIp, | ||
SrcPort: rule.SrcPort, | ||
DstPort: rule.DstPort, | ||
Proto: rule.Proto, | ||
Action: rule.Action, | ||
} | ||
call(obj) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters