All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add mark to packet from libipq
@ 2003-10-16  0:09 Eric Leblond
  2003-10-16  7:08 ` Henrik Nordstrom
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Leblond @ 2003-10-16  0:09 UTC (permalink / raw)
  To: netfilter-devel; +Cc: nufw-devel


[-- Attachment #1.1: Type: text/plain, Size: 399 bytes --]

Hi,

I've done really slight modification to the ip_queue module and to
lip_ipq to add a fonction that can change the mark of a packet and set a
verdict to it (its name is ipq_set_vwmark).

It permits to NuFW to add a mark equal to user id on packet, thus
enabling to set up a users based QOS, accounting, ... 

BR,
-- 
Eric Leblond
Nufw, Now User Filtering Works (http://www.nufw.org)

[-- Attachment #1.2: libipq.diff --]
[-- Type: text/x-patch, Size: 2477 bytes --]

diff -ru iptables-1.2.8.orig/include/libipq/libipq.h iptables-1.2.8/include/libipq/libipq.h
--- iptables-1.2.8.orig/include/libipq/libipq.h	2003-10-16 01:53:08.000000000 +0200
+++ iptables-1.2.8/include/libipq/libipq.h	2003-10-16 01:55:13.000000000 +0200
@@ -79,6 +79,14 @@
                     size_t data_len,
                     unsigned char *buf);
 
+int ipq_set_vwmark(const struct ipq_handle *h,
+                    ipq_id_t id,
+                    unsigned int verdict,
+                    unsigned int nfmark,
+                    unsigned int mask,
+                    size_t data_len,
+                    unsigned char *buf);
+
 int ipq_ctl(const struct ipq_handle *h, int request, ...);
 
 char *ipq_errstr(void);
diff -ru iptables-1.2.8.orig/libipq/libipq.c iptables-1.2.8/libipq/libipq.c
--- iptables-1.2.8.orig/libipq/libipq.c	2003-10-16 01:58:46.000000000 +0200
+++ iptables-1.2.8/libipq/libipq.c	2003-10-16 00:27:58.000000000 +0200
@@ -348,6 +348,56 @@
 	return ipq_netlink_sendmsg(h, &msg, 0);
 }
 
+int ipq_set_vwmark(const struct ipq_handle *h,
+                    ipq_id_t id,
+                    unsigned int verdict,
+                    unsigned long nfmark,
+                    unsigned long mask,
+                    size_t data_len,
+                    unsigned char *buf)
+{
+	unsigned char nvecs;
+	size_t tlen;
+	struct nlmsghdr nlh;
+	ipq_peer_msg_t pm;
+	struct iovec iov[3];
+	struct msghdr msg;
+
+	memset(&nlh, 0, sizeof(nlh));
+	nlh.nlmsg_flags = NLM_F_REQUEST;
+	nlh.nlmsg_type = IPQM_VWMARK;
+	nlh.nlmsg_pid = h->local.nl_pid;
+	memset(&pm, 0, sizeof(pm));
+	pm.msg.vwmark.value = verdict;
+	pm.msg.vwmark.id = id;
+	pm.msg.vwmark.data_len = data_len;
+	pm.msg.vwmark.nfmark = nfmark;
+	pm.msg.vwmark.mask = mask;
+	iov[0].iov_base = &nlh;
+	iov[0].iov_len = sizeof(nlh);
+	iov[1].iov_base = ±
+	iov[1].iov_len = sizeof(pm);
+	tlen = sizeof(nlh) + sizeof(pm);
+	nvecs = 2;
+	if (data_len && buf) {
+		iov[2].iov_base = buf;
+		iov[2].iov_len = data_len;
+		tlen += data_len;
+		nvecs++;
+	}
+	msg.msg_name = (void *)&h->peer;
+	msg.msg_namelen = sizeof(h->peer);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = nvecs;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = 0;
+	nlh.nlmsg_len = tlen;
+	return ipq_netlink_sendmsg(h, &msg, 0);
+}
+
+
+
 /* Not implemented yet */
 int ipq_ctl(const struct ipq_handle *h, int request, ...)
 {

[-- Attachment #1.3: ip_queue.diff --]
[-- Type: text/plain, Size: 2585 bytes --]

--- linux.orig/net/ipv4/netfilter/ip_queue.c	2003-10-16 01:46:27.000000000 +0200
+++ linux/net/ipv4/netfilter/ip_queue.c	2003-10-16 00:31:02.000000000 +0200
@@ -417,6 +417,33 @@
 }
 
 static int
+ipq_set_vwmark(struct ipq_vwmark_msg *vmsg, unsigned int len)
+{
+	struct ipq_queue_entry *entry;
+
+	if (vmsg->value > NF_MAX_VERDICT)
+		return -EINVAL;
+
+	entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
+	if (entry == NULL)
+		return -ENOENT;
+	else {
+		int verdict = vmsg->value;
+		
+		if (vmsg->data_len && vmsg->data_len == len)
+			if (ipq_mangle_ipv4((ipq_verdict_msg_t *)vmsg, entry) < 0)
+				verdict = NF_DROP;
+
+		/* set mark of associated skb */
+		entry->skb->nfmark = vmsg->nfmark & vmsg->mask;
+		
+		ipq_issue_verdict(entry, verdict);
+		return 0;
+	}
+}
+
+
+static int
 ipq_receive_peer(struct ipq_peer_msg *pmsg,
                  unsigned char type, unsigned int len)
 {
@@ -438,6 +465,14 @@
 			status = ipq_set_verdict(&pmsg->msg.verdict,
 			                         len - sizeof(*pmsg));
 			break;
+        case IPQM_VWMARK:
+		if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
+			status = -EINVAL;
+		else
+			status = ipq_set_vwmark(&pmsg->msg.vwmark,
+			                         len - sizeof(*pmsg));
+			break;
+
 	default:
 		status = -EINVAL;
 	}
--- linux.orig/include/linux/netfilter_ipv4/ip_queue.h	2003-10-16 01:47:01.000000000 +0200
+++ linux/include/linux/netfilter_ipv4/ip_queue.h	2003-10-15 23:36:21.000000000 +0200
@@ -47,10 +47,21 @@
 	unsigned char payload[0];	/* Optional replacement packet */
 } ipq_verdict_msg_t;
 
+typedef struct ipq_vwmark_msg {
+	unsigned int value;		/* Verdict to hand to netfilter */
+	unsigned long id;		/* Packet ID for this verdict */
+	size_t data_len;		/* Length of replacement data */
+	unsigned char payload[0];	/* Optional replacement packet */
+	unsigned long nfmark;		/* Mark for the Packet */
+	unsigned long mask;	        /* Mark Mask for the Packet */
+} ipq_vwmark_msg_t;
+
+
 typedef struct ipq_peer_msg {
 	union {
 		ipq_verdict_msg_t verdict;
 		ipq_mode_msg_t mode;
+                ipq_vwmark_msg_t vwmark;
 	} msg;
 } ipq_peer_msg_t;
 
@@ -67,6 +78,7 @@
 #define IPQM_MODE	(IPQM_BASE + 1)		/* Mode request from peer */
 #define IPQM_VERDICT	(IPQM_BASE + 2)		/* Verdict from peer */ 
 #define IPQM_PACKET	(IPQM_BASE + 3)		/* Packet from kernel */
-#define IPQM_MAX	(IPQM_BASE + 4)
+#define IPQM_VWMARK	(IPQM_BASE + 4)		/* Verdict and mark from peer */
+#define IPQM_MAX	(IPQM_BASE + 5)
 
 #endif /*_IP_QUEUE_H*/

[-- Attachment #2: Ceci est une partie de message numériquement signée. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add mark to packet from libipq
  2003-10-16  0:09 [PATCH] Add mark to packet from libipq Eric Leblond
@ 2003-10-16  7:08 ` Henrik Nordstrom
  2003-10-16  7:23   ` Eric Leblond
  0 siblings, 1 reply; 5+ messages in thread
From: Henrik Nordstrom @ 2003-10-16  7:08 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, nufw-devel

On Thu, 16 Oct 2003, Eric Leblond wrote:

> Hi,
> 
> I've done really slight modification to the ip_queue module and to
> lip_ipq to add a fonction that can change the mark of a packet and set a
> verdict to it (its name is ipq_set_vwmark).
> 
> It permits to NuFW to add a mark equal to user id on packet, thus
> enabling to set up a users based QOS, accounting, ... 

I have one question regarding the mark mask value in the kernel message..  
what is the purpose of this? Todays implementation looks rather wasteful
as the userspace may just as well apply the mask before the value is sent
to the kernel.

If you are to have a mask I propose this mask indicates which bits to save 
of the original mark, not a mask to the new mark value. I.e. something 
like this:

            /* set mark of associated skb */
            entry->skb->nfmark = vmsg->nfmark | (entry->skb->nfmark & vmsg->mask);

(alernately mask may be inverted)

but in reality this is not needed either as the userspace knows the
original mask and can a apply whatever transformations it likes 
when giving the new verdict mask.

Regards
Henrik

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add mark to packet from libipq
  2003-10-16  7:08 ` Henrik Nordstrom
