Skip to contentSkip to conversation

libnfnetlink and iface conversion to string

RFC In review Eric Leblond 5 participants 32 messages Dec 27, 2006 – Jan 31, 2007

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

Hi,

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

For now, it is impossible to do this conversion from either libnetfilter_queue or libnfnetlink. But there is two files in libnfnetlink (iftable.c and rntl.c) which have been put here by Harald to provide this conversion (if I remember correctly an old mail from Harald).

It was a long time ago and I don't know if it still planned to modify libnfnetlink to include this feature. Or, would it be a better choice to create a new library dedicated to this conversion.

Any comments are welcome.

I will start to work on it as soon as I know where to go.

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
#1 lore raw
Quoted 9 lines · Eric Leblond

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

For now, it is impossible to do this conversion from either libnetfilter_queue or libnfnetlink. But there is two files in libnfnetlink (iftable.c and rntl.c) which have been put here by Harald to provide this conversion (if I remember correctly an old mail from Harald).

Quoted 3 lines

It was a long time ago and I don't know if it still planned to modify libnfnetlink to include this feature. Or, would it be a better choice to create a new library dedicated to this conversion.

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

However, IMO libnetfilter_queue should provide enough features to let userspace apps implement filtering without requiring extra dependencies. BTW, what are the benefits of dumping the index instead of the interface name in this particular case?

Patrick?

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#2 lore raw

Hi,

Quoted 6 lines · Pablo Neira Ayuso
Quoted 2 lines · Eric Leblond

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

I agree that this does not seem to be the correct place.

Quoted 4 lines

However, IMO libnetfilter_queue should provide enough features to let userspace apps implement filtering without requiring extra dependencies. BTW, what are the benefits of dumping the index instead of the interface name in this particular case?

This is interesting !

I've looked at kernel code and the information was easy to add. I attach a small patch against kernel.

It will add 4*IFNAMSIZ = 64 octets to each nfnetlink_queue message but this is not impressive as a part of the packet payload is usually sent.

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
include/linux/netfilter/nfnetlink_queue.h +4 -0
index 83e7896..8318105 100644
@@ -41,6 +41,10 @@ enum nfqnl_attr_type {
 	NFQA_IFINDEX_PHYSOUTDEV,	/* u_int32_t ifindex */
 	NFQA_HWADDR,			/* nfqnl_msg_packet_hw */
 	NFQA_PAYLOAD,			/* opaque data payload */
+	NFQA_IFNAME_INDEV,		/* string name of iface */
+	NFQA_IFNAME_OUTDEV,		/*  string name of iface  */
+	NFQA_IFNAME_PHYSINDEV,		/* string name of iface */
+	NFQA_IFNAME_PHYSOUTDEV,	/* string name of iface */
 
 	__NFQA_MAX
 };
net/netfilter/nfnetlink_queue.c +18 -0
index a88a017..9b86b9d 100644
@@ -424,6 +424,7 @@ #endif
 		tmp_uint = htonl(indev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
+		NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ, indev->name);
 #else
 		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: indev is physical input device, we need to
@@ -431,20 +432,28 @@ #else
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), 
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_PHYSINDEV, IFNAMSIZ,
+				indev->name);
 			/* this is the bridge group "brX" */
 			tmp_uint = htonl(indev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ,
+				indev->name);
 		} else {
 			/* Case 2: indev is bridge group, we need to look for
 			 * physical device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ,
+				indev->name);
 			if (entskb->nf_bridge
 			    && entskb->nf_bridge->physindev) {
 				tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
 					sizeof(tmp_uint), &tmp_uint);
+				NFA_PUT(skb, NFQA_IFNAME_PHYSINDEV, IFNAMSIZ,
+					entskb->nf_bridge->physindev->name);
 			}
 		}
 #endif
@@ -454,6 +463,7 @@ #endif
 		tmp_uint = htonl(outdev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
+		NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ, outdev->name);
 #else
 		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: outdev is physical output device, we need to
@@ -461,20 +471,28 @@ #else
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_PHYSOUTDEV, IFNAMSIZ,
+				outdev->name);
 			/* this is the bridge group "brX" */
 			tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ,
+				outdev->name);
 		} else {
 			/* Case 2: outdev is bridge group, we need to look for
 			 * physical output device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ,
+				outdev->name);
 			if (entskb->nf_bridge
 			    && entskb->nf_bridge->physoutdev) {
 				tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
 					sizeof(tmp_uint), &tmp_uint);
+				NFA_PUT(skb, NFQA_IFNAME_PHYSOUTDEV, IFNAMSIZ,
+					entskb->nf_bridge->physoutdev->name);
 			}
 		}
 #endif
#3 lore raw

PATCH 1/2 Resend : sending iface name from nfnetlink_queue

Hi,

Quoted 4 lines · Eric Leblond

Hi,

Quoted 1 line · Pablo Neira Ayuso

Eric Leblond wrote:

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

I've looked at kernel code and the information was easy to add. I attach a small patch against kernel.

I resend a modified version of my kernel patch. It fixes a bug on fields size.

BR,

Signature · 3 lines
Éric Leblond, [email protected]
Téléphone : 01 44 89 46 39, Fax : 01 44 89 45 01
INL, http://www.inl.fr
include/linux/netfilter/nfnetlink_queue.h +4 -0
index 83e7896..8318105 100644
@@ -41,6 +41,10 @@ enum nfqnl_attr_type {
 	NFQA_IFINDEX_PHYSOUTDEV,	/* u_int32_t ifindex */
 	NFQA_HWADDR,			/* nfqnl_msg_packet_hw */
 	NFQA_PAYLOAD,			/* opaque data payload */
+	NFQA_IFNAME_INDEV,		/* string name of iface */
+	NFQA_IFNAME_OUTDEV,		/*  string name of iface  */
+	NFQA_IFNAME_PHYSINDEV,		/* string name of iface */
+	NFQA_IFNAME_PHYSOUTDEV,	/* string name of iface */
 
 	__NFQA_MAX
 };
net/netfilter/nfnetlink_queue.c +18 -0
index a88a017..6cc301a 100644
@@ -424,6 +424,7 @@ #endif
 		tmp_uint = htonl(indev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
+		NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ*sizeof(char), indev->name);
 #else
 		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: indev is physical input device, we need to
