Scope DHCP accept rules to IPv4
This commit is contained in:
@@ -129,7 +129,8 @@ func (c *Compiler) compileDHCP(state *FirewallState) {
|
||||
dhcp := func(chain, dir string, ifaceMatch []expr.Any) {
|
||||
state.Rules[chain] = append(state.Rules[chain], ManagedRule{
|
||||
Chain: chain,
|
||||
Exprs: append(append(append(ifaceMatch,
|
||||
Exprs: append(append(append(append(ifaceMatch,
|
||||
matchNFProto(unix.NFPROTO_IPV4)...),
|
||||
matchProtoNum(unix.IPPROTO_UDP)...),
|
||||
matchDPortRange(67, 68)...),
|
||||
&expr.Verdict{Kind: expr.VerdictAccept}),
|
||||
@@ -1536,10 +1537,14 @@ func matchOrigDest(addr string) ([]expr.Any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]expr.Any{
|
||||
return append(matchNFProto(proto), dst...), nil
|
||||
}
|
||||
|
||||
func matchNFProto(proto byte) []expr.Any {
|
||||
return []expr.Any{
|
||||
&expr.Meta{Key: expr.MetaKeyNFPROTO, Register: 1},
|
||||
&expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte{proto}},
|
||||
}, dst...), nil
|
||||
}
|
||||
}
|
||||
|
||||
func matchAddrCIDR(cidr string, isSrc bool) ([]expr.Any, error) {
|
||||
|
||||
@@ -1037,18 +1037,42 @@ func TestCompile_DHCP(t *testing.T) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, want := range []struct{ chain, tag string }{
|
||||
{"input", "dhcp:in:eth0"},
|
||||
{"output", "dhcp:out:eth0"},
|
||||
{"input", "dhcp:in:br0"},
|
||||
{"output", "dhcp:out:br0"},
|
||||
{"forward", "dhcp:fwd:br0"},
|
||||
for _, want := range []struct{ chain, tag, iif, oif string }{
|
||||
{"input", "dhcp:in:eth0", "eth0", ""},
|
||||
{"output", "dhcp:out:eth0", "", "eth0"},
|
||||
{"input", "dhcp:in:br0", "br0", ""},
|
||||
{"output", "dhcp:out:br0", "", "br0"},
|
||||
{"forward", "dhcp:fwd:br0", "br0", "br0"},
|
||||
} {
|
||||
r := find(want.chain, want.tag)
|
||||
if r == nil {
|
||||
t.Errorf("%s: no rule %s", want.chain, want.tag)
|
||||
continue
|
||||
}
|
||||
metas := map[expr.MetaKey][]byte{}
|
||||
for i := 0; i+1 < len(r.Exprs); i++ {
|
||||
if m, ok := r.Exprs[i].(*expr.Meta); ok {
|
||||
if c, ok := r.Exprs[i+1].(*expr.Cmp); ok && c.Op == expr.CmpOpEq {
|
||||
metas[m.Key] = c.Data
|
||||
}
|
||||
}
|
||||
}
|
||||
if got := metas[expr.MetaKeyNFPROTO]; !bytes.Equal(got, []byte{unix.NFPROTO_IPV4}) {
|
||||
t.Errorf("%s: nfproto %v, want ipv4 guard", want.tag, got)
|
||||
}
|
||||
if got := metas[expr.MetaKeyL4PROTO]; !bytes.Equal(got, []byte{unix.IPPROTO_UDP}) {
|
||||
t.Errorf("%s: l4proto %v, want udp", want.tag, got)
|
||||
}
|
||||
for key, name := range map[expr.MetaKey]string{expr.MetaKeyIIFNAME: want.iif, expr.MetaKeyOIFNAME: want.oif} {
|
||||
got, ok := metas[key]
|
||||
if name == "" {
|
||||
if ok {
|
||||
t.Errorf("%s: unexpected meta %v match %q", want.tag, key, got)
|
||||
}
|
||||
} else if string(got) != name+"\x00" {
|
||||
t.Errorf("%s: meta %v %q, want %q", want.tag, key, got, name)
|
||||
}
|
||||
}
|
||||
v, ok := r.Exprs[len(r.Exprs)-1].(*expr.Verdict)
|
||||
if !ok || v.Kind != expr.VerdictAccept {
|
||||
t.Errorf("%s: last expr %#v, want accept verdict", want.tag, r.Exprs[len(r.Exprs)-1])
|
||||
|
||||
Reference in New Issue
Block a user