@ 2003-10-16  7:23   ` Eric Leblond
  2003-10-16  7:31     ` Henrik Nordstrom
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Leblond @ 2003-10-16  7:23 UTC (permalink / raw)
  To: Henrik Nordstrom; +Cc: netfilter-devel, nufw-devel

[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]

Le jeu 16/10/2003 à 09:08, Henrik Nordstrom a écrit :
> On Thu, 16 Oct 2003, Eric Leblond wrote:
> 
> I have one question regarding the mark mask value in the kernel message..  
> what is the purpose of this? Todays implementation looks rather wasteful
> as the userspace may just as well apply the mask before the value is sent
> to the kernel.
> If you are to have a mask I propose this mask indicates which bits to save 
> of the original mark, not a mask to the new mark value. I.e. something 
> like this:
> 
>             /* set mark of associated skb */
>             entry->skb->nfmark = vmsg->nfmark | (entry->skb->nfmark & vmsg->mask);
> 
> (alernately mask may be inverted)

That's what I was wanted ! I was too tired yesterday to see the huge
error I've done. I've found it at the end of my sleep ;-) you're mail
give the answer.
One other question I have it's whether or not it necessary to add
verdict value in the message if using mark sys call ?
If we mark the packet we wen to let it pass trough the gateway...

It will require some work (modification of some functions in ip_queue)
to do so but it's maybe a cleaner way to do.

