Skip to content

Commit c822ed7

Browse files
chent1996aboch
authored andcommitted
ipset: fix bitmap:port entry add failing with invalid protocol
buildEntryData() unconditionally sends IPSET_ATTR_PROTO (defaulting to TCP) whenever Port is set. For bitmap:port ipsets, this protocol attribute is not expected and newer kernels reject it with "invalid protocol". Decouple Protocol and Port attributes: only send IPSET_ATTR_PROTO when entry.Protocol is explicitly set. This matches the behavior of the ipset CLI tool, which does not send protocol for bitmap:port. Note: callers using hash:ip,port or hash:net,port,net must now explicitly set entry.Protocol, as the implicit TCP default is removed. Also add a bitmap:port test case to TestIpsetCreateListAddDelDestroy and fix the port/protocol assertion to handle nil Protocol. Fixes #1054
1 parent 188504c commit c822ed7

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

ipset_linux.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,11 @@ func buildEntryData(entry *IPSetEntry) (*nl.RtAttr, error) {
303303
data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_CIDR2, nl.Uint8Attr(entry.CIDR2)))
304304
}
305305

306-
if entry.Port != nil {
307-
if entry.Protocol == nil {
308-
// use tcp protocol as default
309-
val := uint8(unix.IPPROTO_TCP)
310-
entry.Protocol = &val
311-
}
306+
if entry.Protocol != nil {
312307
data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PROTO, nl.Uint8Attr(*entry.Protocol)))
308+
}
309+
310+
if entry.Port != nil {
313311
buf := make([]byte, 2)
314312
binary.BigEndian.PutUint16(buf, *entry.Port)
315313
data.AddChild(nl.NewRtAttr(int(nl.IPSET_ATTR_PORT|nl.NLA_F_NET_BYTEORDER), buf))

ipset_linux_test.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,21 @@ func TestIpsetCreateListAddDelDestroyWithTestCases(t *testing.T) {
439439
Replace: false,
440440
},
441441
},
442+
{
443+
desc: "Type-bitmap:port",
444+
setname: "my-test-ipset-bitmap-port",
445+
typename: "bitmap:port",
446+
options: IpsetCreateOptions{
447+
Replace: true,
448+
Timeout: &timeout,
449+
PortFrom: 0,
450+
PortTo: 1024,
451+
},
452+
entry: &IPSetEntry{
453+
Port: &port,
454+
Replace: false,
455+
},
456+
},
442457
}
443458

444459
for _, tC := range testCases {
@@ -517,14 +532,17 @@ func TestIpsetCreateListAddDelDestroyWithTestCases(t *testing.T) {
517532
}
518533

519534
if tC.entry.Port != nil {
520-
if *result.Entries[0].Protocol != *tC.entry.Protocol {
521-
t.Fatalf("expected protocol to be '%d', got '%d'", *tC.entry.Protocol, *result.Entries[0].Protocol)
522-
}
523535
if *result.Entries[0].Port != *tC.entry.Port {
524536
t.Fatalf("expected port to be '%d', got '%d'", *tC.entry.Port, *result.Entries[0].Port)
525537
}
526538
}
527539

540+
if tC.entry.Protocol != nil {
541+
if result.Entries[0].Protocol == nil || *result.Entries[0].Protocol != *tC.entry.Protocol {
542+
t.Fatalf("expected protocol to be '%d', got '%v'", *tC.entry.Protocol, result.Entries[0].Protocol)
543+
}
544+
}
545+
528546
if tC.entry.MAC != nil {
529547
if result.Entries[0].MAC.String() != tC.entry.MAC.String() {
530548
t.Fatalf("expected mac to be '%v', got '%v'", tC.entry.MAC, result.Entries[0].MAC)

0 commit comments

Comments
 (0)