This set of patches enables IP multicasting to work under FreeBSD. I am

submitting them as context diffs for the following files:

sys/netinet/ip_mroute.c
sys/netinet/ip_var.h
sys/netinet/raw_ip.c
usr.sbin/mrouted/igmp.c
usr.sbin/mrouted/prune.c

The routine rip_ip_input in raw_ip.c is suggested by Mark Tinguely
(tinguely@plains.nodak.edu). I have been running mrouted with these patches
for over a week and nothing has seemed seriously wrong. It is being run in
two places on our network as a tunnel on one and a subnet querier on the
other. The only problem I have run into is that mrouted on the tunnel must
start up last or the pruning isn't done correctly and multicast packets
flood your subnets.

Submitted by:	Soochon Radee <slr@mitre.org>
This commit is contained in:
Garrett Wollman 1995-03-16 16:25:55 +00:00
parent 619e03fa69
commit d99c7a23fa
5 changed files with 71 additions and 28 deletions

View File

@ -23,7 +23,6 @@
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <net/raw_cb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@ -104,7 +103,7 @@ void multiencap_decap(struct mbuf *m) { /* XXX must fixup manually */
int (*legal_vif_num)(int) = 0;
#else
#else /* MROUTING */
#define INSIZ sizeof(struct in_addr)
#define same(a1, a2) \
@ -121,7 +120,7 @@ struct socket *ip_mrouter = NULL;
struct mrtstat mrtstat;
int ip_mrtproto = IGMP_DVMRP; /* for netstat only */
#else
#else /* MROUTE_LKM */
extern struct mrtstat mrtstat;
extern int ip_mrtproto;
#endif
@ -177,6 +176,7 @@ struct ip multicast_encap_iphdr = {
* Private variables.
*/
static vifi_t numvifs = 0;
static void (*encap_oldrawip)() = 0;
/*
* one-back cache used by multiencap_decap to locate a tunnel's vif
@ -212,6 +212,7 @@ void tbf_send_packet(struct vif *, struct mbuf *, struct ip_moptions *);
void tbf_update_tokens(struct vif *);
static int priority(struct vif *, struct ip *);
static int ip_mrouter_init(struct socket *);
void multiencap_decap(struct mbuf *m);
/*
* A simple hash function: returns MFCHASHMOD of the low-order octet of
@ -580,13 +581,17 @@ add_vif(vifcp)
if (vifcp->vifc_flags & VIFF_TUNNEL) {
if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) {
static int inited = 0;
if(!inited) {
if (encap_oldrawip == 0) {
extern struct protosw inetsw[];
extern u_char ip_protox[];
register u_char pr = ip_protox[ENCAP_PROTO];
encap_oldrawip = inetsw[pr].pr_input;
inetsw[pr].pr_input = multiencap_decap;
for (s = 0; s < MAXVIFS; ++s) {
multicast_decap_if[s].if_name = "mdecap";
multicast_decap_if[s].if_unit = s;
}
inited = 1;
}
ifp = &multicast_decap_if[vifcp->vifc_vifi];
} else {
@ -931,8 +936,9 @@ X_ip_mforward(ip, ifp, m, imo)
int s;
if (mrtdebug > 1)
log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %x\n",
ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp);
log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %x (%s%d)\n",
ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp,
ifp->if_name, ifp->if_unit);
if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 ||
(ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
@ -1119,9 +1125,7 @@ X_ip_mforward(ip, ifp, m, imo)
mrtstat.mrts_upcalls++;
raw_input(mm, &k_igmpproto,
(struct sockaddr *)&k_igmpsrc,
(struct sockaddr *)&k_igmpdst);
rip_ip_input(mm, ip_mrouter, (struct sockaddr *)&k_igmpsrc);
/* set timer to cleanup entry if upcall is lost */
timeout(cleanup_cache, (caddr_t)mb_rt, 100);
@ -1519,15 +1523,19 @@ multiencap_decap(m)
mrtstat.mrts_cant_tunnel++; /*XXX*/
m_freem(m);
if (mrtdebug)
log(LOG_DEBUG, "ip_mforward: no tunnel with %u\n",
log(LOG_DEBUG, "ip_mforward: no tunnel with %x\n",
ntohl(ip->ip_src.s_addr));
return;
}
ifp = vifp->v_ifp;
hlen -= sizeof(struct ifnet *);
m->m_data += hlen;
m->m_len -= hlen;
*(mtod(m, struct ifnet **)) = ifp;
if (hlen > IP_HDR_LEN)
ip_stripoptions(m, (struct mbuf *) 0);
m->m_data += IP_HDR_LEN;
m->m_len -= IP_HDR_LEN;
m->m_pkthdr.len -= IP_HDR_LEN;
m->m_pkthdr.rcvif = ifp;
ifq = &ipintrq;
s = splimp();
if (IF_QFULL(ifq)) {
@ -1879,8 +1887,8 @@ ip_mroute_mod_handle(struct lkm_table *lkmtp, int cmd)
ip_mforward = X_ip_mforward;
old_mrt_ioctl = mrt_ioctl;
mrt_ioctl = X_mrt_ioctl;
old_proto4_input = inetsw[ip_protox[IPPROTO_ENCAP]].pr_input;
inetsw[ip_protox[IPPROTO_ENCAP]].pr_input = X_multiencap_decap;
old_proto4_input = inetsw[ip_protox[ENCAP_PROTO]].pr_input;
inetsw[ip_protox[ENCAP_PROTO]].pr_input = X_multiencap_decap;
old_legal_vif_num = legal_vif_num;
legal_vif_num = X_legal_vif_num;
ip_mrtproto = IGMP_DVMRP;
@ -1896,7 +1904,7 @@ ip_mroute_mod_handle(struct lkm_table *lkmtp, int cmd)
ip_mrouter_done = old_ip_mrouter_done;
ip_mforward = old_ip_mforward;
mrt_ioctl = old_mrt_ioctl;
inetsw[ip_protox[IPPROTO_ENCAP]].pr_input = old_proto4_input;
inetsw[ip_protox[ENCAP_PROTO]].pr_input = old_proto4_input;
legal_vif_num = old_legal_vif_num;
ip_mrtproto = 0;
break;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_var.h 8.1 (Berkeley) 6/10/93
* $Id: ip_var.h,v 1.6 1994/09/14 03:10:14 wollman Exp $
* $Id: ip_var.h,v 1.7 1995/02/14 06:25:17 phk Exp $
*/
#ifndef _NETINET_IP_VAR_H_
@ -194,6 +194,10 @@ int rip_usrreq __P((struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *));
int ip_rsvp_init __P((struct socket *));
int ip_rsvp_done __P((void));
void rip_ip_input __P((struct mbuf *mm,
register struct socket *ip_mrouter, struct sockaddr *src));
#endif
#endif

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
* $Id: raw_ip.c,v 1.14 1995/02/07 02:53:14 wollman Exp $
* $Id: raw_ip.c,v 1.15 1995/02/14 06:24:40 phk Exp $
*/
#include <sys/param.h>
@ -96,10 +96,10 @@ rip_input(m)
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
continue;
if (inp->inp_laddr.s_addr &&
inp->inp_laddr.s_addr == ip->ip_dst.s_addr)
inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
continue;
if (inp->inp_faddr.s_addr &&
inp->inp_faddr.s_addr == ip->ip_src.s_addr)
inp->inp_faddr.s_addr != ip->ip_src.s_addr)
continue;
if (last) {
struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
@ -123,6 +123,27 @@ rip_input(m)
sorwakeup(last);
} else {
m_freem(m);
ipstat.ips_noproto++;
ipstat.ips_delivered--;
}
}
void rip_ip_input(mm, ip_mrouter, src)
struct mbuf *mm;
register struct socket *ip_mrouter;
struct sockaddr *src;
{
if (ip_mrouter)
{
if (sbappendaddr(&ip_mrouter->so_rcv, src,
mm, (struct mbuf *) 0) == 0)
m_freem(mm);
else
sorwakeup(ip_mrouter);
}
else
{
m_freem(mm);
ipstat.ips_noproto++;
ipstat.ips_delivered--;
}

View File

@ -7,7 +7,7 @@
* Leland Stanford Junior University.
*
*
* $Id: igmp.c,v 1.8 1994/08/24 23:53:32 thyagara Exp $
* igmp.c,v 1.2 1994/09/08 02:51:15 wollman Exp
*/
@ -181,12 +181,12 @@ void accept_igmp(recvlen)
case DVMRP_PROBE:
accept_probe(src, dst,
(char *)(igmp+1), igmpdatalen, group);
(char *)(igmp+1), igmpdatalen, ntohl(group));
return;
case DVMRP_REPORT:
accept_report(src, dst,
(char *)(igmp+1), igmpdatalen, group);
(char *)(igmp+1), igmpdatalen, ntohl(group));
return;
case DVMRP_ASK_NEIGHBORS:

