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) \