Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
support for ipv6
Browse files Browse the repository at this point in the history
  • Loading branch information
aroradaman committed Jan 29, 2023
1 parent 049d930 commit 1ade562
Show file tree
Hide file tree
Showing 19 changed files with 455 additions and 279 deletions.
59 changes: 47 additions & 12 deletions backends/ipvsfullstate/common.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,73 @@
package ipvsfullsate

import (
v1 "k8s.io/api/core/v1"
netutils "k8s.io/utils/net"
"sigs.k8s.io/kpng/api/localv1"
"sigs.k8s.io/kpng/backends/ipvsfullstate/internal/ipvs"
)

// getClusterIPs safely returns ClusterIPs associated with the service.
func getClusterIPs(service *localv1.Service) []string {
// getClusterIPs returns ClusterIPs for given IPFamily associated with the service.
func getClusterIPs(service *localv1.Service, ipFamily v1.IPFamily) []string {
IPs := make([]string, 0)
if service.IPs.ClusterIPs != nil {
return service.IPs.ClusterIPs.V4
if ipFamily == v1.IPv4Protocol {
return service.IPs.ClusterIPs.GetV4()
} else if ipFamily == v1.IPv6Protocol {
return service.IPs.ClusterIPs.GetV6()
}
}
return IPs
}

// getExternalIPs safely returns ExternalIPs associated with the service.
func getExternalIPs(service *localv1.Service) []string {
// getExternalIPs safely returns ExternalIPs for given IPFamily associated with the service.
func getExternalIPs(service *localv1.Service, ipFamily v1.IPFamily) []string {
IPs := make([]string, 0)
if service.IPs.ExternalIPs != nil {
return service.IPs.ExternalIPs.V4
if ipFamily == v1.IPv4Protocol {
return service.IPs.ExternalIPs.GetV4()
} else if ipFamily == v1.IPv6Protocol {
return service.IPs.ExternalIPs.GetV6()
}
}
return IPs
}

// getNodeIPs safely returns all Node IPs.
func getNodeIPs() []string {
return *NodeAddresses
// getNodeIPs safely returns all Node IPs for given IPFamily.
func getNodeIPs(ipFamily v1.IPFamily) []string {
IPs := make([]string, 0)
for _, ip := range *NodeAddresses {
if ipFamily == v1.IPv4Protocol && netutils.IsIPv4String(ip) {
IPs = append(IPs, ip)
} else if ipFamily == v1.IPv6Protocol && netutils.IsIPv6String(ip) {
IPs = append(IPs, ip)
}
}
return IPs
}

// getLoadBalancerIPs safely returns LoadBalancerIPs associated with the service.
func getLoadBalancerIPs(service *localv1.Service) []string {
// getLoadBalancerIPs safely returns LoadBalancerIPs for given IPFamily associated with the service.
func getLoadBalancerIPs(service *localv1.Service, ipFamily v1.IPFamily) []string {
IPs := make([]string, 0)
if service.IPs.LoadBalancerIPs != nil {
return service.IPs.LoadBalancerIPs.V4
if ipFamily == v1.IPv4Protocol {
return service.IPs.LoadBalancerIPs.GetV4()
} else if ipFamily == v1.IPv6Protocol {
return service.IPs.LoadBalancerIPs.GetV6()
}
}
return IPs
}

// getEndpointIPs returns EndpointIPs for given IPFamily associated with the endpoint.
func getEndpointIPs(endpoint *localv1.Endpoint, ipFamily v1.IPFamily) []string {
IPs := make([]string, 0)
if endpoint.IPs != nil {
if ipFamily == v1.IPv4Protocol {
return endpoint.IPs.GetV4()
} else if ipFamily == v1.IPv6Protocol {
return endpoint.IPs.GetV6()
}
}
return IPs
}
Expand Down
5 changes: 0 additions & 5 deletions backends/ipvsfullstate/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ func interfaceAddresses() []string {
panic(err)
}

// only IPv4 for now
if ipv4 := ip.To4(); ipv4 == nil {
continue
}

addresses = append(addresses, ip.String())
}
return addresses
Expand Down
111 changes: 58 additions & 53 deletions backends/ipvsfullstate/handle_clusterip_service.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ipvsfullsate

import (
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/kpng/backends/ipvsfullstate/internal/ipsets"
"sigs.k8s.io/kpng/client"
)
Expand All @@ -17,77 +18,81 @@ func (c *Controller) addServiceEndpointsForClusterIP(serviceEndpoints *client.Se
// iterate over service ports
for _, portMapping := range service.Ports {

// iterate over ClusterIPs
for _, clusterIP := range getClusterIPs(service) {
// iterate over ipFamily
for _, ipFamily := range []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol} {

// STEP 1. create virtual server for Cluster IP
server := newVirtualServerForClusterIP(clusterIP, service, portMapping)
c.ipvsManager.ApplyServer(server)
// iterate over ClusterIPs
for _, clusterIP := range getClusterIPs(service, ipFamily) {

// STEP 2. add entry for ClusterIP To kubeClusterIPSet
entry = newEntryForClusterIP(clusterIP, portMapping)
set = c.ipsetsManager.GetSetByName(kubeClusterIPSet)
c.ipsetsManager.AddEntry(entry, set)
// STEP 1. create virtual server for Cluster IP
server := newVirtualServerForClusterIP(clusterIP, service, portMapping)
c.ipvsManager.ApplyServer(server)

// STEP 3. bind the ClusterIP to Host Interface
c.ipvsManager.BindServerToInterface(server)
// STEP 2. add entry for ClusterIP To kubeClusterIPSet
entry = newEntryForClusterIP(clusterIP, portMapping)
set = c.ipsetsManager.GetSetByName(kubeClusterIPSet[ipFamily])
c.ipsetsManager.AddEntry(entry, set)

// STEP 3. bind the ClusterIP to Host Interface
c.ipvsManager.BindServerToInterface(server)

// iterate over service endpoint
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range endpoint.IPs.V4 {
// iterate over service endpoint
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range getEndpointIPs(endpoint, ipFamily) {

// STEP 4. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)
// STEP 4. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)

if endpoint.GetLocal() {
// STEP 5. Add entry for EndpointIP to kubeLoopBackIPSet if endpoint is local
entry = newEntryForLocalEndpoint(endpointIp, endpoint, portMapping)
set = c.ipsetsManager.GetSetByName(kubeLoopBackIPSet)
c.ipsetsManager.AddEntry(entry, set)
if endpoint.GetLocal() {
// STEP 5. Add entry for EndpointIP to kubeLoopBackIPSet if endpoint is local
entry = newEntryForLocalEndpoint(endpointIp, endpoint, portMapping)
set = c.ipsetsManager.GetSetByName(kubeLoopBackIPSet[ipFamily])
c.ipsetsManager.AddEntry(entry, set)
}
}
}
}
}

// iterate over ExternalIPs
for _, externalIP := range getExternalIPs(service) {

// STEP 6. create virtual server for ExternalIP
server := newVirtualServerForExternalIP(externalIP, service, portMapping)
c.ipvsManager.ApplyServer(server)
// iterate over ExternalIPs
for _, externalIP := range getExternalIPs(service, ipFamily) {

// create entry for ExternalIP
entry = newEntryForExternalIP(externalIP, portMapping)
// STEP 6. create virtual server for ExternalIP
server := newVirtualServerForExternalIP(externalIP, service, portMapping)
c.ipvsManager.ApplyServer(server)

// STEP 7. add entry for ExternalIP to kubeExternalIPSet
set = c.ipsetsManager.GetSetByName(kubeExternalIPSet)
c.ipsetsManager.AddEntry(entry, set)
// create entry for ExternalIP
entry = newEntryForExternalIP(externalIP, portMapping)

// STEP 8. add entry for ExternalIP to kubeExternalIPLocalSet if external traffic policy is local
if service.GetExternalTrafficToLocal() {
set = c.ipsetsManager.GetSetByName(kubeExternalIPLocalSet)
// STEP 7. add entry for ExternalIP to kubeExternalIPSet
set = c.ipsetsManager.GetSetByName(kubeExternalIPSet[ipFamily])
c.ipsetsManager.AddEntry(entry, set)
}

// STEP 9. bind the ExternalIP to Host Interface
c.ipvsManager.BindServerToInterface(server)
// STEP 8. add entry for ExternalIP to kubeExternalIPLocalSet if external traffic policy is local
if service.GetExternalTrafficToLocal() {
set = c.ipsetsManager.GetSetByName(kubeExternalIPLocalIPSet[ipFamily])
c.ipsetsManager.AddEntry(entry, set)
}

// STEP 9. bind the ExternalIP to Host Interface
c.ipvsManager.BindServerToInterface(server)

// iterate over service endpoints
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range endpoint.IPs.V4 {
// iterate over service endpoints
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range getEndpointIPs(endpoint, ipFamily) {

// STEP 10. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)
// STEP 10. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)

if endpoint.GetLocal() {
// STEP 11. Add entry for EndpointIP to kubeLoopBackIPSet if endpoint is local
entry = newEntryForLocalEndpoint(endpointIp, endpoint, portMapping)
set = c.ipsetsManager.GetSetByName(kubeLoopBackIPSet)
c.ipsetsManager.AddEntry(entry, set)
if endpoint.GetLocal() {
// STEP 11. Add entry for EndpointIP to kubeLoopBackIPSet if endpoint is local
entry = newEntryForLocalEndpoint(endpointIp, endpoint, portMapping)
set = c.ipsetsManager.GetSetByName(kubeLoopBackIPSet[ipFamily])
c.ipsetsManager.AddEntry(entry, set)
}
}
}
}
Expand Down
73 changes: 39 additions & 34 deletions backends/ipvsfullstate/handle_loadbalancer_service.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ipvsfullsate

import (
v1 "k8s.io/api/core/v1"
ipsets2 "sigs.k8s.io/kpng/backends/ipvsfullstate/internal/ipsets"
"sigs.k8s.io/kpng/client"
)
Expand All @@ -22,50 +23,54 @@ func (c *Controller) addServiceEndpointsForLoadBalancer(serviceEndpoints *client
// iterate over service ports
for _, portMapping := range service.Ports {

// iterate over LoadBalancerIPs
for _, loadBalancerIP := range getLoadBalancerIPs(service) {
// iterate over ipFamily
for _, ipFamily := range []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol} {

// STEP 2. create virtual server for LoadBalancerIP
server := newVirtualServerForLoadBalancer(loadBalancerIP, service, portMapping)
c.ipvsManager.ApplyServer(server)
// iterate over LoadBalancerIPs
for _, loadBalancerIP := range getLoadBalancerIPs(service, ipFamily) {

// STEP 3. add entry for LoadBalancerIP to kubeLoadBalancerSet
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerSet)
entry = newEntryForLoadBalancer(loadBalancerIP, portMapping)
c.ipsetsManager.AddEntry(entry, set)
// STEP 2. create virtual server for LoadBalancerIP
server := newVirtualServerForLoadBalancer(loadBalancerIP, service, portMapping)
c.ipvsManager.ApplyServer(server)

// STEP 4. add entry for LoadBalancerIP to kubeLoadBalancerLocalSet,
// if external traffic policy is local
if service.GetExternalTrafficToLocal() {
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerLocalSet)
// STEP 3. add entry for LoadBalancerIP to kubeLoadBalancerIPSet
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerIPSet[ipFamily])
entry = newEntryForLoadBalancer(loadBalancerIP, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}

// STEP 5. add entry for LoadBalancerIP and SourceRanges to kubeLoadBalancerSourceCIDRSet
for _, sourceRange := range getSourceRangesForLoadBalancer(service) {
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerSourceCIDRSet)
entry = newEntryForLoadBalancerSourceRange(loadBalancerIP, sourceRange, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}
// STEP 4. add entry for LoadBalancerIP to kubeLoadBalancerLocalIPSet,
// if external traffic policy is local
if service.GetExternalTrafficToLocal() {
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerLocalIPSet[ipFamily])
entry = newEntryForLoadBalancer(loadBalancerIP, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}

// STEP 6. add entry for LoadBalancerIP to kubeLoadbalancerFWSet, if source ranges is configured
if len(getSourceRangesForLoadBalancer(service)) > 0 {
set = c.ipsetsManager.GetSetByName(kubeLoadbalancerFWSet)
entry = newEntryForLoadBalancer(loadBalancerIP, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}
// STEP 5. add entry for LoadBalancerIP and SourceRanges to kubeLoadBalancerSourceCIDRIPSet
for _, sourceRange := range getSourceRangesForLoadBalancer(service) {
set = c.ipsetsManager.GetSetByName(kubeLoadBalancerSourceCIDRIPSet[ipFamily])
entry = newEntryForLoadBalancerSourceRange(loadBalancerIP, sourceRange, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}

// STEP 6. add entry for LoadBalancerIP to kubeLoadbalancerFWIPSet, if source ranges is configured
if len(getSourceRangesForLoadBalancer(service)) > 0 {
set = c.ipsetsManager.GetSetByName(kubeLoadbalancerFWIPSet[ipFamily])
entry = newEntryForLoadBalancer(loadBalancerIP, portMapping)
c.ipsetsManager.AddEntry(entry, set)
}

// TODO entries to kubeLoadBalancerSourceIPSet; take reference from upstream ipvs proxier
// TODO entries to kubeLoadBalancerSourceIPSet; take reference from upstream ipvs proxier

// iterate over service endpoints
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range endpoint.IPs.V4 {
// STEP 7. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)
// iterate over service endpoints
for _, endpoint := range endpoints {
// iterate over EndpointIPs
for _, endpointIp := range getEndpointIPs(endpoint, ipFamily) {
// STEP 7. add endpoint as a destination to virtual server
destination := newIpvsDestination(endpointIp, endpoint, portMapping)
c.ipvsManager.AddDestination(destination, server)

}
}
}
}
Expand Down
Loading

0 comments on commit 1ade562

Please sign in to comment.