diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-13 20:54:06 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-13 20:54:06 +0000 |
commit | a49dcb067ccc0d0288291f437054538b34b31dcf (patch) | |
tree | 0579937c1bf07d3bb795d722753a4f295db15530 /sys/netinet | |
parent | 750113cd50e6e0756d40eaf9d929ace22ff84a05 (diff) |
Extend the protosw pr_ctlinput function to include the rdomain. This is
needed so that the route and inp lookups done in TCP and UDP know where
to look. Additionally in_pcbnotifyall() and tcp_respond() got a rdomain
argument as well for similar reasons. With this tcp seems to be now
fully rdomain save and no longer leaks single packets into the main domain.
Looks good markus@, henning@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in_pcb.c | 9 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 4 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 11 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 8 | ||||
-rw-r--r-- | sys/netinet/ipsec_input.c | 11 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 9 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 22 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.c | 8 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 6 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 10 | ||||
-rw-r--r-- | sys/netinet/udp_var.h | 4 |
11 files changed, 59 insertions, 43 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 0e72496653d..333e5b3f071 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.107 2009/11/03 10:59:04 claudio Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.108 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -570,9 +570,10 @@ in_setpeeraddr(inp, nam) * Must be called at splsoftnet. */ void -in_pcbnotifyall(table, dst, errno, notify) +in_pcbnotifyall(table, dst, rdomain, errno, notify) struct inpcbtable *table; struct sockaddr *dst; + u_int rdomain; int errno; void (*notify)(struct inpcb *, int); { @@ -604,6 +605,7 @@ in_pcbnotifyall(table, dst, errno, notify) } #endif if (inp->inp_faddr.s_addr != faddr.s_addr || + inp->inp_rdomain != rdomain || inp->inp_socket == 0) { inp = CIRCLEQ_NEXT(inp, inp_queue); continue; @@ -788,7 +790,8 @@ in_pcbrtentry(inp) ro->ro_dst.sa_family = AF_INET; ro->ro_dst.sa_len = sizeof(ro->ro_dst); satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr; - rtalloc_mpath(ro, &inp->inp_laddr.s_addr, 0); + rtalloc_mpath(ro, &inp->inp_laddr.s_addr, + inp->inp_rdomain); break; } } diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 7e75d8294c6..da1df0acdcc 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.67 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.68 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -272,7 +272,7 @@ struct inpcb * in_pcblookup(struct inpcbtable *, void *, u_int, void *, u_int, int, u_int); void in_pcbnotifyall(struct inpcbtable *, struct sockaddr *, - int, void (*)(struct inpcb *, int)); + u_int, int, void (*)(struct inpcb *, int)); void in_pcbrehash(struct inpcb *); void in_rtchange(struct inpcb *, int); void in_setpeeraddr(struct inpcb *, struct mbuf *); diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index c0cc5dbb89d..e1aeed69ade 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.85 2009/11/03 10:59:04 claudio Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.86 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -308,7 +308,7 @@ icmp_input(struct mbuf *m, ...) int icmplen; int i; struct in_ifaddr *ia; - void *(*ctlfunc)(int, struct sockaddr *, void *); + void *(*ctlfunc)(int, struct sockaddr *, u_int, void *); int code; extern u_char ip_protox[]; int hlen; @@ -469,7 +469,8 @@ icmp_input(struct mbuf *m, ...) */ ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput; if (ctlfunc) - (*ctlfunc)(code, sintosa(&icmpsrc), &icp->icmp_ip); + (*ctlfunc)(code, sintosa(&icmpsrc), m->m_pkthdr.rdomain, + &icp->icmp_ip); break; badcode: @@ -980,7 +981,7 @@ icmp_mtudisc_timeout(struct rtentry *rt, struct rttimer *r) panic("icmp_mtudisc_timeout: bad route to timeout"); if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == (RTF_DYNAMIC | RTF_HOST)) { - void *(*ctlfunc)(int, struct sockaddr *, void *); + void *(*ctlfunc)(int, struct sockaddr *, u_int, void *); extern u_char ip_protox[]; struct sockaddr_in sa; struct rt_addrinfo info; @@ -997,7 +998,7 @@ icmp_mtudisc_timeout(struct rtentry *rt, struct rttimer *r) /* Notify TCP layer of increased Path MTU estimate */ ctlfunc = inetsw[ip_protox[IPPROTO_TCP]].pr_ctlinput; if (ctlfunc) - (*ctlfunc)(PRC_MTUINC,(struct sockaddr *)&sa, NULL); + (*ctlfunc)(PRC_MTUINC,(struct sockaddr *)&sa, 0, NULL); } else if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) rt->rt_rmx.rmx_mtu = 0; diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index d58575fb9e6..9b214c4ea5c 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.138 2009/06/02 21:28:36 blambert Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.139 2009/11/13 20:54:05 claudio Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -562,8 +562,8 @@ extern int ah_massage_headers(struct mbuf **, int, int, int, int); #ifdef INET extern void ah4_input(struct mbuf *, ...); extern int ah4_input_cb(struct mbuf *, ...); -extern void *ah4_ctlinput(int, struct sockaddr *, void *); -extern void *udpencap_ctlinput(int, struct sockaddr *, void *); +extern void *ah4_ctlinput(int, struct sockaddr *, u_int, void *); +extern void *udpencap_ctlinput(int, struct sockaddr *, u_int, void *); #endif /* INET */ #ifdef INET6 @@ -584,7 +584,7 @@ extern int esp_sysctl(int *, u_int, void *, size_t *, void *, size_t); #ifdef INET extern void esp4_input(struct mbuf *, ...); extern int esp4_input_cb(struct mbuf *, ...); -extern void *esp4_ctlinput(int, struct sockaddr *, void *); +extern void *esp4_ctlinput(int, struct sockaddr *, u_int, void *); #endif /* INET */ #ifdef INET6 diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index d371367d458..acc28c6b43b 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.92 2009/08/09 12:47:50 henning Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.93 2009/11/13 20:54:05 claudio Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -746,8 +746,9 @@ ah4_input_cb(struct mbuf *m, ...) } +/* XXX rdomain */ void * -ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) +ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) { if (sa->sa_family != AF_INET || sa->sa_len != sizeof(struct sockaddr_in)) @@ -907,8 +908,9 @@ ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto) return (NULL); } +/* XXX rdomain */ void * -udpencap_ctlinput(int cmd, struct sockaddr *sa, void *v) +udpencap_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) { struct ip *ip = v; struct tdb *tdbp; @@ -965,8 +967,9 @@ udpencap_ctlinput(int cmd, struct sockaddr *sa, void *v) return (NULL); } +/* XXX rdomain */ void * -esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) +esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) { if (sa->sa_family != AF_INET || sa->sa_len != sizeof(struct sockaddr_in)) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index dea6cdf2923..1d112c9f5de 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.229 2009/11/03 10:59:04 claudio Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.230 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -2218,12 +2218,12 @@ dropwithreset: goto drop; if (tiflags & TH_ACK) { tcp_respond(tp, mtod(m, caddr_t), th, (tcp_seq)0, th->th_ack, - TH_RST); + TH_RST, 0); } else { if (tiflags & TH_SYN) tlen++; tcp_respond(tp, mtod(m, caddr_t), th, th->th_seq + tlen, - (tcp_seq)0, TH_RST|TH_ACK); + (tcp_seq)0, TH_RST|TH_ACK, 0); } m_freem(m); return; @@ -3845,7 +3845,8 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, return (so); resetandabort: - tcp_respond(NULL, mtod(m, caddr_t), th, (tcp_seq)0, th->th_ack, TH_RST); + tcp_respond(NULL, mtod(m, caddr_t), th, (tcp_seq)0, th->th_ack, TH_RST, + m->m_pkthdr.rdomain); m_freem(m); abort: if (so != NULL) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index b5d91f7253b..26cba61037b 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.108 2009/11/03 10:59:04 claudio Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.109 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -318,12 +318,13 @@ tcp_template(tp) /* This function looks hairy, because it was so IPv4-dependent. */ #endif /* INET6 */ void -tcp_respond(tp, template, th0, ack, seq, flags) +tcp_respond(tp, template, th0, ack, seq, flags, rdomain) struct tcpcb *tp; caddr_t template; struct tcphdr *th0; tcp_seq ack, seq; int flags; + u_int rdomain; { int tlen; int win = 0; @@ -409,6 +410,12 @@ tcp_respond(tp, template, th0, ack, seq, flags) th->th_win = htons((u_int16_t)win); th->th_urp = 0; + /* force routing domain */ + if (tp) + m->m_pkthdr.rdomain = tp->t_inpcb->inp_rdomain; + else + m->m_pkthdr.rdomain = rdomain; + switch (af) { #ifdef INET6 case AF_INET6: @@ -768,9 +775,10 @@ tcp6_ctlinput(cmd, sa, d) #endif void * -tcp_ctlinput(cmd, sa, v) +tcp_ctlinput(cmd, sa, rdomain, v) int cmd; struct sockaddr *sa; + u_int rdomain; void *v; { struct ip *ip = v; @@ -810,7 +818,7 @@ tcp_ctlinput(cmd, sa, v) seq = ntohl(th->th_seq); inp = in_pcbhashlookup(&tcbtable, ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport, - /* XXX */ 0); + rdomain); if (inp && (tp = intotcpcb(inp)) && SEQ_GEQ(seq, tp->snd_una) && SEQ_LT(seq, tp->snd_max)) { @@ -868,7 +876,7 @@ tcp_ctlinput(cmd, sa, v) th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2)); inp = in_pcbhashlookup(&tcbtable, ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport, - /* XXX */ 0); + rdomain); if (inp) { seq = ntohl(th->th_seq); if (inp->inp_socket && @@ -888,10 +896,10 @@ tcp_ctlinput(cmd, sa, v) sin.sin_port = th->th_sport; sin.sin_addr = ip->ip_src; syn_cache_unreach((struct sockaddr *)&sin, - sa, th, /* XXX */ 0); + sa, th, rdomain); } } else - in_pcbnotifyall(&tcbtable, sa, errno, notify); + in_pcbnotifyall(&tcbtable, sa, rdomain, errno, notify); return NULL; } diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index f939e3faa0a..8253775bfa3 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_timer.c,v 1.43 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: tcp_timer.c,v 1.44 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */ /* @@ -219,8 +219,8 @@ tcp_timer_rexmt(void *arg) * Notify all connections to the same peer about * new mss and trigger retransmit. */ - in_pcbnotifyall(&tcbtable, sintosa(&icmpsrc), EMSGSIZE, - tcp_mtudisc); + in_pcbnotifyall(&tcbtable, sintosa(&icmpsrc), + tp->t_inpcb->inp_rdomain, EMSGSIZE, tcp_mtudisc); splx(s); return; } @@ -454,7 +454,7 @@ tcp_timer_keep(void *arg) */ tcpstat.tcps_keepprobe++; tcp_respond(tp, mtod(tp->t_template, caddr_t), - NULL, tp->rcv_nxt, tp->snd_una - 1, 0); + NULL, tp->rcv_nxt, tp->snd_una - 1, 0, 0); TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepintvl); } else TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle); diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 090ba4f6d3e..2650017254f 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_var.h,v 1.92 2009/08/10 10:13:43 claudio Exp $ */ +/* $OpenBSD: tcp_var.h,v 1.93 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */ /* @@ -558,7 +558,7 @@ int tcp_freeq(struct tcpcb *); #if defined(INET6) && !defined(TCP6) void tcp6_ctlinput(int, struct sockaddr *, void *); #endif -void *tcp_ctlinput(int, struct sockaddr *, void *); +void *tcp_ctlinput(int, struct sockaddr *, u_int, void *); int tcp_ctloutput(int, struct socket *, int, int, struct mbuf **); struct tcpcb * tcp_disconnect(struct tcpcb *); @@ -588,7 +588,7 @@ void tcp_pulloutofband(struct socket *, u_int, struct mbuf *, int); int tcp_reass(struct tcpcb *, struct tcphdr *, struct mbuf *, int *); void tcp_rscale(struct tcpcb *, u_long); void tcp_respond(struct tcpcb *, caddr_t, struct tcphdr *, tcp_seq, - tcp_seq, int); + tcp_seq, int, u_int); void tcp_setpersist(struct tcpcb *); void tcp_slowtimo(void); struct mbuf * diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 53f253f9037..6dd612a5efe 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.131 2009/11/03 10:59:04 claudio Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.132 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -864,7 +864,7 @@ udp6_ctlinput(int cmd, struct sockaddr *sa, void *d) #endif void * -udp_ctlinput(int cmd, struct sockaddr *sa, void *v) +udp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) { struct ip *ip = v; struct udphdr *uhp; @@ -899,17 +899,17 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *v) /* PMTU discovery for udpencap */ if (cmd == PRC_MSGSIZE && ip_mtudisc && udpencap_enable && udpencap_port && uhp->uh_sport == htons(udpencap_port)) { - udpencap_ctlinput(cmd, sa, v); + udpencap_ctlinput(cmd, sa, rdomain, v); return (NULL); } #endif inp = in_pcbhashlookup(&udbtable, ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport, - /* XXX */ 0); + rdomain); if (inp && inp->inp_socket != NULL) notify(inp, errno); } else - in_pcbnotifyall(&udbtable, sa, errno, notify); + in_pcbnotifyall(&udbtable, sa, rdomain, errno, notify); return (NULL); } diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 5241be127db..68f18b0e70d 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_var.h,v 1.19 2008/05/24 19:48:32 thib Exp $ */ +/* $OpenBSD: udp_var.h,v 1.20 2009/11/13 20:54:05 claudio Exp $ */ /* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */ /* @@ -106,7 +106,7 @@ extern struct udpstat udpstat; void udp6_ctlinput(int, struct sockaddr *, void *); int udp6_input(struct mbuf **, int *, int); #endif /* INET6 && !TCP6 */ -void *udp_ctlinput(int, struct sockaddr *, void *); +void *udp_ctlinput(int, struct sockaddr *, u_int, void *); void udp_init(void); void udp_input(struct mbuf *, ...); #ifdef INET6 |