lb_acl.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package ovn
  15. import (
  16. "fmt"
  17. "sort"
  18. "strings"
  19. "yunion.io/x/ovsdb/schema/ovn_nb"
  20. "yunion.io/x/pkg/errors"
  21. computeapi "yunion.io/x/onecloud/pkg/apis/compute"
  22. agentmodels "yunion.io/x/onecloud/pkg/vpcagent/models"
  23. )
  24. const (
  25. errBadLblistenerAcl = errors.Error("bad loadbalancer listener acl rule")
  26. )
  27. func lblistenerToAcls(lport string, lblistener *agentmodels.LoadbalancerListener) ([]*ovn_nb.ACL, error) {
  28. if aclStatus := lblistener.AclStatus; aclStatus != computeapi.LB_BOOL_ON {
  29. return nil, nil
  30. }
  31. var cidrs []string
  32. lbacl := lblistener.LoadbalancerAcl
  33. if lbacl != nil || lbacl.AclEntries != nil {
  34. aclEntries := *lbacl.AclEntries
  35. for _, aclEntry := range aclEntries {
  36. if aclEntry.Cidr != "" {
  37. cidrs = append(cidrs, aclEntry.Cidr)
  38. }
  39. }
  40. }
  41. var (
  42. aclType = lblistener.AclType
  43. action string
  44. actionDefault string
  45. )
  46. switch aclType {
  47. case computeapi.LB_ACL_TYPE_BLACK:
  48. if len(cidrs) == 0 {
  49. // nothing to black out and it will be allowed by
  50. // default by ovn for no matching
  51. return nil, nil
  52. }
  53. action = "drop"
  54. actionDefault = "allow-related"
  55. case computeapi.LB_ACL_TYPE_WHITE:
  56. action = "allow-related"
  57. actionDefault = "drop"
  58. default:
  59. return nil, errors.Wrapf(errBadLblistenerAcl, "unknown acl type %q", aclType)
  60. }
  61. var portmatch = fmt.Sprintf("outport == %q", lport)
  62. var l3match string
  63. if len(cidrs) > 0 {
  64. var l3matches = make([]string, len(cidrs))
  65. sort.Strings(cidrs)
  66. for i, cidr := range cidrs {
  67. l3matches[i] = fmt.Sprintf("ip4.src == %s", cidr)
  68. }
  69. l3match = "(" + strings.Join(l3matches, " || ") + ")"
  70. }
  71. var (
  72. l4proto string
  73. l4port int
  74. l4match string
  75. )
  76. switch listenerType := lblistener.ListenerType; listenerType {
  77. case computeapi.LB_LISTENER_TYPE_TCP,
  78. computeapi.LB_LISTENER_TYPE_HTTP,
  79. computeapi.LB_LISTENER_TYPE_HTTPS:
  80. l4proto = "tcp"
  81. case computeapi.LB_LISTENER_TYPE_UDP:
  82. l4proto = "udp"
  83. default:
  84. return nil, errors.Wrapf(errBadLblistenerAcl, "unknown listener type %q", listenerType)
  85. }
  86. l4port = lblistener.ListenerPort
  87. l4match = fmt.Sprintf("%s.dst == %d", l4proto, l4port)
  88. const (
  89. prio200 = 200
  90. prio100 = 100
  91. )
  92. var (
  93. match200 string
  94. match100 string
  95. )
  96. match200 = portmatch
  97. if l3match != "" {
  98. match200 += " && " + l3match
  99. }
  100. match200 += " && " + l4match
  101. match100 = portmatch + " && " + l4match
  102. acls := []*ovn_nb.ACL{
  103. &ovn_nb.ACL{
  104. Priority: 200,
  105. Direction: aclDirToLport,
  106. Match: match200,
  107. Action: action,
  108. },
  109. &ovn_nb.ACL{
  110. Priority: 100,
  111. Direction: aclDirToLport,
  112. Match: match100,
  113. Action: actionDefault,
  114. },
  115. }
  116. return acls, nil
  117. }