fea: support tcp ceci.
Some checks failed
Coverage CI / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Ubuntu CI / build (push) Has been cancelled

This commit is contained in:
Daniel Ding
2025-11-13 19:43:18 +08:00
parent 6ef583eea2
commit 843999afa5
8 changed files with 251 additions and 11 deletions

View File

@@ -0,0 +1,20 @@
{
"name": "ceci",
"provider": "ceci",
"specifies": {
"tcp": [
{
"listen": "0.0.0.0:80",
"target": [
"192.168.1.11:80",
"192.168.1.12:80"
]
}
],
"http": [
{
"listen": "0.0.0.0:80"
}
]
}
}

View File

@@ -14,15 +14,20 @@ sysctl -p /etc/sysctl.d/90-openlan.conf
/usr/bin/env find /var/openlan/openvpn -name '*client.ovpn' -delete
/usr/bin/env find /var/openlan/openvpn -name '*client.tmpl' -delete
if [ ! -e /etc/openlan/switch/switch.yaml ]; then
cat > /etc/openlan/switch/switch.yaml << EOF
crypt
secret: cb2ff088a34d
cs_dir="/etc/openlan/switch"
if [ ! -e $cs_dir/switch.json ]; then
cat > $cs_dir/switch.json << EOF
{
"crypt": {
"secret": "cb2ff088a34d"
}
}
EOF
fi
if [ ! -e /etc/openlan/switch/network/ipsec.json ]; then
cat > /etc/openlan/switch/network/ipsec.json << EOF
if [ ! -e $cs_dir/network/ipsec.json ]; then
cat > $cs_dir/network/ipsec.json << EOF
{
"name": "ipsec",
"provider": "ipsec"
@@ -30,8 +35,8 @@ if [ ! -e /etc/openlan/switch/network/ipsec.json ]; then
EOF
fi
if [ ! -e /etc/openlan/switch/network/bgp.json ]; then
cat > /etc/openlan/switch/network/bgp.json << EOF
if [ ! -e $cs_dir/network/bgp.json ]; then
cat > $cs_dir/network/bgp.json << EOF
{
"name": "bgp",
"provider": "bgp"
@@ -39,11 +44,20 @@ if [ ! -e /etc/openlan/switch/network/bgp.json ]; then
EOF
fi
if [ ! -e $cs_dir/network/proxy.json ]; then
cat > $cs_dir/network/proxy.json << EOF
{
"name": "proxy",
"provider": "proxy"
}
EOF
fi
for dir in acl findhop link output route network qos dnat; do
if [ -e "/etc/openlan/switch/$dir" ]; then
if [ -e "$cs_dir/$dir" ]; then
continue
fi
mkdir -p "/etc/openlan/switch/$dir"
mkdir -p "$cs_dir/$dir"
done
# wait ipsec service
@@ -54,4 +68,4 @@ while true; do
sleep 5
done
exec /usr/bin/openlan-switch -conf:dir /etc/openlan/switch -log:level 20
exec /usr/bin/openlan-switch -conf:dir $cs_dir -log:level 20

99
pkg/config/ceci.go Normal file
View File

@@ -0,0 +1,99 @@
package config
import "fmt"
type CeciTcp struct {
Name string `json:"-" yaml:"-"`
Listen string `json:"listen" yaml:"listen"`
Target []string `json:"target,omitempty" yaml:"target,omitempty"`
}
func (s *CeciTcp) Correct() {
}
func (s *CeciTcp) Id() string {
return fmt.Sprintf("%s", s.Listen)
}
type CeciHttp struct {
Name string `json:"-" yaml:"-"`
Listen string `json:"listen" yaml:"listen"`
}
func (s *CeciHttp) Correct() {
}
func (s *CeciHttp) Id() string {
return fmt.Sprintf("%s", s.Listen)
}
type CeciSpecifies struct {
Name string `json:"-" yaml:"-"`
Tcp []*CeciTcp `json:"tcp" yaml:"tcp"`
Http []*CeciHttp `json:"http" yaml:"http"`
}
func (s *CeciSpecifies) Correct() {
if s.Tcp == nil {
s.Tcp = make([]*CeciTcp, 0)
}
for _, t := range s.Tcp {
t.Correct()
}
if s.Http == nil {
s.Http = make([]*CeciHttp, 0)
}
for _, t := range s.Http {
t.Correct()
}
}
func (s *CeciSpecifies) FindTcp(value *CeciTcp) (*CeciTcp, int) {
for index, obj := range s.Tcp {
if obj.Id() == value.Id() {
return obj, index
}
}
return nil, -1
}
func (s *CeciSpecifies) AddTcp(value *CeciTcp) bool {
_, find := s.FindTcp(value)
if find == -1 {
s.Tcp = append(s.Tcp, value)
}
return find == -1
}
func (s *CeciSpecifies) DelTcp(value *CeciTcp) (*CeciTcp, bool) {
obj, find := s.FindTcp(value)
if find != -1 {
s.Tcp = append(s.Tcp[:find], s.Tcp[find+1:]...)
}
return obj, find != -1
}
func (s *CeciSpecifies) FindHttp(value *CeciHttp) (*CeciHttp, int) {
for index, obj := range s.Http {
if obj.Id() == value.Id() {
return obj, index
}
}
return nil, -1
}
func (s *CeciSpecifies) AddHttp(value *CeciHttp) bool {
_, find := s.FindHttp(value)
if find == -1 {
s.Http = append(s.Http, value)
}
return find == -1
}
func (s *CeciSpecifies) DelHttp(value *CeciHttp) (*CeciHttp, bool) {
obj, find := s.FindHttp(value)
if find != -1 {
s.Http = append(s.Http[:find], s.Http[find+1:]...)
}
return obj, find != -1
}

View File

@@ -58,6 +58,8 @@ func (n *Network) NewSpecifies() any {
n.Specifies = &RouterSpecifies{}
case "bgp":
n.Specifies = &BgpSpecifies{}
case "ceci":
n.Specifies = &CeciSpecifies{}
default:
n.Specifies = nil
}
@@ -92,6 +94,12 @@ func (n *Network) Correct(sw *Switch) {
obj.Correct()
obj.Name = n.Name
}
case "ceci":
spec := n.Specifies
if obj, ok := spec.(*CeciSpecifies); ok {
obj.Correct()
obj.Name = n.Name
}
default:
br := n.Bridge
br.Network = n.Name
@@ -186,6 +194,7 @@ func (n *Network) Save() {
obj.Outputs = nil
obj.Dnat = nil
obj.FindHop = nil
if err := libol.MarshalSave(&obj, obj.File, true); err != nil {
libol.Error("Network.Save %s %s", obj.Name, err)
}

94
pkg/switch/ceci_linux.go Normal file
View File

@@ -0,0 +1,94 @@
package cswitch
import (
"os/exec"
"github.com/luscis/openlan/pkg/api"
co "github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
)
const (
CeciBin = "/usr/bin/openceci"
)
type CeciWorker struct {
*WorkerImpl
spec *co.CeciSpecifies
}
func NewCeciWorker(c *co.Network) *CeciWorker {
w := &CeciWorker{
WorkerImpl: NewWorkerApi(c),
}
w.spec, _ = c.Specifies.(*co.CeciSpecifies)
return w
}
func (w *CeciWorker) Initialize() {
w.out.Info("CeciWorker.Initialize")
}
func (w *CeciWorker) reloadTcp(obj *co.CeciTcp) {
name := "/var/openlan/ceci/" + obj.Id()
out, err := libol.CreateFile(name + ".log")
if err != nil {
w.out.Warn("CeciWorker.reloadTcp: %s", err)
return
}
libol.MarshalSave(obj, name+".yaml", true)
libol.Go(func() {
w.out.Info("CeciWorker.reloadTcp: %s", obj.Id())
cmd := exec.Command(CeciBin, "-mode", "tcp", "-conf", name+".yaml")
cmd.Stdout = out
cmd.Stderr = out
if err := cmd.Run(); err != nil {
w.out.Warn("CeciWorker.reloadTcp: %s", err)
return
}
})
}
func (w *CeciWorker) reloadHttp(obj *co.CeciHttp) {
name := "/var/openlan/ceci/" + obj.Id()
out, err := libol.CreateFile(name + ".log")
if err != nil {
w.out.Warn("CeciWorker.reloadTcp: %s", err)
return
}
libol.MarshalSave(obj, name+".yaml", true)
libol.Go(func() {
w.out.Info("CeciWorker.reloadHttp: %s", obj.Id())
cmd := exec.Command(CeciBin, "-mode", "http", "-conf", name+".yaml")
cmd.Stdout = out
cmd.Stderr = out
if err := cmd.Run(); err != nil {
w.out.Warn("CeciWorker.reloadHttp: %s", err)
return
}
})
}
func (w *CeciWorker) Start(v api.SwitchApi) {
w.uuid = v.UUID()
w.out.Info("CeciWorker.Start")
for _, obj := range w.spec.Tcp {
w.reloadTcp(obj)
}
for _, obj := range w.spec.Http {
w.reloadHttp(obj)
}
}
func (w *CeciWorker) Stop() {
w.out.Info("CeciWorker.Stop")
}
func (w *CeciWorker) Reload(v api.SwitchApi) {
w.Stop()
w.Initialize()
w.Start(v)
}

View File

@@ -32,6 +32,10 @@ func NewNetworker(c *co.Network) api.NetworkApi {
obj = bgper
case "router":
obj = NewRouterWorker(c)
case "ceci":
cecer := NewCeciWorker(c)
//api.Call.SetBgper(bgper)
obj = cecer
default:
obj = NewOpenLANWorker(c)
}