diff options
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 277 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.h | 48 |
2 files changed, 220 insertions, 105 deletions
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 3053c266a6d..6cd7bc1015e 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1,9 +1,10 @@ -/* $OpenBSD: ip6_mroute.c,v 1.3 2000/02/07 06:09:10 itojun Exp $ */ +/* $OpenBSD: ip6_mroute.c,v 1.4 2000/05/19 13:11:34 itojun Exp $ */ +/* $KAME: ip6_mroute.c,v 1.24 2000/05/19 07:37:05 jinmei Exp $ */ /* * Copyright (C) 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +16,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -93,6 +94,7 @@ static int register_send __P((struct ip6_hdr *, struct mif6 *, * except for netstat or debugging purposes. */ struct socket *ip6_mrouter = NULL; +int ip6_mrouter_ver = 0; int ip6_mrtproto = IPPROTO_PIM; /* for netstat only */ struct mrt6stat mrt6stat; @@ -120,7 +122,7 @@ static void expire_upcalls __P((void *)); #ifdef MROUTING extern struct socket *ip_mrouter; #endif -#endif +#endif /* * 'Interfaces' associated with decapsulator (so we can tell @@ -161,7 +163,7 @@ static int pim6; * Quality of service parameter to be added in the future!!! */ -#define MF6CFIND(o, g, rt) { \ +#define MF6CFIND(o, g, rt) do { \ register struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \ rt = NULL; \ mrt6stat.mrt6s_mfc_lookups++; \ @@ -177,13 +179,13 @@ static int pim6; if (rt == NULL) { \ mrt6stat.mrt6s_mfc_misses++; \ } \ -} +} while (0) /* * Macros to compute elapsed time efficiently * Borrowed from Van Jacobson's scheduling code */ -#define TV_DELTA(a, b, delta) { \ +#define TV_DELTA(a, b, delta) do { \ register int xxs; \ \ delta = (a).tv_usec - (b).tv_usec; \ @@ -199,7 +201,7 @@ static int pim6; delta += (1000000 * xxs); \ } \ } \ -} +} while (0) #define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \ (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec) @@ -212,7 +214,7 @@ static void collate(); static int get_sg_cnt __P((struct sioc_sg_req6 *)); static int get_mif6_cnt __P((struct sioc_mif_req6 *)); -static int ip6_mrouter_init __P((struct socket *, struct mbuf *)); +static int ip6_mrouter_init __P((struct socket *, struct mbuf *, int)); static int add_m6if __P((struct mif6ctl *)); static int del_m6if __P((mifi_t *)); static int add_m6fc __P((struct mf6cctl *)); @@ -231,7 +233,10 @@ ip6_mrouter_set(cmd, so, m) return EACCES; switch (cmd) { - case MRT6_INIT: return ip6_mrouter_init(so, m); +#ifdef MRT6_OINIT + case MRT6_OINIT: return ip6_mrouter_init(so, m, cmd); +#endif + case MRT6_INIT: return ip6_mrouter_init(so, m, cmd); case MRT6_DONE: return ip6_mrouter_done(); case MRT6_ADD_MIF: return add_m6if(mtod(m, struct mif6ctl *)); case MRT6_DEL_MIF: return del_m6if(mtod(m, mifi_t *)); @@ -311,7 +316,7 @@ get_sg_cnt(req) return(ESRCH); #if 0 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; -#endif +#endif return 0; } @@ -368,9 +373,10 @@ set_pim6(i) * Enable multicast routing */ static int -ip6_mrouter_init(so, m) +ip6_mrouter_init(so, m, cmd) struct socket *so; struct mbuf *m; + int cmd; { int *v; @@ -395,6 +401,7 @@ ip6_mrouter_init(so, m) if (ip6_mrouter != NULL) return EADDRINUSE; ip6_mrouter = so; + ip6_mrouter_ver = cmd; bzero((caddr_t)mf6ctable, sizeof(mf6ctable)); bzero((caddr_t)nexpire, sizeof(nexpire)); @@ -441,7 +448,7 @@ ip6_mrouter_done() */ if (!ip_mrouter) #endif -#endif +#endif { for (mifi = 0; mifi < nummifs; mifi++) { if (mif6table[mifi].m6_ifp && @@ -457,7 +464,7 @@ ip6_mrouter_done() #ifdef notyet bzero((caddr_t)qtable, sizeof(qtable)); bzero((caddr_t)tbftable, sizeof(tbftable)); -#endif +#endif bzero((caddr_t)mif6table, sizeof(mif6table)); nummifs = 0; @@ -492,8 +499,9 @@ ip6_mrouter_done() * Reset de-encapsulation cache */ reg_mif_num = -1; - + ip6_mrouter = NULL; + ip6_mrouter_ver = 0; splx(s); @@ -520,7 +528,7 @@ add_m6if(mifcp) int error, s; #ifdef notyet struct tbf *m_tbf = tbftable + mifcp->mif6c_mifi; -#endif +#endif if (mifcp->mif6c_mifi >= MAXMIFS) return EINVAL; @@ -570,7 +578,7 @@ add_m6if(mifcp) #ifdef notyet /* scaling up here allows division by 1024 in critical code */ mifp->m6_rate_limit = mifcp->mif6c_rate_limit * 1024 / 1000; -#endif +#endif /* initialize per mif pkt counters */ mifp->m6_pkt_in = 0; mifp->m6_pkt_out = 0; @@ -628,7 +636,7 @@ del_m6if(mifip) #ifdef notyet bzero((caddr_t)qtable[*mifip], sizeof(qtable[*mifip])); bzero((caddr_t)mifp->m6_tbf, sizeof(*(mifp->m6_tbf))); -#endif +#endif bzero((caddr_t)mifp, sizeof (*mifp)); /* Adjust nummifs down */ @@ -681,7 +689,7 @@ add_m6fc(mfccp) return 0; } - /* + /* * Find the entry for which the upcall was made and update */ s = splnet(); @@ -753,7 +761,7 @@ add_m6fc(mfccp) #endif for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { - + if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr, &mfccp->mf6cc_origin.sin6_addr)&& IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr, @@ -780,7 +788,7 @@ add_m6fc(mfccp) splx(s); return ENOBUFS; } - + /* insert new entry at head of hash chain */ rt->mf6c_origin = mfccp->mf6cc_origin; rt->mf6c_mcastgrp = mfccp->mf6cc_mcastgrp; @@ -791,7 +799,7 @@ add_m6fc(mfccp) rt->mf6c_wrong_if = 0; rt->mf6c_expire = 0; rt->mf6c_stall = NULL; - + /* link into table */ rt->mf6c_next = mf6ctable[hash]; mf6ctable[hash] = rt; @@ -803,7 +811,7 @@ add_m6fc(mfccp) #ifdef UPCALL_TIMING /* - * collect delay statistics on the upcalls + * collect delay statistics on the upcalls */ static void collate(t) @@ -812,9 +820,9 @@ collate(t) register u_long d; register struct timeval tp; register u_long delta; - + GET_TIME(tp); - + if (TV_LT(*t, tp)) { TV_DELTA(tp, *t, delta); @@ -995,7 +1003,7 @@ ip6_mforward(ip6, ifp, m) splx(s); return ENOBUFS; } - + /* is there an upcall waiting for this packet? */ hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst); for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { @@ -1009,6 +1017,9 @@ ip6_mforward(ip6, ifp, m) if (rt == NULL) { struct mrt6msg *im; +#ifdef MRT6_OINIT + struct omrt6msg *oim; +#endif /* no upcall, so make a new entry */ rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE, @@ -1033,14 +1044,35 @@ ip6_mforward(ip6, ifp, m) return ENOBUFS; } - /* + /* * Send message to routing daemon */ sin6.sin6_addr = ip6->ip6_src; - - im = mtod(mm, struct mrt6msg *); - im->im6_msgtype = MRT6MSG_NOCACHE; - im->im6_mbz = 0; + + im = NULL; +#ifdef MRT6_OINIT + oim = NULL; +#endif + switch (ip6_mrouter_ver) { +#ifdef MRT6_OINIT + case MRT6_OINIT: + oim = mtod(mm, struct omrt6msg *); + oim->im6_msgtype = MRT6MSG_NOCACHE; + oim->im6_mbz = 0; + break; +#endif + case MRT6_INIT: + im = mtod(mm, struct mrt6msg *); + im->im6_msgtype = MRT6MSG_NOCACHE; + im->im6_mbz = 0; + break; + default: + free(rte, M_MRTABLE); + m_freem(mb0); + free(rt, M_MRTABLE); + splx(s); + return EINVAL; + } #ifdef MRT6DEBUG if (mrt6debug & DEBUG_FORWARD) @@ -1053,7 +1085,16 @@ ip6_mforward(ip6, ifp, m) mifp++, mifi++) ; - im->im6_mif = mifi; + switch (ip6_mrouter_ver) { +#ifdef MRT6_OINIT + case MRT6_OINIT: + oim->im6_mif = mifi; + break; +#endif + case MRT6_INIT: + im->im6_mif = mifi; + break; + } if (socket_send(ip6_mrouter, mm, &sin6) < 0) { log(LOG_WARNING, "ip6_mforward: ip6_mrouter " @@ -1195,12 +1236,12 @@ ip6_mdq(m, ifp, rt) * seperate. */ -#define MC6_SEND(ip6,mifp,m) { \ - if ((mifp)->m6_flags & MIFF_REGISTER) \ - register_send((ip6), (mifp), (m)); \ - else \ - phyint_send((ip6), (mifp), (m)); \ -} +#define MC6_SEND(ip6, mifp, m) do { \ + if ((mifp)->m6_flags & MIFF_REGISTER) \ + register_send((ip6), (mifp), (m)); \ + else \ + phyint_send((ip6), (mifp), (m)); \ +} while (0) /* * Don't forward if it didn't arrive from the parent mif @@ -1214,7 +1255,7 @@ ip6_mdq(m, ifp, rt) log(LOG_DEBUG, "wrong if: ifid %d mifi %d mififid %x\n", ifp->if_index, mifi, - mif6table[mifi].m6_ifp->if_index); + mif6table[mifi].m6_ifp->if_index); #endif mrt6stat.mrt6s_wrong_if++; rt->mf6c_wrong_if++; @@ -1223,55 +1264,82 @@ ip6_mdq(m, ifp, rt) * packets on this interface, send a message to the * routing daemon. */ - if(mifi < nummifs) /* have to make sure this is a valid mif */ - if(mif6table[mifi].m6_ifp) - - if (pim6 && (m->m_flags & M_LOOP) == 0) { - /* - * Check the M_LOOP flag to avoid an - * unnecessary PIM assert. - * XXX: M_LOOP is an ad-hoc hack... - */ - static struct sockaddr_in6 sin6 = - { sizeof(sin6), AF_INET6 }; - - register struct mbuf *mm; - struct mrt6msg *im; - - mm = m_copy(m, 0, - sizeof(struct ip6_hdr)); - if (mm && - (M_HASCL(mm) || - mm->m_len < sizeof(struct ip6_hdr))) - mm = m_pullup(mm, sizeof(struct ip6_hdr)); - if (mm == NULL) - return ENOBUFS; - - im = mtod(mm, struct mrt6msg *); - im->im6_msgtype = MRT6MSG_WRONGMIF; - im->im6_mbz = 0; + /* have to make sure this is a valid mif */ + if (mifi < nummifs && mif6table[mifi].m6_ifp) + if (pim6 && (m->m_flags & M_LOOP) == 0) { + /* + * Check the M_LOOP flag to avoid an + * unnecessary PIM assert. + * XXX: M_LOOP is an ad-hoc hack... + */ + static struct sockaddr_in6 sin6 = + { sizeof(sin6), AF_INET6 }; - for (mifp = mif6table, iif = 0; - iif < nummifs && mifp && - mifp->m6_ifp != ifp; - mifp++, iif++); + register struct mbuf *mm; + struct mrt6msg *im; +#ifdef MRT6_OINIT + struct omrt6msg *oim; +#endif - im->im6_mif = iif; + mm = m_copy(m, 0, sizeof(struct ip6_hdr)); + if (mm && + (M_HASCL(mm) || + mm->m_len < sizeof(struct ip6_hdr))) + mm = m_pullup(mm, sizeof(struct ip6_hdr)); + if (mm == NULL) + return ENOBUFS; + +#ifdef MRT6_OINIT + oim = NULL; +#endif + im = NULL; + switch (ip6_mrouter_ver) { +#ifdef MRT6_OINIT + case MRT6_OINIT: + oim = mtod(mm, struct omrt6msg *); + oim->im6_msgtype = MRT6MSG_WRONGMIF; + oim->im6_mbz = 0; + break; +#endif + case MRT6_INIT: + im = mtod(mm, struct mrt6msg *); + im->im6_msgtype = MRT6MSG_WRONGMIF; + break; + default: + m_freem(mm); + return EINVAL; + } + for (mifp = mif6table, iif = 0; + iif < nummifs && mifp && + mifp->m6_ifp != ifp; + mifp++, iif++) + ; + + switch (ip6_mrouter_ver) { +#ifdef MRT6_OINIT + case MRT6_OINIT: + oim->im6_mif = iif; + sin6.sin6_addr = oim->im6_src; + break; +#endif + case MRT6_INIT: + im->im6_mif = iif; sin6.sin6_addr = im->im6_src; + break; + } - mrt6stat.mrt6s_upcalls++; + mrt6stat.mrt6s_upcalls++; - if (socket_send(ip6_mrouter, mm, - &sin6) < 0) { + if (socket_send(ip6_mrouter, mm, &sin6) < 0) { #ifdef MRT6DEBUG - if (mrt6debug) - log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); + if (mrt6debug) + log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); #endif - ++mrt6stat.mrt6s_upq_sockfull; - return ENOBUFS; - } /* if socket Q full */ - } /* if PIM */ + ++mrt6stat.mrt6s_upq_sockfull; + return ENOBUFS; + } /* if socket Q full */ + } /* if PIM */ return 0; } /* if wrong iif */ @@ -1293,6 +1361,25 @@ ip6_mdq(m, ifp, rt) */ for (mifp = mif6table, mifi = 0; mifi < nummifs; mifp++, mifi++) if (IF_ISSET(mifi, &rt->mf6c_ifset)) { + /* + * check if the outgoing packet is going to break + * a scope boundary. + * XXX For packets through PIM register tunnel + * interface, we believe a routing daemon. + */ + if ((mif6table[rt->mf6c_parent].m6_flags & + MIFF_REGISTER) == 0 && + (mif6table[mifi].m6_flags & MIFF_REGISTER) == 0 && + (in6_addr2scopeid(ifp, &ip6->ip6_dst) != + in6_addr2scopeid(mif6table[mifi].m6_ifp, + &ip6->ip6_dst) || + in6_addr2scopeid(ifp, &ip6->ip6_src) != + in6_addr2scopeid(mif6table[mifi].m6_ifp, + &ip6->ip6_src))) { + ip6stat.ip6s_badscope++; + continue; + } + mifp->m6_pkt_out++; mifp->m6_bytes_out += plen; MC6_SEND(ip6, mifp, m); @@ -1365,7 +1452,7 @@ phyint_send(ip6, mifp, m) ip6_mloopback(ifp, m, &ro6.ro_dst); } /* - * Put the packet into the sending queue of the outgoing interface + * 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) { @@ -1402,11 +1489,11 @@ phyint_send(ip6, mifp, m) #endif /* MRT6DEBUG */ m_freem(mb_copy); /* simply discard the packet */ return; -#endif +#endif } } -static int +static int register_send(ip6, mif, m) register struct ip6_hdr *ip6; struct mif6 *mif; @@ -1446,7 +1533,7 @@ register_send(ip6, mif, m) /* TODO: check it! */ mm->m_pkthdr.len = len + sizeof(struct ip6_hdr); - /* + /* * Send message to routing daemon */ sin6.sin6_addr = ip6->ip6_src; @@ -1471,7 +1558,7 @@ register_send(ip6, mif, m) } return 0; } - + /* * PIM sparse mode hook * Receives the pim control messages, and passes them up to the listening @@ -1513,12 +1600,12 @@ pim6_input(mp, offp, proto) * if the packet is at least as big as a REGISTER, go ahead * and grab the PIM REGISTER header size, to avoid another * possible m_pullup() later. - * + * * PIM_MINLEN == pimhdr + u_int32 == 8 * PIM6_REG_MINLEN == pimhdr + reghdr + eip6hdr == 4 + 4 + 40 */ minlen = (pimlen >= PIM6_REG_MINLEN) ? PIM6_REG_MINLEN : PIM_MINLEN; - + /* * Make sure that the IP6 and PIM headers in contiguous memory, and * possibly the PIM REGISTER header @@ -1527,7 +1614,7 @@ pim6_input(mp, offp, proto) IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE); /* adjust pointer */ ip6 = mtod(m, struct ip6_hdr *); - + /* adjust mbuf to point to the PIM header */ pim = (struct pim *)((caddr_t)ip6 + off); #else @@ -1558,7 +1645,7 @@ pim6_input(mp, offp, proto) if (mrt6debug & DEBUG_PIM) log(LOG_DEBUG, "pim6_input: invalid checksum\n"); -#endif +#endif m_freem(m); return(IPPROTO_DONE); } @@ -1572,7 +1659,7 @@ pim6_input(mp, offp, proto) log(LOG_ERR, "pim6_input: incorrect version %d, expecting %d\n", pim->pim_ver, PIM_VERSION); -#endif +#endif m_freem(m); return(IPPROTO_DONE); } @@ -1619,7 +1706,7 @@ pim6_input(mp, offp, proto) "pim6_input: register packet size too " "small %d from %s\n", pimlen, ip6_sprintf(&ip6->ip6_src)); -#endif +#endif m_freem(m); return(IPPROTO_DONE); } @@ -1633,7 +1720,7 @@ pim6_input(mp, offp, proto) ip6_sprintf(&eip6->ip6_src), ip6_sprintf(&eip6->ip6_dst), ntohs(eip6->ip6_plen)); -#endif +#endif /* verify the inner packet is destined to a mcast group */ if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) { @@ -1644,7 +1731,7 @@ pim6_input(mp, offp, proto) "pim6_input: inner packet of register " "is not multicast %s\n", ip6_sprintf(&eip6->ip6_dst)); -#endif +#endif m_freem(m); return(IPPROTO_DONE); } @@ -1658,7 +1745,7 @@ pim6_input(mp, offp, proto) log(LOG_ERR, "pim6_input: pim register: " "could not copy register head\n"); -#endif +#endif m_freem(m); return(IPPROTO_DONE); } @@ -1685,7 +1772,7 @@ pim6_input(mp, offp, proto) /* prepare the register head to send to the mrouting daemon */ m = mcp; } - + /* * Pass the PIM message up to the daemon; if it is a register message * pass the 'head' only up to the daemon. This includes the diff --git a/sys/netinet6/ip6_mroute.h b/sys/netinet6/ip6_mroute.h index 9060d359a3b..11540439467 100644 --- a/sys/netinet6/ip6_mroute.h +++ b/sys/netinet6/ip6_mroute.h @@ -1,9 +1,10 @@ -/* $OpenBSD: ip6_mroute.h,v 1.2 1999/12/10 10:04:28 angelos Exp $ */ +/* $OpenBSD: ip6_mroute.h,v 1.3 2000/05/19 13:11:34 itojun Exp $ */ +/* $KAME: ip6_mroute.h,v 1.10 2000/05/19 02:38:53 itojun Exp $ */ /* * Copyright (C) 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +16,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -49,15 +50,18 @@ /* * Multicast Routing set/getsockopt commands. */ -#define MRT6_INIT 100 /* initialize forwarder */ +#ifdef _KERNEL +#define MRT6_OINIT 100 /* initialize forwarder (omrt6msg) */ +#endif #define MRT6_DONE 101 /* shut down forwarder */ #define MRT6_ADD_MIF 102 /* add multicast interface */ #define MRT6_DEL_MIF 103 /* delete multicast interface */ #define MRT6_ADD_MFC 104 /* insert forwarding cache entry */ #define MRT6_DEL_MFC 105 /* delete forwarding cache entry */ #define MRT6_PIM 107 /* enable pim code */ +#define MRT6_INIT 108 /* initialize forwarder (mrt6msg) */ -#if BSD >= 199103 +#if BSD >= 199103 #define GET_TIME(t) microtime(&t) #elif defined(sun) #define GET_TIME(t) uniqtime(&t) @@ -135,21 +139,45 @@ struct mrt6stat { u_quad_t mrt6s_upq_sockfull; /* upcalls dropped - socket full */ }; +#ifdef MRT6_OINIT /* * Struct used to communicate from kernel to multicast router * note the convenient similarity to an IPv6 header. + * XXX old version, superseded by mrt6msg. */ -struct mrt6msg { +struct omrt6msg { u_long unused1; u_char im6_msgtype; /* what type of message */ -#define MRT6MSG_NOCACHE 1 +#if 0 +#define MRT6MSG_NOCACHE 1 #define MRT6MSG_WRONGMIF 2 #define MRT6MSG_WHOLEPKT 3 /* used for user level encap*/ +#endif u_char im6_mbz; /* must be zero */ u_char im6_mif; /* mif rec'd on */ u_char unused2; struct in6_addr im6_src, im6_dst; }; +#endif + +/* + * Structure used to communicate from kernel to multicast router. + * We'll overlay the structure onto an MLD header (not an IPv6 header + * like igmpmsg{} used for IPv4 implementation). This is because this + * structure will be passed via an IPv6 raw socket, on which an application + * will only receive the payload i.e. the data after the IPv6 header and all + * the extension headers. (see Section 3 of draft-ietf-ipngwg-2292bis-01) + */ +struct mrt6msg { +#define MRT6MSG_NOCACHE 1 +#define MRT6MSG_WRONGMIF 2 +#define MRT6MSG_WHOLEPKT 3 /* used for user level encap*/ + u_char im6_mbz; /* must be zero */ + u_char im6_msgtype; /* what type of message */ + u_int16_t im6_mif; /* mif rec'd on */ + u_int32_t im6_pad; /* padding for 64bit arch */ + struct in6_addr im6_src, im6_dst; +}; /* * Argument structure used by multicast routing daemon to get src-grp @@ -183,7 +211,7 @@ struct mif6 { u_int m6_rate_limit; /* max rate */ #ifdef notyet struct tbf *m6_tbf; /* token bucket structure at intf. */ -#endif +#endif struct in6_addr m6_lcl_addr; /* local interface address */ struct ifnet *m6_ifp; /* pointer to interface */ u_quad_t m6_pkt_in; /* # pkts in on interface */ @@ -194,11 +222,11 @@ struct mif6 { #ifdef notyet u_int m6_rsvp_on; /* RSVP listening on this vif */ struct socket *m6_rsvpd; /* RSVP daemon socket */ -#endif +#endif }; /* - * The kernel's multicast forwarding cache entry structure + * The kernel's multicast forwarding cache entry structure */ struct mf6c { struct sockaddr_in6 mf6c_origin; /* IPv6 origin of mcasts */ |