fea: gre tunnel for router.

This commit is contained in:
Daniel Ding
2025-11-24 15:42:43 +08:00
parent 81c06bd317
commit d031718da6
5 changed files with 143 additions and 18 deletions

View File

@@ -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": [

View File

@@ -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 {

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -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
}
}
}