summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ip6_mroute.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
committerume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
commit832f8d224926758a9ae0b23a6b45353e44fbc87a (patch)
treea79fc7ad2b97862c4a404f352f0211ad93a7b5f1 /sys/netinet6/ip6_mroute.c
parent2693854b01a52b0395a91322aa3edf926bddff38 (diff)
downloadFreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.zip
FreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.tar.gz
Sync with recent KAME.
This work was based on kame-20010528-freebsd43-snap.tgz and some critical problem after the snap was out were fixed. There are many many changes since last KAME merge. TODO: - The definitions of SADB_* in sys/net/pfkeyv2.h are still different from RFC2407/IANA assignment because of binary compatibility issue. It should be fixed under 5-CURRENT. - ip6po_m member of struct ip6_pktopts is no longer used. But, it is still there because of binary compatibility issue. It should be removed under 5-CURRENT. Reviewed by: itojun Obtained from: KAME MFC after: 3 weeks
Diffstat (limited to 'sys/netinet6/ip6_mroute.c')
-rw-r--r--sys/netinet6/ip6_mroute.c246
1 files changed, 132 insertions, 114 deletions
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index 82b0d4b..2be8796 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: ip6_mroute.c,v 1.33 2000/10/19 02:23:43 jinmei Exp $ */
+/* $KAME: ip6_mroute.c,v 1.46 2001/04/04 05:17:30 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@@ -50,6 +50,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -143,7 +144,6 @@ static mifi_t nummifs = 0;
static mifi_t reg_mif_num = (mifi_t)-1;
static struct pim6stat pim6stat;
-static struct callout_handle expire_upcalls_ch;
/*
* one-back cache used by ipip_input to locate a tunnel's mif
@@ -165,7 +165,7 @@ static int pim6;
*/
#define MF6CFIND(o, g, rt) do { \
- register struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \
+ struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \
rt = NULL; \
mrt6stat.mrt6s_mfc_lookups++; \
while (_rt) { \
@@ -187,7 +187,7 @@ static int pim6;
* Borrowed from Van Jacobson's scheduling code
*/
#define TV_DELTA(a, b, delta) do { \
- register int xxs; \
+ int xxs; \
\
delta = (a).tv_usec - (b).tv_usec; \
if ((xxs = (a).tv_sec - (b).tv_sec)) { \
@@ -221,6 +221,8 @@ static int del_m6if __P((mifi_t *));
static int add_m6fc __P((struct mf6cctl *));
static int del_m6fc __P((struct mf6cctl *));
+static struct callout expire_upcalls_ch;
+
/*
* Handle MRT setsockopt commands to modify the multicast routing tables.
*/
@@ -241,33 +243,33 @@ ip6_mrouter_set(so, sopt)
return (error);
switch (sopt->sopt_name) {
- case MRT6_INIT:
+ case MRT6_INIT:
#ifdef MRT6_OINIT
- case MRT6_OINIT:
+ case MRT6_OINIT:
#endif
- error = ip6_mrouter_init(so, m, sopt->sopt_name);
- break;
- case MRT6_DONE:
- error = ip6_mrouter_done();
- break;
- case MRT6_ADD_MIF:
- error = add_m6if(mtod(m, struct mif6ctl *));
- break;
- case MRT6_DEL_MIF:
- error = del_m6if(mtod(m, mifi_t *));
- break;
- case MRT6_ADD_MFC:
- error = add_m6fc(mtod(m, struct mf6cctl *));
- break;
- case MRT6_DEL_MFC:
- error = del_m6fc(mtod(m, struct mf6cctl *));
- break;
- case MRT6_PIM:
- error = set_pim6(mtod(m, int *));
- break;
- default:
- error = EOPNOTSUPP;
- break;
+ error = ip6_mrouter_init(so, m, sopt->sopt_name);
+ break;
+ case MRT6_DONE:
+ error = ip6_mrouter_done();
+ break;
+ case MRT6_ADD_MIF:
+ error = add_m6if(mtod(m, struct mif6ctl *));
+ break;
+ case MRT6_DEL_MIF:
+ error = del_m6if(mtod(m, mifi_t *));
+ break;
+ case MRT6_ADD_MFC:
+ error = add_m6fc(mtod(m, struct mf6cctl *));
+ break;
+ case MRT6_DEL_MFC:
+ error = del_m6fc(mtod(m, struct mf6cctl *));
+ break;
+ case MRT6_PIM:
+ error = set_pim6(mtod(m, int *));
+ break;
+ default:
+ error = EOPNOTSUPP;
+ break;
}
(void)m_freem(m);
@@ -302,20 +304,20 @@ mrt6_ioctl(cmd, data)
int cmd;
caddr_t data;
{
- int error = 0;
-
- switch (cmd) {
- case SIOCGETSGCNT_IN6:
- return(get_sg_cnt((struct sioc_sg_req6 *)data));
- break; /* for safety */
- case SIOCGETMIFCNT_IN6:
- return(get_mif6_cnt((struct sioc_mif_req6 *)data));
- break; /* for safety */
- default:
- return (EINVAL);
- break;
- }
- return error;
+ int error = 0;
+
+ switch (cmd) {
+ case SIOCGETSGCNT_IN6:
+ return(get_sg_cnt((struct sioc_sg_req6 *)data));
+ break; /* for safety */
+ case SIOCGETMIFCNT_IN6:
+ return(get_mif6_cnt((struct sioc_mif_req6 *)data));
+ break; /* for safety */
+ default:
+ return (EINVAL);
+ break;
+ }
+ return error;
}
/*
@@ -323,9 +325,9 @@ mrt6_ioctl(cmd, data)
*/
static int
get_sg_cnt(req)
- register struct sioc_sg_req6 *req;
+ struct sioc_sg_req6 *req;
{
- register struct mf6c *rt;
+ struct mf6c *rt;
int s;
s = splnet();
@@ -349,9 +351,9 @@ get_sg_cnt(req)
*/
static int
get_mif6_cnt(req)
- register struct sioc_mif_req6 *req;
+ struct sioc_mif_req6 *req;
{
- register mifi_t mifi = req->mifi;
+ mifi_t mifi = req->mifi;
if (mifi >= nummifs)
return EINVAL;
@@ -415,8 +417,8 @@ ip6_mrouter_init(so, m, cmd)
pim6 = 0;/* used for stubbing out/in pim stuff */
- expire_upcalls_ch =
- timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+ callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
+ expire_upcalls, NULL);
#ifdef MRT6DEBUG
if (mrt6debug)
@@ -478,7 +480,7 @@ ip6_mrouter_done()
pim6 = 0; /* used to stub out/in pim specific code */
- untimeout(expire_upcalls, (caddr_t)NULL, expire_upcalls_ch);
+ callout_stop(&expire_upcalls_ch);
/*
* Free all multicast forwarding cache entries.
@@ -528,9 +530,9 @@ static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 };
*/
static int
add_m6if(mifcp)
- register struct mif6ctl *mifcp;
+ struct mif6ctl *mifcp;
{
- register struct mif6 *mifp;
+ struct mif6 *mifp;
struct ifnet *ifp;
int error, s;
#ifdef notyet
@@ -605,8 +607,8 @@ static int
del_m6if(mifip)
mifi_t *mifip;
{
- register struct mif6 *mifp = mif6table + *mifip;
- register mifi_t mifi;
+ struct mif6 *mifp = mif6table + *mifip;
+ mifi_t mifi;
struct ifnet *ifp;
int s;
@@ -659,7 +661,7 @@ add_m6fc(mfccp)
struct mf6c *rt;
u_long hash;
struct rtdetq *rte;
- register u_short nstl;
+ u_short nstl;
int s;
MF6CFIND(mfccp->mf6cc_origin.sin6_addr,
@@ -809,11 +811,11 @@ add_m6fc(mfccp)
*/
static void
collate(t)
- register struct timeval *t;
+ struct timeval *t;
{
- register u_long d;
- register struct timeval tp;
- register u_long delta;
+ u_long d;
+ struct timeval tp;
+ u_long delta;
GET_TIME(tp);
@@ -912,13 +914,13 @@ socket_send(s, mm, src)
int
ip6_mforward(ip6, ifp, m)
- register struct ip6_hdr *ip6;
+ struct ip6_hdr *ip6;
struct ifnet *ifp;
struct mbuf *m;
{
- register struct mf6c *rt;
- register struct mif6 *mifp;
- register struct mbuf *mm;
+ struct mf6c *rt;
+ struct mif6 *mifp;
+ struct mbuf *mm;
int s;
mifi_t mifi;
@@ -977,10 +979,10 @@ ip6_mforward(ip6, ifp, m)
* send message to routing daemon
*/
- register struct mbuf *mb0;
- register struct rtdetq *rte;
- register u_long hash;
-/* register int i, npkts;*/
+ struct mbuf *mb0;
+ struct rtdetq *rte;
+ u_long hash;
+/* int i, npkts;*/
#ifdef UPCALL_TIMING
struct timeval tp;
@@ -1144,7 +1146,7 @@ ip6_mforward(ip6, ifp, m)
} else {
/* determine if q has overflowed */
struct rtdetq **p;
- register int npkts = 0;
+ int npkts = 0;
for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next)
if (++npkts > MAX_UPQ6) {
@@ -1227,8 +1229,8 @@ expire_upcalls(unused)
}
}
splx(s);
- expire_upcalls_ch =
- timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+ callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
+ expire_upcalls, NULL);
}
/*
@@ -1236,14 +1238,14 @@ expire_upcalls(unused)
*/
static int
ip6_mdq(m, ifp, rt)
- register struct mbuf *m;
- register struct ifnet *ifp;
- register struct mf6c *rt;
+ struct mbuf *m;
+ struct ifnet *ifp;
+ struct mf6c *rt;
{
- register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- register mifi_t mifi, iif;
- register struct mif6 *mifp;
- register int plen = m->m_pkthdr.len;
+ struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ mifi_t mifi, iif;
+ struct mif6 *mifp;
+ int plen = m->m_pkthdr.len;
/*
* Macro to send packet on mif. Since RSVP packets don't get counted on
@@ -1290,7 +1292,7 @@ ip6_mdq(m, ifp, rt)
static struct sockaddr_in6 sin6 =
{ sizeof(sin6), AF_INET6 };
- register struct mbuf *mm;
+ struct mbuf *mm;
struct mrt6msg *im;
#ifdef MRT6_OINIT
struct omrt6msg *oim;
@@ -1319,6 +1321,7 @@ ip6_mdq(m, ifp, rt)
case MRT6_INIT:
im = mtod(mm, struct mrt6msg *);
im->im6_msgtype = MRT6MSG_WRONGMIF;
+ im->im6_mbz = 0;
break;
default:
m_freem(mm);
@@ -1408,12 +1411,13 @@ phyint_send(ip6, mifp, m)
struct mif6 *mifp;
struct mbuf *m;
{
- register struct mbuf *mb_copy;
+ struct mbuf *mb_copy;
struct ifnet *ifp = mifp->m6_ifp;
int error = 0;
- int s = splnet();
- static struct route_in6 ro6;
+ int s = splnet(); /* needs to protect static "ro" below. */
+ static struct route_in6 ro;
struct in6_multi *in6m;
+ struct sockaddr_in6 *dst6;
/*
* Make a new reference to the packet; make sure that
@@ -1424,8 +1428,10 @@ phyint_send(ip6, mifp, m)
if (mb_copy &&
(M_HASCL(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr)))
mb_copy = m_pullup(mb_copy, sizeof(struct ip6_hdr));
- if (mb_copy == NULL)
+ if (mb_copy == NULL) {
+ splx(s);
return;
+ }
/* set MCAST flag to the outgoing packet */
mb_copy->m_flags |= M_MCAST;
@@ -1443,7 +1449,7 @@ phyint_send(ip6, mifp, m)
/* XXX: ip6_output will override ip6->ip6_hlim */
im6o.im6o_multicast_hlim = ip6->ip6_hlim;
im6o.im6o_multicast_loop = 1;
- error = ip6_output(mb_copy, NULL, &ro6,
+ error = ip6_output(mb_copy, NULL, &ro,
IPV6_FORWARDING, &im6o, NULL);
#ifdef MRT6DEBUG
@@ -1459,63 +1465,62 @@ phyint_send(ip6, mifp, m)
* If we belong to the destination multicast group
* on the outgoing interface, loop back a copy.
*/
+ dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
if (in6m != NULL) {
- ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
- ro6.ro_dst.sin6_family = AF_INET6;
- ro6.ro_dst.sin6_addr = ip6->ip6_dst;
- ip6_mloopback(ifp, m, &ro6.ro_dst);
+ dst6->sin6_len = sizeof(struct sockaddr_in6);
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_addr = ip6->ip6_dst;
+ ip6_mloopback(ifp, m, (struct sockaddr_in6 *)&ro.ro_dst);
}
/*
* Put the packet into the sending queue of the outgoing interface
* if it would fit in the MTU of the interface.
*/
if (mb_copy->m_pkthdr.len < ifp->if_mtu || ifp->if_mtu < IPV6_MMTU) {
- ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
- ro6.ro_dst.sin6_family = AF_INET6;
- ro6.ro_dst.sin6_addr = ip6->ip6_dst;
+ dst6->sin6_len = sizeof(struct sockaddr_in6);
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_addr = ip6->ip6_dst;
/*
* We just call if_output instead of nd6_output here, since
* we need no ND for a multicast forwarded packet...right?
*/
error = (*ifp->if_output)(ifp, mb_copy,
- (struct sockaddr *)&ro6.ro_dst,
- NULL);
+ (struct sockaddr *)&ro.ro_dst, NULL);
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
log(LOG_DEBUG, "phyint_send on mif %d err %d\n",
mifp - mif6table, error);
#endif
- }
- else {
+ } else {
#ifdef MULTICAST_PMTUD
icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
- return;
#else
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
log(LOG_DEBUG,
- "phyint_send: packet too big on %s%u o %s g %s"
+ "phyint_send: packet too big on %s o %s g %s"
" size %d(discarded)\n",
- ifp->if_name, ifp->if_unit,
+ if_name(ifp),
ip6_sprintf(&ip6->ip6_src),
ip6_sprintf(&ip6->ip6_dst),
mb_copy->m_pkthdr.len);
#endif /* MRT6DEBUG */
m_freem(mb_copy); /* simply discard the packet */
- return;
#endif
}
+
+ splx(s);
}
static int
register_send(ip6, mif, m)
- register struct ip6_hdr *ip6;
+ struct ip6_hdr *ip6;
struct mif6 *mif;
- register struct mbuf *m;
+ struct mbuf *m;
{
- register struct mbuf *mm;
- register int i, len = m->m_pkthdr.len;
+ struct mbuf *mm;
+ int i, len = m->m_pkthdr.len;
static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 };
struct mrt6msg *im6;
@@ -1530,6 +1535,7 @@ register_send(ip6, mif, m)
MGETHDR(mm, M_DONTWAIT, MT_HEADER);
if (mm == NULL)
return ENOBUFS;
+ mm->m_pkthdr.rcvif = NULL;
mm->m_data += max_linkhdr;
mm->m_len = sizeof(struct ip6_hdr);
@@ -1568,8 +1574,8 @@ register_send(ip6, mif, m)
log(LOG_WARNING,
"register_send: ip_mrouter socket queue full\n");
#endif
- ++mrt6stat.mrt6s_upq_sockfull;
- return ENOBUFS;
+ ++mrt6stat.mrt6s_upq_sockfull;
+ return ENOBUFS;
}
return 0;
}
@@ -1586,21 +1592,21 @@ pim6_input(mp, offp, proto)
struct mbuf **mp;
int *offp, proto;
{
- register struct pim *pim; /* pointer to a pim struct */
- register struct ip6_hdr *ip6;
- register int pimlen;
+ struct pim *pim; /* pointer to a pim struct */
+ struct ip6_hdr *ip6;
+ int pimlen;
struct mbuf *m = *mp;
- int minlen;
+ int minlen;
int off = *offp;
++pim6stat.pim6s_rcv_total;
- ip6 = mtod(m, struct ip6_hdr *);
- pimlen = m->m_pkthdr.len - *offp;
+ ip6 = mtod(m, struct ip6_hdr *);
+ pimlen = m->m_pkthdr.len - *offp;
- /*
- * Validate lengths
- */
+ /*
+ * Validate lengths
+ */
if (pimlen < PIM_MINLEN) {
++pim6stat.pim6s_rcv_tooshort;
#ifdef MRT6DEBUG
@@ -1736,6 +1742,18 @@ pim6_input(mp, offp, proto)
ip6_sprintf(&eip6->ip6_dst),
ntohs(eip6->ip6_plen));
#endif
+
+ /* verify the version number of the inner packet */
+ if ((eip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
+ ++pim6stat.pim6s_rcv_badregisters;
+#ifdef MRT6DEBUG
+ log(LOG_DEBUG, "pim6_input: invalid IP version (%d) "
+ "of the inner packet\n",
+ (eip6->ip6_vfc & IPV6_VERSION));
+#endif
+ m_freem(m);
+ return(IPPROTO_NONE);
+ }
/* verify the inner packet is destined to a mcast group */
if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) {
@@ -1781,7 +1799,7 @@ pim6_input(mp, offp, proto)
#endif
rc = if_simloop(mif6table[reg_mif_num].m6_ifp, m,
- dst.sin6_family, NULL);
+ dst.sin6_family, NULL);
/* prepare the register head to send to the mrouting daemon */
m = mcp;
OpenPOWER on IntegriCloud