Skip to content

Commit

Permalink
Validate Addressfamily
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 committed Jan 30, 2025
1 parent 0d64c98 commit ff87efa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
14 changes: 14 additions & 0 deletions cmd/metal-api/internal/metal/network.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package metal

import (
"fmt"
"net"
"net/netip"
"strconv"
Expand Down Expand Up @@ -266,12 +267,25 @@ type AddressFamily string
type AddressFamilies []AddressFamily

const (
// InvalidAddressFamily identifies a invalid Addressfamily
InvalidAddressFamily = AddressFamily("invalid")
// IPv4AddressFamily identifies IPv4
IPv4AddressFamily = AddressFamily("IPv4")
// IPv6AddressFamily identifies IPv6
IPv6AddressFamily = AddressFamily("IPv6")
)

// Validate a string if it is a addressfamily and returns an error if it is not.
func ValidateAddressFamily(af string) (AddressFamily, error) {
switch strings.ToLower(af) {
case "ipv4":
return IPv4AddressFamily, nil
case "ipv6":
return IPv6AddressFamily, nil
}
return InvalidAddressFamily, fmt.Errorf("given addressfamily:%q is invalid", af)
}

// ToAddressFamily will convert a string af to a AddressFamily
func ToAddressFamily(af string) AddressFamily {
switch strings.ToLower(af) {
Expand Down
7 changes: 6 additions & 1 deletion cmd/metal-api/internal/service/ip-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,12 @@ func (r *ipResource) allocateIP(request *restful.Request, response *restful.Resp
}

if requestPayload.AddressFamily != nil {
if !slices.Contains(nw.AddressFamilies, metal.ToAddressFamily(string(*requestPayload.AddressFamily))) {
af, err := metal.ValidateAddressFamily(string(*requestPayload.AddressFamily))
if err != nil {
r.sendError(request, response, defaultError(err))
return
}
if !slices.Contains(nw.AddressFamilies, af) {
r.sendError(request, response, httperrors.BadRequest(
fmt.Errorf("there is no prefix for the given addressfamily:%s present in network:%s", string(*requestPayload.AddressFamily), requestPayload.NetworkID)),
)
Expand Down
26 changes: 20 additions & 6 deletions cmd/metal-api/internal/service/network-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,12 @@ func (r *networkResource) createNetwork(request *restful.Request, response *rest

var childPrefixLength = metal.ChildPrefixLength{}
for af, length := range requestPayload.DefaultChildPrefixLength {
childPrefixLength[metal.ToAddressFamily(string(af))] = length
addressfamily, err := metal.ValidateAddressFamily(string(af))
if err != nil {
r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily of defaultchildprefixlength is invalid %w", err)))
return
}
childPrefixLength[addressfamily] = length
}

prefixes, destPrefixes, addressFamilies, err := validatePrefixesAndAddressFamilies(requestPayload.Prefixes, requestPayload.DestinationPrefixes, childPrefixLength, privateSuper)
Expand Down Expand Up @@ -627,21 +632,30 @@ func (r *networkResource) allocateNetwork(request *restful.Request, response *re
length := superNetwork.DefaultChildPrefixLength
if len(requestPayload.Length) > 0 {
for af, l := range requestPayload.Length {
length[metal.ToAddressFamily(string(af))] = l
addressfamily, err := metal.ValidateAddressFamily(string(af))
if err != nil {
r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily of length is invalid %w", err)))
return
}
length[addressfamily] = l
}
}

if requestPayload.AddressFamily != nil {
af := metal.ToAddressFamily(string(*requestPayload.AddressFamily))
bits, ok := length[af]
addressfamily, err := metal.ValidateAddressFamily(string(*requestPayload.AddressFamily))
if err != nil {
r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily is invalid %w", err)))
return
}
bits, ok := length[addressfamily]
if !ok {
r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamiliy %s specified, but no childprefixlength for this addressfamily", *requestPayload.AddressFamily)))
return
}
length = metal.ChildPrefixLength{
af: bits,
addressfamily: bits,
}
nwSpec.AddressFamilies = metal.AddressFamilies{af}
nwSpec.AddressFamilies = metal.AddressFamilies{addressfamily}
}

r.log.Info("network allocate", "supernetwork", superNetwork.ID, "defaultchildprefixlength", superNetwork.DefaultChildPrefixLength, "length", length)
Expand Down

0 comments on commit ff87efa

Please sign in to comment.