Skip to content

Commit

Permalink
[IPv6] Add IPv6 support for NetworkPolicy
Browse files Browse the repository at this point in the history
1. Add enhancement in Antrea Controller and Agent to support NetworkPolicy
   in IPv6.
2. Optimize test cases to support IPv6
3. Use regex in CRD to validate IPv4 or IPv6 string
4. Add TestEgressToServerInCIDRBlock and TestEgressToServerInCIDRBlockWithException
5. networkpolicy_controller.go: PodIPs includes PodIP
  • Loading branch information
wenyingd authored and lzhecheng committed Nov 11, 2020
1 parent a31a432 commit 3c5cdcf
Show file tree
Hide file tree
Showing 22 changed files with 1,605 additions and 402 deletions.
6 changes: 3 additions & 3 deletions build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ spec:
items:
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
name:
type: string
Expand Down Expand Up @@ -485,7 +485,7 @@ spec:
- ip
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
namespace:
type: string
Expand All @@ -503,7 +503,7 @@ spec:
protocol:
type: integer
srcIP:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
ttl:
type: integer
Expand Down
6 changes: 3 additions & 3 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ spec:
items:
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
name:
type: string
Expand Down Expand Up @@ -485,7 +485,7 @@ spec:
- ip
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
namespace:
type: string
Expand All @@ -503,7 +503,7 @@ spec:
protocol:
type: integer
srcIP:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
ttl:
type: integer
Expand Down
6 changes: 3 additions & 3 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ spec:
items:
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
name:
type: string
Expand Down Expand Up @@ -485,7 +485,7 @@ spec:
- ip
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
namespace:
type: string
Expand All @@ -503,7 +503,7 @@ spec:
protocol:
type: integer
srcIP:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
ttl:
type: integer
Expand Down
6 changes: 3 additions & 3 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ spec:
items:
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
name:
type: string
Expand Down Expand Up @@ -485,7 +485,7 @@ spec:
- ip
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
namespace:
type: string
Expand All @@ -503,7 +503,7 @@ spec:
protocol:
type: integer
srcIP:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
ttl:
type: integer
Expand Down
6 changes: 3 additions & 3 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ spec:
items:
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
name:
type: string
Expand Down Expand Up @@ -485,7 +485,7 @@ spec:
- ip
properties:
ip:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
namespace:
type: string
Expand All @@ -503,7 +503,7 @@ spec:
protocol:
type: integer
srcIP:
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
type: string
ttl:
type: integer
Expand Down
6 changes: 3 additions & 3 deletions build/yamls/base/crds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ spec:
type: string
ip:
type: string
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
oneOf:
- required: ["pod", "namespace"]
- required: ["service", "namespace"]
Expand All @@ -122,7 +122,7 @@ spec:
properties:
srcIP:
type: string
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
protocol:
type: integer
ttl:
Expand Down Expand Up @@ -558,7 +558,7 @@ spec:
properties:
ip:
type: string
format: ipv4
pattern: ^(((([1]?\d)?\d|2[0-4]\d|25[0-5])\.){3}(([1]?\d)?\d|2[0-4]\d|25[0-5]))|([\da-fA-F]{1,4}(\:[\da-fA-F]{1,4}){7})|(([\da-fA-F]{1,4}:){0,5}::([\da-fA-F]{1,4}:){0,5}[\da-fA-F]{1,4})$
name:
type: string
ports:
Expand Down
8 changes: 6 additions & 2 deletions pkg/agent/controller/networkpolicy/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,12 @@ func newAppliedToGroupMember(name, namespace string, containerPorts ...v1beta2.N
return &v1beta2.GroupMember{Pod: &v1beta2.PodReference{Name: name, Namespace: namespace}, Ports: containerPorts}
}

