Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163280026
D36731.id111051.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
37 KB
Referenced Files
None
Subscribers
None
D36731.id111051.diff
View Options
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -701,6 +701,7 @@
struct in6_multi;
# endif
void icmp6_paramerror(struct mbuf *, int);
+int icmp6_errmap(const struct icmp6_hdr *);
void icmp6_error(struct mbuf *, int, int, int);
void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *);
int icmp6_input(struct mbuf **, int *, int);
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -100,8 +100,6 @@
#define IN_LNAOF(in, ifa) \
((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask))
-extern u_char inetctlerrmap[];
-
#define LLTABLE(ifp) \
((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
/*
diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h
--- a/sys/netinet/ip_icmp.h
+++ b/sys/netinet/ip_icmp.h
@@ -216,6 +216,7 @@
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
#ifdef _KERNEL
+int icmp_errmap(const struct icmp *);
void icmp_error(struct mbuf *, int, int, uint32_t, int);
int icmp_input(struct mbuf **, int *, int);
int ip_next_mtu(int, int);
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -403,6 +403,55 @@
m_freem(n);
}
+int
+icmp_errmap(const struct icmp *icp)
+{
+
+ switch (icp->icmp_type) {
+ case ICMP_UNREACH:
+ switch (icp->icmp_code) {
+ case ICMP_UNREACH_NET:
+ case ICMP_UNREACH_HOST:
+ case ICMP_UNREACH_SRCFAIL:
+ case ICMP_UNREACH_NET_UNKNOWN:
+ case ICMP_UNREACH_HOST_UNKNOWN:
+ case ICMP_UNREACH_ISOLATED:
+ case ICMP_UNREACH_TOSNET:
+ case ICMP_UNREACH_TOSHOST:
+ case ICMP_UNREACH_HOST_PRECEDENCE:
+ case ICMP_UNREACH_PRECEDENCE_CUTOFF:
+ return (EHOSTUNREACH);
+ case ICMP_UNREACH_NEEDFRAG:
+ return (EMSGSIZE);
+ case ICMP_UNREACH_PROTOCOL:
+ case ICMP_UNREACH_PORT:
+ case ICMP_UNREACH_NET_PROHIB:
+ case ICMP_UNREACH_HOST_PROHIB:
+ case ICMP_UNREACH_FILTER_PROHIB:
+ return (ECONNREFUSED);
+ default:
+ return (0);
+ }
+ case ICMP_TIMXCEED:
+ switch (icp->icmp_code) {
+ case ICMP_TIMXCEED_INTRANS:
+ return (EHOSTUNREACH);
+ default:
+ return (0);
+ }
+ case ICMP_PARAMPROB:
+ switch (icp->icmp_code) {
+ case ICMP_PARAMPROB_ERRATPTR:
+ case ICMP_PARAMPROB_OPTABSENT:
+ return (ENOPROTOOPT);
+ default:
+ return (0);
+ }
+ default:
+ return (0);
+ }
+}
+
/*
* Process a received ICMP message.
*/
@@ -484,56 +533,21 @@
code = icp->icmp_code;
switch (icp->icmp_type) {
case ICMP_UNREACH:
- switch (code) {
- case ICMP_UNREACH_NET:
- case ICMP_UNREACH_HOST:
- case ICMP_UNREACH_SRCFAIL:
- case ICMP_UNREACH_NET_UNKNOWN:
- case ICMP_UNREACH_HOST_UNKNOWN:
- case ICMP_UNREACH_ISOLATED:
- case ICMP_UNREACH_TOSNET:
- case ICMP_UNREACH_TOSHOST:
- case ICMP_UNREACH_HOST_PRECEDENCE:
- case ICMP_UNREACH_PRECEDENCE_CUTOFF:
- code = PRC_UNREACH_NET;
- break;
-
- case ICMP_UNREACH_NEEDFRAG:
- code = PRC_MSGSIZE;
- break;
-
- /*
- * RFC 1122, Sections 3.2.2.1 and 4.2.3.9.
- * Treat subcodes 2,3 as immediate RST
- */
- case ICMP_UNREACH_PROTOCOL:
- code = PRC_UNREACH_PROTOCOL;
- break;
- case ICMP_UNREACH_PORT:
- code = PRC_UNREACH_PORT;
- break;
-
- case ICMP_UNREACH_NET_PROHIB:
- case ICMP_UNREACH_HOST_PROHIB:
- case ICMP_UNREACH_FILTER_PROHIB:
- code = PRC_UNREACH_ADMIN_PROHIB;
- break;
-
- default:
- goto badcode;
- }
- goto deliver;
+ if (code > ICMP_UNREACH_PRECEDENCE_CUTOFF)
+ goto badcode;
+ else
+ goto deliver;
case ICMP_TIMXCEED:
- if (code > 1)
+ if (code > ICMP_TIMXCEED_REASS)
goto badcode;
- code += PRC_TIMXCEED_INTRANS;
- goto deliver;
+ else
+ goto deliver;
case ICMP_PARAMPROB:
- if (code > 1)
+ if (code > ICMP_PARAMPROB_LENGTH)
goto badcode;
- code = PRC_PARAMPROB;
+
deliver:
/*
* Problem with datagram; advise higher level routines.
@@ -553,7 +567,6 @@
if (icmpprintfs)
printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
#endif
- icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
/*
* XXX if the packet contains [IPv4 AH TCP], we can't make a
* notification to TCP layer.
@@ -576,8 +589,7 @@
* ICMP_ADVLENPREF. See its definition in ip_icmp.h.
*/
if (ip_ctlprotox[icp->icmp_ip.ip_p] != NULL)
- ip_ctlprotox[icp->icmp_ip.ip_p](code, &icmpsrc,
- &icp->icmp_ip);
+ ip_ctlprotox[icp->icmp_ip.ip_p](icp);
break;
badcode:
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -873,23 +873,6 @@
return (ENOENT);
}
-/* (x) - issued by icmp_input() */
-u_char inetctlerrmap[PRC_NCMDS] = {
- [PRC_MSGSIZE] = EMSGSIZE, /* (x) */
- [PRC_HOSTDEAD] = EHOSTDOWN,
- [PRC_HOSTUNREACH] = EHOSTUNREACH,
- [PRC_UNREACH_NET] = EHOSTUNREACH, /* (x) */
- [PRC_UNREACH_HOST] = EHOSTUNREACH,
- [PRC_UNREACH_PROTOCOL] = ECONNREFUSED, /* (x) */
- [PRC_UNREACH_PORT] = ECONNREFUSED, /* (x) */
- [12] = EMSGSIZE,
- [PRC_UNREACH_SRCFAIL] = EHOSTUNREACH,
- [PRC_TIMXCEED_INTRANS] = EHOSTUNREACH, /* (x) */
- [PRC_TIMXCEED_REASS] = 0, /* (x) */
- [PRC_PARAMPROB] = ENOPROTOOPT, /* (x) */
- [PRC_UNREACH_ADMIN_PROHIB] = ECONNREFUSED, /* (x) */
-};
-
/*
* Forward a packet. If some error occurs return the sender
* an icmp packet. Note we can't always generate a meaningful
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -238,7 +238,8 @@
extern int (*rsvp_input_p)(struct mbuf **, int *, int);
typedef int ipproto_input_t(struct mbuf **, int *, int);
-typedef void ipproto_ctlinput_t(int, struct sockaddr_in *, struct ip *);
+struct icmp;
+typedef void ipproto_ctlinput_t(struct icmp *);
int ipproto_register(uint8_t, ipproto_input_t, ipproto_ctlinput_t);
int ipproto_unregister(uint8_t);
#define IPPROTO_REGISTER(prot, input, ctl) do { \
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -804,17 +804,12 @@
}
void
-rip_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
+rip_ctlinput(struct icmp *icmp)
{
-
- switch (cmd) {
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
- case PRC_MSGSIZE:
- if (IPSEC_ENABLED(ipv4))
- IPSEC_CTLINPUT(ipv4, cmd, (struct sockaddr *)sin, ip);
- break;
+ if (IPSEC_ENABLED(ipv4))
+ IPSEC_CTLINPUT(ipv4, icmp);
#endif
- }
}
static int
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,23 +260,21 @@
}
void
-sctp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *inner_ip)
+sctp_ctlinput(struct icmp *icmp)
{
- struct ip *outer_ip;
+ struct ip *inner_ip, *outer_ip;
struct sctphdr *sh;
- struct icmp *icmp;
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
struct sctp_nets *net;
struct sctp_init_chunk *ch;
struct sockaddr_in src, dst;
- if (inetctlerrmap[cmd] == 0)
+ if (icmp_errmap(icmp) == 0)
return;
- icmp = (struct icmp *)((caddr_t)inner_ip -
- (sizeof(struct icmp) - sizeof(struct ip)));
outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
+ inner_ip = &icmp->icmp_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;
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -322,7 +322,7 @@
void sctp_close(struct socket *so);
int sctp_disconnect(struct socket *so);
-void sctp_ctlinput(int, struct sockaddr_in *, struct ip *);
+ipproto_ctlinput_t sctp_ctlinput;
int sctp_ctloutput(struct socket *, struct sockopt *);
void sctp_input_with_port(struct mbuf *, int, uint16_t);
int sctp_input(struct mbuf **, int *, int);
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -7190,11 +7190,11 @@
#ifdef INET
static void
-sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ctx SCTP_UNUSED)
+sctp_recv_icmp_tunneled_packet(udp_tun_icmp_param_t param)
{
+ struct icmp *icmp = param.icmp;
struct ip *outer_ip, *inner_ip;
struct sctphdr *sh;
- struct icmp *icmp;
struct udphdr *udp;
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
@@ -7203,9 +7203,7 @@
struct sockaddr_in src, dst;
uint8_t type, code;
- inner_ip = (struct ip *)vip;
- icmp = (struct icmp *)((caddr_t)inner_ip -
- (sizeof(struct icmp) - sizeof(struct ip)));
+ inner_ip = &icmp->icmp_ip;
outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
if (ntohs(outer_ip->ip_len) <
sizeof(struct ip) + 8 + (inner_ip->ip_hl << 2) + sizeof(struct udphdr) + 8) {
@@ -7300,9 +7298,9 @@
#ifdef INET6
static void
-sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx SCTP_UNUSED)
+sctp_recv_icmp6_tunneled_packet(udp_tun_icmp_param_t param)
{
- struct ip6ctlparam *ip6cp;
+ struct ip6ctlparam *ip6cp = param.ip6cp;
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
struct sctp_nets *net;
@@ -7311,7 +7309,6 @@
struct sockaddr_in6 src, dst;
uint8_t type, code;
- ip6cp = (struct ip6ctlparam *)d;
/*
* XXX: We assume that when IPV6 is non NULL, M and OFF are valid.
*/
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
@@ -2842,38 +2842,44 @@
}
static void
-tcp_ctlinput_with_port(int cmd, struct sockaddr_in *sin, struct ip *ip,
- uint16_t port)
+tcp_ctlinput_with_port(struct icmp *icp, uint16_t port)
{
+ struct ip *ip;
struct tcphdr *th;
struct inpcb *inp;
struct tcpcb *tp;
- struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
- struct icmp *icp;
+ struct inpcb *(*notify)(struct inpcb *, int);
struct in_conninfo inc;
tcp_seq icmp_tcp_seq;
- int mtu;
+ int errno, mtu;
- switch (cmd) {
- case PRC_MSGSIZE:
+ errno = icmp_errmap(icp);
+ switch (errno) {
+ case 0:
+ return;
+ case EMSGSIZE:
notify = tcp_mtudisc_notify;
break;
- case PRC_UNREACH_PORT:
- case PRC_UNREACH_PROTOCOL:
- case PRC_TIMXCEED_INTRANS:
- case PRC_UNREACH_ADMIN_PROHIB:
+ case ECONNREFUSED:
if (V_icmp_may_rst)
notify = tcp_drop_syn_sent;
+ else
+ notify = tcp_notify;
break;
+ case EHOSTUNREACH:
+ if (V_icmp_may_rst && icp->icmp_type == ICMP_TIMXCEED)
+ notify = tcp_drop_syn_sent;
+ else
+ notify = tcp_notify;
+ break;
+ default:
+ notify = tcp_notify;
}
- if (inetctlerrmap[cmd] == 0)
- return;
-
- icp = (struct icmp *)((caddr_t)ip - offsetof(struct icmp, icmp_ip));
+ ip = &icp->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,
+ inp = in_pcblookup(&V_tcbinfo, ip->ip_dst, th->th_dport, ip->ip_src,
th->th_sport, INPLOOKUP_WLOCKPCB, NULL);
if (inp != NULL) {
if (!(inp->inp_flags & INP_TIMEWAIT) &&
@@ -2881,7 +2887,7 @@
!(inp->inp_socket == NULL)) {
tp = intotcpcb(inp);
#ifdef TCP_OFFLOAD
- if (tp->t_flags & TF_TOE && cmd == PRC_MSGSIZE) {
+ if (tp->t_flags & TF_TOE && errno == EMSGSIZE) {
/*
* MTU discovery for offloaded connections. Let
* the TOE driver verify seq# and process it.
@@ -2896,7 +2902,7 @@
}
if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
- if (cmd == PRC_MSGSIZE) {
+ if (errno == EMSGSIZE) {
/*
* MTU discovery: we got a needfrag and
* will potentially try a lower MTU.
@@ -2910,22 +2916,21 @@
if (mtu < tp->t_maxseg +
sizeof(struct tcpiphdr)) {
bzero(&inc, sizeof(inc));
- inc.inc_faddr = sin->sin_addr;
+ inc.inc_faddr = ip->ip_dst;
inc.inc_fibnum =
inp->inp_inc.inc_fibnum;
tcp_hc_updatemtu(&inc, mtu);
inp = tcp_mtudisc(inp, mtu);
}
} else
- inp = (*notify)(inp,
- inetctlerrmap[cmd]);
+ inp = (*notify)(inp, errno);
}
}
} else {
bzero(&inc, sizeof(inc));
inc.inc_fport = th->th_dport;
inc.inc_lport = th->th_sport;
- inc.inc_faddr = sin->sin_addr;
+ inc.inc_faddr = ip->ip_dst;
inc.inc_laddr = ip->ip_src;
syncache_unreach(&inc, icmp_tcp_seq, port);
}
@@ -2935,26 +2940,24 @@
}
static void
-tcp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
+tcp_ctlinput(struct icmp *icmp)
{
- tcp_ctlinput_with_port(cmd, sin, ip, htons(0));
+ tcp_ctlinput_with_port(icmp, htons(0));
}
static void
-tcp_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *vip, void *unused)
+tcp_ctlinput_viaudp(udp_tun_icmp_param_t param)
{
/* Its a tunneled TCP over UDP icmp */
+ struct icmp *icmp = param.icmp;
struct ip *outer_ip, *inner_ip;
- struct icmp *icmp;
struct udphdr *udp;
struct tcphdr *th, ttemp;
int i_hlen, o_len;
uint16_t port;
- inner_ip = (struct ip *)vip;
- icmp = (struct icmp *)((caddr_t)inner_ip -
- (sizeof(struct icmp) - sizeof(struct ip)));
outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
+ inner_ip = &icmp->icmp_ip;
i_hlen = inner_ip->ip_hl << 2;
o_len = ntohs(outer_ip->ip_len);
if (o_len <
@@ -2975,7 +2978,7 @@
o_len -= sizeof(struct udphdr);
outer_ip->ip_len = htons(o_len);
/* Now call in to the normal handling code */
- tcp_ctlinput_with_port(cmd, (struct sockaddr_in *)sa, vip, port);
+ tcp_ctlinput_with_port(icmp, port);
}
#endif /* INET */
@@ -2995,11 +2998,10 @@
}
static void
-tcp6_ctlinput_with_port(int cmd, struct sockaddr_in6 *sin6,
- struct ip6ctlparam *ip6cp, uint16_t port)
+tcp6_ctlinput_with_port(struct ip6ctlparam *ip6cp, uint16_t port)
{
struct in6_addr *dst;
- struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
+ struct inpcb *(*notify)(struct inpcb *, int);
struct ip6_hdr *ip6;
struct mbuf *m;
struct inpcb *inp;
@@ -3013,29 +3015,51 @@
tcp_seq icmp_tcp_seq;
unsigned int mtu;
unsigned int off;
+ int errno;
icmp6 = ip6cp->ip6c_icmp6;
m = ip6cp->ip6c_m;
ip6 = ip6cp->ip6c_ip6;
off = ip6cp->ip6c_off;
- dst = ip6cp->ip6c_finaldst;
+ dst = &ip6cp->ip6c_finaldst->sin6_addr;
- switch (cmd) {
- case PRC_MSGSIZE:
+ errno = icmp6_errmap(icmp6);
+ switch (errno) {
+ case 0:
+ return;
+ case EMSGSIZE:
notify = tcp_mtudisc_notify;
break;
- case PRC_UNREACH_ADMIN_PROHIB:
- case PRC_UNREACH_PORT:
- case PRC_UNREACH_PROTOCOL:
- case PRC_TIMXCEED_INTRANS:
+ case ECONNREFUSED:
if (V_icmp_may_rst)
notify = tcp_drop_syn_sent;
+ else
+ notify = tcp_notify;
+ break;
+ case EHOSTUNREACH:
+ /*
+ * There are only four ICMPs that may reset connection:
+ * - administratively prohibited
+ * - port unreachable
+ * - time exceeded in transit
+ * - unknown next header
+ */
+ if (V_icmp_may_rst &&
+ ((icmp6->icmp6_type == ICMP6_DST_UNREACH &&
+ (icmp6->icmp6_code == ICMP6_DST_UNREACH_ADMIN ||
+ icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)) ||
+ (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED &&
+ icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) ||
+ (icmp6->icmp6_type == ICMP6_PARAM_PROB &&
+ icmp6->icmp6_code == ICMP6_PARAMPROB_NEXTHEADER)))
+ notify = tcp_drop_syn_sent;
+ else
+ notify = tcp_notify;
break;
+ default:
+ notify = tcp_notify;
}
- if (inet6ctlerrmap[cmd] == 0)
- return;
-
/* Check if we can safely get the ports from the tcp hdr */
if (m == NULL ||
(m->m_pkthdr.len <
@@ -3057,7 +3081,7 @@
!(inp->inp_socket == NULL)) {
tp = intotcpcb(inp);
#ifdef TCP_OFFLOAD
- if (tp->t_flags & TF_TOE && cmd == PRC_MSGSIZE) {
+ if (tp->t_flags & TF_TOE && errno == EMSGSIZE) {
/* MTU discovery for offloaded connections. */
mtu = tcp6_next_pmtu(icmp6);
tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu);
@@ -3069,7 +3093,7 @@
}
if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
- if (cmd == PRC_MSGSIZE) {
+ if (errno == EMSGSIZE) {
/*
* MTU discovery:
* If we got a needfrag set the MTU
@@ -3097,8 +3121,7 @@
ICMP6STAT_INC(icp6s_pmtuchg);
}
} else
- inp = (*notify)(inp,
- inet6ctlerrmap[cmd]);
+ inp = (*notify)(inp, errno);
}
}
} else {
@@ -3117,20 +3140,19 @@
}
static void
-tcp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
+tcp6_ctlinput(struct ip6ctlparam *ctl)
{
- tcp6_ctlinput_with_port(cmd, sin6, ctl, htons(0));
+ tcp6_ctlinput_with_port(ctl, htons(0));
}
static void
-tcp6_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *d, void *unused)
+tcp6_ctlinput_viaudp(udp_tun_icmp_param_t param)
{
- struct ip6ctlparam *ip6cp;
+ struct ip6ctlparam *ip6cp = param.ip6cp;
struct mbuf *m;
struct udphdr *udp;
uint16_t port;
- ip6cp = (struct ip6ctlparam *)d;
m = m_pulldown(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(struct udphdr), NULL);
if (m == NULL) {
return;
@@ -3145,7 +3167,7 @@
ip6cp->ip6c_m->m_pkthdr.len -= sizeof(struct udphdr);
}
/* Now call in to the normal handling code */
- tcp6_ctlinput_with_port(cmd, (struct sockaddr_in6 *)sa, ip6cp, port);
+ tcp6_ctlinput_with_port(ip6cp, port);
}
#endif /* INET6 */
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
@@ -740,54 +740,52 @@
#ifdef INET
static void
-udp_common_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip,
- struct inpcbinfo *pcbinfo)
+udp_common_ctlinput(struct icmp *icmp, struct inpcbinfo *pcbinfo)
{
+ struct ip *ip = &icmp->icmp_ip;
struct udphdr *uh;
struct inpcb *inp;
- if (inetctlerrmap[cmd] == 0)
+ if (icmp_errmap(icmp) == 0)
return;
uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
- inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport, ip->ip_src,
+ inp = in_pcblookup(pcbinfo, ip->ip_dst, 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]);
+ udp_notify(inp, icmp_errmap(icmp));
INP_WUNLOCK(inp);
} else {
- inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
+ inp = in_pcblookup(pcbinfo, ip->ip_dst, 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);
+ func(icmp);
}
}
}
static void
-udp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
+udp_ctlinput(struct icmp *icmp)
{
- return (udp_common_ctlinput(cmd, sin, ip, &V_udbinfo));
+ return (udp_common_ctlinput(icmp, &V_udbinfo));
}
static void
-udplite_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
+udplite_ctlinput(struct icmp *icmp)
{
- return (udp_common_ctlinput(cmd, sin, ip, &V_ulitecbinfo));
+ return (udp_common_ctlinput(icmp, &V_ulitecbinfo));
}
#endif /* INET */
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -64,7 +64,11 @@
#ifdef _KERNEL
typedef bool udp_tun_func_t(struct mbuf *, int, struct inpcb *,
const struct sockaddr *, void *);
-typedef void udp_tun_icmp_t(int, struct sockaddr *, void *, void *);
+typedef union {
+ struct icmp *icmp;
+ struct ip6ctlparam *ip6cp;
+} udp_tun_icmp_param_t __attribute__((__transparent_union__));
+typedef void udp_tun_icmp_t(udp_tun_icmp_param_t);
/*
* UDP control block; one per udp.
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -147,7 +147,7 @@
struct ifnet **, struct in6_addr *);
static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
struct ifnet *, int);
-static int icmp6_notify_error(struct mbuf **, int, int, int);
+static int icmp6_notify_error(struct mbuf **, int, int);
/*
* Kernel module interface for updating icmp6stat. The argument is an index
@@ -390,6 +390,50 @@
m_freem(m);
}
+int
+icmp6_errmap(const struct icmp6_hdr *icmp6)
+{
+
+ switch (icmp6->icmp6_type) {
+ case ICMP6_DST_UNREACH:
+ switch (icmp6->icmp6_code) {
+ case ICMP6_DST_UNREACH_NOROUTE:
+ case ICMP6_DST_UNREACH_ADDR:
+ return (EHOSTUNREACH);
+ case ICMP6_DST_UNREACH_NOPORT:
+ case ICMP6_DST_UNREACH_ADMIN:
+ return (ECONNREFUSED);
+ case ICMP6_DST_UNREACH_BEYONDSCOPE:
+ return (ENOPROTOOPT);
+ default:
+ return (0); /* Shouldn't happen. */
+ }
+ case ICMP6_PACKET_TOO_BIG:
+ return (EMSGSIZE);
+ case ICMP6_TIME_EXCEEDED:
+ switch (icmp6->icmp6_code) {
+ case ICMP6_TIME_EXCEED_TRANSIT:
+ return (EHOSTUNREACH);
+ case ICMP6_TIME_EXCEED_REASSEMBLY:
+ return (0);
+ default:
+ return (0); /* Shouldn't happen. */
+ }
+ case ICMP6_PARAM_PROB:
+ switch (icmp6->icmp6_code) {
+ case ICMP6_PARAMPROB_NEXTHEADER:
+ return (ECONNREFUSED);
+ case ICMP6_PARAMPROB_HEADER:
+ case ICMP6_PARAMPROB_OPTION:
+ return (ENOPROTOOPT);
+ default:
+ return (0); /* Shouldn't happen. */
+ }
+ default:
+ return (0);
+ }
+}
+
/*
* Process a received ICMP6 message.
*/
@@ -467,72 +511,43 @@
case ICMP6_DST_UNREACH:
icmp6_ifstat_inc(ifp, ifs6_in_dstunreach);
switch (code) {
- case ICMP6_DST_UNREACH_NOROUTE:
- case ICMP6_DST_UNREACH_ADDR: /* PRC_HOSTDEAD is a DOS */
- code = PRC_UNREACH_NET;
- break;
case ICMP6_DST_UNREACH_ADMIN:
icmp6_ifstat_inc(ifp, ifs6_in_adminprohib);
- code = PRC_UNREACH_ADMIN_PROHIB;
- break;
+ case ICMP6_DST_UNREACH_NOROUTE:
+ case ICMP6_DST_UNREACH_ADDR:
case ICMP6_DST_UNREACH_BEYONDSCOPE:
- /* I mean "source address was incorrect." */
- code = PRC_PARAMPROB;
- break;
case ICMP6_DST_UNREACH_NOPORT:
- code = PRC_UNREACH_PORT;
- break;
+ goto deliver;
default:
goto badcode;
}
- goto deliver;
- break;
-
case ICMP6_PACKET_TOO_BIG:
icmp6_ifstat_inc(ifp, ifs6_in_pkttoobig);
-
- /* validation is made in icmp6_mtudisc_update */
-
- code = PRC_MSGSIZE;
-
/*
+ * Validation is made in icmp6_mtudisc_update.
* Updating the path MTU will be done after examining
* intermediate extension headers.
*/
goto deliver;
- break;
-
case ICMP6_TIME_EXCEEDED:
icmp6_ifstat_inc(ifp, ifs6_in_timeexceed);
switch (code) {
case ICMP6_TIME_EXCEED_TRANSIT:
- code = PRC_TIMXCEED_INTRANS;
- break;
case ICMP6_TIME_EXCEED_REASSEMBLY:
- code = PRC_TIMXCEED_REASS;
- break;
+ goto deliver;
default:
goto badcode;
}
- goto deliver;
- break;
-
case ICMP6_PARAM_PROB:
icmp6_ifstat_inc(ifp, ifs6_in_paramprob);
switch (code) {
case ICMP6_PARAMPROB_NEXTHEADER:
- code = PRC_UNREACH_PROTOCOL;
- break;
case ICMP6_PARAMPROB_HEADER:
case ICMP6_PARAMPROB_OPTION:
- code = PRC_PARAMPROB;
- break;
+ goto deliver;
default:
goto badcode;
}
- goto deliver;
- break;
-
case ICMP6_ECHO_REQUEST:
icmp6_ifstat_inc(ifp, ifs6_in_echo);
if (code != 0)
@@ -856,14 +871,13 @@
ifp ? ifp->if_index : 0));
if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) {
/* ICMPv6 error: MUST deliver it by spec... */
- code = PRC_NCMDS;
- /* deliver */
+ goto deliver;
} else {
/* ICMPv6 informational: MUST not deliver */
break;
}
deliver:
- if (icmp6_notify_error(&m, off, icmp6len, code) != 0) {
+ if (icmp6_notify_error(&m, off, icmp6len) != 0) {
/* In this case, m should've been freed. */
*mp = NULL;
return (IPPROTO_DONE);
@@ -892,7 +906,7 @@
}
static int
-icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
+icmp6_notify_error(struct mbuf **mp, int off, int icmp6len)
{
struct mbuf *m;
struct icmp6_hdr *icmp6;
@@ -1075,7 +1089,7 @@
ip6cp.ip6c_icmp6 = icmp6;
ip6cp.ip6c_ip6 = (struct ip6_hdr *)(icmp6 + 1);
ip6cp.ip6c_off = eoff;
- ip6cp.ip6c_finaldst = &icmp6dst.sin6_addr;
+ ip6cp.ip6c_finaldst = &icmp6dst;
ip6cp.ip6c_src = &icmp6src;
ip6cp.ip6c_nxt = nxt;
@@ -1086,7 +1100,7 @@
}
if (ip6_ctlprotox[nxt] != NULL)
- ip6_ctlprotox[nxt](code, &icmp6dst, &ip6cp);
+ ip6_ctlprotox[nxt](&ip6cp);
}
*mp = m;
return (0);
@@ -1100,7 +1114,7 @@
void
icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
{
- struct in6_addr *dst = ip6cp->ip6c_finaldst;
+ struct in6_addr *dst = &ip6cp->ip6c_finaldst->sin6_addr;
struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */
u_int mtu = ntohl(icmp6->icmp6_mtu);
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -680,10 +680,11 @@
return ((inp->inp_vflag & INP_IPV6) != 0);
}
+
void
in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr_in6 *sa6_dst,
u_int fport_arg, const struct sockaddr_in6 *src, u_int lport_arg,
- int cmd, void *cmdarg,
+ int errno, void *cmdarg,
struct inpcb *(*notify)(struct inpcb *, int))
{
struct inpcb_iterator inpi = INP_ITERATOR(pcbinfo, INPLOOKUP_WLOCKPCB,
@@ -692,10 +693,6 @@
struct sockaddr_in6 sa6_src;
u_short fport = fport_arg, lport = lport_arg;
u_int32_t flowinfo;
- int errno;
-
- if ((unsigned)cmd >= PRC_NCMDS)
- return;
if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr))
return;
@@ -706,23 +703,6 @@
sa6_src = (src == NULL) ? sa6_any : *src;
flowinfo = sa6_src.sin6_flowinfo;
- /*
- * Redirects go to all references to the destination,
- * and use in6_rtchange to invalidate the route cache.
- * Dead host indications: also use in6_rtchange to invalidate
- * the cache, and deliver the error to all the sockets.
- * Otherwise, if we have knowledge of the local port and address,
- * deliver only to that socket.
- */
- if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
- fport = 0;
- lport = 0;
- bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr));
-
- if (cmd != PRC_HOSTDEAD)
- notify = in6_rtchange;
- }
- errno = inet6ctlerrmap[cmd];
while ((inp = inp_next(&inpi)) != NULL) {
INP_WLOCK_ASSERT(inp);
/*
@@ -731,7 +711,7 @@
* know the value, notify.
* XXX: should we avoid to notify the value to TCP sockets?
*/
- if (cmd == PRC_MSGSIZE && cmdarg != NULL)
+ if (errno == EMSGSIZE && cmdarg != NULL)
ip6_notify_pmtu(inp, sa6_dst, *(uint32_t *)cmdarg);
/*
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -553,7 +553,6 @@
offsetof(struct in6_ifstat, tag) / sizeof(uint64_t)], 1);\
} while (/*CONSTCOND*/ 0)
-extern u_char inet6ctlerrmap[];
VNET_DECLARE(unsigned long, in6_maxmtu);
#define V_in6_maxmtu VNET(in6_maxmtu)
#endif /* _KERNEL */
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1707,23 +1707,3 @@
proto = *nxtp;
}
}
-
-/*
- * System control for IP6
- * (x) - issued by icmp6_input()
- */
-u_char inet6ctlerrmap[PRC_NCMDS] = {
- [PRC_MSGSIZE] = EMSGSIZE, /* (x) */
- [PRC_HOSTDEAD] = EHOSTDOWN,
- [PRC_HOSTUNREACH] = EHOSTUNREACH,
- [PRC_UNREACH_NET] = EHOSTUNREACH, /* (x) */
- [PRC_UNREACH_HOST] = EHOSTUNREACH,
- [PRC_UNREACH_PROTOCOL] = ECONNREFUSED, /* (x) */
- [PRC_UNREACH_PORT] = ECONNREFUSED, /* (x) */
- [12] = EMSGSIZE,
- [PRC_UNREACH_SRCFAIL] = EHOSTUNREACH,
- [PRC_TIMXCEED_INTRANS] = EHOSTUNREACH, /* (x) */
- [PRC_TIMXCEED_REASS] = 0, /* (x) */
- [PRC_PARAMPROB] = ENOPROTOOPT, /* (x) */
- [PRC_UNREACH_ADMIN_PROHIB] = ECONNREFUSED, /* (x) */
-};
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -421,9 +421,9 @@
* | ip6c_icmp6
* ip6c_m
*
- * ip6c_finaldst usually points to ip6c_ip6->ip6_dst. if the original
- * (internal) packet carries a routing header, it may point the final
- * destination address in the routing header.
+ * ip6c_finaldst's sin6_addr usually points to ip6c_ip6->ip6_dst. If the
+ * original * (internal) packet carries a routing header, it may point the
+ * final * destination address in the routing header.
*
* ip6c_src: ip6c_ip6->ip6_src + scope info + flowlabel in ip6c_ip6
* (beware of flowlabel, if you try to compare it against others)
@@ -436,14 +436,13 @@
int ip6c_off; /* offset of the target proto header */
struct sockaddr_in6 *ip6c_src; /* srcaddr w/ additional info */
struct sockaddr_in6 *ip6c_dst; /* (final) dstaddr w/ additional info */
- struct in6_addr *ip6c_finaldst; /* final destination address */
+ struct sockaddr_in6 *ip6c_finaldst; /* final destination address */
void *ip6c_cmdarg; /* control command dependent data */
u_int8_t ip6c_nxt; /* final next header field */
};
typedef int ip6proto_input_t(struct mbuf **, int *, int);
-typedef void ip6proto_ctlinput_t(int, struct sockaddr_in6 *,
- struct ip6ctlparam *);
+typedef void ip6proto_ctlinput_t(struct ip6ctlparam *);
int ip6proto_register(uint8_t, ip6proto_input_t, ip6proto_ctlinput_t);
int ip6proto_unregister(uint8_t);
#define IP6PROTO_REGISTER(prot, input, ctl) do { \
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -323,33 +323,14 @@
}
void
-rip6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ip6cp)
+rip6_ctlinput(struct ip6ctlparam *ip6cp)
{
- const struct sockaddr_in6 *sa6_src;
- void *cmdarg;
- struct inpcb *(*notify)(struct inpcb *, int) = in6_rtchange;
-
- if ((unsigned)cmd >= PRC_NCMDS)
- return;
- if (PRC_IS_REDIRECT(cmd))
- notify = in6_rtchange, ip6cp = NULL;
- else if (cmd == PRC_HOSTDEAD)
- ip6cp = NULL;
- else if (inet6ctlerrmap[cmd] == 0)
- return;
+ int errno;
- /*
- * If the parameter is from icmp6, decode it.
- */
- if (ip6cp != NULL) {
- cmdarg = ip6cp->ip6c_cmdarg;
- sa6_src = ip6cp->ip6c_src;
- } else {
- cmdarg = NULL;
- sa6_src = &sa6_any;
- }
-
- in6_pcbnotify(&V_ripcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg, notify);
+ if ((errno = icmp6_errmap(ip6cp->ip6c_icmp6)) != 0)
+ in6_pcbnotify(&V_ripcbinfo, ip6cp->ip6c_finaldst, 0,
+ ip6cp->ip6c_src, 0, errno, ip6cp->ip6c_cmdarg,
+ in6_rtchange);
}
/*
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
@@ -248,7 +248,7 @@
}
void
-sctp6_ctlinput(int cmd, struct sockaddr_in6 *pktdst, struct ip6ctlparam *ip6cp)
+sctp6_ctlinput(struct ip6ctlparam *ip6cp)
{
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
@@ -256,13 +256,9 @@
struct sctphdr sh;
struct sockaddr_in6 src, dst;
- if (inet6ctlerrmap[cmd] == 0)
+ if (icmp6_errmap(ip6cp->ip6c_icmp6) == 0)
return;
- if (ip6cp->ip6c_m == NULL) {
- return;
- }
-
/*
* Check if we can safely examine the ports and the
* verification tag of the SCTP common header.
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
@@ -547,28 +547,24 @@
}
static void
-udp6_common_ctlinput(int cmd, struct sockaddr_in6 *sin6,
- struct ip6ctlparam *ip6cp, struct inpcbinfo *pcbinfo)
+udp6_common_ctlinput(struct ip6ctlparam *ip6cp, struct inpcbinfo *pcbinfo)
{
struct udphdr uh;
struct ip6_hdr *ip6;
struct mbuf *m;
struct inpcb *inp;
- int off = 0;
- void *cmdarg;
- struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
+ int errno, off = 0;
struct udp_portonly {
u_int16_t uh_sport;
u_int16_t uh_dport;
} *uhp;
- if (inet6ctlerrmap[cmd] == 0)
+ if ((errno = icmp6_errmap(ip6cp->ip6c_icmp6)) == 0)
return;
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))
@@ -589,25 +585,25 @@
func = up->u_icmp_func;
INP_RUNLOCK(inp);
if (func != NULL)
- func(cmd, (struct sockaddr *)ip6cp->ip6c_src, ip6cp,
- up->u_tun_ctx);
+ func(ip6cp);
}
- in6_pcbnotify(pcbinfo, sin6, uh.uh_dport, ip6cp->ip6c_src,
- uh.uh_sport, cmd, cmdarg, notify);
+ in6_pcbnotify(pcbinfo, ip6cp->ip6c_finaldst, uh.uh_dport,
+ ip6cp->ip6c_src, uh.uh_sport, errno, ip6cp->ip6c_cmdarg,
+ udp_notify);
}
static void
-udp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
+udp6_ctlinput(struct ip6ctlparam *ctl)
{
- return (udp6_common_ctlinput(cmd, sin6, ctl, &V_udbinfo));
+ return (udp6_common_ctlinput(ctl, &V_udbinfo));
}
static void
-udplite6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
+udplite6_ctlinput(struct ip6ctlparam *ctl)
{
- return (udp6_common_ctlinput(cmd, sin6, ctl, &V_ulitecbinfo));
+ return (udp6_common_ctlinput(ctl, &V_ulitecbinfo));
}
static int
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -279,23 +279,21 @@
}
int
-ipsec4_ctlinput(int code, struct sockaddr *sa, void *v)
+ipsec4_ctlinput(ipsec_ctlinput_param_t param)
{
+ struct icmp *icp = param.icmp;
+ struct ip *ip = &icp->icmp_ip;
+ struct sockaddr_in icmpsrc = {
+ .sin_len = sizeof(struct sockaddr_in),
+ .sin_family = AF_INET,
+ .sin_addr = ip->ip_dst,
+ };
struct in_conninfo inc;
struct secasvar *sav;
- struct icmp *icp;
- struct ip *ip = v;
uint32_t pmtu, spi;
uint32_t max_pmtu;
uint8_t proto;
- if (code != PRC_MSGSIZE || ip == NULL)
- return (EINVAL);
- if (sa->sa_family != AF_INET ||
- sa->sa_len != sizeof(struct sockaddr_in))
- return (EAFNOSUPPORT);
-
- icp = __containerof(ip, struct icmp, icmp_ip);
pmtu = ntohs(icp->icmp_nextmtu);
if (pmtu < V_ip4_ipsec_min_pmtu)
@@ -307,14 +305,14 @@
return (EINVAL);
memcpy(&spi, (caddr_t)ip + (ip->ip_hl << 2), sizeof(spi));
- sav = key_allocsa((union sockaddr_union *)sa, proto, spi);
+ sav = key_allocsa((union sockaddr_union *)&icmpsrc, proto, spi);
if (sav == NULL)
return (ENOENT);
key_freesav(&sav);
memset(&inc, 0, sizeof(inc));
- inc.inc_faddr = satosin(sa)->sin_addr;
+ inc.inc_faddr = ip->ip_dst;
/* Update pmtu only if its smaller than the current one. */
max_pmtu = tcp_hc_getmtu(&inc);
@@ -568,7 +566,7 @@
}
int
-ipsec6_ctlinput(int code, struct sockaddr *sa, void *v)
+ipsec6_ctlinput(ipsec_ctlinput_param_t param)
{
return (0);
}
diff --git a/sys/netipsec/ipsec_support.h b/sys/netipsec/ipsec_support.h
--- a/sys/netipsec/ipsec_support.h
+++ b/sys/netipsec/ipsec_support.h
@@ -38,6 +38,13 @@
struct sockaddr;
struct ipsec_support;
struct tcpmd5_support;
+struct icmp;
+struct ip6ctlparam;
+
+typedef union {
+ struct icmp *icmp;
+ struct ip6ctlparam *ip6cp;
+} ipsec_ctlinput_param_t __attribute__((__transparent_union__));
size_t ipsec_hdrsiz_inpcb(struct inpcb *);
int ipsec_init_pcbpolicy(struct inpcb *);
@@ -53,7 +60,7 @@
int ipsec4_pcbctl(struct inpcb *, struct sockopt *);
int ipsec4_output(struct mbuf *, struct inpcb *);
int ipsec4_capability(struct mbuf *, u_int);
-int ipsec4_ctlinput(int, struct sockaddr *, void *);
+int ipsec4_ctlinput(ipsec_ctlinput_param_t);
#endif /* INET */
#ifdef INET6
@@ -63,7 +70,7 @@
int ipsec6_pcbctl(struct inpcb *, struct sockopt *);
int ipsec6_output(struct mbuf *, struct inpcb *);
int ipsec6_capability(struct mbuf *, u_int);
-int ipsec6_ctlinput(int, struct sockaddr *, void *);
+int ipsec6_ctlinput(ipsec_ctlinput_param_t);
#endif /* INET6 */
struct ipsec_methods {
@@ -74,7 +81,7 @@
int (*pcbctl)(struct inpcb *, struct sockopt *);
size_t (*hdrsize)(struct inpcb *);
int (*capability)(struct mbuf *, u_int);
- int (*ctlinput)(int, struct sockaddr *, void *);
+ int (*ctlinput)(ipsec_ctlinput_param_t);
int (*udp_input)(struct mbuf *, int, int);
int (*udp_pcbctl)(struct inpcb *, struct sockopt *);
@@ -156,8 +163,8 @@
(*(proto ## _ipsec_support)->methods->capability)(m, __VA_ARGS__)
#define IPSEC_HDRSIZE(proto, inp) \
(*(proto ## _ipsec_support)->methods->hdrsize)(inp)
-#define IPSEC_CTLINPUT(proto, code, sa, v) \
- (*(proto ## _ipsec_support)->methods->ctlinput)(code, sa, v)
+#define IPSEC_CTLINPUT(proto, param) \
+ (*(proto ## _ipsec_support)->methods->ctlinput)(param)
#define UDPENCAP_INPUT(m, ...) \
(*ipv4_ipsec_support->methods->udp_input)(m, __VA_ARGS__)
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -167,49 +167,6 @@
#define PR_CAPATTACH 0x80 /* socket can attach in cap mode */
#define PR_SOCKBUF 0x100 /* private implementation of buffers */
-/*
- * The arguments to the ctlinput routine are
- * (*protosw[].pr_ctlinput)(cmd, sa, arg);
- * where cmd is one of the commands below, sa is a pointer to a sockaddr,
- * and arg is a `void *' argument used within a protocol family.
- */
-#define PRC_ROUTEDEAD 1 /* select new route if possible ??? */
-/* was PRC_QUENCH2 3 DEC congestion bit says slow down */
-/* was PRC_QUENCH 4 Deprecated by RFC 6633 */
-#define PRC_MSGSIZE 5 /* message size forced drop */
-#define PRC_HOSTDEAD 6 /* host appears to be down */
-#define PRC_HOSTUNREACH 7 /* deprecated (use PRC_UNREACH_HOST) */
-#define PRC_UNREACH_NET 8 /* no route to network */
-#define PRC_UNREACH_HOST 9 /* no route to host */
-#define PRC_UNREACH_PROTOCOL 10 /* dst says bad protocol */
-#define PRC_UNREACH_PORT 11 /* bad port # */
-/* was PRC_UNREACH_NEEDFRAG 12 (use PRC_MSGSIZE) */
-#define PRC_UNREACH_SRCFAIL 13 /* source route failed */
-#define PRC_REDIRECT_NET 14 /* net routing redirect */
-#define PRC_REDIRECT_HOST 15 /* host routing redirect */
-#define PRC_REDIRECT_TOSNET 16 /* redirect for type of service & net */
-#define PRC_REDIRECT_TOSHOST 17 /* redirect for tos & host */
-#define PRC_TIMXCEED_INTRANS 18 /* packet lifetime expired in transit */
-#define PRC_TIMXCEED_REASS 19 /* lifetime expired on reass q */
-#define PRC_PARAMPROB 20 /* header incorrect */
-#define PRC_UNREACH_ADMIN_PROHIB 21 /* packet administrativly prohibited */
-
-#define PRC_NCMDS 22
-
-#define PRC_IS_REDIRECT(cmd) \
- ((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
-
-#ifdef PRCREQUESTS
-char *prcrequests[] = {
- "IFDOWN", "ROUTEDEAD", "IFUP", "DEC-BIT-QUENCH2",
- "QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
- "NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
- "#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
- "TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
- "PARAMPROB", "ADMIN-UNREACH"
-};
-#endif
-
/*
* The arguments to ctloutput are:
* (*protosw[].pr_ctloutput)(req, so, level, optname, optval, p);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 22, 4:55 PM (7 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35372847
Default Alt Text
D36731.id111051.diff (37 KB)
Attached To
Mode
D36731: netinet*: remove PRC_ constants and streamline ICMP processing
Attached
Detach File
Event Timeline
Log In to Comment