1515package baremetal
1616
1717import (
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
3233func 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 }
0 commit comments