Skip to content

Commit 4205264

Browse files
committedJan 6, 2023
Attractor ipv4/ipv6-prefix also accept IP range
Allows limiting the pool of IP addresses to allocate IPs from. -Enables coordination of multiple Attractors when they share the same external network. -Can be also used to exclude reserved IPs of Gateway Routers. Example: ipv4-prefix: 169.254.100.0-169.254.100.100/24 ipv6-prefix: 100:100::0-100:100::100/64;100:100::2000-100:100::ffff/64
1 parent 3805116 commit 4205264

File tree

4 files changed

+63
-10
lines changed

4 files changed

+63
-10
lines changed
 

‎api/v1/attractor_types.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,18 @@ type InterfaceSpec struct {
5050
// +kubebuilder:validation:Pattern=`^[^:\//\s]{1,13}$`
5151
Name string `json:"name"`
5252

53-
// (immutable) IPv4 prefix of the interface, which is used for frontend to set up communication with the ipv4 gateways.
53+
// (immutable) IPv4 prefix or range of the interface, which is used for frontend to set up communication with the ipv4 gateways.
5454
// If the type is "nsm-vlan", this information must be specified.
55+
// For example, '192.168.100.0/24', '192.168.100.1-192.168.100.100/24'.
56+
// Multiple IP ranges can be combined using semicolon delimiter, but they must belong to the same network.
57+
// For example, '192.168.100.3-192.168.100.100/24;192.168.100.200-192.168.100.250/24'.
5558
PrefixIPv4 string `json:"ipv4-prefix,omitempty"`
5659

57-
// (immutable) IPv6 prefix of the interface, which is used for frontend to set up communication with the ipv6 gateways.
60+
// (immutable) IPv6 prefix or range of the interface, which is used for frontend to set up communication with the ipv6 gateways.
5861
// If the type is "nsm-vlan", this information must be specified.
62+
// For example, '100:100::/64', '100:100::bbbb-100:100::cccc/64'.
63+
// Multiple IP ranges can be combined using semicolon delimiter, but they must belong to the same network.
64+
// For example, '100:100::2-100:100::ffff/64;100:100::a:2-100:100::a:f/64;100:100::e:2-100:100::e:f/64'.
5965
PrefixIPv6 string `json:"ipv6-prefix,omitempty"`
6066

6167
// Interface choice.

‎api/v1/attractor_webhook.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ func (r *Attractor) validateAttractor() error {
9494
}
9595
switch r.Spec.Interface.Type {
9696
case NSMVlan:
97-
_, err := validatePrefix(r.Spec.Interface.PrefixIPv4)
97+
err := validatePrefixAndRange(r.Spec.Interface.PrefixIPv4)
9898
if err != nil {
9999
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("ipv4-prefix"), r.Spec.Interface.PrefixIPv4, err.Error()))
100100
}
101101

102-
_, err = validatePrefix(r.Spec.Interface.PrefixIPv6)
102+
err = validatePrefixAndRange(r.Spec.Interface.PrefixIPv6)
103103
if err != nil {
104104
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("ipv6-prefix"), r.Spec.Interface.PrefixIPv6, err.Error()))
105105
}

‎api/v1/types.go

+41
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,47 @@ func validatePrefix(p string) (*net.IPNet, error) {
9898
return n, nil
9999
}
100100

101+
func validatePrefixAndRange(p string) error {
102+
var err error
103+
var network *net.IPNet
104+
composite := strings.Split(p, ";")
105+
for _, c := range composite {
106+
if r := strings.SplitN(c, "-", 2); len(r) == 2 {
107+
// validate IP range
108+
firstip := net.ParseIP(r[0])
109+
if firstip == nil {
110+
return fmt.Errorf("'%s' is not a valid IP range start", r[0])
111+
}
112+
_, ipNet, err := net.ParseCIDR(r[1])
113+
if err != nil {
114+
return fmt.Errorf("'%s' is not a valid CIDR: %s", r[1], err)
115+
}
116+
if !ipNet.Contains(firstip) {
117+
return fmt.Errorf("'%s' is not a valid IP range start for CIDR %s", ipNet.String(), firstip)
118+
}
119+
if network == nil {
120+
network = ipNet
121+
} else {
122+
if !network.IP.Equal(ipNet.IP) {
123+
return fmt.Errorf("network mismatch: '%s' != '%s'", network, ipNet)
124+
}
125+
netOnes, netBits := network.Mask.Size()
126+
ones, bits := ipNet.Mask.Size()
127+
if netOnes != ones || netBits != bits {
128+
return fmt.Errorf("network mask mismatch: %v != %v", network.Mask, ipNet.Mask)
129+
}
130+
}
131+
} else {
132+
// validate prefix
133+
if len(composite) > 1 {
134+
return fmt.Errorf("%s composite subnet config is invalid", composite)
135+
}
136+
_, err = validatePrefix(c)
137+
}
138+
}
139+
return err
140+
}
141+
101142
type InterfaceType string
102143

103144
const (

‎config/crd/bases/meridio.nordix.org_attractors.yaml

+12-6
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,20 @@ spec:
7474
description: defines the interface information that attractor use
7575
properties:
7676
ipv4-prefix:
77-
description: (immutable) IPv4 prefix of the interface, which is
78-
used for frontend to set up communication with the ipv4 gateways.
79-
If the type is "nsm-vlan", this information must be specified.
77+
description: (immutable) IPv4 prefix or range of the interface,
78+
which is used for frontend to set up communication with the
79+
ipv4 gateways. If the type is "nsm-vlan", this information must
80+
be specified. For example, '192.168.100.0/24', '192.168.100.1-192.168.100.100/24'.
81+
Multiple IP ranges can be combined using semicolon delimiter,
82+
but they must belong to the same network. For example, '192.168.100.3-192.168.100.100/24;192.168.100.200-192.168.100.250/24'.
8083
type: string
8184
ipv6-prefix:
82-
description: (immutable) IPv6 prefix of the interface, which is
83-
used for frontend to set up communication with the ipv6 gateways.
84-
If the type is "nsm-vlan", this information must be specified.
85+
description: (immutable) IPv6 prefix or range of the interface,
86+
which is used for frontend to set up communication with the
87+
ipv6 gateways. If the type is "nsm-vlan", this information must
88+
be specified. For example, '100:100::/64', '100:100::bbbb-100:100::cccc/64'.
89+
Multiple IP ranges can be combined using semicolon delimiter,
90+
but they must belong to the same network. For example, '100:100::2-100:100::ffff/64;100:100::a:2-100:100::a:f/64;100:100::e:2-100:100::e:f/64'.
8591
type: string
8692
name:
8793
description: Name of the interface. Must be a valid Linux kernel

0 commit comments

Comments
 (0)
Please sign in to comment.