tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Routing socket and interrupt levels
On Mar 25, 2008, at 3:33 PM, Andrew Doran wrote:
Messages can be sent through the routing socket from device interrupt
handlers at IPL_VM. The one I saw was notification of link state
change. The
socket code operates at a much lower level, IPL_SOFTNET, and
shouldn't be
called from a higher level. The below fixes it by enqueuing routing
messages
to a soft interrupt. Any objections?
Thanks,
Andrew
Index: rtsock.c
===================================================================
RCS file: /cvsroot/src/sys/net/rtsock.c,v
retrieving revision 1.98
diff -u -r1.98 rtsock.c
--- rtsock.c 20 Feb 2008 17:05:53 -0000 1.98
+++ rtsock.c 25 Mar 2008 22:25:27 -0000
@@ -75,6 +75,7 @@
#include <sys/protosw.h>
#include <sys/sysctl.h>
#include <sys/kauth.h>
+#include <sys/intr.h>
#ifdef RTSOCK_DEBUG
#include <netinet/in.h>
#endif /* RTSOCK_DEBUG */
@@ -91,6 +92,10 @@
struct sockaddr route_src = { .sa_len = 2, .sa_family = PF_ROUTE, };
struct sockproto route_proto = { .sp_family = PF_ROUTE, };
+int route_maxqlen = IFQ_MAXLEN;
+static struct ifqueue route_intrq;
+static void *route_sih;
+
struct walkarg {
int w_op;
int w_arg;
@@ -111,6 +116,7 @@
static int sysctl_iflist(int, struct walkarg *, int);
static int sysctl_rtable(SYSCTLFN_PROTO);
static inline void rt_adjustcount(int, int);
+static void route_enqueue(struct mbuf *);
static void route_enqueue(struct mbuf *, int);
/* Sleazy use of local variables throughout file, warning!!!! */
#define dst info.rti_info[RTAX_DST]
@@ -460,7 +466,7 @@
if (family)
route_proto.sp_protocol = family;
if (m)
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
if (rp)
rp->rcb_proto.sp_family = PF_ROUTE;
}
@@ -712,7 +718,7 @@
return;
mtod(m, struct rt_msghdr *)->rtm_addrs = rtinfo->rti_addrs;
route_proto.sp_protocol = sa ? sa->sa_family : 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, sa ? sa->sa_family : 0);
}
/*
@@ -741,7 +747,7 @@
if (m == NULL)
return;
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, 0);
#ifdef COMPAT_14
memset(&info, 0, sizeof(info));
memset(&oifm, 0, sizeof(oifm));
@@ -770,7 +776,7 @@
if (m == NULL)
return;
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, 0);
#endif
}
@@ -833,7 +839,7 @@
mtod(m, struct rt_msghdr *)->rtm_addrs = info.rti_addrs;
}
route_proto.sp_protocol = sa ? sa->sa_family : 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, sa ? sa->sa_family : 0);
}
}
@@ -867,7 +873,7 @@
if (m == NULL)
return;
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, 0);
}
/*
@@ -910,7 +916,7 @@
m->m_pkthdr.len += data_len;
mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src, &route_dst);
+ route_enqueue(m);
route_enqueue(m, 0);
}
/*
@@ -1164,6 +1170,54 @@
}
/*
+ * Routing message software interrupt routine
+ */
+static void
+route_intr(void *cookie)
+{
+ int s;
+ struct mbuf *m;
+
+ while (!IF_IS_EMPTY(&route_intrq)) {
+ s = splnet();
+ IF_DEQUEUE(&route_intrq, m);
+ splx(s);
+ if (m == NULL)
+ break;
Make route_proto a local;
route_proto.sp_family = (uintptr_t) M_GETCTX(m);
+ raw_input(m, &route_proto, &route_src, &route_dst);
+ }
+}
+
+/*
+ * Enqueue a message to the software interrupt routine.
+ */
+static void
+route_enqueue(struct mbuf *m)
, int family
+{
+ int s, wasempty;
+
+ s = splnet();
+ if (IF_QFULL(&route_intrq)) {
+ IF_DROP(&route_intrq);
+ m_freem(m);
+ } else {
+ wasempty = IF_IS_EMPTY(&route_intrq);
M_SETCTX(m, family);
+ IF_ENQUEUE(&route_intrq, m);
+ if (wasempty)
+ softint_schedule(route_sih);
+ }
+ splx(s);
+}
+
+void
+rt_init(void)
+{
+
+ route_intrq.ifq_maxlen = route_maxqlen;
+ route_sih = softint_establish(SOFTINT_NET, route_intr, NULL);
+}
+
+/*
* Definitions of protocols supported in the ROUTE domain.
*/
Home |
Main Index |
Thread Index |
Old Index