mirror of
https://github.com/luscis/openlan.git
synced 2025-10-09 18:40:04 +08:00
fea: ip prefix rules for route-map.
This commit is contained in:
@@ -8,7 +8,9 @@ import (
|
||||
|
||||
// openlan bgp enable --router-id 1.1.1.1 --local-as 30
|
||||
// openlan bgp disable
|
||||
// openlan bgp add neighbor --address 1.1.1.2 --remote-as 32
|
||||
// openlan bgp neighbor add --address 1.1.1.2 --remote-as 32
|
||||
// openlan bgp advertis add --neighbor 1.1.1.2 --prefix 192.168.1.0/24
|
||||
// openlan bgp receives add --neighbor 1.1.1.2 --prefix 192.168.2.0/24
|
||||
|
||||
type BGP struct {
|
||||
Cmd
|
||||
@@ -76,6 +78,8 @@ func (b BGP) Commands(app *api.App) {
|
||||
Action: b.Disable,
|
||||
},
|
||||
Neighbor{}.Commands(),
|
||||
Advertis{}.Commands(),
|
||||
Receives{}.Commands(),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -139,3 +143,127 @@ func (s Neighbor) Commands() *cli.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Advertis struct {
|
||||
Cmd
|
||||
}
|
||||
|
||||
func (s Advertis) Url(prefix string) string {
|
||||
return prefix + "/api/network/bgp/advertis"
|
||||
}
|
||||
|
||||
func (s Advertis) Add(c *cli.Context) error {
|
||||
data := &schema.BgpPrefix{
|
||||
Prefix: c.String("prefix"),
|
||||
Neighbor: c.String("neighbor"),
|
||||
}
|
||||
url := s.Url(c.String("url"))
|
||||
clt := s.NewHttp(c.String("token"))
|
||||
if err := clt.PostJSON(url, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Advertis) Remove(c *cli.Context) error {
|
||||
data := &schema.BgpPrefix{
|
||||
Prefix: c.String("prefix"),
|
||||
Neighbor: c.String("neighbor"),
|
||||
}
|
||||
url := s.Url(c.String("url"))
|
||||
clt := s.NewHttp(c.String("token"))
|
||||
if err := clt.DeleteJSON(url, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Advertis) Commands() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "advertis",
|
||||
Usage: "Neighbor advertised routes",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "Add advertis prefix",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "neighbor", Required: true},
|
||||
&cli.StringFlag{Name: "prefix", Required: true},
|
||||
},
|
||||
Action: s.Add,
|
||||
},
|
||||
{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Remove advertis prefix",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "neighbor", Required: true},
|
||||
&cli.StringFlag{Name: "prefix", Required: true},
|
||||
},
|
||||
Action: s.Remove,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Receives struct {
|
||||
Cmd
|
||||
}
|
||||
|
||||
func (s Receives) Url(prefix string) string {
|
||||
return prefix + "/api/network/bgp/receives"
|
||||
}
|
||||
|
||||
func (s Receives) Add(c *cli.Context) error {
|
||||
data := &schema.BgpPrefix{
|
||||
Prefix: c.String("prefix"),
|
||||
Neighbor: c.String("neighbor"),
|
||||
}
|
||||
url := s.Url(c.String("url"))
|
||||
clt := s.NewHttp(c.String("token"))
|
||||
if err := clt.PostJSON(url, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Receives) Remove(c *cli.Context) error {
|
||||
data := &schema.BgpPrefix{
|
||||
Prefix: c.String("prefix"),
|
||||
Neighbor: c.String("neighbor"),
|
||||
}
|
||||
url := s.Url(c.String("url"))
|
||||
clt := s.NewHttp(c.String("token"))
|
||||
if err := clt.DeleteJSON(url, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Receives) Commands() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "receives",
|
||||
Usage: "Neighbor received prefix",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "Add received prefix",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "neighbor", Required: true},
|
||||
&cli.StringFlag{Name: "prefix", Required: true},
|
||||
},
|
||||
Action: s.Add,
|
||||
},
|
||||
{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Remove received prefix",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "neighbor", Required: true},
|
||||
&cli.StringFlag{Name: "prefix", Required: true},
|
||||
},
|
||||
Action: s.Remove,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -131,6 +131,10 @@ type Bgper interface {
|
||||
Get() *schema.Bgp
|
||||
AddNeighbor(data schema.BgpNeighbor)
|
||||
DelNeighbor(data schema.BgpNeighbor)
|
||||
AddReceives(data schema.BgpPrefix)
|
||||
DelReceives(data schema.BgpPrefix)
|
||||
AddAdvertis(data schema.BgpPrefix)
|
||||
DelAdvertis(data schema.BgpPrefix)
|
||||
}
|
||||
|
||||
type APICall struct {
|
||||
|
@@ -18,6 +18,10 @@ func (h Bgp) Router(router *mux.Router) {
|
||||
router.HandleFunc("/api/network/bgp", h.Remove).Methods("DELETE")
|
||||
router.HandleFunc("/api/network/bgp/neighbor", h.RemoveNeighbor).Methods("DELETE")
|
||||
router.HandleFunc("/api/network/bgp/neighbor", h.AddNeighbor).Methods("POST")
|
||||
router.HandleFunc("/api/network/bgp/advertis", h.RemoveAdvertis).Methods("DELETE")
|
||||
router.HandleFunc("/api/network/bgp/advertis", h.AddAdvertis).Methods("POST")
|
||||
router.HandleFunc("/api/network/bgp/receives", h.RemoveReceivess).Methods("DELETE")
|
||||
router.HandleFunc("/api/network/bgp/receives", h.AddReceivess).Methods("POST")
|
||||
}
|
||||
|
||||
func (h Bgp) Get(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -80,3 +84,59 @@ func (h Bgp) AddNeighbor(w http.ResponseWriter, r *http.Request) {
|
||||
Call.bgper.AddNeighbor(nei)
|
||||
ResponseMsg(w, 0, "")
|
||||
}
|
||||
|
||||
func (h Bgp) RemoveAdvertis(w http.ResponseWriter, r *http.Request) {
|
||||
data := schema.BgpPrefix{}
|
||||
if err := GetData(r, &data); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if Call.bgper == nil {
|
||||
http.Error(w, "network is nil", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
Call.bgper.DelAdvertis(data)
|
||||
ResponseMsg(w, 0, "")
|
||||
}
|
||||
|
||||
func (h Bgp) AddAdvertis(w http.ResponseWriter, r *http.Request) {
|
||||
data := schema.BgpPrefix{}
|
||||
if err := GetData(r, &data); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if Call.bgper == nil {
|
||||
http.Error(w, "network is nil", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
Call.bgper.AddAdvertis(data)
|
||||
ResponseMsg(w, 0, "")
|
||||
}
|
||||
|
||||
func (h Bgp) RemoveReceivess(w http.ResponseWriter, r *http.Request) {
|
||||
data := schema.BgpPrefix{}
|
||||
if err := GetData(r, &data); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if Call.bgper == nil {
|
||||
http.Error(w, "network is nil", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
Call.bgper.DelReceives(data)
|
||||
ResponseMsg(w, 0, "")
|
||||
}
|
||||
|
||||
func (h Bgp) AddReceivess(w http.ResponseWriter, r *http.Request) {
|
||||
data := schema.BgpPrefix{}
|
||||
if err := GetData(r, &data); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if Call.bgper == nil {
|
||||
http.Error(w, "network is nil", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
Call.bgper.AddReceives(data)
|
||||
ResponseMsg(w, 0, "")
|
||||
}
|
||||
|
@@ -8,6 +8,8 @@ type BgpNeighbor struct {
|
||||
RemoteAs int `json:"remoteas" yaml:"remoteas"`
|
||||
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||
State string `json:"state,omitempty" yaml:"state,omitempty"`
|
||||
Advertis []string `json:"advertis,omitempty" yaml:"advertis,omitempty"`
|
||||
Receives []string `json:"receives,omitempty" yaml:"receives,omitempty"`
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) Correct() {
|
||||
@@ -17,6 +19,56 @@ func (s *BgpNeighbor) Id() string {
|
||||
return fmt.Sprintf("%s", s.Address)
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) FindReceives(value string) int {
|
||||
for index, obj := range s.Receives {
|
||||
if obj == value {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) AddReceives(value string) bool {
|
||||
find := s.FindReceives(value)
|
||||
if find == -1 {
|
||||
s.Receives = append(s.Receives, value)
|
||||
}
|
||||
return find == -1
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) DelReceives(value string) bool {
|
||||
find := s.FindReceives(value)
|
||||
if find != -1 {
|
||||
s.Receives = append(s.Receives[:find], s.Receives[find+1:]...)
|
||||
}
|
||||
return find != -1
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) FindAdvertis(value string) int {
|
||||
for index, obj := range s.Advertis {
|
||||
if obj == value {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) AddAdvertis(value string) bool {
|
||||
find := s.FindAdvertis(value)
|
||||
if find == -1 {
|
||||
s.Advertis = append(s.Advertis, value)
|
||||
}
|
||||
return find == -1
|
||||
}
|
||||
|
||||
func (s *BgpNeighbor) DelAdvertis(value string) bool {
|
||||
find := s.FindAdvertis(value)
|
||||
if find != -1 {
|
||||
s.Advertis = append(s.Advertis[:find], s.Advertis[find+1:]...)
|
||||
}
|
||||
return find != -1
|
||||
}
|
||||
|
||||
type BgpSpecifies struct {
|
||||
Name string `json:"-" yaml:"-"`
|
||||
LocalAs int `json:"localas" yaml:"localas"`
|
||||
|
@@ -3,7 +3,9 @@ package schema
|
||||
type BgpNeighbor struct {
|
||||
Address string `json:"address"`
|
||||
RemoteAs int `json:"remoteas"`
|
||||
State string `json:"state"`
|
||||
State string `json:"state,omitempty" yaml:"state,omitempty"`
|
||||
Advertis []string `json:"advertis"`
|
||||
Receives []string `json:"receives"`
|
||||
}
|
||||
|
||||
type Bgp struct {
|
||||
@@ -11,3 +13,8 @@ type Bgp struct {
|
||||
RouterId string `json:"routerid"`
|
||||
Neighbors []BgpNeighbor `json:"neighbors"`
|
||||
}
|
||||
|
||||
type BgpPrefix struct {
|
||||
Prefix string `json:"prefix"`
|
||||
Neighbor string `json:"neighbor"`
|
||||
}
|
||||
|
@@ -50,10 +50,17 @@ router bgp {{ .LocalAs }}
|
||||
exit-address-family
|
||||
!
|
||||
|
||||
{{- range .Neighbors }}
|
||||
ip prefix-list {{ .Address }}-out seq 10 permit any
|
||||
ip prefix-list {{ .Address }}-in seq 10 permit any
|
||||
{{- range $nei := .Neighbors }}
|
||||
{{- range $seq, $prefix := .Advertis }}
|
||||
ip prefix-list {{ $nei.Address }}-out seq {{ inc $seq }} permit {{ $prefix }} le 32
|
||||
{{- end }}
|
||||
ip prefix-list {{ $nei.Address }}-out seq 65535 deny any
|
||||
{{- range $seq, $prefix := .Receives }}
|
||||
ip prefix-list {{ $nei.Address }}-in seq {{ inc $seq }} permit {{ $prefix }} le 32
|
||||
{{- end }}
|
||||
ip prefix-list {{ $nei.Address }}-in seq 65535 deny any
|
||||
{{- end }}
|
||||
!
|
||||
|
||||
{{- range .Neighbors }}
|
||||
route-map {{ .Address }}-in permit 10
|
||||
@@ -81,7 +88,13 @@ func (w *BgpWorker) save() {
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
if obj, err := template.New("main").Parse(BgpTmpl); err != nil {
|
||||
|
||||
maps := template.FuncMap{
|
||||
"inc": func(i int) int {
|
||||
return i + 1
|
||||
},
|
||||
}
|
||||
if obj, err := template.New("main").Funcs(maps).Parse(BgpTmpl); err != nil {
|
||||
w.out.Warn("BgpWorker.save: %s", err)
|
||||
} else {
|
||||
if err := obj.Execute(out, w.spec); err != nil {
|
||||
@@ -130,6 +143,8 @@ func (w *BgpWorker) Get() *schema.Bgp {
|
||||
obj := schema.BgpNeighbor{
|
||||
Address: nei.Address,
|
||||
RemoteAs: nei.RemoteAs,
|
||||
Receives: nei.Receives,
|
||||
Advertis: nei.Advertis,
|
||||
}
|
||||
data.Neighbors = append(data.Neighbors, obj)
|
||||
}
|
||||
@@ -163,3 +178,47 @@ func (w *BgpWorker) DelNeighbor(data schema.BgpNeighbor) {
|
||||
w.reload()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *BgpWorker) AddReceives(data schema.BgpPrefix) {
|
||||
obj := &co.BgpNeighbor{
|
||||
Address: data.Neighbor,
|
||||
}
|
||||
if nei, _ := w.spec.FindNeighbor(obj); nei != nil {
|
||||
if nei.AddReceives(data.Prefix) {
|
||||
w.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *BgpWorker) DelReceives(data schema.BgpPrefix) {
|
||||
obj := &co.BgpNeighbor{
|
||||
Address: data.Neighbor,
|
||||
}
|
||||
if nei, _ := w.spec.FindNeighbor(obj); nei != nil {
|
||||
if nei.DelReceives(data.Prefix) {
|
||||
w.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *BgpWorker) AddAdvertis(data schema.BgpPrefix) {
|
||||
obj := &co.BgpNeighbor{
|
||||
Address: data.Neighbor,
|
||||
}
|
||||
if nei, _ := w.spec.FindNeighbor(obj); nei != nil {
|
||||
if nei.AddAdvertis(data.Prefix) {
|
||||
w.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *BgpWorker) DelAdvertis(data schema.BgpPrefix) {
|
||||
obj := &co.BgpNeighbor{
|
||||
Address: data.Neighbor,
|
||||
}
|
||||
if nei, _ := w.spec.FindNeighbor(obj); nei != nil {
|
||||
if nei.DelAdvertis(data.Prefix) {
|
||||
w.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user