mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 17:32:43 +00:00
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:
parent
619e03fa69
commit
d99c7a23fa
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7083
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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--;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user