fix: host network ipv6 support (#23013)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2025-08-02 12:15:07 +08:00
committed by GitHub
parent ef04ac2dac
commit fbefeae06f
34 changed files with 770 additions and 183 deletions
+11 -1
View File
@@ -263,6 +263,7 @@ func init() {
INDEX int64 `help:"nic index"`
Type string `help:"Nic type" choices:"admin|ipmi"`
IpAddr string `help:"IP address"`
Ip6Addr string `help:"IPv6 address"`
Bridge string `help:"Bridge of hostwire"`
Interface string `help:"Interface name, eg:eth0, en0"`
}
@@ -278,6 +279,9 @@ func init() {
if len(args.IpAddr) > 0 {
params.Add(jsonutils.NewString(args.IpAddr), "ip_addr")
}
if len(args.Ip6Addr) > 0 {
params.Add(jsonutils.NewString(args.Ip6Addr), "ip6_addr")
}
if len(args.Bridge) > 0 {
params.Add(jsonutils.NewString(args.Bridge), "bridge")
}
@@ -310,7 +314,8 @@ func init() {
type HostEnableNetIfOptions struct {
ID string `help:"ID or Name of host"`
MAC string `help:"MAC of NIC to enable"`
Ip string `help:"IP address"`
Ip string `help:"IPv4 address"`
Ip6 string `help:"IPv6 address"`
Network string `help:"network to connect"`
Reserved bool `help:"fetch IP from reserved pool"`
}
@@ -319,6 +324,11 @@ func init() {
params.Add(jsonutils.NewString(args.MAC), "mac")
if len(args.Ip) > 0 {
params.Add(jsonutils.NewString(args.Ip), "ip_addr")
}
if len(args.Ip6) > 0 {
params.Add(jsonutils.NewString(args.Ip6), "ip6_addr")
}
if len(args.Ip) > 0 || len(args.Ip6) > 0 {
if args.Reserved {
params.Add(jsonutils.JSONTrue, "reserve")
}
+2
View File
@@ -127,6 +127,8 @@ type GuestnetworkBaseDesc struct {
Id string `json:"id"`
Provider string `json:"provider"`
MappedIpAddr string `json:"mapped_ip_addr"`
MappedIp6Addr string `json:"mapped_ip6_addr"`
} `json:"vpc"`
Networkaddresses jsonutils.JSONObject `json:"networkaddresses"`
+12
View File
@@ -672,6 +672,12 @@ type HostAddNetifInput struct {
Reserve *bool `json:"reserve"`
RequireDesignatedIp *bool `json:"require_designated_ip"`
Ip6Addr string `json:"ip6_addr"`
RequireIpv6 *bool `json:"require_ipv6"`
StrictIpv6 *bool `json:"strict_ipv6"`
}
type HostEnableNetifInput struct {
@@ -690,6 +696,12 @@ type HostEnableNetifInput struct {
Reserve *bool `json:"reserve"`
RequireDesignatedIp *bool `json:"require_designated_ip"`
Ip6Addr string `json:"ip6_addr"`
RequireIpv6 *bool `json:"require_ipv6"`
StrictIpv6 *bool `json:"strict_ipv6"`
}
type HostDisableNetifInput struct {
+1
View File
@@ -168,6 +168,7 @@ type NetworkTopologyOutput struct {
type HostnetworkTopologyOutput struct {
IpAddr string `json:"ip_addr"`
Ip6Addr string `json:"ip6_addr"`
MacAddr string `json:"mac_addr"`
}
+89
View File
@@ -16,6 +16,7 @@ package compute
import (
"fmt"
"strings"
"yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/pkg/util/netutils"
@@ -51,12 +52,22 @@ const (
sVpcInterExtIP2 = "100.65.0.2"
VpcInterExtMac1 = "ee:ee:ee:ee:ee:f0"
VpcInterExtMac2 = "ee:ee:ee:ee:ee:f1"
sVpcInterCidr6 = "fc00::fffe:100:65:0:0/100"
sVpcInterExtCidr6 = "fc00::fffe:100:65:0:0/112"
VpcInterExtMask6 = 112
sVpcInterExtIP16 = "fc00::fffe:100:65:0:1"
sVpcInterExtIP26 = "fc00::fffe:100:65:0:2"
)
var (
vpcInterCidr netutils.IPV4Prefix
vpcInterExtIP1 netutils.IPV4Addr
vpcInterExtIP2 netutils.IPV4Addr
vpcInterCidr6 netutils.IPV6Prefix
vpcInterExtIP16 netutils.IPV6Addr
vpcInterExtIP26 netutils.IPV6Addr
)
func VpcInterCidr() netutils.IPV4Prefix {
@@ -71,12 +82,28 @@ func VpcInterExtIP2() netutils.IPV4Addr {
return vpcInterExtIP2
}
func VpcInterCidr6() netutils.IPV6Prefix {
return vpcInterCidr6
}
func VpcInterExtIP16() netutils.IPV6Addr {
return vpcInterExtIP16
}
func VpcInterExtIP26() netutils.IPV6Addr {
return vpcInterExtIP26
}
const (
sVpcMappedCidr = "100.64.0.0/17"
VpcMappedIPMask = 17
sVpcMappedGatewayIP = "100.64.0.1"
VpcMappedGatewayMac = "ee:ee:ee:ee:ee:ee"
sVpcMappedCidr6 = "fc00::fffe:100:64:0:0/100"
VpcMappedIPMask6 = 100
sVpcMappedGatewayIP6 = "fc00::fffe:100:64:0:1"
// reserved: [100.64.0.2, 100.64.0.127]
// [128, 2176 (128+2048)]
@@ -98,18 +125,31 @@ const (
sVpcEipGatewayIP = "100.64.128.2"
VpcEipGatewayMac = "ee:ee:ee:ee:ee:ef"
sVpcEipGatewayCidr6 = "fc00::fffe:100:64:f000:0/100"
VpcEipGatewayIPMask6 = 100
sVpcEipGatewayIP6 = "fc00::fffe:100:64:f000:2"
sVpcEipGatewayIP3 = "100.64.128.3"
VpcEipGatewayMac3 = "ee:ee:ee:ee:ee:f0"
sVpcEipGatewayIP63 = "fc00::fffe:100:64:f000:3"
)
var (
vpcMappedCidr netutils.IPV4Prefix
vpcMappedGatewayIP netutils.IPV4Addr
vpcMappedCidr6 netutils.IPV6Prefix
vpcMappedGatewayIP6 netutils.IPV6Addr
vpcEipGatewayCidr netutils.IPV4Prefix
vpcEipGatewayIP netutils.IPV4Addr
vpcEipGatewayIP3 netutils.IPV4Addr
vpcEipGatewayCidr6 netutils.IPV6Prefix
vpcEipGatewayIP6 netutils.IPV6Addr
vpcEipGatewayIP63 netutils.IPV6Addr
vpcMappedHostIPStart netutils.IPV4Addr
vpcMappedHostIPEnd netutils.IPV4Addr
@@ -131,17 +171,41 @@ func init() {
return v
}
mi6 := func(v netutils.IPV6Addr, err error) netutils.IPV6Addr {
if err != nil {
panic(err.Error())
}
return v
}
mp6 := func(v netutils.IPV6Prefix, err error) netutils.IPV6Prefix {
if err != nil {
panic(err.Error())
}
return v
}
vpcInterCidr = mp(netutils.NewIPV4Prefix(sVpcInterCidr))
vpcInterExtIP1 = mi(netutils.NewIPV4Addr(sVpcInterExtIP1))
vpcInterExtIP2 = mi(netutils.NewIPV4Addr(sVpcInterExtIP2))
vpcInterCidr6 = mp6(netutils.NewIPV6Prefix(sVpcInterCidr6))
vpcInterExtIP16 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP16))
vpcInterExtIP26 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP26))
vpcMappedCidr = mp(netutils.NewIPV4Prefix(sVpcMappedCidr))
vpcMappedGatewayIP = mi(netutils.NewIPV4Addr(sVpcMappedGatewayIP))
vpcMappedCidr6 = mp6(netutils.NewIPV6Prefix(sVpcMappedCidr6))
vpcMappedGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcMappedGatewayIP6))
vpcEipGatewayCidr = mp(netutils.NewIPV4Prefix(sVpcEipGatewayCidr))
vpcEipGatewayIP = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP))
vpcEipGatewayIP3 = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP3))
vpcEipGatewayCidr6 = mp6(netutils.NewIPV6Prefix(sVpcEipGatewayCidr6))
vpcEipGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP6))
vpcEipGatewayIP63 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP63))
vpcMappedHostIPStart = mi(netutils.NewIPV4Addr(sVpcMappedHostIPStart))
vpcMappedHostIPEnd = mi(netutils.NewIPV4Addr(sVpcMappedHostIPEnd))
@@ -153,22 +217,42 @@ func VpcMappedCidr() netutils.IPV4Prefix {
return vpcMappedCidr
}
func VpcMappedCidr6() netutils.IPV6Prefix {
return vpcMappedCidr6
}
func VpcMappedGatewayIP() netutils.IPV4Addr {
return vpcMappedGatewayIP
}
func VpcMappedGatewayIP6() netutils.IPV6Addr {
return vpcMappedGatewayIP6
}
func VpcEipGatewayCidr() netutils.IPV4Prefix {
return vpcEipGatewayCidr
}
func VpcEipGatewayCidr6() netutils.IPV6Prefix {
return vpcEipGatewayCidr6
}
func VpcEipGatewayIP() netutils.IPV4Addr {
return vpcEipGatewayIP
}
func VpcEipGatewayIP6() netutils.IPV6Addr {
return vpcEipGatewayIP6
}
func VpcEipGatewayIP3() netutils.IPV4Addr {
return vpcEipGatewayIP3
}
func VpcEipGatewayIP63() netutils.IPV6Addr {
return vpcEipGatewayIP63
}
func VpcMappedHostIPStart() netutils.IPV4Addr {
return vpcMappedHostIPStart
}
@@ -188,3 +272,8 @@ func VpcMappedIPEnd() netutils.IPV4Addr {
func VpcOvnEncapCostStr() string {
return fmt.Sprintf("%d", VPC_OVN_ENCAP_COST)
}
func GenVpcMappedIP6(ip string) string {
segs := strings.Split(ip, ".")
return fmt.Sprintf("fc00::fffe:100:64:%s:%s", segs[2], segs[3])
}
+1 -1
View File
@@ -73,7 +73,7 @@ const (
SKU_STATUS_AVAILABLE = "available"
SKU_STATUS_SOLDOUT = "soldout"
MetaServiceMonitorAgentUrl = "http://169.254.169.254/monitor"
MetaServiceMonitorAgentUrl = "http://%s/monitor"
)
var (
+2 -2
View File
@@ -115,12 +115,12 @@ func GetNicDHCPConfig(
conf.Gateway = net.ParseIP(n.Gateway)
}
if n.Ip6Addr != "" {
ipAddr6, err := netutils.NewIPV6Addr(n.Ip6Addr)
ip6Addr, err := netutils.NewIPV6Addr(n.Ip6Addr)
if err != nil {
return nil, errors.Wrapf(err, "Parse IPv6 address error: %q", n.Ip6Addr)
}
conf.ClientIP6 = net.ParseIP(ipAddr6.String())
conf.ClientIP6 = net.ParseIP(ip6Addr.String())
conf.PrefixLen6 = n.Masklen6
conf.Gateway6 = net.ParseIP(n.Gateway6)
}
+5 -1
View File
@@ -163,9 +163,10 @@ func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SG
reuseAddr := false
hn := host.GetAttach2Network(netConfig.Network)
if hn != nil && options.Options.BaremetalServerReuseHostIp {
if netConfig.Address == "" || netConfig.Address == hn.IpAddr {
if (netConfig.Address == "" && netConfig.Address6 == "") || (netConfig.Address == hn.IpAddr && netConfig.Address6 == hn.Ip6Addr) {
// try to reuse host network IP address
netConfig.Address = hn.IpAddr
netConfig.Address6 = hn.Ip6Addr
reuseAddr = true
}
}
@@ -248,17 +249,20 @@ func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ct
nicConfs = append(nicConfs, nicConf)
}
address := ""
address6 := ""
reuseAddr := false
hn := host.GetAttach2Network(net.Id)
if hn != nil && options.Options.BaremetalServerReuseHostIp {
// try to reuse host network IP address
address = hn.IpAddr
address6 = hn.Ip6Addr
reuseAddr = true
}
return guest.Attach2Network(ctx, userCred, models.Attach2NetworkArgs{
Network: net,
PendingUsage: pendingUsage,
IpAddr: address,
Ip6Addr: address6,
NicDriver: netConfig.Driver,
BwLimit: netConfig.BwLimit,
Virtual: netConfig.Vip,
@@ -163,9 +163,10 @@ func (self *SCloudpodsBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *
reuseAddr := false
hn := host.GetAttach2Network(netConfig.Network)
if hn != nil && options.Options.BaremetalServerReuseHostIp {
if netConfig.Address == "" || netConfig.Address == hn.IpAddr {
if (netConfig.Address == "" && netConfig.Address6 == "") || (netConfig.Address == hn.IpAddr && netConfig.Address6 == hn.Ip6Addr) {
// try to reuse host network IP address
netConfig.Address = hn.IpAddr
netConfig.Address6 = hn.Ip6Addr
reuseAddr = true
}
}
@@ -248,17 +249,20 @@ func (self *SCloudpodsBaremetalGuestDriver) Attach2RandomNetwork(guest *models.S
nicConfs = append(nicConfs, nicConf)
}
address := ""
address6 := ""
reuseAddr := false
hn := host.GetAttach2Network(net.Id)
if hn != nil && options.Options.BaremetalServerReuseHostIp {
// try to reuse host network IP address
address = hn.IpAddr
address6 = hn.Ip6Addr
reuseAddr = true
}
return guest.Attach2Network(ctx, userCred, models.Attach2NetworkArgs{
Network: net,
PendingUsage: pendingUsage,
IpAddr: address,
Ip6Addr: address6,
NicDriver: netConfig.Driver,
BwLimit: netConfig.BwLimit,
Virtual: netConfig.Vip,
+11 -1
View File
@@ -1203,7 +1203,17 @@ func (self *SKVMGuestDriver) RequestQgaCommand(ctx context.Context, userCred mcc
func (self *SKVMGuestDriver) FetchMonitorUrl(ctx context.Context, guest *models.SGuest) string {
if options.Options.KvmMonitorAgentUseMetadataService && !guest.IsSriov() {
return apis.MetaServiceMonitorAgentUrl
var metadataIp string
strictIpv6, err := guest.IsStrictIpv6()
if err != nil {
log.Errorf("IsStrictIpv6 for guest %s error: %v", guest.Id, err)
}
if strictIpv6 {
metadataIp = "[" + options.Options.MetadataServerIp6s[0] + "]"
} else {
metadataIp = options.Options.MetadataServerIp4s[0]
}
return fmt.Sprintf(apis.MetaServiceMonitorAgentUrl, metadataIp)
}
return self.SVirtualizedGuestDriver.FetchMonitorUrl(ctx, guest)
}
+5 -1
View File
@@ -139,8 +139,12 @@ func (self *SBaseHostDriver) FinishUnconvert(ctx context.Context, userCred mccli
if adminNic == nil {
return fmt.Errorf("admin nic is nil")
}
accessIp := adminNic.IpAddr
if accessIp == "" {
accessIp = adminNic.Ip6Addr
}
db.Update(host, func() error {
host.AccessIp = adminNic.IpAddr
host.AccessIp = accessIp
host.SetEnabled(true)
host.HostType = api.HOST_TYPE_BAREMETAL
host.HostStatus = api.HOST_OFFLINE
+1 -1
View File
@@ -64,7 +64,7 @@ type SGroupnetwork struct {
// IPv6地址
Ip6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user" create:"optional"` // Column(VARCHAR(64, charset='ascii'), nullable=True)
Index int8 `nullable:"false" default:"0" list:"user" list:"user" update:"user" create:"optional"` // Column(TINYINT, nullable=False, default=0)
Index int8 `nullable:"false" default:"0" list:"user" update:"user" create:"optional"` // Column(TINYINT, nullable=False, default=0)
EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(36, charset='ascii'), nullable=True)
}
+4 -4
View File
@@ -649,13 +649,13 @@ func (grp *SGroup) PerformAttachnetwork(ctx context.Context, userCred mcclient.T
return nil, errors.Wrapf(httperrors.ErrConflict, "candidate ip %s is occupied!", input.IpAddr)
}
var ipAddr6 string
var ip6Addr string
if len(input.Ip6Addr) > 0 || input.RequireIPv6 {
ipAddr6, err = net.GetFreeIP(ctx, userCred, nil, nil, input.Ip6Addr, input.AllocDir, input.Reserved != nil && *input.Reserved, api.AddressTypeIPv6)
ip6Addr, err = net.GetFreeIP(ctx, userCred, nil, nil, input.Ip6Addr, input.AllocDir, input.Reserved != nil && *input.Reserved, api.AddressTypeIPv6)
if err != nil {
return nil, errors.Wrap(err, "GetFreeIPv6")
}
if len(input.Ip6Addr) > 0 && ipAddr6 != input.Ip6Addr && input.RequireDesignatedIp != nil && *input.RequireDesignatedIp {
if len(input.Ip6Addr) > 0 && ip6Addr != input.Ip6Addr && input.RequireDesignatedIp != nil && *input.RequireDesignatedIp {
return nil, errors.Wrapf(httperrors.ErrConflict, "candidate v6 ip %s is occupied!", input.Ip6Addr)
}
}
@@ -664,7 +664,7 @@ func (grp *SGroup) PerformAttachnetwork(ctx context.Context, userCred mcclient.T
gn.NetworkId = net.Id
gn.GroupId = grp.Id
gn.IpAddr = ipAddr
gn.Ip6Addr = ipAddr6
gn.Ip6Addr = ip6Addr
gn.SetModelManager(GroupnetworkManager, &gn)
+2 -1
View File
@@ -125,7 +125,8 @@ func (guest *SGuest) PerformMigrateNetwork(ctx context.Context, userCred mcclien
// perform the database change
_, err = db.Update(&srcNic, func() error {
srcNic.NetworkId = destNet.Id
srcNic.MappedIpAddr = "" // reset MappedIpAddr anyway
srcNic.MappedIpAddr = "" // reset MappedIpAddr anyway
srcNic.MappedIp6Addr = "" // reset MappedIp6Addr anyway
return nil
})
if err != nil {
+92 -11
View File
@@ -112,6 +112,8 @@ type SGuestnetwork struct {
// IPv4映射地址,当子网属于私有云vpc的时候分配,用于访问外网
MappedIpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
// IPv6映射地址,当子网属于私有云vpc的时候分配,用于访问外网
MappedIp6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
// 网卡关联的Eip实例
EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
@@ -359,18 +361,8 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
gn.IpAddr = ipAddr
}
}
if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD {
var err error
GuestnetworkManager.lockAllocMappedAddr(ctx)
defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
gn.MappedIpAddr, err = GuestnetworkManager.allocMappedIpAddr(ctx)
if err != nil {
return nil, err
}
}
}
var err error
if ipBindMac := NetworkIpMacManager.GetMacFromIp(network.Id, gn.IpAddr); ipBindMac != "" {
gn.MacAddr = ipBindMac
@@ -416,6 +408,17 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
}
}
if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD && len(gn.IpAddr) > 0 || len(gn.Ip6Addr) > 0 {
var err error
GuestnetworkManager.lockAllocMappedAddr(ctx)
defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
gn.MappedIpAddr, err = GuestnetworkManager.allocMappedIpAddr(ctx)
if err != nil {
return nil, errors.Wrap(err, "GuestnetworkManager.allocMappedIpAddr")
}
gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
}
ifname, err = gn.checkOrAllocateIfname(network, ifname)
if err != nil {
return nil, err
@@ -609,12 +612,22 @@ func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.Guestnet
} else {
if _, err := db.Update(gn, func() error {
gn.MappedIpAddr = addr
gn.MappedIp6Addr = api.GenVpcMappedIP6(addr)
return nil
}); err != nil {
log.Errorf("getJsonDescOneCloudVpc: row %d: db update mapped addr: %v", gn.RowId, err)
gn.MappedIpAddr = ""
gn.MappedIp6Addr = ""
}
}
} else if gn.MappedIp6Addr == "" {
if _, err := db.Update(gn, func() error {
gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
return nil
}); err != nil {
log.Errorf("getJsonDescOneCloudVpc for v6: row %d: db update mapped addr6: %v", gn.RowId, err)
gn.MappedIp6Addr = ""
}
}
desc := gn.getJsonDesc()
@@ -623,6 +636,7 @@ func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.Guestnet
desc.Vpc.Id = vpc.Id
desc.Vpc.Provider = api.VPC_PROVIDER_OVN
desc.Vpc.MappedIpAddr = gn.MappedIpAddr
desc.Vpc.MappedIp6Addr = gn.MappedIp6Addr
return desc
}
@@ -1364,3 +1378,70 @@ func (manager *SGuestnetworkManager) ListItemExportKeys(ctx context.Context,
return q, nil
}
func (manager *SGuestnetworkManager) InitializeData() error {
err := manager.initOvnMappedIps()
if err != nil {
return errors.Wrap(err, "initOvnMappedIps")
}
return nil
}
func (manager *SGuestnetworkManager) initOvnMappedIps() error {
q := manager.Query()
networksQ := NetworkManager.Query().SubQuery()
wiresQ := WireManager.Query().SubQuery()
vpcQ := VpcManager.Query().SubQuery()
regionQ := CloudregionManager.Query().SubQuery()
q = q.Join(networksQ, sqlchemy.Equals(q.Field("network_id"), networksQ.Field("id")))
q = q.Join(wiresQ, sqlchemy.Equals(networksQ.Field("wire_id"), wiresQ.Field("id")))
q = q.Join(vpcQ, sqlchemy.Equals(wiresQ.Field("vpc_id"), vpcQ.Field("id")))
q = q.Join(regionQ, sqlchemy.Equals(vpcQ.Field("cloudregion_id"), regionQ.Field("id")))
q = q.Filter(sqlchemy.Equals(regionQ.Field("provider"), api.CLOUD_PROVIDER_ONECLOUD))
q = q.Filter(sqlchemy.NotEquals(vpcQ.Field("id"), api.DEFAULT_VPC_ID))
q = q.Filter(sqlchemy.OR(
sqlchemy.IsEmpty(q.Field("mapped_ip_addr")),
sqlchemy.IsEmpty(q.Field("mapped_ip6_addr")),
))
gns := make([]SGuestnetwork, 0)
err := db.FetchModelObjects(manager, q, &gns)
if err != nil {
return errors.Wrap(err, "FetchModelObjects")
}
for i := range gns {
gn := &gns[i]
var v4addr string
if gn.MappedIpAddr == "" {
addr, err := manager.allocMappedIpAddr(context.Background())
if err != nil {
return errors.Wrap(err, "allocMappedIpAddr")
}
v4addr = addr
} else {
v4addr = gn.MappedIpAddr
}
if _, err := db.Update(gn, func() error {
gn.MappedIpAddr = v4addr
gn.MappedIp6Addr = api.GenVpcMappedIP6(v4addr)
return nil
}); err != nil {
return errors.Wrap(err, "db.Update")
}
}
return nil
}
func (guest *SGuest) IsStrictIpv6() (bool, error) {
q := GuestnetworkManager.Query().Equals("guest_id", guest.Id)
q = q.IsNotEmpty("ip6_addr").IsNullOrEmpty("ip_addr").IsFalse("virtual")
cnt, err := q.CountWithError()
if err != nil {
return false, errors.Wrap(err, "CountWithError")
}
return cnt > 0, nil
}
-1
View File
@@ -3730,7 +3730,6 @@ func (self *SGuest) attach2NetworkOnce(
teamWithMac = args.teamWithMac
)
network.updateDnsRecord(guestnic, true)
network.updateGuestNetmap(guestnic)
if pendingUsage != nil && len(teamWithMac) == 0 {
cancelUsage := SRegionQuota{}
if network.IsExitNetwork() {
+7 -2
View File
@@ -196,6 +196,7 @@ func (self *SGuest) doPrepaidRecycleNoLock(ctx context.Context, userCred mcclien
1,
net.WireId,
"",
"",
1000,
nicType,
i,
@@ -205,7 +206,10 @@ func (self *SGuest) doPrepaidRecycleNoLock(ctx context.Context, userCred mcclien
&ifname,
&brname,
false,
false)
false,
false,
false,
)
if err != nil {
log.Errorf("fail to addNetInterface %d: %s", i, err)
fakeHost.RealDelete(ctx, userCred)
@@ -546,7 +550,7 @@ func (self *SHost) BorrowIpAddrsFromGuest(ctx context.Context, userCred mcclient
return fmt.Errorf(msg)
}
err = self.EnableNetif(ctx, userCred, netif, "", guestnics[i].IpAddr, "", "", false, false)
err = self.EnableNetif(ctx, userCred, netif, "", guestnics[i].IpAddr, guestnics[i].Ip6Addr, "", "", false, false, false, false)
if err != nil {
log.Errorf("fail to enable netif %s %s", guestnics[i].IpAddr, err)
return err
@@ -586,6 +590,7 @@ func (host *SHost) SetGuestCreateNetworkAndDiskParams(ctx context.Context, userC
Network: hn.NetworkId,
Mac: netifs[i].Mac,
Address: hn.IpAddr,
Address6: hn.Ip6Addr,
Reserved: true,
})
netIdx += 1
+2
View File
@@ -62,6 +62,8 @@ type SHostnetwork struct {
NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
// IP地址
IpAddr string `width:"16" charset:"ascii" list:"domain"`
// IPv6地址
Ip6Addr string `width:"64" charset:"ascii" list:"domain"`
// MAC地址
MacAddr string `width:"18" charset:"ascii" list:"domain"`
// VLAN
+300 -76
View File
@@ -209,6 +209,8 @@ type SHost struct {
// IPv4地址,作为私有云vpc访问外网时的网关
OvnMappedIpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
// IPv6地址,作为私有云vpc访问外网时的网关
OvnMappedIp6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
// UEFI详情
UefiInfo jsonutils.JSONObject `nullable:"true" get:"domain" update:"domain" create:"domain_optional"`
@@ -2148,8 +2150,13 @@ func (hh *SHost) DeleteBaremetalnetwork(ctx context.Context, userCred mcclient.T
net := bn.GetNetwork()
bn.Delete(ctx, userCred)
db.OpsLog.LogDetachEvent(ctx, hh, net, userCred, nil)
if reserve && net != nil && len(bn.IpAddr) > 0 && regutils.MatchIP4Addr(bn.IpAddr) {
ReservedipManager.ReserveIP(ctx, userCred, net, bn.IpAddr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv4)
if reserve && net != nil {
if len(bn.IpAddr) > 0 && regutils.MatchIP4Addr(bn.IpAddr) {
ReservedipManager.ReserveIP(ctx, userCred, net, bn.IpAddr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv4)
}
if len(bn.Ip6Addr) > 0 && regutils.MatchIP6Addr(bn.Ip6Addr) {
ReservedipManager.ReserveIP(ctx, userCred, net, bn.Ip6Addr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv6)
}
}
}
@@ -3675,11 +3682,14 @@ func fetchHostNics(hostIds []string) (map[string][]*types.SNic, error) {
wires.Field("name").Label("wire"),
wires.Field("bandwidth"),
hn.Field("ip_addr"),
hn.Field("ip6_addr"),
networks.Field("guest_gateway").Label("gateway"),
networks.Field("guest_gateway6").Label("gateway6"),
networks.Field("guest_dns").Label("dns"),
networks.Field("guest_domain").Label("domain"),
networks.Field("guest_ntp").Label("ntp"),
networks.Field("guest_ip_mask").Label("masklen"),
networks.Field("guest_ip6_mask").Label("masklen6"),
networks.Field("name").Label("net"),
networks.Field("id").Label("net_id"),
zones.Field("name").Label("zone"),
@@ -4306,6 +4316,7 @@ func (hh *SHost) PostCreate(
if hh.OvnVersion != "" && hh.OvnMappedIpAddr == "" {
HostManager.lockAllocOvnMappedIpAddr(ctx)
defer HostManager.unlockAllocOvnMappedIpAddr(ctx)
addr, err := HostManager.allocOvnMappedIpAddr(ctx)
if err != nil {
log.Errorf("host %s(%s): alloc vpc mapped addr: %v",
@@ -4313,6 +4324,7 @@ func (hh *SHost) PostCreate(
}
if _, err := db.Update(hh, func() error {
hh.OvnMappedIpAddr = addr
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(addr)
return nil
}); err != nil {
log.Errorf("host %s(%s): db update vpc mapped addr: %v",
@@ -4722,6 +4734,7 @@ func (hh *SHost) PostUpdate(ctx context.Context, userCred mcclient.TokenCredenti
if hh.OvnVersion != "" && hh.OvnMappedIpAddr == "" {
HostManager.lockAllocOvnMappedIpAddr(ctx)
defer HostManager.unlockAllocOvnMappedIpAddr(ctx)
addr, err := HostManager.allocOvnMappedIpAddr(ctx)
if err != nil {
log.Errorf("host %s(%s): alloc vpc mapped addr: %v",
@@ -4730,6 +4743,7 @@ func (hh *SHost) PostUpdate(ctx context.Context, userCred mcclient.TokenCredenti
}
if _, err := db.Update(hh, func() error {
hh.OvnMappedIpAddr = addr
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(addr)
return nil
}); err != nil {
log.Errorf("host %s(%s): db update vpc mapped addr: %v",
@@ -5590,6 +5604,10 @@ func (h *SHost) PerformAddNetif(
if len(ipAddr) > 0 && !regutils.MatchIP4Addr(ipAddr) {
return nil, errors.Wrapf(httperrors.ErrInputParameter, "invalid ip_addr %s", ipAddr)
}
ip6Addr := input.Ip6Addr
if len(ip6Addr) > 0 && !regutils.MatchIP6Addr(ip6Addr) {
return nil, errors.Wrapf(httperrors.ErrInputParameter, "invalid ip6_addr %s", ip6Addr)
}
rate := input.Rate
nicType := input.NicType
index := input.Index
@@ -5600,6 +5618,8 @@ func (h *SHost) PerformAddNetif(
bridge := input.Bridge
reserve := (input.Reserve != nil && *input.Reserve)
requireDesignatedIp := (input.RequireDesignatedIp != nil && *input.RequireDesignatedIp)
requireIpv6 := (input.RequireIpv6 != nil && *input.RequireIpv6)
strictIpv6 := (input.StrictIpv6 != nil && *input.StrictIpv6)
isLinkUp := tristate.None
if linkUp != "" {
@@ -5610,16 +5630,16 @@ func (h *SHost) PerformAddNetif(
}
}
err = h.addNetif(ctx, userCred, mac, vlan, wire, ipAddr, int(rate), nicType, index, isLinkUp,
int16(mtu), reset, netIf, bridge, reserve, requireDesignatedIp)
err = h.addNetif(ctx, userCred, mac, vlan, wire, ipAddr, ip6Addr, int(rate), nicType, index, isLinkUp,
int16(mtu), reset, netIf, bridge, reserve, requireDesignatedIp, requireIpv6, strictIpv6)
return nil, errors.Wrap(err, "addNetif")
}
func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
mac string, vlanId int, wire string, ipAddr string,
mac string, vlanId int, wire string, ipAddr string, ip6Addr string,
rate int, nicType compute.TNicType, index int, linkUp tristate.TriState, mtu int16,
reset bool, strInterface *string, strBridge *string,
reserve bool, requireDesignatedIp bool,
reserve bool, requireDesignatedIp bool, requireIpv6 bool, strictIpv6 bool,
) error {
var sw *SWire
if len(wire) > 0 {
@@ -5632,32 +5652,78 @@ func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
}
}
sw = iWire.(*SWire)
if len(ipAddr) > 0 {
iIpAddr, err := netutils.NewIPV4Addr(ipAddr)
if err != nil {
return httperrors.NewInputParameterError("invalid ipaddr %s", ipAddr)
if len(ipAddr) > 0 || len(ip6Addr) > 0 {
var v4addr *netutils.IPV4Addr
var v6addr *netutils.IPV6Addr
if len(ipAddr) > 0 {
iIpAddr, err := netutils.NewIPV4Addr(ipAddr)
if err != nil {
return httperrors.NewInputParameterError("invalid ipaddr %s", ipAddr)
}
v4addr = &iIpAddr
}
findAddr := false
if len(ip6Addr) > 0 {
iIp6Addr, err := netutils.NewIPV6Addr(ip6Addr)
if err != nil {
return httperrors.NewInputParameterError("invalid ip6addr %s", ip6Addr)
}
v6addr = &iIp6Addr
}
var v4net, v6net *SNetwork
swNets, err := sw.getNetworks(ctx, userCred, userCred, NetworkManager.AllowScope(userCred))
if err != nil {
return httperrors.NewInputParameterError("no networks on wire %s", wire)
}
for i := range swNets {
if swNets[i].IsAddressInRange(iIpAddr) {
findAddr = true
if v4net == nil && v4addr != nil && swNets[i].IsAddressInRange(*v4addr) {
v4net = &swNets[i]
}
if v6net == nil && v6addr != nil && swNets[i].IsAddress6InRange(*v6addr) {
v6net = &swNets[i]
}
if v4net != nil && v6net != nil {
break
}
}
if !findAddr {
return httperrors.NewBadRequestError("IP %s not attach to wire %s", ipAddr, wire)
if v4net == nil && v6net == nil {
var addrs []string
if len(ipAddr) > 0 {
addrs = append(addrs, ipAddr)
}
if len(ip6Addr) > 0 {
addrs = append(addrs, ip6Addr)
}
return httperrors.NewBadRequestError("IP %s not attach to wire %s", strings.Join(addrs, ","), wire)
}
if v4net != nil && v6net != nil && v4net.Id != v6net.Id {
return httperrors.NewConflictError("IPv4 %s and IPv6 %s must be on the same network", ipAddr, ip6Addr)
}
}
} else if len(ipAddr) > 0 && len(wire) == 0 {
ipWire, err := WireManager.GetOnPremiseWireOfIp(ipAddr)
if err != nil {
return httperrors.NewBadRequestError("IP %s not attach to any wire", ipAddr)
} else {
var v4wire, v6wire *SWire
if len(ipAddr) > 0 {
ipWire, err := WireManager.GetOnPremiseWireOfIp(ipAddr)
if err != nil {
return httperrors.NewBadRequestError("IP %s not attach to any wire", ipAddr)
}
v4wire = ipWire
}
if len(ip6Addr) > 0 {
ipWire, err := WireManager.GetOnPremiseWireOfIp6(ip6Addr)
if err != nil {
return httperrors.NewBadRequestError("IPv6 %s not attach to any wire", ip6Addr)
}
v6wire = ipWire
}
if v4wire != nil && v6wire != nil && v4wire.Id != v6wire.Id {
return httperrors.NewConflictError("IPv4 %s and IPv6 %s must be on the same wire", ipAddr, ip6Addr)
}
if v4wire != nil {
sw = v4wire
} else if v6wire != nil {
sw = v6wire
}
sw = ipWire
}
netif, err := NetInterfaceManager.FetchByMacVlan(mac, vlanId)
if err != nil {
@@ -5762,8 +5828,8 @@ func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
}
}
}
if len(ipAddr) > 0 {
err = h.EnableNetif(ctx, userCred, netif, "", ipAddr, "", "", reserve, requireDesignatedIp)
if len(ipAddr) > 0 || len(ip6Addr) > 0 {
err = h.EnableNetif(ctx, userCred, netif, "", ipAddr, ip6Addr, "", "", reserve, requireDesignatedIp, requireIpv6, strictIpv6)
if err != nil {
return httperrors.NewBadRequestError("%v", err)
}
@@ -5795,8 +5861,10 @@ func (h *SHost) PerformEnableNetif(
reserve := (input.Reserve != nil && *input.Reserve)
requireDesignatedIp := (input.RequireDesignatedIp != nil && *input.RequireDesignatedIp)
requireIpv6 := (input.RequireIpv6 != nil && *input.RequireIpv6)
strictIpv6 := (input.StrictIpv6 != nil && *input.StrictIpv6)
err = h.EnableNetif(ctx, userCred, netif, input.NetworkId, input.IpAddr, input.AllocDir, input.NetType, reserve, requireDesignatedIp)
err = h.EnableNetif(ctx, userCred, netif, input.NetworkId, input.IpAddr, input.Ip6Addr, input.AllocDir, input.NetType, reserve, requireDesignatedIp, requireIpv6, strictIpv6)
if err != nil {
return nil, httperrors.NewBadRequestError("%v", err)
}
@@ -5804,27 +5872,64 @@ func (h *SHost) PerformEnableNetif(
}
func (h *SHost) EnableNetif(ctx context.Context, userCred mcclient.TokenCredential, netif *SNetInterface,
network, ipAddr, allocDir string, netType api.TNetworkType, reserve, requireDesignatedIp bool) error {
bn := netif.GetHostNetwork()
if bn != nil {
log.Debugf("Netif has been attach2network? %s", jsonutils.Marshal(bn))
return nil
}
var net *SNetwork
network, ipAddr, ip6Addr, allocDir string, netType api.TNetworkType, reserve, requireDesignatedIp bool,
requireIpv6 bool, strictIpv6 bool) error {
// bn := netif.GetHostNetwork()
// if bn != nil {
// log.Debugf("Netif has been attach2network? %s", jsonutils.Marshal(bn))
// return nil
// }
var v4net, v6net *SNetwork
var err error
if len(ipAddr) > 0 {
net, err = netif.GetCandidateNetworkForIp(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ipAddr)
if len(ipAddr) > 0 && !strictIpv6 {
net, err := netif.GetCandidateNetworkForIp(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ipAddr)
if net != nil {
log.Infof("find network %s for ip %s", net.GetName(), ipAddr)
log.Infof("find network %s for ip4 %s", net.GetName(), ipAddr)
v4net = net
} else if requireDesignatedIp {
log.Errorf("Cannot allocate IP %s, not reachable", ipAddr)
return fmt.Errorf("Cannot allocate IP %s, not reachable", ipAddr)
log.Errorf("Cannot allocate IP %s, not reachable: %s", ipAddr, err)
return fmt.Errorf("Cannot allocate IP %s, not reachable: %s", ipAddr, err)
} else {
log.Infof("not found network with scope: %s, ip_addr: %s", NetworkManager.AllowScope(userCred), ipAddr)
log.Infof("not found network with scope: %s, ip_addr: %s, err: %s", NetworkManager.AllowScope(userCred), ipAddr, err)
// the ipaddr is not usable, should be reset to empty
ipAddr = ""
}
}
if len(ip6Addr) > 0 {
if v4net != nil {
ip6, err := netutils.NewIPV6Addr(ip6Addr)
if err != nil {
return errors.Wrapf(err, "netutils.NewIPV6Addr: %s", ip6Addr)
}
if v4net.IsAddress6InRange(ip6) {
v6net = v4net
}
} else {
net, err := netif.GetCandidateNetworkForIp6(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ip6Addr)
if net != nil {
log.Infof("find network %s for ip %s", net.GetName(), ip6Addr)
v6net = net
} else if requireIpv6 {
log.Errorf("Cannot allocate IPv6 %s, not reachable: %s", ip6Addr, err)
return fmt.Errorf("Cannot allocate IPv6 %s, not reachable: %s", ip6Addr, err)
} else {
log.Infof("not found network with scope: %s, ip6_addr: %s, err: %s", NetworkManager.AllowScope(userCred), ip6Addr, err)
// the ipaddr is not usable, should be reset to empty
ip6Addr = ""
}
}
}
var net *SNetwork
if v4net != nil && v6net != nil {
if v4net.Id != v6net.Id {
return errors.Wrap(httperrors.ErrConflict, "v4net and v6net must be on the same network")
}
net = v4net
} else if v6net != nil {
net = v6net
} else if v4net != nil {
net = v4net
}
wire := netif.GetWire()
if wire == nil {
return fmt.Errorf("No wire attached")
@@ -5879,20 +5984,28 @@ func (h *SHost) EnableNetif(ctx context.Context, userCred mcclient.TokenCredenti
allocDir: allocDir,
reserved: reserve,
requireDesignatedIp: requireDesignatedIp,
ip6Addr: ip6Addr,
requireIpv6: requireIpv6,
strictIpv6: strictIpv6,
}
bn, err = h.Attach2Network(ctx, userCred, attachOpt)
bn, err := h.attach2Network(ctx, userCred, attachOpt)
if err != nil {
return errors.Wrap(err, "hh.Attach2Network")
}
bnIP := bn.IpAddr
if len(bnIP) == 0 {
bnIP = bn.Ip6Addr
}
switch netif.NicType {
case api.NIC_TYPE_IPMI:
err = h.setIpmiIp(userCred, bn.IpAddr)
err = h.setIpmiIp(userCred, bnIP)
if err != nil {
return errors.Wrap(err, "setIpmiIp")
}
case api.NIC_TYPE_ADMIN:
err = h.setAccessIp(userCred, bn.IpAddr)
err = h.setAccessIp(userCred, bnIP)
if err != nil {
return errors.Wrap(err, "setAccessIp")
}
@@ -5928,20 +6041,21 @@ func (hh *SHost) PerformDisableNetif(
*/
func (hh *SHost) DisableNetif(ctx context.Context, userCred mcclient.TokenCredential, netif *SNetInterface, reserve bool) error {
bn := netif.GetHostNetwork()
var ipAddr string
var ipAddr, ip6Addr string
if bn != nil {
ipAddr = bn.IpAddr
ip6Addr = bn.Ip6Addr
hh.UpdateDnsRecord(netif, false)
hh.DeleteBaremetalnetwork(ctx, userCred, bn, reserve)
}
var err error
switch netif.NicType {
case api.NIC_TYPE_IPMI:
if ipAddr == hh.IpmiIp {
if ipAddr == hh.IpmiIp || ip6Addr == hh.IpmiIp {
err = hh.setIpmiIp(userCred, "")
}
case api.NIC_TYPE_ADMIN:
if ipAddr == hh.AccessIp {
if ipAddr == hh.AccessIp || ip6Addr == hh.AccessIp {
err = hh.setAccessIp(userCred, "")
}
}
@@ -5955,16 +6069,21 @@ type hostAttachNetworkOption struct {
allocDir string
reserved bool
requireDesignatedIp bool
ip6Addr string
requireIpv6 bool
strictIpv6 bool
}
func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mcclient.TokenCredential, ipAddr string, netif *SNetInterface) error {
func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mcclient.TokenCredential, ipAddr, ip6Addr string, netif *SNetInterface) error {
if !hh.IsBaremetal {
return httperrors.NewNotAcceptableError("Not a baremetal")
}
if hh.HostType == api.HOST_TYPE_KVM {
return httperrors.NewNotAcceptableError("Not being convert to hypervisor")
}
// ?
// if hh.HostType == api.HOST_TYPE_KVM {
// return httperrors.NewNotAcceptableError("Not being convert to hypervisor")
// }
bmServer := hh.GetBaremetalServer()
if bmServer == nil {
@@ -5987,59 +6106,118 @@ func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mccl
return httperrors.NewNotFoundError("Not found guest nic by mac %s", netif.Mac)
}
if findNic.IpAddr != ipAddr {
if len(ipAddr) > 0 && findNic.IpAddr != ipAddr {
return httperrors.NewNotAcceptableError("Guest nic ip addr %s not equal %s", findNic.IpAddr, ipAddr)
}
if len(ip6Addr) > 0 && findNic.Ip6Addr != ip6Addr {
return httperrors.NewNotAcceptableError("Guest nic ip addr6 %s not equal %s", findNic.Ip6Addr, ip6Addr)
}
return nil
}
func (hh *SHost) Attach2Network(
func (hh *SHost) attach2Network(
ctx context.Context,
userCred mcclient.TokenCredential,
opt *hostAttachNetworkOption,
) (*SHostnetwork, error) {
log.Infof("host attach2Network: %s", jsonutils.Marshal(opt))
netif := opt.netif
net := opt.net
ipAddr := opt.ipAddr
ip6Addr := opt.ip6Addr
allocDir := opt.allocDir
reserved := opt.reserved
requireDesignatedIp := opt.requireDesignatedIp
bn := opt.netif.GetHostNetwork()
lockman.LockObject(ctx, net)
defer lockman.ReleaseObject(ctx, net)
usedAddrs := net.GetUsedAddresses(ctx)
if ipAddr != "" {
// converted baremetal can resuse related guest network ip
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, ipAddr, netif); err == nil {
// force remove used server addr for reuse
delete(usedAddrs, ipAddr)
} else {
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
var freeIp4, freeIp6 string
if (!opt.strictIpv6 || len(ipAddr) > 0) && (bn == nil || bn.IpAddr != ipAddr) {
// allocate ipv4 address
usedAddrs := net.GetUsedAddresses(ctx)
if ipAddr != "" {
// converted baremetal can resuse related guest network ip
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, ipAddr, "", netif); err == nil {
// force remove used server addr for reuse
delete(usedAddrs, ipAddr)
} else {
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
}
}
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs, nil, ipAddr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv4)
if err != nil {
return nil, errors.Wrap(err, "net.GetFreeIPv4")
}
if len(ipAddr) > 0 && ipAddr != freeIp && requireDesignatedIp {
return nil, fmt.Errorf("IPv4 address %s is occupied, get %s instead", ipAddr, freeIp)
}
freeIp4 = freeIp
}
if (opt.requireIpv6 || len(ip6Addr) > 0) && (bn == nil || bn.Ip6Addr != ip6Addr) {
usedAddrs6 := net.GetUsedAddresses6(ctx)
if ip6Addr != "" {
// converted baremetal can resuse related guest network ip
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, "", ip6Addr, netif); err == nil {
// force remove used server addr for reuse
delete(usedAddrs6, ip6Addr)
} else {
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
}
}
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs6, nil, ip6Addr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv6)
if err != nil {
return nil, errors.Wrap(err, "net.GetFreeIPv6")
}
if len(ip6Addr) > 0 && ip6Addr != freeIp && requireDesignatedIp {
return nil, fmt.Errorf("IPv6 address %s is occupied, get %s instead", ip6Addr, freeIp)
}
freeIp6 = freeIp
}
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs, nil, ipAddr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv4)
if err != nil {
return nil, errors.Wrap(err, "net.GetFreeIP")
if bn == nil {
bn = &SHostnetwork{}
bn.SetModelManager(HostnetworkManager, bn)
bn.BaremetalId = hh.Id
bn.NetworkId = net.Id
bn.MacAddr = netif.Mac
bn.IpAddr = freeIp4
bn.Ip6Addr = freeIp6
err := HostnetworkManager.TableSpec().Insert(ctx, bn)
if err != nil {
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
}
} else if (freeIp4 != "" && freeIp4 != bn.IpAddr) || (freeIp6 != "" && freeIp6 != bn.Ip6Addr) {
_, err := db.Update(bn, func() error {
if freeIp4 != "" {
bn.IpAddr = freeIp4
}
if freeIp6 != "" {
bn.Ip6Addr = freeIp6
}
return nil
})
if err != nil {
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
}
} else {
return bn, nil
}
if len(ipAddr) > 0 && ipAddr != freeIp && requireDesignatedIp {
return nil, fmt.Errorf("IP address %s is occupied, get %s instead", ipAddr, freeIp)
var addrs []string
if len(freeIp4) > 0 {
addrs = append(addrs, freeIp4)
}
bn := &SHostnetwork{}
bn.BaremetalId = hh.Id
bn.SetModelManager(HostnetworkManager, bn)
bn.NetworkId = net.Id
bn.IpAddr = freeIp
bn.MacAddr = netif.Mac
err = HostnetworkManager.TableSpec().Insert(ctx, bn)
if err != nil {
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
if len(freeIp6) > 0 {
addrs = append(addrs, freeIp6)
}
db.OpsLog.LogAttachEvent(ctx, hh, net, userCred, jsonutils.NewString(freeIp))
db.OpsLog.LogAttachEvent(ctx, hh, net, userCred, jsonutils.NewString(strings.Join(addrs, ",")))
hh.UpdateDnsRecord(netif, true)
net.UpdateBaremetalNetmap(bn, hh.GetNetifName(netif))
// net.UpdateBaremetalNetmap(bn, hh.GetNetifName(netif))
return bn, nil
}
@@ -6587,7 +6765,7 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
netif := host.GetNetInterface(enables[i].GetMac(), enables[i].GetVlanId())
// always true reserved address pool
log.Debugf("enable netif %s", enables[i].GetMac())
err = host.EnableNetif(ctx, userCred, netif, "", enables[i].GetIpAddr(), "", "", true, true)
err = host.EnableNetif(ctx, userCred, netif, "", enables[i].GetIpAddr(), "", "", "", true, true, false, false)
if err != nil {
result.AddError(err)
} else {
@@ -6618,9 +6796,9 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
wireId = wire.Id
}
}
err = host.addNetif(ctx, userCred, extNic.GetMac(), extNic.GetVlanId(), wireId, extNic.GetIpAddr(), 0,
err = host.addNetif(ctx, userCred, extNic.GetMac(), extNic.GetVlanId(), wireId, extNic.GetIpAddr(), "", 0,
compute.TNicType(extNic.GetNicType()), int(extNic.GetIndex()),
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, strNetIf, strBridge, true, true)
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, strNetIf, strBridge, true, true, false, false)
if err != nil {
result.AddError(err)
} else {
@@ -7499,8 +7677,54 @@ func (manager *SHostManager) initHostname() error {
return nil
}
func (manager *SHostManager) initOvnMappedIp6Addr() error {
hosts := []SHost{}
q := manager.Query().IsNotEmpty("ovn_version")
q = q.Filter(
sqlchemy.OR(
sqlchemy.IsNullOrEmpty(q.Field("ovn_mapped_ip6_addr")),
sqlchemy.IsNullOrEmpty(q.Field("ovn_mapped_ip_addr")),
),
)
err := db.FetchModelObjects(manager, q, &hosts)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range hosts {
hh := &hosts[i]
var v4addr string
if hh.OvnMappedIp6Addr == "" {
addr, err := HostManager.allocOvnMappedIpAddr(context.Background())
if err != nil {
return errors.Wrapf(err, "host %s(%s): alloc vpc mapped addr", hh.Name, hh.Id)
}
v4addr = addr
} else {
v4addr = hh.OvnMappedIpAddr
}
if _, err := db.Update(hh, func() error {
hh.OvnMappedIpAddr = v4addr
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(v4addr)
return nil
}); err != nil {
return errors.Wrapf(err, "host %s(%s): db update vpc mapped addr", hh.Name, hh.Id)
}
}
return nil
}
func (manager *SHostManager) InitializeData() error {
return manager.initHostname()
var err error
err = manager.initHostname()
if err != nil {
return errors.Wrapf(err, "initHostname")
}
err = manager.initOvnMappedIp6Addr()
if err != nil {
return errors.Wrapf(err, "initOvnMappedIp6Addr")
}
return nil
}
func (hh *SHost) PerformProbeIsolatedDevices(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
+1
View File
@@ -50,6 +50,7 @@ func InitDB() error {
NetworkAddressManager,
NetworkIpMacManager,
GuestManager,
GuestnetworkManager,
HostManager,
LoadbalancerCertificateManager,
LoadbalancerAclManager,
+19 -2
View File
@@ -169,10 +169,13 @@ func (netIf *SNetInterface) hostNetworkToJson(bn *SHostnetwork) *jsonutils.JSOND
}
}*/
func (netIf *SNetInterface) networkToNic(ipAddr string, network *SNetwork, nic *types.SNic) *types.SNic {
func (netIf *SNetInterface) networkToNic(ipAddr, ip6Addr string, network *SNetwork, nic *types.SNic) *types.SNic {
if len(ipAddr) > 0 {
nic.IpAddr = ipAddr
}
if len(ip6Addr) > 0 {
nic.Ip6Addr = ip6Addr
}
if network != nil {
if len(network.GuestGateway) > 0 && regutils.MatchIP4Addr(network.GuestGateway) {
@@ -190,6 +193,11 @@ func (netIf *SNetInterface) networkToNic(ipAddr string, network *SNetwork, nic *
nic.Masklen = network.GuestIpMask
nic.Net = network.Name
nic.NetId = network.Id
nic.Masklen6 = network.GuestIp6Mask
if len(network.GuestGateway6) > 0 && regutils.MatchIP6Addr(network.GuestGateway6) {
nic.Gateway6 = network.GuestGateway6
}
}
return nic
@@ -256,7 +264,7 @@ func (netif *SNetInterface) getBaremetalJsonDesc() *types.SNic {
}
bn := netif.GetHostNetwork()
if bn != nil {
nic = netif.networkToNic(bn.IpAddr, bn.GetNetwork(), nic)
nic = netif.networkToNic(bn.IpAddr, bn.Ip6Addr, bn.GetNetwork(), nic)
}
return nic
}
@@ -290,6 +298,15 @@ func (netIf *SNetInterface) GetCandidateNetworkForIp(ctx context.Context, userCr
return wire.GetCandidateNetworkForIp(ctx, userCred, ownerId, scope, ipAddr)
}
func (netIf *SNetInterface) GetCandidateNetworkForIp6(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ip6Addr string) (*SNetwork, error) {
wire := netIf.GetWire()
if wire == nil {
return nil, nil
}
log.Infof("ip6Addr: %s, netiName: %s, wire: %s", ip6Addr, netIf.GetName(), wire.GetName())
return wire.GetCandidateNetworkForIp6(ctx, userCred, ownerId, scope, ip6Addr)
}
func (netif *SNetInterface) IsUsableServernic() bool {
if netif.NicType == api.NIC_TYPE_IPMI {
return false
+21 -18
View File
@@ -21,7 +21,6 @@ import (
"math"
"math/big"
"sort"
"strconv"
"strings"
"time"
@@ -122,9 +121,9 @@ type SNetwork struct {
// IPv6网关
GuestGateway6 string `width:"64" charset:"ascii" nullable:"true" list:"user" update:"user" create:"optional"`
// IPv6域名服务器
GuestDns6 string `width:"64" charset:"ascii" nullable:"true"`
// GuestDns6 string `width:"64" charset:"ascii" nullable:"true"`
GuestDomain6 string `width:"128" charset:"ascii" nullable:"true"`
// GuestDomain6 string `width:"128" charset:"ascii" nullable:"true"`
VlanId int `nullable:"false" default:"1" list:"user" update:"user" create:"optional"`
@@ -582,19 +581,6 @@ func (snet *SNetwork) _updateDnsRecord(name string, ipAddr string, isAdd bool) {
}
}
func (snet *SNetwork) updateGuestNetmap(nic *SGuestnetwork) {
// TODO
}
func (snet *SNetwork) UpdateBaremetalNetmap(nic *SHostnetwork, name string) {
snet.UpdateNetmap(nic.IpAddr, auth.AdminCredential().GetTenantId(), name)
}
func (snet *SNetwork) UpdateNetmap(ip, project, name string) {
// TODO ??
}
type DNSUpdateKeySecret struct {
Key string
Secret string
@@ -951,6 +937,23 @@ func (manager *SNetworkManager) GetOnPremiseNetworkOfIP(ipAddr string, serverTyp
return nil, sql.ErrNoRows
}
func (manager *SNetworkManager) GetOnPremiseNetworkOfIP6(ip6Addr string, serverType string, isPublic tristate.TriState) (*SNetwork, error) {
address, err := netutils.NewIPV6Addr(ip6Addr)
if err != nil {
return nil, errors.Wrap(err, "NewIPV6Addr")
}
nets, err := manager.fetchAllOnpremiseNetworks(serverType, isPublic)
if err != nil {
return nil, errors.Wrap(err, "fetchAllOnpremiseNetworks")
}
for _, n := range nets {
if n.IsAddress6InRange(address) {
return &n, nil
}
}
return nil, sql.ErrNoRows
}
func (manager *SNetworkManager) allNetworksQ(providers []string, brands []string, cloudEnv string, rangeObjs []db.IStandaloneModel) *sqlchemy.SQuery {
networks := manager.Query().SubQuery()
wires := WireManager.Query().SubQuery()
@@ -2579,7 +2582,7 @@ func (snet *SNetwork) isOneCloudVpcNetwork() bool {
return IsOneCloudVpcResource(snet)
}
func parseIpToIntArray(ip string) ([]int, error) {
/*func parseIpToIntArray(ip string) ([]int, error) {
ipSp := strings.Split(strings.Trim(ip, "."), ".")
if len(ipSp) > 4 {
return nil, httperrors.NewInputParameterError("Parse Ip Failed")
@@ -2596,7 +2599,7 @@ func parseIpToIntArray(ip string) ([]int, error) {
ipIa = append(ipIa, val)
}
return ipIa, nil
}
}*/
// IP子网列表
func (manager *SNetworkManager) ListItemFilter(
@@ -66,8 +66,20 @@ func (manager *SHostnetworkManager) handleNetworkIdChange(ctx context.Context, a
return err
}
for _, hn := range hns {
addr, _ := netutils.NewIPV4Addr(hn.IpAddr)
if args.newNet.IsAddressInRange(addr) {
inNet := false
if len(hn.IpAddr) > 0 {
addr, _ := netutils.NewIPV4Addr(hn.IpAddr)
if args.newNet.IsAddressInRange(addr) {
inNet = true
}
}
if len(hn.Ip6Addr) > 0 {
addr, _ := netutils.NewIPV6Addr(hn.Ip6Addr)
if args.newNet.IsAddress6InRange(addr) {
inNet = true
}
}
if inNet {
_, err = db.Update(&hn, func() error {
hn.NetworkId = args.newNet.Id
return nil
+1
View File
@@ -1982,6 +1982,7 @@ func (svpc *SVpc) GetDetailsTopology(ctx context.Context, userCred mcclient.Toke
for j := range hns {
host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{
IpAddr: hns[j].IpAddr,
Ip6Addr: hns[j].Ip6Addr,
MacAddr: hns[j].MacAddr,
})
}
+41 -1
View File
@@ -1036,7 +1036,7 @@ func (swire *SWire) GetCandidateNetworkForIp(ctx context.Context, userCred mccli
}
netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
}
for _, net := range netPublics {
if net.IsAddressInRange(ip) {
@@ -1046,6 +1046,32 @@ func (swire *SWire) GetCandidateNetworkForIp(ctx context.Context, userCred mccli
return nil, nil
}
func (swire *SWire) GetCandidateNetworkForIp6(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ip6Addr string) (*SNetwork, error) {
ip6, err := netutils.NewIPV6Addr(ip6Addr)
if err != nil {
return nil, errors.Wrapf(err, "netutils.NewIPV6Addr: %s", ip6Addr)
}
netPrivates, err := swire.getPrivateNetworks(ctx, userCred, ownerId, scope)
if err != nil {
return nil, errors.Wrapf(err, "swire.getPrivateNetworks %s", swire.GetId())
}
for _, net := range netPrivates {
if net.IsAddress6InRange(ip6) {
return &net, nil
}
}
netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
if err != nil {
return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
}
for _, net := range netPublics {
if net.IsAddress6InRange(ip6) {
return &net, nil
}
}
return nil, nil
}
func ChooseNetworkByAddressCount(nets []*SNetwork) (*SNetwork, *SNetwork) {
return chooseNetworkByAddressCount(nets)
}
@@ -1332,6 +1358,19 @@ func (manager *SWireManager) GetOnPremiseWireOfIp(ipAddr string) (*SWire, error)
}
}
func (manager *SWireManager) GetOnPremiseWireOfIp6(ip6Addr string) (*SWire, error) {
net, err := NetworkManager.GetOnPremiseNetworkOfIP6(ip6Addr, "", tristate.None)
if err != nil {
return nil, err
}
wire, _ := net.GetWire()
if wire != nil {
return wire, nil
} else {
return nil, fmt.Errorf("Wire not found")
}
}
func (w *SWire) PerformMergeNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeNetworkInput) (jsonutils.JSONObject, error) {
return nil, w.StartMergeNetwork(ctx, userCred, "")
}
@@ -1855,6 +1894,7 @@ func (swire *SWire) GetDetailsTopology(ctx context.Context, userCred mcclient.To
for j := range hns {
host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{
IpAddr: hns[j].IpAddr,
Ip6Addr: hns[j].Ip6Addr,
MacAddr: hns[j].MacAddr,
})
}
+14 -5
View File
@@ -36,6 +36,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/version"
"yunion.io/x/pkg/utils"
@@ -1588,7 +1589,7 @@ func (h *SHostInfo) updateOrCreateHost(hostId string) (*api.HostDetails, error)
if options.HostOptions.EnableSsl {
schema = "https"
}
if strings.Contains(masterIp, ":") {
if regutils.MatchIP6Addr(masterIp) {
input.ManagerUri = fmt.Sprintf("%s://[%s]:%d", schema, masterIp, options.HostOptions.Port)
} else {
input.ManagerUri = fmt.Sprintf("%s://%s:%d", schema, masterIp, options.HostOptions.Port)
@@ -1906,7 +1907,7 @@ func (h *SHostInfo) uploadNetworkInfo() error {
func (h *SHostInfo) doSendPhysicalNicInfo(nic *types.SNicDevInfo) error {
log.Infof("upload physical nic: %s(%s)", nic.Dev, nic.Mac)
_, err := h.doUploadNicInfoInternal(nic.Dev, nic.Mac.String(), 1, "", "", "", nic.Up != nil && *nic.Up)
_, err := h.doUploadNicInfoInternal(nic.Dev, nic.Mac.String(), 1, "", "", "", "", nic.Up != nil && *nic.Up)
if err != nil {
return errors.Wrap(err, "doUploadNicInfoInternal")
}
@@ -1914,15 +1915,15 @@ func (h *SHostInfo) doSendPhysicalNicInfo(nic *types.SNicDevInfo) error {
}
func (h *SHostInfo) doUploadNicInfo(nic *SNIC) (*api.HostDetails, error) {
hostDetails, err := h.doUploadNicInfoInternal(nic.Inter, nic.BridgeDev.GetMac(), nic.BridgeDev.GetVlanId(), nic.Wire, nic.Bridge, nic.Ip, true)
hostDetails, err := h.doUploadNicInfoInternal(nic.Inter, nic.BridgeDev.GetMac(), nic.BridgeDev.GetVlanId(), nic.Wire, nic.Bridge, nic.Ip, nic.Ip6, true)
if err != nil {
return nil, errors.Wrap(err, "doUploadNicInfoInternal")
}
return hostDetails, nil
}
func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire, bridge, ipaddr string, isUp bool) (*api.HostDetails, error) {
log.Infof("Upload NIC br:%s if:%s", bridge, ifname)
func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire, bridge, ipaddr, ip6addr string, isUp bool) (*api.HostDetails, error) {
log.Infof("Upload NIC br:%s if:%s ip:%s ip6:%s", bridge, ifname, ipaddr, ip6addr)
content := jsonutils.NewDict()
content.Set("mac", jsonutils.NewString(mac))
content.Set("vlan_id", jsonutils.NewInt(int64(vlanId)))
@@ -1942,6 +1943,14 @@ func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire
// always try to allocate from reserved pool
content.Set("reserve", jsonutils.JSONTrue)
}
if len(ip6addr) > 0 {
content.Set("ip6_addr", jsonutils.NewString(ip6addr))
if ip6addr == h.GetMasterIp() {
content.Set("nic_type", jsonutils.NewString(string(api.NIC_TYPE_ADMIN)))
}
// always try to allocate from reserved pool
content.Set("reserve", jsonutils.JSONTrue)
}
res, err := modules.Hosts.PerformAction(h.GetSession(), h.HostId, "add-netif", content)
if err != nil {
return nil, errors.Wrapf(err, "modules.Hosts.PerformAction add-netif: %s", content.String())
@@ -28,7 +28,7 @@ func init() {
"baremetalnetwork",
"baremetalnetworks",
[]string{"Baremetal_ID", "Host",
"Network_ID", "Network", "IP_addr", "Mac_addr",
"Network_ID", "Network", "IP_addr", "IP6_addr", "Mac_addr",
"Nic_Type"},
[]string{},
&Hosts,
+2 -1
View File
@@ -167,7 +167,8 @@ var (
func init() {
Hosts = HostManager{modules.NewComputeManager("host", "hosts",
[]string{"ID", "Name", "Access_mac", "Access_ip", "Ipmi_Ip", "Ovn_Mapped_Ip_Addr",
[]string{"ID", "Name", "Access_mac", "Access_ip", "Ipmi_Ip",
"Ovn_Mapped_Ip_Addr", "Ovn_Mapped_Ip6_Addr",
"Manager_URI",
"Status", "enabled", "host_status",
"Guests", "Running_guests",
+3 -2
View File
@@ -21,6 +21,7 @@ import (
"io"
"net"
"os"
"strconv"
"strings"
"time"
@@ -75,7 +76,7 @@ func (conf ClientConfig) Connect() (*ssh.Client, error) {
if err != nil {
return nil, err
}
addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
addr := net.JoinHostPort(conf.Host, strconv.Itoa(conf.Port))
client, err := ssh.Dial("tcp", addr, cliConfig)
if err != nil {
return nil, err
@@ -89,7 +90,7 @@ func (conf ClientConfig) ConnectContext(ctx context.Context) (*ssh.Client, error
return nil, err
}
addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
addr := net.JoinHostPort(conf.Host, strconv.Itoa(conf.Port))
d := &net.Dialer{}
netconn, err := d.DialContext(ctx, "tcp", addr)
if err != nil {
+92 -39
View File
@@ -122,9 +122,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
Name: vpcExtLsName(vpc.Id),
}
vpcR1extp = &ovn_nb.LogicalRouterPort{
Name: vpcR1extpName(vpc.Id),
Mac: apis.VpcInterExtMac1,
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcInterExtIP1(), apis.VpcInterExtMask)},
Name: vpcR1extpName(vpc.Id),
Mac: apis.VpcInterExtMac1,
Networks: []string{
fmt.Sprintf("%s/%d", apis.VpcInterExtIP1(), apis.VpcInterExtMask),
fmt.Sprintf("%s/%d", apis.VpcInterExtIP16(), apis.VpcInterExtMask6),
},
}
vpcExtr1p = &ovn_nb.LogicalSwitchPort{
Name: vpcExtr1pName(vpc.Id),
@@ -135,9 +138,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
},
}
vpcR2extp = &ovn_nb.LogicalRouterPort{
Name: vpcR2extpName(vpc.Id),
Mac: apis.VpcInterExtMac2,
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcInterExtIP2(), apis.VpcInterExtMask)},
Name: vpcR2extpName(vpc.Id),
Mac: apis.VpcInterExtMac2,
Networks: []string{
fmt.Sprintf("%s/%d", apis.VpcInterExtIP2(), apis.VpcInterExtMask),
fmt.Sprintf("%s/%d", apis.VpcInterExtIP26(), apis.VpcInterExtMask6),
},
}
vpcExtr2p = &ovn_nb.LogicalSwitchPort{
Name: vpcExtr2pName(vpc.Id),
@@ -175,9 +181,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
Name: vpcHostLsName(vpc.Id),
}
vpcRhp = &ovn_nb.LogicalRouterPort{
Name: vpcRhpName(vpc.Id),
Mac: apis.VpcMappedGatewayMac,
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP(), apis.VpcMappedIPMask)},
Name: vpcRhpName(vpc.Id),
Mac: apis.VpcMappedGatewayMac,
Networks: []string{
fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP(), apis.VpcMappedIPMask),
fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP6(), apis.VpcMappedIPMask6),
},
}
vpcHrp = &ovn_nb.LogicalSwitchPort{
Name: vpcHrpName(vpc.Id),
@@ -205,9 +214,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
Name: vpcEipLsName(vpc.Id),
}
vpcRep = &ovn_nb.LogicalRouterPort{
Name: vpcRepName(vpc.Id),
Mac: apis.VpcEipGatewayMac,
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP(), apis.VpcEipGatewayIPMask)},
Name: vpcRepName(vpc.Id),
Mac: apis.VpcEipGatewayMac,
Networks: []string{
fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP(), apis.VpcEipGatewayIPMask),
fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP6(), apis.VpcEipGatewayIPMask6),
},
}
vpcErp = &ovn_nb.LogicalSwitchPort{
Name: vpcErpName(vpc.Id),
@@ -265,7 +277,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
vpc = network.Vpc
rpMac = mac.HashSubnetRouterPortMac(network.Id)
mdMac = mac.HashSubnetMetadataMac(network.Id)
mdIp = "169.254.169.254"
// mdIp = "169.254.169.254"
)
netLs := &ovn_nb.LogicalSwitch{
Name: netLsName(network.Id),
@@ -275,16 +287,22 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
}
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
networks = append(networks, fmt.Sprintf("%s/%d", network.GuestGateway6, network.GuestIp6Mask))
for _, ip6 := range opts.MetadataServerIp6s {
networks = append(networks, fmt.Sprintf("%s/128", ip6))
}
}
netRnp := &ovn_nb.LogicalRouterPort{
Name: netRnpName(network.Id),
Mac: rpMac,
Networks: networks,
}
mtu := opts.OvnUnderlayMtu
mtu -= apis.VPC_OVN_ENCAP_COST
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
netRnp.Ipv6RaConfigs = map[string]string{
"address_mode": "dhcpv6_stateful",
// "send_periodic": "false",
"address_mode": "dhcpv6_stateful",
"mtu": fmt.Sprintf("%d", mtu),
"send_periodic": "true",
}
}
netNrp := &ovn_nb.LogicalSwitchPort{
@@ -295,10 +313,13 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
"router-port": netRnpName(network.Id),
},
}
netMdpAddrs := []string{mdMac}
netMdpAddrs = append(netMdpAddrs, opts.MetadataServerIp4s...)
netMdpAddrs = append(netMdpAddrs, opts.MetadataServerIp6s...)
netMdp := &ovn_nb.LogicalSwitchPort{
Name: netMdpName(network.Id),
Type: "localport",
Addresses: []string{fmt.Sprintf("%s %s", mdMac, mdIp)},
Addresses: []string{strings.Join(netMdpAddrs, " ")},
}
var (
vpcExtBackRoute *ovn_nb.LogicalRouterStaticRoute
@@ -306,7 +327,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
vpcExtBackRoute6 *ovn_nb.LogicalRouterStaticRoute
vpcExtBackRoute6IdRef string
)
{
if len(network.GuestGateway) > 0 && network.GuestIpMask > 0 {
if ipAddr, err := netutils.NewIPV4Addr(network.GuestGateway); err != nil {
return errors.Wrap(err, "NewIPV4Addr GuestGateway")
} else {
@@ -325,7 +346,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
vpcExtBackRouteIdRef = "vpcExtBackRoute"
}
}
/*if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
if ip6Addr, err := netutils.NewIPV6Addr(network.GuestGateway6); err != nil {
return errors.Wrap(err, "NewIPV6Addr GuestGateway6")
} else {
@@ -335,7 +356,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
vpcExtBackRoute6 = &ovn_nb.LogicalRouterStaticRoute{
Policy: ptr("dst-ip"),
IpPrefix: netAddrCidr6,
Nexthop: apis.VpcInterExtIP1().String(),
Nexthop: apis.VpcInterExtIP16().String(),
OutputPort: ptr(vpcR2extpName(vpc.Id)),
ExternalIds: map[string]string{
externalKeyOcRef: ocStaticRoute6Ref,
@@ -343,7 +364,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
}
vpcExtBackRoute6IdRef = "vpcExtBackRoute6"
}
}*/
}
var (
args []string
@@ -354,7 +375,9 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
netRnp,
netNrp,
netMdp,
vpcExtBackRoute,
}
if vpcExtBackRoute != nil {
irows = append(irows, vpcExtBackRoute)
}
if vpcExtBackRoute6 != nil {
irows = append(irows, vpcExtBackRoute6)
@@ -368,13 +391,17 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
args = append(args, ovnCreateArgs(netRnp, netRnp.Name)...)
args = append(args, ovnCreateArgs(netNrp, netNrp.Name)...)
args = append(args, ovnCreateArgs(netMdp, netMdp.Name)...)
args = append(args, ovnCreateArgs(vpcExtBackRoute, vpcExtBackRouteIdRef)...)
if vpcExtBackRoute != nil {
args = append(args, ovnCreateArgs(vpcExtBackRoute, vpcExtBackRouteIdRef)...)
}
if vpcExtBackRoute6 != nil {
args = append(args, ovnCreateArgs(vpcExtBackRoute6, vpcExtBackRoute6IdRef)...)
}
args = append(args, "--", "add", "Logical_Switch", netLs.Name, "ports", "@"+netNrp.Name, "@"+netMdp.Name)
args = append(args, "--", "add", "Logical_Router", vpcLrName(vpc.Id), "ports", "@"+netRnp.Name)
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRouteIdRef)
if vpcExtBackRoute != nil {
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRouteIdRef)
}
if vpcExtBackRoute6 != nil {
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRoute6IdRef)
}
@@ -387,7 +414,7 @@ func (keeper *OVNNorthboundKeeper) ClaimVpcHost(ctx context.Context, vpc *agentm
)
vpcHostLsp := &ovn_nb.LogicalSwitchPort{
Name: vpcHostLspName(vpc.Id, host.Id),
Addresses: []string{fmt.Sprintf("%s %s", mac.HashVpcHostDistgwMac(host.Id), host.OvnMappedIpAddr)},
Addresses: []string{fmt.Sprintf("%s %s %s", mac.HashVpcHostDistgwMac(host.Id), host.OvnMappedIpAddr, host.OvnMappedIp6Addr)},
}
if m := keeper.DB.LogicalSwitchPort.FindOneMatchNonZeros(vpcHostLsp); m != nil {
m.SetExternalId(externalKeyOcVersion, ocVersion)
@@ -413,10 +440,11 @@ func (keeper *OVNNorthboundKeeper) ClaimVpcEipgw(ctx context.Context, vpc *agent
var (
ocVersion = fmt.Sprintf("%s.%d", vpc.UpdatedAt, vpc.UpdateVersion)
eipgwVip = apis.VpcEipGatewayIP3().String()
eipgwVip6 = apis.VpcEipGatewayIP63().String()
)
vpcEipLsp := &ovn_nb.LogicalSwitchPort{
Name: vpcEipLspName(vpc.Id, eipgwVip),
Addresses: []string{fmt.Sprintf("%s %s", apis.VpcEipGatewayMac3, eipgwVip)},
Addresses: []string{fmt.Sprintf("%s %s %s", apis.VpcEipGatewayMac3, eipgwVip, eipgwVip6)},
}
if m := keeper.DB.LogicalSwitchPort.FindOneMatchNonZeros(vpcEipLsp); m != nil {
m.SetExternalId(externalKeyOcVersion, ocVersion)
@@ -457,7 +485,7 @@ func generateDhcpOptions(ctx context.Context, guestnetwork *agentmodels.Guestnet
var (
network = guestnetwork.Network
dhcpMac = mac.HashSubnetDhcpMac(network.Id)
mdIp = "169.254.169.254/32"
mdIp = fmt.Sprintf("%s/32", opts.MetadataServerIp4s[0])
ocDhcpRef = fmt.Sprintf("dhcp/%s/%s", guestnetwork.GuestId, guestnetwork.Ifname)
)
@@ -618,6 +646,8 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
ocAclRef = fmt.Sprintf("acl/%s/%s/%s", network.Id, guestnetwork.GuestId, guestnetwork.Ifname)
ocQosRef = fmt.Sprintf("qos/%s/%s/%s", network.Id, guestnetwork.GuestId, guestnetwork.Ifname)
ocQosEipRef = fmt.Sprintf("qos-eip/%s/%s/%s/v2", vpc.Id, guestnetwork.GuestId, guestnetwork.Ifname)
ocGnrDefault6Ref = fmt.Sprintf("gnrDefault6/%s/%s/%s", vpc.Id, guestnetwork.GuestId, guestnetwork.Ifname)
)
var (
@@ -708,10 +738,11 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
}
var (
gnrDefault *ovn_nb.LogicalRouterStaticRoute
qosEipIn *ovn_nb.QoS
qosEipOut *ovn_nb.QoS
hasQoSEip bool
gnrDefault *ovn_nb.LogicalRouterStaticRoute
gnrDefault6 *ovn_nb.LogicalRouterStaticRoute
qosEipIn *ovn_nb.QoS
qosEipOut *ovn_nb.QoS
hasQoSEip bool
)
{
gnrDefaultPolicy := "src-ip"
@@ -759,14 +790,27 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
}
} else if vpcHasDistgw(vpc) {
gnrDefault = &ovn_nb.LogicalRouterStaticRoute{
Policy: &gnrDefaultPolicy,
IpPrefix: guestnetwork.IpAddr + "/32",
Nexthop: host.OvnMappedIpAddr,
OutputPort: ptr(vpcRhpName(vpc.Id)),
ExternalIds: map[string]string{
externalKeyOcRef: ocGnrDefaultRef,
},
if len(guestnetwork.IpAddr) > 0 {
gnrDefault = &ovn_nb.LogicalRouterStaticRoute{
Policy: &gnrDefaultPolicy,
IpPrefix: guestnetwork.IpAddr + "/32",
Nexthop: host.OvnMappedIpAddr,
OutputPort: ptr(vpcRhpName(vpc.Id)),
ExternalIds: map[string]string{
externalKeyOcRef: ocGnrDefaultRef,
},
}
}
if len(guestnetwork.Ip6Addr) > 0 {
gnrDefault6 = &ovn_nb.LogicalRouterStaticRoute{
Policy: &gnrDefaultPolicy,
IpPrefix: guestnetwork.Ip6Addr + "/32",
Nexthop: host.OvnMappedIp6Addr,
OutputPort: ptr(vpcRhpName(vpc.Id)),
ExternalIds: map[string]string{
externalKeyOcRef: ocGnrDefault6Ref,
},
}
}
}
}
@@ -794,7 +838,9 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
irows := []types.IRow{
gnp,
dhcpOpt,
}
if len(guestnetwork.IpAddr) > 0 {
irows = append(irows, dhcpOpt)
}
if len(guestnetwork.Ip6Addr) > 0 {
irows = append(irows, dhcp6Opt)
@@ -802,6 +848,9 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
if gnrDefault != nil {
irows = append(irows, gnrDefault)
}
if gnrDefault6 != nil {
irows = append(irows, gnrDefault6)
}
for _, acl := range acls {
irows = append(irows, acl)
}
@@ -828,6 +877,10 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
args = append(args, ovnCreateArgs(gnrDefault, "gnrDefault")...)
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@gnrDefault")
}
if gnrDefault6 != nil {
args = append(args, ovnCreateArgs(gnrDefault6, "gnrDefault6")...)
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@gnrDefault6")
}
for i, acl := range acls {
ref := fmt.Sprintf("acl%d", i)
args = append(args, ovnCreateArgs(acl, ref)...)
+3 -2
View File
@@ -16,7 +16,8 @@ package helper
import (
"context"
"fmt"
"net"
"strconv"
"time"
"golang.org/x/crypto/ssh"
@@ -82,7 +83,7 @@ func GetValidPrivateKey(host string, port int, username string, projectId string
ssh.PublicKeys(signer),
},
}
addr := fmt.Sprintf("%s:%d", host, port)
addr := net.JoinHostPort(host, strconv.Itoa(port))
client, err := ssh.Dial("tcp", addr, config)
if err != nil {
errs = append(errs, errors.Wrapf(err, "dial %s by %s", addr, username))
+1
View File
@@ -254,6 +254,7 @@ func handleSshShell(ctx context.Context, w http.ResponseWriter, r *http.Request)
}
func handleSshSession(ctx context.Context, session *session.SSshSession, w http.ResponseWriter) {
log.Infof("handleSshSession %s", jsonutils.Marshal(session).String())
handleDataSession(ctx, session, w, "ws", nil, false)
}
+2 -4
View File
@@ -107,15 +107,13 @@ func resolveServerIPPortById(ctx context.Context, s *mcclient.ClientSession, id
ip = guestNicDetails.EipAddr
} else if len(guestNicDetails.IpAddr) > 0 {
ip = guestNicDetails.IpAddr
} else if len(guestNicDetails.Ip6Addr) > 0 {
ip = guestNicDetails.Ip6Addr
} else {
return "", 0, nil, errors.Wrap(httperrors.ErrNotSupported, "no valid ipv4 addr")
}
}
if ip == guestNicDetails.Ip6Addr {
return "", 0, nil, errors.Wrap(httperrors.ErrNotSupported, "ipv6 not supported")
}
if ip == guestNicDetails.IpAddr && len(guestNicDetails.MappedIpAddr) > 0 {
// need to do open forward
ip, port, err = acquireForward(ctx, s, guestDetails.Id, ip, "tcp", port)
+3 -2
View File
@@ -16,8 +16,9 @@ package session
import (
"context"
"fmt"
"net"
"os/exec"
"strconv"
"time"
"golang.org/x/crypto/ssh"
@@ -111,7 +112,7 @@ func (s *SSshSession) IsNeedLogin() (bool, error) {
ssh.Password(s.Password),
},
}
addr := fmt.Sprintf("%s:%d", s.Host, s.Port)
addr := net.JoinHostPort(s.Host, strconv.Itoa(s.Port))
client, err := ssh.Dial("tcp", addr, config)
if err != nil {
return true, err