netinet*: de-void control input IP protocol methods
After decoupling of protosw(9) and IP wire protocols in 78b1fc05b2
for
IPv4 we got vector ip_ctlprotox[] that is executed only and only from
icmp_input() and respectively for IPv6 we got ip6_ctlprotox[] executed
only and only from icmp6_input(). This allows to use protocol specific
argument types in these methods instead of struct sockaddr and void.
Reviewed by: melifaro
Differential revision: https://reviews.freebsd.org/D36727
This commit is contained in:
parent
46ddeb6be8
commit
43d39ca7e5
@ -573,8 +573,8 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
|
||||
* 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,
|
||||
(struct sockaddr *)&icmpsrc, &icp->icmp_ip);
|
||||
ip_ctlprotox[icp->icmp_ip.ip_p](code, &icmpsrc,
|
||||
&icp->icmp_ip);
|
||||
break;
|
||||
|
||||
badcode:
|
||||
|
@ -228,8 +228,6 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
|
||||
struct mbuf *);
|
||||
void ip_fillid(struct ip *);
|
||||
int rip_ctloutput(struct socket *, struct sockopt *);
|
||||
void rip_ctlinput(int, struct sockaddr *, void *);
|
||||
int rip_input(struct mbuf **, int *, int);
|
||||
int ipip_input(struct mbuf **, int *, int);
|
||||
int rsvp_input(struct mbuf **, int *, int);
|
||||
|
||||
@ -240,7 +238,7 @@ extern void (*ip_rsvp_force_done)(struct socket *);
|
||||
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 *, void *);
|
||||
typedef void ipproto_ctlinput_t(int, struct sockaddr_in *, struct ip *);
|
||||
int ipproto_register(uint8_t, ipproto_input_t, ipproto_ctlinput_t);
|
||||
int ipproto_unregister(uint8_t);
|
||||
#define IPPROTO_REGISTER(prot, input, ctl) do { \
|
||||
@ -249,6 +247,9 @@ int ipproto_unregister(uint8_t);
|
||||
MPASS(error == 0); \
|
||||
} while (0)
|
||||
|
||||
ipproto_input_t rip_input;
|
||||
ipproto_ctlinput_t rip_ctlinput;
|
||||
|
||||
VNET_DECLARE(struct pfil_head *, inet_pfil_head);
|
||||
#define V_inet_pfil_head VNET(inet_pfil_head)
|
||||
#define PFIL_INET_NAME "inet"
|
||||
|
@ -804,14 +804,14 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
}
|
||||
|
||||
void
|
||||
rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
rip_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
|
||||
case PRC_MSGSIZE:
|
||||
if (IPSEC_ENABLED(ipv4))
|
||||
IPSEC_CTLINPUT(ipv4, cmd, sa, vip);
|
||||
IPSEC_CTLINPUT(ipv4, cmd, (struct sockaddr *)sin, ip);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ sctp_notify(struct sctp_inpcb *inp,
|
||||
}
|
||||
|
||||
void
|
||||
sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
sctp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
|
||||
{
|
||||
struct ip *outer_ip;
|
||||
struct ip *inner_ip;
|
||||
@ -272,17 +272,16 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
struct sctp_init_chunk *ch;
|
||||
struct sockaddr_in src, dst;
|
||||
|
||||
if (sa->sa_family != AF_INET ||
|
||||
((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY) {
|
||||
return;
|
||||
}
|
||||
if (PRC_IS_REDIRECT(cmd)) {
|
||||
vip = NULL;
|
||||
ip = NULL;
|
||||
} else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
|
||||
return;
|
||||
}
|
||||
if (vip != NULL) {
|
||||
inner_ip = (struct ip *)vip;
|
||||
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));
|
||||
|
@ -322,7 +322,7 @@ struct sctphdr;
|
||||
|
||||
void sctp_close(struct socket *so);
|
||||
int sctp_disconnect(struct socket *so);
|
||||
void sctp_ctlinput(int, struct sockaddr *, void *);
|
||||
void sctp_ctlinput(int, struct sockaddr_in *, struct ip *);
|
||||
int sctp_ctloutput(struct socket *, struct sockopt *);
|
||||
void sctp_input_with_port(struct mbuf *, int, uint16_t);
|
||||
int sctp_input(struct mbuf **, int *, int);
|
||||
|
@ -109,9 +109,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/tcp_syncache.h>
|
||||
#include <netinet/tcp_hpts.h>
|
||||
#include <netinet/cc/cc.h>
|
||||
#ifdef INET6
|
||||
#include <netinet6/tcp6_var.h>
|
||||
#endif
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/tcp_fastopen.h>
|
||||
#ifdef TCPPCAP
|
||||
@ -125,6 +122,9 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#ifdef INET6
|
||||
#include <netinet6/tcp6_var.h>
|
||||
#endif
|
||||
|
||||
#include <netipsec/ipsec_support.h>
|
||||
|
||||
@ -133,6 +133,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
static ip6proto_ctlinput_t tcp6_ctlinput;
|
||||
static udp_tun_icmp_t tcp6_ctlinput_viaudp;
|
||||
|
||||
VNET_DEFINE(int, tcp_mssdflt) = TCP_MSS;
|
||||
#ifdef INET6
|
||||
VNET_DEFINE(int, tcp_v6mssdflt) = TCP6_MSS;
|
||||
@ -372,6 +375,8 @@ static struct inpcb *tcp_mtudisc_notify(struct inpcb *, int);
|
||||
static struct inpcb *tcp_mtudisc(struct inpcb *, int);
|
||||
static char * tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th,
|
||||
const void *ip4hdr, const void *ip6hdr);
|
||||
static ipproto_ctlinput_t tcp_ctlinput;
|
||||
static udp_tun_icmp_t tcp_ctlinput_viaudp;
|
||||
|
||||
static struct tcp_function_block tcp_def_funcblk = {
|
||||
.tfb_tcp_block_name = "freebsd",
|
||||
@ -2849,11 +2854,10 @@ tcp_next_pmtu(const struct icmp *icp, const struct ip *ip)
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
tcp_ctlinput_with_port(int cmd, struct sockaddr_in *sin, struct ip *ip,
|
||||
uint16_t port)
|
||||
{
|
||||
struct ip *ip = vip;
|
||||
struct tcphdr *th;
|
||||
struct in_addr faddr;
|
||||
struct inpcb *inp;
|
||||
struct tcpcb *tp;
|
||||
struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
|
||||
@ -2862,8 +2866,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
tcp_seq icmp_tcp_seq;
|
||||
int mtu;
|
||||
|
||||
faddr = ((struct sockaddr_in *)sa)->sin_addr;
|
||||
if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY)
|
||||
return;
|
||||
|
||||
if (cmd == PRC_MSGSIZE)
|
||||
@ -2884,13 +2887,14 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
return;
|
||||
|
||||
if (ip == NULL) {
|
||||
in_pcbnotifyall(&V_tcbinfo, faddr, inetctlerrmap[cmd], notify);
|
||||
in_pcbnotifyall(&V_tcbinfo, sin->sin_addr, inetctlerrmap[cmd],
|
||||
notify);
|
||||
return;
|
||||
}
|
||||
|
||||
icp = (struct icmp *)((caddr_t)ip - offsetof(struct icmp, icmp_ip));
|
||||
th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
|
||||
inp = in_pcblookup(&V_tcbinfo, faddr, th->th_dport, ip->ip_src,
|
||||
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 */
|
||||
@ -2933,7 +2937,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
if (mtu < tp->t_maxseg +
|
||||
sizeof(struct tcpiphdr)) {
|
||||
bzero(&inc, sizeof(inc));
|
||||
inc.inc_faddr = faddr;
|
||||
inc.inc_faddr = sin->sin_addr;
|
||||
inc.inc_fibnum =
|
||||
inp->inp_inc.inc_fibnum;
|
||||
tcp_hc_updatemtu(&inc, mtu);
|
||||
@ -2948,7 +2952,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
bzero(&inc, sizeof(inc));
|
||||
inc.inc_fport = th->th_dport;
|
||||
inc.inc_lport = th->th_sport;
|
||||
inc.inc_faddr = faddr;
|
||||
inc.inc_faddr = sin->sin_addr;
|
||||
inc.inc_laddr = ip->ip_src;
|
||||
syncache_unreach(&inc, icmp_tcp_seq, port);
|
||||
}
|
||||
@ -2957,13 +2961,13 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
|
||||
INP_WUNLOCK(inp);
|
||||
}
|
||||
|
||||
void
|
||||
tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
static void
|
||||
tcp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
|
||||
{
|
||||
tcp_ctlinput_with_port(cmd, sa, vip, htons(0));
|
||||
tcp_ctlinput_with_port(cmd, sin, ip, htons(0));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
tcp_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *vip, void *unused)
|
||||
{
|
||||
/* Its a tunneled TCP over UDP icmp */
|
||||
@ -2998,7 +3002,7 @@ tcp_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *vip, void *unused)
|
||||
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, sa, vip, port);
|
||||
tcp_ctlinput_with_port(cmd, (struct sockaddr_in *)sa, vip, port);
|
||||
}
|
||||
#endif /* INET */
|
||||
|
||||
@ -3018,7 +3022,8 @@ tcp6_next_pmtu(const struct icmp6_hdr *icmp6)
|
||||
}
|
||||
|
||||
static void
|
||||
tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
|
||||
tcp6_ctlinput_with_port(int cmd, struct sockaddr_in6 *sin6,
|
||||
struct ip6ctlparam *ip6cp, uint16_t port)
|
||||
{
|
||||
struct in6_addr *dst;
|
||||
struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
|
||||
@ -3027,7 +3032,6 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
|
||||
struct inpcb *inp;
|
||||
struct tcpcb *tp;
|
||||
struct icmp6_hdr *icmp6;
|
||||
struct ip6ctlparam *ip6cp = NULL;
|
||||
const struct sockaddr_in6 *sa6_src = NULL;
|
||||
struct in_conninfo inc;
|
||||
struct tcp_ports {
|
||||
@ -3038,13 +3042,8 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
|
||||
unsigned int mtu;
|
||||
unsigned int off;
|
||||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
ip6cp = (struct ip6ctlparam *)d;
|
||||
if (ip6cp != NULL) {
|
||||
icmp6 = ip6cp->ip6c_icmp6;
|
||||
m = ip6cp->ip6c_m;
|
||||
ip6 = ip6cp->ip6c_ip6;
|
||||
@ -3077,9 +3076,8 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
|
||||
return;
|
||||
|
||||
if (ip6 == NULL) {
|
||||
in6_pcbnotify(&V_tcbinfo, sa, 0,
|
||||
(const struct sockaddr *)sa6_src,
|
||||
0, cmd, NULL, notify);
|
||||
in6_pcbnotify(&V_tcbinfo, sin6, 0, sa6_src, 0, cmd, NULL,
|
||||
notify);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3168,13 +3166,13 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
|
||||
INP_WUNLOCK(inp);
|
||||
}
|
||||
|
||||
void
|
||||
tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||
static void
|
||||
tcp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
|
||||
{
|
||||
tcp6_ctlinput_with_port(cmd, sa, d, htons(0));
|
||||
tcp6_ctlinput_with_port(cmd, sin6, ctl, htons(0));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
tcp6_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *d, void *unused)
|
||||
{
|
||||
struct ip6ctlparam *ip6cp;
|
||||
@ -3197,7 +3195,7 @@ tcp6_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *d, void *unused)
|
||||
ip6cp->ip6c_m->m_pkthdr.len -= sizeof(struct udphdr);
|
||||
}
|
||||
/* Now call in to the normal handling code */
|
||||
tcp6_ctlinput_with_port(cmd, sa, d, port);
|
||||
tcp6_ctlinput_with_port(cmd, (struct sockaddr_in6 *)sa, ip6cp, port);
|
||||
}
|
||||
|
||||
#endif /* INET6 */
|
||||
|
@ -1084,9 +1084,7 @@ void tcp_discardcb(struct tcpcb *);
|
||||
bool tcp_freecb(struct tcpcb *);
|
||||
void tcp_twstart(struct tcpcb *);
|
||||
void tcp_twclose(struct tcptw *, int);
|
||||
void tcp_ctlinput(int, struct sockaddr *, void *);
|
||||
int tcp_ctloutput(struct socket *, struct sockopt *);
|
||||
void tcp_ctlinput_viaudp(int, struct sockaddr *, void *, void *);
|
||||
void tcp_fini(void *);
|
||||
char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, const void *,
|
||||
const void *);
|
||||
|
@ -740,21 +740,18 @@ udp_notify(struct inpcb *inp, int errno)
|
||||
|
||||
#ifdef INET
|
||||
static void
|
||||
udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
|
||||
udp_common_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip,
|
||||
struct inpcbinfo *pcbinfo)
|
||||
{
|
||||
struct ip *ip = vip;
|
||||
struct udphdr *uh;
|
||||
struct in_addr faddr;
|
||||
struct inpcb *inp;
|
||||
|
||||
faddr = ((struct sockaddr_in *)sa)->sin_addr;
|
||||
if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY)
|
||||
return;
|
||||
|
||||
if (PRC_IS_REDIRECT(cmd)) {
|
||||
/* signal EHOSTDOWN, as it flushes the cached route */
|
||||
in_pcbnotifyall(pcbinfo, faddr, EHOSTDOWN, udp_notify);
|
||||
in_pcbnotifyall(pcbinfo, sin->sin_addr, EHOSTDOWN, udp_notify);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -770,7 +767,7 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
|
||||
return;
|
||||
if (ip != NULL) {
|
||||
uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
|
||||
inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
|
||||
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);
|
||||
@ -779,7 +776,7 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
|
||||
}
|
||||
INP_WUNLOCK(inp);
|
||||
} else {
|
||||
inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
|
||||
inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
|
||||
ip->ip_src, uh->uh_sport,
|
||||
INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
|
||||
if (inp != NULL) {
|
||||
@ -792,26 +789,27 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
|
||||
func = up->u_icmp_func;
|
||||
INP_RUNLOCK(inp);
|
||||
if (func != NULL)
|
||||
(*func)(cmd, sa, vip, ctx);
|
||||
(*func)(cmd, (struct sockaddr *)sin,
|
||||
ip, ctx);
|
||||
}
|
||||
}
|
||||
} else
|
||||
in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd],
|
||||
in_pcbnotifyall(pcbinfo, sin->sin_addr, inetctlerrmap[cmd],
|
||||
udp_notify);
|
||||
}
|
||||
|
||||
static void
|
||||
udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
udp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
|
||||
{
|
||||
|
||||
return (udp_common_ctlinput(cmd, sa, vip, &V_udbinfo));
|
||||
return (udp_common_ctlinput(cmd, sin, ip, &V_udbinfo));
|
||||
}
|
||||
|
||||
static void
|
||||
udplite_ctlinput(int cmd, struct sockaddr *sa, void *vip)
|
||||
udplite_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
|
||||
{
|
||||
|
||||
return (udp_common_ctlinput(cmd, sa, vip, &V_ulitecbinfo));
|
||||
return (udp_common_ctlinput(cmd, sin, ip, &V_ulitecbinfo));
|
||||
}
|
||||
#endif /* INET */
|
||||
|
||||
|
@ -113,7 +113,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet6/nd6.h>
|
||||
#include <netinet6/send.h>
|
||||
|
||||
extern ipproto_ctlinput_t *ip6_ctlprotox[];
|
||||
extern ip6proto_ctlinput_t *ip6_ctlprotox[];
|
||||
|
||||
VNET_PCPUSTAT_DEFINE(struct icmp6stat, icmp6stat);
|
||||
VNET_PCPUSTAT_SYSINIT(icmp6stat);
|
||||
@ -1086,8 +1086,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
}
|
||||
|
||||
if (ip6_ctlprotox[nxt] != NULL)
|
||||
ip6_ctlprotox[nxt](code, (struct sockaddr *)&icmp6dst,
|
||||
&ip6cp);
|
||||
ip6_ctlprotox[nxt](code, &icmp6dst, &ip6cp);
|
||||
}
|
||||
*mp = m;
|
||||
return (0);
|
||||
|
@ -681,30 +681,29 @@ inp_match6(const struct inpcb *inp, void *v __unused)
|
||||
return ((inp->inp_vflag & INP_IPV6) != 0);
|
||||
}
|
||||
void
|
||||
in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
|
||||
u_int fport_arg, const struct sockaddr *src, u_int lport_arg,
|
||||
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,
|
||||
struct inpcb *(*notify)(struct inpcb *, int))
|
||||
{
|
||||
struct inpcb_iterator inpi = INP_ITERATOR(pcbinfo, INPLOOKUP_WLOCKPCB,
|
||||
inp_match6, NULL);
|
||||
struct inpcb *inp;
|
||||
struct sockaddr_in6 sa6_src, *sa6_dst;
|
||||
struct sockaddr_in6 sa6_src;
|
||||
u_short fport = fport_arg, lport = lport_arg;
|
||||
u_int32_t flowinfo;
|
||||
int errno;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS || dst->sa_family != AF_INET6)
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
|
||||
sa6_dst = (struct sockaddr_in6 *)dst;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr))
|
||||
return;
|
||||
|
||||
/*
|
||||
* note that src can be NULL when we get notify by local fragmentation.
|
||||
*/
|
||||
sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src;
|
||||
sa6_src = (src == NULL) ? sa6_any : *src;
|
||||
flowinfo = sa6_src.sin6_flowinfo;
|
||||
|
||||
/*
|
||||
@ -733,8 +732,7 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
|
||||
* XXX: should we avoid to notify the value to TCP sockets?
|
||||
*/
|
||||
if (cmd == PRC_MSGSIZE && cmdarg != NULL)
|
||||
ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst,
|
||||
*(u_int32_t *)cmdarg);
|
||||
ip6_notify_pmtu(inp, sa6_dst, *(uint32_t *)cmdarg);
|
||||
|
||||
/*
|
||||
* Detect if we should notify the error. If no source and
|
||||
|
@ -94,8 +94,8 @@ struct inpcb *
|
||||
in6_pcblookup_mbuf(struct inpcbinfo *, struct in6_addr *,
|
||||
u_int, struct in6_addr *, u_int, int,
|
||||
struct ifnet *ifp, struct mbuf *);
|
||||
void in6_pcbnotify(struct inpcbinfo *, struct sockaddr *,
|
||||
u_int, const struct sockaddr *, u_int, int, void *,
|
||||
void in6_pcbnotify(struct inpcbinfo *, struct sockaddr_in6 *, u_int,
|
||||
const struct sockaddr_in6 *, u_int, int, void *,
|
||||
struct inpcb *(*)(struct inpcb *, int));
|
||||
struct inpcb *
|
||||
in6_rtchange(struct inpcb *, int);
|
||||
|
@ -394,8 +394,6 @@ int frag6_input(struct mbuf **, int *, int);
|
||||
void frag6_drain(void);
|
||||
|
||||
void rip6_init(void);
|
||||
int rip6_input(struct mbuf **, int *, int);
|
||||
void rip6_ctlinput(int, struct sockaddr *, void *);
|
||||
int rip6_ctloutput(struct socket *, struct sockopt *);
|
||||
int rip6_usrreq(struct socket *,
|
||||
int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *);
|
||||
@ -444,7 +442,8 @@ struct ip6ctlparam {
|
||||
};
|
||||
|
||||
typedef int ip6proto_input_t(struct mbuf **, int *, int);
|
||||
typedef void ip6proto_ctlinput_t(int, struct sockaddr *, void *);
|
||||
typedef void ip6proto_ctlinput_t(int, struct sockaddr_in6 *,
|
||||
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 { \
|
||||
@ -452,6 +451,10 @@ int ip6proto_unregister(uint8_t);
|
||||
error = ip6proto_register(prot, input, ctl); \
|
||||
MPASS(error == 0); \
|
||||
} while (0)
|
||||
|
||||
ip6proto_input_t rip6_input;
|
||||
ip6proto_ctlinput_t rip6_ctlinput;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_NETINET6_IP6_VAR_H_ */
|
||||
|
@ -323,31 +323,25 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
|
||||
void
|
||||
rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||
rip6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ip6cp)
|
||||
{
|
||||
struct ip6ctlparam *ip6cp = NULL;
|
||||
const struct sockaddr_in6 *sa6_src = NULL;
|
||||
const struct sockaddr_in6 *sa6_src;
|
||||
void *cmdarg;
|
||||
struct inpcb *(*notify)(struct inpcb *, int) = in6_rtchange;
|
||||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
if (PRC_IS_REDIRECT(cmd))
|
||||
notify = in6_rtchange, d = NULL;
|
||||
notify = in6_rtchange, ip6cp = NULL;
|
||||
else if (cmd == PRC_HOSTDEAD)
|
||||
d = NULL;
|
||||
ip6cp = NULL;
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the parameter is from icmp6, decode it.
|
||||
*/
|
||||
if (d != NULL) {
|
||||
ip6cp = (struct ip6ctlparam *)d;
|
||||
if (ip6cp != NULL) {
|
||||
cmdarg = ip6cp->ip6c_cmdarg;
|
||||
sa6_src = ip6cp->ip6c_src;
|
||||
} else {
|
||||
@ -355,8 +349,7 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||
sa6_src = &sa6_any;
|
||||
}
|
||||
|
||||
(void) in6_pcbnotify(&V_ripcbinfo, sa, 0,
|
||||
(const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
|
||||
in6_pcbnotify(&V_ripcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg, notify);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -248,34 +248,22 @@ sctp6_notify(struct sctp_inpcb *inp,
|
||||
}
|
||||
|
||||
void
|
||||
sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
|
||||
sctp6_ctlinput(int cmd, struct sockaddr_in6 *pktdst, struct ip6ctlparam *ip6cp)
|
||||
{
|
||||
struct ip6ctlparam *ip6cp;
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
struct sctp_nets *net;
|
||||
struct sctphdr sh;
|
||||
struct sockaddr_in6 src, dst;
|
||||
|
||||
if (pktdst->sa_family != AF_INET6 ||
|
||||
pktdst->sa_len != sizeof(struct sockaddr_in6)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS) {
|
||||
return;
|
||||
}
|
||||
if (PRC_IS_REDIRECT(cmd)) {
|
||||
d = NULL;
|
||||
ip6cp = NULL;
|
||||
} else if (inet6ctlerrmap[cmd] == 0) {
|
||||
return;
|
||||
}
|
||||
/* If the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
ip6cp = (struct ip6ctlparam *)d;
|
||||
} else {
|
||||
ip6cp = (struct ip6ctlparam *)NULL;
|
||||
}
|
||||
|
||||
if (ip6cp != NULL) {
|
||||
/*
|
||||
|
@ -48,7 +48,7 @@ int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
|
||||
int
|
||||
sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
|
||||
struct mbuf *, struct proc *);
|
||||
void sctp6_ctlinput(int, struct sockaddr *, void *);
|
||||
ip6proto_ctlinput_t sctp6_ctlinput;
|
||||
void
|
||||
sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
|
||||
uint8_t, uint8_t, uint32_t);
|
||||
|
@ -72,14 +72,8 @@ VNET_DECLARE(int, tcp_v6mssdflt); /* XXX */
|
||||
#define V_tcp_v6mssdflt VNET(tcp_v6mssdflt)
|
||||
#endif
|
||||
|
||||
struct ip6_hdr;
|
||||
void tcp6_ctlinput(int, struct sockaddr *, void *);
|
||||
void tcp6_ctlinput_viaudp(int, struct sockaddr *, void *, void *);
|
||||
int tcp6_input(struct mbuf **, int *, int);
|
||||
int tcp6_input_with_port(struct mbuf **, int *, int, uint16_t);
|
||||
|
||||
extern struct pr_usrreqs tcp6_usrreqs;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET_TCP6_VAR_H_ */
|
||||
|
@ -547,14 +547,13 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
|
||||
static void
|
||||
udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
|
||||
struct inpcbinfo *pcbinfo)
|
||||
udp6_common_ctlinput(int cmd, struct sockaddr_in6 *sin6,
|
||||
struct ip6ctlparam *ip6cp, struct inpcbinfo *pcbinfo)
|
||||
{
|
||||
struct udphdr uh;
|
||||
struct ip6_hdr *ip6;
|
||||
struct mbuf *m;
|
||||
int off = 0;
|
||||
struct ip6ctlparam *ip6cp = NULL;
|
||||
const struct sockaddr_in6 *sa6_src = NULL;
|
||||
void *cmdarg;
|
||||
struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
|
||||
@ -563,22 +562,17 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
|
||||
u_int16_t uh_dport;
|
||||
} *uhp;
|
||||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
if (PRC_IS_REDIRECT(cmd))
|
||||
notify = in6_rtchange, d = NULL;
|
||||
notify = in6_rtchange, ip6cp = NULL;
|
||||
else if (cmd == PRC_HOSTDEAD)
|
||||
d = NULL;
|
||||
ip6cp = NULL;
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
ip6cp = (struct ip6ctlparam *)d;
|
||||
if (ip6cp != NULL) {
|
||||
m = ip6cp->ip6c_m;
|
||||
ip6 = ip6cp->ip6c_ip6;
|
||||
off = ip6cp->ip6c_off;
|
||||
@ -619,7 +613,7 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
|
||||
/* Yes it is. */
|
||||
INP_RUNLOCK(inp);
|
||||
(*up->u_icmp_func)(cmd, (struct sockaddr *)ip6cp->ip6c_src,
|
||||
d, up->u_tun_ctx);
|
||||
ip6cp, up->u_tun_ctx);
|
||||
return;
|
||||
} else {
|
||||
/* Can't find it. */
|
||||
@ -627,26 +621,25 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport,
|
||||
(struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd,
|
||||
cmdarg, notify);
|
||||
in6_pcbnotify(pcbinfo, sin6, uh.uh_dport, ip6cp->ip6c_src,
|
||||
uh.uh_sport, cmd, cmdarg, notify);
|
||||
} else
|
||||
(void)in6_pcbnotify(pcbinfo, sa, 0,
|
||||
(const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
|
||||
in6_pcbnotify(pcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg,
|
||||
notify);
|
||||
}
|
||||
|
||||
void
|
||||
udp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||
static void
|
||||
udp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
|
||||
{
|
||||
|
||||
return (udp6_common_ctlinput(cmd, sa, d, &V_udbinfo));
|
||||
return (udp6_common_ctlinput(cmd, sin6, ctl, &V_udbinfo));
|
||||
}
|
||||
|
||||
void
|
||||
udplite6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||
static void
|
||||
udplite6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
|
||||
{
|
||||
|
||||
return (udp6_common_ctlinput(cmd, sa, d, &V_ulitecbinfo));
|
||||
return (udp6_common_ctlinput(cmd, sin6, ctl, &V_ulitecbinfo));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -68,10 +68,6 @@
|
||||
#ifdef _KERNEL
|
||||
SYSCTL_DECL(_net_inet6_udp6);
|
||||
|
||||
extern struct pr_usrreqs udp6_usrreqs;
|
||||
|
||||
void udp6_ctlinput(int, struct sockaddr *, void *);
|
||||
void udplite6_ctlinput(int, struct sockaddr *, void *);
|
||||
int udp6_input(struct mbuf **, int *, int);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user