mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-06 20:10:11 +02:00
79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
package nftables
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/google/nftables"
|
|
"github.com/google/nftables/expr"
|
|
)
|
|
|
|
func (f *Firewall) AcceptIpv6MulticastOutput(_ context.Context, intf string) error {
|
|
f.mutex.Lock()
|
|
defer f.mutex.Unlock()
|
|
|
|
conn, err := nftables.New()
|
|
if err != nil {
|
|
return fmt.Errorf("creating nftables connection: %w", err)
|
|
}
|
|
|
|
table, _, _, outputChain := setupFilterWithBaseChains(conn)
|
|
|
|
const maxExprsLen = 6
|
|
exprs := make([]expr.Any, 0, maxExprsLen)
|
|
|
|
if intf != "" && intf != "*" {
|
|
exprs = append(exprs,
|
|
&expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1},
|
|
&expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte(intf + "\x00")},
|
|
)
|
|
}
|
|
|
|
// ff02::1:ff00:0/104 mask is 13 bytes of 0xff
|
|
mask := []byte{
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
|
} //nolint:mnd
|
|
addr := []byte{
|
|
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00,
|
|
} //nolint:mnd
|
|
|
|
exprs = append(exprs,
|
|
&expr.Payload{
|
|
DestRegister: 1,
|
|
Base: expr.PayloadBaseNetworkHeader,
|
|
Offset: 24, // IPv6 Destination Address offset //nolint:mnd
|
|
Len: 16, //nolint:mnd
|
|
},
|
|
&expr.Bitwise{
|
|
SourceRegister: 1,
|
|
DestRegister: 1,
|
|
Len: 16, //nolint:mnd
|
|
Mask: mask,
|
|
Xor: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //nolint:mnd
|
|
},
|
|
&expr.Cmp{
|
|
Op: expr.CmpOpEq,
|
|
Register: 1,
|
|
Data: addr,
|
|
},
|
|
&expr.Verdict{Kind: expr.VerdictAccept},
|
|
)
|
|
|
|
rule := &nftables.Rule{
|
|
Table: table,
|
|
Chain: outputChain,
|
|
Exprs: exprs,
|
|
}
|
|
|
|
conn.AddRule(rule)
|
|
|
|
err = conn.Flush()
|
|
if err != nil {
|
|
return fmt.Errorf("flushing: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|