@@ -431,20 +432,28 @@ #else
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), 
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_PHYSINDEV, IFNAMSIZ*sizeof(char),
+				indev->name);
 			/* this is the bridge group "brX" */
 			tmp_uint = htonl(indev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ*sizeof(char),
+				indev->name);
 		} else {
 			/* Case 2: indev is bridge group, we need to look for
 			 * physical device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_INDEV, IFNAMSIZ*sizeof(char),
+				indev->name);
 			if (entskb->nf_bridge
 			    && entskb->nf_bridge->physindev) {
 				tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
 					sizeof(tmp_uint), &tmp_uint);
+				NFA_PUT(skb, NFQA_IFNAME_PHYSINDEV, IFNAMSIZ*sizeof(char),
+					entskb->nf_bridge->physindev->name);
 			}
 		}
 #endif
@@ -454,6 +463,7 @@ #endif
 		tmp_uint = htonl(outdev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
+		NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ*sizeof(char), outdev->name);
 #else
 		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: outdev is physical output device, we need to
@@ -461,20 +471,28 @@ #else
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_PHYSOUTDEV, IFNAMSIZ*sizeof(char),
+				outdev->name);
 			/* this is the bridge group "brX" */
 			tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ*sizeof(char),
+				outdev->name);
 		} else {
 			/* Case 2: outdev is bridge group, we need to look for
 			 * physical output device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
+			NFA_PUT(skb, NFQA_IFNAME_OUTDEV, IFNAMSIZ*sizeof(char),
+				outdev->name);
 			if (entskb->nf_bridge
 			    && entskb->nf_bridge->physoutdev) {
 				tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
 					sizeof(tmp_uint), &tmp_uint);
+				NFA_PUT(skb, NFQA_IFNAME_PHYSOUTDEV, IFNAMSIZ*sizeof(char),
+					entskb->nf_bridge->physoutdev->name);
 			}
 		}
 #endif
#4 lore raw

Re: [Patch 1/2] Resend : sending iface name from nfnetlink_queue

Quoted 11 lines · Eric Leblond
Quoted 9 lines · Eric Leblond
Quoted 8 lines
Quoted 2 lines · Eric Leblond

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

Quoted 6 lines
Quoted 2 lines

I've looked at kernel code and the information was easy to add. I attach a small patch against kernel.

I resend a modified version of my kernel patch. It fixes a bug on fields size.

I think Harald already stated his dislike for this approach, just to be explicit: I don't think we should add interface names to the netlink protocols, userspace should resolve the ifindex.

#5 lore raw

PATCH 2/2 getting iface name from libnetfilter_queue

In reply to Eric Leblond

Hi,

here's a patch against libnetfilter_queue.

It adds functions that can be used to get interface name.

BR,

Quoted 26 lines · Eric Leblond

Hi,

Quoted 6 lines · Pablo Neira Ayuso
Quoted 2 lines · Eric Leblond

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

I agree that this does not seem to be the correct place.

Quoted 4 lines

However, IMO libnetfilter_queue should provide enough features to let userspace apps implement filtering without requiring extra dependencies. BTW, what are the benefits of dumping the index instead of the interface name in this particular case?

This is interesting !

I've looked at kernel code and the information was easy to add. I attach a small patch against kernel.

It will add 4*IFNAMSIZ = 64 octets to each nfnetlink_queue message but this is not impressive as a part of the packet payload is usually sent.

BR,

Signature · 3 lines
Éric Leblond, [email protected]
Téléphone : 01 44 89 46 39, Fax : 01 44 89 45 01
INL, http://www.inl.fr
nfqnl_test.c +25 -5
Index: utils/nfqnl_test.c
===================================================================
@@ -2,11 +2,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <errno.h>
 #include <netinet/in.h>
 #include <linux/netfilter.h>		/* for NF_ACCEPT */
 
 #include <libnetfilter_queue/libnetfilter_queue.h>
 
+/* #define PRINT_INFOS  */
+
 /* returns packet id */
 static u_int32_t print_pkt (struct nfq_data *tb)
 {
@@ -16,13 +19,17 @@
 	int ret;
 	char *data;
 	
+    id = ntohl(ph->packet_id);
 	ph = nfq_get_msg_packet_hdr(tb);
 	if (ph){
 		id = ntohl(ph->packet_id);
+#ifdef PRINT_INFOS
 		printf("hw_protocol=0x%04x hook=%u id=%u ",
 			ntohs(ph->hw_protocol), ph->hook, id);
+#endif
 	}
 	
+#ifdef PRINT_INFOS
 	mark = nfq_get_nfmark(tb);
 	if (mark)
 		printf("mark=%u ", mark);
@@ -40,7 +47,7 @@
 		printf("payload_len=%d ", ret);
 
 	fputc('\n', stdout);
-
+#endif
 	return id;
 }
 	
@@ -49,7 +56,9 @@
 	      struct nfq_data *nfa, void *data)
 {
 	u_int32_t id = print_pkt(nfa);
+#ifdef PRINT_INFOS
 	printf("entering callback\n");
+#endif
 	return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
 }
 
@@ -96,11 +105,22 @@
 
 	nh = nfq_nfnlh(h);
 	fd = nfnl_fd(nh);
+    while ((rv = recv(fd, buf, sizeof(buf), 0))) {
+        if (rv<0){
+            printf("got error %d during recv\n",errno);
+            if (errno != ENOBUFS){
+                break;
+            } else {
+                printf("got error %d restart recv\n",errno);
+                continue;
+            }
+        }
+#ifdef PRINT_INFOS
+        printf("pkt received\n");
+#endif
+        nfq_handle_packet(h, buf, rv);
+    }
 
-	while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
-		printf("pkt received\n");
-		nfq_handle_packet(h, buf, rv);
-	}
 
 	printf("unbinding from queue 0\n");
 	nfq_destroy_queue(qh);
libnetfilter_queue/linux_nfnetlink_queue.h +4 -0
Index: include/libnetfilter_queue/linux_nfnetlink_queue.h
===================================================================
@@ -45,6 +45,10 @@
 	NFQA_IFINDEX_PHYSOUTDEV,	/* u_int32_t ifindex */
 	NFQA_HWADDR,			/* nfqnl_msg_packet_hw */
 	NFQA_PAYLOAD,			/* opaque data payload */
+	NFQA_IFNAME_INDEV,		/* string name of iface */
+	NFQA_IFNAME_OUTDEV,		/*  string name of iface  */
+	NFQA_IFNAME_PHYSINDEV,	/* string name of iface */
+	NFQA_IFNAME_PHYSOUTDEV,	/* string name of iface */
 
 	__NFQA_MAX
 };
libnetfilter_queue/libnetfilter_queue.h +7 -0
Index: include/libnetfilter_queue/libnetfilter_queue.h
===================================================================
@@ -80,6 +80,13 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+/* return NULL if not set */
+extern char* nfq_get_indev_name(struct nfq_data *nfad);
+extern char* nfq_get_physindev_name(struct nfq_data *nfad);
+extern char* nfq_get_outdev_name(struct nfq_data *nfad);
+extern char* nfq_get_physoutdev_name(struct nfq_data *nfad);
+
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */
libnetfilter_queue.c +20 -0
Index: src/libnetfilter_queue.c
===================================================================
@@ -419,6 +419,26 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char* nfq_get_indev_name(struct nfq_data *nfad)
+{
+	return nfnl_get_pointer_to_data(nfad->data, NFQA_IFNAME_INDEV, char);
+}
+
+char* nfq_get_physindev_name(struct nfq_data *nfad)
+{
+	return nfnl_get_pointer_to_data(nfad->data, NFQA_IFNAME_PHYSINDEV, char);
+}
+
+char* nfq_get_outdev_name(struct nfq_data *nfad)
+{
+	return nfnl_get_pointer_to_data(nfad->data, NFQA_IFNAME_OUTDEV, char);
+}
+
+char* nfq_get_physoutdev_name(struct nfq_data *nfad)
+{
+	return nfnl_get_pointer_to_data(nfad->data, NFQA_IFNAME_PHYSOUTDEV, char);
+}
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
#6 lore raw
In reply to Eric Leblond
Quoted 2 lines · Eric Leblond

It will add 4*IFNAMSIZ = 64 octets to each nfnetlink_queue message but this is not impressive as a part of the packet payload is usually sent.

No, please don't do that.

In your application, it might not be a lot, since you always send the packet payload. other applications might only need a smal bit of that.

Also, I _really_ want to get rid of interface names throughout netfilter/iptables at some point in the future. all 'next generation' subsystems (such as all nfnetlink based services) should just deal with ifindexes.

all of iproute2 also uses ifindexes, and IIRC their netlink messages also only have ifindexes.

Please put some functions into libnfnetlink, even if it doesn't natively
belong there. If there's more netlink unification, we can always make
those just wrappers for the 'real new unified' ifindex/name resolving functions.

