Thread (29 messages) flat view 29 messages, 9 authors, 6d ago

Re: [PATCH 03/13 net-next] net: inet: relocate ip_generic_getfrag and guard IPv4 socket logic

From: Stanislav Fomichev <hidden>
Date: 2026-09-10 21:19:47
Also in: lkml

On 09/10, Fernando Fernandez Mancera wrote:
quoted hunk ↗ jump to hunk
To enable compiling the INET subsystem without IPv4, shared generic
utilities must be relocated and IPv4 socket logic must be guarded for
CONFIG_IPV4.

This patch moves the generic ip_generec_getfrag() from ip_output.c to
af_inet.c. It also introduces CONFIG_IPV4 guards around af_inet.c to
reject IPv4-specific ioctls, protocol registrations and bind requests.
The same guard is added to reject IPv4-mapped IPv6.

Signed-off-by: Fernando Fernandez Mancera <redacted>
---
 net/ipv4/af_inet.c   | 96 +++++++++++++++++++++++++++++++++++++-------
 net/ipv4/ip_output.c | 18 ---------
 net/ipv6/af_inet6.c  |  5 +++
 net/ipv6/datagram.c  | 12 ++++++
 4 files changed, 99 insertions(+), 32 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d9421ac38d78..b0c48ba544bf 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -129,6 +129,28 @@
 int disable_ipv6_mod;
 EXPORT_SYMBOL(disable_ipv6_mod);
 
+/* Keep the function here for now as it is generic, it should be moved
+ * to a common L3 place
+ */
+int
+ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
+{
+	struct msghdr *msg = from;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (!copy_from_iter_full(to, len, &msg->msg_iter))
+			return -EFAULT;
+	} else {
+		__wsum csum = 0;
+
+		if (!csum_and_copy_from_iter_full(to, len, &csum, &msg->msg_iter))
+			return -EFAULT;
+		skb->csum = csum_block_add(skb->csum, csum, odd);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(ip_generic_getfrag);
+
 /* The inetsw table contains everything that inet_create needs to
  * build a new socket.
  */
@@ -425,8 +447,10 @@ int inet_release(struct socket *sock)
 		if (!sk->sk_kern_sock)
 			BPF_CGROUP_RUN_PROG_INET_SOCK_RELEASE(sk);
 
+#if IS_ENABLED(CONFIG_IPV4)
 		/* Applications forget to leave groups before exiting */
 		ip_mc_drop_socket(sk);
+#endif
 
 		/* If linger is set, we don't return until the close
 		 * is complete.  Otherwise we return immediately. The
@@ -478,6 +502,7 @@ EXPORT_SYMBOL(inet_bind);
 int __inet_bind(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len,
 		u32 flags)
 {
+#if IS_ENABLED(CONFIG_IPV4)
 	struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
 	struct inet_sock *inet = inet_sk(sk);
 	struct net *net = sock_net(sk);
@@ -570,6 +595,9 @@ int __inet_bind(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len,
 		release_sock(sk);
 out:
 	return err;
+#else
+	return -EAFNOSUPPORT;
+#endif
 }
 
 int inet_dgram_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
@@ -962,18 +990,24 @@ EXPORT_SYMBOL(inet_shutdown);
 int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
-	int err = 0;
-	struct net *net = sock_net(sk);
+#if IS_ENABLED(CONFIG_IPV4)
 	void __user *p = (void __user *)arg;
-	struct ifreq ifr;
+	struct net *net = sock_net(sk);
 	struct rtentry rt;
+	struct ifreq ifr;
+#endif
+	int err = 0;
 
 	switch (cmd) {
 	case SIOCADDRT:
 	case SIOCDELRT:
+#if IS_ENABLED(CONFIG_IPV4)
 		if (copy_from_user(&rt, p, sizeof(struct rtentry)))
 			return -EFAULT;
 		err = ip_rt_ioctl(net, cmd, &rt);
+#else
+		err = -EOPNOTSUPP;
+#endif
 		break;
 	case SIOCRTMSG:
 		err = -EINVAL;
@@ -981,18 +1015,26 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 	case SIOCDARP:
 	case SIOCGARP:
 	case SIOCSARP:
+#if IS_ENABLED(CONFIG_IPV4)
 		err = arp_ioctl(net, cmd, (void __user *)arg);
+#else
+		err = -EOPNOTSUPP;
+#endif
 		break;
 	case SIOCGIFADDR:
 	case SIOCGIFBRDADDR:
 	case SIOCGIFNETMASK:
 	case SIOCGIFDSTADDR:
 	case SIOCGIFPFLAGS:
+#if IS_ENABLED(CONFIG_IPV4)
 		if (get_user_ifreq(&ifr, NULL, p))
 			return -EFAULT;
 		err = devinet_ioctl(net, cmd, &ifr);
 		if (!err && put_user_ifreq(&ifr, p))
 			err = -EFAULT;
+#else
+		err = -EOPNOTSUPP;
+#endif
 		break;
 
 	case SIOCSIFADDR:
@@ -1001,9 +1043,13 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 	case SIOCSIFDSTADDR:
 	case SIOCSIFPFLAGS:
 	case SIOCSIFFLAGS:
+#if IS_ENABLED(CONFIG_IPV4)
 		if (get_user_ifreq(&ifr, NULL, p))
 			return -EFAULT;
 		err = devinet_ioctl(net, cmd, &ifr);
+#else
+		err = -EOPNOTSUPP;
+#endif
(passing by comment)

Don't we have a coding style rule to avoid ifdef conditional in C code?
Should we add some new devinet4_ioctl/etc wrappers that we can conditionally
compile out in the headers?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help