mirror of
https://github.com/luscis/openlan.git
synced 2025-10-08 10:00:12 +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 enable --router-id 1.1.1.1 --local-as 30
|
||||||
// openlan bgp disable
|
// 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 {
|
type BGP struct {
|
||||||
Cmd
|
Cmd
|
||||||
@@ -76,6 +78,8 @@ func (b BGP) Commands(app *api.App) {
|
|||||||
Action: b.Disable,
|
Action: b.Disable,
|
||||||
},
|
},
|
||||||
Neighbor{}.Commands(),
|
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
|
Get() *schema.Bgp
|
||||||
AddNeighbor(data schema.BgpNeighbor)
|
AddNeighbor(data schema.BgpNeighbor)
|
||||||
DelNeighbor(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 {
|
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", h.Remove).Methods("DELETE")
|
||||||
router.HandleFunc("/api/network/bgp/neighbor", h.RemoveNeighbor).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/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) {
|
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)
|
Call.bgper.AddNeighbor(nei)
|
||||||
ResponseMsg(w, 0, "")
|
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, "")
|
||||||
|
}
|
||||||
|
@@ -3,11 +3,13 @@ package config
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type BgpNeighbor struct {
|
type BgpNeighbor struct {
|
||||||
Name string `json:"-" yaml:"-"`
|
Name string `json:"-" yaml:"-"`
|
||||||
Address string `json:"address" yaml:"address"`
|
Address string `json:"address" yaml:"address"`
|
||||||
RemoteAs int `json:"remoteas" yaml:"remoteas"`
|
RemoteAs int `json:"remoteas" yaml:"remoteas"`
|
||||||
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||||
State string `json:"state,omitempty" yaml:"state,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() {
|
func (s *BgpNeighbor) Correct() {
|
||||||
@@ -17,6 +19,56 @@ func (s *BgpNeighbor) Id() string {
|
|||||||
return fmt.Sprintf("%s", s.Address)
|
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 {
|
type BgpSpecifies struct {
|
||||||
Name string `json:"-" yaml:"-"`
|
Name string `json:"-" yaml:"-"`
|
||||||
LocalAs int `json:"localas" yaml:"localas"`
|
LocalAs int `json:"localas" yaml:"localas"`
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
package schema
|
package schema
|
||||||
|
|
||||||
type BgpNeighbor struct {
|
type BgpNeighbor struct {
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
RemoteAs int `json:"remoteas"`
|
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 {
|
type Bgp struct {
|
||||||
@@ -11,3 +13,8 @@ type Bgp struct {
|
|||||||
RouterId string `json:"routerid"`
|
RouterId string `json:"routerid"`
|
||||||
Neighbors []BgpNeighbor `json:"neighbors"`
|
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
|
exit-address-family
|
||||||
!
|
!
|
||||||
|
|
||||||
{{- range .Neighbors }}
|
{{- range $nei := .Neighbors }}
|
||||||
ip prefix-list {{ .Address }}-out seq 10 permit any
|
{{- range $seq, $prefix := .Advertis }}
|
||||||
ip prefix-list {{ .Address }}-in seq 10 permit any
|
ip prefix-list {{ $nei.Address }}-out seq {{ inc $seq }} permit {{ $prefix }} le 32
|
||||||
{{- end }}
|
{{- 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 }}
|
{{- range .Neighbors }}
|
||||||
route-map {{ .Address }}-in permit 10
|
route-map {{ .Address }}-in permit 10
|
||||||
@@ -81,7 +88,13 @@ func (w *BgpWorker) save() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer out.Close()
|
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)
|
w.out.Warn("BgpWorker.save: %s", err)
|
||||||
} else {
|
} else {
|
||||||
if err := obj.Execute(out, w.spec); err != nil {
|
if err := obj.Execute(out, w.spec); err != nil {
|
||||||
@@ -130,6 +143,8 @@ func (w *BgpWorker) Get() *schema.Bgp {
|
|||||||
obj := schema.BgpNeighbor{
|
obj := schema.BgpNeighbor{
|
||||||
Address: nei.Address,
|
Address: nei.Address,
|
||||||
RemoteAs: nei.RemoteAs,
|
RemoteAs: nei.RemoteAs,
|
||||||
|
Receives: nei.Receives,
|
||||||
|
Advertis: nei.Advertis,
|
||||||
}
|
}
|
||||||
data.Neighbors = append(data.Neighbors, obj)
|
data.Neighbors = append(data.Neighbors, obj)
|
||||||
}
|
}
|
||||||
@@ -163,3 +178,47 @@ func (w *BgpWorker) DelNeighbor(data schema.BgpNeighbor) {
|
|||||||
w.reload()
|
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