Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Userdata in sets always set key to big endian

Open
#123 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
go
Domain
networking

Research direction

Start in set.go around the set marshal at line 386, then compare the emitted NFTA_SET_USERDATA bytes with the nftables and libnftnl userdata enum definitions cited in the issue. Determine how key and data byte order should be represented and identify the existing set API and tests, if any, that need to cover configurable userdata; done means nft displays the intended endianness for the generated set.

Written by the indexing model from the issue text.

Description

There is static userdata inside the set marshal:

	if s.Anonymous || s.Constant || s.Interval {
		tableInfo = append(tableInfo,
			// Semantically useless - kept for binary compatability with nft
			netlink.Attribute{Type: unix.NFTA_SET_USERDATA, Data: []byte("\x00\x04\x02\x00\x00\x00")})
	}

https://github.com/google/nftables/blob/master/set.go#L386

According to nftables code:

static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data)
{
	unsigned char *value = nftnl_udata_get(attr);
	const struct nftnl_udata **tb = data;
	uint8_t type = nftnl_udata_type(attr);
	uint8_t len = nftnl_udata_len(attr);

	switch (type) {
	case NFTNL_UDATA_SET_KEYBYTEORDER:
	case NFTNL_UDATA_SET_DATABYTEORDER:
	case NFTNL_UDATA_SET_MERGE_ELEMENTS:
	case NFTNL_UDATA_SET_DATA_INTERVAL:
		if (len != sizeof(uint32_t))
			return -1;
		break;
	case NFTNL_UDATA_SET_KEY_TYPEOF:
	case NFTNL_UDATA_SET_DATA_TYPEOF:
		if (len < 3)
			return -1;
		break;
	case NFTNL_UDATA_SET_COMMENT:
		if (value[len - 1] != '\0')
			return -1;
		break;
	default:
		return 0;
	}
	tb[type] = attr;
	return 0;
}

https://git.netfilter.org/nftables/tree/src/netlink.c#n715

When i look up the enum in the nft lib i found that keybyteorder and databyteorder are values 0 and 1:

enum nftnl_udata_set_types {
	NFTNL_UDATA_SET_KEYBYTEORDER,
	NFTNL_UDATA_SET_DATABYTEORDER,
	NFTNL_UDATA_SET_MERGE_ELEMENTS,
	NFTNL_UDATA_SET_KEY_TYPEOF,
	NFTNL_UDATA_SET_DATA_TYPEOF,
	NFTNL_UDATA_SET_EXPR,
	NFTNL_UDATA_SET_DATA_INTERVAL,
	NFTNL_UDATA_SET_COMMENT,
	__NFTNL_UDATA_SET_MAX
};

https://git.netfilter.org/libnftnl/tree/include/libnftnl/udata.h#n40

I also found this byteoder enum: http://charette.no-ip.com:81/programming/doxygen/netfilter/datatype_8h.html#aec0612005abb2f2a88c2de638a442cf2

This would set the key data type to be big endian encoded. I can also observe that when i use this example code:

	workerSetElements := make([]nftables.SetElement, len(setElements))
	for i, v := range setElements {
		bs := make([]byte, 4)
		binary.LittleEndian.PutUint32(bs, uint32(i))
		workerSetElements[i] = nftables.SetElement{
			Key:         bs,
			Val:         ip2array(v),
			IntervalEnd: false,
		}
	}

This generates a netlink message like this:

May 17 06:44:01 ip-10-0-1-19 nftables-controller[31154]: nl: send msgs: {Header:{Length:116 Type:unknown(2572) Flags:request|acknowledge|0x400 Sequence:3804372827 PID:31154} Data:[2 0 0 0 12 0 2 0 95 95 109 97 112 37 100 0 8 0 4 0 0 0 0 1 14 0 1 0 115 116 97 116 101 108 101 115 115 0 0 0 60 0 3 128 28 0 1 128 12 0 1 128 8 0 1 0 0 0 0 0 12 0 2 128 8 0 1 0 10 0 1 225 28 0 2 128 12 0 1 128 8 0 1 0 1 0 0 0 12 0 2 128 8 0 1 0 10 0 1 82]}

When i look into how the second key is defined we can see that its correctly little endian: 8 0 1 0 1 0 0 0

Here is the userdata from nftables when i create the same set with it:

|00016|--|00013|        |len |flags| type|
| 00 04 01 00  |        |      data      |
| 00 00 01 04  |        |      data      |
| 02 00 00 00  |        |      data      |

I can observe that it sets key 0 (endianness for key) to 1 (LE) and for key 1 (data) to 2 (BE).

It would be awesome to control userdata in that case so that nft does show the correct output and not display LE uint32 as BE which confuses operations :D

Thanks

Dominant language
Go
Stars
1.4k
Forks
187
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from google/nftables

All issues in google/nftables

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.