Skip to content

Commit ec40153

Browse files
swordqiuQiu Jian
andauthored
fix: dhcpv6 support, phase 2 (#22851)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
1 parent ed0b1ee commit ec40153

File tree

21 files changed

+1056
-239
lines changed

21 files changed

+1056
-239
lines changed

pkg/baremetal/manager.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,31 +1040,37 @@ func (b *SBaremetalInstance) GetIPMINicIPAddr() string {
10401040
func (b *SBaremetalInstance) GetDHCPConfig(cliMac net.HardwareAddr) (*dhcp.ResponseConfig, error) {
10411041
var nic *types.SNic
10421042
var hostname string
1043+
var osName string
10431044
if b.GetServer() != nil && (b.GetTask() == nil || !b.GetTask().NeedPXEBoot()) {
10441045
nic = b.GetServer().GetNicByMac(cliMac)
1045-
hostname = b.GetServer().GetName()
1046+
hostname = b.GetServer().GetHostName()
1047+
osName = b.GetServer().GetOsName()
10461048
} else {
10471049
nic = b.GetNicByMac(cliMac)
10481050
}
10491051
if nic == nil {
10501052
return nil, fmt.Errorf("GetNicDHCPConfig no nic found by mac: %s", cliMac)
10511053
}
1052-
return b.getDHCPConfig(nic, hostname, false, 0)
1054+
return b.getDHCPConfig(nic, hostname, false, 0, osName)
10531055
}
10541056

10551057
func (b *SBaremetalInstance) GetPXEDHCPConfig(arch uint16) (*dhcp.ResponseConfig, error) {
1056-
return b.getDHCPConfig(b.GetAdminNic(), "", true, arch)
1058+
return b.getDHCPConfig(b.GetAdminNic(), "", true, arch, "Linux")
10571059
}
10581060

10591061
func (b *SBaremetalInstance) getDHCPConfig(
10601062
nic *types.SNic,
10611063
hostName string,
10621064
isPxe bool,
10631065
arch uint16,
1066+
osName string,
10641067
) (*dhcp.ResponseConfig, error) {
10651068
if hostName == "" {
10661069
hostName = b.GetName()
10671070
}
1071+
if osName == "" {
1072+
osName = "Linux"
1073+
}
10681074
serverIP, err := b.manager.Agent.GetDHCPServerIP()
10691075
if err != nil {
10701076
return nil, err
@@ -1078,7 +1084,7 @@ func (b *SBaremetalInstance) getDHCPConfig(
10781084
return nil, errors.Errorf("Baremetal %s not need UEFI PXE boot", b.GetName())
10791085
}
10801086
}
1081-
return GetNicDHCPConfig(nic, serverIP.String(), hostName, isPxe, arch)
1087+
return GetNicDHCPConfig(nic, serverIP, b.manager.Agent.ListenInterface.HardwareAddr, hostName, isPxe, arch, osName)
10821088
}
10831089

10841090
func (b *SBaremetalInstance) GetNotifyUrl() string {
@@ -2550,6 +2556,22 @@ func (server *SBaremetalServer) GetName() string {
25502556
return id
25512557
}
25522558

2559+
func (server *SBaremetalServer) GetHostName() string {
2560+
hostname, err := server.desc.GetString("hostname")
2561+
if err != nil {
2562+
log.Errorf("Get hostname from desc %s error: %v", server.desc.String(), err)
2563+
}
2564+
return hostname
2565+
}
2566+
2567+
func (server *SBaremetalServer) GetOsName() string {
2568+
osName, err := server.desc.GetString("os_name")
2569+
if err != nil {
2570+
log.Errorf("Get os name from desc %s error: %v", server.desc.String(), err)
2571+
}
2572+
return osName
2573+
}
2574+
25532575
func (server *SBaremetalServer) SaveDesc(desc jsonutils.JSONObject) error {
25542576
if desc != nil {
25552577
server.desc = desc.(*jsonutils.JSONDict)

pkg/baremetal/nic.go

Lines changed: 101 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
package baremetal
1616

1717
import (
18-
"fmt"
1918
"net"
2019
"os"
2120
"path/filepath"
2221
"strings"
2322
"time"
2423

24+
"yunion.io/x/pkg/errors"
2525
"yunion.io/x/pkg/util/netutils"
26+
"yunion.io/x/pkg/util/regutils"
2627

2728
o "yunion.io/x/onecloud/pkg/baremetal/options"
2829
"yunion.io/x/onecloud/pkg/cloudcommon/types"
@@ -31,68 +32,127 @@ import (
3132

3233
func GetNicDHCPConfig(
3334
n *types.SNic,
34-
serverIP string,
35+
serverIP net.IP,
36+
serverMac net.HardwareAddr,
3537
hostName string,
3638
isPxe bool,
3739
arch uint16,
40+
osName string,
3841
) (*dhcp.ResponseConfig, error) {
3942
if n == nil {
40-
return nil, fmt.Errorf("Nic is nil")
43+
return nil, errors.Wrap(errors.ErrEmpty, "Nic is nil")
4144
}
42-
if n.IpAddr == "" {
43-
return nil, fmt.Errorf("Nic no ip address")
45+
if n.IpAddr == "" && n.Ip6Addr == "" {
46+
return nil, errors.Wrap(errors.ErrEmpty, "Nic no ip or ip6 address")
4447
}
45-
ipAddr, err := netutils.NewIPV4Addr(n.IpAddr)
46-
if err != nil {
47-
return nil, fmt.Errorf("Parse IP address error: %q", n.IpAddr)
48+
49+
routes4 := make([]dhcp.SRouteInfo, 0)
50+
routes6 := make([]dhcp.SRouteInfo, 0)
51+
for _, route := range n.Routes {
52+
routeInfo, err := dhcp.ParseRouteInfo([]string{route[0], route[1]})
53+
if err != nil {
54+
return nil, errors.Wrapf(err, "Parse route %s error: %q", route, err)
55+
}
56+
if regutils.MatchCIDR6(route[0]) {
57+
routes6 = append(routes6, *routeInfo)
58+
} else {
59+
routes4 = append(routes4, *routeInfo)
60+
}
4861
}
4962

50-
subnetMask := net.ParseIP(netutils.Masklen2Mask(n.Masklen).String())
63+
if n.IsDefault == nil || *n.IsDefault {
64+
if n.Gateway != "" && !strings.HasPrefix(strings.ToLower(osName), "win") {
65+
routes4 = append(routes4, dhcp.SRouteInfo{
66+
Prefix: net.ParseIP("0.0.0.0"),
67+
PrefixLen: 0,
68+
Gateway: net.ParseIP(n.Gateway),
69+
})
70+
}
71+
if n.Gateway6 != "" {
72+
routes6 = append(routes6, dhcp.SRouteInfo{
73+
Prefix: net.ParseIP("::"),
74+
PrefixLen: 0,
75+
Gateway: net.ParseIP(n.Gateway6),
76+
})
77+
}
78+
}
5179

52-
routes := make([][]string, 0)
53-
for _, route := range n.Routes {
54-
routes = append(routes, []string{route[0], route[1]})
80+
conf := &dhcp.ResponseConfig{
81+
InterfaceMac: serverMac,
82+
83+
ServerIP: serverIP,
84+
Domain: n.Domain,
85+
OsName: osName,
86+
Hostname: strings.ToLower(hostName),
87+
Routes: routes4,
88+
Routes6: routes6,
89+
LeaseTime: time.Duration(o.Options.DhcpLeaseTime) * time.Second,
90+
RenewalTime: time.Duration(o.Options.DhcpRenewalTime) * time.Second,
5591
}
5692

57-
parseIPs := func(ips string) []net.IP {
58-
ret := make([]net.IP, 0)
59-
iplist := strings.Split(ips, ",")
60-
for _, ip := range iplist {
61-
ret = append(ret, net.ParseIP(ip))
93+
if n.IpAddr != "" {
94+
ipAddr, err := netutils.NewIPV4Addr(n.IpAddr)
95+
if err != nil {
96+
return nil, errors.Wrapf(err, "Parse IP address error: %q", n.IpAddr)
6297
}
63-
return ret
98+
99+
subnetMask := net.ParseIP(netutils.Masklen2Mask(n.Masklen).String())
100+
101+
conf.ClientIP = net.ParseIP(ipAddr.String())
102+
conf.SubnetMask = subnetMask
103+
conf.BroadcastAddr = net.ParseIP(ipAddr.BroadcastAddr(n.Masklen).String())
104+
conf.Gateway = net.ParseIP(n.Gateway)
105+
}
106+
if n.Ip6Addr != "" {
107+
ipAddr6, err := netutils.NewIPV6Addr(n.Ip6Addr)
108+
if err != nil {
109+
return nil, errors.Wrapf(err, "Parse IPv6 address error: %q", n.Ip6Addr)
110+
}
111+
112+
conf.ClientIP6 = net.ParseIP(ipAddr6.String())
113+
conf.PrefixLen6 = n.Masklen6
114+
conf.Gateway6 = net.ParseIP(n.Gateway6)
64115
}
65116

66-
parseDomains := func(domains string) []net.IP {
67-
ret := make([]net.IP, 0)
68-
domainlist := strings.Split(domains, ",")
69-
for _, domain := range domainlist {
70-
addrs, _ := net.LookupHost(domain)
71-
for _, addr := range addrs {
72-
ret = append(ret, net.ParseIP(addr))
117+
if len(n.Dns) > 0 {
118+
conf.DNSServers = make([]net.IP, 0)
119+
conf.DNSServers6 = make([]net.IP, 0)
120+
for _, dns := range strings.Split(n.Dns, ",") {
121+
if regutils.MatchIP4Addr(dns) {
122+
conf.DNSServers = append(conf.DNSServers, net.ParseIP(dns))
123+
} else if regutils.MatchIP6Addr(dns) {
124+
conf.DNSServers6 = append(conf.DNSServers6, net.ParseIP(dns))
73125
}
74126
}
75-
return ret
76127
}
77128

78-
conf := &dhcp.ResponseConfig{
79-
ServerIP: net.ParseIP(serverIP),
80-
ClientIP: net.ParseIP(ipAddr.String()),
81-
Gateway: net.ParseIP(n.Gateway),
82-
SubnetMask: subnetMask,
83-
BroadcastAddr: net.ParseIP(ipAddr.BroadcastAddr(n.Masklen).String()),
84-
DNSServers: parseIPs(n.Dns),
85-
NTPServers: parseDomains(n.Ntp),
86-
Domain: n.Domain,
87-
OsName: "Linux",
88-
Hostname: hostName,
89-
Routes: routes,
90-
LeaseTime: time.Duration(o.Options.DhcpLeaseTime) * time.Second,
91-
RenewalTime: time.Duration(o.Options.DhcpRenewalTime) * time.Second,
129+
if len(n.Ntp) > 0 {
130+
conf.NTPServers = make([]net.IP, 0)
131+
conf.NTPServers6 = make([]net.IP, 0)
132+
for _, ntp := range strings.Split(n.Ntp, ",") {
133+
if regutils.MatchIP4Addr(ntp) {
134+
conf.NTPServers = append(conf.NTPServers, net.ParseIP(ntp))
135+
} else if regutils.MatchIP6Addr(ntp) {
136+
conf.NTPServers6 = append(conf.NTPServers6, net.ParseIP(ntp))
137+
} else if regutils.MatchDomainName(ntp) {
138+
ntpAddrs, _ := net.LookupHost(ntp)
139+
for _, ntpAddr := range ntpAddrs {
140+
if regutils.MatchIP4Addr(ntpAddr) {
141+
conf.NTPServers = append(conf.NTPServers, net.ParseIP(ntpAddr))
142+
} else if regutils.MatchIP6Addr(ntpAddr) {
143+
conf.NTPServers6 = append(conf.NTPServers6, net.ParseIP(ntpAddr))
144+
}
145+
}
146+
}
147+
}
148+
}
149+
150+
if n.Mtu > 0 {
151+
conf.MTU = uint16(n.Mtu)
92152
}
93153

94154
if isPxe {
95-
conf.BootServer = serverIP
155+
conf.BootServer = serverIP.String()
96156
if len(o.Options.TftpBootServer) > 0 {
97157
conf.BootServer = o.Options.TftpBootServer
98158
}

pkg/baremetal/types/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ type IBaremetalServer interface {
4141
GetNicByMac(mac net.HardwareAddr) *types.SNic
4242

4343
GetRootTemplateId() string
44+
45+
GetHostName() string
46+
GetOsName() string
4447
}

pkg/cloudcommon/types/nic.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ type SNic struct {
5252
Bandwidth int `json:"bandwidth"`
5353

5454
Index int `json:"index"`
55+
56+
IsDefault *bool `json:"is_default"`
5557
}
5658

5759
type SRoute []string
@@ -132,5 +134,7 @@ func (n SServerNic) ToNic() SNic {
132134
Ip6Addr: n.Ip6,
133135
Masklen6: uint8(n.Masklen6),
134136
Gateway6: n.Gateway6,
137+
138+
IsDefault: &n.IsDefault,
135139
}
136140
}

0 commit comments

Comments
 (0)