Skip to content

Commit 7bac3e3

Browse files
rwhelanstapelberg
authored andcommitted
Restructure code base into smaller files (google#15)
* Restrcture code base into smaller files * Package level doc string * Move ExprsFromMsg back from expr sub-module * gofmt
1 parent 07c974e commit 7bac3e3

9 files changed

+763
-625
lines changed

chain.go

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright 2018 Google LLC. All Rights Reserved.
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+
15+
package nftables
16+
17+
import (
18+
"math"
19+
20+
"github.com/google/nftables/binaryutil"
21+
"github.com/mdlayher/netlink"
22+
"golang.org/x/sys/unix"
23+
)
24+
25+
// ChainHook specifies at which step in packet processing the Chain should be
26+
// executed. See also
27+
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_hooks
28+
type ChainHook uint32
29+
30+
// Possible ChainHook values.
31+
const (
32+
ChainHookPrerouting ChainHook = unix.NF_INET_PRE_ROUTING
33+
ChainHookInput ChainHook = unix.NF_INET_LOCAL_IN
34+
ChainHookForward ChainHook = unix.NF_INET_FORWARD
35+
ChainHookOutput ChainHook = unix.NF_INET_LOCAL_OUT
36+
ChainHookPostrouting ChainHook = unix.NF_INET_POST_ROUTING
37+
ChainHookIngress ChainHook = unix.NF_NETDEV_INGRESS
38+
)
39+
40+
// ChainPriority orders the chain relative to Netfilter internal operations. See
41+
// also
42+
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_priority
43+
type ChainPriority int32
44+
45+
// Possible ChainPriority values.
46+
const ( // from /usr/include/linux/netfilter_ipv4.h
47+
ChainPriorityFirst ChainPriority = math.MinInt32
48+
ChainPriorityConntrackDefrag ChainPriority = -400
49+
ChainPriorityRaw ChainPriority = -300
50+
ChainPrioritySELinuxFirst ChainPriority = -225
51+
ChainPriorityConntrack ChainPriority = -200
52+
ChainPriorityMangle ChainPriority = -150
53+
ChainPriorityNATDest ChainPriority = -100
54+
ChainPriorityFilter ChainPriority = 0
55+
ChainPrioritySecurity ChainPriority = 50
56+
ChainPriorityNATSource ChainPriority = 100
57+
ChainPrioritySELinuxLast ChainPriority = 225
58+
ChainPriorityConntrackHelper ChainPriority = 300
59+
ChainPriorityConntrackConfirm ChainPriority = math.MaxInt32
60+
ChainPriorityLast ChainPriority = math.MaxInt32
61+
)
62+
63+
// ChainType defines what this chain will be used for. See also
64+
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_types
65+
type ChainType string
66+
67+
// Possible ChainType values.
68+
const (
69+
ChainTypeFilter ChainType = "filter"
70+
ChainTypeRoute ChainType = "route"
71+
ChainTypeNAT ChainType = "nat"
72+
)
73+
74+
// A Chain contains Rules. See also
75+
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
76+
type Chain struct {
77+
Name string
78+
Table *Table
79+
Hooknum ChainHook
80+
Priority ChainPriority
81+
Type ChainType
82+
}
83+
84+
// AddChain adds the specified Chain. See also
85+
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains
86+
func (cc *Conn) AddChain(c *Chain) *Chain {
87+
chainHook := cc.marshalAttr([]netlink.Attribute{
88+
{Type: unix.NFTA_HOOK_HOOKNUM, Data: binaryutil.BigEndian.PutUint32(uint32(c.Hooknum))},
89+
{Type: unix.NFTA_HOOK_PRIORITY, Data: binaryutil.BigEndian.PutUint32(uint32(c.Priority))},
90+
})
91+
92+
data := cc.marshalAttr([]netlink.Attribute{
93+
{Type: unix.NFTA_CHAIN_TABLE, Data: []byte(c.Table.Name + "\x00")},
94+
{Type: unix.NFTA_CHAIN_NAME, Data: []byte(c.Name + "\x00")},
95+
{Type: unix.NLA_F_NESTED | unix.NFTA_CHAIN_HOOK, Data: chainHook},
96+
{Type: unix.NFTA_CHAIN_TYPE, Data: []byte(c.Type + "\x00")},
97+
})
98+
99+
cc.messages = append(cc.messages, netlink.Message{
100+
Header: netlink.Header{
101+
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWCHAIN),
102+
Flags: netlink.Request | netlink.Acknowledge | netlink.Create,
103+
},
104+
Data: append(extraHeader(uint8(c.Table.Family), 0), data...),
105+
})
106+
107+
return c
108+
}

