Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions api/v1alpha1/egressshard_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ type AddressClaimRef struct {
// +kubebuilder:validation:XValidation:rule="!(has(oldSelf.nat64Prefix) && size(oldSelf.nat64Prefix) > 0) || (has(self.nat64Prefix) && size(self.nat64Prefix) > 0)",message="nat64Prefix cannot be unassigned once assigned"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.shardAddressIPv6ClaimRef) || has(self.shardAddressIPv6ClaimRef)",message="shardAddressIPv6ClaimRef cannot be unassigned once assigned"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.shardAddressIPv4ClaimRef) || has(self.shardAddressIPv4ClaimRef)",message="shardAddressIPv4ClaimRef cannot be unassigned once assigned"
// +kubebuilder:validation:XValidation:rule="!(has(self.translateWellKnownPrefix) && self.translateWellKnownPrefix) || (has(self.nat64Prefix) && size(self.nat64Prefix) > 0)",message="translateWellKnownPrefix requires nat64Prefix"
type EgressShardSpec struct {
// TargetRef identifies the Node this shard executes on.
// +kubebuilder:validation:Required
Expand Down Expand Up @@ -283,8 +284,9 @@ type EgressShardSpec struct {
ShardAddressIPv4ClaimRef *AddressClaimRef `json:"shardAddressIPv4ClaimRef,omitempty"`

// NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard
// translates to IPv4 — one Datum-operated Network-Specific Prefix, shared
// fabric-wide, never per-tenant. It must be the prefix the resolver
// translates to IPv4 — a Datum-operated Network-Specific Prefix, shared
// fabric-wide, never per-tenant. TranslateWellKnownPrefix adds the RFC 6052
// Well-Known Prefix alongside it. It must be the prefix the resolver
// synthesizes into; a shard translating for a different one is a
// blackhole with no symptom on either side.
//
Expand All @@ -297,6 +299,20 @@ type EgressShardSpec struct {
// +kubebuilder:validation:XValidation:rule="self == '' || isCIDR(self)",message="nat64Prefix must be a valid CIDR"
// +kubebuilder:validation:XValidation:rule="self == oldSelf || oldSelf == ''",message="nat64Prefix is immutable once assigned"
NAT64Prefix string `json:"nat64Prefix,omitempty"`

// TranslateWellKnownPrefix additionally translates destinations inside the
// RFC 6052 Well-Known Prefix 64:ff9b::/96 to IPv4 from ShardAddressIPv4, so
// clients using a public DNS64 resolver reach IPv4 destinations. Requires
// NAT64Prefix.
//
// RFC 6052 §3.1 forbids the Well-Known Prefix from representing non-global
// IPv4 addresses; the implementation must refuse such destinations.
//
// Mutable, unlike NAT64Prefix. Disabling it blackholes every destination
// clients already resolved into the Well-Known Prefix until their DNS TTLs
// expire.
// +optional
TranslateWellKnownPrefix bool `json:"translateWellKnownPrefix,omitempty"`
}

// EgressShardStatus defines the observed state of an EgressShard.
Expand Down Expand Up @@ -345,6 +361,12 @@ type EgressShardStatus struct {
// +kubebuilder:validation:XValidation:rule="self == '' || isCIDR(self)",message="nat64Prefix must be a valid CIDR"
NAT64Prefix string `json:"nat64Prefix,omitempty"`

// TranslatesWellKnownPrefix reports whether this shard's datapath is
// programmed to translate the RFC 6052 Well-Known Prefix 64:ff9b::/96, from
// Spec.TranslateWellKnownPrefix. False whenever ShardAddressIPv4 is empty.
// +optional
TranslatesWellKnownPrefix bool `json:"translatesWellKnownPrefix,omitempty"`

// Conditions contains the standard conditions for this resource,
// including Programmed (see ConditionTypeProgrammed).
//
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/egressshard_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func TestEgressShardSpecFieldNames(t *testing.T) {
orig := newTestEgressShard()
orig.Spec.ShardAddressIPv4 = "198.51.100.7"
orig.Spec.NAT64Prefix = "64:ff9b::/96"
orig.Spec.TranslateWellKnownPrefix = true

data, err := json.Marshal(orig.Spec)
if err != nil {
Expand All @@ -164,6 +165,9 @@ func TestEgressShardSpecFieldNames(t *testing.T) {
t.Errorf("%s: got %v, want %q", key, raw, value)
}
}
if raw, ok := m["translateWellKnownPrefix"]; !ok || raw != true {
t.Errorf("translateWellKnownPrefix: got %v, want true", raw)
}
if _, ok := m["targetRef"]; !ok {
t.Error("expected \"targetRef\" key to be present")
}
Expand Down Expand Up @@ -205,6 +209,7 @@ func TestEgressShardSpecOmitEmpty(t *testing.T) {
for _, key := range []string{
"shardSID", "shardAddressIPv6", "shardAddressIPv4", "nat64Prefix",
"shardAddressIPv6ClaimRef", "shardAddressIPv4ClaimRef",
"translateWellKnownPrefix",
} {
if _, ok := m[key]; ok {
t.Errorf("expected %q key to be absent when empty", key)
Expand Down
28 changes: 26 additions & 2 deletions config/crd/network.datumapis.com_egressshards.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ spec:
nat64Prefix:
description: |-
NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard
translates to IPv4 — one Datum-operated Network-Specific Prefix, shared
fabric-wide, never per-tenant. It must be the prefix the resolver
translates to IPv4 — a Datum-operated Network-Specific Prefix, shared
fabric-wide, never per-tenant. TranslateWellKnownPrefix adds the RFC 6052
Well-Known Prefix alongside it. It must be the prefix the resolver
synthesizes into; a shard translating for a different one is a
blackhole with no symptom on either side.

Expand Down Expand Up @@ -300,6 +301,20 @@ spec:
- kind
- name
type: object
translateWellKnownPrefix:
description: |-
TranslateWellKnownPrefix additionally translates destinations inside the
RFC 6052 Well-Known Prefix 64:ff9b::/96 to IPv4 from ShardAddressIPv4, so
clients using a public DNS64 resolver reach IPv4 destinations. Requires
NAT64Prefix.

RFC 6052 §3.1 forbids the Well-Known Prefix from representing non-global
IPv4 addresses; the implementation must refuse such destinations.

Mutable, unlike NAT64Prefix. Disabling it blackholes every destination
clients already resolved into the Well-Known Prefix until their DNS TTLs
expire.
type: boolean
required:
- targetRef
type: object
Expand All @@ -325,6 +340,9 @@ spec:
rule: '!has(oldSelf.shardAddressIPv6ClaimRef) || has(self.shardAddressIPv6ClaimRef)'
- message: shardAddressIPv4ClaimRef cannot be unassigned once assigned
rule: '!has(oldSelf.shardAddressIPv4ClaimRef) || has(self.shardAddressIPv4ClaimRef)'
- message: translateWellKnownPrefix requires nat64Prefix
rule: '!(has(self.translateWellKnownPrefix) && self.translateWellKnownPrefix)
|| (has(self.nat64Prefix) && size(self.nat64Prefix) > 0)'
status:
description: |-
EgressShardStatus defines the observed state of an EgressShard.
Expand Down Expand Up @@ -444,6 +462,12 @@ spec:
x-kubernetes-validations:
- message: shardSID must be a valid IPv6 address
rule: self == '' || (isIP(self) && ip(self).family() == 6)
translatesWellKnownPrefix:
description: |-
TranslatesWellKnownPrefix reports whether this shard's datapath is
programmed to translate the RFC 6052 Well-Known Prefix 64:ff9b::/96, from
Spec.TranslateWellKnownPrefix. False whenever ShardAddressIPv4 is empty.
type: boolean
type: object
type: object
served: true
Expand Down
4 changes: 3 additions & 1 deletion docs/api/bgp.md
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,8 @@ _Appears in:_
| `shardAddressIPv6ClaimRef` _[AddressClaimRef](#addressclaimref)_ | ShardAddressIPv6ClaimRef records the addressing-service claim<br />ShardAddressIPv6 came from — see AddressClaimRef. Set it in the same<br />write as the address whenever that address came from a claim.<br />Nothing here resolves it and no component reads it to program anything;<br />it is the only trail from a translating address back to the allocation<br />accountable for it. | | |
| `shardAddressIPv4` _string_ | ShardAddressIPv4 is the dedicated, publicly-routable IPv4 address this<br />shard translates to, and the source an IPv4-only destination sees.<br />Unlike ShardAddressIPv6, reachability for it is not established by a<br />BGPAdvertisement into the EVPN fabric: an IPv4 reply arrives from the<br />internet, so the underlay or an upstream announcement must attract this<br />address to this node.<br />Empty means no IPv4 address is assigned to this shard. | | |
| `shardAddressIPv4ClaimRef` _[AddressClaimRef](#addressclaimref)_ | ShardAddressIPv4ClaimRef records the addressing-service claim<br />ShardAddressIPv4 came from — see AddressClaimRef. Set it in the same<br />write as the address whenever that address came from a claim.<br />Nothing here resolves it and no component reads it to program anything;<br />it is the only trail from a translating address back to the allocation<br />accountable for it. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard<br />translates to IPv4 — one Datum-operated Network-Specific Prefix, shared<br />fabric-wide, never per-tenant. It must be the prefix the resolver<br />synthesizes into; a shard translating for a different one is a<br />blackhole with no symptom on either side.<br />Set together with ShardAddressIPv4 or not at all: an address with no<br />prefix has nothing to translate for, and a prefix with no address has<br />nothing to translate into. Write-once for the same reason the addresses<br />are: a shard that starts translating a different prefix blackholes every<br />destination the resolver already synthesized into the old one. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard<br />translates to IPv4 — a Datum-operated Network-Specific Prefix, shared<br />fabric-wide, never per-tenant. TranslateWellKnownPrefix adds the RFC 6052<br />Well-Known Prefix alongside it. It must be the prefix the resolver<br />synthesizes into; a shard translating for a different one is a<br />blackhole with no symptom on either side.<br />Set together with ShardAddressIPv4 or not at all: an address with no<br />prefix has nothing to translate for, and a prefix with no address has<br />nothing to translate into. Write-once for the same reason the addresses<br />are: a shard that starts translating a different prefix blackholes every<br />destination the resolver already synthesized into the old one. | | |
| `translateWellKnownPrefix` _boolean_ | TranslateWellKnownPrefix additionally translates destinations inside the<br />RFC 6052 Well-Known Prefix 64:ff9b::/96 to IPv4 from ShardAddressIPv4, so<br />clients using a public DNS64 resolver reach IPv4 destinations. Requires<br />NAT64Prefix.<br />RFC 6052 §3.1 forbids the Well-Known Prefix from representing non-global<br />IPv4 addresses; the implementation must refuse such destinations.<br />Mutable, unlike NAT64Prefix. Disabling it blackholes every destination<br />clients already resolved into the Well-Known Prefix until their DNS TTLs<br />expire. | | |


#### EgressShardStatus
Expand All @@ -1089,6 +1090,7 @@ _Appears in:_
| `shardAddressIPv6` _string_ | ShardAddressIPv6 is the IPv6 masquerade source this shard's datapath is<br />programmed with. Empty means it translates no IPv6 flow. | | |
| `shardAddressIPv4` _string_ | ShardAddressIPv4 is the IPv4 masquerade source this shard's datapath is<br />programmed with. Empty means it performs no NAT64. Publishing it is also<br />what makes the underlay reachability prerequisite in<br />Spec.ShardAddressIPv4 checkable. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the prefix this shard's datapath is programmed to<br />translate. Empty whenever ShardAddressIPv4 is empty. | | |
| `translatesWellKnownPrefix` _boolean_ | TranslatesWellKnownPrefix reports whether this shard's datapath is<br />programmed to translate the RFC 6052 Well-Known Prefix 64:ff9b::/96, from<br />Spec.TranslateWellKnownPrefix. False whenever ShardAddressIPv4 is empty. | | |
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#condition-v1-meta) array_ | Conditions contains the standard conditions for this resource,<br />including Programmed (see ConditionTypeProgrammed). | | |


Expand Down
4 changes: 3 additions & 1 deletion docs/api/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ _Appears in:_
| `shardAddressIPv6ClaimRef` _[AddressClaimRef](#addressclaimref)_ | ShardAddressIPv6ClaimRef records the addressing-service claim<br />ShardAddressIPv6 came from — see AddressClaimRef. Set it in the same<br />write as the address whenever that address came from a claim.<br />Nothing here resolves it and no component reads it to program anything;<br />it is the only trail from a translating address back to the allocation<br />accountable for it. | | |
| `shardAddressIPv4` _string_ | ShardAddressIPv4 is the dedicated, publicly-routable IPv4 address this<br />shard translates to, and the source an IPv4-only destination sees.<br />Unlike ShardAddressIPv6, reachability for it is not established by a<br />BGPAdvertisement into the EVPN fabric: an IPv4 reply arrives from the<br />internet, so the underlay or an upstream announcement must attract this<br />address to this node.<br />Empty means no IPv4 address is assigned to this shard. | | |
| `shardAddressIPv4ClaimRef` _[AddressClaimRef](#addressclaimref)_ | ShardAddressIPv4ClaimRef records the addressing-service claim<br />ShardAddressIPv4 came from — see AddressClaimRef. Set it in the same<br />write as the address whenever that address came from a claim.<br />Nothing here resolves it and no component reads it to program anything;<br />it is the only trail from a translating address back to the allocation<br />accountable for it. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard<br />translates to IPv4 — one Datum-operated Network-Specific Prefix, shared<br />fabric-wide, never per-tenant. It must be the prefix the resolver<br />synthesizes into; a shard translating for a different one is a<br />blackhole with no symptom on either side.<br />Set together with ShardAddressIPv4 or not at all: an address with no<br />prefix has nothing to translate for, and a prefix with no address has<br />nothing to translate into. Write-once for the same reason the addresses<br />are: a shard that starts translating a different prefix blackholes every<br />destination the resolver already synthesized into the old one. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the IPv6 prefix whose synthesized addresses this shard<br />translates to IPv4 — a Datum-operated Network-Specific Prefix, shared<br />fabric-wide, never per-tenant. TranslateWellKnownPrefix adds the RFC 6052<br />Well-Known Prefix alongside it. It must be the prefix the resolver<br />synthesizes into; a shard translating for a different one is a<br />blackhole with no symptom on either side.<br />Set together with ShardAddressIPv4 or not at all: an address with no<br />prefix has nothing to translate for, and a prefix with no address has<br />nothing to translate into. Write-once for the same reason the addresses<br />are: a shard that starts translating a different prefix blackholes every<br />destination the resolver already synthesized into the old one. | | |
| `translateWellKnownPrefix` _boolean_ | TranslateWellKnownPrefix additionally translates destinations inside the<br />RFC 6052 Well-Known Prefix 64:ff9b::/96 to IPv4 from ShardAddressIPv4, so<br />clients using a public DNS64 resolver reach IPv4 destinations. Requires<br />NAT64Prefix.<br />RFC 6052 §3.1 forbids the Well-Known Prefix from representing non-global<br />IPv4 addresses; the implementation must refuse such destinations.<br />Mutable, unlike NAT64Prefix. Disabling it blackholes every destination<br />clients already resolved into the Well-Known Prefix until their DNS TTLs<br />expire. | | |


#### EgressShardStatus
Expand All @@ -190,6 +191,7 @@ _Appears in:_
| `shardAddressIPv6` _string_ | ShardAddressIPv6 is the IPv6 masquerade source this shard's datapath is<br />programmed with. Empty means it translates no IPv6 flow. | | |
| `shardAddressIPv4` _string_ | ShardAddressIPv4 is the IPv4 masquerade source this shard's datapath is<br />programmed with. Empty means it performs no NAT64. Publishing it is also<br />what makes the underlay reachability prerequisite in<br />Spec.ShardAddressIPv4 checkable. | | |
| `nat64Prefix` _string_ | NAT64Prefix is the prefix this shard's datapath is programmed to<br />translate. Empty whenever ShardAddressIPv4 is empty. | | |
| `translatesWellKnownPrefix` _boolean_ | TranslatesWellKnownPrefix reports whether this shard's datapath is<br />programmed to translate the RFC 6052 Well-Known Prefix 64:ff9b::/96, from<br />Spec.TranslateWellKnownPrefix. False whenever ShardAddressIPv4 is empty. | | |
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#condition-v1-meta) array_ | Conditions contains the standard conditions for this resource,<br />including Programmed (see ConditionTypeProgrammed). | | |


Expand Down
Loading
Loading