On Mon, Apr 11, 2011 at 19:52 +0200, Claudio Jeker wrote: > On Mon, Apr 11, 2011 at 07:18:13PM +0200, Mike Belopuhov wrote: > > On Mon, Apr 11, 2011 at 18:51 +0200, Claudio Jeker wrote: > > > On Mon, Apr 11, 2011 at 04:52:23PM +0200, Mike Belopuhov wrote: > > > > hi, > > > > > > > > currently there's no way to figure out what rdomain the diverted > > > > connection came from. this diff introduces a neat hack that reyk > > > > and i have invented. from the programmer's perspective this is > > > > as simple as calling getsockopt(SO_RTABLE) on the "accepted" socket. > > > > from the kernel perspective each socket has an associated pcb > > > > structure that includes an rdomain value. atm this rdomain is > > > > inherited from the listening socket, which is totally useless if > > > > you do divert-to from a different rdomain. this diff tries to > > > > lookup a divert mbuf tag and get an rdomain from there, which is > > > > an original rdomain of the packet. > > > > > > > > OK? > > > > > > Isn't divert-to supported on UDP sockets? If that is the case we need to > > > think about the udp case as well (which is a bit more complex because of > > > the way UDP works). > > > > > > > it's not immediately useful for udp. also there's no way to query an > > rdomain of a single message. > > That's what cmsg would be for. There is already IP_RECVDSTADDR and > IP_RECVDSTPORT so one could add another IP_RECVRDOMAIN cmsg type to cover > this in UDP. >
right. can we do this in a different diff? > > Ah but that is another check, pf is using its own flag to quickly check if > it is a diverted packet. So I wonder why do we have a PF_TAG_DIVERTED flag > as well and should we check that one first? > PF_TAG_DIVERTED is used for divert-to but not for divert-packet. after giving this a thought, i believe we shouldn't do anything for the divert-packet case as accept(2) is not specified for the divert(4) sockets. Index: netinet/tcp_input.c =================================================================== RCS file: /home/cvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.244 diff -u -p -r1.244 tcp_input.c --- netinet/tcp_input.c 5 Apr 2011 18:16:07 -0000 1.244 +++ netinet/tcp_input.c 12 Apr 2011 10:21:42 -0000 @@ -3671,6 +3671,9 @@ syn_cache_get(struct sockaddr *src, stru struct mbuf *am; int s; struct socket *oso; +#if NPF > 0 + struct pf_divert *divert = NULL; +#endif s = splsoftnet(); if ((sc = syn_cache_lookup(src, dst, &scp, @@ -3754,6 +3757,12 @@ syn_cache_get(struct sockaddr *src, stru inp = (struct inpcb *)so->so_pcb; #endif /* INET6 */ +#if NPF > 0 + if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED && + (divert = pf_find_divert(m)) != NULL) + inp->inp_rtableid = divert->rdomain; + else +#endif /* inherit rtable from listening socket */ inp->inp_rtableid = sc->sc_rtableid; Index: net/pf.c =================================================================== RCS file: /home/cvs/src/sys/net/pf.c,v retrieving revision 1.739 diff -u -p -r1.739 pf.c --- net/pf.c 7 Apr 2011 19:35:05 -0000 1.739 +++ net/pf.c 12 Apr 2011 10:06:56 -0000 @@ -5964,6 +5964,7 @@ done: if ((divert = pf_get_divert(m))) { m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; divert->port = r->divert.port; + divert->rdomain = pd.rdomain; divert->addr.ipv4 = r->divert.addr.v4; } } @@ -6243,6 +6244,7 @@ done: if ((divert = pf_get_divert(m))) { m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; divert->port = r->divert.port; + divert->rdomain = pd.rdomain; divert->addr.ipv6 = r->divert.addr.v6; } } Index: net/pfvar.h =================================================================== RCS file: /home/cvs/src/sys/net/pfvar.h,v retrieving revision 1.326 diff -u -p -r1.326 pfvar.h --- net/pfvar.h 6 Apr 2011 13:18:39 -0000 1.326 +++ net/pfvar.h 8 Apr 2011 15:55:25 -0000 @@ -1442,6 +1442,7 @@ struct pf_divert { struct in6_addr ipv6; } addr; u_int16_t port; + u_int16_t rdomain; }; #define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */