Skip to content

Commit

Permalink
Feature: IPv6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
adjivas committed Feb 19, 2025
1 parent 7595dfe commit 439a64b
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 47 deletions.
78 changes: 48 additions & 30 deletions internal/context/ausf_context_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package context
import (
"fmt"
"os"
"strconv"
"net/netip"

"github.com/google/uuid"

"github.com/free5gc/ausf/internal/net_util"
"github.com/free5gc/ausf/internal/logger"
"github.com/free5gc/ausf/pkg/factory"
"github.com/free5gc/openapi/models"
Expand All @@ -23,36 +24,46 @@ func InitAusfContext(context *AUSFContext) {
context.GroupID = configuration.GroupId
context.NrfUri = configuration.NrfUri
context.NrfCertPem = configuration.NrfCertPem
context.UriScheme = models.UriScheme(configuration.Sbi.Scheme) // default uri scheme
context.RegisterIPv4 = factory.AusfSbiDefaultIPv4 // default localhost
context.SBIPort = factory.AusfSbiDefaultPort // default port
if sbi != nil {
if sbi.RegisterIPv4 != "" {
context.RegisterIPv4 = sbi.RegisterIPv4
}
if sbi.Port != 0 {
context.SBIPort = sbi.Port
}

if sbi.Scheme == "https" {
context.UriScheme = models.UriScheme_HTTPS
} else {
context.UriScheme = models.UriScheme_HTTP
}

context.BindingIPv4 = os.Getenv(sbi.BindingIPv4)
if context.BindingIPv4 != "" {
logger.InitLog.Info("Parsing ServerIPv4 address from ENV Variable.")
} else {
context.BindingIPv4 = sbi.BindingIPv4
if context.BindingIPv4 == "" {
logger.InitLog.Warn("Error parsing ServerIPv4 address as string. Using the 0.0.0.0 address as default.")
context.BindingIPv4 = "0.0.0.0"
}
}

if sbi.RegisterIP != "" {
context.RegisterIP = sbi.RegisterIP
} else if sbi.RegisterIPv4 != "" {
context.RegisterIP = sbi.RegisterIPv4
} else {
context.RegisterIP = factory.AusfSbiDefaultIPv4 // default uri scheme
}

if sbi.Port != 0 {
context.SBIPort = sbi.Port
} else {
context.SBIPort = factory.AusfSbiDefaultPort // default port
}

context.Url = string(context.UriScheme) + "://" + context.RegisterIPv4 + ":" + strconv.Itoa(context.SBIPort)
if sbi.Scheme == "https" {
context.UriScheme = models.UriScheme_HTTPS
} else {
context.UriScheme = models.UriScheme_HTTP
}

if bindingIP := os.Getenv(sbi.BindingIP); bindingIP != "" {
context.BindingIP = bindingIP;
logger.InitLog.Info("Parsing ServerIP address from ENV Variable.")
} else if bindingIP := sbi.BindingIP; bindingIP != "" {
context.BindingIP = bindingIP;
} else if bindingIPv4 := os.Getenv(sbi.BindingIPv4); bindingIPv4 != "" {
context.BindingIP = bindingIPv4;
logger.InitLog.Info("Parsing ServerIPv4 address from ENV Variable.")
} else if bindingIPv4 := sbi.BindingIPv4; bindingIPv4 != "" {
context.BindingIP = bindingIPv4;
} else {
logger.InitLog.Warn("Error parsing ServerIPv4 address as string. Using the 0.0.0.0 address as default.")
context.BindingIP = "0.0.0.0"
}

sbiRegisterIp := net_util.RegisterAddr(context.RegisterIP)
sbiPort := uint16(context.SBIPort)

context.Url = string(context.UriScheme) + "://" + netip.AddrPortFrom(sbiRegisterIp, sbiPort).String()
context.PlmnList = append(context.PlmnList, configuration.PlmnSupportList...)

// context.NfService
Expand All @@ -74,8 +85,15 @@ func AddNfServices(serviceMap *map[models.ServiceName]models.NfService, config *
nfService.ServiceName = models.ServiceName_NAUSF_AUTH

var ipEndPoint models.IpEndPoint
ipEndPoint.Ipv4Address = context.RegisterIPv4
ipEndPoint.Port = int32(context.SBIPort)

registerAddr := net_util.RegisterAddr(context.RegisterIP)
if registerAddr.Is6() {
ipEndPoint.Ipv6Address = context.RegisterIP
} else if registerAddr.Is4() {
ipEndPoint.Ipv4Address = context.RegisterIP
}

ipEndPoints = append(ipEndPoints, ipEndPoint)

var nfServiceVersion models.NfServiceVersion
Expand Down
4 changes: 2 additions & 2 deletions internal/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ type AUSFContext struct {
NfId string
GroupID string
SBIPort int
RegisterIPv4 string
BindingIPv4 string
RegisterIP string
BindingIP string
Url string
UriScheme models.UriScheme
NrfUri string
Expand Down
17 changes: 17 additions & 0 deletions internal/net_util/net_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package net_util

import (
"net"
"net/netip"

"github.com/free5gc/ausf/internal/logger"
)

func RegisterAddr(registerIP string) netip.Addr {
ips, err := net.LookupIP(registerIP)
if err != nil {
logger.InitLog.Errorf("Resolve RegisterIP hostname %s failed: %+v", registerIP, err)
}
ip, _ := netip.ParseAddr(ips[0].String());

Check failure on line 15 in internal/net_util/net_util.go

View workflow job for this annotation

GitHub Actions / lint (1.21)

Error return value of `netip.ParseAddr` is not checked (errcheck)
return ip
}
26 changes: 19 additions & 7 deletions internal/sbi/consumer/nrf_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"
"net/http"
"strconv"
"net/netip"
"strings"
"sync"
"time"
Expand All @@ -18,6 +18,7 @@ import (
"github.com/free5gc/openapi/Nnrf_NFDiscovery"
"github.com/free5gc/openapi/Nnrf_NFManagement"
"github.com/free5gc/openapi/models"
"github.com/free5gc/ausf/internal/net_util"
)

type nnrfService struct {
Expand Down Expand Up @@ -200,7 +201,13 @@ func (s *nnrfService) buildNfProfile(ausfContext *ausf_context.AUSFContext) (pro
profile.NfInstanceId = ausfContext.NfId
profile.NfType = models.NfType_AUSF
profile.NfStatus = models.NfStatus_REGISTERED
profile.Ipv4Addresses = append(profile.Ipv4Addresses, ausfContext.RegisterIPv4)

registerAddr := net_util.RegisterAddr(ausfContext.RegisterIP)
if registerAddr.Is6() {
profile.Ipv6Addresses = append(profile.Ipv6Addresses, ausfContext.RegisterIP)
} else if registerAddr.Is4() {
profile.Ipv4Addresses = append(profile.Ipv4Addresses, ausfContext.RegisterIP)
}
services := []models.NfService{}
for _, nfService := range ausfContext.NfService {
services = append(services, nfService)
Expand Down Expand Up @@ -235,13 +242,18 @@ func (s *nnrfService) GetUdmUrl(nrfUri string) string {
nfDiscoverParam,
)
if err != nil {
logger.ConsumerLog.Errorln("[Search UDM UEAU] ", err.Error(), "use defalt udmUrl", udmUrl)
logger.ConsumerLog.Errorln("[Search UDM UEAU] ", err.Error(), "use default udmUrl", udmUrl)
} else if len(res.NfInstances) > 0 {
udmInstance := res.NfInstances[0]
if len(udmInstance.Ipv4Addresses) > 0 && udmInstance.NfServices != nil {
ueauService := (*udmInstance.NfServices)[0]
ueauEndPoint := (*ueauService.IpEndPoints)[0]
udmUrl = string(ueauService.Scheme) + "://" + ueauEndPoint.Ipv4Address + ":" + strconv.Itoa(int(ueauEndPoint.Port))
ueauService := (*udmInstance.NfServices)[0]
ueauEndPoint := (*ueauService.IpEndPoints)[0]
port := uint16(ueauEndPoint.Port)
if len(udmInstance.Ipv6Addresses) > 0 && udmInstance.NfServices != nil {
registerIp := net_util.RegisterAddr(ueauEndPoint.Ipv6Address)
udmUrl = string(ueauService.Scheme) + "://" + netip.AddrPortFrom(registerIp, port).String()
} else if len(udmInstance.Ipv4Addresses) > 0 && udmInstance.NfServices != nil {
registerIp := net_util.RegisterAddr(ueauEndPoint.Ipv4Address)
udmUrl = string(ueauService.Scheme) + "://" + netip.AddrPortFrom(registerIp, port).String()
}
} else {
logger.ConsumerLog.Errorln("[Search UDM UEAU] len(NfInstances) = 0")
Expand Down
39 changes: 31 additions & 8 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"strconv"
"sync"
"net/netip"

"github.com/asaskevich/govalidator"

Expand Down Expand Up @@ -106,16 +107,29 @@ func (c *Configuration) validate() (bool, error) {
}

type Sbi struct {
Scheme string `yaml:"scheme" valid:"scheme"`
RegisterIPv4 string `yaml:"registerIPv4,omitempty" valid:"host,required"` // IP that is registered at NRF.
BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,required"` // IP used to run the server in the node.
Port int `yaml:"port,omitempty" valid:"port,required"`
Scheme string `yaml:"scheme" valid:"in(http|https)"`
RegisterIPv4 string `yaml:"registerIPv4,omitempty" valid:"host,optional"` // IP that is registered at NRF.
RegisterIP string `yaml:"registerIP,omitempty" valid:"host,optional"` // IP that is registered at NRF.
BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,optional"` // IP used to run the server in the node.
BindingIP string `yaml:"bindingIP,omitempty" valid:"host,optional"` // IP used to run the server in the node.
Port int `yaml:"port,omitempty" valid:"port,required,with_register,with_binding"`
Tls *Tls `yaml:"tls,omitempty" valid:"optional"`
}

func (s *Sbi) validate() (bool, error) {
govalidator.TagMap["scheme"] = govalidator.Validator(func(str string) bool {
return str == "https" || str == "http"
govalidator.CustomTypeTagMap.Set("with_register", func(i interface{}, context interface{}) bool {
switch v := context.(type) {
case Sbi:
return (v.RegisterIPv4 != "" && v.RegisterIP == "") || (v.RegisterIP != "" && v.RegisterIPv4 == "")
}
return false
})
govalidator.CustomTypeTagMap.Set("with_binding", func(i interface{}, context interface{}) bool {
switch v := context.(type) {
case Sbi:
return (v.BindingIPv4 != "" && v.BindingIP == "") || (v.BindingIP != "" && v.BindingIPv4 == "")
}
return false
})

if tls := s.Tls; tls != nil {
Expand Down Expand Up @@ -240,7 +254,10 @@ func (c *Config) GetLogReportCaller() bool {
func (c *Config) GetSbiBindingAddr() string {
c.RLock()
defer c.RUnlock()
return c.GetSbiBindingIP() + ":" + strconv.Itoa(c.GetSbiPort())

bindIP, _ := netip.ParseAddr(c.GetSbiBindingIP());

Check failure on line 258 in pkg/factory/config.go

View workflow job for this annotation

GitHub Actions / lint (1.21)

Error return value of `netip.ParseAddr` is not checked (errcheck)
sbiPort := uint16(c.GetSbiPort())
return netip.AddrPortFrom(bindIP, sbiPort).String()
}

func (c *Config) GetSbiBindingIP() string {
Expand All @@ -250,7 +267,13 @@ func (c *Config) GetSbiBindingIP() string {
if c.Configuration == nil || c.Configuration.Sbi == nil {
return bindIP
}
if c.Configuration.Sbi.BindingIPv4 != "" {
if c.Configuration.Sbi.BindingIP != "" {
if bindIP = os.Getenv(c.Configuration.Sbi.BindingIP); bindIP != "" {
logger.CfgLog.Infof("Parsing ServerIP [%s] from ENV Variable", bindIP)
} else {
bindIP = c.Configuration.Sbi.BindingIP
}
} else if c.Configuration.Sbi.BindingIPv4 != "" {
if bindIP = os.Getenv(c.Configuration.Sbi.BindingIPv4); bindIP != "" {
logger.CfgLog.Infof("Parsing ServerIPv4 [%s] from ENV Variable", bindIP)
} else {
Expand Down

0 comments on commit 439a64b

Please sign in to comment.