Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115064447
D36729.id111406.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D36729.id111406.diff
View Options
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -260,10 +260,9 @@
}
void
-sctp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
+sctp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *inner_ip)
{
struct ip *outer_ip;
- struct ip *inner_ip;
struct sctphdr *sh;
struct icmp *icmp;
struct sctp_inpcb *inp;
@@ -272,91 +271,85 @@
struct sctp_init_chunk *ch;
struct sockaddr_in src, dst;
- if (PRC_IS_REDIRECT(cmd)) {
- ip = NULL;
- } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
+ if (inetctlerrmap[cmd] == 0)
return;
- }
- if (ip != NULL) {
- inner_ip = ip;
- icmp = (struct icmp *)((caddr_t)inner_ip -
- (sizeof(struct icmp) - sizeof(struct ip)));
- outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
- sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
- memset(&src, 0, sizeof(struct sockaddr_in));
- src.sin_family = AF_INET;
- src.sin_len = sizeof(struct sockaddr_in);
- src.sin_port = sh->src_port;
- src.sin_addr = inner_ip->ip_src;
- memset(&dst, 0, sizeof(struct sockaddr_in));
- dst.sin_family = AF_INET;
- dst.sin_len = sizeof(struct sockaddr_in);
- dst.sin_port = sh->dest_port;
- dst.sin_addr = inner_ip->ip_dst;
- /*
- * 'dst' holds the dest of the packet that failed to be
- * sent. 'src' holds our local endpoint address. Thus we
- * reverse the dst and the src in the lookup.
- */
- inp = NULL;
- net = NULL;
- stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
- (struct sockaddr *)&src,
- &inp, &net, 1,
- SCTP_DEFAULT_VRFID);
- if ((stcb != NULL) &&
- (net != NULL) &&
- (inp != NULL)) {
- /* Check the verification tag */
- if (ntohl(sh->v_tag) != 0) {
+
+ icmp = (struct icmp *)((caddr_t)inner_ip -
+ (sizeof(struct icmp) - sizeof(struct ip)));
+ outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
+ sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
+ memset(&src, 0, sizeof(struct sockaddr_in));
+ src.sin_family = AF_INET;
+ src.sin_len = sizeof(struct sockaddr_in);
+ src.sin_port = sh->src_port;
+ src.sin_addr = inner_ip->ip_src;
+ memset(&dst, 0, sizeof(struct sockaddr_in));
+ dst.sin_family = AF_INET;
+ dst.sin_len = sizeof(struct sockaddr_in);
+ dst.sin_port = sh->dest_port;
+ dst.sin_addr = inner_ip->ip_dst;
+ /*
+ * 'dst' holds the dest of the packet that failed to be
+ * sent. 'src' holds our local endpoint address. Thus we
+ * reverse the dst and the src in the lookup.
+ */
+ inp = NULL;
+ net = NULL;
+ stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
+ (struct sockaddr *)&src,
+ &inp, &net, 1,
+ SCTP_DEFAULT_VRFID);
+ if ((stcb != NULL) &&
+ (net != NULL) &&
+ (inp != NULL)) {
+ /* Check the verification tag */
+ if (ntohl(sh->v_tag) != 0) {
+ /*
+ * This must be the verification tag used
+ * for sending out packets. We don't
+ * consider packets reflecting the
+ * verification tag.
+ */
+ if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
+ SCTP_TCB_UNLOCK(stcb);
+ return;
+ }
+ } else {
+ if (ntohs(outer_ip->ip_len) >=
+ sizeof(struct ip) +
+ 8 + (inner_ip->ip_hl << 2) + 20) {
/*
- * This must be the verification tag used
- * for sending out packets. We don't
- * consider packets reflecting the
- * verification tag.
+ * In this case we can check if we
+ * got an INIT chunk and if the
+ * initiate tag matches.
*/
- if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
+ ch = (struct sctp_init_chunk *)(sh + 1);
+ if ((ch->ch.chunk_type != SCTP_INITIATION) ||
+ (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
SCTP_TCB_UNLOCK(stcb);
return;
}
} else {
- if (ntohs(outer_ip->ip_len) >=
- sizeof(struct ip) +
- 8 + (inner_ip->ip_hl << 2) + 20) {
- /*
- * In this case we can check if we
- * got an INIT chunk and if the
- * initiate tag matches.
- */
- ch = (struct sctp_init_chunk *)(sh + 1);
- if ((ch->ch.chunk_type != SCTP_INITIATION) ||
- (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
- SCTP_TCB_UNLOCK(stcb);
- return;
- }
- } else {
- SCTP_TCB_UNLOCK(stcb);
- return;
- }
- }
- sctp_notify(inp, stcb, net,
- icmp->icmp_type,
- icmp->icmp_code,
- ntohs(inner_ip->ip_len),
- (uint32_t)ntohs(icmp->icmp_nextmtu));
- } else {
- if ((stcb == NULL) && (inp != NULL)) {
- /* reduce ref-count */
- SCTP_INP_WLOCK(inp);
- SCTP_INP_DECR_REF(inp);
- SCTP_INP_WUNLOCK(inp);
- }
- if (stcb) {
SCTP_TCB_UNLOCK(stcb);
+ return;
}
}
+ sctp_notify(inp, stcb, net,
+ icmp->icmp_type,
+ icmp->icmp_code,
+ ntohs(inner_ip->ip_len),
+ (uint32_t)ntohs(icmp->icmp_nextmtu));
+ } else {
+ if ((stcb == NULL) && (inp != NULL)) {
+ /* reduce ref-count */
+ SCTP_INP_WLOCK(inp);
+ SCTP_INP_DECR_REF(inp);
+ SCTP_INP_WUNLOCK(inp);
+ }
+ if (stcb) {
+ SCTP_TCB_UNLOCK(stcb);
+ }
}
- return;
}
#endif
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2866,39 +2866,27 @@
tcp_seq icmp_tcp_seq;
int mtu;
- if (cmd == PRC_MSGSIZE)
+ switch (cmd) {
+ case PRC_MSGSIZE:
notify = tcp_mtudisc_notify;
- else if (V_icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
- cmd == PRC_UNREACH_PORT || cmd == PRC_UNREACH_PROTOCOL ||
- cmd == PRC_TIMXCEED_INTRANS) && ip)
- notify = tcp_drop_syn_sent;
-
- /*
- * Hostdead is ugly because it goes linearly through all PCBs.
- * XXX: We never get this from ICMP, otherwise it makes an
- * excellent DoS attack on machines with many connections.
- */
- else if (cmd == PRC_HOSTDEAD)
- ip = NULL;
- else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0)
- return;
+ break;
+ case PRC_UNREACH_PORT:
+ case PRC_UNREACH_PROTOCOL:
+ case PRC_TIMXCEED_INTRANS:
+ case PRC_UNREACH_ADMIN_PROHIB:
+ if (V_icmp_may_rst)
+ notify = tcp_drop_syn_sent;
+ break;
+ }
- if (ip == NULL) {
- in_pcbnotifyall(&V_tcbinfo, sin->sin_addr, inetctlerrmap[cmd],
- notify);
+ if (inetctlerrmap[cmd] == 0)
return;
- }
icp = (struct icmp *)((caddr_t)ip - offsetof(struct icmp, icmp_ip));
th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ icmp_tcp_seq = th->th_seq;
inp = in_pcblookup(&V_tcbinfo, sin->sin_addr, th->th_dport, ip->ip_src,
th->th_sport, INPLOOKUP_WLOCKPCB, NULL);
- if (inp != NULL && PRC_IS_REDIRECT(cmd)) {
- /* signal EHOSTDOWN, as it flushes the cached route */
- inp = (*notify)(inp, EHOSTDOWN);
- goto out;
- }
- icmp_tcp_seq = th->th_seq;
if (inp != NULL) {
if (!(inp->inp_flags & INP_TIMEWAIT) &&
!(inp->inp_flags & INP_DROPPED) &&
@@ -3029,7 +3017,6 @@
struct inpcb *inp;
struct tcpcb *tp;
struct icmp6_hdr *icmp6;
- const struct sockaddr_in6 *sa6_src = NULL;
struct in_conninfo inc;
struct tcp_ports {
uint16_t th_sport;
@@ -3039,44 +3026,27 @@
unsigned int mtu;
unsigned int off;
- /* if the parameter is from icmp6, decode it. */
- if (ip6cp != NULL) {
- icmp6 = ip6cp->ip6c_icmp6;
- m = ip6cp->ip6c_m;
- ip6 = ip6cp->ip6c_ip6;
- off = ip6cp->ip6c_off;
- sa6_src = ip6cp->ip6c_src;
- dst = ip6cp->ip6c_finaldst;
- } else {
- m = NULL;
- ip6 = NULL;
- off = 0; /* fool gcc */
- sa6_src = &sa6_any;
- dst = NULL;
- }
+ icmp6 = ip6cp->ip6c_icmp6;
+ m = ip6cp->ip6c_m;
+ ip6 = ip6cp->ip6c_ip6;
+ off = ip6cp->ip6c_off;
+ dst = ip6cp->ip6c_finaldst;
- if (cmd == PRC_MSGSIZE)
+ switch (cmd) {
+ case PRC_MSGSIZE:
notify = tcp_mtudisc_notify;
- else if (V_icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
- cmd == PRC_UNREACH_PORT || cmd == PRC_UNREACH_PROTOCOL ||
- cmd == PRC_TIMXCEED_INTRANS) && ip6 != NULL)
- notify = tcp_drop_syn_sent;
-
- /*
- * Hostdead is ugly because it goes linearly through all PCBs.
- * XXX: We never get this from ICMP, otherwise it makes an
- * excellent DoS attack on machines with many connections.
- */
- else if (cmd == PRC_HOSTDEAD)
- ip6 = NULL;
- else if ((unsigned)cmd >= PRC_NCMDS || inet6ctlerrmap[cmd] == 0)
- return;
+ break;
+ case PRC_UNREACH_ADMIN_PROHIB:
+ case PRC_UNREACH_PORT:
+ case PRC_UNREACH_PROTOCOL:
+ case PRC_TIMXCEED_INTRANS:
+ if (V_icmp_may_rst)
+ notify = tcp_drop_syn_sent;
+ break;
+ }
- if (ip6 == NULL) {
- in6_pcbnotify(&V_tcbinfo, sin6, 0, sa6_src, 0, cmd, NULL,
- notify);
+ if (inet6ctlerrmap[cmd] == 0)
return;
- }
/* Check if we can safely get the ports from the tcp hdr */
if (m == NULL ||
@@ -3088,11 +3058,6 @@
m_copydata(m, off, sizeof(struct tcp_ports), (caddr_t)&t_ports);
inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_dst, t_ports.th_dport,
&ip6->ip6_src, t_ports.th_sport, INPLOOKUP_WLOCKPCB, NULL);
- if (inp != NULL && PRC_IS_REDIRECT(cmd)) {
- /* signal EHOSTDOWN, as it flushes the cached route */
- inp = (*notify)(inp, EHOSTDOWN);
- goto out;
- }
off += sizeof(struct tcp_ports);
if (m->m_pkthdr.len < (int32_t) (off + sizeof(tcp_seq))) {
goto out;
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -746,53 +746,34 @@
struct udphdr *uh;
struct inpcb *inp;
- if (PRC_IS_REDIRECT(cmd)) {
- /* signal EHOSTDOWN, as it flushes the cached route */
- in_pcbnotifyall(pcbinfo, sin->sin_addr, EHOSTDOWN, udp_notify);
+ if (inetctlerrmap[cmd] == 0)
return;
- }
- /*
- * Hostdead is ugly because it goes linearly through all PCBs.
- *
- * XXX: We never get this from ICMP, otherwise it makes an excellent
- * DoS attack on machines with many connections.
- */
- if (cmd == PRC_HOSTDEAD)
- ip = NULL;
- else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0)
- return;
- if (ip != NULL) {
- uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport, ip->ip_src,
+ uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL);
+ if (inp != NULL) {
+ INP_WLOCK_ASSERT(inp);
+ if (inp->inp_socket != NULL)
+ udp_notify(inp, inetctlerrmap[cmd]);
+ INP_WUNLOCK(inp);
+ } else {
inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
- ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL);
+ ip->ip_src, uh->uh_sport,
+ INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
if (inp != NULL) {
- INP_WLOCK_ASSERT(inp);
- if (inp->inp_socket != NULL) {
- udp_notify(inp, inetctlerrmap[cmd]);
- }
- INP_WUNLOCK(inp);
- } else {
- inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
- ip->ip_src, uh->uh_sport,
- INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
- if (inp != NULL) {
- struct udpcb *up;
- void *ctx;
- udp_tun_icmp_t *func;
-
- up = intoudpcb(inp);
- ctx = up->u_tun_ctx;
- func = up->u_icmp_func;
- INP_RUNLOCK(inp);
- if (func != NULL)
- (*func)(cmd, (struct sockaddr *)sin,
- ip, ctx);
- }
+ struct udpcb *up;
+ void *ctx;
+ udp_tun_icmp_t *func;
+
+ up = intoudpcb(inp);
+ ctx = up->u_tun_ctx;
+ func = up->u_icmp_func;
+ INP_RUNLOCK(inp);
+ if (func != NULL)
+ (*func)(cmd, (struct sockaddr *)sin, ip, ctx);
}
- } else
- in_pcbnotifyall(pcbinfo, sin->sin_addr, inetctlerrmap[cmd],
- udp_notify);
+ }
}
static void
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -256,124 +256,112 @@
struct sctphdr sh;
struct sockaddr_in6 src, dst;
- if ((unsigned)cmd >= PRC_NCMDS) {
+ if (inet6ctlerrmap[cmd] == 0)
return;
- }
- if (PRC_IS_REDIRECT(cmd)) {
- ip6cp = NULL;
- } else if (inet6ctlerrmap[cmd] == 0) {
+
+ if (ip6cp->ip6c_m == NULL) {
return;
}
- if (ip6cp != NULL) {
- /*
- * XXX: We assume that when IPV6 is non NULL, M and OFF are
- * valid.
- */
- if (ip6cp->ip6c_m == NULL) {
- return;
- }
-
- /*
- * Check if we can safely examine the ports and the
- * verification tag of the SCTP common header.
- */
- if (ip6cp->ip6c_m->m_pkthdr.len <
- (int32_t)(ip6cp->ip6c_off + offsetof(struct sctphdr, checksum))) {
- return;
- }
+ /*
+ * Check if we can safely examine the ports and the
+ * verification tag of the SCTP common header.
+ */
+ if (ip6cp->ip6c_m->m_pkthdr.len <
+ (int32_t)(ip6cp->ip6c_off + offsetof(struct sctphdr, checksum))) {
+ return;
+ }
- /* Copy out the port numbers and the verification tag. */
- memset(&sh, 0, sizeof(sh));
- m_copydata(ip6cp->ip6c_m,
- ip6cp->ip6c_off,
- sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
- (caddr_t)&sh);
- memset(&src, 0, sizeof(struct sockaddr_in6));
- src.sin6_family = AF_INET6;
- src.sin6_len = sizeof(struct sockaddr_in6);
- src.sin6_port = sh.src_port;
- src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
- if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
- return;
- }
- memset(&dst, 0, sizeof(struct sockaddr_in6));
- dst.sin6_family = AF_INET6;
- dst.sin6_len = sizeof(struct sockaddr_in6);
- dst.sin6_port = sh.dest_port;
- dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
- if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
- return;
- }
- inp = NULL;
- net = NULL;
- stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
- (struct sockaddr *)&src,
- &inp, &net, 1, SCTP_DEFAULT_VRFID);
- if ((stcb != NULL) &&
- (net != NULL) &&
- (inp != NULL)) {
- /* Check the verification tag */
- if (ntohl(sh.v_tag) != 0) {
+ /* Copy out the port numbers and the verification tag. */
+ memset(&sh, 0, sizeof(sh));
+ m_copydata(ip6cp->ip6c_m,
+ ip6cp->ip6c_off,
+ sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
+ (caddr_t)&sh);
+ memset(&src, 0, sizeof(struct sockaddr_in6));
+ src.sin6_family = AF_INET6;
+ src.sin6_len = sizeof(struct sockaddr_in6);
+ src.sin6_port = sh.src_port;
+ src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
+ if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
+ return;
+ }
+ memset(&dst, 0, sizeof(struct sockaddr_in6));
+ dst.sin6_family = AF_INET6;
+ dst.sin6_len = sizeof(struct sockaddr_in6);
+ dst.sin6_port = sh.dest_port;
+ dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
+ if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
+ return;
+ }
+ inp = NULL;
+ net = NULL;
+ stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
+ (struct sockaddr *)&src,
+ &inp, &net, 1, SCTP_DEFAULT_VRFID);
+ if ((stcb != NULL) &&
+ (net != NULL) &&
+ (inp != NULL)) {
+ /* Check the verification tag */
+ if (ntohl(sh.v_tag) != 0) {
+ /*
+ * This must be the verification tag used
+ * for sending out packets. We don't
+ * consider packets reflecting the
+ * verification tag.
+ */
+ if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
+ SCTP_TCB_UNLOCK(stcb);
+ return;
+ }
+ } else {
+ if (ip6cp->ip6c_m->m_pkthdr.len >=
+ ip6cp->ip6c_off + sizeof(struct sctphdr) +
+ sizeof(struct sctp_chunkhdr) +
+ offsetof(struct sctp_init, a_rwnd)) {
/*
- * This must be the verification tag used
- * for sending out packets. We don't
- * consider packets reflecting the
- * verification tag.
+ * In this case we can check if we
+ * got an INIT chunk and if the
+ * initiate tag matches.
*/
- if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
+ uint32_t initiate_tag;
+ uint8_t chunk_type;
+
+ m_copydata(ip6cp->ip6c_m,
+ ip6cp->ip6c_off +
+ sizeof(struct sctphdr),
+ sizeof(uint8_t),
+ (caddr_t)&chunk_type);
+ m_copydata(ip6cp->ip6c_m,
+ ip6cp->ip6c_off +
+ sizeof(struct sctphdr) +
+ sizeof(struct sctp_chunkhdr),
+ sizeof(uint32_t),
+ (caddr_t)&initiate_tag);
+ if ((chunk_type != SCTP_INITIATION) ||
+ (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
SCTP_TCB_UNLOCK(stcb);
return;
}
} else {
- if (ip6cp->ip6c_m->m_pkthdr.len >=
- ip6cp->ip6c_off + sizeof(struct sctphdr) +
- sizeof(struct sctp_chunkhdr) +
- offsetof(struct sctp_init, a_rwnd)) {
- /*
- * In this case we can check if we
- * got an INIT chunk and if the
- * initiate tag matches.
- */
- uint32_t initiate_tag;
- uint8_t chunk_type;
-
- m_copydata(ip6cp->ip6c_m,
- ip6cp->ip6c_off +
- sizeof(struct sctphdr),
- sizeof(uint8_t),
- (caddr_t)&chunk_type);
- m_copydata(ip6cp->ip6c_m,
- ip6cp->ip6c_off +
- sizeof(struct sctphdr) +
- sizeof(struct sctp_chunkhdr),
- sizeof(uint32_t),
- (caddr_t)&initiate_tag);
- if ((chunk_type != SCTP_INITIATION) ||
- (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
- SCTP_TCB_UNLOCK(stcb);
- return;
- }
- } else {
- SCTP_TCB_UNLOCK(stcb);
- return;
- }
- }
- sctp6_notify(inp, stcb, net,
- ip6cp->ip6c_icmp6->icmp6_type,
- ip6cp->ip6c_icmp6->icmp6_code,
- ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
- } else {
- if ((stcb == NULL) && (inp != NULL)) {
- /* reduce inp's ref-count */
- SCTP_INP_WLOCK(inp);
- SCTP_INP_DECR_REF(inp);
- SCTP_INP_WUNLOCK(inp);
- }
- if (stcb) {
SCTP_TCB_UNLOCK(stcb);
+ return;
}
}
+ sctp6_notify(inp, stcb, net,
+ ip6cp->ip6c_icmp6->icmp6_type,
+ ip6cp->ip6c_icmp6->icmp6_code,
+ ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
+ } else {
+ if ((stcb == NULL) && (inp != NULL)) {
+ /* reduce inp's ref-count */
+ SCTP_INP_WLOCK(inp);
+ SCTP_INP_DECR_REF(inp);
+ SCTP_INP_WUNLOCK(inp);
+ }
+ if (stcb) {
+ SCTP_TCB_UNLOCK(stcb);
+ }
}
}
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -553,8 +553,8 @@
struct udphdr uh;
struct ip6_hdr *ip6;
struct mbuf *m;
+ struct inpcb *inp;
int off = 0;
- const struct sockaddr_in6 *sa6_src = NULL;
void *cmdarg;
struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
struct udp_portonly {
@@ -562,70 +562,38 @@
u_int16_t uh_dport;
} *uhp;
- if ((unsigned)cmd >= PRC_NCMDS)
+ if (inet6ctlerrmap[cmd] == 0)
return;
- if (PRC_IS_REDIRECT(cmd))
- notify = in6_rtchange, ip6cp = NULL;
- else if (cmd == PRC_HOSTDEAD)
- ip6cp = NULL;
- else if (inet6ctlerrmap[cmd] == 0)
+
+ m = ip6cp->ip6c_m;
+ ip6 = ip6cp->ip6c_ip6;
+ off = ip6cp->ip6c_off;
+ cmdarg = ip6cp->ip6c_cmdarg;
+
+ /* Check if we can safely examine src and dst ports. */
+ if (m->m_pkthdr.len < off + sizeof(*uhp))
return;
- /* if the parameter is from icmp6, decode it. */
- if (ip6cp != NULL) {
- m = ip6cp->ip6c_m;
- ip6 = ip6cp->ip6c_ip6;
- off = ip6cp->ip6c_off;
- cmdarg = ip6cp->ip6c_cmdarg;
- sa6_src = ip6cp->ip6c_src;
- } else {
- m = NULL;
- ip6 = NULL;
- cmdarg = NULL;
- sa6_src = &sa6_any;
- }
+ bzero(&uh, sizeof(uh));
+ m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
- if (ip6) {
- /*
- * XXX: We assume that when IPV6 is non NULL,
- * M and OFF are valid.
- */
+ /* Check to see if its tunneled */
+ inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_dst, uh.uh_dport,
+ &ip6->ip6_src, uh.uh_sport, INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
+ m->m_pkthdr.rcvif, m);
+ if (inp != NULL) {
+ struct udpcb *up;
+ udp_tun_icmp_t *func;
- /* Check if we can safely examine src and dst ports. */
- if (m->m_pkthdr.len < off + sizeof(*uhp))
- return;
-
- bzero(&uh, sizeof(uh));
- m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
-
- if (!PRC_IS_REDIRECT(cmd)) {
- /* Check to see if its tunneled */
- struct inpcb *inp;
- inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_dst,
- uh.uh_dport, &ip6->ip6_src, uh.uh_sport,
- INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
- m->m_pkthdr.rcvif, m);
- if (inp != NULL) {
- struct udpcb *up;
-
- up = intoudpcb(inp);
- if (up->u_icmp_func) {
- /* Yes it is. */
- INP_RUNLOCK(inp);
- (*up->u_icmp_func)(cmd, (struct sockaddr *)ip6cp->ip6c_src,
- ip6cp, up->u_tun_ctx);
- return;
- } else {
- /* Can't find it. */
- INP_RUNLOCK(inp);
- }
- }
- }
- in6_pcbnotify(pcbinfo, sin6, uh.uh_dport, ip6cp->ip6c_src,
- uh.uh_sport, cmd, cmdarg, notify);
- } else
- in6_pcbnotify(pcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg,
- notify);
+ up = intoudpcb(inp);
+ func = up->u_icmp_func;
+ INP_RUNLOCK(inp);
+ if (func != NULL)
+ func(cmd, (struct sockaddr *)ip6cp->ip6c_src, ip6cp,
+ up->u_tun_ctx);
+ }
+ in6_pcbnotify(pcbinfo, sin6, uh.uh_dport, ip6cp->ip6c_src,
+ uh.uh_sport, cmd, cmdarg, notify);
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 21, 3:22 AM (16 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17658503
Default Alt Text
D36729.id111406.diff (20 KB)
Attached To
Mode
D36729: netinet*: remove dead code from TCP, UDP, SCTP control input
Attached
Detach File
Event Timeline
Log In to Comment