feature: add a standalone dhcp relay service

This commit is contained in:
Qiu Jian
2021-04-05 23:17:26 +08:00
parent 4b4349fe7d
commit baabc82903
7 changed files with 136 additions and 7 deletions
@@ -0,0 +1,3 @@
INTERFACE=""
INTERFACE_IP=""
RELAY=""
@@ -0,0 +1,22 @@
[Unit]
Description=Yunion Cloud DHCP Relay Agent
Documentation=https://docs.yunion.cn
After=network-online.target
Wants=network-online.target
After=network.target
[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/yunion_dhcprelay
User=root
Group=root
ExecStart=/opt/yunion/bin/dhcprelay --interface "$INTERFACE" --ip "$IP" --relay "$RELAY"
WorkingDirectory=/opt/yunion/bin
KillMode=process
Restart=always
RestartSec=30
LimitNOFILE=500000
LimitNPROC=500000
[Install]
WantedBy=multi-user.target
+2
View File
@@ -0,0 +1,2 @@
DESCRIPTION="Yunion Tiny DHCP Relay Server"
SERVICE="yes"
+93
View File
@@ -0,0 +1,93 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/structarg"
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostdhcp"
"yunion.io/x/onecloud/pkg/util/atexit"
)
type Options struct {
Help bool `help:"Show help"`
Interface string `help:"Listening interface, e.g. eth0"`
Ip string `help:"Listening interface IP, e.g. 192.168.22.2"`
Port int `help:"listening port" default:"67"`
Relay string `help:"Relay server address, e.g. 192.168.22.23"`
}
func relayMain() error {
parse, err := structarg.NewArgumentParser(&Options{},
"dhcprelay",
"An independent dhcp relay.",
`See "dhcprelay --help" for help.`)
if err != nil {
return err
}
err = parse.ParseArgs(os.Args[1:], false)
options := parse.Options().(*Options)
if options.Help {
fmt.Print(parse.HelpString())
return errors.Error("Need help!")
}
if len(options.Interface) == 0 {
return errors.Error("Missing interface")
}
if len(options.Ip) == 0 {
return errors.Error("Missing interface IP")
}
if len(options.Relay) == 0 {
return errors.Error("Missing DHCP relay server")
}
srv, err := hostdhcp.NewGuestDHCPServer(options.Interface, options.Port, []string{
options.Relay, "67",
})
if err != nil {
return errors.Wrap(err, "NewGuestDHCPServer")
}
srv.Start(false)
srv.RelaySetup(options.Ip)
for {
time.Sleep(time.Hour)
}
return nil
}
func main() {
defer atexit.Handle()
err := relayMain()
if err != nil {
fmt.Fprintf(os.Stdout, "Error: %s", err)
os.Exit(-1)
}
}
+14 -5
View File
@@ -41,7 +41,7 @@ type SGuestDHCPServer struct {
iface string
}
func NewGuestDHCPServer(iface string, relay []string) (*SGuestDHCPServer, error) {
func NewGuestDHCPServer(iface string, port int, relay []string) (*SGuestDHCPServer, error) {
var (
err error
guestdhcp = new(SGuestDHCPServer)
@@ -51,7 +51,7 @@ func NewGuestDHCPServer(iface string, relay []string) (*SGuestDHCPServer, error)
return nil, fmt.Errorf("Wrong dhcp relay address")
}
guestdhcp.server, guestdhcp.conn, err = dhcp.NewDHCPServer2(iface, uint16(options.HostOptions.DhcpServerPort), DEFAULT_DHCP_CLIENT_PORT)
guestdhcp.server, guestdhcp.conn, err = dhcp.NewDHCPServer2(iface, uint16(port), DEFAULT_DHCP_CLIENT_PORT)
if err != nil {
return nil, err
}
@@ -67,14 +67,19 @@ func NewGuestDHCPServer(iface string, relay []string) (*SGuestDHCPServer, error)
return guestdhcp, nil
}
func (s *SGuestDHCPServer) Start() {
func (s *SGuestDHCPServer) Start(blocking bool) {
log.Infof("SGuestDHCPServer starting ...")
go func() {
serve := func() {
err := s.server.ListenAndServe(s)
if err != nil {
log.Errorf("DHCP serve error: %s", err)
}
}()
}
if blocking {
serve()
} else {
go serve()
}
}
func (s *SGuestDHCPServer) RelaySetup(addr string) error {
@@ -139,6 +144,10 @@ func (s *SGuestDHCPServer) getGuestConfig(guestDesc, guestNic jsonutils.JSONObje
}
func (s *SGuestDHCPServer) getConfig(pkt dhcp.Packet) *dhcp.ResponseConfig {
if guestman.GuestDescGetter == nil {
return nil
}
var (
mac = pkt.CHAddr().String()
ip, port = "", ""
+1 -1
View File
@@ -117,7 +117,7 @@ func (h *SHostInfo) GetBridgeDev(bridge string) hostbridge.IBridgeDriver {
func (h *SHostInfo) StartDHCPServer() {
for _, nic := range h.Nics {
nic.dhcpServer.Start()
nic.dhcpServer.Start(false)
}
}
+1 -1
View File
@@ -359,7 +359,7 @@ func NewNIC(desc string) (*SNIC, error) {
if nic.EnableDHCPRelay() {
dhcpRelay = options.HostOptions.DhcpRelay
}
nic.dhcpServer, err = hostdhcp.NewGuestDHCPServer(nic.Bridge, dhcpRelay)
nic.dhcpServer, err = hostdhcp.NewGuestDHCPServer(nic.Bridge, options.HostOptions.DhcpServerPort, dhcpRelay)
if err != nil {
return nil, err
}