added ability to create regular chains without a hook priority (#183)
See https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_regular_chains for info on regular chains. Closes #179.
This commit is contained in:
parent
6cd15ed863
commit
cbeb0fb1ec
70
chain.go
70
chain.go
|
@ -30,38 +30,48 @@ import (
|
||||||
type ChainHook uint32
|
type ChainHook uint32
|
||||||
|
|
||||||
// Possible ChainHook values.
|
// Possible ChainHook values.
|
||||||
const (
|
var (
|
||||||
ChainHookPrerouting ChainHook = unix.NF_INET_PRE_ROUTING
|
ChainHookPrerouting *ChainHook = ChainHookRef(unix.NF_INET_PRE_ROUTING)
|
||||||
ChainHookInput ChainHook = unix.NF_INET_LOCAL_IN
|
ChainHookInput *ChainHook = ChainHookRef(unix.NF_INET_LOCAL_IN)
|
||||||
ChainHookForward ChainHook = unix.NF_INET_FORWARD
|
ChainHookForward *ChainHook = ChainHookRef(unix.NF_INET_FORWARD)
|
||||||
ChainHookOutput ChainHook = unix.NF_INET_LOCAL_OUT
|
ChainHookOutput *ChainHook = ChainHookRef(unix.NF_INET_LOCAL_OUT)
|
||||||
ChainHookPostrouting ChainHook = unix.NF_INET_POST_ROUTING
|
ChainHookPostrouting *ChainHook = ChainHookRef(unix.NF_INET_POST_ROUTING)
|
||||||
ChainHookIngress ChainHook = unix.NF_NETDEV_INGRESS
|
ChainHookIngress *ChainHook = ChainHookRef(unix.NF_NETDEV_INGRESS)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ChainHookRef returns a pointer to a ChainHookRef value.
|
||||||
|
func ChainHookRef(h ChainHook) *ChainHook {
|
||||||
|
return &h
|
||||||
|
}
|
||||||
|
|
||||||
// ChainPriority orders the chain relative to Netfilter internal operations. See
|
// ChainPriority orders the chain relative to Netfilter internal operations. See
|
||||||
// also
|
// also
|
||||||
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_priority
|
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_priority
|
||||||
type ChainPriority int32
|
type ChainPriority int32
|
||||||
|
|
||||||
// Possible ChainPriority values.
|
// Possible ChainPriority values.
|
||||||
const ( // from /usr/include/linux/netfilter_ipv4.h
|
var ( // from /usr/include/linux/netfilter_ipv4.h
|
||||||
ChainPriorityFirst ChainPriority = math.MinInt32
|
ChainPriorityFirst *ChainPriority = ChainPriorityRef(math.MinInt32)
|
||||||
ChainPriorityConntrackDefrag ChainPriority = -400
|
ChainPriorityConntrackDefrag *ChainPriority = ChainPriorityRef(-400)
|
||||||
ChainPriorityRaw ChainPriority = -300
|
ChainPriorityRaw *ChainPriority = ChainPriorityRef(-300)
|
||||||
ChainPrioritySELinuxFirst ChainPriority = -225
|
ChainPrioritySELinuxFirst *ChainPriority = ChainPriorityRef(-225)
|
||||||
ChainPriorityConntrack ChainPriority = -200
|
ChainPriorityConntrack *ChainPriority = ChainPriorityRef(-200)
|
||||||
ChainPriorityMangle ChainPriority = -150
|
ChainPriorityMangle *ChainPriority = ChainPriorityRef(-150)
|
||||||
ChainPriorityNATDest ChainPriority = -100
|
ChainPriorityNATDest *ChainPriority = ChainPriorityRef(-100)
|
||||||
ChainPriorityFilter ChainPriority = 0
|
ChainPriorityFilter *ChainPriority = ChainPriorityRef(0)
|
||||||
ChainPrioritySecurity ChainPriority = 50
|
ChainPrioritySecurity *ChainPriority = ChainPriorityRef(50)
|
||||||
ChainPriorityNATSource ChainPriority = 100
|
ChainPriorityNATSource *ChainPriority = ChainPriorityRef(100)
|
||||||
ChainPrioritySELinuxLast ChainPriority = 225
|
ChainPrioritySELinuxLast *ChainPriority = ChainPriorityRef(225)
|
||||||
ChainPriorityConntrackHelper ChainPriority = 300
|
ChainPriorityConntrackHelper *ChainPriority = ChainPriorityRef(300)
|
||||||
ChainPriorityConntrackConfirm ChainPriority = math.MaxInt32
|
ChainPriorityConntrackConfirm *ChainPriority = ChainPriorityRef(math.MaxInt32)
|
||||||
ChainPriorityLast ChainPriority = math.MaxInt32
|
ChainPriorityLast *ChainPriority = ChainPriorityRef(math.MaxInt32)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ChainPriorityRef returns a pointer to a ChainPriority value.
|
||||||
|
func ChainPriorityRef(p ChainPriority) *ChainPriority {
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
// ChainType defines what this chain will be used for. See also
|
// ChainType defines what this chain will be used for. See also
|
||||||
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_types
|
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_types
|
||||||
type ChainType string
|
type ChainType string
|
||||||
|
@ -87,8 +97,8 @@ const (
|
||||||
type Chain struct {
|
type Chain struct {
|
||||||
Name string
|
Name string
|
||||||
Table *Table
|
Table *Table
|
||||||
Hooknum ChainHook
|
Hooknum *ChainHook
|
||||||
Priority ChainPriority
|
Priority *ChainPriority
|
||||||
Type ChainType
|
Type ChainType
|
||||||
Policy *ChainPolicy
|
Policy *ChainPolicy
|
||||||
}
|
}
|
||||||
|
@ -103,10 +113,10 @@ func (cc *Conn) AddChain(c *Chain) *Chain {
|
||||||
{Type: unix.NFTA_CHAIN_NAME, Data: []byte(c.Name + "\x00")},
|
{Type: unix.NFTA_CHAIN_NAME, Data: []byte(c.Name + "\x00")},
|
||||||
})
|
})
|
||||||
|
|
||||||
if c.Type != "" {
|
if c.Hooknum != nil && c.Priority != nil {
|
||||||
hookAttr := []netlink.Attribute{
|
hookAttr := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_HOOK_HOOKNUM, Data: binaryutil.BigEndian.PutUint32(uint32(c.Hooknum))},
|
{Type: unix.NFTA_HOOK_HOOKNUM, Data: binaryutil.BigEndian.PutUint32(uint32(*c.Hooknum))},
|
||||||
{Type: unix.NFTA_HOOK_PRIORITY, Data: binaryutil.BigEndian.PutUint32(uint32(c.Priority))},
|
{Type: unix.NFTA_HOOK_PRIORITY, Data: binaryutil.BigEndian.PutUint32(uint32(*c.Priority))},
|
||||||
}
|
}
|
||||||
data = append(data, cc.marshalAttr([]netlink.Attribute{
|
data = append(data, cc.marshalAttr([]netlink.Attribute{
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_CHAIN_HOOK, Data: cc.marshalAttr(hookAttr)},
|
{Type: unix.NLA_F_NESTED | unix.NFTA_CHAIN_HOOK, Data: cc.marshalAttr(hookAttr)},
|
||||||
|
@ -249,10 +259,10 @@ func chainFromMsg(msg netlink.Message) (*Chain, error) {
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookFromMsg(b []byte) (ChainHook, ChainPriority, error) {
|
func hookFromMsg(b []byte) (*ChainHook, *ChainPriority, error) {
|
||||||
ad, err := netlink.NewAttributeDecoder(b)
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ad.ByteOrder = binary.BigEndian
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
@ -269,5 +279,5 @@ func hookFromMsg(b []byte) (ChainHook, ChainPriority, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hooknum, prio, nil
|
return &hooknum, &prio, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1143,7 +1143,7 @@ func TestTProxy(t *testing.T) {
|
||||||
Name: "divert",
|
Name: "divert",
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
Hooknum: nftables.ChainHookPrerouting,
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
Priority: -150,
|
Priority: nftables.ChainPriorityRef(-150),
|
||||||
},
|
},
|
||||||
Exprs: []expr.Any{
|
Exprs: []expr.Any{
|
||||||
// [ payload load 1b @ network header + 9 => reg 1 ]
|
// [ payload load 1b @ network header + 9 => reg 1 ]
|
||||||
|
@ -1384,7 +1384,7 @@ func TestAddRuleWithPosition(t *testing.T) {
|
||||||
Name: "ipv4chain-1",
|
Name: "ipv4chain-1",
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
Hooknum: nftables.ChainHookPrerouting,
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
Priority: 0,
|
Priority: nftables.ChainPriorityRef(0),
|
||||||
},
|
},
|
||||||
|
|
||||||
Exprs: []expr.Any{
|
Exprs: []expr.Any{
|
||||||
|
@ -1523,8 +1523,8 @@ func TestListChains(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "undef",
|
Name: "undef",
|
||||||
Hooknum: 0,
|
Hooknum: nil,
|
||||||
Priority: 0,
|
Priority: nil,
|
||||||
Policy: nil,
|
Policy: nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1564,8 +1564,16 @@ func TestListChains(t *testing.T) {
|
||||||
|
|
||||||
for i, chain := range chains {
|
for i, chain := range chains {
|
||||||
validate(chain.Name, want[i].Name, "name", i)
|
validate(chain.Name, want[i].Name, "name", i)
|
||||||
validate(chain.Hooknum, want[i].Hooknum, "hooknum", i)
|
if want[i].Hooknum != nil && chain.Hooknum != nil {
|
||||||
validate(chain.Priority, want[i].Priority, "priority", i)
|
validate(*chain.Hooknum, *want[i].Hooknum, "hooknum value", i)
|
||||||
|
} else {
|
||||||
|
validate(chain.Hooknum, want[i].Hooknum, "hooknum pointer", i)
|
||||||
|
}
|
||||||
|
if want[i].Priority != nil && chain.Priority != nil {
|
||||||
|
validate(*chain.Priority, *want[i].Priority, "priority value", i)
|
||||||
|
} else {
|
||||||
|
validate(chain.Priority, want[i].Priority, "priority pointer", i)
|
||||||
|
}
|
||||||
validate(chain.Type, want[i].Type, "type", i)
|
validate(chain.Type, want[i].Type, "type", i)
|
||||||
|
|
||||||
if want[i].Policy != nil && chain.Policy != nil {
|
if want[i].Policy != nil && chain.Policy != nil {
|
||||||
|
@ -1588,7 +1596,7 @@ func TestAddChain(t *testing.T) {
|
||||||
chain: &nftables.Chain{
|
chain: &nftables.Chain{
|
||||||
Name: "base-chain",
|
Name: "base-chain",
|
||||||
Hooknum: nftables.ChainHookPrerouting,
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
Priority: 0,
|
Priority: nftables.ChainPriorityRef(0),
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
},
|
},
|
||||||
want: [][]byte{
|
want: [][]byte{
|
||||||
|
@ -1671,7 +1679,7 @@ func TestDelChain(t *testing.T) {
|
||||||
chain: &nftables.Chain{
|
chain: &nftables.Chain{
|
||||||
Name: "base-chain",
|
Name: "base-chain",
|
||||||
Hooknum: nftables.ChainHookPrerouting,
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
Priority: 0,
|
Priority: nftables.ChainPriorityRef(0),
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
},
|
},
|
||||||
want: [][]byte{
|
want: [][]byte{
|
||||||
|
@ -3425,7 +3433,7 @@ func TestDynsetWithOneExpression(t *testing.T) {
|
||||||
Name: "forward",
|
Name: "forward",
|
||||||
Hooknum: nftables.ChainHookForward,
|
Hooknum: nftables.ChainHookForward,
|
||||||
Table: table,
|
Table: table,
|
||||||
Priority: 0,
|
Priority: nftables.ChainPriorityRef(0),
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
}
|
}
|
||||||
set := &nftables.Set{
|
set := &nftables.Set{
|
||||||
|
@ -3527,7 +3535,7 @@ func TestDynsetWithMultipleExpressions(t *testing.T) {
|
||||||
Name: "forward",
|
Name: "forward",
|
||||||
Hooknum: nftables.ChainHookForward,
|
Hooknum: nftables.ChainHookForward,
|
||||||
Table: table,
|
Table: table,
|
||||||
Priority: 0,
|
Priority: nftables.ChainPriorityRef(0),
|
||||||
Type: nftables.ChainTypeFilter,
|
Type: nftables.ChainTypeFilter,
|
||||||
}
|
}
|
||||||
set := &nftables.Set{
|
set := &nftables.Set{
|
||||||
|
|
Loading…
Reference in New Issue