Skip to contentSkip to conversation

netlink_ack takes gfp flag as parameter

NETLINK Pablo Neira 2 participants 2 messages Sep 24, 2004

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

Hi Davem,

AFAIK ip_queue, ip6_queue and dn_rtmsg use netlink_ack in interrupt context which calls alloc_skb with the GFP_KERNEL flag. This patch adds a new parameter to netlink_ack to set the gfp flag.

regards,
Pablo

===== include/linux/netlink.h 1.19 vs edited =====

include/linux/netlink.h +1 -1
@@ -119,7 +119,7 @@
 extern void netlink_detach(int unit);
 extern int netlink_post(int unit, struct sk_buff *skb);
 extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len));
-extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
+extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, int gfp_mask);
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
 extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
 			     __u32 group, int allocation);

===== net/netlink/af_netlink.c 1.56 vs edited =====

net/netlink/af_netlink.c +3 -2
@@ -957,7 +957,8 @@
 	return 0;
 }
 
-void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
+void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, 
+		 int gfp_mask)
 {
 	struct sk_buff *skb;
 	struct nlmsghdr *rep;
@@ -969,7 +970,7 @@
 	else
 		size = NLMSG_SPACE(4 + NLMSG_ALIGN(nlh->nlmsg_len));
 
-	skb = alloc_skb(size, GFP_KERNEL);
+	skb = alloc_skb(size, gfp_mask);
 	if (!skb) {
 		struct sock *sk;
 

===== kernel/audit.c 1.3 vs edited =====

kernel/audit.c +2 -2
@@ -419,9 +419,9 @@
 		if (rlen > skb->len)
 			rlen = skb->len;
 		if ((err = audit_receive_msg(skb, nlh))) {
-			netlink_ack(skb, nlh, -err);
+			netlink_ack(skb, nlh, -err, GFP_KERNEL);
 		} else if (nlh->nlmsg_flags & NLM_F_ACK)
-			netlink_ack(skb, nlh, 0);
+			netlink_ack(skb, nlh, 0, GFP_KERNEL);
 		skb_pull(skb, rlen);
 	}
 	return 0;

===== net/decnet/netfilter/dn_rtmsg.c 1.3 vs edited =====

net/decnet/netfilter/dn_rtmsg.c +3 -1
@@ -99,7 +99,9 @@
 }
 
 
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
+#define RCV_SKB_FAIL(err) do {					\
+	netlink_ack(skb, nlh, (err), GFP_ATOMIC); return; 	\
+	} while (0) 						\
 
 static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
 {

===== net/ipv6/netfilter/ip6_queue.c 1.14 vs edited =====

net/ipv6/netfilter/ip6_queue.c +3 -1
@@ -474,7 +474,9 @@
 		ipq_issue_verdict(entry, NF_DROP);
 }
 
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
+#define RCV_SKB_FAIL(err) do {					\
+	netlink_ack(skb, nlh, (err), GFP_ATOMIC); return; 	\
+	} while (0) 						\
 
 static inline void
 ipq_rcv_skb(struct sk_buff *skb)

===== net/ipv4/netfilter/ip_queue.c 1.17 vs edited =====

net/ipv4/netfilter/ip_queue.c +4 -2
@@ -471,7 +471,9 @@
 		ipq_issue_verdict(entry, NF_DROP);
 }
 
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
+#define RCV_SKB_FAIL(err) do {					\
+	netlink_ack(skb, nlh, (err), GFP_ATOMIC); return; 	\
+	} while (0)						\
 
 static inline void
 ipq_rcv_skb(struct sk_buff *skb)
@@ -526,7 +528,7 @@
 		RCV_SKB_FAIL(status);
 		
 	if (flags & NLM_F_ACK)
-		netlink_ack(skb, nlh, 0);
+		netlink_ack(skb, nlh, 0, GFP_ATOMIC);
         return;
 }
 

===== net/core/rtnetlink.c 1.27 vs edited =====

net/core/rtnetlink.c +2 -2
@@ -558,9 +558,9 @@
 			 */
 			if (err == 0)
 				return -1;
-			netlink_ack(skb, nlh, err);
+			netlink_ack(skb, nlh, err, GFP_KERNEL);
 		} else if (nlh->nlmsg_flags&NLM_F_ACK)
-			netlink_ack(skb, nlh, 0);
+			netlink_ack(skb, nlh, 0, GFP_KERNEL);
 		skb_pull(skb, rlen);
 	}
 

===== net/ipv4/tcp_diag.c 1.16 vs edited =====

net/ipv4/tcp_diag.c +1 -1
@@ -634,7 +634,7 @@
 			return;
 		err = tcpdiag_rcv_msg(skb, nlh);
 		if (err || nlh->nlmsg_flags & NLM_F_ACK) 
-			netlink_ack(skb, nlh, err);
+			netlink_ack(skb, nlh, err, GFP_KERNEL);
 	}
 }
 

===== net/xfrm/xfrm_user.c 1.48 vs edited =====

net/xfrm/xfrm_user.c +1 -1
@@ -995,7 +995,7 @@
 		if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) {
 			if (err == 0)
 				return -1;
-			netlink_ack(skb, nlh, err);
+			netlink_ack(skb, nlh, err, GFP_KERNEL);
 		} else if (nlh->nlmsg_flags & NLM_F_ACK)
 			netlink_ack(skb, nlh, 0);
 		skb_pull(skb, rlen);
maintainer
#1 lore raw
Quoted 4 lines · Pablo Neira

AFAIK ip_queue, ip6_queue and dn_rtmsg use netlink_ack in interrupt context which calls alloc_skb with the GFP_KERNEL flag. This patch adds a new parameter to netlink_ack to set the gfp flag.

Bogus. All of those functions call netlink_ack in the context of the sending process.

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt