From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Sun, 10 Nov 2024 19:35:52 +0100
Subject: batctl: Add noflood_mark command

Adds support for the new 'noflood_mark' setting in batman-adv.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>

diff --git a/batctl/patches/2002-batctl-Add-noflood_mark-command.patch b/batctl/patches/2002-batctl-Add-noflood_mark-command.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d4498603785a21a71951a6195cd96661be44d685
--- /dev/null
+++ b/batctl/patches/2002-batctl-Add-noflood_mark-command.patch
@@ -0,0 +1,217 @@
+From 12884631753aa24d9e36c5d65950320ecab61384 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Fri, 26 Apr 2019 19:27:38 +0200
+Subject: [PATCH] batctl: Add noflood_mark command
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Adds support for the new 'noflood_mark' setting in batman-adv.
+
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+---
+ Makefile       |   1 +
+ README.rst     |  15 ++++++
+ batman_adv.h   |  12 +++++
+ noflood_mark.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 168 insertions(+)
+ create mode 100644 noflood_mark.c
+
+--- a/Makefile
++++ b/Makefile
+@@ -69,6 +69,7 @@ $(eval $(call add_command,multicast_mode
+ $(eval $(call add_command,neighbors,y))
+ $(eval $(call add_command,neighbors_json,y))
+ $(eval $(call add_command,network_coding,y))
++$(eval $(call add_command,noflood_mark,y))
+ $(eval $(call add_command,orig_interval,y))
+ $(eval $(call add_command,originators,y))
+ $(eval $(call add_command,originators_json,y))
+--- a/README.rst
++++ b/README.rst
+@@ -430,6 +430,21 @@ Example::
+ 
+ 
+ 
++batctl noflood_mark
++=======================
++
++display or modify noflood_mark setting
++
++Usage::
++
++  batctl noflood_mark|nf $value[/0x$mask]
++
++* Example 1: ``batctl nf 0x00000001/0xffffffff``
++* Example 2: ``batctl nf 0x00040000/0xffff0000``
++* Example 3: ``batctl nf 16``
++* Example 4: ``batctl nf 0x0f``
++
++
+ batctl translocal
+ -----------------
+ 
+--- a/batman_adv.h
++++ b/batman_adv.h
+@@ -481,6 +481,18 @@ enum batadv_nl_attrs {
+ 	 */
+ 	BATADV_ATTR_MULTICAST_FANOUT,
+ 
++	/**
++	 * @BATADV_ATTR_NOFLOOD_MARK: the noflood mark which allows to tag
++	 *  frames which should never be broadcast flooded through the mesh.
++	 */
++	BATADV_ATTR_NOFLOOD_MARK,
++
++	/**
++	 * @BATADV_ATTR_NOFLOOD_MASK: the noflood (bit)mask which allows to tag
++	 *  frames which should never be broadcast flooded through the mesh.
++	 */
++	BATADV_ATTR_NOFLOOD_MASK,
++
+ 	/* add attributes above here, update the policy in netlink.c */
+ 
+ 	/**
+--- /dev/null
++++ b/noflood_mark.c
+@@ -0,0 +1,140 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2009-2019  B.A.T.M.A.N. contributors:
++ *
++ * Antonio Quartulli <a@unstable.cc>
++ * Linus Lüssing <linus.luessing@c0d3.blue>
++ *
++ * License-Filename: LICENSES/preferred/GPL-2.0
++ */
++
++#include <errno.h>
++#include <stddef.h>
++#include <stdint.h>
++#include <string.h>
++
++#include "main.h"
++#include "sys.h"
++
++static struct noflood_mark_data {
++	uint32_t noflood_mark;
++	uint32_t noflood_mask;
++} noflood_mark;
++
++static int parse_noflood_mark(struct state *state, int argc, char *argv[])
++{
++	struct settings_data *settings = state->cmd->arg;
++	struct noflood_mark_data *data = settings->data;
++	char *mask_ptr;
++	char buff[256];
++	uint32_t mark;
++	uint32_t mask;
++	char *endptr;
++
++	if (argc != 2) {
++		fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
++		return -EINVAL;
++	}
++
++	strncpy(buff, argv[1], sizeof(buff));
++	buff[sizeof(buff) - 1] = '\0';
++
++	/* parse the mask if it has been specified, otherwise assume the mask is
++	 * the biggest possible
++	 */
++	mask = 0xFFFFFFFF;
++	mask_ptr = strchr(buff, '/');
++	if (mask_ptr) {
++		*mask_ptr = '\0';
++		mask_ptr++;
++
++		/* the mask must be entered in hex base as it is going to be a
++		 * bitmask and not a prefix length
++		 */
++		mask = strtoul(mask_ptr, &endptr, 16);
++		if (!endptr || *endptr != '\0')
++			goto inval_format;
++	}
++
++	/* the mark can be entered in any base */
++	mark = strtoul(buff, &endptr, 0);
++	if (!endptr || *endptr != '\0')
++		goto inval_format;
++
++	data->noflood_mask = mask;
++	/* erase bits not covered by the mask */
++	data->noflood_mark = mark & mask;
++
++	return 0;
++
++inval_format:
++	fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
++	fprintf(stderr, "The following formats for mark(/mask) are allowed:\n");
++	fprintf(stderr, " * 0x12345678\n");
++	fprintf(stderr, " * 0x12345678/0xabcdef09\n");
++	return -EINVAL;
++}
++
++static int print_noflood_mark(struct nl_msg *msg, void *arg)
++{
++	struct nlattr *attrs[BATADV_ATTR_MAX + 1];
++	struct nlmsghdr *nlh = nlmsg_hdr(msg);
++	struct genlmsghdr *ghdr;
++	int *result = arg;
++
++	if (!genlmsg_valid_hdr(nlh, 0))
++		return NL_OK;
++
++	ghdr = nlmsg_data(nlh);
++
++	if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
++		      genlmsg_len(ghdr), batadv_netlink_policy)) {
++		return NL_OK;
++	}
++
++	if (!attrs[BATADV_ATTR_NOFLOOD_MARK] ||
++	    !attrs[BATADV_ATTR_NOFLOOD_MASK])
++		return NL_OK;
++
++	printf("0x%08x/0x%08x\n",
++	       nla_get_u32(attrs[BATADV_ATTR_NOFLOOD_MARK]),
++	       nla_get_u32(attrs[BATADV_ATTR_NOFLOOD_MASK]));
++
++	*result = 0;
++	return NL_STOP;
++}
++
++static int get_noflood_mark(struct state *state)
++{
++	return sys_simple_nlquery(state, BATADV_CMD_GET_MESH,
++				  NULL, print_noflood_mark);
++}
++
++static int set_attrs_noflood_mark(struct nl_msg *msg, void *arg)
++{
++	struct state *state = arg;
++	struct settings_data *settings = state->cmd->arg;
++	struct noflood_mark_data *data = settings->data;
++
++	nla_put_u32(msg, BATADV_ATTR_NOFLOOD_MARK, data->noflood_mark);
++	nla_put_u32(msg, BATADV_ATTR_NOFLOOD_MASK, data->noflood_mask);
++
++	return 0;
++}
++
++static int set_noflood_mark(struct state *state)
++{
++	return sys_simple_nlquery(state, BATADV_CMD_SET_MESH,
++				  set_attrs_noflood_mark, NULL);
++}
++
++static struct settings_data batctl_settings_noflood_mark = {
++	.data = &noflood_mark,
++	.parse = parse_noflood_mark,
++	.netlink_get = get_noflood_mark,
++	.netlink_set = set_noflood_mark,
++};
++
++COMMAND_NAMED(SUBCOMMAND, noflood_mark, "nf", handle_sys_setting,
++	      COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
++	      &batctl_settings_noflood_mark,
++	      "[mark]            \tdisplay or modify noflood_mark setting");
