question: Rule to string representation an reverse
Closed this issue · 2 comments
greenpau commented
All, and @rwhelan , @sbezverk,
In a nutshell, I want to validate the existence of the following nftables
rule:
oifname "cni-podman0" ip daddr 192.168.124.0/24 ct state established,related counter packets 108 bytes 125682 accept # handle 71
The Rule
object looks like this:
(*nftables.Rule)(0xc000140780)({
Table: (*nftables.Table)(0xc0001cd660)({
Name: (string) (len=6) "filter",
Use: (uint32) 0,
Flags: (uint32) 0,
Family: (nftables.TableFamily) 0
}),
Chain: (*nftables.Chain)(0xc0001d0580)({
Name: (string) (len=7) "FORWARD",
Table: (*nftables.Table)(<nil>),
Hooknum: (nftables.ChainHook) 0,
Priority: (nftables.ChainPriority) 0,
Type: (nftables.ChainType) "",
Policy: (*nftables.ChainPolicy)(<nil>)
}),
Position: (uint64) 0,
Handle: (uint64) 71,
Exprs: ([]expr.Any) (len=9 cap=16) {
(*expr.Meta)(0xc0001c4ad0)({
Key: (expr.MetaKey) 7,
SourceRegister: (bool) false,
Register: (uint32) 1
}),
(*expr.Cmp)(0xc0001cd760)({
Op: (expr.CmpOp) 0,
Register: (uint32) 1,
Data: ([]uint8) (len=16 cap=16) {
0000000063 6e 69 2d 70 6f 64 6d61 6e 30 00 00 00 00 00|cni-podman0.....|
}
}),
(*expr.Payload)(0xc00012c270)({
OperationType: (expr.PayloadOperationType) 0,
DestRegister: (uint32) 1,
SourceRegister: (uint32) 0,
Base: (expr.PayloadBase) 1,
Offset: (uint32) 16,
Len: (uint32) 4,
CsumType: (expr.PayloadCsumType) 0,
CsumOffset: (uint32) 0,
CsumFlags: (uint32) 0
}),
(*expr.Bitwise)(0xc0001d0a40)({
SourceRegister: (uint32) 1,
DestRegister: (uint32) 1,
Len: (uint32) 4,
Mask: ([]uint8) (len=4 cap=4) {
00000000ff ff ff 00 |....|
},
Xor: ([]uint8) (len=4 cap=4) {
0000000000 00 00 00 |....|
}
}),
(*expr.Cmp)(0xc0001cd920)({
Op: (expr.CmpOp) 0,
Register: (uint32) 1,
Data: ([]uint8) (len=4 cap=4) {
00000000c0 a8 7c 00 |..|.|
}
}),
(*expr.Bitwise)(0xc0001d0dc0)({
SourceRegister: (uint32) 1,
DestRegister: (uint32) 1,
Len: (uint32) 4,
Mask: ([]uint8) (len=4 cap=4) {
0000000006 00 00 00 |....|
},
Xor: ([]uint8) (len=4 cap=4) {
0000000000 00 00 00 |....|
}
}),
(*expr.Cmp)(0xc0001cdaa0)({
Op: (expr.CmpOp) 1,
Register: (uint32) 1,
Data: ([]uint8) (len=4 cap=4) {
0000000000 00 00 00 |....|
}
}),
(*expr.Counter)(0xc0001c4c10)({
Bytes: (uint64) 125682,
Packets: (uint64) 108
}),
(*expr.Verdict)(0xc0001cdc00)({
Kind: (expr.VerdictKind) 1,
Chain: (string) ""
})
},
UserData: ([]uint8) <nil>
})
Is there a way to convert Rule
struct to text representation (i.e. the output of nft list chain ip filter FORWARD -a
? I did not find an existing method to do so for the Rule
.
greenpau commented
Relevant issue: sbezverk/nftableslib#56
greenpau commented
Here is how to add he above rule in Go:
// Add rule for inbound traffic
// nft add rule oifname "dummy0" ip daddr 192.168.100.100 ct state established,related counter packets 0 bytes 0 accept
inboundInterfaceRule := &nftables.Rule{
Table: addr.table,
Chain: chain,
Exprs: []expr.Any{},
}
// meta load oifname => reg 1
// cmp eq reg 1 0x6d6d7564 0x00003079 0x00000000 0x00000000
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Meta{
Key: expr.MetaKeyOIFNAME,
Register: 1,
})
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: getNftInterfaceName(intfName),
})
if addr.conf.Version == "6" {
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseNetworkHeader,
Offset: 64,
Len: 16,
})
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: addr.conf.Address.IP.To16(),
})
} else {
// payload load 4b @ network header + 16 => reg 1
// cmp eq reg 1 0x6464a8c0 ]
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseNetworkHeader,
Offset: 16,
Len: 4,
})
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: addr.conf.Address.IP.To4(),
})
}
// ct load state => reg 1 ]
// bitwise reg 1 = (reg=1 & 0x00000006 ) ^ 0x00000000
// cmp neq reg 1 0x00000000
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Ct{
Register: 1,
Key: expr.CtKeySTATE,
})
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Bitwise{
SourceRegister: 1,
DestRegister: 1,
Xor: []byte{0x0, 0x0, 0x0, 0x0},
Mask: []byte("\x06\x00\x00\x00"),
Len: 4,
})
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Cmp{
Op: expr.CmpOpNeq,
Register: 1,
Data: []byte{0x0, 0x0, 0x0, 0x0},
})
// counter pkts 0 bytes 0
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Counter{})
// immediate reg 0 accept
inboundInterfaceRule.Exprs = append(inboundInterfaceRule.Exprs, &expr.Verdict{
Kind: expr.VerdictAccept,
})
nb.conn.AddRule(inboundInterfaceRule)
if err := nb.conn.Flush(); err != nil {
return fmt.Errorf(
"failed adding outbound traffic rule in table %s chain %s for address %v of interface %s",
addr.table.Name, chainName, addr.conf, intfName,
)
}