[netfilter-cvslog] r6439 - in trunk/libnfnetlink: include/libnfnetlink src

laforge at netfilter.org laforge at netfilter.org
Thu Jan 26 10:28:47 CET 2006


Author: laforge at netfilter.org
Date: 2006-01-26 10:28:47 +0100 (Thu, 26 Jan 2006)
New Revision: 6439

Modified:
   trunk/libnfnetlink/include/libnfnetlink/linux_nfnetlink.h
   trunk/libnfnetlink/src/libnfnetlink.c
Log:
fix logic for using one socket for multiple subsystems to be compatible with
multiple nfnetlink sockets per process (pid overlap)


Modified: trunk/libnfnetlink/include/libnfnetlink/linux_nfnetlink.h
===================================================================
--- trunk/libnfnetlink/include/libnfnetlink/linux_nfnetlink.h	2006-01-26 09:12:19 UTC (rev 6438)
+++ trunk/libnfnetlink/include/libnfnetlink/linux_nfnetlink.h	2006-01-26 09:28:47 UTC (rev 6439)
@@ -112,7 +112,6 @@
 {
 	int (*call)(struct sock *nl, struct sk_buff *skb, 
 		struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
-	kernel_cap_t cap_required; /* capabilities required for this msg */
 	u_int16_t attr_count;	/* number of nfattr's */
 };
 
@@ -146,7 +145,7 @@
 extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
 extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
 
-extern int nfattr_parse(struct nfattr *tb[], int maxattr, 
+extern void nfattr_parse(struct nfattr *tb[], int maxattr, 
 			struct nfattr *nfa, int len);
 
 #define nfattr_parse_nested(tb, max, nfa) \
@@ -154,11 +153,14 @@
 
 #define nfattr_bad_size(tb, max, cta_min)				\
 ({	int __i, __res = 0;						\
- 	for (__i=0; __i<max; __i++) 					\
+ 	for (__i=0; __i<max; __i++) {					\
+ 		if (!cta_min[__i])					\
+ 			continue;					\
  		if (tb[__i] && NFA_PAYLOAD(tb[__i]) < cta_min[__i]){	\
  			__res = 1;					\
  			break;						\
  		}							\
+ 	}								\
  	__res;								\
 })
 

Modified: trunk/libnfnetlink/src/libnfnetlink.c
===================================================================
--- trunk/libnfnetlink/src/libnfnetlink.c	2006-01-26 09:12:19 UTC (rev 6438)
+++ trunk/libnfnetlink/src/libnfnetlink.c	2006-01-26 09:28:47 UTC (rev 6439)
@@ -33,8 +33,19 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+#include <linux/netlink.h>
+
 #include <libnfnetlink/libnfnetlink.h>
 
+#ifndef NETLINK_ADD_MEMBERSHIP
+#define NETLINK_ADD_MEMBERSHIP 1
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+
 #define nfnl_error(format, args...) \
 	fprintf(stderr, "%s: " format "\n", __FUNCTION__, ## args)
 
@@ -95,25 +106,23 @@
 
 static int recalc_rebind_subscriptions(struct nfnl_handle *nfnlh)
 {
-	int i;
-	u_int32_t new_subscriptions = 0;
+	int i, err;
+	u_int32_t new_subscriptions = nfnlh->subscriptions;
 
 	for (i = 0; i < NFNL_MAX_SUBSYS; i++)
 		new_subscriptions |= nfnlh->subsys[i].subscriptions;
 
-	if (nfnlh->subscriptions != new_subscriptions) {
-		int err;
 
-		nfnlh->local.nl_groups = new_subscriptions;
-		err = bind(nfnlh->fd, (struct sockaddr *)&nfnlh->local,
-			   sizeof(nfnlh->local));
-		if (err < 0) {
-			nfnl_error("bind(netlink): %s", strerror(errno));
-			return err;
-		}
-		nfnlh->subscriptions = new_subscriptions;
+	nfnlh->local.nl_groups = new_subscriptions;
+	err = bind(nfnlh->fd, (struct sockaddr *)&nfnlh->local,
+		   sizeof(nfnlh->local));
+	if (err < 0) {
+		nfnl_error("bind(netlink): %s", strerror(errno));
+		return err;
 	}
 
+	nfnlh->subscriptions = new_subscriptions;
+
 	return 0;
 }
 
@@ -156,11 +165,24 @@
 		goto err_close;
 	}
 	nfnlh->seq = time(NULL);
-	/*
-	 * nfnl_talk checks: h->nlmsg_pid != nfnlh->local.nl_pid
-	 */
-	nfnlh->local.nl_pid = getpid();
 
+	/* don't set pid here, only first socket of process has real pid !!! 
+	 * binding to pid '0' will default */
+
+	/* let us do the initial bind */
+	if (recalc_rebind_subscriptions(nfnlh) < 0)
+		goto err_close;
+
+	/* use getsockname to get the netlink pid that the kernel assigned us */
+	addr_len = sizeof(nfnlh->local);
+	err = getsockname(nfnlh->fd, (struct sockaddr *)&nfnlh->local, 
+			  &addr_len);
+	if (addr_len != sizeof(nfnlh->local)) {
+		nfnl_error("Bad address length (%u != %zd)", addr_len,
+			   sizeof(nfnlh->local));
+		goto err_close;
+	}
+
 	return nfnlh;
 
 err_close:
@@ -206,6 +228,8 @@
 	ssh->subscriptions = subscriptions;
 	ssh->subsys_id = subsys_id;
 
+	/* FIXME: reimplement this based on 
+	 * setsockopt(nfnlh->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,,) */
 	if (recalc_rebind_subscriptions(nfnlh) < 0) {
 		free(ssh->cb);
 		ssh->cb = NULL;




More information about the netfilter-cvslog mailing list