View File

@ -7,7 +7,7 @@
* Leland Stanford Junior University.
*
*
* $Id: prune.c,v 1.4 1994/08/24 23:54:33 thyagara Exp $
* $Id: prune.c,v 1.2 1994/09/08 02:51:23 wollman Exp $
*/
@ -530,7 +530,12 @@ void send_prune(kt)
*p++ = ((char *)&(kt->kt_origin))[i];
for (i = 0; i < 4; i++)
*p++ = ((char *)&(kt->kt_mcastgrp))[i];
#if BYTE_ORDER == BIG_ENDIAN
for (i = 0; i < 4; i++)
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
for (i = 3; i >= 0; i--)
#endif
*p++ = ((char *)&(kt->kt_prsent_timer))[i];
datalen += 12;
@ -589,7 +594,12 @@ void accept_prune(src, dst, p, datalen)
((char *)&prun_src)[i] = *p++;
for (i = 0; i< 4; i++)
((char *)&prun_dst)[i] = *p++;
#if BYTE_ORDER == BIG_ENDIAN
for (i = 0; i< 4; i++)
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
for (i = 3; i >= 0; i--)
#endif
((char *)&prun_tmr)[i] = *p++;
kt = find_src_grp(prun_src, prun_dst);
@ -1051,7 +1061,7 @@ void age_table_entry()
krl;
prev_krl = krl, krl = krl->rl_next) {
if ((krl->rl_timer -= ROUTE_MAX_REPORT_DELAY) <= 0) {
log(LOG_DEBUG, 0, "forw again s %x g%x on vif %d",
log(LOG_DEBUG, 0, "forw again s %x g %x on vif %d",
kt->kt_origin, kt->kt_mcastgrp, krl->rl_vifi);
if (!VIFM_ISSET(krl->rl_vifi, kt->kt_grpmems)) {