Netdev List
 help / color / mirror / Atom feed
* [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters
@ 2026-06-01 14:32 Fernando Fernandez Mancera
  2026-06-02 19:36 ` David Ahern
  0 siblings, 1 reply; 4+ messages in thread
From: Fernando Fernandez Mancera @ 2026-06-01 14:32 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, davem, kuba, pabeni, Fernando Fernandez Mancera

Currently, modifying IPv4 interface configuration parameters requires
interacting with sysctl (/proc/sys/net/ipv4/conf/*). While
ip-netconf exists for monitoring these values, there has been no native
way to set them directly through iproute2.

This patch introduces the support for that via 'inet' at the 'ip link
set'. It uses IFLA_INET_CONF netlink attribute to set the parameter.

Example to enable forwarding on an interface:

ip link set dev enp8s0 inet forwarding on

Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
 ip/iplink.c           | 354 ++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip-link.8.in |  81 ++++++++++
 2 files changed, 435 insertions(+)

diff --git a/ip/iplink.c b/ip/iplink.c
index 2c052d29..38bdc71f 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -19,6 +19,7 @@
 #include <arpa/inet.h>
 #include <linux/if.h>
 #include <linux/if_ether.h>
+#include <linux/ip.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -102,6 +103,23 @@ void iplink_usage(void)
 		"		[ master DEVICE ][ vrf NAME ]\n"
 		"		[ nomaster ]\n"
 		"		[ addrgenmode { eui64 | none | stable_secret | random } ]\n"
+		"		[ inet [ { forwarding | proxy_arp | accept_redirects |\n"
+		"			   secure_redirects | send_redirects | shared_media |\n"
+		"			   accept_source_route | bootp_relay | log_martians |\n"
+		"			   arp_filter | disable_xfrm | disable_policy |\n"
+		"			   promote_secondaries | arp_notify | accept_local |\n"
+		"			   src_vmark | proxy_arp_pvlan | route_localnet |\n"
+		"			   bc_forwarding | ignore_routes_with_linkdown |\n"
+		"			   drop_unicast_in_l2_multicast |\n"
+		"			   drop_gratuitous_arp | arp_evict_nocarrier } { on | off } ]\n"
+		"		       [ rp_filter { 0 | 1 | 2 } ]\n"
+		"		       [ arp_announce { 0 | 1 | 2 } ]\n"
+		"		       [ arp_ignore { 0 | 1 | ... | 8 } ]\n"
+		"		       [ arp_accept { 0 | 1 | 2 } ]\n"
+		"		       [ force_igmp_version { 0 | 1 | 2 | 3 } ]\n"
+		"		       [ tag TAG ] [ medium_id ID ]\n"
+		"		       [ igmpv2_unsolicited_report_interval INTERVAL ]\n"
+		"		       [ igmpv3_unsolicited_report_interval INTERVAL ] ]\n"
 		"		[ protodown { on | off } ]\n"
 		"		[ protodown_reason PREASON { on | off } ]\n"
 		"		[ gso_max_size BYTES ] [ gso_ipv4_max_size BYTES ] [ gso_max_segs PACKETS ]\n"
@@ -551,6 +569,339 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
 	return 0;
 }
 
+static int iplink_parse_inet(int *argcp, char ***argvp, struct iplink_req *req)
+{
+	struct rtattr *afs, *afinet, *inet_devconf;
+	char **argv = *argvp;
+	int argc = *argcp;
+	int ret;
+
+	afs = addattr_nest(&req->n, sizeof(*req), IFLA_AF_SPEC);
+	afinet = addattr_nest(&req->n, sizeof(*req), AF_INET);
+	inet_devconf = addattr_nest(&req->n, sizeof(*req), IFLA_INET_CONF);
+
+	while (NEXT_ARG_OK()) {
+		NEXT_ARG();
+		if (matches(*argv, "forwarding") == 0) {
+			int forwarding;
+
+			NEXT_ARG();
+			forwarding = parse_on_off("forwarding", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_FORWARDING, forwarding);
+		} else if (matches(*argv, "proxy_arp") == 0) {
+			int proxy_arp;
+
+			NEXT_ARG();
+			proxy_arp = parse_on_off("proxy_arp", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_PROXY_ARP, proxy_arp);
+		} else if (matches(*argv, "accept_redirects") == 0) {
+			int accept_redirects;
+
+			NEXT_ARG();
+			accept_redirects = parse_on_off("accept_redirects", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ACCEPT_REDIRECTS, accept_redirects);
+		} else if (matches(*argv, "secure_redirects") == 0) {
+			int secure_redirects;
+
+			NEXT_ARG();
+			secure_redirects = parse_on_off("secure_redirects", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_SECURE_REDIRECTS, secure_redirects);
+		} else if (matches(*argv, "send_redirects") == 0) {
+			int send_redirects;
+
+			NEXT_ARG();
+			send_redirects = parse_on_off("send_redirects", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_SEND_REDIRECTS, send_redirects);
+		} else if (matches(*argv, "shared_media") == 0) {
+			int shared_media;
+
+			NEXT_ARG();
+			shared_media = parse_on_off("shared_media", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_SHARED_MEDIA, shared_media);
+		} else if (matches(*argv, "rp_filter") == 0) {
+			int rp_filter;
+
+			NEXT_ARG();
+			if (get_integer(&rp_filter, *argv, 0)) {
+				invarg("Invalid \"rp_filter\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_RP_FILTER, rp_filter);
+		} else if (matches(*argv, "accept_source_route") == 0) {
+			int accept_source_route;
+
+			NEXT_ARG();
+			accept_source_route = parse_on_off("accept_source_route", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route);
+		} else if (matches(*argv, "bootp_relay") == 0) {
+			int bootp_relay;
+
+			NEXT_ARG();
+			bootp_relay = parse_on_off("bootp_relay", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_BOOTP_RELAY, bootp_relay);
+		} else if (matches(*argv, "log_martians") == 0) {
+			int log_martians;
+
+			NEXT_ARG();
+			log_martians = parse_on_off("log_martians", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_LOG_MARTIANS, log_martians);
+		} else if (matches(*argv, "tag") == 0) {
+			int tag;
+
+			NEXT_ARG();
+			if (get_integer(&tag, *argv, 0)) {
+				invarg("Invalid \"tag\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_TAG, tag);
+		} else if (matches(*argv, "arp_filter") == 0) {
+			int arp_filter;
+
+			NEXT_ARG();
+			arp_filter = parse_on_off("arp_filter", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARPFILTER, arp_filter);
+		} else if (matches(*argv, "medium_id") == 0) {
+			int medium_id;
+
+			NEXT_ARG();
+			if (get_integer(&medium_id, *argv, 0)) {
+				invarg("Invalid \"medium_id\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_MEDIUM_ID, medium_id);
+		} else if (matches(*argv, "disable_xfrm") == 0) {
+			int disable_xfrm;
+
+			NEXT_ARG();
+			disable_xfrm = parse_on_off("disable_xfrm", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_NOXFRM, disable_xfrm);
+		} else if (matches(*argv, "disable_policy") == 0) {
+			int disable_policy;
+
+			NEXT_ARG();
+			disable_policy = parse_on_off("disable_policy", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_NOPOLICY, disable_policy);
+		} else if (matches(*argv, "force_igmp_version") == 0) {
+			int force_igmp_version;
+
+			NEXT_ARG();
+			if (get_integer(&force_igmp_version, *argv, 0)) {
+				invarg("Invalid \"force_igmp_version\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_FORCE_IGMP_VERSION, force_igmp_version);
+		} else if (matches(*argv, "arp_announce") == 0) {
+			int arp_announce;
+
+			NEXT_ARG();
+			if (get_integer(&arp_announce, *argv, 0)) {
+				invarg("Invalid \"arp_announce\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARP_ANNOUNCE, arp_announce);
+		} else if (matches(*argv, "arp_ignore") == 0) {
+			int arp_ignore;
+
+			NEXT_ARG();
+			if (get_integer(&arp_ignore, *argv, 0)) {
+				invarg("Invalid \"arp_ignore\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARP_IGNORE, arp_ignore);
+		} else if (matches(*argv, "promote_secondaries") == 0) {
+			int promote_secondaries;
+
+			NEXT_ARG();
+			promote_secondaries = parse_on_off("promote_secondaries", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_PROMOTE_SECONDARIES, promote_secondaries);
+		} else if (matches(*argv, "arp_accept") == 0) {
+			int arp_accept;
+
+			NEXT_ARG();
+			if (get_integer(&arp_accept, *argv, 0)) {
+				invarg("Invalid \"arp_accept\" value\n", *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARP_ACCEPT, arp_accept);
+		} else if (matches(*argv, "arp_notify") == 0) {
+			int arp_notify;
+
+			NEXT_ARG();
+			arp_notify = parse_on_off("arp_notify", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARP_NOTIFY, arp_notify);
+		} else if (matches(*argv, "accept_local") == 0) {
+			int accept_local;
+
+			NEXT_ARG();
+			accept_local = parse_on_off("accept_local", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ACCEPT_LOCAL, accept_local);
+		} else if (matches(*argv, "src_vmark") == 0) {
+			int src_vmark;
+
+			NEXT_ARG();
+			src_vmark = parse_on_off("src_vmark", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_SRC_VMARK, src_vmark);
+		} else if (matches(*argv, "proxy_arp_pvlan") == 0) {
+			int proxy_arp_pvlan;
+
+			NEXT_ARG();
+			proxy_arp_pvlan = parse_on_off("proxy_arp_pvlan", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_PROXY_ARP_PVLAN, proxy_arp_pvlan);
+		} else if (matches(*argv, "route_localnet") == 0) {
+			int route_localnet;
+
+			NEXT_ARG();
+			route_localnet = parse_on_off("route_localnet", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ROUTE_LOCALNET, route_localnet);
+		} else if (matches(*argv, "bc_forwarding") == 0) {
+			int bc_forwarding;
+
+			NEXT_ARG();
+			bc_forwarding = parse_on_off("bc_forwarding", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_BC_FORWARDING, bc_forwarding);
+		} else if (matches(*argv, "igmpv2_unsolicited_report_interval") == 0) {
+			int igmpv2_interval;
+
+			NEXT_ARG();
+			if (get_integer(&igmpv2_interval, *argv, 0)) {
+				invarg("Invalid \"igmpv2_unsolicited_report_interval\" value\n",
+				       *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, igmpv2_interval);
+		} else if (matches(*argv, "igmpv3_unsolicited_report_interval") == 0) {
+			int igmpv3_interval;
+
+			NEXT_ARG();
+			if (get_integer(&igmpv3_interval, *argv, 0)) {
+				invarg("Invalid \"igmpv3_unsolicited_report_interval\" value\n",
+				       *argv);
+				return -1;
+			}
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, igmpv3_interval);
+		} else if (matches(*argv, "ignore_routes_with_linkdown") == 0) {
+			int ignore_routes_linkdown;
+
+			NEXT_ARG();
+			ignore_routes_linkdown = parse_on_off("ignore_routes_with_linkdown",
+							      *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, ignore_routes_linkdown);
+		} else if (matches(*argv, "drop_unicast_in_l2_multicast") == 0) {
+			int drop_unicast_mcast;
+
+			NEXT_ARG();
+			drop_unicast_mcast = parse_on_off("drop_unicast_in_l2_multicast",
+							  *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, drop_unicast_mcast);
+		} else if (matches(*argv, "drop_gratuitous_arp") == 0) {
+			int drop_gratuitous_arp;
+
+			NEXT_ARG();
+			drop_gratuitous_arp = parse_on_off("drop_gratuitous_arp", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_DROP_GRATUITOUS_ARP, drop_gratuitous_arp);
+		} else if (matches(*argv, "arp_evict_nocarrier") == 0) {
+			int arp_evict_nocarrier;
+
+			NEXT_ARG();
+			arp_evict_nocarrier = parse_on_off("arp_evict_nocarrier", *argv, &ret);
+			if (ret)
+				return ret;
+			addattr32(&req->n, sizeof(*req),
+				  IPV4_DEVCONF_ARP_EVICT_NOCARRIER, arp_evict_nocarrier);
+		} else {
+			/* rewind arg */
+			PREV_ARG();
+			break;
+		}
+	}
+
+	if (argc == *argcp)
+		incomplete_command();
+
+	addattr_nest_end(&req->n, inet_devconf);
+	addattr_nest_end(&req->n, afinet);
+	addattr_nest_end(&req->n, afs);
+
+	*argcp = argc;
+	*argvp = argv;
+	return 0;
+}
+
 int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
 {
 	bool move_netns = false;
@@ -634,6 +985,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
 			if (get_integer(&mtu, *argv, 0))
 				invarg("Invalid \"mtu\" value\n", *argv);
 			addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
+		} else if (strcmp(*argv, "inet") == 0) {
+			if (iplink_parse_inet(&argc, &argv, req) < 0)
+				return -1;
 		} else if (strcmp(*argv, "xdpgeneric") == 0 ||
 			   strcmp(*argv, "xdpdrv") == 0 ||
 			   strcmp(*argv, "xdpoffload") == 0 ||
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index e89b2db3..a55b09fc 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -179,6 +179,43 @@ ip-link \- network device configuration
 .br
 .RB "[ " addrgenmode " { " eui64 " | " none " | " stable_secret " | " random " } ]"
 .br
+.RB "[ " inet " [ { " forwarding " | " proxy_arp " | " accept_redirects " |"
+.br
+.in +8
+.BR secure_redirects " | " send_redirects " | " shared_media " |"
+.br
+.BR accept_source_route " | " bootp_relay " | " log_martians " |"
+.br
+.BR arp_filter " | " disable_xfrm " | " disable_policy " |"
+.br
+.BR promote_secondaries " | " arp_notify " | " accept_local " |"
+.br
+.BR src_vmark " | " proxy_arp_pvlan " | " route_localnet " |"
+.br
+.BR bc_forwarding " | " ignore_routes_with_linkdown " |"
+.br
+.BR drop_unicast_in_l2_multicast " |"
+.br
+.BR drop_gratuitous_arp " | " arp_evict_nocarrier " } { " on " | " off " } ]"
+.br
+.RB "[ " rp_filter " { " 0 " | " 1 " | " 2 " } ]"
+.br
+.RB "[ " arp_announce " { " 0 " | " 1 " | " 2 " } ]"
+.br
+.RB "[ " arp_ignore " { " 0 " | " 1 " | " ... " | " 8 " } ]"
+.br
+.RB "[ " arp_accept " { " 0 " | " 1 " | " 2 " } ]"
+.br
+.RB "[ " force_igmp_version " { " 0 " | " 1 " | " 2 " | " 3 " } ]"
+.br
+.RB "[ " tag " " TAG " ] [ " medium_id " " ID " ]"
+.br
+.RB "[ " igmpv2_unsolicited_report_interval " " INTERVAL " ]"
+.br
+.RB "[ " igmpv3_unsolicited_report_interval " " INTERVAL " ] ]"
+.br
+.in -10
+.br
 .RB "[ " macaddr
 .RI "[ " MACADDR " ]"
 .br
@@ -2617,6 +2654,50 @@ set the IPv6 address generation mode
 .I random
 - like stable_secret, but auto-generate a new random secret if none is set
 
+.TP
+.B inet
+set the IPv4 devconf network parameters for the specific device. These parameters map directly to the kernel's IPv4 interface sysctls.
+
+.in +8
+.BR forwarding " { " on " | " off " }"
+- enable or disable IPv4 forwarding on the device.
+
+.BR proxy_arp ", " accept_redirects ", " secure_redirects ", " send_redirects ", "
+.BR shared_media ", " accept_source_route ", " bootp_relay ", " log_martians ", "
+.BR arp_filter ", " disable_xfrm ", " disable_policy ", " promote_secondaries ", "
+.BR arp_notify ", " accept_local ", " src_vmark ", " proxy_arp_pvlan ", "
+.BR route_localnet ", " bc_forwarding ", " ignore_routes_with_linkdown ", "
+.BR drop_unicast_in_l2_multicast ", " drop_gratuitous_arp ", " arp_evict_nocarrier ", "
+.BR "{ " on " | " off " }"
+- toggle the corresponding boolean network parameter.
+
+.BR rp_filter " { " 0 " | " 1 " | " 2 " }"
+- set reverse path filtering.
+
+.BR arp_announce " { " 0 " | " 1 " | " 2 " }"
+- define different restriction levels for announcing the local source IP address from IP packets in ARP requests.
+
+.BR arp_ignore " { " 0 " | " 1 " | " ... " | " 8 " }"
+- define different modes for replying to ARP requests that resolve local target IP addresses.
+
+.BR arp_accept " { " 0 " | " 1 " | " 2 " }"
+- define behavior for gratuitous ARP frames.
+
+.BR force_igmp_version " { " 0 " | " 1 " | " 2 " | " 3 " }"
+- force IGMP version.
+
+.BI tag " TAG "
+- set the interface tag.
+
+.BI medium_id " ID "
+- set the interface medium ID.
+
+.BI igmpv2_unsolicited_report_interval " INTERVAL "
+.br
+.BI igmpv3_unsolicited_report_interval " INTERVAL "
+- set the IGMP unsolicited report interval in milliseconds.
+.in -8
+
 .TP
 .BR "link-netnsid "
 set peer netnsid for a cross-netns interface
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters
  2026-06-01 14:32 [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters Fernando Fernandez Mancera
@ 2026-06-02 19:36 ` David Ahern
  2026-06-02 19:46   ` Fernando Fernandez Mancera
  0 siblings, 1 reply; 4+ messages in thread
From: David Ahern @ 2026-06-02 19:36 UTC (permalink / raw)
  To: Fernando Fernandez Mancera, netdev
  Cc: stephen, davem, kuba, pabeni, Nicolas Dichtel

On 6/1/26 8:32 AM, Fernando Fernandez Mancera wrote:
> Currently, modifying IPv4 interface configuration parameters requires
> interacting with sysctl (/proc/sys/net/ipv4/conf/*). While
> ip-netconf exists for monitoring these values, there has been no native
> way to set them directly through iproute2.
> 
> This patch introduces the support for that via 'inet' at the 'ip link
> set'. It uses IFLA_INET_CONF netlink attribute to set the parameter.
> 
> Example to enable forwarding on an interface:
> 
> ip link set dev enp8s0 inet forwarding on

If an attribute can be set this way, then ip link show needs to show the
values. What's the plan on that front?

> 
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
> ---
>  ip/iplink.c           | 354 ++++++++++++++++++++++++++++++++++++++++++
>  man/man8/ip-link.8.in |  81 ++++++++++
>  2 files changed, 435 insertions(+)
> 

...

>  		"		[ gso_max_size BYTES ] [ gso_ipv4_max_size BYTES ] [ gso_max_segs PACKETS ]\n"
> @@ -551,6 +569,339 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
>  	return 0;
>  }
>  
> +static int iplink_parse_inet(int *argcp, char ***argvp, struct iplink_req *req)
> +{
> +	struct rtattr *afs, *afinet, *inet_devconf;
> +	char **argv = *argvp;
> +	int argc = *argcp;
> +	int ret;
> +
> +	afs = addattr_nest(&req->n, sizeof(*req), IFLA_AF_SPEC);
> +	afinet = addattr_nest(&req->n, sizeof(*req), AF_INET);
> +	inet_devconf = addattr_nest(&req->n, sizeof(*req), IFLA_INET_CONF);
> +
> +	while (NEXT_ARG_OK()) {
> +		NEXT_ARG();
> +		if (matches(*argv, "forwarding") == 0) {

new uses of matches are not allowed. If s/matches/strcmp/ is the only
comment, I can fix up before applying.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters
  2026-06-02 19:36 ` David Ahern
@ 2026-06-02 19:46   ` Fernando Fernandez Mancera
  2026-06-02 21:11     ` David Ahern
  0 siblings, 1 reply; 4+ messages in thread
From: Fernando Fernandez Mancera @ 2026-06-02 19:46 UTC (permalink / raw)
  To: David Ahern, netdev; +Cc: stephen, davem, kuba, pabeni, Nicolas Dichtel

On 6/2/26 9:36 PM, David Ahern wrote:
> On 6/1/26 8:32 AM, Fernando Fernandez Mancera wrote:
>> Currently, modifying IPv4 interface configuration parameters requires
>> interacting with sysctl (/proc/sys/net/ipv4/conf/*). While
>> ip-netconf exists for monitoring these values, there has been no native
>> way to set them directly through iproute2.
>>
>> This patch introduces the support for that via 'inet' at the 'ip link
>> set'. It uses IFLA_INET_CONF netlink attribute to set the parameter.
>>
>> Example to enable forwarding on an interface:
>>
>> ip link set dev enp8s0 inet forwarding on
> 
> If an attribute can be set this way, then ip link show needs to show the
> values. What's the plan on that front?
> 

I could introduce it in a follow-up patch. I guess it makes sense to 
introduce it for ip -d link show only, right? I am happy to work on it 
anyway.

>>
>> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>> ---
>>   ip/iplink.c           | 354 ++++++++++++++++++++++++++++++++++++++++++
>>   man/man8/ip-link.8.in |  81 ++++++++++
>>   2 files changed, 435 insertions(+)
>>
> 
> ...
> 
>>   		"		[ gso_max_size BYTES ] [ gso_ipv4_max_size BYTES ] [ gso_max_segs PACKETS ]\n"
>> @@ -551,6 +569,339 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
>>   	return 0;
>>   }
>>   
>> +static int iplink_parse_inet(int *argcp, char ***argvp, struct iplink_req *req)
>> +{
>> +	struct rtattr *afs, *afinet, *inet_devconf;
>> +	char **argv = *argvp;
>> +	int argc = *argcp;
>> +	int ret;
>> +
>> +	afs = addattr_nest(&req->n, sizeof(*req), IFLA_AF_SPEC);
>> +	afinet = addattr_nest(&req->n, sizeof(*req), AF_INET);
>> +	inet_devconf = addattr_nest(&req->n, sizeof(*req), IFLA_INET_CONF);
>> +
>> +	while (NEXT_ARG_OK()) {
>> +		NEXT_ARG();
>> +		if (matches(*argv, "forwarding") == 0) {
> 
> new uses of matches are not allowed. If s/matches/strcmp/ is the only
> comment, I can fix up before applying.
> 

Sorry I didn't know this. Thanks.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters
  2026-06-02 19:46   ` Fernando Fernandez Mancera
@ 2026-06-02 21:11     ` David Ahern
  0 siblings, 0 replies; 4+ messages in thread
From: David Ahern @ 2026-06-02 21:11 UTC (permalink / raw)
  To: Fernando Fernandez Mancera, netdev
  Cc: stephen, davem, kuba, pabeni, Nicolas Dichtel

On 6/2/26 1:46 PM, Fernando Fernandez Mancera wrote:
> On 6/2/26 9:36 PM, David Ahern wrote:
>> On 6/1/26 8:32 AM, Fernando Fernandez Mancera wrote:
>>> Currently, modifying IPv4 interface configuration parameters requires
>>> interacting with sysctl (/proc/sys/net/ipv4/conf/*). While
>>> ip-netconf exists for monitoring these values, there has been no native
>>> way to set them directly through iproute2.
>>>
>>> This patch introduces the support for that via 'inet' at the 'ip link
>>> set'. It uses IFLA_INET_CONF netlink attribute to set the parameter.
>>>
>>> Example to enable forwarding on an interface:
>>>
>>> ip link set dev enp8s0 inet forwarding on
>>
>> If an attribute can be set this way, then ip link show needs to show the
>> values. What's the plan on that front?
>>
> 
> I could introduce it in a follow-up patch. I guess it makes sense to
> introduce it for ip -d link show only, right? I am happy to work on it
> anyway.

yes, -d only.

Will give Nicolas a chance to review.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-02 21:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 14:32 [PATCH iproute2-next] iplink: add support for setting IPv4 devconf parameters Fernando Fernandez Mancera
2026-06-02 19:36 ` David Ahern
2026-06-02 19:46   ` Fernando Fernandez Mancera
2026-06-02 21:11     ` David Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox