libnfnetlink and iface conversion to string
Subsystems (3)
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
Pablo Neira Ayuso
maintainerQuoted 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_queueor libnfnetlink. But there is two files in libnfnetlink (iftable.candrntl.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
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_queueshould 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
@@ -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
@@ -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
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
@@ -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
@@ -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
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.
PATCH 2/2 getting iface name from libnetfilter_queue
In reply to Eric LeblondHi,
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_queueshould 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_queuemessage 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
@@ -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
@@ -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
@@ -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
@@ -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,
Quoted 2 lines · Eric Leblond
It will add 4*IFNAMSIZ = 64 octets to each
nfnetlink_queuemessage 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
Hi,
Quoted 10 lines · Harald Welte
Quoted 2 lines · Eric Leblond
It will add 4*IFNAMSIZ = 64 octets to each
nfnetlink_queuemessage 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
Pablo Neira Ayuso
maintainerQuoted 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
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 */
structnfnl_ifindex2name_table*nfnl_ifindex2name_open(); /* destroy table */
voidnfnl_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 */
voidnfnl_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_queueapplication.
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
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_queuemessage 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
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.candiftable.cHowever, 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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
-1nladdr.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
-11u_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
Pablo Neira Ayuso
maintainerRe: [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_fdstill 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
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_fdstill 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
Re: [Patch 1/2] libnfnetlink, iface conversion to string
In reply to Pablo Neira AyusoQuoted 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_fdstill 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
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, fromrtnl.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
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, fromrtnl.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.
Pablo Neira Ayuso
maintainerRe: [Patch 1/2] libnfnetlink, iface conversion to string
In reply to Eric LeblondHi 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, fromrtnl.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);
voidnlif_table_fini(struct nlif_inst *orig);
intnlif_get_fd(struct nlif_inst *nlif_inst); /* to be used in select */ intnlif_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
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, fromrtnl.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
_handleQuoted 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);
voidnlif_table_fini(struct nlif_inst *orig);
intnlif_get_fd(struct nlif_inst *nlif_inst); /* to be used in select */ intnlif_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);
voidnlif_close(struct nlif_handle *h);
intnlif_fd(struct nlif_handle *h);
intnlif_catch(struct nlif_handle *h);
char *nlif_index2name(structnlif_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.hlike: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:
intnlif_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
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
Pablo Neira Ayuso
maintainerRe: [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
PATCH 2/2 libnetfilter_queue, iface conversion to string
In reply to Pablo Neira AyusoHi,
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,
Pablo Neira Ayuso
maintainerRe: [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
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_index2namethat 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
@@ -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
@@ -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,
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
PATCH 2/2 libnetfilter_queue and iface conversion to string
In reply to Eric LeblondHi,
Here's the patch against libnetfilter_queue.
BR,
Signature · 2 lines
Eric Leblond <[email protected]> INL
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 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
@@ -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,
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.
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
@@ -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
@@ -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,
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,
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_queueor libnfnetlink. But there is two files in libnfnetlink (iftable.candrntl.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_queueshould 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.