[yes, I'm back, more or less]

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
#7 lore raw

Hi,

Quoted 10 lines · Harald Welte
Quoted 2 lines · Eric Leblond

It will add 4*IFNAMSIZ = 64 octets to each nfnetlink_queue message but this is not impressive as a part of the packet payload is usually sent.

No, please don't do that.
Also, I _really_ want to get rid of interface names throughout netfilter/iptables at some point in the future. all 'next generation' subsystems (such as all nfnetlink based services) should just deal with ifindexes.

Quoted 4 lines

Please put some functions into libnfnetlink, even if it doesn't natively
belong there. If there's more netlink unification, we can always make
those just wrappers for the 'real new unified' ifindex/name resolving functions.

I've thought at this solution before getting interessed by pablo's suggestion. But I've got a conception problem.

It is not correct to do a dump (and send a netlink message) for each ifindex resolution. Thus, libnfnetlink needs to listen to netlink interfaces message. A permanent "task" is thus needed to have the job done : It can be a dedicated thread or a carefully hidden select.

In fact, if we omit the thread approach which is somehow intrusive, I don't see a way to do this via a simple call to added functions.

Any idea welcome.

Quoted 1 line

[yes, I'm back, more or less]

Great news !

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
#8 lore raw
Quoted 7 lines · Eric Leblond

It is not correct to do a dump (and send a netlink message) for each ifindex resolution. Thus, libnfnetlink needs to listen to netlink interfaces message. A permanent "task" is thus needed to have the job done : It can be a dedicated thread or a carefully hidden select.

In fact, if we omit the thread approach which is somehow intrusive, I don't see a way to do this via a simple call to added functions.

You have to open a netlink socket for NETLINK_ROUTE, request a dump (RTM_GETLINK) to keep a cache of current tuples interface/index available, and subscribe to interface events (RTNLGRP_LINK) to keep the cache up to date. You can put both the nfqueue and the rtnetlink sockets in a poll. Something like:

/* create a table ifindex to interface */
struct nfnl_ifindex2name_table *nfnl_ifindex2name_open(); /* destroy table */
void nfnl_ifindex2name_close(struct nfnl_ifindex2name_table *);

/* returns a socket descriptor to listen to interface events */ int nfnl_ifindex2name_events_open();
/* process data available for the socket and update the table */ int nfnl_ifindex2name_process_event(int, struct nfnl_ifindex2name_table *); /* close socket */
void nfnl_ifindex2name_events_close(int); /* close the socket */

Another alternative could be the use of libnl, although this introduces a new library dependency for every libnetfilter_queue application.

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#9 lore raw

Hi,

Quoted 5 lines · Pablo Neira Ayuso
Quoted 4 lines · Eric Leblond

It is not correct to do a dump (and send a netlink message) for each ifindex resolution. Thus, libnfnetlink needs to listen to netlink interfaces message. A permanent "task" is thus needed to have the job done : It can be a dedicated thread or a carefully hidden select.

Quoted 7 lines

/* create a table ifindex to interface */
struct nfnl_ifindex2name_table *nfnl_ifindex2name_open(); /* destroy table */
void nfnl_ifindex2name_close(struct nfnl_ifindex2name_table *);

/* returns a socket descriptor to listen to interface events */ int nfnl_ifindex2name_events_open();

Speaking as NuFW's developper and thus libnetfilter_queue user, this clearly mean that I need to modify select part of my code, not just add some functions calls. It forces the developper to use directly libnfnetlink. This goes against my way to see libnetfilter_queue and other libnetfilter* libraries.

Quoted 7 lines

/* process data available for the socket and update the table */ int nfnl_ifindex2name_process_event(int, struct nfnl_ifindex2name_table *); /* close socket */
void nfnl_ifindex2name_events_close(int); /* close the socket */

Another alternative could be the use of libnl, although this introduces a new library dependency for every libnetfilter_queue application.

I think that ifname resolution is necessary for an application if it is a linked with wanted features. If it has to use it, application can link to libnl (or something else) and have it done. If it don't need it then libnetfilter_queue is enough.

route netlink message is not a part of Netfilter, we should'nt use it in Netfilter code if it is not transparent :
* It duplicates code
* It changes the "spirit" of libnetfilter* libraries

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
#10 lore raw
In reply to Eric Leblond
Quoted 17 lines · Eric Leblond

Hi,

Quoted 10 lines · Harald Welte
Quoted 2 lines · Eric Leblond

It will add 4*IFNAMSIZ = 64 octets to each nfnetlink_queue message but this is not impressive as a part of the packet payload is usually sent.

No, please don't do that.
Also, I _really_ want to get rid of interface names throughout netfilter/iptables at some point in the future. all 'next generation' subsystems (such as all nfnetlink based services) should just deal with ifindexes.

Quoted 4 lines

Please put some functions into libnfnetlink, even if it doesn't natively
belong there. If there's more netlink unification, we can always make
those just wrappers for the 'real new unified' ifindex/name resolving functions.

Quoted 7 lines

I've thought at this solution before getting interessed by pablo's suggestion. But I've got a conception problem.

It is not correct to do a dump (and send a netlink message) for each ifindex resolution. Thus, libnfnetlink needs to listen to netlink interfaces message. A permanent "task" is thus needed to have the job done : It can be a dedicated thread or a carefully hidden select.

the latter, a caerfully hidden select. I actually have code for this, which I am allowed to release under GPL (was written as part of a non-gpl project)

I have committed that code to svn:
http://svn.netfilter.org/cgi-bin/viewcvs.cgi/trunk/libnfnetlink/src/
rtnl.c and iftable.c

However, I never found the time to integrate them intl libnfnetlink, so they remained dead code for the last 16 months :(

Quoted 2 lines

In fact, if we omit the thread approach which is somehow intrusive, I don't see a way to do this via a simple call to added functions.

It isn't all that difficult to keep a in-memory list of name-ifindex mappings. You once dump at startup, and then listen to events...

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
#11 lore raw

cover libnfnetlink and iface conversion to string

Hi,

Quoted 8 lines · Harald Welte
Quoted 1 line · Eric Leblond

Hi,

I have committed that code to svn:
http://svn.netfilter.org/cgi-bin/viewcvs.cgi/trunk/libnfnetlink/src/
rtnl.c and iftable.c

However, I never found the time to integrate them intl libnfnetlink, so they remained dead code for the last 16 months :(

Here's an attempt to add iface name resolution to libnfnetlink. It works and it is not too difficult to use.

Quoted 5 lines
Quoted 2 lines

In fact, if we omit the thread approach which is somehow intrusive, I don't see a way to do this via a simple call to added functions.

It isn't all that difficult to keep a in-memory list of name-ifindex mappings. You once dump at startup, and then listen to events...

This can be translated like that :
1. get netlink_fd with nlif_table_init()
2. use nlif_treat_msg(netlink_fd) to parse initial message
3. put netlink_fd in a select, and call nlif_treat_msg(netlink_fd) when data arrives
4. cleanup with nlif_table_fini(void) when feature is not needed any more

I join the patch for NuFW as code example.

To follow :
* Patch for libnfnetlink
* Patch for libnetfilter_queue

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
nufw/packetsrv.c +15 -0
Index: src/nufw/packetsrv.c
===================================================================
@@ -18,6 +18,8 @@
 
 #include "nufw.h"
 
+#include "iface.h"
+
 /** \file packetsrv.c
  *  \brief Packet server thread
  *
@@ -159,6 +161,7 @@
     return 1;
 }
 
+
 /**
  * Open a netlink connection and returns file descriptor
  */
@@ -335,6 +338,7 @@
     unsigned char buffer[BUFSIZ];
     struct timeval tv;
     int fd;
+    int if_fd;
     int rv;
     int select_result;
     fd_set wk_set;
@@ -345,6 +349,12 @@
         exit(EXIT_FAILURE);
     }
 
+    if_fd = iface_table_open();
+
+    if (if_fd < 0) {
+        exit(EXIT_FAILURE);
+    }
+
     log_area_printf (DEBUG_AREA_MAIN, DEBUG_LEVEL_WARNING,
             "[+] Packet server started");
 
@@ -360,6 +370,7 @@
         /* wait new event on socket */
         FD_ZERO(&wk_set);
         FD_SET(fd,&wk_set);
+        FD_SET(if_fd,&wk_set);
         select_result = select(fd+1,&wk_set,NULL,NULL,&tv);
         if (select_result == -1)
         {
@@ -380,6 +391,10 @@
             continue;
         }
 
+        if (FD_ISSET(if_fd,&wk_set)){
+            iface_treat_message(if_fd);
+            continue;
+        }
         /* read one packet */
         rv = recv(fd, buffer, sizeof(buffer), 0);
         if (rv < 0)
nufw/iface.c +20 -0
Index: src/nufw/iface.c
===================================================================
@@ -42,4 +42,24 @@
 	return 1;
 }
 
+int iface_table_open()
+{
+    int iftable_fd;
+    /* opening ifname resolution handle */
+    iftable_fd = nlif_table_init();
+    if (iftable_fd <= 0) {
+        log_area_printf (DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
+                "[!] Error during nlif_table_init()");
+        return -1;
+    }
+    /* treat initial rtnetlink message */
+    nlif_treat_msg(iftable_fd);
+
+    return iftable_fd;
+}
+
+int iface_treat_message(int fd)
+{
+   return nlif_treat_msg(fd);
+}
 #endif
nufw/Makefile.am +2 -2
Index: src/nufw/Makefile.am
===================================================================
@@ -4,8 +4,8 @@
 sbin_PROGRAMS = nufw
 
 # nufw
-nufw_SOURCES = authsrv.c  common.c  main.c  packetsrv.c  proto.h  structure.h\
-		tls.c audit.c conntrack.c log.c iface.c
+nufw_SOURCES = authsrv.c  common.c  main.c  iface.c packetsrv.c  proto.h  structure.h\
+		tls.c audit.c conntrack.c log.c
 if HAVE_IPQ
 nufw_LDADD = -lipq -lpthread -lgnutls
 endif
ChangeLog +3 -0
Index: ChangeLog
===================================================================
@@ -1,6 +1,9 @@
 2.1.2
 	- log_mysql: add option to log by default in SQL
 	database with IPV4 schema
+	- libnuclient: add nu_get_home_dir function which is not
+	dependant of HOME environment variable
+	- nufw: fix compilation in ipq mode (workaround ipq.h problem)
 2.1.1 (2007/01/03)
 	- suppress ldap authentication code
 	- add support for log prefix
#12 lore raw

PATCH 1/2 libnfnetlink, iface conversion to string

Hi,

Here's the patch against libnfnetlink.

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
libnfnetlink/libnfnetlink.h +7 -0
Index: include/libnfnetlink/libnfnetlink.h
===================================================================
@@ -176,6 +176,13 @@
 
 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
 
+int nlif_table_init(void);
+void nlif_table_fini(void);
+
+char *nlif_index_2name(unsigned int index);
+int nlif_treat_msg(int fd);
+
+
 /* Pablo: What is the equivalence of be64_to_cpu in userspace?
  * 
  * Harald: Good question.  I don't think there's a standard way [yet?], 
rtnl.c +3 -3
Index: src/rtnl.c
===================================================================
@@ -116,7 +116,7 @@
         struct sockaddr_nl nladdr;
 
         memset(&nladdr, 0, sizeof(nladdr));
-	memset(&req, 0, sizeof(req));
+        memset(&req, 0, sizeof(req));
         nladdr.nl_family = AF_NETLINK;
 
         req.nlh.nlmsg_len = sizeof(req);
@@ -127,11 +127,11 @@
         req.g.rtgen_family = AF_INET;
 
         return sendto(rtnl_fd, (void*)&req, sizeof(req), 0, 
-		      (struct sockaddr*)&nladdr, sizeof(nladdr));
+                (struct sockaddr*)&nladdr, sizeof(nladdr));
 }
 
 /* rtnl_receive - receive netlink packets from rtnetlink socket */
-int rtnl_receive()
+int rtnl_receive(int rtnl_fd)
 {
 	int status;
 	char buf[8192];
iftable.c +37 -19

148 lines not on this page · raw message

Makefile.am +1 -1
Index: src/Makefile.am
===================================================================
@@ -8,4 +8,4 @@
 
 libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles	\
 			  -version-info $(LIBVERSION)
-libnfnetlink_la_SOURCES = libnfnetlink.c 
+libnfnetlink_la_SOURCES = libnfnetlink.c iftable.c rtnl.c
#13 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

rtnl.c line 119

Quoted 10 lines · Eric Leblond

Index: src/rtnl.c
===================================================================

rtnl.c +1 -1
@@ -116,7 +116,7 @@
         struct sockaddr_nl nladdr;
 
         memset(&nladdr, 0, sizeof(nladdr));
-	memset(&req, 0, sizeof(req));
+        memset(&req, 0, sizeof(req));

Reindenting, but fine ..

rtnl.c line 130

Quoted 9 lines
rtnl.c +1 -1
         nladdr.nl_family = AF_NETLINK;
 
         req.nlh.nlmsg_len = sizeof(req);
@@ -127,11 +127,11 @@
         req.g.rtgen_family = AF_INET;
 
         return sendto(rtnl_fd, (void*)&req, sizeof(req), 0, 
-		      (struct sockaddr*)&nladdr, sizeof(nladdr));
+                (struct sockaddr*)&nladdr, sizeof(nladdr));

This one isn't.

rtnl.c line 134

Quoted 5 lines
rtnl.c +1 -1
 }
 
 /* rtnl_receive - receive netlink packets from rtnetlink socket */
-int rtnl_receive()
+int rtnl_receive(int rtnl_fd)

header file needs to be fixed as well. Is the global rtnl_fd still needed?

iftable.c line 5

Quoted 13 lines
rtnl.c +0 -0
 {
 	int status;
 	char buf[8192];

Index: src/iftable.c
===================================================================

iftable.c +1 -1
@@ -2,7 +2,7 @@
  *
  * (C) 2004 by Astaro AG, written by Harald Welte <[email protected]>
  *
- * This software is Free Software and licensed under GNU GPLv2. 
+ * This software is Free Software and licensed under GNU GPLv2.

Please do cleanup in seperate patches.

iftable.c line 27

Quoted 11 lines
iftable.c +2 -2
  *
  */
 
@@ -23,8 +23,8 @@
 
 #define iftb_log(x, ...)
 
-struct ifindex_map {
-	struct ifindex_map *next;
+struct ifindex_map_t {
+	struct ifindex_map_t *next;

No useless renaming without a reason please.

Quoted 85 lines
iftable.c +10 -11
 	u_int32_t	index;
 	u_int32_t	type;
@@ -34,7 +34,7 @@
 	char		name[16];
 };
 
-static struct ifindex_map *ifindex_map[16];
+static struct ifindex_map_t *ifindex_map[16];
 
 /* iftable_dump - Dump the interface table to a given file stream
  * @outfd:	file stream to which table should be dumped
@@ -44,7 +44,7 @@
 	int i;
 
 	for (i = 0; i < 16; i++) {
-		struct ifindex_map *im;
+		struct ifindex_map_t *im;
 		for (im = ifindex_map[i]; im; im = im->next) {
 			fprintf(outfd, "%u %s", im->index, im->name);
 			if (!(im->flags & IFF_UP))
@@ -67,7 +67,7 @@
 {
 	unsigned int hash;
 	struct ifinfomsg *ifi_msg = NLMSG_DATA(n);
-	struct ifindex_map *im, **imp;
+	struct ifindex_map_t *im, **imp;
 	struct rtattr *cb[IFLA_MAX+1];
 
 	if (n->nlmsg_type != RTM_NEWLINK)
@@ -108,7 +108,7 @@
 		iftb_log(LOG_DEBUG, "creating new iftable (ifindex=%u)",
 			 im->index);
 	}
-	
+
 	im->type = ifi_msg->ifi_type;
 	im->flags = ifi_msg->ifi_flags;
 	if (cb[IFLA_ADDRESS]) {
@@ -129,14 +129,13 @@
  * @n:		netlink message header of a RTM_DELLINK nlmsg
  * @arg:	not used
  *
- * Delete an entry from the interface table.  
+ * Delete an entry from the interface table.
  * Returns -1 on error, 0 if no matching entry was found or 1 on success.
  */
 int iftable_del(struct nlmsghdr *n, void *arg)
 {
 	struct ifinfomsg *ifi_msg = NLMSG_DATA(n);
 	struct rtattr *cb[IFLA_MAX+1];
-	struct ifindex_map *im;
 
 	if (n->nlmsg_type != RTM_DELLINK) {
 		iftb_log(LOG_ERROR,
@@ -157,15 +156,15 @@
 
 	return 1;
 }
-	
-/* ifindex_2name - get the name for an ifindex
+
+/* nl_ifindex_2name - get the name for an ifindex
  * @index:	ifindex to be resolved
  *
  * Return value: character string containing name of interface
  */
-char *ifindex_2name(unsigned int index)
+char *nlif_index_2name(unsigned int index)
 {
-	struct ifindex_map *im;
+	struct ifindex_map_t *im;
 
 	if (index == 0)
 		return "*";
@@ -183,7 +182,7 @@
  */
 int  iftable_up(unsigned int index)
 {
-	struct ifindex_map *im;
+	struct ifindex_map_t *im;
 
 	for (im = ifindex_map[index&0xF]; im; im = im->next) {
 		if (im->index == index) {

iftable.c line 210

Quoted 4 lines
iftable.c +1 -0
@@ -208,6 +207,14 @@
 	if (fini)
 		goto cleanup;
 
+	memset(ifindex_map,0,sizeof(ifindex_map));

whitespace after comma.

iftable.c line 216

Quoted 6 lines
iftable.c +6 -0
+
+	ret = rtnl_init();
+
+	if (ret == -1) {
+		goto cleanup_none;
+	}

Please no parens around single expressions.

Quoted 58 lines
iftable.c +17 -5
+
 	if (rtnl_handler_register(&handlers[0]) < 0) {
 		ret = -1;
 		goto cleanup_none;
@@ -223,7 +230,7 @@
 		goto cleanup_1;
 	}
 
-	return 0;
+	return ret;
 
 #if 0
 	if (rtnl_wilddump_requet(rtnl_fd, AF_UNSPEC, RTM_GETLINK) < 0) {
@@ -243,19 +250,30 @@
 	return ret;
 }
 
-/* iftable_init - Initialize interface table
+/** nl_iftable_init - Initialize interface table
+ *
+ * Initialize rtnl interface and interface table
+ *
+ * \return file descriptor to netlink socket
  */
-int iftable_init(void)
+int nlif_table_init(void)
 {
 	iftb_log(LOG_DEBUG, "%s", __FUNCTION__);
 	return init_or_fini(0);
 }
 
-/* iftable_fini - Destructor of interface table
+/* nl_iftable_fini - Destructor of interface table
  */
-void iftable_fini(void)
+void nlif_table_fini(void)
 {
 	init_or_fini(1);
 }
 
+/**
+ * \return 0 if OK
+ */
+int nlif_treat_msg(int fd)
+{
+	return rtnl_receive(fd);
+}
 

Index: src/Makefile.am
===================================================================

Makefile.am +1 -1
@@ -8,4 +8,4 @@
 
 libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles	\
 			  -version-info $(LIBVERSION)
-libnfnetlink_la_SOURCES = libnfnetlink.c 
+libnfnetlink_la_SOURCES = libnfnetlink.c iftable.c rtnl.c
#14 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Quoted 7 lines · Patrick McHardy

rtnl.c line 134

Quoted 3 lines · Eric Leblond

/* rtnl_receive - receive netlink packets from rtnetlink socket */

rtnl.c +1 -1
-int rtnl_receive()
+int rtnl_receive(int rtnl_fd)

header file needs to be fixed as well. Is the global rtnl_fd still needed?

Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

static int rtnl_fd;
static int rtnl_seq = 0;
static int rtnl_dump;
static struct sockaddr_nl rtnl_local;

Quoted 1 line

From iftable.c:

static struct ifindex_map *ifindex_map[16];

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#15 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Quoted 11 lines · Pablo Neira Ayuso
Quoted 7 lines · Patrick McHardy

rtnl.c line 134

Quoted 3 lines · Eric Leblond

/* rtnl_receive - receive netlink packets from rtnetlink socket */

rtnl.c +1 -1
-int rtnl_receive()
+int rtnl_receive(int rtnl_fd)

header file needs to be fixed as well. Is the global rtnl_fd still needed?

Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

I totally agree. Patch was prefixed with RFC because I wanted to see if API was correct. As there is no problem from this point, I will do the needed cleaning.

All my apologies to Patrick, a bad vimrc and some mistakes make from previous patch something awful.

Quoted 1 line

static struct ifindex_map *ifindex_map[16];

To answer to Patrick, I really don't like to have variable and type with the same name, it's quiet confusing. That's why I change it to "struct ifindex_map_t".

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
#16 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

In reply to Pablo Neira Ayuso
Quoted 11 lines · Pablo Neira Ayuso
Quoted 7 lines · Patrick McHardy

rtnl.c line 134

Quoted 3 lines · Eric Leblond

/* rtnl_receive - receive netlink packets from rtnetlink socket */

rtnl.c +1 -1
-int rtnl_receive()
+int rtnl_receive(int rtnl_fd)

header file needs to be fixed as well. Is the global rtnl_fd still needed?

Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

sorry for leaving such a mess of code for you to clean up. This was initially from a daemon, nothing that would ever clutter somebody elses' namespace.

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
#17 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Hi,

Quoted 4 lines · Pablo Neira Ayuso
Quoted 3 lines

Patrick McHardy wrote:
Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

I've done a big cleaning and I hope I will not annoy Patrick with my coding style problem this time.

I've introduced two structures:

struct rtnl_inst {
       int rtnl_fd;
       int rtnl_seq;
       int rtnl_dump;
       struct sockaddr_nl rtnl_local;
       struct rtnl_handler *handlers;
};
struct nlif_inst {
       struct ifindex_map *ifindex_map[16];
       struct rtnl_inst *rtnl_inst;
       struct rtnl_handler *ifadd_handler;
       struct rtnl_handler *ifdel_handler;
};

which hide all previously defined global variables.

The list of exported functions is the following:

struct nlif_inst *nlif_table_init(void);
void nlif_table_fini(struct nlif_inst *orig);
int nlif_get_fd(struct nlif_inst *nlif_inst); /* to be used in select */ int nlif_treat_msg(struct nlif_inst *nlif_inst);

char *nlif_index_2name(struct nlif_inst *nlif_inst, unsigned int index);

I've just prefixed previously proposed functions with nlif_inst...

Quoted 3 lines

sorry for leaving such a mess of code for you to clean up. This was initially from a daemon, nothing that would ever clutter somebody elses' namespace.

No pb.

BR,
--
Eric Leblond <[email protected]>

=== include/libnfnetlink/libnfnetlink.h
==================================================================

libnfnetlink/libnfnetlink.h +16 -0
@@ -176,6 +176,22 @@
 
 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
 
+struct nlif_inst {
+	struct ifindex_map *ifindex_map[16];
+	struct rtnl_inst *rtnl_inst;
+	struct rtnl_handler *ifadd_handler;
+	struct rtnl_handler *ifdel_handler;
+};
+
+struct nlif_inst *nlif_table_init(void);
+void nlif_table_fini(struct nlif_inst *orig);
+int nlif_get_fd(struct nlif_inst *nlif_inst);
+
+
+char *nlif_index_2name(struct nlif_inst *nlif_inst, unsigned int index);
+int nlif_treat_msg(struct nlif_inst *nlif_inst);
+
+
 /* Pablo: What is the equivalence of be64_to_cpu in userspace?
  * 
  * Harald: Good question.  I don't think there's a standard way [yet?], 

=== src/Makefile.am
==================================================================

Makefile.am +1 -1
@@ -8,4 +8,4 @@
 
 libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles	\
 			  -version-info $(LIBVERSION)
-libnfnetlink_la_SOURCES = libnfnetlink.c 
+libnfnetlink_la_SOURCES = libnfnetlink.c iftable.c rtnl.c

=== src/iftable.c
==================================================================

iftable.c +73 -50

221 lines not on this page · raw message

=== src/rtnl.c
==================================================================

rtnl.c +45 -41

196 lines not on this page · raw message

=== src/rtnl.h
==================================================================

rtnl.h +16 -6
@@ -12,17 +12,27 @@
 	void		*arg;
 };
 
+struct rtnl_inst {
+	int rtnl_fd;
+	int rtnl_seq;
+	int rtnl_dump;
+	struct sockaddr_nl rtnl_local;
+	struct rtnl_handler *handlers;
+};
 
+
+
+
 /* api for handler plugins */
-int rtnl_handler_register(struct rtnl_handler *hdlr);
-int rtnl_handler_unregister(struct rtnl_handler *hdlr);
+int rtnl_handler_register(struct rtnl_inst *rtnl_inst,struct rtnl_handler *hdlr);
+int rtnl_handler_unregister(struct rtnl_inst *rtnl_inst, struct rtnl_handler *hdlr);
 int rtnl_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-int rtnl_dump_type(unsigned int type);
+int rtnl_dump_type(struct rtnl_inst *rtnl_inst, unsigned int type);
 
 /* api for core program */
-int rtnl_init(void);
-void rtnl_fini(void);
-int rtnl_receive();
+struct rtnl_inst *rtnl_init(void);
+void rtnl_fini(struct rtnl_inst *rtnl_inst);
+int rtnl_receive(struct rtnl_inst *rtnl_inst);
   
 
 #endif
#18 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Quoted 5 lines · Eric Leblond

Hi,

Quoted 2 lines · Pablo Neira Ayuso
Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

Patrick McHardy wrote:
Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

I've done a big cleaning and I hope I will not annoy Patrick with my coding style problem this time.

Thanks Eric, no further objections from my side. Pablo is more familiar with this code than myself, so I'll leave it to him to apply it.

#19 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

In reply to Eric Leblond

Hi Eric,

Quoted 11 lines · Eric Leblond
Quoted 4 lines · Pablo Neira Ayuso
Quoted 3 lines

Patrick McHardy wrote:
Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

I've done a big cleaning and I hope I will not annoy Patrick with my coding style problem this time.

I've introduced two structures:

struct rtnl_inst {

              ^^^^

please, rename this to _handle

Quoted 8 lines
       int rtnl_fd;
       int rtnl_seq;
       int rtnl_dump;
       struct sockaddr_nl rtnl_local;
       struct rtnl_handler *handlers;
};

struct nlif_inst {

              ^^^^

same thing here

Quoted 6 lines
       struct ifindex_map *ifindex_map[16];
       struct rtnl_inst *rtnl_inst;
       struct rtnl_handler *ifadd_handler;
       struct rtnl_handler *ifdel_handler;
};
Quoted 8 lines

which hide all previously defined global variables.

The list of exported functions is the following:

struct nlif_inst *nlif_table_init(void);
void nlif_table_fini(struct nlif_inst *orig);
int nlif_get_fd(struct nlif_inst *nlif_inst); /* to be used in select */ int nlif_treat_msg(struct nlif_inst *nlif_inst);

I prefer keeping it homogeneous with libnfnetlink, I would rename the functions above to:

struct nlif_handle *nlif_open(void);
void nlif_close(struct nlif_handle *h);
int nlif_fd(struct nlif_handle *h);
int nlif_catch(struct nlif_handle *h);
char *nlif_index2name(struct nlif_handle *h, unsigned int index);

BTW, could you spend some time on documenting the API in docbook format? I know that this is not available in all netfilter libraries but I'd appreciate it, we should start getting use to do these things ;)

Quoted 5 lines

=== include/libnfnetlink/libnfnetlink.h
==================================================================

libnfnetlink/libnfnetlink.h line 184

Quoted 9 lines
libnfnetlink/libnfnetlink.h +6 -0
@@ -176,6 +176,22 @@
 
 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
 
+struct nlif_inst {
+	struct ifindex_map *ifindex_map[16];
+	struct rtnl_inst *rtnl_inst;
+	struct rtnl_handler *ifadd_handler;
+	struct rtnl_handler *ifdel_handler;
+};

move this definition to an internal header file and just put an empty definition inside libnfnetlink.h like:

struct nlif_handle;

This is better for encapsulation, if we have to modify the layout later for whatever reason, we will not break backward binary compatibility. We just give a pointer to an object with private attributes that are only accesible through the appropiate functions like the nlif_fd() getter.

Quoted 27 lines

=== src/iftable.c
==================================================================

iftable.c +1 -11
@@ -19,6 +19,7 @@
 
 #include <linux/netdevice.h>
 
+#include <libnfnetlink/libnfnetlink.h>
 #include "rtnl.h"
 
 #define iftb_log(x, ...)
@@ -34,28 +35,6 @@
 	char		name[16];
 };
 
-static struct ifindex_map *ifindex_map[16];
-
-/* iftable_dump - Dump the interface table to a given file stream
- * @outfd:	file stream to which table should be dumped
- */
-int iftable_dump(FILE *outfd)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		struct ifindex_map *im;

iftable.c line 57

Quoted 10 lines
iftable.c +0 -10
-		for (im = ifindex_map[i]; im; im = im->next) {
-			fprintf(outfd, "%u %s", im->index, im->name);
-			if (!(im->flags & IFF_UP))
-				fputs(" DOWN", outfd);
-			fputc('\n', outfd);
-		}
-	}
-	fflush(outfd);
-	return 0;
-}

We can introduce some kind of iterator, later:
int nlif_iterate(struct nlif_handle *h, int (*iterate)(void *data));

That's enough for now, we can revisit this later and clean it up a bit more. Thanks.

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#20 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Hi Pablo,

Excellent remarks as usual...

Here's the modified patch.

Quoted 122 lines

Hi Eric,

Quoted 11 lines · Eric Leblond
Quoted 4 lines · Pablo Neira Ayuso
Quoted 3 lines

Patrick McHardy wrote:
Indeed. Eric, all this global stuff below must dissapear at all, from rtnl.c:

I've done a big cleaning and I hope I will not annoy Patrick with my coding style problem this time.

I've introduced two structures:

struct rtnl_inst {

              ^^^^

please, rename this to _handle

Quoted 8 lines
       int rtnl_fd;
       int rtnl_seq;
       int rtnl_dump;
       struct sockaddr_nl rtnl_local;
       struct rtnl_handler *handlers;
};

struct nlif_inst {

              ^^^^

same thing here

Quoted 6 lines
       struct ifindex_map *ifindex_map[16];
       struct rtnl_inst *rtnl_inst;
       struct rtnl_handler *ifadd_handler;
       struct rtnl_handler *ifdel_handler;
};
Quoted 8 lines

which hide all previously defined global variables.

The list of exported functions is the following:

struct nlif_inst *nlif_table_init(void);
void nlif_table_fini(struct nlif_inst *orig);
int nlif_get_fd(struct nlif_inst *nlif_inst); /* to be used in select */ int nlif_treat_msg(struct nlif_inst *nlif_inst);

I prefer keeping it homogeneous with libnfnetlink, I would rename the functions above to:

struct nlif_handle *nlif_open(void);
void nlif_close(struct nlif_handle *h);
int nlif_fd(struct nlif_handle *h);
int nlif_catch(struct nlif_handle *h);
char *nlif_index2name(struct nlif_handle *h, unsigned int index);

BTW, could you spend some time on documenting the API in docbook format? I know that this is not available in all netfilter libraries but I'd appreciate it, we should start getting use to do these things ;)

Quoted 5 lines

=== include/libnfnetlink/libnfnetlink.h
==================================================================

libnfnetlink/libnfnetlink.h line 184

Quoted 9 lines
libnfnetlink/libnfnetlink.h +6 -0
@@ -176,6 +176,22 @@
 
 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
 
+struct nlif_inst {
+	struct ifindex_map *ifindex_map[16];
+	struct rtnl_inst *rtnl_inst;
+	struct rtnl_handler *ifadd_handler;
+	struct rtnl_handler *ifdel_handler;
+};

move this definition to an internal header file and just put an empty definition inside libnfnetlink.h like:

struct nlif_handle;

This is better for encapsulation, if we have to modify the layout later for whatever reason, we will not break backward binary compatibility. We just give a pointer to an object with private attributes that are only accesible through the appropiate functions like the nlif_fd() getter.

Quoted 27 lines

=== src/iftable.c
==================================================================

iftable.c +1 -11
@@ -19,6 +19,7 @@
 
 #include <linux/netdevice.h>
 
+#include <libnfnetlink/libnfnetlink.h>
 #include "rtnl.h"
 
 #define iftb_log(x, ...)
@@ -34,28 +35,6 @@
 	char		name[16];
 };
 
-static struct ifindex_map *ifindex_map[16];
-
-/* iftable_dump - Dump the interface table to a given file stream
- * @outfd:	file stream to which table should be dumped
- */
-int iftable_dump(FILE *outfd)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		struct ifindex_map *im;

iftable.c line 57

Quoted 10 lines
iftable.c +0 -10
-		for (im = ifindex_map[i]; im; im = im->next) {
-			fprintf(outfd, "%u %s", im->index, im->name);
-			if (!(im->flags & IFF_UP))
-				fputs(" DOWN", outfd);
-			fputc('\n', outfd);
-		}
-	}
-	fflush(outfd);
-	return 0;
-}

We can introduce some kind of iterator, later:
int nlif_iterate(struct nlif_handle *h, int (*iterate)(void *data));

Quoted 7 lines

That's enough for now, we can revisit this later and clean it up a bit more. Thanks.

--
The dawn of the fourth age of Linux firewalling is coming; a time of great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris

=== include/libnfnetlink/libnfnetlink.h
==================================================================

libnfnetlink/libnfnetlink.h +11 -0
@@ -176,6 +176,17 @@
 
 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
 
+struct nlif_handle;
+
+struct nlif_handle *nlif_open(void);
+void nlif_close(struct nlif_handle *orig);
+int nlif_fd(struct nlif_handle *nlif_handle);
+
+
+char *nlif_index2name(struct nlif_handle *nlif_handle, unsigned int index);
+int nlif_catch(struct nlif_handle *nlif_handle);
+
+
 /* Pablo: What is the equivalence of be64_to_cpu in userspace?
  * 
  * Harald: Good question.  I don't think there's a standard way [yet?], 

=== src/Makefile.am
==================================================================

Makefile.am +1 -1
@@ -8,4 +8,4 @@
 
 libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles	\
 			  -version-info $(LIBVERSION)
-libnfnetlink_la_SOURCES = libnfnetlink.c 
+libnfnetlink_la_SOURCES = libnfnetlink.c iftable.c rtnl.c

=== src/iftable.c
==================================================================

iftable.c +115 -49

262 lines not on this page · raw message

=== src/rtnl.c
==================================================================

rtnl.c +56 -47

207 lines not on this page · raw message

=== src/rtnl.h
==================================================================

rtnl.h +16 -6
@@ -12,17 +12,27 @@
 	void		*arg;
 };
 
+struct rtnl_handle {
+	int rtnl_fd;
+	int rtnl_seq;
+	int rtnl_dump;
+	struct sockaddr_nl rtnl_local;
+	struct rtnl_handler *handlers;
+};
 
+
+
+
 /* api for handler plugins */
-int rtnl_handler_register(struct rtnl_handler *hdlr);
-int rtnl_handler_unregister(struct rtnl_handler *hdlr);
+int rtnl_handler_register(struct rtnl_handle *rtnl_handle,struct rtnl_handler *hdlr);
+int rtnl_handler_unregister(struct rtnl_handle *rtnl_handle, struct rtnl_handler *hdlr);
 int rtnl_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-int rtnl_dump_type(unsigned int type);
+int rtnl_dump_type(struct rtnl_handle *rtnl_handle, unsigned int type);
 
 /* api for core program */
-int rtnl_init(void);
-void rtnl_fini(void);
-int rtnl_receive();
+struct rtnl_handle *rtnl_init(void);
+void rtnl_fini(struct rtnl_handle *rtnl_handle);
+int rtnl_receive(struct rtnl_handle *rtnl_handle);
   
 
 #endif
#21 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Quoted 5 lines · Eric Leblond

Hi Pablo,

Excellent remarks as usual...

Here's the modified patch.

There's only some really cosmetic point that I wnat to make: I believe it's not always within 80 characters wide lines (or is that just in the patch due to different tab expansion?). But we can do that even after the commit ;)

Technically, I'm happy with the changes.

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
#22 lore raw

Re: [Patch 1/2] libnfnetlink, iface conversion to string

Quoted 4 lines · Harald Welte

There's only some really cosmetic point that I wnat to make: I believe it's not always within 80 characters wide lines (or is that just in the patch due to different tab expansion?). But we can do that even after the commit ;)

Indeed, I just splitted some line to fit into 80 chars and remove some blank lines, then I applied the patch to SVN.

Eric, have a look at Documentation/CodingStyle inside the kernel tree, that is basically the same policy that the netfilter project follows for everything inside and outside kernel, everyone will appreciate it ;)