> but in reality this is not needed either as the userspace knows the
> original mask and can a apply whatever transformations it likes 
> when giving the new verdict mask.

How could userspace knows it ?

BR,
-- 
Eric Leblond
Nufw, Now User Filtering Works (http://www.nufw.org)

[-- Attachment #2: Ceci est une partie de message numériquement signée. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add mark to packet from libipq
  2003-10-16  7:23   ` Eric Leblond
@ 2003-10-16  7:31     ` Henrik Nordstrom
  2003-10-16 22:13       ` Eric Leblond
  0 siblings, 1 reply; 5+ messages in thread
From: Henrik Nordstrom @ 2003-10-16  7:31 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, nufw-devel

On Thu, 16 Oct 2003, Eric Leblond wrote:

> > but in reality this is not needed either as the userspace knows the
> > original mask and can a apply whatever transformations it likes 
> > when giving the new verdict mask.
> 
> How could userspace knows it ?

It got the mark with the packet in packet_msg->mark, so the userspace
application can just apply the transformation it likes when setting the
verdict.

Example using mask operation

   mark = newvalue | (packet_msg->mark & mask);

but obviously other transformations is possible as well.

Regards
Henrik

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add mark to packet from libipq
  2003-10-16  7:31     ` Henrik Nordstrom
@ 2003-10-16 22:13       ` Eric Leblond
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Leblond @ 2003-10-16 22:13 UTC (permalink / raw)
  To: Henrik Nordstrom; +Cc: netfilter-devel, nufw-devel


[-- Attachment #1.1: Type: text/plain, Size: 532 bytes --]

Le jeu 16/10/2003 à 09:31, Henrik Nordstrom a écrit :
> On Thu, 16 Oct 2003, Eric Leblond wrote:
> It got the mark with the packet in packet_msg->mark, so the userspace
> application can just apply the transformation it likes when setting the
> verdict.

I've done this changes and suppress references to a mask.
I attach the diffs for module and lib.

The code is tested on my box with nufw (CVS version) so it is in state :
Work For Me.

BR,
-- 
Eric Leblond
Nufw, Now User Filtering Works (http://www.nufw.org)

[-- Attachment #1.2: ip_queue.diff --]
[-- Type: text/plain, Size: 2510 bytes --]

--- linux.orig/include/linux/netfilter_ipv4/ip_queue.h	2003-10-16 01:47:01.000000000 +0200
+++ linux/include/linux/netfilter_ipv4/ip_queue.h	2003-10-16 23:53:17.000000000 +0200
@@ -47,10 +47,20 @@
 	unsigned char payload[0];	/* Optional replacement packet */
 } ipq_verdict_msg_t;
 
+typedef struct ipq_vwmark_msg {
+	unsigned int value;		/* Verdict to hand to netfilter */
+	unsigned long id;		/* Packet ID for this verdict */
+	size_t data_len;		/* Length of replacement data */
+	unsigned char payload[0];	/* Optional replacement packet */
+	unsigned long nfmark;		/* Mark for the Packet */
+} ipq_vwmark_msg_t;
+
+
 typedef struct ipq_peer_msg {
 	union {
 		ipq_verdict_msg_t verdict;
 		ipq_mode_msg_t mode;
+                ipq_vwmark_msg_t vwmark;
 	} msg;
 } ipq_peer_msg_t;
 
@@ -67,6 +77,7 @@
 #define IPQM_MODE	(IPQM_BASE + 1)		/* Mode request from peer */
 #define IPQM_VERDICT	(IPQM_BASE + 2)		/* Verdict from peer */ 
 #define IPQM_PACKET	(IPQM_BASE + 3)		/* Packet from kernel */
-#define IPQM_MAX	(IPQM_BASE + 4)
+#define IPQM_VWMARK	(IPQM_BASE + 4)		/* Verdict and mark from peer */
+#define IPQM_MAX	(IPQM_BASE + 5)
 
 #endif /*_IP_QUEUE_H*/
--- linux.orig/net/ipv4/netfilter/ip_queue.c	2003-10-16 01:46:27.000000000 +0200
+++ linux/net/ipv4/netfilter/ip_queue.c	2003-10-16 23:54:11.000000000 +0200
@@ -417,6 +417,33 @@
 }
 
 static int
+ipq_set_vwmark(struct ipq_vwmark_msg *vmsg, unsigned int len)
+{
+	struct ipq_queue_entry *entry;
+
+	if (vmsg->value > NF_MAX_VERDICT)
+		return -EINVAL;
+
+	entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
+	if (entry == NULL)
+		return -ENOENT;
+	else {
+		int verdict = vmsg->value;
+		
+		if (vmsg->data_len && vmsg->data_len == len)
+			if (ipq_mangle_ipv4((ipq_verdict_msg_t *)vmsg, entry) < 0)
+				verdict = NF_DROP;
+
+		/* set mark of associated skb */
+		entry->skb->nfmark = vmsg->nfmark;
+		
+		ipq_issue_verdict(entry, verdict);
+		return 0;
+	}
+}
+
+
+static int
 ipq_receive_peer(struct ipq_peer_msg *pmsg,
                  unsigned char type, unsigned int len)
 {
@@ -438,6 +465,14 @@
 			status = ipq_set_verdict(&pmsg->msg.verdict,
 			                         len - sizeof(*pmsg));
 			break;
+        case IPQM_VWMARK:
+		if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
+			status = -EINVAL;
+		else
+			status = ipq_set_vwmark(&pmsg->msg.vwmark,
+			                         len - sizeof(*pmsg));
+			break;
+
 	default:
 		status = -EINVAL;
 	}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: libipq.diff --]
[-- Type: text/x-patch; name=libipq.diff; charset=UTF-8, Size: 2475 bytes --]

diff -ru iptables-1.2.8.orig/include/libipq/libipq.h iptables-1.2.8/include/libipq/libipq.h
--- iptables-1.2.8.orig/include/libipq/libipq.h	2003-10-16 01:53:08.000000000 +0200
+++ iptables-1.2.8/include/libipq/libipq.h	2003-10-16 23:47:35.000000000 +0200
@@ -79,6 +79,13 @@
                     size_t data_len,
                     unsigned char *buf);
 
+int ipq_set_vwmark(const struct ipq_handle *h,
+                    ipq_id_t id,
+                    unsigned int verdict,
+                    unsigned long nfmark,
+                    size_t data_len,
+                    unsigned char *buf);
+
 int ipq_ctl(const struct ipq_handle *h, int request, ...);
 
 char *ipq_errstr(void);
Les fichiers binaires iptables-1.2.8.orig/libipq/libipq.a et iptables-1.2.8/libipq/libipq.a sont différents.
diff -ru iptables-1.2.8.orig/libipq/libipq.c iptables-1.2.8/libipq/libipq.c
--- iptables-1.2.8.orig/libipq/libipq.c	2003-10-16 01:58:46.000000000 +0200
+++ iptables-1.2.8/libipq/libipq.c	2003-10-16 23:33:10.000000000 +0200
@@ -348,6 +348,54 @@
 	return ipq_netlink_sendmsg(h, &msg, 0);
 }
 
+int ipq_set_vwmark(const struct ipq_handle *h,
+                    ipq_id_t id,
+                    unsigned int verdict,
+                    unsigned long nfmark,
+                    size_t data_len,
+                    unsigned char *buf)
+{
+	unsigned char nvecs;
+	size_t tlen;
+	struct nlmsghdr nlh;
+	ipq_peer_msg_t pm;
+	struct iovec iov[3];
+	struct msghdr msg;
+
+	memset(&nlh, 0, sizeof(nlh));
+	nlh.nlmsg_flags = NLM_F_REQUEST;
+	nlh.nlmsg_type = IPQM_VWMARK;
+	nlh.nlmsg_pid = h->local.nl_pid;
+	memset(&pm, 0, sizeof(pm));
+	pm.msg.vwmark.value = verdict;
+	pm.msg.vwmark.id = id;
+	pm.msg.vwmark.data_len = data_len;
+	pm.msg.vwmark.nfmark = nfmark;
+	iov[0].iov_base = &nlh;
+	iov[0].iov_len = sizeof(nlh);
+	iov[1].iov_base = &pm;
+	iov[1].iov_len = sizeof(pm);
+	tlen = sizeof(nlh) + sizeof(pm);
+	nvecs = 2;
+	if (data_len && buf) {
+		iov[2].iov_base = buf;
+		iov[2].iov_len = data_len;
+		tlen += data_len;
+		nvecs++;
+	}
+	msg.msg_name = (void *)&h->peer;
+	msg.msg_namelen = sizeof(h->peer);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = nvecs;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = 0;
+	nlh.nlmsg_len = tlen;
+	return ipq_netlink_sendmsg(h, &msg, 0);
+}
+
+
+
 /* Not implemented yet */
 int ipq_ctl(const struct ipq_handle *h, int request, ...)
 {

[-- Attachment #2: Ceci est une partie de message numériquement signée. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-10-16 22:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-16  0:09 [PATCH] Add mark to packet from libipq Eric Leblond
2003-10-16  7:08 ` Henrik Nordstrom
2003-10-16  7:23   ` Eric Leblond
2003-10-16  7:31     ` Henrik Nordstrom
2003-10-16 22:13       ` Eric Leblond

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.