Skip to content

Commit

Permalink
fqdn: Make maximum number of IPs per restored rule configurable
Browse files Browse the repository at this point in the history
Only count the number of IPs for each FQDN selector/rule when storing
rules for restoration, rather than ignoring later rules on a port
after previous rules have hit the maximum number of IPs.

Make the maximum number of IPs per restored rule configurable with the
new option '--tofqdns-max-ips-per-restored-rule' (default 1000).

Signed-off-by: Jarno Rajahalme <jarno@covalent.io>
  • Loading branch information
jrajahalme authored and aanm committed Nov 12, 2020
1 parent e8605f8 commit 871e7e1
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 9 deletions.
1 change: 1 addition & 0 deletions Documentation/cmdref/cilium-agent.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions daemon/cmd/daemon_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,9 @@ func init() {
flags.Int(option.ToFQDNsMaxIPsPerHost, defaults.ToFQDNsMaxIPsPerHost, "Maximum number of IPs to maintain per FQDN name for each endpoint")
option.BindEnv(option.ToFQDNsMaxIPsPerHost)

flags.Int(option.ToFQDNsMaxIPsPerRestoredRule, defaults.ToFQDNsMaxIPsPerRestoredRule, "Maximum number of IPs to maintain for each restored rule")
option.BindEnv(option.ToFQDNsMaxIPsPerRestoredRule)

flags.Int(option.ToFQDNsMaxDeferredConnectionDeletes, defaults.ToFQDNsMaxDeferredConnectionDeletes, "Maximum number of IPs to retain for expired DNS lookups with still-active connections")
option.BindEnv(option.ToFQDNsMaxDeferredConnectionDeletes)

Expand Down
4 changes: 3 additions & 1 deletion daemon/cmd/fqdn.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,9 @@ func (d *Daemon) bootstrapFQDN(possibleEndpoints map[uint16]*endpoint.Endpoint,
if err != nil {
return err
}
proxy.DefaultDNSProxy, err = dnsproxy.StartDNSProxy("", port, option.Config.ToFQDNsEnableDNSCompression, d.lookupEPByIP, d.LookupSecIDByIP, d.lookupIPsBySecID, d.notifyOnDNSMsg)
proxy.DefaultDNSProxy, err = dnsproxy.StartDNSProxy("", port, option.Config.ToFQDNsEnableDNSCompression,
option.Config.ToFQDNsMaxIPsPerRestoredRule, d.lookupEPByIP, d.LookupSecIDByIP, d.lookupIPsBySecID,
d.notifyOnDNSMsg)
if err == nil {
// Increase the ProxyPort reference count so that it will never get released.
err = d.l7Proxy.SetProxyPort(listenerName, proxy.DefaultDNSProxy.BindPort)
Expand Down
4 changes: 4 additions & 0 deletions pkg/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ const (
// for each FQDN name in an endpoint's FQDN cache
ToFQDNsMaxIPsPerHost = 50

// ToFQDNsMaxIPsPerRestoredRule defines the maximum number of IPs to maintain
// for each FQDN selector in endpoint's restored ToFQDN rules.
ToFQDNsMaxIPsPerRestoredRule = 1000

// ToFQDNsMaxDeferredConnectionDeletes Maximum number of IPs to retain for
// expired DNS lookups with still-active connections
ToFQDNsMaxDeferredConnectionDeletes = 10000
Expand Down
17 changes: 10 additions & 7 deletions pkg/fqdn/dnsproxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ type DNSProxy struct {
// helpers.go but is modified during testing.
lookupTargetDNSServer func(w dns.ResponseWriter) (serverIP net.IP, serverPort uint16, addrStr string, err error)

// maxIPsPerRestoredRule is the maximum number of IPs to maintain for each
// restored ToFQDNs rule.
maxIPsPerRestoredRule int

// this mutex protects variables below this point
lock.Mutex

Expand Down Expand Up @@ -182,32 +186,30 @@ func (p *DNSProxy) GetRules(endpointID uint16) restore.DNSRules {

restored := make(restore.DNSRules)
for port, entries := range p.allowed[uint64(endpointID)] {
count := 0
var ipRules restore.IPRules
for cs, regex := range entries {
var IPs map[string]struct{}
if !cs.IsWildcard() {
IPs = make(map[string]struct{})
count := 0
Loop:
for _, nid := range cs.GetSelections() {
for _, ip := range p.LookupIPsBySecID(nid) {
IPs[ip] = struct{}{}
count++
if count > 1000 {
if count > p.maxIPsPerRestoredRule {
log.WithFields(logrus.Fields{
logfields.EndpointID: endpointID,
logfields.Port: port,
logfields.EndpointLabelSelector: cs,
}).Warning("Too many DNS rules or destinations for a port, skipping the rest")
logfields.Limit: p.maxIPsPerRestoredRule,
}).Warning("Too many IPs for a rule, skipping the rest")
break Loop
}
}
}
}
ipRules = append(ipRules, restore.IPRule{IPs: IPs, Re: restore.RuleRegex{Regexp: regex}})
if count > 1000 {
break
}
}
restored[port] = ipRules
}
Expand Down Expand Up @@ -355,7 +357,7 @@ func (proxyStat *ProxyRequestContext) IsTimeout() bool {
// notifyFunc will be called with DNS response data that is returned to a
// requesting endpoint. Note that denied requests will not trigger this
// callback.
func StartDNSProxy(address string, port uint16, enableDNSCompression bool, lookupEPFunc LookupEndpointIDByIPFunc, lookupSecIDFunc LookupSecIDByIPFunc, lookupIPsFunc LookupIPsBySecIDFunc, notifyFunc NotifyOnDNSMsgFunc) (*DNSProxy, error) {
func StartDNSProxy(address string, port uint16, enableDNSCompression bool, maxRestoreIPs int, lookupEPFunc LookupEndpointIDByIPFunc, lookupSecIDFunc LookupSecIDByIPFunc, lookupIPsFunc LookupIPsBySecIDFunc, notifyFunc NotifyOnDNSMsgFunc) (*DNSProxy, error) {
if port == 0 {
log.Debug("DNS Proxy port is configured to 0. A random port will be assigned by the OS.")
}
Expand All @@ -374,6 +376,7 @@ func StartDNSProxy(address string, port uint16, enableDNSCompression bool, looku
restored: make(perEPRestored),
restoredEPs: make(restoredEPs),
EnableDNSCompression: enableDNSCompression,
maxIPsPerRestoredRule: maxRestoreIPs,
}
atomic.StoreInt32(&p.rejectReply, dns.RcodeRefused)

Expand Down
2 changes: 1 addition & 1 deletion pkg/fqdn/dnsproxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (s *DNSProxyTestSuite) SetUpTest(c *C) {
s.dnsServer = setupServer(c)
c.Assert(s.dnsServer, Not(IsNil), Commentf("unable to setup DNS server"))

proxy, err := StartDNSProxy("", 0, true, // any address, any port, enable compression
proxy, err := StartDNSProxy("", 0, true, 1000, // any address, any port, enable compression, max 1000 restore IPs
// LookupEPByIP
func(ip net.IP) (*endpoint.Endpoint, error) {
if s.restoring {
Expand Down
3 changes: 3 additions & 0 deletions pkg/logging/logfields/logfields.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ const (
// performed
Reason = "reason"

// Limit is a numerical limit that has been exceeded
Limit = "limit"

// Debug is a boolean value for whether debug is set or not.
Debug = "debug"

Expand Down
11 changes: 11 additions & 0 deletions pkg/option/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ const (
// for each FQDN name in an endpoint's FQDN cache
ToFQDNsMaxIPsPerHost = "tofqdns-endpoint-max-ip-per-hostname"

// ToFQDNMaxIPsPerRestoredRule defines the maximum number of IPs to maintain
// for each FQDN selector in endpoint's restored ToFQDN rules
ToFQDNsMaxIPsPerRestoredRule = "tofqdns-max-ips-per-restored-rule"

// ToFQDNsMaxDeferredConnectionDeletes defines the maximum number of IPs to
// retain for expired DNS lookups with still-active connections"
ToFQDNsMaxDeferredConnectionDeletes = "tofqdns-max-deferred-connection-deletes"
Expand Down Expand Up @@ -908,6 +912,7 @@ var HelpFlagSections = []FlagsSection{
Flags: []string{
FQDNRejectResponseCode,
ToFQDNsMaxIPsPerHost,
ToFQDNsMaxIPsPerRestoredRule,
ToFQDNsMinTTL,
ToFQDNsPreCache,
ToFQDNsProxyPort,
Expand Down Expand Up @@ -1640,6 +1645,10 @@ type DaemonConfig struct {
// for each FQDN name in an endpoint's FQDN cache
ToFQDNsMaxIPsPerHost int

// ToFQDNMaxIPsPerRestoredRule defines the maximum number of IPs to maintain
// for each FQDN selector in endpoint's restored ToFQDN rules
ToFQDNsMaxIPsPerRestoredRule int

// ToFQDNsMaxIPsPerHost defines the maximum number of IPs to retain for
// expired DNS lookups with still-active connections
ToFQDNsMaxDeferredConnectionDeletes int
Expand Down Expand Up @@ -2052,6 +2061,7 @@ var (
EnableL7Proxy: defaults.EnableL7Proxy,
EndpointStatus: make(map[string]struct{}),
ToFQDNsMaxIPsPerHost: defaults.ToFQDNsMaxIPsPerHost,
ToFQDNsMaxIPsPerRestoredRule: defaults.ToFQDNsMaxIPsPerRestoredRule,
KVstorePeriodicSync: defaults.KVstorePeriodicSync,
KVstoreConnectivityTimeout: defaults.KVstoreConnectivityTimeout,
IPAllocationTimeout: defaults.IPAllocationTimeout,
Expand Down Expand Up @@ -2579,6 +2589,7 @@ func (c *DaemonConfig) Populate() {

// toFQDNs options
c.ToFQDNsMaxIPsPerHost = viper.GetInt(ToFQDNsMaxIPsPerHost)
c.ToFQDNsMaxIPsPerRestoredRule = viper.GetInt(ToFQDNsMaxIPsPerRestoredRule)
if maxZombies := viper.GetInt(ToFQDNsMaxDeferredConnectionDeletes); maxZombies >= 0 {
c.ToFQDNsMaxDeferredConnectionDeletes = viper.GetInt(ToFQDNsMaxDeferredConnectionDeletes)
} else {
Expand Down

0 comments on commit 871e7e1

Please sign in to comment.