BTW, I have inserted a test file under utils/ called iftable.c. I introduced again two minor changes in the API since the last discussion to keep it homogeneous with libnfnetlink:

int nlif_index2name(handler, index, name): Now you have to pass a buffer of IFNAMSIZ where the interface name will be copied, better than the previous that returns a pointer that needs to be "duplicated".

int nlif_query(handler): Call this function to request a whole dump of the interface table, you have to call this after nlif_open, but someone could call it elsewhere to request a whole resync with the interface table.

int nlif_catch(handle): Call this to update the table in the event of changes

As Harald said, there are more cleanups still pending, like setting errno to report errors, some possible const'ification, assertions, probably move to linux_list interface instead of the array of pointers to interface structures... Once we've solved this stuff I'll prepare another libraries release.

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#23 lore raw

PATCH 2/2 libnetfilter_queue, iface conversion to string

In reply to Pablo Neira Ayuso

Hi,

Here's the updated patch for libnetfilter_queue.

BR
--
Eric Leblond <[email protected]>

=== include/libnetfilter_queue/libnetfilter_queue.h
==================================================================

libnetfilter_queue/libnetfilter_queue.h +5 -0
@@ -80,6 +80,11 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+extern char *nfq_get_indev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad);
+extern char *nfq_get_physindev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad);
+extern char *nfq_get_outdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad);
+extern char *nfq_get_physoutdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad);
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */

