diff --git a/apinetlet/controllers/networkpolicy_controller.go b/apinetlet/controllers/networkpolicy_controller.go index 885c9894..440adba8 100644 --- a/apinetlet/controllers/networkpolicy_controller.go +++ b/apinetlet/controllers/networkpolicy_controller.go @@ -333,7 +333,6 @@ func (r *NetworkPolicyReconciler) fetchIPsFromNetworkInterfaces(ctx context.Cont if ip.Addr.Is6() { ipFamily = corev1.IPv6Protocol } - ip.Addr.Is4() ips = append(ips, apinetv1alpha1.ObjectIP{ Prefix: net.IPPrefix{Prefix: netip.PrefixFrom(ip.Addr, ip.Addr.BitLen())}, IPFamily: ipFamily, diff --git a/go.sum b/go.sum index 5c637255..665d9dfc 100644 --- a/go.sum +++ b/go.sum @@ -135,8 +135,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= diff --git a/metalnetlet/controllers/networkinterface_controller.go b/metalnetlet/controllers/networkinterface_controller.go index e18b8bc3..b0902566 100644 --- a/metalnetlet/controllers/networkinterface_controller.go +++ b/metalnetlet/controllers/networkinterface_controller.go @@ -14,9 +14,11 @@ import ( "github.com/ironcore-dev/ironcore-net/apimachinery/api/net" metalnetletclient "github.com/ironcore-dev/ironcore-net/metalnetlet/client" utilhandler "github.com/ironcore-dev/ironcore-net/metalnetlet/handler" + netiputils "github.com/ironcore-dev/ironcore-net/utils/netip" "github.com/ironcore-dev/ironcore/utils/generic" utilslices "github.com/ironcore-dev/ironcore/utils/slices" metalnetv1alpha1 "github.com/ironcore-dev/metalnet/api/v1alpha1" + "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -212,53 +214,52 @@ func extractFirewallRulesFromRule(rule v1alpha1.Rule, direction metalnetv1alpha1 var firewallRules []metalnetv1alpha1.FirewallRule for _, port := range rule.NetworkPolicyPorts { - firewallRule := metalnetv1alpha1.FirewallRule{ - FirewallRuleID: types.UID(uuid.New().String()), - Direction: direction, - Action: metalnetv1alpha1.FirewallRuleActionAccept, - Priority: priority, - IpFamily: corev1.IPv4Protocol, //TODO: later support for IPv6 - ProtocolMatch: &metalnetv1alpha1.ProtocolMatch{}, + baseFirewallRule := metalnetv1alpha1.FirewallRule{ + Direction: direction, + Action: metalnetv1alpha1.FirewallRuleActionAccept, + Priority: priority, + ProtocolMatch: &metalnetv1alpha1.ProtocolMatch{}, } switch *port.Protocol { case corev1.ProtocolTCP: - firewallRule.ProtocolMatch.ProtocolType = generic.Pointer(metalnetv1alpha1.FirewallRuleProtocolTypeTCP) + baseFirewallRule.ProtocolMatch.ProtocolType = generic.Pointer(metalnetv1alpha1.FirewallRuleProtocolTypeTCP) case corev1.ProtocolUDP: - firewallRule.ProtocolMatch.ProtocolType = generic.Pointer(metalnetv1alpha1.FirewallRuleProtocolTypeUDP) + baseFirewallRule.ProtocolMatch.ProtocolType = generic.Pointer(metalnetv1alpha1.FirewallRuleProtocolTypeUDP) //TODO: no support for SCTP protocol in metalnetlet and metalnetlet FirewallRuleProtocolTypeICMP is not defined in ironcore } if port.Port != 0 { if direction == metalnetv1alpha1.FirewallRuleDirectionIngress { - firewallRule.ProtocolMatch.PortRange = &metalnetv1alpha1.PortMatch{SrcPort: &port.Port} + baseFirewallRule.ProtocolMatch.PortRange = &metalnetv1alpha1.PortMatch{SrcPort: &port.Port} } else { - firewallRule.ProtocolMatch.PortRange = &metalnetv1alpha1.PortMatch{DstPort: &port.Port} + baseFirewallRule.ProtocolMatch.PortRange = &metalnetv1alpha1.PortMatch{DstPort: &port.Port} } if port.EndPort != nil { if direction == metalnetv1alpha1.FirewallRuleDirectionIngress { - firewallRule.ProtocolMatch.PortRange.EndSrcPort = *port.EndPort + baseFirewallRule.ProtocolMatch.PortRange.EndSrcPort = *port.EndPort } else { - firewallRule.ProtocolMatch.PortRange.EndDstPort = *port.EndPort + baseFirewallRule.ProtocolMatch.PortRange.EndDstPort = *port.EndPort } } } for _, cidrBlock := range rule.CIDRBlock { - cidrFirewallRule := firewallRule - cidrFirewallRule.FirewallRuleID = types.UID(uuid.New().String()) + firewallRule := baseFirewallRule + firewallRule.FirewallRuleID = types.UID(uuid.New().String()) + firewallRule.IpFamily = netiputils.GetIPFamilyFromPrefix(cidrBlock.CIDR) if direction == metalnetv1alpha1.FirewallRuleDirectionIngress { - cidrFirewallRule.SourcePrefix = &metalnetv1alpha1.IPPrefix{Prefix: cidrBlock.CIDR.Prefix} + firewallRule.SourcePrefix = &metalnetv1alpha1.IPPrefix{Prefix: cidrBlock.CIDR.Prefix} } else { - cidrFirewallRule.DestinationPrefix = &metalnetv1alpha1.IPPrefix{Prefix: cidrBlock.CIDR.Prefix} + firewallRule.DestinationPrefix = &metalnetv1alpha1.IPPrefix{Prefix: cidrBlock.CIDR.Prefix} } - firewallRules = append(firewallRules, cidrFirewallRule) + firewallRules = append(firewallRules, firewallRule) if len(cidrBlock.Except) > 0 { for _, exceptCIDR := range cidrBlock.Except { - exceptFirewallRule := cidrFirewallRule + exceptFirewallRule := firewallRule exceptFirewallRule.FirewallRuleID = types.UID(uuid.New().String()) exceptFirewallRule.Action = metalnetv1alpha1.FirewallRuleActionDeny @@ -274,16 +275,17 @@ func extractFirewallRulesFromRule(rule v1alpha1.Rule, direction metalnetv1alpha1 } for _, objectIP := range rule.ObjectIPs { - objectIPFirewallRule := firewallRule - objectIPFirewallRule.FirewallRuleID = types.UID(uuid.New().String()) + firewallRule := baseFirewallRule + firewallRule.FirewallRuleID = types.UID(uuid.New().String()) + firewallRule.IpFamily = netiputils.GetIPFamilyFromPrefix(objectIP.Prefix) if direction == metalnetv1alpha1.FirewallRuleDirectionIngress { - objectIPFirewallRule.SourcePrefix = &metalnetv1alpha1.IPPrefix{Prefix: objectIP.Prefix.Prefix} + firewallRule.SourcePrefix = &metalnetv1alpha1.IPPrefix{Prefix: objectIP.Prefix.Prefix} } else { - objectIPFirewallRule.DestinationPrefix = &metalnetv1alpha1.IPPrefix{Prefix: objectIP.Prefix.Prefix} + firewallRule.DestinationPrefix = &metalnetv1alpha1.IPPrefix{Prefix: objectIP.Prefix.Prefix} } - firewallRules = append(firewallRules, objectIPFirewallRule) + firewallRules = append(firewallRules, firewallRule) } } diff --git a/metalnetlet/controllers/networkinterface_controller_test.go b/metalnetlet/controllers/networkinterface_controller_test.go index 1219b256..696419ed 100644 --- a/metalnetlet/controllers/networkinterface_controller_test.go +++ b/metalnetlet/controllers/networkinterface_controller_test.go @@ -120,6 +120,12 @@ var _ = Describe("NetworkInterfaceController", func() { {Prefix: netip.MustParsePrefix("192.168.2.100/32")}, }, }, + { + CIDR: net.IPPrefix{Prefix: netip.MustParsePrefix("2001:db8::/64")}, + Except: []net.IPPrefix{ + {Prefix: netip.MustParsePrefix("2001:db8::1234/128")}, + }, + }, }, ObjectIPs: []v1alpha1.ObjectIP{ { @@ -146,6 +152,9 @@ var _ = Describe("NetworkInterfaceController", func() { { Prefix: net.IPPrefix{Prefix: netip.MustParsePrefix("192.168.178.60/32")}, }, + { + Prefix: net.IPPrefix{Prefix: netip.MustParsePrefix("2001:db8:5678:abcd::60/128")}, + }, }, NetworkPolicyPorts: []v1alpha1.NetworkPolicyPort{ { @@ -225,6 +234,46 @@ var _ = Describe("NetworkInterfaceController", func() { })), })), }), + MatchFields(IgnoreExtras, Fields{ + "FirewallRuleID": Not(BeEmpty()), + "Direction": Equal(metalnetv1alpha1.FirewallRuleDirectionIngress), + "Action": Equal(metalnetv1alpha1.FirewallRuleActionAccept), + "Priority": PointTo(Equal(int32(3000))), + "IpFamily": Equal(corev1.IPv6Protocol), + "SourcePrefix": PointTo(MatchFields(IgnoreExtras, Fields{ + "Prefix": Equal(netip.MustParsePrefix("2001:db8::/64")), + })), + "DestinationPrefix": BeNil(), + "ProtocolMatch": PointTo(MatchFields(IgnoreExtras, Fields{ + "ProtocolType": PointTo(Equal(metalnetv1alpha1.FirewallRuleProtocolTypeTCP)), + "PortRange": PointTo(MatchFields(IgnoreExtras, Fields{ + "SrcPort": PointTo(Equal(int32(8080))), + "EndSrcPort": Equal(int32(8090)), + "DstPort": BeNil(), + "EndDstPort": BeEquivalentTo(0), + })), + })), + }), + MatchFields(IgnoreExtras, Fields{ + "FirewallRuleID": Not(BeEmpty()), + "Direction": Equal(metalnetv1alpha1.FirewallRuleDirectionIngress), + "Action": Equal(metalnetv1alpha1.FirewallRuleActionDeny), + "Priority": PointTo(Equal(int32(3000))), + "IpFamily": Equal(corev1.IPv6Protocol), + "SourcePrefix": PointTo(MatchFields(IgnoreExtras, Fields{ + "Prefix": Equal(netip.MustParsePrefix("2001:db8::1234/128")), + })), + "DestinationPrefix": BeNil(), + "ProtocolMatch": PointTo(MatchFields(IgnoreExtras, Fields{ + "ProtocolType": PointTo(Equal(metalnetv1alpha1.FirewallRuleProtocolTypeTCP)), + "PortRange": PointTo(MatchFields(IgnoreExtras, Fields{ + "SrcPort": PointTo(Equal(int32(8080))), + "EndSrcPort": Equal(int32(8090)), + "DstPort": BeNil(), + "EndDstPort": BeEquivalentTo(0), + })), + })), + }), MatchFields(IgnoreExtras, Fields{ "FirewallRuleID": Not(BeEmpty()), "Direction": Equal(metalnetv1alpha1.FirewallRuleDirectionIngress), @@ -325,6 +374,46 @@ var _ = Describe("NetworkInterfaceController", func() { })), })), }), + MatchFields(IgnoreExtras, Fields{ + "FirewallRuleID": Not(BeEmpty()), + "Direction": Equal(metalnetv1alpha1.FirewallRuleDirectionEgress), + "Action": Equal(metalnetv1alpha1.FirewallRuleActionAccept), + "Priority": PointTo(Equal(int32(3000))), + "IpFamily": Equal(corev1.IPv6Protocol), + "SourcePrefix": BeNil(), + "DestinationPrefix": PointTo(MatchFields(IgnoreExtras, Fields{ + "Prefix": Equal(netip.MustParsePrefix("2001:db8:5678:abcd::60/128")), + })), + "ProtocolMatch": PointTo(MatchFields(IgnoreExtras, Fields{ + "ProtocolType": PointTo(Equal(metalnetv1alpha1.FirewallRuleProtocolTypeTCP)), + "PortRange": PointTo(MatchFields(IgnoreExtras, Fields{ + "SrcPort": BeNil(), + "EndSrcPort": BeEquivalentTo(0), + "DstPort": PointTo(Equal(int32(8095))), + "EndDstPort": BeEquivalentTo(0), + })), + })), + }), + MatchFields(IgnoreExtras, Fields{ + "FirewallRuleID": Not(BeEmpty()), + "Direction": Equal(metalnetv1alpha1.FirewallRuleDirectionEgress), + "Action": Equal(metalnetv1alpha1.FirewallRuleActionAccept), + "Priority": PointTo(Equal(int32(3000))), + "IpFamily": Equal(corev1.IPv6Protocol), + "SourcePrefix": BeNil(), + "DestinationPrefix": PointTo(MatchFields(IgnoreExtras, Fields{ + "Prefix": Equal(netip.MustParsePrefix("2001:db8:5678:abcd::60/128")), + })), + "ProtocolMatch": PointTo(MatchFields(IgnoreExtras, Fields{ + "ProtocolType": PointTo(Equal(metalnetv1alpha1.FirewallRuleProtocolTypeTCP)), + "PortRange": PointTo(MatchFields(IgnoreExtras, Fields{ + "SrcPort": BeNil(), + "EndSrcPort": BeEquivalentTo(0), + "DstPort": PointTo(Equal(int32(9000))), + "EndDstPort": Equal(int32(9010)), + })), + })), + }), )), )) diff --git a/utils/netip/netip.go b/utils/netip/netip.go index 95ab38aa..8cdf070f 100644 --- a/utils/netip/netip.go +++ b/utils/netip/netip.go @@ -8,6 +8,9 @@ import ( "math" "math/big" "net/netip" + + "github.com/ironcore-dev/ironcore-net/apimachinery/api/net" + corev1 "k8s.io/api/core/v1" ) func PrefixSize(p netip.Prefix) int64 { @@ -31,3 +34,10 @@ func AddOffsetAddress(address netip.Addr, offset uint64) (netip.Addr, error) { } return addr, nil } + +func GetIPFamilyFromPrefix(ipPrefix net.IPPrefix) corev1.IPFamily { + if ipPrefix.Addr().Is6() { + return corev1.IPv6Protocol + } + return corev1.IPv4Protocol +}