|
@@ -5,6 +5,7 @@ import (
|
|
"errors"
|
|
"errors"
|
|
"fmt"
|
|
"fmt"
|
|
"maps"
|
|
"maps"
|
|
|
|
+ "net"
|
|
"sort"
|
|
"sort"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
@@ -1630,3 +1631,233 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
|
|
}
|
|
}
|
|
return rules
|
|
return rules
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclRule) {
|
|
|
|
+ rules = make(map[string]models.AclRule)
|
|
|
|
+
|
|
|
|
+ taggedNodes := GetTagMapWithNodesByNetwork(models.NetworkID(targetnode.Network), false)
|
|
|
|
+
|
|
|
|
+ acls := listDevicePolicies(models.NetworkID(targetnode.Network))
|
|
|
|
+ var targetNodeTags = make(map[models.TagID]struct{})
|
|
|
|
+ targetNodeTags["*"] = struct{}{}
|
|
|
|
+ /*
|
|
|
|
+ if target node is egress gateway
|
|
|
|
+ if acl policy has egress route and it is present in target node egress ranges
|
|
|
|
+ fetches all the nodes in that policy and add rules
|
|
|
|
+ */
|
|
|
|
+ if targetnode.IsEgressGateway {
|
|
|
|
+ for _, rangeI := range targetnode.EgressGatewayRanges {
|
|
|
|
+ targetNodeTags[models.TagID(rangeI)] = struct{}{}
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, acl := range acls {
|
|
|
|
+ if !acl.Enabled {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ srcTags := convAclTagToValueMap(acl.Src)
|
|
|
|
+ dstTags := convAclTagToValueMap(acl.Dst)
|
|
|
|
+ _, srcAll := srcTags["*"]
|
|
|
|
+ _, dstAll := dstTags["*"]
|
|
|
|
+
|
|
|
|
+ for nodeTag := range targetNodeTags {
|
|
|
|
+ aclRule := models.AclRule{
|
|
|
|
+ ID: acl.ID,
|
|
|
|
+ AllowedProtocol: acl.Proto,
|
|
|
|
+ AllowedPorts: acl.Port,
|
|
|
|
+ Direction: acl.AllowedDirection,
|
|
|
|
+ Allowed: true,
|
|
|
|
+ }
|
|
|
|
+ if nodeTag != "*" {
|
|
|
|
+ ip, cidr, err := net.ParseCIDR(nodeTag.String())
|
|
|
|
+ if err != nil {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if ip.To4() != nil {
|
|
|
|
+ aclRule.Dst = *cidr
|
|
|
|
+ } else {
|
|
|
|
+ aclRule.Dst6 = *cidr
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ aclRule.Dst = net.IPNet{
|
|
|
|
+ IP: net.IPv4zero, // 0.0.0.0
|
|
|
|
+ Mask: net.CIDRMask(0, 32), // /0 means match all IPv4
|
|
|
|
+ }
|
|
|
|
+ aclRule.Dst6 = net.IPNet{
|
|
|
|
+ IP: net.IPv6zero, // ::
|
|
|
|
+ Mask: net.CIDRMask(0, 128), // /0 means match all IPv6
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if acl.AllowedDirection == models.TrafficDirectionBi {
|
|
|
|
+ var existsInSrcTag bool
|
|
|
|
+ var existsInDstTag bool
|
|
|
|
+
|
|
|
|
+ if _, ok := srcTags[nodeTag.String()]; ok || srcAll {
|
|
|
|
+ existsInSrcTag = true
|
|
|
|
+ }
|
|
|
|
+ if _, ok := srcTags[targetnode.ID.String()]; ok || srcAll {
|
|
|
|
+ existsInSrcTag = true
|
|
|
|
+ }
|
|
|
|
+ if _, ok := dstTags[nodeTag.String()]; ok || dstAll {
|
|
|
|
+ existsInDstTag = true
|
|
|
|
+ }
|
|
|
|
+ if _, ok := dstTags[targetnode.ID.String()]; ok || dstAll {
|
|
|
|
+ existsInDstTag = true
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if existsInSrcTag && !existsInDstTag {
|
|
|
|
+ // get all dst tags
|
|
|
|
+ for dst := range dstTags {
|
|
|
|
+ if dst == nodeTag.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // Get peers in the tags and add allowed rules
|
|
|
|
+ nodes := taggedNodes[models.TagID(dst)]
|
|
|
|
+ if dst != targetnode.ID.String() {
|
|
|
|
+ node, err := GetNodeByID(dst)
|
|
|
|
+ if err == nil {
|
|
|
|
+ nodes = append(nodes, node)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, node := range nodes {
|
|
|
|
+ if node.ID == targetnode.ID {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.Address.IP != nil {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.Address6.IP != nil {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address != "" {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.StaticNode.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address6 != "" {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.StaticNode.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if existsInDstTag && !existsInSrcTag {
|
|
|
|
+ // get all src tags
|
|
|
|
+ for src := range srcTags {
|
|
|
|
+ if src == nodeTag.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // Get peers in the tags and add allowed rules
|
|
|
|
+ nodes := taggedNodes[models.TagID(src)]
|
|
|
|
+ if src != targetnode.ID.String() {
|
|
|
|
+ node, err := GetNodeByID(src)
|
|
|
|
+ if err == nil {
|
|
|
|
+ nodes = append(nodes, node)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, node := range nodes {
|
|
|
|
+ if node.ID == targetnode.ID {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.Address.IP != nil {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.Address6.IP != nil {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address != "" {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.StaticNode.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address6 != "" {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.StaticNode.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if existsInDstTag && existsInSrcTag {
|
|
|
|
+ nodes := taggedNodes[nodeTag]
|
|
|
|
+ for srcID := range srcTags {
|
|
|
|
+ if srcID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ node, err := GetNodeByID(srcID)
|
|
|
|
+ if err == nil {
|
|
|
|
+ nodes = append(nodes, node)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for dstID := range dstTags {
|
|
|
|
+ if dstID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ node, err := GetNodeByID(dstID)
|
|
|
|
+ if err == nil {
|
|
|
|
+ nodes = append(nodes, node)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, node := range nodes {
|
|
|
|
+ if node.ID == targetnode.ID {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.Address.IP != nil {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.Address6.IP != nil {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address != "" {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.StaticNode.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address6 != "" {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.StaticNode.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ _, all := dstTags["*"]
|
|
|
|
+ if _, ok := dstTags[nodeTag.String()]; ok || all {
|
|
|
|
+ // get all src tags
|
|
|
|
+ for src := range srcTags {
|
|
|
|
+ if src == nodeTag.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // Get peers in the tags and add allowed rules
|
|
|
|
+ nodes := taggedNodes[models.TagID(src)]
|
|
|
|
+ for _, node := range nodes {
|
|
|
|
+ if node.ID == targetnode.ID {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if node.Address.IP != nil {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.Address6.IP != nil {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address != "" {
|
|
|
|
+ aclRule.IPList = append(aclRule.IPList, node.StaticNode.AddressIPNet4())
|
|
|
|
+ }
|
|
|
|
+ if node.IsStatic && node.StaticNode.Address6 != "" {
|
|
|
|
+ aclRule.IP6List = append(aclRule.IP6List, node.StaticNode.AddressIPNet6())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if len(aclRule.IPList) > 0 || len(aclRule.IP6List) > 0 {
|
|
|
|
+ rules[acl.ID] = aclRule
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|