=== src/libnetfilter_queue.c
==================================================================

libnetfilter_queue.c +25 -0
@@ -419,6 +419,31 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char *nfq_get_indev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index2name(nlif_handle, ifindex);
+}
+
+char *nfq_get_physindev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physindev(nfad);
+	return nlif_index2name(nlif_handle, ifindex);
+}
+
+char *nfq_get_outdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_outdev(nfad);
+	return nlif_index2name(nlif_handle, ifindex);
+}
+
+char *nfq_get_physoutdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physoutdev(nfad);
+	return nlif_index2name(nlif_handle, ifindex);
+}
+
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
#24 lore raw

Re: [Patch 2/2] libnetfilter_queue, iface conversion to string

Eric,

Quoted 1 line · Eric Leblond

Here's the updated patch for libnetfilter_queue.

Could you resend a patch that fits the change that I introduced in nlif_index2name that requires a buffer to be passed? Thanks.

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#25 lore raw

Re: [Patch 2/2] libnetfilter_queue, iface conversion to string

Hi,

Quoted 7 lines · Pablo Neira Ayuso

Eric,

Quoted 1 line · Eric Leblond

Here's the updated patch for libnetfilter_queue.

Could you resend a patch that fits the change that I introduced in nlif_index2name that requires a buffer to be passed? Thanks.

