-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnftables_set.go
More file actions
94 lines (84 loc) · 3.63 KB
/
nftables_set.go
File metadata and controls
94 lines (84 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package coredns_nftables
import (
"context"
"time"
"github.com/google/nftables"
"github.com/miekg/dns"
)
type NftablesSetAddElement struct {
TableName string
SetName string
Interval bool
Timeout time.Duration
KeyType nftables.SetDatatype
}
func (m *NftablesSetAddElement) Name() string { return "nftables-set-add-element" }
func (m *NftablesSetAddElement) ServeDNS(ctx context.Context, cache *NftablesCache, answer *dns.RR, family nftables.TableFamily) (error, bool) {
var elements []nftables.SetElement
var element_text string
switch (*answer).Header().Rrtype {
case dns.TypeA:
elements = []nftables.SetElement{{Key: (*answer).(*dns.A).A}}
element_text = (*answer).(*dns.A).A.String()
case dns.TypeAAAA:
elements = []nftables.SetElement{{Key: (*answer).(*dns.AAAA).AAAA}}
element_text = (*answer).(*dns.AAAA).AAAA.String()
default:
return nil, true
}
tableCache := cache.MutableNftablesTable(family, m.TableName)
// get old set
set, _ := cache.NftableConnection.GetSetByName(tableCache.table, m.SetName)
if set == nil {
// Create nftable set if KeyType is not nftables.TypeInvalid
var keyType = m.KeyType
if keyType == nftables.TypeInvalid {
if family == nftables.TableFamilyIPv4 {
keyType = nftables.TypeIPAddr
} else if family == nftables.TableFamilyIPv6 {
keyType = nftables.TypeIP6Addr
} else {
log.Debugf("Nftables set %v %v %v ignore element %s because set not found", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return nil, true
}
}
// Ignore unmatched set
if (*answer).Header().Rrtype == dns.TypeA && keyType == nftables.TypeIP6Addr {
log.Debugf("Nftables set %v %v %v ignore element %s because it's a ipv6 set", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return nil, true
} else if (*answer).Header().Rrtype == dns.TypeAAAA && keyType == nftables.TypeIPAddr {
log.Debugf("Nftables set %v %v %v ignore element %s because it's a ipv4 set", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return nil, true
}
portSet := &nftables.Set{
Table: tableCache.table,
Name: m.SetName,
KeyType: keyType,
Interval: m.Interval,
HasTimeout: m.Timeout.Microseconds() > 0,
Timeout: m.Timeout,
}
log.Debugf("Nftables create set %v %v %v and add element %s", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
err := cache.NftableConnection.AddSet(portSet, elements)
if err != nil {
log.Errorf("Nftables create set %v %v %v and add element %s but AddSet failed. %v", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text, err)
return err, false
}
err = cache.NftableConnection.Flush()
if err != nil {
log.Errorf("Nftables create set %v %v %v and add element %s but Flush failed. %v", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text, err)
cache.HasNftableConnectionError = true
}
return err, false
}
// Ignore unmatched set
if (*answer).Header().Rrtype == dns.TypeA && set.KeyType == nftables.TypeIP6Addr {
log.Debugf("Nftables set %v %v %v ignore element %s because it's a ipv6 set", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return nil, true
} else if (*answer).Header().Rrtype == dns.TypeAAAA && set.KeyType == nftables.TypeIPAddr {
log.Debugf("Nftables set %v %v %v ignore element %s because it's a ipv4 set", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return nil, true
}
log.Debugf("Nftables set %v %v %v add element %s", (*cache).GetFamilyName(family), m.TableName, m.SetName, element_text)
return cache.SetAddElements(tableCache, set, elements), false
}