Hey
so now I changed the tagging from tcp_output to ip_output.
I also put an pf_tag_unref to so_free and sosetopt (in case that there
is allready a tag set).
I couldn't see a reason for a pf_tag_unref in the so_accept because
the socket could be reused.
Thanks to Henning for the ideas!
Any further ideas ? I'm in a good run :)
So and finally with an cvs diff on current:
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.67
diff -u -p -r1.67 uipc_socket.c
--- kern/uipc_socket.c 20 Dec 2007 17:16:50 -0000 1.67
+++ kern/uipc_socket.c 6 Mar 2008 19:40:42 -0000
@@ -48,6 +48,8 @@
#include <sys/resourcevar.h>
#include <sys/pool.h>
+#include <net/pfvar.h>
+
void filt_sordetach(struct knote *kn);
int filt_soread(struct knote *kn, long hint);
void filt_sowdetach(struct knote *kn);
@@ -115,6 +117,7 @@ socreate(int dom, struct socket **aso, i
so->so_rgid = p->p_cred->p_rgid;
so->so_egid = p->p_ucred->cr_gid;
so->so_cpid = p->p_pid;
+ so->so_pftag = 0;
so->so_proto = prp;
error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
(struct mbuf *)(long)proto, NULL);
@@ -188,6 +191,10 @@ sofree(struct socket *so)
if (!soqremque(so, 0))
return;
}
+
+ if(so->so_pftag != 0)
+ pf_tag_unref(so->so_pftag);
+
sbrelease(&so->so_snd);
sorflush(so);
pool_put(&socket_pool, so);
@@ -1085,6 +1092,25 @@ sosetopt(struct socket *so, int level, i
}
break;
}
+
+ case SO_PFTAG:
+ {
+ if (m == NULL) {
+ error = EINVAL;
+ goto bad;
+ }
+ if(so->so_pftag != 0)
+ {
+ pf_tag_unref(so->so_pftag);
+ }
+ so->so_pftag = pf_tagname2tag(mtod(m, char *));
+ if(so->so_pftag == 0)
+ {
+ error = EINVAL; /*XXX*/
+ goto bad;
+ }
+ break;
+ }
default:
error = ENOPROTOOPT;
@@ -1173,6 +1199,14 @@ sogetopt(struct socket *so, int level, i
mtod(m, struct timeval *)->tv_sec = val / hz;
mtod(m, struct timeval *)->tv_usec =
(val % hz) * tick;
+ break;
+ }
+ case SO_PFTAG:
+ {
+ char tagname[PF_TAG_NAME_SIZE];
+ pf_tag2tagname(so->so_pftag, tagname);
+ m->m_len = strlen(tagname) + 1;
+ strlcpy(mtod(m, char *), tagname, m->m_len);
break;
}
Index: net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.259
diff -u -p -r1.259 pfvar.h
--- net/pfvar.h 2 Dec 2007 12:08:04 -0000 1.259
+++ net/pfvar.h 6 Mar 2008 19:40:44 -0000
@@ -41,6 +41,7 @@
#include <net/radix.h>
#include <net/route.h>
+#include <net/if.h>
#include <netinet/ip_ipsp.h>
#include <netinet/tcp_fsm.h>
Index: netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.190
diff -u -p -r1.190 ip_output.c
--- netinet/ip_output.c 29 Oct 2007 16:19:23 -0000 1.190
+++ netinet/ip_output.c 6 Mar 2008 19:40:46 -0000
@@ -118,21 +118,27 @@ ip_output(struct mbuf *m0, ...)
struct m_tag *mtag;
struct tdb_ident *tdbi;
- struct inpcb *inp;
struct tdb *tdb;
int s;
#endif /* IPSEC */
+ struct inpcb *inp;
va_start(ap, m0);
opt = va_arg(ap, struct mbuf *);
ro = va_arg(ap, struct route *);
flags = va_arg(ap, int);
imo = va_arg(ap, struct ip_moptions *);
-#ifdef IPSEC
+
inp = va_arg(ap, struct inpcb *);
- if (inp && (inp->inp_flags & INP_IPV6) != 0)
- panic("ip_output: IPv6 pcb is passed");
+ if(inp)
+ {
+ if(inp->inp_socket->so_pftag != 0)
+ pf_tag_packet(m, inp->inp_socket->so_pftag, -1);
+#ifdef IPSEC
+ if((inp->inp_flags & INP_IPV6) != 0)
+ panic("ip_output: IPv6 pcb is passed");
#endif /* IPSEC */
+ }
va_end(ap);
#ifdef DIAGNOSTIC
Index: netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.81
diff -u -p -r1.81 tcp_output.c
--- netinet/tcp_output.c 24 Nov 2007 12:59:28 -0000 1.81
+++ netinet/tcp_output.c 6 Mar 2008 19:40:48 -0000
@@ -761,6 +761,7 @@ send:
error = ENOBUFS;
goto out;
}
+
m->m_data += max_linkhdr;
m->m_len = hdrlen;
}
Index: sys/socket.h
===================================================================
RCS file: /cvs/src/sys/sys/socket.h,v
retrieving revision 1.55
diff -u -p -r1.55 socket.h
--- sys/socket.h 27 Nov 2007 16:22:14 -0000 1.55
+++ sys/socket.h 6 Mar 2008 19:40:48 -0000
@@ -80,6 +80,7 @@
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_NETPROC 0x1020 /* multiplex; network
processing */
+#define SO_PFTAG 0x1030 /* tag packets from this socket
*/
/*
* Structure used for manipulating linger option.
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.40
diff -u -p -r1.40 socketvar.h
--- sys/socketvar.h 5 Jul 2007 09:04:04 -0000 1.40
+++ sys/socketvar.h 6 Mar 2008 19:40:49 -0000
@@ -108,6 +108,7 @@ struct socket {
uid_t so_euid, so_ruid; /* who opened the socket */
gid_t so_egid, so_rgid;
pid_t so_cpid; /* pid of process that opened socket */
+ u_int16_t so_pftag; /* tag a packet from this socket */
};
#define SB_EMPTY_FIXUP(sb)
\