Here's the related patch.

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
libnetfilter_queue/libnetfilter_queue.h +9 -0
Index: include/libnetfilter_queue/libnetfilter_queue.h
===================================================================
@@ -80,6 +80,15 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+extern int nfq_get_indev_name(struct nlif_handle *nlif_handle,
+			      struct nfq_data *nfad, char *name);
+extern int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
+			          struct nfq_data *nfad, char *name);
+extern int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
+			       struct nfq_data *nfad, char *name);
+extern int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
+				   struct nfq_data *nfad, char *name);
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */
libnetfilter_queue.c +29 -0
Index: src/libnetfilter_queue.c
===================================================================
@@ -419,6 +419,35 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+int nfq_get_indev_name(struct nlif_handle *nlif_handle,
+			struct nfq_data *nfad, char *name)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index2name(nlif_handle, ifindex, name);
+}
+
+int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
+			   struct nfq_data *nfad, char *name)
+{
+	u_int32_t ifindex = nfq_get_physindev(nfad);
+	return nlif_index2name(nlif_handle, ifindex, name);
+}
+
+int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
+			struct nfq_data *nfad, char *name)
+{
+	u_int32_t ifindex = nfq_get_outdev(nfad);
+	return nlif_index2name(nlif_handle, ifindex, name);
+}
+
+int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
+			    struct nfq_data *nfad, char *name)
+{
+	u_int32_t ifindex = nfq_get_physoutdev(nfad);
+	return nlif_index2name(nlif_handle, ifindex, name);
+}
+
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
maintainer Applied
#26 lore raw

