diff --git a/dist/rootfs/etc/openlan/switch/network/router.json.example b/dist/rootfs/etc/openlan/switch/network/router.json.example index eb31d77..d2f00c9 100755 --- a/dist/rootfs/etc/openlan/switch/network/router.json.example +++ b/dist/rootfs/etc/openlan/switch/network/router.json.example @@ -10,6 +10,18 @@ { "cidr": "192.168.1.0/24" } + ], + "tunnels": [ + { + "protocol": "gre", + "remote": "100.100.1.1", + "address": "1.1.1.1" + }, + { + "protocol": "ipip", + "remote": "100.100.1.1", + "address": "1.1.2.1" + } ] }, "routes": [ diff --git a/pkg/config/common.go b/pkg/config/common.go index dbd29c9..499564e 100755 --- a/pkg/config/common.go +++ b/pkg/config/common.go @@ -9,11 +9,20 @@ import ( "github.com/luscis/openlan/pkg/libol" ) -var index = 99 +var genindexs map[string]int -func GenName(prefix string) string { +func init() { + genindexs = make(map[string]int, 32) +} + +func GenName(name string) string { + index, ok := genindexs[name] + if !ok { + index = 99 + } index += 1 - return fmt.Sprintf("%s%d", prefix, index) + genindexs[name] = index + return fmt.Sprintf("%s%d", name, index) } func VarDir(name ...string) string { diff --git a/pkg/config/output.go b/pkg/config/output.go index dd0a5eb..7d9a4ea 100755 --- a/pkg/config/output.go +++ b/pkg/config/output.go @@ -23,15 +23,15 @@ func (o *Output) Id() string { } func (o *Output) GenName() { - if o.Link == "" { - if o.Protocol == "gre" { - o.Link = fmt.Sprintf("%s%d", "gre", o.Segment) - } else if o.Protocol == "vxlan" { - o.Link = fmt.Sprintf("%s%d", "vxlan", o.Segment) - } else if o.Protocol == "tcp" || o.Protocol == "tls" || - o.Protocol == "wss" { - o.Link = o.Remote - } else if o.Segment > 0 { + switch o.Protocol { + case "gre": + o.Link = fmt.Sprintf("%s%d", "gei", o.Segment) + case "vxlan": + o.Link = fmt.Sprintf("%s%d", "xei", o.Segment) + case "tcp", "tls", "wss": + o.Link = o.Remote + default: + if o.Segment > 0 { o.Link = fmt.Sprintf("%s.%d", o.Remote, o.Segment) } else { o.Link = o.Remote diff --git a/pkg/config/router.go b/pkg/config/router.go index 088ff3c..da1fd74 100644 --- a/pkg/config/router.go +++ b/pkg/config/router.go @@ -1,13 +1,49 @@ package config +import ( + "fmt" + "strings" +) + +type RouterTunnel struct { + Link string `json:"link,omitempty" yaml:"link,omitempty"` + Remote string `json:"remote,omitempty" yaml:"remote,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + Address string `json:"address,omitempty" yaml:"address,omitempty"` +} + +func (t *RouterTunnel) Id() string { + return fmt.Sprintf("%s-%s", t.Protocol, t.Remote) +} + +func (t *RouterTunnel) Correct() { + if t.Protocol == "" { + t.Protocol = "gre" + } + switch t.Protocol { + case "gre": + t.Link = GenName("gre") + case "ipip": + t.Link = GenName("ipi") + } + + if t.Address != "" && !strings.Contains(t.Address, "/") { + t.Address = t.Address + "/30" + } +} + type RouterSpecifies struct { - Mss int `json:"tcpMss,omitempty" yaml:"tcpMss,omitempty"` - Name string `json:"-" yaml:"-"` - Link string `json:"link,omitempty" yaml:"link,omitempty"` - Subnets []Subnet `json:"subnets,omitempty" yaml:"subnets,omitempty"` - Loopback string `json:"loopback,omitempty" yaml:"loopback,omitempty"` - Addresses []string `json:"addresses,omitempty" yaml:"addresses,omitempty"` + Mss int `json:"tcpMss,omitempty" yaml:"tcpMss,omitempty"` + Name string `json:"-" yaml:"-"` + Link string `json:"link,omitempty" yaml:"link,omitempty"` + Subnets []*Subnet `json:"subnets,omitempty" yaml:"subnets,omitempty"` + Loopback string `json:"loopback,omitempty" yaml:"loopback,omitempty"` + Addresses []string `json:"addresses,omitempty" yaml:"addresses,omitempty"` + Tunnels []*RouterTunnel `json:"tunnels,omitempty" yaml:"tunnels,omitempty"` } func (n *RouterSpecifies) Correct() { + for _, t := range n.Tunnels { + t.Correct() + } } diff --git a/pkg/switch/router_linux.go b/pkg/switch/router_linux.go index ddfe12f..e3c9c89 100755 --- a/pkg/switch/router_linux.go +++ b/pkg/switch/router_linux.go @@ -3,6 +3,7 @@ package cswitch import ( "github.com/luscis/openlan/pkg/api" co "github.com/luscis/openlan/pkg/config" + "github.com/luscis/openlan/pkg/libol" nl "github.com/vishvananda/netlink" ) @@ -71,6 +72,11 @@ func (w *RouterWorker) addAddress() error { func (w *RouterWorker) Start(v api.SwitchApi) { w.uuid = v.UUID() + + for _, tun := range w.spec.Tunnels { + w.AddTunnel(tun) + } + w.WorkerImpl.Start(v) w.addAddress() } @@ -94,6 +100,10 @@ func (w *RouterWorker) delAddress() error { func (w *RouterWorker) Stop() { w.delAddress() w.WorkerImpl.Stop() + + for _, tun := range w.spec.Tunnels { + w.DelTunnel(tun) + } } func (w *RouterWorker) Reload(v api.SwitchApi) { @@ -101,3 +111,61 @@ func (w *RouterWorker) Reload(v api.SwitchApi) { w.Initialize() w.Start(v) } + +func (w *RouterWorker) AddTunnel(data *co.RouterTunnel) { + var link nl.Link + + switch data.Protocol { + case "gre": + link = &nl.Gretun{ + LinkAttrs: nl.LinkAttrs{ + Name: data.Link, + }, + Local: libol.ParseAddr("0.0.0.0"), + Remote: libol.ParseAddr(data.Remote), + } + if err := nl.LinkAdd(link); err != nil { + w.out.Error("WorkerImpl.AddTunnel.gre %s %s", data.Id(), err) + return + } + case "ipip": + link = &nl.Iptun{ + LinkAttrs: nl.LinkAttrs{ + Name: data.Link, + }, + Local: libol.ParseAddr("0.0.0.0"), + Remote: libol.ParseAddr(data.Remote), + } + if err := nl.LinkAdd(link); err != nil { + w.out.Error("WorkerImpl.AddTunnel.ip %s %s", data.Id(), err) + return + } + } + + if link == nil { + return + } + + addr, err := nl.ParseAddr(data.Address) + if err == nil { + if err := nl.AddrAdd(link, addr); err != nil { + w.out.Warn("WorkerImpl.AddTunnel.addAddr: %s: %s", addr, err) + return + } + } + if err := nl.LinkSetUp(link); err != nil { + w.out.Warn("WorkerImpl.AddTunnel.up: %s: %s", data.Id(), err) + } +} + +func (w *RouterWorker) DelTunnel(data *co.RouterTunnel) { + if data.Link == "" { + return + } + if link, err := nl.LinkByName(data.Link); err == nil { + if err := nl.LinkDel(link); err != nil { + w.out.Error("WorkerImpl.DelTunnel %s %s", data.Id(), err) + return + } + } +}