func newAddressGroupMember(ip string) *v1beta2.GroupMember {
return &v1beta2.GroupMember{IPs: []v1beta2.IPAddress{v1beta2.IPAddress(net.ParseIP(ip))}}
func newAddressGroupMember(ips ...string) *v1beta2.GroupMember {
ipAddrs := make([]v1beta2.IPAddress, len(ips))
for idx, ip := range ips {
ipAddrs[idx] = v1beta2.IPAddress(net.ParseIP(ip))
}
return &v1beta2.GroupMember{IPs: ipAddrs}
}

func TestRuleCacheAddAddressGroup(t *testing.T) {
Expand Down
41 changes: 27 additions & 14 deletions pkg/agent/controller/networkpolicy/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ type reconciler struct {

// priorityAssigners provides interfaces to manage OF priorities for each OVS table.
priorityAssigners map[binding.TableIDType]*tablePriorityAssigner
// ipv4Enabled tells if IPv4 is supported on this Node or not.
ipv4Enabled bool
// ipv6Enabled tells is IPv6 is supported on this Node or not.
ipv6Enabled bool
}

// newReconciler returns a new *reconciler.
Expand All @@ -208,6 +212,11 @@ func newReconciler(ofClient openflow.Client, ifaceStore interfacestore.Interface
idAllocator: newIDAllocator(),
priorityAssigners: priorityAssigners,
}
// Check if ofClient is nil or not to be compatible with unit tests.
if ofClient != nil {
reconciler.ipv4Enabled = ofClient.IsIPv4Enabled()
reconciler.ipv6Enabled = ofClient.IsIPv6Enabled()
}
return reconciler
}

Expand Down Expand Up @@ -408,7 +417,7 @@ func (r *reconciler) computeOFRulesForAdd(rule *CompletedRule, ofPriority *uint1
// Addresses got from source GroupMembers' IPs.
from1 := groupMembersToOFAddresses(rule.FromAddresses)
// Get addresses that in From IPBlock but not in Except IPBlocks.
from2 := ipBlocksToOFAddresses(rule.From.IPBlocks)
from2 := ipBlocksToOFAddresses(rule.From.IPBlocks, r.ipv4Enabled, r.ipv6Enabled)

podsByServicesMap, servicesMap := groupMembersByServices(rule.Services, rule.TargetMembers)

Expand Down Expand Up @@ -471,7 +480,7 @@ func (r *reconciler) computeOFRulesForAdd(rule *CompletedRule, ofPriority *uint1
}
if len(rule.To.IPBlocks) > 0 {
// Diff Addresses between To and Except of IPBlocks
to := ipBlocksToOFAddresses(rule.To.IPBlocks)
to := ipBlocksToOFAddresses(rule.To.IPBlocks, r.ipv4Enabled, r.ipv6Enabled)
ofRule.To = append(ofRule.To, to...)
}
}
Expand Down Expand Up @@ -532,7 +541,7 @@ func (r *reconciler) update(lastRealized *lastRealized, newRule *CompletedRule,
// only happen to Group members.
if newRule.Direction == v1beta2.DirectionIn {
from1 := groupMembersToOFAddresses(newRule.FromAddresses)
from2 := ipBlocksToOFAddresses(newRule.From.IPBlocks)
from2 := ipBlocksToOFAddresses(newRule.From.IPBlocks, r.ipv4Enabled, r.ipv6Enabled)
addedFrom := groupMembersToOFAddresses(newRule.FromAddresses.Difference(lastRealized.FromAddresses))
deletedFrom := groupMembersToOFAddresses(lastRealized.FromAddresses.Difference(newRule.FromAddresses))

Expand Down Expand Up @@ -833,35 +842,39 @@ func groupMembersToOFAddresses(groupMemberSet v1beta2.GroupMemberSet) []types.Ad
return addresses
}

func ipBlocksToOFAddresses(ipBlocks []v1beta2.IPBlock) []types.Address {
func ipBlocksToOFAddresses(ipBlocks []v1beta2.IPBlock, ipv4Enabled, ipv6Enabled bool) []types.Address {
// Must not return nil as it means not restricted by addresses in Openflow implementation.
addresses := make([]types.Address, 0)
for _, b := range ipBlocks {
exceptIPNet := make([]*net.IPNet, 0, len(b.Except))
blockCIDR := ip.IPNetToNetIPNet(&b.CIDR)
if !isIPNetSupportedByAF(blockCIDR, ipv4Enabled, ipv6Enabled) {
klog.Infof("IPBlock %s is using unsupported address family, skip it", blockCIDR.String())
continue
}
exceptIPNets := make([]*net.IPNet, 0, len(b.Except))
for i := range b.Except {
c := b.Except[i]
exceptIPNet = append(exceptIPNet, ip.IPNetToNetIPNet(&c))
except := ip.IPNetToNetIPNet(&c)
exceptIPNets = append(exceptIPNets, except)
}
diffCIDRs, err := ip.DiffFromCIDRs(ip.IPNetToNetIPNet(&b.CIDR), exceptIPNet)
diffCIDRs, err := ip.DiffFromCIDRs(blockCIDR, exceptIPNets)
if err != nil {
// Currently only IPv4 addresses are supported
klog.Errorf("Error when determining diffCIDRs: %v", err)
continue
}
for _, d := range diffCIDRs {
addresses = append(addresses, ipNetToOFAddress(*ip.NetIPNetToIPNet(d)))
addresses = append(addresses, openflow.NewIPNetAddress(*d))
}
}

return addresses
}

func ipNetToOFAddress(in v1beta2.IPNet) *openflow.IPNetAddress {
ipNet := net.IPNet{
IP: net.IP(in.IP),
Mask: net.CIDRMask(int(in.PrefixLength), 32),
func isIPNetSupportedByAF(ipnet *net.IPNet, ipv4Enabled, ipv6Enabled bool) bool {
if (ipnet.IP.To4() != nil && ipv4Enabled) || (ipnet.IP.To4() == nil && ipv6Enabled) {
return true
}
return openflow.NewIPNetAddress(ipNet)
return false
}

func ipsToOFAddresses(ips sets.String) []types.Address {
Expand Down
Loading

0 comments on commit 3c5cdcf

Please sign in to comment.