summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2002-11-15 22:53:53 +0000
committerluigi <luigi@FreeBSD.org>2002-11-15 22:53:53 +0000
commit60e892bf319d72d9b1ee2c14488fa30da0195da3 (patch)
tree3749705a7135b04736f5f3cc35c85e50866bc963
parent5044bd9ace87bfc9ba423a4ea2003b64b244ba2c (diff)
downloadFreeBSD-src-60e892bf319d72d9b1ee2c14488fa30da0195da3.zip
FreeBSD-src-60e892bf319d72d9b1ee2c14488fa30da0195da3.tar.gz
Massive cleanup of the ip_mroute code.
No functional changes, but: + the mrouting module now should behave the same as the compiled-in version (it did not before, some of the rsvp code was not loaded properly); + netinet/ip_mroute.c is now truly optional; + removed some redundant/unused code; + changed many instances of '0' to NULL and INADDR_ANY as appropriate; + removed several static variables to make the code more SMP-friendly; + fixed some minor bugs in the mrouting code (mostly, incorrect return values from functions). This commit is also a prerequisite to the addition of support for PIM, which i would like to put in before DP2 (it does not change any of the existing APIs, anyways). Note, in the process we found out that some device drivers fail to properly handle changes in IFF_ALLMULTI, leading to interesting behaviour when a multicast router is started. This bug is not corrected by this commit, and will be fixed with a separate commit. Detailed changes: -------------------- netinet/ip_mroute.c all the above. conf/files make ip_mroute.c optional net/route.c fix mrt_ioctl hook netinet/ip_input.c fix ip_mforward hook, move rsvp_input() here together with other rsvp code, and a couple of indentation fixes. netinet/ip_output.c fix ip_mforward and ip_mcast_src hooks netinet/ip_var.h rsvp function hooks netinet/raw_ip.c hooks for mrouting and rsvp functions, plus interface cleanup. netinet/ip_mroute.h remove an unused and optional field from a struct Most of the code is from Pavlin Radoslavov and the XORP project Reviewed by: sam MFC after: 1 week
-rw-r--r--sys/conf/files2
-rw-r--r--sys/net/route.c2
-rw-r--r--sys/netinet/ip_input.c33
-rw-r--r--sys/netinet/ip_mroute.c1386
-rw-r--r--sys/netinet/ip_mroute.h3
-rw-r--r--sys/netinet/ip_output.c11
-rw-r--r--sys/netinet/ip_var.h7
-rw-r--r--sys/netinet/raw_ip.c40
8 files changed, 596 insertions, 888 deletions
diff --git a/sys/conf/files b/sys/conf/files
index c2dbd2a..300fe54 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1318,7 +1318,7 @@ netinet/ip_flow.c optional inet
netinet/ip_fw2.c optional ipfirewall
netinet/ip_icmp.c optional inet
netinet/ip_input.c optional inet
-netinet/ip_mroute.c optional inet
+netinet/ip_mroute.c optional mrouting
netinet/ip_output.c optional inet
netinet/raw_ip.c optional inet
netinet/tcp_debug.c optional tcpdebug
diff --git a/sys/net/route.c b/sys/net/route.c
index d71a950..adf0b3b 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -403,7 +403,7 @@ rtioctl(req, data)
{
#ifdef INET
/* Multicast goop, grrr... */
- return mrt_ioctl(req, data);
+ return mrt_ioctl ? mrt_ioctl(req, data) : EOPNOTSUPP;
#else /* INET */
return ENXIO;
#endif /* INET */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 8173a25..f928744 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -600,7 +600,8 @@ pass:
* ip_mforward() returns a non-zero value, the packet
* must be discarded, else it may be accepted below.
*/
- if (ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
+ if (ip_mforward &&
+ ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
ipstat.ips_cantforward++;
m_freem(m);
return;
@@ -2073,10 +2074,10 @@ ip_rsvp_init(struct socket *so)
{
if (so->so_type != SOCK_RAW ||
so->so_proto->pr_protocol != IPPROTO_RSVP)
- return EOPNOTSUPP;
+ return EOPNOTSUPP;
if (ip_rsvpd != NULL)
- return EADDRINUSE;
+ return EADDRINUSE;
ip_rsvpd = so;
/*
@@ -2105,3 +2106,29 @@ ip_rsvp_done(void)
}
return 0;
}
+
+void
+rsvp_input(struct mbuf *m, int off) /* XXX must fixup manually */
+{
+ if (rsvp_input_p) { /* call the real one if loaded */
+ rsvp_input_p(m, off);
+ return;
+ }
+
+ /* Can still get packets with rsvp_on = 0 if there is a local member
+ * of the group to which the RSVP packet is addressed. But in this
+ * case we want to throw the packet away.
+ */
+
+ if (!rsvp_on) {
+ m_freem(m);
+ return;
+ }
+
+ if (ip_rsvpd != NULL) {
+ rip_input(m, off);
+ return;
+ }
+ /* Drop the packet */
+ m_freem(m);
+}
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 11da8ef..3caba6b 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -45,157 +45,30 @@
#include <netinet/udp.h>
#include <machine/in_cksum.h>
-#ifndef MROUTING
-extern u_long _ip_mcast_src(int vifi);
-extern int _ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m,
- struct ip_moptions *imo);
-extern int _ip_mrouter_done(void);
-extern int _ip_mrouter_get(struct socket *so, struct sockopt *sopt);
-extern int _ip_mrouter_set(struct socket *so, struct sockopt *sopt);
-extern int _mrt_ioctl(int req, caddr_t data);
-
/*
- * Dummy routines and globals used when multicast routing is not compiled in.
+ * Control debugging code for rsvp and multicast routing code.
+ * Can only set them with the debugger.
*/
+static u_int rsvpdebug; /* non-zero enables debugging */
-struct socket *ip_mrouter = NULL;
-u_int rsvpdebug = 0;
-
-int
-_ip_mrouter_set(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- return(EOPNOTSUPP);
-}
-
-int (*ip_mrouter_set)(struct socket *, struct sockopt *) = _ip_mrouter_set;
-
-
-int
-_ip_mrouter_get(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- return(EOPNOTSUPP);
-}
-
-int (*ip_mrouter_get)(struct socket *, struct sockopt *) = _ip_mrouter_get;
-
-int
-_ip_mrouter_done()
-{
- return(0);
-}
-
-int (*ip_mrouter_done)(void) = _ip_mrouter_done;
-
-int
-_ip_mforward(ip, ifp, m, imo)
- struct ip *ip;
- struct ifnet *ifp;
- struct mbuf *m;
- struct ip_moptions *imo;
-{
- return(0);
-}
-
-int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
- struct ip_moptions *) = _ip_mforward;
-
-int
-_mrt_ioctl(int req, caddr_t data)
-{
- return EOPNOTSUPP;
-}
-
-int (*mrt_ioctl)(int, caddr_t) = _mrt_ioctl;
-
-void
-rsvp_input(m, off) /* XXX must fixup manually */
- struct mbuf *m;
- int off;
-{
- /* Can still get packets with rsvp_on = 0 if there is a local member
- * of the group to which the RSVP packet is addressed. But in this
- * case we want to throw the packet away.
- */
- if (!rsvp_on) {
- m_freem(m);
- return;
- }
-
- if (ip_rsvpd != NULL) {
- if (rsvpdebug)
- printf("rsvp_input: Sending packet up old-style socket\n");
- rip_input(m, off);
- return;
- }
- /* Drop the packet */
- m_freem(m);
-}
-
-int (*legal_vif_num)(int) = 0;
-
-/*
- * This should never be called, since IP_MULTICAST_VIF should fail, but
- * just in case it does get called, the code a little lower in ip_output
- * will assign the packet a local address.
- */
-u_long
-_ip_mcast_src(int vifi) { return INADDR_ANY; }
-u_long (*ip_mcast_src)(int) = _ip_mcast_src;
-
-int
-ip_rsvp_vif_init(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- return(EINVAL);
-}
-
-int
-ip_rsvp_vif_done(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- return(EINVAL);
-}
-
-void
-ip_rsvp_force_done(so)
- struct socket *so;
-{
- return;
-}
-
-#else /* MROUTING */
+static u_int mrtdebug; /* any set of the flags below */
+#define DEBUG_MFC 0x02
+#define DEBUG_FORWARD 0x04
+#define DEBUG_EXPIRE 0x08
+#define DEBUG_XMIT 0x10
#define M_HASCL(m) ((m)->m_flags & M_EXT)
static MALLOC_DEFINE(M_MRTABLE, "mroutetbl", "multicast routing tables");
-#ifndef MROUTE_KLD
-/* The socket used to communicate with the multicast routing daemon. */
-struct socket *ip_mrouter = NULL;
-#endif
-
-#if defined(MROUTING) || defined(MROUTE_KLD)
static struct mrtstat mrtstat;
SYSCTL_STRUCT(_net_inet_ip, OID_AUTO, mrtstat, CTLFLAG_RW,
- &mrtstat, mrtstat, "Multicast Routing Statistics (struct mrtstat, netinet/ip_mroute.h)");
-#endif
+ &mrtstat, mrtstat,
+ "Multicast Routing Statistics (struct mrtstat, netinet/ip_mroute.h)");
static struct mfc *mfctable[MFCTBLSIZ];
static u_char nexpire[MFCTBLSIZ];
static struct vif viftable[MAXVIFS];
-static u_int mrtdebug = 0; /* debug level */
-#define DEBUG_MFC 0x02
-#define DEBUG_FORWARD 0x04
-#define DEBUG_EXPIRE 0x08
-#define DEBUG_XMIT 0x10
-static u_int tbfdebug = 0; /* tbf debug level */
-static u_int rsvpdebug = 0; /* rsvp debug level */
static struct callout_handle expire_upcalls_ch;
@@ -241,8 +114,8 @@ static struct ip multicast_encap_iphdr = {
/*
* Private variables.
*/
-static vifi_t numvifs = 0;
-static const struct encaptab *encap_cookie = NULL;
+static vifi_t numvifs;
+static const struct encaptab *encap_cookie;
/*
* one-back cache used by mroute_encapcheck to locate a tunnel's vif
@@ -252,7 +125,8 @@ static u_long last_encap_src;
static struct vif *last_encap_vif;
static u_long X_ip_mcast_src(int vifi);
-static int X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo);
+static int X_ip_mforward(struct ip *ip, struct ifnet *ifp,
+ struct mbuf *m, struct ip_moptions *imo);
static int X_ip_mrouter_done(void);
static int X_ip_mrouter_get(struct socket *so, struct sockopt *m);
static int X_ip_mrouter_set(struct socket *so, struct sockopt *m);
@@ -269,8 +143,7 @@ static int del_mfc(struct mfcctl *);
static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
static int set_assert(int);
static void expire_upcalls(void *);
-static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
- vifi_t);
+static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *, vifi_t);
static void phyint_send(struct ip *, struct vif *, struct mbuf *);
static void encap_send(struct ip *, struct vif *, struct mbuf *);
static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long);
@@ -300,210 +173,179 @@ static int pim_assert;
/*
* Find a route for a given origin IP address and Multicast group address
* Type of service parameter to be added in the future!!!
+ * Statistics are updated by the caller if needed
+ * (mrtstat.mrts_mfc_lookups and mrtstat.mrts_mfc_misses)
*/
+static struct mfc *
+mfc_find(in_addr_t o, in_addr_t g)
+{
+ struct mfc *rt;
-#define MFCFIND(o, g, rt) { \
- register struct mfc *_rt = mfctable[MFCHASH(o,g)]; \
- rt = NULL; \
- ++mrtstat.mrts_mfc_lookups; \
- while (_rt) { \
- if ((_rt->mfc_origin.s_addr == o) && \
- (_rt->mfc_mcastgrp.s_addr == g) && \
- (_rt->mfc_stall == NULL)) { \
- rt = _rt; \
- break; \
- } \
- _rt = _rt->mfc_next; \
- } \
- if (rt == NULL) { \
- ++mrtstat.mrts_mfc_misses; \
- } \
+ for (rt = mfctable[MFCHASH(o,g)]; rt; rt = rt->mfc_next)
+ if ((rt->mfc_origin.s_addr == o) &&
+ (rt->mfc_mcastgrp.s_addr == g) && (rt->mfc_stall == NULL))
+ break;
+ return rt;
}
-
/*
* Macros to compute elapsed time efficiently
* Borrowed from Van Jacobson's scheduling code
*/
-#define TV_DELTA(a, b, delta) { \
- register int xxs; \
- \
- delta = (a).tv_usec - (b).tv_usec; \
- if ((xxs = (a).tv_sec - (b).tv_sec)) { \
- switch (xxs) { \
- case 2: \
- delta += 1000000; \
- /* FALLTHROUGH */ \
- case 1: \
- delta += 1000000; \
- break; \
- default: \
- delta += (1000000 * xxs); \
- } \
- } \
+#define TV_DELTA(a, b, delta) { \
+ int xxs; \
+ delta = (a).tv_usec - (b).tv_usec; \
+ if ((xxs = (a).tv_sec - (b).tv_sec)) { \
+ switch (xxs) { \
+ case 2: \
+ delta += 1000000; \
+ /* FALLTHROUGH */ \
+ case 1: \
+ delta += 1000000; \
+ break; \
+ default: \
+ delta += (1000000 * xxs); \
+ } \
+ } \
}
#define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \
(a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec)
-#ifdef UPCALL_TIMING
-u_long upcall_data[51];
-static void collate(struct timeval *);
-#endif /* UPCALL_TIMING */
-
-
/*
* Handle MRT setsockopt commands to modify the multicast routing tables.
*/
static int
-X_ip_mrouter_set(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
+X_ip_mrouter_set(struct socket *so, struct sockopt *sopt)
{
- int error, optval;
- vifi_t vifi;
- struct vifctl vifc;
- struct mfcctl mfc;
-
- if (so != ip_mrouter && sopt->sopt_name != MRT_INIT)
- return (EPERM);
-
- error = 0;
- switch (sopt->sopt_name) {
- case MRT_INIT:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
- error = ip_mrouter_init(so, optval);
- break;
-
- case MRT_DONE:
- error = ip_mrouter_done();
- break;
+ int error, optval;
+ vifi_t vifi;
+ struct vifctl vifc;
+ struct mfcctl mfc;
+
+ if (so != ip_mrouter && sopt->sopt_name != MRT_INIT)
+ return EPERM;
+
+ error = 0;
+ switch (sopt->sopt_name) {
+ case MRT_INIT:
+ error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
+ if (error)
+ break;
+ error = ip_mrouter_init(so, optval);
+ break;
- case MRT_ADD_VIF:
- error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
- if (error)
- break;
- error = add_vif(&vifc);
- break;
+ case MRT_DONE:
+ error = ip_mrouter_done();
+ break;
- case MRT_DEL_VIF:
- error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
- if (error)
- break;
- error = del_vif(vifi);
- break;
+ case MRT_ADD_VIF:
+ error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
+ if (error)
+ break;
+ error = add_vif(&vifc);
+ break;
- case MRT_ADD_MFC:
- case MRT_DEL_MFC:
- error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);
- if (error)
- break;
- if (sopt->sopt_name == MRT_ADD_MFC)
- error = add_mfc(&mfc);
- else
- error = del_mfc(&mfc);
- break;
+ case MRT_DEL_VIF:
+ error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
+ if (error)
+ break;
+ error = del_vif(vifi);
+ break;
- case MRT_ASSERT:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
- set_assert(optval);
- break;
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);
+ if (error)
+ break;
+ if (sopt->sopt_name == MRT_ADD_MFC)
+ error = add_mfc(&mfc);
+ else
+ error = del_mfc(&mfc);
+ break;
+
+ case MRT_ASSERT:
+ error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
+ if (error)
+ break;
+ set_assert(optval);
+ break;
- default:
- error = EOPNOTSUPP;
- break;
- }
- return (error);
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ return error;
}
-#ifndef MROUTE_KLD
-int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;
-#endif
-
/*
* Handle MRT getsockopt commands
*/
static int
-X_ip_mrouter_get(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
+X_ip_mrouter_get(struct socket *so, struct sockopt *sopt)
{
- int error;
- static int version = 0x0305; /* !!! why is this here? XXX */
+ int error;
+ static int version = 0x0305; /* !!! why is this here? XXX */
- switch (sopt->sopt_name) {
- case MRT_VERSION:
- error = sooptcopyout(sopt, &version, sizeof version);
- break;
+ switch (sopt->sopt_name) {
+ case MRT_VERSION:
+ error = sooptcopyout(sopt, &version, sizeof version);
+ break;
- case MRT_ASSERT:
- error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);
- break;
- default:
- error = EOPNOTSUPP;
- break;
- }
- return (error);
-}
+ case MRT_ASSERT:
+ error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);
+ break;
-#ifndef MROUTE_KLD
-int (*ip_mrouter_get)(struct socket *, struct sockopt *) = X_ip_mrouter_get;
-#endif
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ return error;
+}
/*
* Handle ioctl commands to obtain information from the cache
*/
static int
-X_mrt_ioctl(cmd, data)
- int cmd;
- caddr_t data;
+X_mrt_ioctl(int cmd, caddr_t data)
{
int error = 0;
switch (cmd) {
- case (SIOCGETVIFCNT):
- return (get_vif_cnt((struct sioc_vif_req *)data));
- break;
- case (SIOCGETSGCNT):
- return (get_sg_cnt((struct sioc_sg_req *)data));
- break;
- default:
- return (EINVAL);
- break;
+ case (SIOCGETVIFCNT):
+ error = get_vif_cnt((struct sioc_vif_req *)data);
+ break;
+
+ case (SIOCGETSGCNT):
+ error = get_sg_cnt((struct sioc_sg_req *)data);
+ break;
+
+ default:
+ error = EINVAL;
+ break;
}
return error;
}
-#ifndef MROUTE_KLD
-int (*mrt_ioctl)(int, caddr_t) = X_mrt_ioctl;
-#endif
-
/*
* returns the packet, byte, rpf-failure count for the source group provided
*/
static int
-get_sg_cnt(req)
- register struct sioc_sg_req *req;
+get_sg_cnt(struct sioc_sg_req *req)
{
- register struct mfc *rt;
int s;
+ struct mfc *rt;
s = splnet();
- MFCFIND(req->src.s_addr, req->grp.s_addr, rt);
+ rt = mfc_find(req->src.s_addr, req->grp.s_addr);
splx(s);
- if (rt != NULL) {
- req->pktcnt = rt->mfc_pkt_cnt;
- req->bytecnt = rt->mfc_byte_cnt;
- req->wrong_if = rt->mfc_wrong_if;
- } else
+ if (rt == NULL) {
req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;
-
+ return EADDRNOTAVAIL;
+ }
+ req->pktcnt = rt->mfc_pkt_cnt;
+ req->bytecnt = rt->mfc_byte_cnt;
+ req->wrong_if = rt->mfc_wrong_if;
return 0;
}
@@ -511,12 +353,12 @@ get_sg_cnt(req)
* returns the input and output packet and byte counts on the vif provided
*/
static int
-get_vif_cnt(req)
- register struct sioc_vif_req *req;
+get_vif_cnt(struct sioc_vif_req *req)
{
- register vifi_t vifi = req->vifi;
+ vifi_t vifi = req->vifi;
- if (vifi >= numvifs) return EINVAL;
+ if (vifi >= numvifs)
+ return EINVAL;
req->icount = viftable[vifi].v_pkt_in;
req->ocount = viftable[vifi].v_pkt_out;
@@ -530,21 +372,20 @@ get_vif_cnt(req)
* Enable multicast routing
*/
static int
-ip_mrouter_init(so, version)
- struct socket *so;
- int version;
+ip_mrouter_init(struct socket *so, int version)
{
if (mrtdebug)
- log(LOG_DEBUG,"ip_mrouter_init: so_type = %d, pr_protocol = %d\n",
- so->so_type, so->so_proto->pr_protocol);
+ log(LOG_DEBUG, "ip_mrouter_init: so_type = %d, pr_protocol = %d\n",
+ so->so_type, so->so_proto->pr_protocol);
- if (so->so_type != SOCK_RAW ||
- so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;
+ if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_IGMP)
+ return EOPNOTSUPP;
if (version != 1)
return ENOPROTOOPT;
- if (ip_mrouter != NULL) return EADDRINUSE;
+ if (ip_mrouter != NULL)
+ return EADDRINUSE;
ip_mrouter = so;
@@ -553,7 +394,7 @@ ip_mrouter_init(so, version)
pim_assert = 0;
- expire_upcalls_ch = timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+ expire_upcalls_ch = timeout(expire_upcalls, NULL, EXPIRE_TIMEOUT);
if (mrtdebug)
log(LOG_DEBUG, "ip_mrouter_init\n");
@@ -565,7 +406,7 @@ ip_mrouter_init(so, version)
* Disable multicast routing
*/
static int
-X_ip_mrouter_done()
+X_ip_mrouter_done(void)
{
vifi_t vifi;
int i;
@@ -583,10 +424,12 @@ X_ip_mrouter_done()
*/
for (vifi = 0; vifi < numvifs; vifi++) {
if (viftable[vifi].v_lcl_addr.s_addr != 0 &&
- !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
- ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
- ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr
- = INADDR_ANY;
+ !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
+ struct sockaddr_in *so = (struct sockaddr_in *)&(ifr.ifr_addr);
+
+ so->sin_len = sizeof(struct sockaddr_in);
+ so->sin_family = AF_INET;
+ so->sin_addr.s_addr = INADDR_ANY;
ifp = viftable[vifi].v_ifp;
if_allmulti(ifp, 0);
}
@@ -596,7 +439,7 @@ X_ip_mrouter_done()
numvifs = 0;
pim_assert = 0;
- untimeout(expire_upcalls, (caddr_t)NULL, expire_upcalls_ch);
+ untimeout(expire_upcalls, NULL, expire_upcalls_ch);
/*
* Free all multicast forwarding cache entries.
@@ -622,13 +465,13 @@ X_ip_mrouter_done()
/*
* Reset de-encapsulation cache
*/
- last_encap_src = 0;
+ last_encap_src = INADDR_ANY;
last_encap_vif = NULL;
if (encap_cookie) {
encap_detach(encap_cookie);
encap_cookie = NULL;
}
-
+
ip_mrouter = NULL;
splx(s);
@@ -639,16 +482,11 @@ X_ip_mrouter_done()
return 0;
}
-#ifndef MROUTE_KLD
-int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
-#endif
-
/*
* Set PIM assert processing global
*/
static int
-set_assert(i)
- int i;
+set_assert(int i)
{
if ((i != 1) && (i != 0))
return EINVAL;
@@ -660,14 +498,13 @@ set_assert(i)
/*
* Decide if a packet is from a tunnelled peer.
- * Return 0 if not, 64 if so.
+ * Return 0 if not, 64 if so. XXX yuck.. 64 ???
*/
static int
mroute_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
{
struct ip *ip = mtod(m, struct ip *);
int hlen = ip->ip_hl << 2;
- register struct vif *vifp;
/*
* don't claim the packet if it's not to a multicast destination or if
@@ -676,26 +513,23 @@ mroute_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
* uniquely identifies the tunnel (i.e., that this site has
* at most one tunnel with the remote site).
*/
- if (! IN_MULTICAST(ntohl(((struct ip *)((char *)ip + hlen))->ip_dst.s_addr))) {
+ if (!IN_MULTICAST(ntohl(((struct ip *)((char *)ip+hlen))->ip_dst.s_addr)))
return 0;
- }
if (ip->ip_src.s_addr != last_encap_src) {
- register struct vif *vife;
-
- vifp = viftable;
- vife = vifp + numvifs;
+ struct vif *vifp = viftable;
+ struct vif *vife = vifp + numvifs;
+
last_encap_src = ip->ip_src.s_addr;
- last_encap_vif = 0;
+ last_encap_vif = NULL;
for ( ; vifp < vife; ++vifp)
if (vifp->v_rmt_addr.s_addr == ip->ip_src.s_addr) {
- if ((vifp->v_flags & (VIFF_TUNNEL|VIFF_SRCRT))
- == VIFF_TUNNEL)
+ if ((vifp->v_flags & (VIFF_TUNNEL|VIFF_SRCRT)) == VIFF_TUNNEL)
last_encap_vif = vifp;
break;
}
}
- if ((vifp = last_encap_vif) == 0) {
- last_encap_src = 0;
+ if (last_encap_vif == NULL) {
+ last_encap_src = INADDR_ANY;
return 0;
}
return 64;
@@ -713,7 +547,7 @@ mroute_encap_input(struct mbuf *m, int off)
int hlen = ip->ip_hl << 2;
if (hlen > sizeof(struct ip))
- ip_stripoptions(m, (struct mbuf *) 0);
+ ip_stripoptions(m, (struct mbuf *) 0);
m->m_data += sizeof(struct ip);
m->m_len -= sizeof(struct ip);
m->m_pkthdr.len -= sizeof(struct ip);
@@ -721,13 +555,13 @@ mroute_encap_input(struct mbuf *m, int off)
m->m_pkthdr.rcvif = last_encap_vif->v_ifp;
(void) IF_HANDOFF(&ipintrq, m, NULL);
- /*
- * normally we would need a "schednetisr(NETISR_IP)"
- * here but we were called by ip_input and it is going
- * to loop back & try to dequeue the packet we just
- * queued as soon as we return so we avoid the
- * unnecessary software interrrupt.
- */
+ /*
+ * normally we would need a "schednetisr(NETISR_IP)"
+ * here but we were called by ip_input and it is going
+ * to loop back & try to dequeue the packet we just
+ * queued as soon as we return so we avoid the
+ * unnecessary software interrrupt.
+ */
}
extern struct domain inetdomain;
@@ -743,60 +577,63 @@ static struct protosw mroute_encap_protosw =
* Add a vif to the vif table
*/
static int
-add_vif(vifcp)
- register struct vifctl *vifcp;
+add_vif(struct vifctl *vifcp)
{
- register struct vif *vifp = viftable + vifcp->vifc_vifi;
- static struct sockaddr_in sin = {sizeof sin, AF_INET};
+ struct vif *vifp = viftable + vifcp->vifc_vifi;
+ struct sockaddr_in sin = {sizeof sin, AF_INET};
struct ifaddr *ifa;
struct ifnet *ifp;
int error, s;
struct tbf *v_tbf = tbftable + vifcp->vifc_vifi;
- if (vifcp->vifc_vifi >= MAXVIFS) return EINVAL;
- if (vifp->v_lcl_addr.s_addr != 0) return EADDRINUSE;
+ if (vifcp->vifc_vifi >= MAXVIFS)
+ return EINVAL;
+ if (vifp->v_lcl_addr.s_addr != INADDR_ANY)
+ return EADDRINUSE;
+ if (vifcp->vifc_lcl_addr.s_addr == INADDR_ANY)
+ return EADDRNOTAVAIL;
/* Find the interface with an address in AF_INET family */
sin.sin_addr = vifcp->vifc_lcl_addr;
ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
- if (ifa == 0) return EADDRNOTAVAIL;
+ if (ifa == NULL)
+ return EADDRNOTAVAIL;
ifp = ifa->ifa_ifp;
if (vifcp->vifc_flags & VIFF_TUNNEL) {
if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) {
- /*
- * An encapsulating tunnel is wanted. Tell
- * mroute_encap_input() to start paying attention
- * to encapsulated packets.
- */
- if (encap_cookie == NULL) {
- encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV4,
+ /*
+ * An encapsulating tunnel is wanted. Tell
+ * mroute_encap_input() to start paying attention
+ * to encapsulated packets.
+ */
+ if (encap_cookie == NULL) {
+ encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV4,
mroute_encapcheck,
(struct protosw *)&mroute_encap_protosw, NULL);
- if (encap_cookie == NULL) {
- printf("ip_mroute: unable to attach encap\n");
- return (EIO); /* XXX */
- }
- for (s = 0; s < MAXVIFS; ++s) {
- multicast_decap_if[s].if_name = "mdecap";
- multicast_decap_if[s].if_unit = s;
- }
+ if (encap_cookie == NULL) {
+ printf("ip_mroute: unable to attach encap\n");
+ return EIO; /* XXX */
}
- /*
- * Set interface to fake encapsulator interface
- */
- ifp = &multicast_decap_if[vifcp->vifc_vifi];
- /*
- * Prepare cached route entry
- */
- bzero(&vifp->v_route, sizeof(vifp->v_route));
+ for (s = 0; s < MAXVIFS; ++s) {
+ multicast_decap_if[s].if_name = "mdecap";
+ multicast_decap_if[s].if_unit = s;
+ }
+ }
+ /*
+ * Set interface to fake encapsulator interface
+ */
+ ifp = &multicast_decap_if[vifcp->vifc_vifi];
+ /*
+ * Prepare cached route entry
+ */
+ bzero(&vifp->v_route, sizeof(vifp->v_route));
} else {
log(LOG_ERR, "source routed tunnels not supported\n");
return EOPNOTSUPP;
}
- } else {
- /* Make sure the interface supports multicast */
+ } else { /* Make sure the interface supports multicast */
if ((ifp->if_flags & IFF_MULTICAST) == 0)
return EOPNOTSUPP;
@@ -852,37 +689,33 @@ add_vif(vifcp)
* Delete a vif from the vif table
*/
static int
-del_vif(vifi)
- vifi_t vifi;
+del_vif(vifi_t vifi)
{
- register struct vif *vifp = &viftable[vifi];
- register struct mbuf *m;
- struct ifnet *ifp;
- struct ifreq ifr;
+ struct vif *vifp;
int s;
- if (vifi >= numvifs) return EINVAL;
- if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL;
+ if (vifi >= numvifs)
+ return EINVAL;
+ vifp = &viftable[vifi];
+ if (vifp->v_lcl_addr.s_addr == INADDR_ANY)
+ return EADDRNOTAVAIL;
s = splnet();
- if (!(vifp->v_flags & VIFF_TUNNEL)) {
- ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
- ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
- ifp = vifp->v_ifp;
- if_allmulti(ifp, 0);
- }
+ if (!(vifp->v_flags & VIFF_TUNNEL))
+ if_allmulti(vifp->v_ifp, 0);
if (vifp == last_encap_vif) {
- last_encap_vif = 0;
- last_encap_src = 0;
+ last_encap_vif = NULL;
+ last_encap_src = INADDR_ANY;
}
/*
* Free packets queued at the interface
*/
while (vifp->v_tbf->tbf_q) {
- m = vifp->v_tbf->tbf_q;
+ struct mbuf *m = vifp->v_tbf->tbf_q;
+
vifp->v_tbf->tbf_q = m->m_act;
m_freem(m);
}
@@ -891,11 +724,12 @@ del_vif(vifi)
bzero((caddr_t)vifp, sizeof (*vifp));
if (mrtdebug)
- log(LOG_DEBUG, "del_vif %d, numvifs %d\n", vifi, numvifs);
+ log(LOG_DEBUG, "del_vif %d, numvifs %d\n", vifi, numvifs);
/* Adjust numvifs down */
for (vifi = numvifs; vifi > 0; vifi--)
- if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;
+ if (viftable[vifi-1].v_lcl_addr.s_addr != INADDR_ANY)
+ break;
numvifs = vifi;
splx(s);
@@ -904,20 +738,50 @@ del_vif(vifi)
}
/*
+ * update an mfc entry without resetting counters and S,G addresses.
+ */
+static void
+update_mfc_params(struct mfc *rt, struct mfcctl *mfccp)
+{
+ int i;
+
+ rt->mfc_parent = mfccp->mfcc_parent;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+}
+
+/*
+ * fully initialize an mfc entry from the parameter.
+ */
+static void
+init_mfc_params(struct mfc *rt, struct mfcctl *mfccp)
+{
+ rt->mfc_origin = mfccp->mfcc_origin;
+ rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
+
+ update_mfc_params(rt, mfccp);
+
+ /* initialize pkt counters per src-grp */
+ rt->mfc_pkt_cnt = 0;
+ rt->mfc_byte_cnt = 0;
+ rt->mfc_wrong_if = 0;
+ rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+}
+
+
+/*
* Add an mfc entry
*/
static int
-add_mfc(mfccp)
- struct mfcctl *mfccp;
+add_mfc(struct mfcctl *mfccp)
{
struct mfc *rt;
u_long hash;
struct rtdetq *rte;
- register u_short nstl;
+ u_short nstl;
int s;
- int i;
- MFCFIND(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr, rt);
+ rt = mfc_find(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr);
/* If an entry already exists, just update the fields */
if (rt) {
@@ -928,9 +792,7 @@ add_mfc(mfccp)
mfccp->mfcc_parent);
s = splnet();
- rt->mfc_parent = mfccp->mfcc_parent;
- for (i = 0; i < numvifs; i++)
- rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+ update_mfc_params(rt, mfccp);
splx(s);
return 0;
}
@@ -943,8 +805,8 @@ add_mfc(mfccp)
for (rt = mfctable[hash], nstl = 0; rt; rt = rt->mfc_next) {
if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
- (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&
- (rt->mfc_stall != NULL)) {
+ (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&
+ (rt->mfc_stall != NULL)) {
if (nstl++)
log(LOG_ERR, "add_mfc %s o %lx g %lx p %x dbx %p\n",
@@ -959,16 +821,7 @@ add_mfc(mfccp)
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
mfccp->mfcc_parent, (void *)rt->mfc_stall);
- rt->mfc_origin = mfccp->mfcc_origin;
- rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
- rt->mfc_parent = mfccp->mfcc_parent;
- for (i = 0; i < numvifs; i++)
- rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
- /* initialize pkt counters per src-grp */
- rt->mfc_pkt_cnt = 0;
- rt->mfc_byte_cnt = 0;
- rt->mfc_wrong_if = 0;
- rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+ init_mfc_params(rt, mfccp);
rt->mfc_expire = 0; /* Don't clean this guy up */
nexpire[hash]--;
@@ -979,9 +832,6 @@ add_mfc(mfccp)
ip_mdq(rte->m, rte->ifp, rt, -1);
m_freem(rte->m);
-#ifdef UPCALL_TIMING
- collate(&(rte->t));
-#endif /* UPCALL_TIMING */
free(rte, M_MRTABLE);
rte = n;
}
@@ -1000,48 +850,27 @@ add_mfc(mfccp)
mfccp->mfcc_parent);
for (rt = mfctable[hash]; rt != NULL; rt = rt->mfc_next) {
-
if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
- (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {
-
- rt->mfc_origin = mfccp->mfcc_origin;
- rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
- rt->mfc_parent = mfccp->mfcc_parent;
- for (i = 0; i < numvifs; i++)
- rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
- /* initialize pkt counters per src-grp */
- rt->mfc_pkt_cnt = 0;
- rt->mfc_byte_cnt = 0;
- rt->mfc_wrong_if = 0;
- rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+ (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {
+ init_mfc_params(rt, mfccp);
if (rt->mfc_expire)
nexpire[hash]--;
- rt->mfc_expire = 0;
+ rt->mfc_expire = 0;
+ break; /* XXX */
}
}
- if (rt == NULL) {
- /* no upcall, so make a new entry */
+ if (rt == NULL) { /* no upcall, so make a new entry */
rt = (struct mfc *)malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT);
if (rt == NULL) {
splx(s);
return ENOBUFS;
}
- /* insert new entry at head of hash chain */
- rt->mfc_origin = mfccp->mfcc_origin;
- rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
- rt->mfc_parent = mfccp->mfcc_parent;
- for (i = 0; i < numvifs; i++)
- rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
- /* initialize pkt counters per src-grp */
- rt->mfc_pkt_cnt = 0;
- rt->mfc_byte_cnt = 0;
- rt->mfc_wrong_if = 0;
- rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+ init_mfc_params(rt, mfccp);
rt->mfc_expire = 0;
rt->mfc_stall = NULL;
- /* link into table */
+ /* insert new entry at head of hash chain */
rt->mfc_next = mfctable[hash];
mfctable[hash] = rt;
}
@@ -1050,38 +879,11 @@ add_mfc(mfccp)
return 0;
}
-#ifdef UPCALL_TIMING
-/*
- * collect delay statistics on the upcalls
- */
-static void collate(t)
-register struct timeval *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);
-
- d = delta >> 10;
- if (d > 50)
- d = 50;
-
- ++upcall_data[d];
- }
-}
-#endif /* UPCALL_TIMING */
-
/*
* Delete an mfc entry
*/
static int
-del_mfc(mfccp)
- struct mfcctl *mfccp;
+del_mfc(struct mfcctl *mfccp)
{
struct in_addr origin;
struct in_addr mcastgrp;
@@ -1092,7 +894,6 @@ del_mfc(mfccp)
origin = mfccp->mfcc_origin;
mcastgrp = mfccp->mfcc_mcastgrp;
- hash = MFCHASH(origin.s_addr, mcastgrp.s_addr);
if (mrtdebug & DEBUG_MFC)
log(LOG_DEBUG,"del_mfc orig %lx mcastgrp %lx\n",
@@ -1100,15 +901,12 @@ del_mfc(mfccp)
s = splnet();
- nptr = &mfctable[hash];
- while ((rt = *nptr) != NULL) {
+ hash = MFCHASH(origin.s_addr, mcastgrp.s_addr);
+ for (nptr = &mfctable[hash]; (rt = *nptr) != NULL; nptr = &rt->mfc_next)
if (origin.s_addr == rt->mfc_origin.s_addr &&
- mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&
- rt->mfc_stall == NULL)
+ mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&
+ rt->mfc_stall == NULL)
break;
-
- nptr = &rt->mfc_next;
- }
if (rt == NULL) {
splx(s);
return EADDRNOTAVAIL;
@@ -1126,21 +924,16 @@ del_mfc(mfccp)
* Send a message to mrouted on the multicast routing socket
*/
static int
-socket_send(s, mm, src)
- struct socket *s;
- struct mbuf *mm;
- struct sockaddr_in *src;
+socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src)
{
- if (s) {
- if (sbappendaddr(&s->so_rcv,
- (struct sockaddr *)src,
- mm, (struct mbuf *)0) != 0) {
- sorwakeup(s);
- return 0;
- }
+ if (s) {
+ if (sbappendaddr(&s->so_rcv, (struct sockaddr *)src, mm, NULL) != 0) {
+ sorwakeup(s);
+ return 0;
}
- m_freem(mm);
- return -1;
+ }
+ m_freem(mm);
+ return -1;
}
/*
@@ -1157,20 +950,12 @@ socket_send(s, mm, src)
#define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */
static int
-X_ip_mforward(ip, ifp, m, imo)
- register struct ip *ip;
- struct ifnet *ifp;
- struct mbuf *m;
- struct ip_moptions *imo;
+X_ip_mforward(struct ip *ip, struct ifnet *ifp,
+ struct mbuf *m, struct ip_moptions *imo)
{
- register struct mfc *rt;
- register u_char *ipoptions;
- static struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
- static int srctun = 0;
- register struct mbuf *mm;
+ struct mfc *rt;
int s;
vifi_t vifi;
- struct vif *vifp;
if (mrtdebug & DEBUG_FORWARD)
log(LOG_DEBUG, "ip_mforward: src %lx, dst %lx, ifp %p\n",
@@ -1178,7 +963,7 @@ X_ip_mforward(ip, ifp, m, imo)
(void *)ifp);
if (ip->ip_hl < (sizeof(struct ip) + TUNNEL_LEN) >> 2 ||
- (ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
+ ((u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
/*
* Packet arrived via a physical interface or
* an encapsulated tunnel.
@@ -1188,68 +973,67 @@ X_ip_mforward(ip, ifp, m, imo)
* Packet arrived through a source-route tunnel.
* Source-route tunnels are no longer supported.
*/
- if ((srctun++ % 1000) == 0)
+ static int last_log;
+ if (last_log != time_second) {
+ last_log = time_second;
log(LOG_ERR,
"ip_mforward: received source-routed packet from %lx\n",
(u_long)ntohl(ip->ip_src.s_addr));
-
+ }
return 1;
}
if ((imo) && ((vifi = imo->imo_multicast_vif) < numvifs)) {
if (ip->ip_ttl < 255)
- ip->ip_ttl++; /* compensate for -1 in *_send routines */
+ ip->ip_ttl++; /* compensate for -1 in *_send routines */
if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
- vifp = viftable + vifi;
+ struct vif *vifp = viftable + vifi;
+
printf("Sending IPPROTO_RSVP from %lx to %lx on vif %d (%s%s%d)\n",
(long)ntohl(ip->ip_src.s_addr), (long)ntohl(ip->ip_dst.s_addr),
vifi,
(vifp->v_flags & VIFF_TUNNEL) ? "tunnel on " : "",
vifp->v_ifp->if_name, vifp->v_ifp->if_unit);
}
- return (ip_mdq(m, ifp, NULL, vifi));
+ return ip_mdq(m, ifp, NULL, vifi);
}
if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
printf("Warning: IPPROTO_RSVP from %lx to %lx without vif option\n",
(long)ntohl(ip->ip_src.s_addr), (long)ntohl(ip->ip_dst.s_addr));
- if(!imo)
- printf("In fact, no options were specified at all\n");
+ if (!imo)
+ printf("In fact, no options were specified at all\n");
}
/*
* Don't forward a packet with time-to-live of zero or one,
* or a packet destined to a local-only group.
*/
- if (ip->ip_ttl <= 1 ||
- ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP)
+ if (ip->ip_ttl <= 1 || ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP)
return 0;
/*
* Determine forwarding vifs from the forwarding cache table
*/
s = splnet();
- MFCFIND(ip->ip_src.s_addr, ip->ip_dst.s_addr, rt);
+ ++mrtstat.mrts_mfc_lookups;
+ rt = mfc_find(ip->ip_src.s_addr, ip->ip_dst.s_addr);
/* Entry exists, so forward if necessary */
if (rt != NULL) {
splx(s);
- return (ip_mdq(m, ifp, rt, -1));
+ return ip_mdq(m, ifp, rt, -1);
} else {
/*
* If we don't have a route for packet's origin,
- * Make a copy of the packet &
- * send message to routing daemon
+ * Make a copy of the packet & send message to routing daemon
*/
- register struct mbuf *mb0;
- register struct rtdetq *rte;
- register u_long hash;
+ struct mbuf *mb0;
+ struct rtdetq *rte;
+ u_long hash;
int hlen = ip->ip_hl << 2;
-#ifdef UPCALL_TIMING
- struct timeval tp;
- GET_TIME(tp);
-#endif
+ ++mrtstat.mrts_mfc_misses;
mrtstat.mrts_no_route++;
if (mrtdebug & (DEBUG_FORWARD | DEBUG_MFC))
@@ -1276,55 +1060,60 @@ X_ip_mforward(ip, ifp, m, imo)
return ENOBUFS;
}
- /* is there an upcall waiting for this packet? */
+ /* is there an upcall waiting for this flow ? */
hash = MFCHASH(ip->ip_src.s_addr, ip->ip_dst.s_addr);
for (rt = mfctable[hash]; rt; rt = rt->mfc_next) {
if ((ip->ip_src.s_addr == rt->mfc_origin.s_addr) &&
- (ip->ip_dst.s_addr == rt->mfc_mcastgrp.s_addr) &&
- (rt->mfc_stall != NULL))
+ (ip->ip_dst.s_addr == rt->mfc_mcastgrp.s_addr) &&
+ (rt->mfc_stall != NULL))
break;
}
if (rt == NULL) {
int i;
struct igmpmsg *im;
+ struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
+ struct mbuf *mm;
+
+ /*
+ * Locate the vifi for the incoming interface for this packet.
+ * If none found, drop packet.
+ */
+ for (vifi=0; vifi<numvifs && viftable[vifi].v_ifp != ifp; vifi++)
+ ;
+ if (vifi >= numvifs) /* vif not found, drop packet */
+ goto non_fatal;
/* no upcall, so make a new entry */
rt = (struct mfc *)malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT);
- if (rt == NULL) {
- free(rte, M_MRTABLE);
- m_freem(mb0);
- splx(s);
- return ENOBUFS;
- }
+ if (rt == NULL)
+ goto fail;
/* Make a copy of the header to send to the user level process */
mm = m_copy(mb0, 0, hlen);
- if (mm == NULL) {
- free(rte, M_MRTABLE);
- m_freem(mb0);
- free(rt, M_MRTABLE);
- splx(s);
- return ENOBUFS;
- }
+ if (mm == NULL)
+ goto fail1;
/*
* Send message to routing daemon to install
* a route into the kernel table
*/
- k_igmpsrc.sin_addr = ip->ip_src;
im = mtod(mm, struct igmpmsg *);
- im->im_msgtype = IGMPMSG_NOCACHE;
- im->im_mbz = 0;
+ im->im_msgtype = IGMPMSG_NOCACHE;
+ im->im_mbz = 0;
+ im->im_vif = vifi;
mrtstat.mrts_upcalls++;
+ k_igmpsrc.sin_addr = ip->ip_src;
if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) {
log(LOG_WARNING, "ip_mforward: ip_mrouter socket queue full\n");
++mrtstat.mrts_upq_sockfull;
+fail1:
+ free(rt, M_MRTABLE);
+fail:
free(rte, M_MRTABLE);
m_freem(mb0);
- free(rt, M_MRTABLE);
splx(s);
return ENOBUFS;
}
@@ -1348,11 +1137,17 @@ X_ip_mforward(ip, ifp, m, imo)
int npkts = 0;
struct rtdetq **p;
+ /*
+ * XXX ouch! we need to append to the list, but we
+ * only have a pointer to the front, so we have to
+ * scan the entire list every time.
+ */
for (p = &rt->mfc_stall; *p != NULL; p = &(*p)->next)
npkts++;
if (npkts > MAX_UPQ) {
mrtstat.mrts_upq_ovflw++;
+non_fatal:
free(rte, M_MRTABLE);
m_freem(mb0);
splx(s);
@@ -1365,9 +1160,6 @@ X_ip_mforward(ip, ifp, m, imo)
rte->m = mb0;
rte->ifp = ifp;
-#ifdef UPCALL_TIMING
- rte->t = tp;
-#endif
rte->next = NULL;
splx(s);
@@ -1376,11 +1168,6 @@ X_ip_mforward(ip, ifp, m, imo)
}
}
-#ifndef MROUTE_KLD
-int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
- struct ip_moptions *) = X_ip_mforward;
-#endif
-
/*
* Clean up the cache entry if upcall is not serviced
*/
@@ -1403,9 +1190,8 @@ expire_upcalls(void *unused)
* Make sure it wasn't marked to not expire (shouldn't happen)
* If it expires now
*/
- if (mfc->mfc_stall != NULL &&
- mfc->mfc_expire != 0 &&
- --mfc->mfc_expire == 0) {
+ if (mfc->mfc_stall != NULL && mfc->mfc_expire != 0 &&
+ --mfc->mfc_expire == 0) {
if (mrtdebug & DEBUG_EXPIRE)
log(LOG_DEBUG, "expire_upcalls: expiring (%lx %lx)\n",
(u_long)ntohl(mfc->mfc_origin.s_addr),
@@ -1432,23 +1218,18 @@ expire_upcalls(void *unused)
}
}
splx(s);
- expire_upcalls_ch = timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+ expire_upcalls_ch = timeout(expire_upcalls, NULL, EXPIRE_TIMEOUT);
}
/*
* Packet forwarding routine once entry in the cache is made
*/
static int
-ip_mdq(m, ifp, rt, xmt_vif)
- register struct mbuf *m;
- register struct ifnet *ifp;
- register struct mfc *rt;
- register vifi_t xmt_vif;
+ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
{
- register struct ip *ip = mtod(m, struct ip *);
- register vifi_t vifi;
- register struct vif *vifp;
- register int plen = ip->ip_len;
+ struct ip *ip = mtod(m, struct ip *);
+ vifi_t vifi;
+ int plen = ip->ip_len;
/*
* Macro to send packet on vif. Since RSVP packets don't get counted on
@@ -1491,24 +1272,23 @@ ip_mdq(m, ifp, rt, xmt_vif)
if (pim_assert && rt->mfc_ttls[vifi] &&
(ifp->if_flags & IFF_BROADCAST) &&
!(viftable[vifi].v_flags & VIFF_TUNNEL)) {
- struct sockaddr_in k_igmpsrc;
- struct mbuf *mm;
- struct igmpmsg *im;
- int hlen = ip->ip_hl << 2;
struct timeval now;
- register u_long delta;
+ u_long delta;
GET_TIME(now);
TV_DELTA(rt->mfc_last_assert, now, delta);
if (delta > ASSERT_MSG_TIME) {
- mm = m_copy(m, 0, hlen);
+ struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
+ struct igmpmsg *im;
+ int hlen = ip->ip_hl << 2;
+ struct mbuf *mm = m_copy(m, 0, hlen);
+
if (mm && (M_HASCL(mm) || mm->m_len < hlen))
mm = m_pullup(mm, hlen);
- if (mm == NULL) {
+ if (mm == NULL)
return ENOBUFS;
- }
rt->mfc_last_assert = now;
@@ -1519,7 +1299,12 @@ ip_mdq(m, ifp, rt, xmt_vif)
k_igmpsrc.sin_addr = im->im_src;
- socket_send(ip_mrouter, mm, &k_igmpsrc);
+ if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) {
+ log(LOG_WARNING,
+ "ip_mforward: ip_mrouter socket queue full\n");
+ ++mrtstat.mrts_upq_sockfull;
+ return ENOBUFS;
+ }
}
}
return 0;
@@ -1542,41 +1327,30 @@ ip_mdq(m, ifp, rt, xmt_vif)
* - the ttl exceeds the vif's threshold
* - there are group members downstream on interface
*/
- for (vifp = viftable, vifi = 0; vifi < numvifs; vifp++, vifi++)
- if ((rt->mfc_ttls[vifi] > 0) &&
- (ip->ip_ttl > rt->mfc_ttls[vifi])) {
- vifp->v_pkt_out++;
- vifp->v_bytes_out += plen;
- MC_SEND(ip, vifp, m);
+ for (vifi = 0; vifi < numvifs; vifi++)
+ if ((rt->mfc_ttls[vifi] > 0) && (ip->ip_ttl > rt->mfc_ttls[vifi])) {
+ viftable[vifi].v_pkt_out++;
+ viftable[vifi].v_bytes_out += plen;
+ MC_SEND(ip, viftable+vifi, m);
}
return 0;
}
/*
- * check if a vif number is legal/ok. This is used by ip_output, to export
- * numvifs there,
+ * check if a vif number is legal/ok. This is used by ip_output.
*/
static int
-X_legal_vif_num(vif)
- int vif;
+X_legal_vif_num(int vif)
{
- if (vif >= 0 && vif < numvifs)
- return(1);
- else
- return(0);
+ return (vif >= 0 && vif < numvifs);
}
-#ifndef MROUTE_KLD
-int (*legal_vif_num)(int) = X_legal_vif_num;
-#endif
-
/*
* Return the local address used by this vif
*/
static u_long
-X_ip_mcast_src(vifi)
- int vifi;
+X_ip_mcast_src(int vifi)
{
if (vifi >= 0 && vifi < numvifs)
return viftable[vifi].v_lcl_addr.s_addr;
@@ -1584,18 +1358,11 @@ X_ip_mcast_src(vifi)
return INADDR_ANY;
}
-#ifndef MROUTE_KLD
-u_long (*ip_mcast_src)(int) = X_ip_mcast_src;
-#endif
-
static void
-phyint_send(ip, vifp, m)
- struct ip *ip;
- struct vif *vifp;
- struct mbuf *m;
+phyint_send(struct ip *ip, struct vif *vifp, struct mbuf *m)
{
- register struct mbuf *mb_copy;
- register int hlen = ip->ip_hl << 2;
+ struct mbuf *mb_copy;
+ int hlen = ip->ip_hl << 2;
/*
* Make a new reference to the packet; make sure that
@@ -1615,14 +1382,21 @@ phyint_send(ip, vifp, m)
}
static void
-encap_send(ip, vifp, m)
- register struct ip *ip;
- register struct vif *vifp;
- register struct mbuf *m;
+encap_send(struct ip *ip, struct vif *vifp, struct mbuf *m)
{
- register struct mbuf *mb_copy;
- register struct ip *ip_copy;
- register int i, len = ip->ip_len;
+ struct mbuf *mb_copy;
+ struct ip *ip_copy;
+ int i, len = ip->ip_len;
+
+ /*
+ * XXX: take care of delayed checksums.
+ * XXX: if network interfaces are capable of computing checksum for
+ * encapsulated multicast data packets, we need to reconsider this.
+ */
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ in_delayed_cksum(m);
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ }
/*
* copy the old packet & pullup its IP header into the
@@ -1687,16 +1461,11 @@ encap_send(ip, vifp, m)
*/
static void
-tbf_control(vifp, m, ip, p_len)
- register struct vif *vifp;
- register struct mbuf *m;
- register struct ip *ip;
- register u_long p_len;
+tbf_control(struct vif *vifp, struct mbuf *m, struct ip *ip, u_long p_len)
{
- register struct tbf *t = vifp->v_tbf;
+ struct tbf *t = vifp->v_tbf;
- if (p_len > MAX_BKT_SIZE) {
- /* drop if packet is too large */
+ if (p_len > MAX_BKT_SIZE) { /* drop if packet is too large */
mrtstat.mrts_pkt2large++;
m_freem(m);
return;
@@ -1704,18 +1473,11 @@ tbf_control(vifp, m, ip, p_len)
tbf_update_tokens(vifp);
- /* if there are enough tokens,
- * and the queue is empty,
- * send this packet out
- */
-
- if (t->tbf_q_len == 0) {
- /* queue empty, send packet if enough tokens */
- if (p_len <= t->tbf_n_tok) {
+ if (t->tbf_q_len == 0) { /* queue empty... */
+ if (p_len <= t->tbf_n_tok) { /* send packet if enough tokens */
t->tbf_n_tok -= p_len;
tbf_send_packet(vifp, m);
- } else {
- /* queue packet and timeout till later */
+ } else { /* no, queue packet and try later */
tbf_queue(vifp, m);
timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
}
@@ -1724,40 +1486,32 @@ tbf_control(vifp, m, ip, p_len)
tbf_queue(vifp, m);
tbf_process_q(vifp);
} else {
- /* queue length too much, try to dq and queue and process */
+ /* queue full, try to dq and queue and process */
if (!tbf_dq_sel(vifp, ip)) {
mrtstat.mrts_q_overflow++;
m_freem(m);
- return;
} else {
tbf_queue(vifp, m);
tbf_process_q(vifp);
}
}
- return;
}
/*
* adds a packet to the queue at the interface
*/
static void
-tbf_queue(vifp, m)
- register struct vif *vifp;
- register struct mbuf *m;
+tbf_queue(struct vif *vifp, struct mbuf *m)
{
- register int s = splnet();
- register struct tbf *t = vifp->v_tbf;
+ int s = splnet();
+ struct tbf *t = vifp->v_tbf;
- if (t->tbf_t == NULL) {
- /* Queue was empty */
+ if (t->tbf_t == NULL) /* Queue was empty */
t->tbf_q = m;
- } else {
- /* Insert at tail */
+ else /* Insert at tail */
t->tbf_t->m_act = m;
- }
- /* Set new tail pointer */
- t->tbf_t = m;
+ t->tbf_t = m; /* Set new tail pointer */
#ifdef DIAGNOSTIC
/* Make sure we didn't get fed a bogus mbuf */
@@ -1771,59 +1525,47 @@ tbf_queue(vifp, m)
splx(s);
}
-
/*
* processes the queue at the interface
*/
static void
-tbf_process_q(vifp)
- register struct vif *vifp;
+tbf_process_q(struct vif *vifp)
{
- register struct mbuf *m;
- register int len;
- register int s = splnet();
- register struct tbf *t = vifp->v_tbf;
+ int s = splnet();
+ struct tbf *t = vifp->v_tbf;
/* loop through the queue at the interface and send as many packets
* as possible
*/
while (t->tbf_q_len > 0) {
- m = t->tbf_q;
-
- len = mtod(m, struct ip *)->ip_len;
+ struct mbuf *m = t->tbf_q;
+ int len = mtod(m, struct ip *)->ip_len;
/* determine if the packet can be sent */
- if (len <= t->tbf_n_tok) {
- /* if so,
- * reduce no of tokens, dequeue the packet,
- * send the packet.
- */
- t->tbf_n_tok -= len;
+ if (len > t->tbf_n_tok) /* not enough tokens, we are done */
+ break;
+ /* ok, reduce no of tokens, dequeue and send the packet. */
+ t->tbf_n_tok -= len;
- t->tbf_q = m->m_act;
- if (--t->tbf_q_len == 0)
- t->tbf_t = NULL;
+ t->tbf_q = m->m_act;
+ if (--t->tbf_q_len == 0)
+ t->tbf_t = NULL;
- m->m_act = NULL;
- tbf_send_packet(vifp, m);
-
- } else break;
+ m->m_act = NULL;
+ tbf_send_packet(vifp, m);
}
splx(s);
}
static void
-tbf_reprocess_q(xvifp)
- void *xvifp;
+tbf_reprocess_q(void *xvifp)
{
- register struct vif *vifp = xvifp;
+ struct vif *vifp = xvifp;
+
if (ip_mrouter == NULL)
return;
-
tbf_update_tokens(vifp);
-
tbf_process_q(vifp);
-
if (vifp->v_tbf->tbf_q_len)
timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
}
@@ -1832,15 +1574,13 @@ tbf_reprocess_q(xvifp)
* based on the precedence value and the priority
*/
static int
-tbf_dq_sel(vifp, ip)
- register struct vif *vifp;
- register struct ip *ip;
+tbf_dq_sel(struct vif *vifp, struct ip *ip)
{
- register int s = splnet();
- register u_int p;
- register struct mbuf *m, *last;
- register struct mbuf **np;
- register struct tbf *t = vifp->v_tbf;
+ int s = splnet();
+ u_int p;
+ struct mbuf *m, *last;
+ struct mbuf **np;
+ struct tbf *t = vifp->v_tbf;
p = priority(vifp, ip);
@@ -1853,36 +1593,32 @@ tbf_dq_sel(vifp, ip)
if (m == t->tbf_t)
t->tbf_t = last;
m_freem(m);
- /* it's impossible for the queue to be empty, but
- * we check anyway. */
+ /* It's impossible for the queue to be empty, but check anyways. */
if (--t->tbf_q_len == 0)
t->tbf_t = NULL;
splx(s);
mrtstat.mrts_drop_sel++;
- return(1);
+ return 1;
}
np = &m->m_act;
last = m;
}
splx(s);
- return(0);
+ return 0;
}
static void
-tbf_send_packet(vifp, m)
- register struct vif *vifp;
- register struct mbuf *m;
+tbf_send_packet(struct vif *vifp, struct mbuf *m)
{
- struct ip_moptions imo;
- int error;
- static struct route ro;
int s = splnet();
- if (vifp->v_flags & VIFF_TUNNEL) {
- /* If tunnel options */
- ip_output(m, (struct mbuf *)0, &vifp->v_route,
- IP_FORWARDING, (struct ip_moptions *)0, NULL);
- } else {
+ if (vifp->v_flags & VIFF_TUNNEL) /* If tunnel options */
+ ip_output(m, NULL, &vifp->v_route, IP_FORWARDING, NULL, NULL);
+ else {
+ struct ip_moptions imo;
+ int error;
+ static struct route ro; /* XXX check this */
+
imo.imo_multicast_ifp = vifp->v_ifp;
imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1;
imo.imo_multicast_loop = 1;
@@ -1894,8 +1630,7 @@ tbf_send_packet(vifp, m)
* should get rejected because they appear to come from
* the loopback interface, thus preventing looping.
*/
- error = ip_output(m, (struct mbuf *)0, &ro,
- IP_FORWARDING, &imo, NULL);
+ error = ip_output(m, NULL, &ro, IP_FORWARDING, &imo, NULL);
if (mrtdebug & DEBUG_XMIT)
log(LOG_DEBUG, "phyint_send on vif %d err %d\n",
@@ -1909,13 +1644,12 @@ tbf_send_packet(vifp, m)
* in milliseconds & update the no. of tokens in the bucket
*/
static void
-tbf_update_tokens(vifp)
- register struct vif *vifp;
+tbf_update_tokens(struct vif *vifp)
{
struct timeval tp;
- register u_long tm;
- register int s = splnet();
- register struct tbf *t = vifp->v_tbf;
+ u_long tm;
+ int s = splnet();
+ struct tbf *t = vifp->v_tbf;
GET_TIME(tp);
@@ -1940,11 +1674,9 @@ tbf_update_tokens(vifp)
}
static int
-priority(vifp, ip)
- register struct vif *vifp;
- register struct ip *ip;
+priority(struct vif *vifp, struct ip *ip)
{
- register int prio;
+ int prio = 50; /* the lowest priority -- default case */
/* temporary hack; may add general packet classifier some day */
@@ -1954,27 +1686,22 @@ priority(vifp, ip)
* [16384, 32768) : audio - highest priority
* [32768, 49152) : whiteboard - medium priority
* [49152, 65536) : video - low priority
+ *
+ * Everything else gets lowest priority.
*/
if (ip->ip_p == IPPROTO_UDP) {
struct udphdr *udp = (struct udphdr *)(((char *)ip) + (ip->ip_hl << 2));
switch (ntohs(udp->uh_dport) & 0xc000) {
- case 0x4000:
- prio = 70;
- break;
- case 0x8000:
- prio = 60;
- break;
- case 0xc000:
- prio = 55;
- break;
- default:
- prio = 50;
- break;
+ case 0x4000:
+ prio = 70;
+ break;
+ case 0x8000:
+ prio = 60;
+ break;
+ case 0xc000:
+ prio = 55;
+ break;
}
- if (tbfdebug > 1)
- log(LOG_DEBUG, "port %x prio%d\n", ntohs(udp->uh_dport), prio);
- } else {
- prio = 50;
}
return prio;
}
@@ -1983,111 +1710,65 @@ priority(vifp, ip)
* End of token bucket filter modifications
*/
-int
-ip_rsvp_vif_init(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
+static int
+X_ip_rsvp_vif(struct socket *so, struct sockopt *sopt)
{
- int error, i, s;
-
- if (rsvpdebug)
- printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n",
- so->so_type, so->so_proto->pr_protocol);
+ int error, vifi, s;
if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
return EOPNOTSUPP;
- /* Check mbuf. */
- error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
+ error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
if (error)
- return (error);
-
- if (rsvpdebug)
- printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n", i, rsvp_on);
+ return error;
s = splnet();
- /* Check vif. */
- if (!legal_vif_num(i)) {
+ if (vifi < 0 || vifi >= numvifs) { /* Error if vif is invalid */
splx(s);
return EADDRNOTAVAIL;
}
- /* Check if socket is available. */
- if (viftable[i].v_rsvpd != NULL) {
- splx(s);
- return EADDRINUSE;
- }
-
- viftable[i].v_rsvpd = so;
- /* This may seem silly, but we need to be sure we don't over-increment
- * the RSVP counter, in case something slips up.
- */
- if (!viftable[i].v_rsvp_on) {
- viftable[i].v_rsvp_on = 1;
- rsvp_on++;
- }
-
- splx(s);
- return 0;
-}
-
-int
-ip_rsvp_vif_done(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- int error, i, s;
-
- if (rsvpdebug)
- printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
- so->so_type, so->so_proto->pr_protocol);
-
- if (so->so_type != SOCK_RAW ||
- so->so_proto->pr_protocol != IPPROTO_RSVP)
- return EOPNOTSUPP;
-
- error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
- if (error)
- return (error);
-
- s = splnet();
-
- /* Check vif. */
- if (!legal_vif_num(i)) {
- splx(s);
- return EADDRNOTAVAIL;
+ if (sopt->sopt_name == IP_RSVP_VIF_ON) {
+ /* Check if socket is available. */
+ if (viftable[vifi].v_rsvpd != NULL) {
+ splx(s);
+ return EADDRINUSE;
}
- if (rsvpdebug)
- printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
- viftable[i].v_rsvpd, so);
-
+ viftable[vifi].v_rsvpd = so;
+ /* This may seem silly, but we need to be sure we don't over-increment
+ * the RSVP counter, in case something slips up.
+ */
+ if (!viftable[vifi].v_rsvp_on) {
+ viftable[vifi].v_rsvp_on = 1;
+ rsvp_on++;
+ }
+ } else { /* must be VIF_OFF */
/*
* XXX as an additional consistency check, one could make sure
- * that viftable[i].v_rsvpd == so, otherwise passing so as
+ * that viftable[vifi].v_rsvpd == so, otherwise passing so as
* first parameter is pretty useless.
*/
- viftable[i].v_rsvpd = NULL;
+ viftable[vifi].v_rsvpd = NULL;
/*
* This may seem silly, but we need to be sure we don't over-decrement
* the RSVP counter, in case something slips up.
*/
- if (viftable[i].v_rsvp_on) {
- viftable[i].v_rsvp_on = 0;
- rsvp_on--;
+ if (viftable[vifi].v_rsvp_on) {
+ viftable[vifi].v_rsvp_on = 0;
+ rsvp_on--;
}
-
- splx(s);
- return 0;
+ }
+ splx(s);
+ return 0;
}
-void
-ip_rsvp_force_done(so)
- struct socket *so;
+static void
+X_ip_rsvp_force_done(struct socket *so)
{
int vifi;
- register int s;
+ int s;
/* Don't bother if it is not the right type of socket. */
if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
@@ -2112,18 +1793,15 @@ ip_rsvp_force_done(so)
}
splx(s);
- return;
}
-void
-rsvp_input(m, off)
- struct mbuf *m;
- int off;
+static void
+X_rsvp_input(struct mbuf *m, int off)
{
int vifi;
- register struct ip *ip = mtod(m, struct ip *);
- static struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET };
- register int s;
+ struct ip *ip = mtod(m, struct ip *);
+ struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET };
+ int s;
struct ifnet *ifp;
if (rsvpdebug)
@@ -2145,7 +1823,7 @@ rsvp_input(m, off)
#ifdef DIAGNOSTIC
if (!(m->m_flags & M_PKTHDR))
- panic("rsvp_input no hdr");
+ panic("rsvp_input no hdr");
#endif
ifp = m->m_pkthdr.rcvif;
@@ -2191,72 +1869,52 @@ rsvp_input(m, off)
splx(s);
}
-#ifdef MROUTE_KLD
-
static int
ip_mroute_modevent(module_t mod, int type, void *unused)
{
- int s;
-
- switch (type) {
- static u_long (*old_ip_mcast_src)(int);
- static int (*old_ip_mrouter_set)(struct socket *,
- struct sockopt *);
- static int (*old_ip_mrouter_get)(struct socket *,
- struct sockopt *);
- static int (*old_ip_mrouter_done)(void);
- static int (*old_ip_mforward)(struct ip *, struct ifnet *,
- struct mbuf *, struct ip_moptions *);
- static int (*old_mrt_ioctl)(int, caddr_t);
- static int (*old_legal_vif_num)(int);
-
- case MOD_LOAD:
- s = splnet();
- /* XXX Protect against multiple loading */
- old_ip_mcast_src = ip_mcast_src;
- ip_mcast_src = X_ip_mcast_src;
- old_ip_mrouter_get = ip_mrouter_get;
- ip_mrouter_get = X_ip_mrouter_get;
- old_ip_mrouter_set = ip_mrouter_set;
- ip_mrouter_set = X_ip_mrouter_set;
- old_ip_mrouter_done = ip_mrouter_done;
- ip_mrouter_done = X_ip_mrouter_done;
- old_ip_mforward = ip_mforward;
- ip_mforward = X_ip_mforward;
- old_mrt_ioctl = mrt_ioctl;
- mrt_ioctl = X_mrt_ioctl;
- old_legal_vif_num = legal_vif_num;
- legal_vif_num = X_legal_vif_num;
+ int s;
- splx(s);
- return 0;
+ switch (type) {
+ case MOD_LOAD:
+ s = splnet();
+ /* XXX Protect against multiple loading */
+ ip_mcast_src = X_ip_mcast_src;
+ ip_mforward = X_ip_mforward;
+ ip_mrouter_done = X_ip_mrouter_done;
+ ip_mrouter_get = X_ip_mrouter_get;
+ ip_mrouter_set = X_ip_mrouter_set;
+ ip_rsvp_force_done = X_ip_rsvp_force_done;
+ ip_rsvp_vif = X_ip_rsvp_vif;
+ legal_vif_num = X_legal_vif_num;
+ mrt_ioctl = X_mrt_ioctl;
+ rsvp_input_p = X_rsvp_input;
+ splx(s);
+ break;
- case MOD_UNLOAD:
- if (ip_mrouter)
- return EINVAL;
-
- s = splnet();
- ip_mrouter_get = old_ip_mrouter_get;
- ip_mrouter_set = old_ip_mrouter_set;
- ip_mrouter_done = old_ip_mrouter_done;
- ip_mforward = old_ip_mforward;
- mrt_ioctl = old_mrt_ioctl;
- legal_vif_num = old_legal_vif_num;
- splx(s);
- return 0;
+ case MOD_UNLOAD:
+ if (ip_mrouter)
+ return EINVAL;
- default:
- break;
- }
- return 0;
+ s = splnet();
+ ip_mcast_src = NULL;
+ ip_mforward = NULL;
+ ip_mrouter_done = NULL;
+ ip_mrouter_get = NULL;
+ ip_mrouter_set = NULL;
+ ip_rsvp_force_done = NULL;
+ ip_rsvp_vif = NULL;
+ legal_vif_num = NULL;
+ mrt_ioctl = NULL;
+ rsvp_input_p = NULL;
+ splx(s);
+ break;
+ }
+ return 0;
}
static moduledata_t ip_mroutemod = {
- "ip_mroute",
- ip_mroute_modevent,
- 0
+ "ip_mroute",
+ ip_mroute_modevent,
+ 0
};
DECLARE_MODULE(ip_mroute, ip_mroutemod, SI_SUB_PSEUDO, SI_ORDER_ANY);
-
-#endif /* MROUTE_KLD */
-#endif /* MROUTING */
diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h
index 0e61652..1045ebb 100644
--- a/sys/netinet/ip_mroute.h
+++ b/sys/netinet/ip_mroute.h
@@ -215,9 +215,6 @@ struct rtdetq {
struct mbuf *m; /* A copy of the packet */
struct ifnet *ifp; /* Interface pkt came in on */
vifi_t xmt_vif; /* Saved copy of imo_multicast_vif */
-#ifdef UPCALL_TIMING
- struct timeval t; /* Timestamp */
-#endif /* UPCALL_TIMING */
struct rtdetq *next; /* Next in list of packets */
};
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 44212ca..4c19090 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -325,7 +325,9 @@ ip_output(m0, opt, ro, flags, imo, inp)
ip->ip_ttl = imo->imo_multicast_ttl;
if (imo->imo_multicast_vif != -1)
ip->ip_src.s_addr =
- ip_mcast_src(imo->imo_multicast_vif);
+ ip_mcast_src ?
+ ip_mcast_src(imo->imo_multicast_vif) :
+ INADDR_ANY;
} else
ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
/*
@@ -385,14 +387,15 @@ ip_output(m0, opt, ro, flags, imo, inp)
*/
if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
/*
- * Check if rsvp daemon is running. If not, don't
+ * If rsvp daemon is not running, do not
* set ip_moptions. This ensures that the packet
* is multicast and not just sent down one link
* as prescribed by rsvpd.
*/
if (!rsvp_on)
- imo = NULL;
- if (ip_mforward(ip, ifp, m, imo) != 0) {
+ imo = NULL;
+ if (ip_mforward &&
+ ip_mforward(ip, ifp, m, imo) != 0) {
m_freem(m);
goto done;
}
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 5e821eb..c03c446 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -191,9 +191,10 @@ void ipip_input(struct mbuf *, int);
void rsvp_input(struct mbuf *, int);
int ip_rsvp_init(struct socket *);
int ip_rsvp_done(void);
-int ip_rsvp_vif_init(struct socket *, struct sockopt *);
-int ip_rsvp_vif_done(struct socket *, struct sockopt *);
-void ip_rsvp_force_done(struct socket *);
+extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
+extern void (*ip_rsvp_force_done)(struct socket *);
+extern void (*rsvp_input_p)(struct mbuf *m, int off);
+
#ifdef IPDIVERT
void div_init(void);
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index f435d97..8599a1b 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -86,6 +86,28 @@ ip_fw_ctl_t *ip_fw_ctl_ptr;
ip_dn_ctl_t *ip_dn_ctl_ptr;
/*
+ * hooks for multicast routing. They all default to NULL,
+ * so leave them not initialized and rely on BSS being set to 0.
+ */
+
+/* The socket used to communicate with the multicast routing daemon. */
+struct socket *ip_mrouter;
+
+/* The various mrouter and rsvp functions */
+int (*ip_mrouter_set)(struct socket *, struct sockopt *);
+int (*ip_mrouter_get)(struct socket *, struct sockopt *);
+int (*ip_mrouter_done)(void);
+int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
+ struct ip_moptions *);
+int (*mrt_ioctl)(int, caddr_t);
+int (*legal_vif_num)(int);
+u_long (*ip_mcast_src)(int);
+
+void (*rsvp_input_p)(struct mbuf *m, int off);
+int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
+void (*ip_rsvp_force_done)(struct socket *);
+
+/*
* Nominal space allocated to a raw ip socket.
*/
#define RIPSNDQ 8192
@@ -351,7 +373,8 @@ rip_ctloutput(so, sopt)
case MRT_DEL_MFC:
case MRT_VERSION:
case MRT_ASSERT:
- error = ip_mrouter_get(so, sopt);
+ error = ip_mrouter_get ? ip_mrouter_get(so, sopt) :
+ EOPNOTSUPP;
break;
default:
@@ -401,13 +424,10 @@ rip_ctloutput(so, sopt)
error = ip_rsvp_done();
break;
- /* XXX - should be combined */
case IP_RSVP_VIF_ON:
- error = ip_rsvp_vif_init(so, sopt);
- break;
-
case IP_RSVP_VIF_OFF:
- error = ip_rsvp_vif_done(so, sopt);
+ error = ip_rsvp_vif ?
+ ip_rsvp_vif(so, sopt) : EINVAL;
break;
case MRT_INIT:
@@ -418,7 +438,8 @@ rip_ctloutput(so, sopt)
case MRT_DEL_MFC:
case MRT_VERSION:
case MRT_ASSERT:
- error = ip_mrouter_set(so, sopt);
+ error = ip_mrouter_set ? ip_mrouter_set(so, sopt) :
+ EOPNOTSUPP;
break;
default:
@@ -546,9 +567,10 @@ rip_detach(struct socket *so)
inp = sotoinpcb(so);
if (inp == 0)
panic("rip_detach");
- if (so == ip_mrouter)
+ if (so == ip_mrouter && ip_mrouter_done)
ip_mrouter_done();
- ip_rsvp_force_done(so);
+ if (ip_rsvp_force_done)
+ ip_rsvp_force_done(so);
if (so == ip_rsvpd)
ip_rsvp_done();
in_pcbdetach(inp);
OpenPOWER on IntegriCloud