summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>1999-01-18 02:06:59 +0000
committerfenner <fenner@FreeBSD.org>1999-01-18 02:06:59 +0000
commitc9e9dccbb7e008df4c1d1904f54554e6220f0616 (patch)
tree48cd7336425d82ac58905563ccc1b69e56252f3b /sys/netinet
parent331c793e6579b70b11e5fc3881c8aba6bd917ebb (diff)
downloadFreeBSD-src-c9e9dccbb7e008df4c1d1904f54554e6220f0616.zip
FreeBSD-src-c9e9dccbb7e008df4c1d1904f54554e6220f0616.tar.gz
Use dynamic memory allocation instead of mbuf's for multicast routing
state. Note: this requires a recompilation of netstat (but netstat has been broken since rev 1.52 of ip_mroute.c anyway) Obtained from: Significantly based on Steve McCanne's <mccanne@cs.berkeley.edu> work for BSD/OS
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_mroute.c184
-rw-r--r--sys/netinet/ip_mroute.h5
2 files changed, 86 insertions, 103 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index ebc7a6e..65bfecf 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -9,13 +9,14 @@
* Modified by Bill Fenner, PARC, April 1995
*
* MROUTING Revision: 3.5
- * $Id: ip_mroute.c,v 1.51 1998/12/16 18:07:11 fenner Exp $
+ * $Id: ip_mroute.c,v 1.52 1999/01/12 12:16:50 eivind Exp $
*/
#include "opt_mrouting.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -185,7 +186,7 @@ ip_rsvp_force_done(so)
#define same(a1, a2) \
(bcmp((caddr_t)(a1), (caddr_t)(a2), INSIZ) == 0)
-#define MT_MRTABLE MT_RTABLE /* since nothing else uses it */
+static MALLOC_DEFINE(M_MRTABLE, "mroutetbl", "multicast routing tables");
/*
* Globals. All but ip_mrouter and ip_mrtproto could be static,
@@ -203,7 +204,7 @@ static int ip_mrtproto;
#define NO_RTE_FOUND 0x1
#define RTE_FOUND 0x2
-static struct mbuf *mfctable[MFCTBLSIZ];
+static struct mfc *mfctable[MFCTBLSIZ];
static u_char nexpire[MFCTBLSIZ];
static struct vif viftable[MAXVIFS];
static u_int mrtdebug = 0; /* debug level */
@@ -321,19 +322,17 @@ static int pim_assert;
*/
#define MFCFIND(o, g, rt) { \
- register struct mbuf *_mb_rt = mfctable[MFCHASH(o,g)]; \
- register struct mfc *_rt = NULL; \
+ register struct mfc *_rt = mfctable[MFCHASH(o,g)]; \
rt = NULL; \
++mrtstat.mrts_mfc_lookups; \
- while (_mb_rt) { \
- _rt = mtod(_mb_rt, struct mfc *); \
+ while (_rt) { \
if ((_rt->mfc_origin.s_addr == o) && \
(_rt->mfc_mcastgrp.s_addr == g) && \
- (_mb_rt->m_act == NULL)) { \
+ (_rt->mfc_stall == NULL)) { \
rt = _rt; \
break; \
} \
- _mb_rt = _mb_rt->m_next; \
+ _rt = _rt->mfc_next; \
} \
if (rt == NULL) { \
++mrtstat.mrts_mfc_misses; \
@@ -591,8 +590,7 @@ X_ip_mrouter_done()
int i;
struct ifnet *ifp;
struct ifreq ifr;
- struct mbuf *mb_rt;
- struct mbuf *m;
+ struct mfc *rt;
struct rtdetq *rte;
int s;
@@ -623,18 +621,18 @@ X_ip_mrouter_done()
* Free all multicast forwarding cache entries.
*/
for (i = 0; i < MFCTBLSIZ; i++) {
- mb_rt = mfctable[i];
- while (mb_rt) {
- if (mb_rt->m_act != NULL) {
- while (mb_rt->m_act) {
- m = mb_rt->m_act;
- mb_rt->m_act = m->m_act;
- rte = mtod(m, struct rtdetq *);
- m_freem(rte->m);
- m_free(m);
- }
+ for (rt = mfctable[i]; rt != NULL; ) {
+ struct mfc *nr = rt->mfc_next;
+
+ for (rte = rt->mfc_stall; rte != NULL; ) {
+ struct rtdetq *n = rte->next;
+
+ m_freem(rte->m);
+ free(rte, M_MRTABLE);
+ rte = n;
}
- mb_rt = m_free(mb_rt);
+ free(rt, M_MRTABLE);
+ rt = nr;
}
}
@@ -840,9 +838,7 @@ add_mfc(mfccp)
struct mfcctl *mfccp;
{
struct mfc *rt;
- register struct mbuf *mb_rt;
u_long hash;
- struct mbuf *mb_ntry;
struct rtdetq *rte;
register u_short nstl;
int s;
@@ -871,25 +867,24 @@ add_mfc(mfccp)
*/
s = splnet();
hash = MFCHASH(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr);
- for (mb_rt = mfctable[hash], nstl = 0; mb_rt; mb_rt = mb_rt->m_next) {
+ for (rt = mfctable[hash], nstl = 0; rt; rt = rt->mfc_next) {
- rt = mtod(mb_rt, struct mfc *);
if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
(rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&
- (mb_rt->m_act != NULL)) {
+ (rt->mfc_stall != NULL)) {
if (nstl++)
log(LOG_ERR, "add_mfc %s o %lx g %lx p %x dbx %p\n",
"multiple kernel entries",
(u_long)ntohl(mfccp->mfcc_origin.s_addr),
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
- mfccp->mfcc_parent, (void *)mb_rt->m_act);
+ mfccp->mfcc_parent, (void *)rt->mfc_stall);
if (mrtdebug & DEBUG_MFC)
log(LOG_DEBUG,"add_mfc o %lx g %lx p %x dbg %p\n",
(u_long)ntohl(mfccp->mfcc_origin.s_addr),
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
- mfccp->mfcc_parent, (void *)mb_rt->m_act);
+ mfccp->mfcc_parent, (void *)rt->mfc_stall);
rt->mfc_origin = mfccp->mfcc_origin;
rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
@@ -906,19 +901,18 @@ add_mfc(mfccp)
nexpire[hash]--;
/* free packets Qed at the end of this entry */
- while (mb_rt->m_act) {
- mb_ntry = mb_rt->m_act;
- rte = mtod(mb_ntry, struct rtdetq *);
-/* #ifdef RSVP_ISI */
+ for (rte = rt->mfc_stall; rte != NULL; ) {
+ struct rtdetq *n = rte->next;
+
ip_mdq(rte->m, rte->ifp, rt, -1);
-/* #endif */
- mb_rt->m_act = mb_ntry->m_act;
m_freem(rte->m);
#ifdef UPCALL_TIMING
collate(&(rte->t));
#endif /* UPCALL_TIMING */
- m_free(mb_ntry);
+ free(rte, M_MRTABLE);
+ rte = n;
}
+ rt->mfc_stall = NULL;
}
}
@@ -932,9 +926,8 @@ add_mfc(mfccp)
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
mfccp->mfcc_parent);
- for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) {
+ for (rt = mfctable[hash]; rt != NULL; rt = rt->mfc_next) {
- rt = mtod(mb_rt, struct mfc *);
if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
(rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {
@@ -953,16 +946,14 @@ add_mfc(mfccp)
rt->mfc_expire = 0;
}
}
- if (mb_rt == NULL) {
+ if (rt == NULL) {
/* no upcall, so make a new entry */
- MGET(mb_rt, M_DONTWAIT, MT_MRTABLE);
- if (mb_rt == NULL) {
+ rt = (struct mfc *)malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT);
+ if (rt == NULL) {
splx(s);
return ENOBUFS;
}
- rt = mtod(mb_rt, struct mfc *);
-
/* insert new entry at head of hash chain */
rt->mfc_origin = mfccp->mfcc_origin;
rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
@@ -975,11 +966,11 @@ add_mfc(mfccp)
rt->mfc_wrong_if = 0;
rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
rt->mfc_expire = 0;
+ rt->mfc_stall = NULL;
/* link into table */
- mb_rt->m_next = mfctable[hash];
- mfctable[hash] = mb_rt;
- mb_rt->m_act = NULL;
+ rt->mfc_next = mfctable[hash];
+ mfctable[hash] = rt;
}
}
splx(s);
@@ -1022,8 +1013,7 @@ del_mfc(mfccp)
struct in_addr origin;
struct in_addr mcastgrp;
struct mfc *rt;
- struct mbuf *mb_rt;
- struct mbuf **nptr;
+ struct mfc **nptr;
u_long hash;
int s;
@@ -1038,21 +1028,21 @@ del_mfc(mfccp)
s = splnet();
nptr = &mfctable[hash];
- while ((mb_rt = *nptr) != NULL) {
- rt = mtod(mb_rt, struct mfc *);
+ while ((rt = *nptr) != NULL) {
if (origin.s_addr == rt->mfc_origin.s_addr &&
mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&
- mb_rt->m_act == NULL)
+ rt->mfc_stall == NULL)
break;
- nptr = &mb_rt->m_next;
+ nptr = &rt->mfc_next;
}
- if (mb_rt == NULL) {
+ if (rt == NULL) {
splx(s);
return EADDRNOTAVAIL;
}
- MFREE(mb_rt, *nptr);
+ *nptr = rt->mfc_next;
+ free(rt, M_MRTABLE);
splx(s);
@@ -1178,13 +1168,9 @@ X_ip_mforward(ip, ifp, m, imo)
* send message to routing daemon
*/
- register struct mbuf *mb_rt;
- register struct mbuf *mb_ntry;
register struct mbuf *mb0;
register struct rtdetq *rte;
- register struct mbuf *rte_m;
register u_long hash;
- register int npkts;
int hlen = ip->ip_hl << 2;
#ifdef UPCALL_TIMING
struct timeval tp;
@@ -1203,8 +1189,8 @@ X_ip_mforward(ip, ifp, m, imo)
* just going to fail anyway. Make sure to pullup the header so
* that other people can't step on it.
*/
- MGET(mb_ntry, M_DONTWAIT, MT_DATA);
- if (mb_ntry == NULL) {
+ rte = (struct rtdetq *)malloc((sizeof *rte), M_MRTABLE, M_NOWAIT);
+ if (rte == NULL) {
splx(s);
return ENOBUFS;
}
@@ -1212,29 +1198,28 @@ X_ip_mforward(ip, ifp, m, imo)
if (mb0 && (M_HASCL(mb0) || mb0->m_len < hlen))
mb0 = m_pullup(mb0, hlen);
if (mb0 == NULL) {
- m_free(mb_ntry);
+ free(rte, M_MRTABLE);
splx(s);
return ENOBUFS;
}
/* is there an upcall waiting for this packet? */
hash = MFCHASH(ip->ip_src.s_addr, ip->ip_dst.s_addr);
- for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) {
- rt = mtod(mb_rt, struct mfc *);
+ 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) &&
- (mb_rt->m_act != NULL))
+ (rt->mfc_stall != NULL))
break;
}
- if (mb_rt == NULL) {
+ if (rt == NULL) {
int i;
struct igmpmsg *im;
/* no upcall, so make a new entry */
- MGET(mb_rt, M_DONTWAIT, MT_MRTABLE);
- if (mb_rt == NULL) {
- m_free(mb_ntry);
+ rt = (struct mfc *)malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT);
+ if (rt == NULL) {
+ free(rte, M_MRTABLE);
m_freem(mb0);
splx(s);
return ENOBUFS;
@@ -1242,9 +1227,9 @@ X_ip_mforward(ip, ifp, m, imo)
/* Make a copy of the header to send to the user level process */
mm = m_copy(mb0, 0, hlen);
if (mm == NULL) {
- m_free(mb_ntry);
+ free(rte, M_MRTABLE);
m_freem(mb0);
- m_free(mb_rt);
+ free(rt, M_MRTABLE);
splx(s);
return ENOBUFS;
}
@@ -1264,15 +1249,13 @@ X_ip_mforward(ip, ifp, m, imo)
if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) {
log(LOG_WARNING, "ip_mforward: ip_mrouter socket queue full\n");
++mrtstat.mrts_upq_sockfull;
- m_free(mb_ntry);
+ free(rte, M_MRTABLE);
m_freem(mb0);
- m_free(mb_rt);
+ free(rt, M_MRTABLE);
splx(s);
return ENOBUFS;
}
- rt = mtod(mb_rt, struct mfc *);
-
/* insert new entry at head of hash chain */
rt->mfc_origin.s_addr = ip->ip_src.s_addr;
rt->mfc_mcastgrp.s_addr = ip->ip_dst.s_addr;
@@ -1283,36 +1266,36 @@ X_ip_mforward(ip, ifp, m, imo)
rt->mfc_parent = -1;
/* link into table */
- mb_rt->m_next = mfctable[hash];
- mfctable[hash] = mb_rt;
- mb_rt->m_act = NULL;
+ rt->mfc_next = mfctable[hash];
+ mfctable[hash] = rt;
+ rt->mfc_stall = rte;
- rte_m = mb_rt;
} else {
/* determine if q has overflowed */
- for (rte_m = mb_rt, npkts = 0; rte_m->m_act; rte_m = rte_m->m_act)
+ int npkts = 0;
+ struct rtdetq **p;
+
+ for (p = &rt->mfc_stall; *p != NULL; p = &(*p)->next)
npkts++;
if (npkts > MAX_UPQ) {
mrtstat.mrts_upq_ovflw++;
- m_free(mb_ntry);
+ free(rte, M_MRTABLE);
m_freem(mb0);
splx(s);
return 0;
}
- }
- mb_ntry->m_act = NULL;
- rte = mtod(mb_ntry, struct rtdetq *);
+ /* Add this entry to the end of the queue */
+ *p = rte;
+ }
rte->m = mb0;
rte->ifp = ifp;
#ifdef UPCALL_TIMING
rte->t = tp;
#endif
-
- /* Add this entry to the end of the queue */
- rte_m->m_act = mb_ntry;
+ rte->next = NULL;
splx(s);
@@ -1331,9 +1314,8 @@ int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
static void
expire_upcalls(void *unused)
{
- struct mbuf *mb_rt, *m, **nptr;
struct rtdetq *rte;
- struct mfc *mfc;
+ struct mfc *mfc, **nptr;
int i;
int s;
@@ -1342,15 +1324,13 @@ expire_upcalls(void *unused)
if (nexpire[i] == 0)
continue;
nptr = &mfctable[i];
- for (mb_rt = *nptr; mb_rt != NULL; mb_rt = *nptr) {
- mfc = mtod(mb_rt, struct mfc *);
-
+ for (mfc = *nptr; mfc != NULL; mfc = *nptr) {
/*
* Skip real cache entries
* Make sure it wasn't marked to not expire (shouldn't happen)
* If it expires now
*/
- if (mb_rt->m_act != NULL &&
+ if (mfc->mfc_stall != NULL &&
mfc->mfc_expire != 0 &&
--mfc->mfc_expire == 0) {
if (mrtdebug & DEBUG_EXPIRE)
@@ -1361,20 +1341,20 @@ expire_upcalls(void *unused)
* drop all the packets
* free the mbuf with the pkt, if, timing info
*/
- while (mb_rt->m_act) {
- m = mb_rt->m_act;
- mb_rt->m_act = m->m_act;
-
- rte = mtod(m, struct rtdetq *);
+ for (rte = mfc->mfc_stall; rte; ) {
+ struct rtdetq *n = rte->next;
+
m_freem(rte->m);
- m_free(m);
+ free(rte, M_MRTABLE);
+ rte = n;
}
++mrtstat.mrts_cache_cleanups;
nexpire[i]--;
- MFREE(mb_rt, *nptr);
+ *nptr = mfc->mfc_next;
+ free(mfc, M_MRTABLE);
} else {
- nptr = &mb_rt->m_next;
+ nptr = &mfc->mfc_next;
}
}
}
@@ -1555,7 +1535,7 @@ phyint_send(ip, vifp, m)
if (mb_copy == NULL)
return;
- if (vifp->v_rate_limit <= 0)
+ if (vifp->v_rate_limit == 0)
tbf_send_packet(vifp, mb_copy);
else
tbf_control(vifp, mb_copy, mtod(mb_copy, struct ip *), ip->ip_len);
@@ -1616,7 +1596,7 @@ encap_send(ip, vifp, m)
ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
mb_copy->m_data -= sizeof(multicast_encap_iphdr);
- if (vifp->v_rate_limit <= 0)
+ if (vifp->v_rate_limit == 0)
tbf_send_packet(vifp, mb_copy);
else
tbf_control(vifp, mb_copy, ip, ip_copy->ip_len);
diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h
index 94ddeac..0526bbb 100644
--- a/sys/netinet/ip_mroute.h
+++ b/sys/netinet/ip_mroute.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)ip_mroute.h 8.1 (Berkeley) 6/10/93
- * $Id: ip_mroute.h,v 1.13 1997/02/22 09:41:35 peter Exp $
+ * $Id: ip_mroute.h,v 1.14 1998/08/23 03:07:14 wollman Exp $
*/
#ifndef _NETINET_IP_MROUTE_H_
@@ -188,6 +188,8 @@ struct mfc {
u_long mfc_wrong_if; /* wrong if for src-grp */
int mfc_expire; /* time to clean entry up */
struct timeval mfc_last_assert; /* last time I sent an assert*/
+ struct rtdetq *mfc_stall; /* q of packets awaiting mfc */
+ struct mfc *mfc_next; /* next mfc entry */
};
/*
@@ -216,6 +218,7 @@ struct rtdetq {
#ifdef UPCALL_TIMING
struct timeval t; /* Timestamp */
#endif /* UPCALL_TIMING */
+ struct rtdetq *next; /* Next in list of packets */
};
#define MFCTBLSIZ 256
OpenPOWER on IntegriCloud