summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1995-03-16 16:25:55 +0000
committerwollman <wollman@FreeBSD.org>1995-03-16 16:25:55 +0000
commitb6beceae27e1650af0e5a1ee94bb83a629d6530a (patch)
treed878fa17c7db5f8fb8d5da16fdf99ebdb6f5e3f4
parent965da3c27aad8b8260f2d9f4b1b580a4da6c1e04 (diff)
downloadFreeBSD-src-b6beceae27e1650af0e5a1ee94bb83a629d6530a.zip
FreeBSD-src-b6beceae27e1650af0e5a1ee94bb83a629d6530a.tar.gz
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>
-rw-r--r--sys/netinet/ip_mroute.c46
-rw-r--r--sys/netinet/ip_var.h6
-rw-r--r--sys/netinet/raw_ip.c27
-rw-r--r--usr.sbin/mrouted/igmp.c6
-rw-r--r--usr.sbin/mrouted/prune.c14
5 files changed, 71 insertions, 28 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 5afffbb..40b39da 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -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;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 08e0c57..5ac0e80 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -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
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 4fcc900..95fe7a6 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -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--;
}
diff --git a/usr.sbin/mrouted/igmp.c b/usr.sbin/mrouted/igmp.c
index 7ddf3bc..ce5c1ce 100644
--- a/usr.sbin/mrouted/igmp.c
+++ b/usr.sbin/mrouted/igmp.c
@@ -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:
diff --git a/usr.sbin/mrouted/prune.c b/usr.sbin/mrouted/prune.c
index 04387a1..dfab604 100644
--- a/usr.sbin/mrouted/prune.c
+++ b/usr.sbin/mrouted/prune.c
@@ -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)) {
OpenPOWER on IntegriCloud