# Copyright 2017 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

# AF_NETLINK/NETLINK_NETFILTER support.

include <linux/net.h>
include <uapi/linux/netlink.h>
include <uapi/linux/netfilter.h>
include <uapi/linux/netfilter/nfnetlink.h>

resource sock_nl_netfilter[sock_netlink]

socket$nl_netfilter(domain const[AF_NETLINK], type const[SOCK_RAW], proto const[NETLINK_NETFILTER]) sock_nl_netfilter

sendmsg$nl_netfilter(fd sock_nl_netfilter, msg ptr[in, msghdr_nl_netfilter], f flags[send_flags])

type msghdr_nl_netfilter msghdr_netlink[netlink_msg_netfilter]

netlink_msg_netfilter {
	len	len[parent, int32]
	type	int8[0:20]
	subsys	flags[nfnl_subsys, int8]
	flags	flags[netlink_netfilter_msg_flags, int16]
	seq	netlink_seq
	pid	netlink_port_id
	hdr	nfgenmsg
# No body. Generic attribute can represent a random body.
	attrs	array[nl_generic_attr]
} [align[4]]

type netlink_msg_netfilter_t[SUBSYS, CMD, POLICY] netlink_msg_netfilter_tt[SUBSYS, CMD, array[POLICY]]

type netlink_msg_netfilter_tt[SUBSYS, CMD, POLICY] {
	len	len[parent, int32]
	type	const[CMD, int8]
	subsys	const[SUBSYS, int8]
	flags	flags[netlink_netfilter_msg_flags, int16]
	seq	const[0, int32]
	pid	const[0, int32]
	hdr	nfgenmsg
	attrs	POLICY
} [align[4]]

nfgenmsg {
	nfgen_family	flags[nfproto, int8]
	version		const[NFNETLINK_V0, int8]
# res_id seems to mean things like cpu/queue/group number, so prefer small values.
	res_id		int16be[0:10]
} [align[4]]

nfnl_subsys = NFNL_SUBSYS_CTNETLINK, NFNL_SUBSYS_CTNETLINK_EXP, NFNL_SUBSYS_QUEUE, NFNL_SUBSYS_ULOG, NFNL_SUBSYS_OSF, NFNL_SUBSYS_IPSET, NFNL_SUBSYS_ACCT, NFNL_SUBSYS_CTNETLINK_TIMEOUT, NFNL_SUBSYS_CTHELPER, NFNL_SUBSYS_NFTABLES, NFNL_SUBSYS_NFT_COMPAT
nfproto = NFPROTO_UNSPEC, NFPROTO_INET, NFPROTO_IPV4, NFPROTO_ARP, NFPROTO_NETDEV, NFPROTO_BRIDGE, NFPROTO_IPV6

# We always need to send NLM_F_REQUEST and some netlink flags are not used.
netlink_netfilter_msg_flags = NLM_F_ACK_REQUEST, NLM_F_APPEND_REQUEST, NLM_F_CREATE_REQUEST, NLM_F_DUMP_REQUEST, NLM_F_EXCL_REQUEST, NLM_F_EXCL_REQUEST, NLM_F_MULTI_REQUEST, NLM_F_NONREC_REQUEST, NLM_F_REPLACE_REQUEST

define NLM_F_ACK_REQUEST	NLM_F_ACK | NLM_F_REQUEST
define NLM_F_APPEND_REQUEST	NLM_F_APPEND | NLM_F_REQUEST
define NLM_F_CREATE_REQUEST	NLM_F_CREATE | NLM_F_REQUEST
define NLM_F_DUMP_REQUEST	NLM_F_DUMP | NLM_F_REQUEST
define NLM_F_EXCL_REQUEST	NLM_F_EXCL | NLM_F_REQUEST
define NLM_F_MULTI_REQUEST	NLM_F_MULTI | NLM_F_REQUEST
define NLM_F_NONREC_REQUEST	NLM_F_NONREC | NLM_F_REQUEST
define NLM_F_REPLACE_REQUEST	NLM_F_REPLACE | NLM_F_REQUEST
