Subject: Re: CVS commit: src/sys
To: Jason Thorpe <thorpej@wasabisystems.com>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-net
Date: 08/24/2003 11:42:42
[moved from source-changes]
There is a technical issue with IPv4-mapped v6 addresses being passed
downward, through TCP (or UDP), into ip_output and thus into IPsec.
The IPsec code (whichever flavour) then has to look up an appropriate
policy for a v6 in6pcb or a v4 inpcb, respectively.
The reason for this is that IPsec state is cached in the pcb
(either in6pcb or inpcb). But in NetBSD, those structures are different.
programming-language terms, the interface is polymorphic.
Instead of passing the object that IPsec wants -- the pcb,
specifically the inp_sp or in6p_sp_ -- KAME code passes a handle to
that object, namely, the struct socket*.
The way I see it, passing handles is a kludge, the kind of thing which
should not have gone into the tree in the first place.
Again, the way I see it, the right way to do this is for the portions
of the inpcb which need to be shared between ip4 and ipv6, is to make
the necessarily-shared state to in fact be common. Diffs to achieve
this this aren't pretty, but I submit that passing around handles
isn't a good solution, ether.
The code below is a sample of what I'm suggesting, as a compromise.
(If the V6 code had been written according the policy of the NetBSD
project in the first place, such a shim wouldn't be necessary.)
Jason,
Whatever happens, netinet6/in6_pcb.h should be fixed. It just doesn't
pass muster. Have you looked at the layout of fields within struct in6pcb?
struct inpcb_hdr {
/*
* KAME does not follow use sys/queue.h, or share
* common PCB hash links with INET(4), so we need a union of
* disjoint inpcb and in6pcb link fields even for the header.
*/
union {
struct {
LIST_ENTRY(inpcb) hdru4_hash;
CIRCLEQ_ENTRY(inpcb) hdru4_queue;
} hdru_in4pcb;
struct {
struct in6pcb *hdru6_next, *hdru6_prev;
/* pointers to other pcb's */
struct in6pcb *hdru6_head;
/* pointer back to chain of
in6pcb's for this protocol */
} hdru_in6pcb;
} hdr_u;
struct socket *inphdr_socket;
struct inpcbpolicy *inphdr_sp; /* security policy. */
caddr_t inphdr_ppcb; /* pointer to per-protocol pcb */
/* XXX these are commom but are they worth sharing? */
u_int16_t inphdr_fport; /* foreign port */
u_int16_t inphdr_lport; /* local port */
};
/* inet4 compatibility names */
#ifdef INET
#define inp_hash inphdr.hdr_u.hdru_in4pcb.hdru4_hash
#define inp_queue inphdr.hdr_u.hdru_in4pcb.hdru4_queue
#define inp_ppcb inphdr.inphdr_ppcb
#define inp_socket inphdr.inphdr_socket
#define inp_sp inphdr.inphdr_sp
#define inp_fport inphdr.inphdr_fport
#define inp_lport inphdr.inphdr_lport
#endif
/* inet6 compatibility names */
#ifdef INET6
#define in6p_next inphdr.hdr_u.hdru_in6pcb.hdru6_next
#define in6p_prev inphdr.hdr_u.hdru_in6pcb.hdru6_prev
#define in6p_head inphdr.hdr_u.hdru_in6pcb.hdru6_head
#define in6p_ppcb inphdr.inphdr_ppcb
#define in6p_socket inphdr.inphdr_socket
#define in6p_sp inphdr.inphdr_sp
#define in6p_fport inphdr.inphdr_fport
#define in6p_lport inphdr.inphdr_lport
#endif
#endif /* __NETINET_IN_PCB_COMMON_H__ */