Skip to content

Commit

Permalink
Support NetPol for user defined networks
Browse files Browse the repository at this point in the history
This commit provides Network Policy support for user defined l3
or l2 networks when it is configured as the primary network for
namespace. It's done by subscribing to NetPol events from secondary
network controllers and handling it appropriately in base network
and policy controllers.

Signed-off-by: Periyasamy Palanisamy <[email protected]>
  • Loading branch information
pperiyasamy committed Sep 19, 2024
1 parent 8017e9a commit 87ce669
Show file tree
Hide file tree
Showing 15 changed files with 605 additions and 149 deletions.
16 changes: 16 additions & 0 deletions go-controller/pkg/ovn/base_event_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ func (h *baseNetworkControllerEventHandler) isObjectInTerminalState(objType refl

func (h *baseNetworkControllerEventHandler) recordAddEvent(objType reflect.Type, obj interface{}) {
switch objType {
case factory.PolicyType:
np := obj.(*knet.NetworkPolicy)
klog.V(5).Infof("Recording add event on network policy %s/%s", np.Namespace, np.Name)
metrics.GetConfigDurationRecorder().Start("networkpolicy", np.Namespace, np.Name)
case factory.MultiNetworkPolicyType:
mnp := obj.(*mnpapi.MultiNetworkPolicy)
klog.V(5).Infof("Recording add event on multinetwork policy %s/%s", mnp.Namespace, mnp.Name)
Expand All @@ -223,6 +227,10 @@ func (h *baseNetworkControllerEventHandler) recordAddEvent(objType reflect.Type,
// RecordUpdateEvent records the udpate event on this given object.
func (h *baseNetworkControllerEventHandler) recordUpdateEvent(objType reflect.Type, obj interface{}) {
switch objType {
case factory.PolicyType:
np := obj.(*knet.NetworkPolicy)
klog.V(5).Infof("Recording update event on network policy %s/%s", np.Namespace, np.Name)
metrics.GetConfigDurationRecorder().Start("networkpolicy", np.Namespace, np.Name)
case factory.MultiNetworkPolicyType:
mnp := obj.(*mnpapi.MultiNetworkPolicy)
klog.V(5).Infof("Recording update event on multinetwork policy %s/%s", mnp.Namespace, mnp.Name)
Expand All @@ -233,6 +241,10 @@ func (h *baseNetworkControllerEventHandler) recordUpdateEvent(objType reflect.Ty
// RecordDeleteEvent records the delete event on this given object.
func (h *baseNetworkControllerEventHandler) recordDeleteEvent(objType reflect.Type, obj interface{}) {
switch objType {
case factory.PolicyType:
np := obj.(*knet.NetworkPolicy)
klog.V(5).Infof("Recording delete event on network policy %s/%s", np.Namespace, np.Name)
metrics.GetConfigDurationRecorder().Start("networkpolicy", np.Namespace, np.Name)
case factory.MultiNetworkPolicyType:
mnp := obj.(*mnpapi.MultiNetworkPolicy)
klog.V(5).Infof("Recording delete event on multinetwork policy %s/%s", mnp.Namespace, mnp.Name)
Expand All @@ -243,6 +255,10 @@ func (h *baseNetworkControllerEventHandler) recordDeleteEvent(objType reflect.Ty
// RecordSuccessEvent records the success event on this given object.
func (h *baseNetworkControllerEventHandler) recordSuccessEvent(objType reflect.Type, obj interface{}) {
switch objType {
case factory.PolicyType:
np := obj.(*knet.NetworkPolicy)
klog.V(5).Infof("Recording success event on network policy %s/%s", np.Namespace, np.Name)
metrics.GetConfigDurationRecorder().End("networkpolicy", np.Namespace, np.Name)
case factory.MultiNetworkPolicyType:
mnp := obj.(*mnpapi.MultiNetworkPolicy)
klog.V(5).Infof("Recording success event on multinetwork policy %s/%s", mnp.Namespace, mnp.Name)
Expand Down
41 changes: 40 additions & 1 deletion go-controller/pkg/ovn/base_network_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ovn
import (
"fmt"
"net"
"reflect"
"sync"
"time"

Expand All @@ -29,6 +30,7 @@ import (
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"

kapi "k8s.io/api/core/v1"
knet "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -91,6 +93,8 @@ type BaseNetworkController struct {
retryNamespaces *ovnretry.RetryFramework
// retry framework for network policies
retryNetworkPolicies *ovnretry.RetryFramework
// retry framework for network policies
retryMultiNetworkPolicies *ovnretry.RetryFramework
// retry framework for IPAMClaims
retryIPAMClaims *ovnretry.RetryFramework

Expand Down Expand Up @@ -179,8 +183,10 @@ type BaseSecondaryNetworkController struct {

networkID *int

// network policy events factory handler
netPolicyHandler *factory.Handler
// multi-network policy events factory handler
policyHandler *factory.Handler
multiNetPolicyHandler *factory.Handler
}

func getNetworkControllerName(netName string) string {
Expand Down Expand Up @@ -929,6 +935,39 @@ func (bnc *BaseNetworkController) findMigratablePodIPsForSubnets(subnets []*net.
return ipList, nil
}

func (bnc *BaseNetworkController) AddResourceCommon(objType reflect.Type, obj interface{}) error {
switch objType {
case factory.PolicyType:
np, ok := obj.(*knet.NetworkPolicy)
if !ok {
return fmt.Errorf("could not cast %T object to *knet.NetworkPolicy", obj)
}

if err := bnc.addNetworkPolicy(np); err != nil {
klog.Infof("Network Policy add failed for %s/%s, will try again later: %v",
np.Namespace, np.Name, err)
return err
}
default:
klog.Errorf("Can not process add resource event, object type %s is not supported", objType)
}
return nil
}

func (bnc *BaseNetworkController) DeleteResourceCommon(objType reflect.Type, obj interface{}) error {
switch objType {
case factory.PolicyType:
knp, ok := obj.(*knet.NetworkPolicy)
if !ok {
return fmt.Errorf("could not cast obj of type %T to *knet.NetworkPolicy", obj)
}
return bnc.deleteNetworkPolicy(knp)
default:
klog.Errorf("Can not process delete resource event, object type %s is not supported", objType)
}
return nil
}

func initLoadBalancerGroups(nbClient libovsdbclient.Client, netInfo util.NetInfo) (
clusterLoadBalancerGroupUUID, switchLoadBalancerGroupUUID, routerLoadBalancerGroupUUID string, err error) {

Expand Down
17 changes: 11 additions & 6 deletions go-controller/pkg/ovn/base_network_controller_namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,27 @@ func getNamespaceAddrSetDbIDs(namespaceName, controller string) *libovsdbops.DbO
// WatchNamespaces starts the watching of namespace resource and calls
// back the appropriate handler logic
func (bnc *BaseNetworkController) WatchNamespaces() error {
if bnc.IsSecondary() {
if bnc.IsPrimaryNetwork() && !util.IsNetworkSegmentationSupportEnabled() {
// For primary user defined networks, we don't have to watch namespace events if
// network segmentation support is not enabled.
return nil
}

if bnc.IsSecondary() && !util.IsMultiNetworkPoliciesSupportEnabled() {
// For secondary networks, we don't have to watch namespace events if
// multi-network policy support is not enabled.
if !util.IsMultiNetworkPoliciesSupportEnabled() {
return nil
}
return nil
}

if bnc.namespaceHandler != nil {
return nil
}

handler, err := bnc.retryNamespaces.WatchResource()
if err == nil {
bnc.namespaceHandler = handler
if err != nil {
return err
}
bnc.namespaceHandler = handler
return err
}

Expand Down
85 changes: 83 additions & 2 deletions go-controller/pkg/ovn/base_network_controller_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,84 @@ func NewNetworkPolicy(policy *knet.NetworkPolicy) *networkPolicy {
return np
}

func (bnc *BaseNetworkController) syncNetworkPolicies(networkPolicies []interface{}) error {
expectedPolicies := make(map[string]map[string]bool)
for _, npInterface := range networkPolicies {
policy, ok := npInterface.(*knet.NetworkPolicy)
if !ok {
return fmt.Errorf("spurious object in syncNetworkPolicies: %v", npInterface)
}
if nsMap, ok := expectedPolicies[policy.Namespace]; ok {
nsMap[policy.Name] = true
} else {
expectedPolicies[policy.Namespace] = map[string]bool{
policy.Name: true,
}
}
}
err := bnc.syncNetworkPoliciesCommon(expectedPolicies)
if err != nil {
return err
}

// FIXME: For primary user defined networks, we need the hairpin allow ACL.
// The port group is not found error is thrown at line 269. Is that expected ?
// (or) should this be fixed https://github.com/ovn-org/ovn-kubernetes/blob/master/go-controller/pkg/ovn/base_network_controller.go#L632 ?
if bnc.NetInfo.IsSecondary() {
return nil
}

// add default hairpin allow acl
err = bnc.addHairpinAllowACL()
if err != nil {
return fmt.Errorf("failed to create allow hairpin acl: %w", err)
}

return nil
}

func (bnc *BaseNetworkController) addHairpinAllowACL() error {
var v4Match, v6Match, match string

if config.IPv4Mode {
v4Match = fmt.Sprintf("%s.src == %s", "ip4", config.Gateway.MasqueradeIPs.V4OVNServiceHairpinMasqueradeIP.String())
match = v4Match
}
if config.IPv6Mode {
v6Match = fmt.Sprintf("%s.src == %s", "ip6", config.Gateway.MasqueradeIPs.V6OVNServiceHairpinMasqueradeIP.String())
match = v6Match
}
if config.IPv4Mode && config.IPv6Mode {
match = fmt.Sprintf("(%s || %s)", v4Match, v6Match)
}

ingressACLIDs := bnc.getNetpolDefaultACLDbIDs(string(knet.PolicyTypeIngress))
ingressACL := libovsdbutil.BuildACL(ingressACLIDs, types.DefaultAllowPriority, match,
nbdb.ACLActionAllowRelated, nil, libovsdbutil.LportIngress)

egressACLIDs := bnc.getNetpolDefaultACLDbIDs(string(knet.PolicyTypeEgress))
egressACL := libovsdbutil.BuildACL(egressACLIDs, types.DefaultAllowPriority, match,
nbdb.ACLActionAllowRelated, nil, libovsdbutil.LportEgressAfterLB)

ops, err := libovsdbops.CreateOrUpdateACLsOps(bnc.nbClient, nil, nil, ingressACL, egressACL)
if err != nil {
return fmt.Errorf("failed to create or update hairpin allow ACL %v", err)
}

ops, err = libovsdbops.AddACLsToPortGroupOps(bnc.nbClient, ops, bnc.getClusterPortGroupName(types.ClusterPortGroupNameBase),
ingressACL, egressACL)
if err != nil {
return fmt.Errorf("failed to add ACL hairpin allow acl to port group: %v", err)
}

_, err = libovsdbops.TransactAndCheck(bnc.nbClient, ops)
if err != nil {
return err
}

return nil
}

// syncNetworkPoliciesCommon syncs logical entities associated with existing network policies.
// It serves both networkpolicies (for default network) and multi-networkpolicies (for secondary networks)
func (bnc *BaseNetworkController) syncNetworkPoliciesCommon(expectedPolicies map[string]map[string]bool) error {
Expand Down Expand Up @@ -560,7 +638,7 @@ func (bnc *BaseNetworkController) getNewLocalPolicyPorts(np *networkPolicy,

// getExistingLocalPolicyPorts will find and return port info for every given pod obj, that is present in np.localPods.
func (bnc *BaseNetworkController) getExistingLocalPolicyPorts(np *networkPolicy,
objs ...interface{}) (policyPortsToUUIDs map[string]string, policyPortUUIDs []string) {
objs ...interface{}) (policyPortsToUUIDs map[string]string, policyPortUUIDs []string, err error) {
klog.Infof("Processing NetworkPolicy %s/%s to delete %d local pods...", np.namespace, np.name, len(objs))

policyPortUUIDs = []string{}
Expand Down Expand Up @@ -767,7 +845,10 @@ func (bnc *BaseNetworkController) handleLocalPodSelectorDelFunc(np *networkPolic
return nil
}

portNamesToUUIDs, policyPortUUIDs := bnc.getExistingLocalPolicyPorts(np, objs...)
portNamesToUUIDs, policyPortUUIDs, err := bnc.getExistingLocalPolicyPorts(np, objs...)
if err != nil {
return err
}

if len(portNamesToUUIDs) > 0 {
var err error
Expand Down
29 changes: 20 additions & 9 deletions go-controller/pkg/ovn/base_network_controller_secondary.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (bsnc *BaseSecondaryNetworkController) AddSecondaryNetworkResourceCommon(ob
return nil

default:
return fmt.Errorf("object type %s not supported", objType)
return bsnc.AddResourceCommon(objType, obj)
}
return nil
}
Expand Down Expand Up @@ -214,7 +214,7 @@ func (bsnc *BaseSecondaryNetworkController) DeleteSecondaryNetworkResourceCommon
klog.Infof("Released IPs %q for network %q", ipamClaim.Status.IPs, ipamClaim.Spec.Network)

default:
return fmt.Errorf("object type %s not supported", objType)
return bsnc.DeleteResourceCommon(objType, obj)
}
return nil
}
Expand Down Expand Up @@ -721,21 +721,32 @@ func (bsnc *BaseSecondaryNetworkController) deleteNamespace4SecondaryNetwork(ns
return nil
}

// WatchMultiNetworkPolicy starts the watching of multinetworkpolicy resource and calls
// WatchNetworkPolicy starts the watching of networkpolicy resource and calls
// back the appropriate handler logic
func (bsnc *BaseSecondaryNetworkController) WatchMultiNetworkPolicy() error {
if !util.IsMultiNetworkPoliciesSupportEnabled() {
func (bsnc *BaseSecondaryNetworkController) WatchNetworkPolicy() error {
if bsnc.netPolicyHandler != nil {
return nil
}
handler, err := bsnc.retryNetworkPolicies.WatchResource()
if err != nil {
return err
}
bsnc.netPolicyHandler = handler
return nil
}

if bsnc.policyHandler != nil {
// WatchMultiNetworkPolicy starts the watching of multinetworkpolicy resource and calls
// back the appropriate handler logic
func (bsnc *BaseSecondaryNetworkController) WatchMultiNetworkPolicy() error {
if bsnc.multiNetPolicyHandler != nil {
return nil
}
handler, err := bsnc.retryNetworkPolicies.WatchResource()
handler, err := bsnc.retryMultiNetworkPolicies.WatchResource()
if err != nil {
bsnc.policyHandler = handler
return err
}
return err
bsnc.multiNetPolicyHandler = handler
return nil
}

// cleanupPolicyLogicalEntities cleans up all the port groups and address sets that belong to the given controller
Expand Down
22 changes: 17 additions & 5 deletions go-controller/pkg/ovn/base_secondary_layer2_network_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ func (oc *BaseSecondaryLayer2NetworkController) stop() {
if oc.ipamClaimsHandler != nil {
oc.watchFactory.RemoveIPAMClaimsHandler(oc.ipamClaimsHandler)
}
if oc.policyHandler != nil {
oc.watchFactory.RemoveMultiNetworkPolicyHandler(oc.policyHandler)
if oc.netPolicyHandler != nil {
oc.watchFactory.RemovePolicyHandler(oc.netPolicyHandler)
}
if oc.multiNetPolicyHandler != nil {
oc.watchFactory.RemoveMultiNetworkPolicyHandler(oc.multiNetPolicyHandler)
}
if oc.podHandler != nil {
oc.watchFactory.RemovePodHandler(oc.podHandler)
Expand Down Expand Up @@ -101,9 +104,18 @@ func (oc *BaseSecondaryLayer2NetworkController) run() error {
return err
}

// WatchMultiNetworkPolicy depends on WatchPods and WatchNamespaces
if err := oc.WatchMultiNetworkPolicy(); err != nil {
return err
if util.IsMultiNetworkPoliciesSupportEnabled() {
// WatchMultiNetworkPolicy depends on WatchPods and WatchNamespaces
if err := oc.WatchMultiNetworkPolicy(); err != nil {
return err
}
}

if oc.IsPrimaryNetwork() {
// WatchNetworkPolicy depends on WatchPods and WatchNamespaces
if err := oc.WatchNetworkPolicy(); err != nil {
return err
}
}

return nil
Expand Down
Loading

0 comments on commit 87ce669

Please sign in to comment.