Re: [Patch 2/2] libnetfilter_queue, iface conversion to string

Quoted 1 line · Eric Leblond

Here's the related patch.

Applied. Merci Eric.

Signature · 2 lines
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
#27 lore raw

PATCH 2/2 libnetfilter_queue and iface conversion to string

In reply to Eric Leblond

Hi,

Here's the patch against libnetfilter_queue.

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
libnetfilter_queue/libnetfilter_queue.h +5 -0
Index: include/libnetfilter_queue/libnetfilter_queue.h
===================================================================
@@ -80,6 +80,11 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+extern char* nfq_get_indev_name(struct nfq_data *nfad);
+extern char* nfq_get_physindev_name(struct nfq_data *nfad);
+extern char* nfq_get_outdev_name(struct nfq_data *nfad);
+extern char* nfq_get_physoutdev_name(struct nfq_data *nfad);
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */
libnetfilter_queue.c +25 -0
Index: src/libnetfilter_queue.c
===================================================================
@@ -419,6 +419,31 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char* nfq_get_indev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char* nfq_get_physindev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physindev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char* nfq_get_outdev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_outdev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char* nfq_get_physoutdev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physoutdev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
#28 lore raw

Re: [Patch 2/2] libnetfilter_queue and iface conversion to string

Quoted 5 lines · Eric Leblond