conn.go

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2018 Google LLC. All Rights Reserved.
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+
15+
package nftables
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/google/nftables/expr"
21+
"github.com/mdlayher/netlink"
22+
"github.com/mdlayher/netlink/nltest"
23+
"golang.org/x/sys/unix"
24+
)
25+
26+
// A Conn represents a netlink connection of the nftables family.
27+
//
28+
// All methods return their input, so that variables can be defined from string
29+
// literals when desired.
30+
//
31+
// Commands are buffered. Flush sends all buffered commands in a single batch.
32+
type Conn struct {
33+
TestDial nltest.Func // for testing only; passed to nltest.Dial
34+
NetNS int // Network namespace netlink will interact with.
35+
messages []netlink.Message
36+
err error
37+
}
38+
39+
// Flush sends all buffered commands in a single batch to nftables.
40+
func (cc *Conn) Flush() error {
41+
if cc.err != nil {
42+
return cc.err // serialization error
43+
}
44+
conn, err := cc.dialNetlink()
45+
if err != nil {
46+
return err
47+
}
48+
49+
defer conn.Close()
50+
51+
if _, err := conn.SendMessages(batch(cc.messages)); err != nil {
52+
return fmt.Errorf("SendMessages: %v", err)
53+
}
54+
55+
if _, err := conn.Receive(); err != nil {
56+
return fmt.Errorf("Receive: %v", err)
57+
}
58+
59+
cc.messages = nil
60+
61+
return nil
62+
}
63+
64+
// FlushRuleset flushes the entire ruleset. See also
65+
// https://wiki.nftables.org/wiki-nftables/index.php/Operations_at_ruleset_level
66+
func (cc *Conn) FlushRuleset() {
67+
cc.messages = append(cc.messages, netlink.Message{
68+
Header: netlink.Header{
69+
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_DELTABLE),
70+
Flags: netlink.Request | netlink.Acknowledge | netlink.Create,
71+
},
72+
Data: extraHeader(0, 0),
73+
})
74+
}
75+
76+
func (cc *Conn) dialNetlink() (*netlink.Conn, error) {
77+
if cc.TestDial != nil {
78+
return nltest.Dial(cc.TestDial), nil
79+
}
80+
return netlink.Dial(unix.NETLINK_NETFILTER, &netlink.Config{NetNS: cc.NetNS})
81+
}
82+
83+
func (cc *Conn) setErr(err error) {
84+
if cc.err != nil {
85+
return
86+
}
87+
cc.err = err
88+
}
89+
90+
func (cc *Conn) marshalAttr(attrs []netlink.Attribute) []byte {
91+
b, err := netlink.MarshalAttributes(attrs)
92+
if err != nil {
93+
cc.setErr(err)
94+
return nil
95+
}
96+
return b
97+
}
98+
99+
func (cc *Conn) marshalExpr(e expr.Any) []byte {
100+
b, err := expr.Marshal(e)
101+
if err != nil {
102+
cc.setErr(err)
103+
return nil
104+
}
105+
return b
106+
}
107+
108+
func batch(messages []netlink.Message) []netlink.Message {
109+
batch := []netlink.Message{
110+
{
111+
Header: netlink.Header{
112+
Type: netlink.HeaderType(unix.NFNL_MSG_BATCH_BEGIN),
113+
Flags: netlink.Request,
114+
},
115+
Data: extraHeader(0, unix.NFNL_SUBSYS_NFTABLES),
116+
},
117+
}
118+
119+
batch = append(batch, messages...)
120+
121+
batch = append(batch, netlink.Message{
122+
Header: netlink.Header{
123+
Type: netlink.HeaderType(unix.NFNL_MSG_BATCH_END),
124+
Flags: netlink.Request,
125+
},
126+
Data: extraHeader(0, unix.NFNL_SUBSYS_NFTABLES),
127+
})
128+
129+
return batch
130+
}

counter.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2018 Google LLC. All Rights Reserved.
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+
15+
package nftables
16+
17+
import (
18+
"github.com/google/nftables/binaryutil"
19+
"github.com/mdlayher/netlink"
20+
"golang.org/x/sys/unix"
21+
)
22+
23+
// CounterObj implements Obj.
24+
type CounterObj struct {
25+
Table *Table
26+
Name string // e.g. “fwded”
27+
28+
Bytes uint64
29+
Packets uint64
30+
}
31+
32+
func (c *CounterObj) unmarshal(ad *netlink.AttributeDecoder) error {
33+
for ad.Next() {
34+
switch ad.Type() {
35+
case unix.NFTA_COUNTER_BYTES:
36+
c.Bytes = ad.Uint64()
37+
case unix.NFTA_COUNTER_PACKETS:
38+
c.Packets = ad.Uint64()
39+
}
40+
}
41+
return ad.Err()
42+
}
43+
44+
func (c *CounterObj) family() TableFamily {
45+
return c.Table.Family
46+
}
47+
48+
func (c *CounterObj) marshal(data bool) ([]byte, error) {
49+
obj, err := netlink.MarshalAttributes([]netlink.Attribute{
50+
{Type: unix.NFTA_COUNTER_BYTES, Data: binaryutil.BigEndian.PutUint64(c.Bytes)},
51+
{Type: unix.NFTA_COUNTER_PACKETS, Data: binaryutil.BigEndian.PutUint64(c.Packets)},
52+
})
53+
if err != nil {
54+
return nil, err
55+
}
56+
const NFT_OBJECT_COUNTER = 1 // TODO: get into x/sys/unix
57+
attrs := []netlink.Attribute{
58+
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(c.Table.Name + "\x00")},
59+
{Type: unix.NFTA_OBJ_NAME, Data: []byte(c.Name + "\x00")},
60+
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(NFT_OBJECT_COUNTER)},
61+
}
62+
if data {
63+
attrs = append(attrs, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA, Data: obj})
64+
}
65+
return netlink.MarshalAttributes(attrs)
66+
}

doc.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 Google LLC. All Rights Reserved.
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+
15+
// Package nftables manipulates Linux nftables (the iptables successor).
16+
package nftables

0 commit comments

Comments
 (0)