summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/raw_ip6.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet6/raw_ip6.c')
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c66
1 files changed, 19 insertions, 47 deletions
diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c
index e2d6693a..dfd7c45b 100644
--- a/freebsd/sys/netinet6/raw_ip6.c
+++ b/freebsd/sys/netinet6/raw_ip6.c
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/errno.h>
#include <sys/jail.h>
+#include <sys/kernel.h>
#include <rtems/bsd/sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -83,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <net/if.h>
+#include <net/if_var.h>
#include <net/if_types.h>
#include <net/route.h>
#include <net/vnet.h>
@@ -126,7 +128,12 @@ VNET_DECLARE(struct inpcbinfo, ripcbinfo);
extern u_long rip_sendspace;
extern u_long rip_recvspace;
-VNET_DEFINE(struct rip6stat, rip6stat);
+VNET_PCPUSTAT_DEFINE(struct rip6stat, rip6stat);
+VNET_PCPUSTAT_SYSINIT(rip6stat);
+
+#ifdef VIMAGE
+VNET_PCPUSTAT_SYSUNINIT(rip6stat);
+#endif /* VIMAGE */
/*
* Hooks for multicast routing. They all default to NULL, so leave them not
@@ -158,18 +165,12 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
struct mbuf *m = *mp;
register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
register struct inpcb *in6p;
- struct inpcb *last = 0;
+ struct inpcb *last = NULL;
struct mbuf *opts = NULL;
struct sockaddr_in6 fromsa;
RIP6STAT_INC(rip6s_ipackets);
- if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
- /* XXX Send icmp6 host/port unreach? */
- m_freem(m);
- return (IPPROTO_DONE);
- }
-
init_sin6(&fromsa, m); /* general init */
ifp = m->m_pkthdr.rcvif;
@@ -265,7 +266,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
*/
if (n && ipsec6_in_reject(n, last)) {
m_freem(n);
- IPSEC6STAT_INC(in_polvio);
/* Do not inject data into pcb. */
} else
#endif /* IPSEC */
@@ -297,7 +297,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
*/
if ((last != NULL) && ipsec6_in_reject(m, last)) {
m_freem(m);
- IPSEC6STAT_INC(in_polvio);
IP6STAT_DEC(ip6s_delivered);
/* Do not inject data into pcb. */
INP_RUNLOCK(last);
@@ -385,17 +384,10 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
* may have setup with control call.
*/
int
-#if __STDC__
-rip6_output(struct mbuf *m, ...)
-#else
-rip6_output(m, va_alist)
- struct mbuf *m;
- va_dcl
-#endif
+rip6_output(struct mbuf *m, struct socket *so, ...)
{
struct mbuf *control;
struct m_tag *mtag;
- struct socket *so;
struct sockaddr_in6 *dstsock;
struct in6_addr *dst;
struct ip6_hdr *ip6;
@@ -407,11 +399,11 @@ rip6_output(m, va_alist)
int type = 0, code = 0; /* for ICMPv6 output statistics only */
int scope_ambiguous = 0;
int use_defzone = 0;
+ int hlim = 0;
struct in6_addr in6a;
va_list ap;
- va_start(ap, m);
- so = va_arg(ap, struct socket *);
+ va_start(ap, so);
dstsock = va_arg(ap, struct sockaddr_in6 *);
control = va_arg(ap, struct mbuf *);
va_end(ap);
@@ -461,7 +453,7 @@ rip6_output(m, va_alist)
code = icmp6->icmp6_code;
}
- M_PREPEND(m, sizeof(*ip6), M_DONTWAIT);
+ M_PREPEND(m, sizeof(*ip6), M_NOWAIT);
if (m == NULL) {
error = ENOBUFS;
goto bad;
@@ -471,8 +463,9 @@ rip6_output(m, va_alist)
/*
* Source address selection.
*/
- error = in6_selectsrc(dstsock, optp, in6p, NULL, so->so_cred,
- &oifp, &in6a);
+ error = in6_selectsrc_socket(dstsock, optp, in6p, so->so_cred,
+ scope_ambiguous, &in6a, &hlim);
+
if (error)
goto bad;
error = prison_check_ip6(in6p->inp_cred, &in6a);
@@ -480,19 +473,6 @@ rip6_output(m, va_alist)
goto bad;
ip6->ip6_src = in6a;
- if (oifp && scope_ambiguous) {
- /*
- * Application should provide a proper zone ID or the use of
- * default zone IDs should be enabled. Unfortunately, some
- * applications do not behave as it should, so we need a
- * workaround. Even if an appropriate ID is not determined
- * (when it's required), if we can determine the outgoing
- * interface. determine the zone ID based on the interface.
- */
- error = in6_setscope(&dstsock->sin6_addr, oifp, NULL);
- if (error != 0)
- goto bad;
- }
ip6->ip6_dst = dstsock->sin6_addr;
/*
@@ -507,7 +487,7 @@ rip6_output(m, va_alist)
* ip6_plen will be filled in ip6_output, so not fill it here.
*/
ip6->ip6_nxt = in6p->inp_ip_p;
- ip6->ip6_hlim = in6_selecthlim(in6p, oifp);
+ ip6->ip6_hlim = hlim;
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 ||
in6p->in6p_cksum != -1) {
@@ -795,7 +775,6 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
struct inpcb *inp;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
struct in6_addr in6a;
- struct ifnet *ifp = NULL;
int error = 0, scope_ambiguous = 0;
inp = sotoinpcb(so);
@@ -824,21 +803,14 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
/* Source address selection. XXX: need pcblookup? */
- error = in6_selectsrc(addr, inp->in6p_outputopts,
- inp, NULL, so->so_cred, &ifp, &in6a);
+ error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
+ inp, so->so_cred, scope_ambiguous, &in6a, NULL);
if (error) {
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_ripcbinfo);
return (error);
}
- /* XXX: see above */
- if (ifp && scope_ambiguous &&
- (error = in6_setscope(&addr->sin6_addr, ifp, NULL)) != 0) {
- INP_WUNLOCK(inp);
- INP_INFO_WUNLOCK(&V_ripcbinfo);
- return (error);
- }
inp->in6p_faddr = addr->sin6_addr;
inp->in6p_laddr = in6a;
soisconnected(so);