Index: src/libnetfilter_queue.c
===================================================================

libnetfilter_queue.c line 427

Quoted 9 lines
libnetfilter_queue.c +6 -0
@@ -419,6 +419,31 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char* nfq_get_indev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index_2name(ifindex);
+}
+

This might appear annoying, but I don't like inconsistency since it distracts me. So char * please, as in the parameters or in the other functions in this file.

#29 lore raw

Resend: [Patch 2/2] libnetfilter_queue and iface conversion to string

Hi,

Quoted 7 lines · Patrick McHardy

Review

Quoted 3 lines · Eric Leblond

Index: src/libnetfilter_queue.c

(quoted diff) +2 -0
+char* nfq_get_indev_name(struct nfq_data *nfad)
+{

This might appear annoying, but I don't like inconsistency since it distracts me. So char * please, as in the parameters or in the other functions in this file.

Ok, not a problem. I'm sorry that I've missed this coding style point too :(

BR,

Signature · 2 lines
Eric Leblond <[email protected]>
INL
libnetfilter_queue/libnetfilter_queue.h +5 -0
Index: include/libnetfilter_queue/libnetfilter_queue.h
===================================================================
@@ -80,6 +80,11 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+extern char *nfq_get_indev_name(struct nfq_data *nfad);
+extern char *nfq_get_physindev_name(struct nfq_data *nfad);
+extern char *nfq_get_outdev_name(struct nfq_data *nfad);
+extern char *nfq_get_physoutdev_name(struct nfq_data *nfad);
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */
libnetfilter_queue.c +25 -0
Index: src/libnetfilter_queue.c
===================================================================
@@ -419,6 +419,31 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char *nfq_get_indev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char *nfq_get_physindev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physindev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char *nfq_get_outdev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_outdev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+char *nfq_get_physoutdev_name(struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physoutdev(nfad);
+	return nlif_index_2name(ifindex);
+}
+
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
#30 lore raw

Resend: [Patch 2/2] libnetfilter_queue and iface conversion to string

Hi,

Here's the patch which adapts libnetfilter_queue to last sent patch.

BR,
--
Eric

=== include/libnetfilter_queue/libnetfilter_queue.h
==================================================================

libnetfilter_queue/libnetfilter_queue.h +5 -0
@@ -80,6 +80,11 @@
 extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
 extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
 
+extern char *nfq_get_indev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad);
+extern char *nfq_get_physindev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad);
+extern char *nfq_get_outdev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad);
+extern char *nfq_get_physoutdev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad);
+
 extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
 
 /* return -1 if problem, length otherwise */

=== src/libnetfilter_queue.c
==================================================================

libnetfilter_queue.c +25 -0
@@ -419,6 +419,31 @@
 	return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
 }
 
+char *nfq_get_indev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_indev(nfad);
+	return nlif_index_2name(nlif_inst, ifindex);
+}
+
+char *nfq_get_physindev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physindev(nfad);
+	return nlif_index_2name(nlif_inst, ifindex);
+}
+
+char *nfq_get_outdev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_outdev(nfad);
+	return nlif_index_2name(nlif_inst, ifindex);
+}
+
+char *nfq_get_physoutdev_name(struct nlif_inst *nlif_inst, struct nfq_data *nfad)
+{
+	u_int32_t ifindex = nfq_get_physoutdev(nfad);
+	return nlif_index_2name(nlif_inst, ifindex);
+}
+
+
 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
 {
 	return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
#31 lore raw
In reply to Pablo Neira Ayuso
Quoted 11 lines · Pablo Neira Ayuso
Quoted 9 lines · Eric Leblond

I'm currently working on NuFW where I try to do iface conversion from integer to string to be able to filter "naturally" on interfaces.

For now, it is impossible to do this conversion from either libnetfilter_queue or libnfnetlink. But there is two files in libnfnetlink (iftable.c and rntl.c) which have been put here by Harald to provide this conversion (if I remember correctly an old mail from Harald).

Quoted 3 lines
Quoted 3 lines

It was a long time ago and I don't know if it still planned to modify libnfnetlink to include this feature. Or, would it be a better choice to create a new library dedicated to this conversion.

There already is libnl .. it may be a bit overkill if all you need is ifindex<->ifname conversion though.

Quoted 6 lines

Interesting question. Since this is related with the rtnetlink subsystem, I'm unsure that this feature naturally belongs to libnfnetlink nor to libnetfilter_queue.

However, IMO libnetfilter_queue should provide enough features to let userspace apps implement filtering without requiring extra dependencies.

Agreed, this would be a good addition in my opinion. Probably better to keep in it libnfnetlink since that doesn't require people to unnecessarily link libnfnetlink_queue just for this.