Page MenuHomeFreeBSD

D36122.diff
No OneTemporary

D36122.diff

diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -60,7 +60,6 @@
#include <net/if_llatbl.h>
#include <net/if_types.h>
#include <net/netisr.h>
-#include <net/raw_cb.h>
#include <net/route.h>
#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
@@ -150,7 +149,7 @@
int (*carp_get_vhid_p)(struct ifaddr *);
/*
- * Used by rtsock/raw_input callback code to decide whether to filter the update
+ * Used by rtsock callback code to decide whether to filter the update
* notification to a socket bound to a particular FIB.
*/
#define RTS_FILTER_FIB M_PROTO8
@@ -159,7 +158,14 @@
*/
#define m_rtsock_family m_pkthdr.PH_loc.eight[0]
+struct rcb {
+ LIST_ENTRY(rcb) list;
+ struct socket *rcb_socket;
+ sa_family_t rcb_family;
+};
+
typedef struct {
+ LIST_HEAD(, rcb) cblist;
int ip_count; /* attached w/ AF_INET */
int ip6_count; /* attached w/ AF_INET6 */
int any_count; /* total attached */
@@ -198,7 +204,6 @@
uint32_t weight, struct walkarg *w);
static int sysctl_iflist(int af, struct walkarg *w);
static int sysctl_ifmalist(int af, struct walkarg *w);
-static int route_output(struct mbuf *m, struct socket *so, ...);
static void rt_getmetrics(const struct rtentry *rt,
const struct nhop_object *nh, struct rt_metrics *out);
static void rt_dispatch(struct mbuf *, sa_family_t);
@@ -267,84 +272,85 @@
vnet_rts_uninit, 0);
#endif
-static int
-raw_input_rts_cb(struct mbuf *m, struct sockproto *proto, struct sockaddr *src,
- struct rawcb *rp)
+static void
+rts_append_data(struct socket *so, struct mbuf *m)
{
- int fibnum;
-
- KASSERT(m != NULL, ("%s: m is NULL", __func__));
- KASSERT(proto != NULL, ("%s: proto is NULL", __func__));
- KASSERT(rp != NULL, ("%s: rp is NULL", __func__));
- /* No filtering requested. */
- if ((m->m_flags & RTS_FILTER_FIB) == 0)
- return (0);
-
- /* Check if it is a rts and the fib matches the one of the socket. */
- fibnum = M_GETFIB(m);
- if (proto->sp_family != PF_ROUTE ||
- rp->rcb_socket == NULL ||
- rp->rcb_socket->so_fibnum == fibnum)
- return (0);
-
- /* Filtering requested and no match, the socket shall be skipped. */
- return (1);
+ if (sbappendaddr(&so->so_rcv, &route_src, m, NULL) == 0) {
+ soroverflow(so);
+ m_freem(m);
+ } else
+ sorwakeup(so);
}
static void
rts_input(struct mbuf *m)
{
- struct sockproto route_proto;
+ struct rcb *rcb;
+ struct socket *last;
- route_proto.sp_family = PF_ROUTE;
- route_proto.sp_protocol = m->m_rtsock_family;
-
- raw_input_ext(m, &route_proto, &route_src, raw_input_rts_cb);
-}
-
-/*
- * It really doesn't make any sense at all for this code to share much
- * with raw_usrreq.c, since its functionality is so restricted. XXX
- */
-static void
-rts_abort(struct socket *so)
-{
+ last = NULL;
+ RTSOCK_LOCK();
+ LIST_FOREACH(rcb, &V_route_cb.cblist, list) {
+ if (rcb->rcb_family != AF_UNSPEC &&
+ rcb->rcb_family != m->m_rtsock_family)
+ continue;
+ if ((m->m_flags & RTS_FILTER_FIB) &&
+ M_GETFIB(m) != rcb->rcb_socket->so_fibnum)
+ continue;
+ if (last != NULL) {
+ struct mbuf *n;
- raw_usrreqs.pru_abort(so);
+ n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+ if (n != NULL)
+ rts_append_data(last, n);
+ }
+ last = rcb->rcb_socket;
+ }
+ if (last != NULL)
+ rts_append_data(last, m);
+ else
+ m_freem(m);
+ RTSOCK_UNLOCK();
}
static void
rts_close(struct socket *so)
{
- raw_usrreqs.pru_close(so);
+ soisdisconnected(so);
}
-/* pru_accept is EOPNOTSUPP */
+static SYSCTL_NODE(_net, OID_AUTO, rtsock, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "Routing socket infrastructure");
+static u_long rts_sendspace = 8192;
+SYSCTL_ULONG(_net_rtsock, OID_AUTO, sendspace, CTLFLAG_RW, &rts_sendspace, 0,
+ "Default routing socket send space");
+static u_long rts_recvspace = 8192;
+SYSCTL_ULONG(_net_rtsock, OID_AUTO, recvspace, CTLFLAG_RW, &rts_recvspace, 0,
+ "Default routing socket receive space");
static int
rts_attach(struct socket *so, int proto, struct thread *td)
{
- struct rawcb *rp;
+ struct rcb *rcb;
int error;
- KASSERT(so->so_pcb == NULL, ("rts_attach: so_pcb != NULL"));
+ error = soreserve(so, rts_sendspace, rts_recvspace);
+ if (error)
+ return (error);
- /* XXX */
- rp = malloc(sizeof *rp, M_PCB, M_WAITOK | M_ZERO);
+ rcb = malloc(sizeof(*rcb), M_PCB, M_WAITOK);
+ rcb->rcb_socket = so;
+ rcb->rcb_family = proto;
- so->so_pcb = (caddr_t)rp;
+ so->so_pcb = rcb;
so->so_fibnum = td->td_proc->p_fibnum;
- error = raw_attach(so, proto);
- rp = sotorawcb(so);
- if (error) {
- so->so_pcb = NULL;
- free(rp, M_PCB);
- return error;
- }
+ so->so_options |= SO_USELOOPBACK;
+
RTSOCK_LOCK();
- switch(rp->rcb_proto.sp_protocol) {
+ LIST_INSERT_HEAD(&V_route_cb.cblist, rcb, list);
+ switch (proto) {
case AF_INET:
V_route_cb.ip_count++;
break;
@@ -355,36 +361,18 @@
V_route_cb.any_count++;
RTSOCK_UNLOCK();
soisconnected(so);
- so->so_options |= SO_USELOOPBACK;
- return 0;
-}
-static int
-rts_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
-{
-
- return (raw_usrreqs.pru_bind(so, nam, td)); /* xxx just EINVAL */
-}
-
-static int
-rts_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
-{
-
- return (raw_usrreqs.pru_connect(so, nam, td)); /* XXX just EINVAL */
+ return (0);
}
-/* pru_connect2 is EOPNOTSUPP */
-/* pru_control is EOPNOTSUPP */
-
static void
rts_detach(struct socket *so)
{
- struct rawcb *rp = sotorawcb(so);
-
- KASSERT(rp != NULL, ("rts_detach: rp == NULL"));
+ struct rcb *rcb = so->so_pcb;
RTSOCK_LOCK();
- switch(rp->rcb_proto.sp_protocol) {
+ LIST_REMOVE(rcb, list);
+ switch(rcb->rcb_family) {
case AF_INET:
V_route_cb.ip_count--;
break;
@@ -394,66 +382,18 @@
}
V_route_cb.any_count--;
RTSOCK_UNLOCK();
- raw_usrreqs.pru_detach(so);
+ free(rcb, M_PCB);
+ so->so_pcb = NULL;
}
-static int
-rts_disconnect(struct socket *so)
-{
-
- return (raw_usrreqs.pru_disconnect(so));
-}
-
-/* pru_listen is EOPNOTSUPP */
-
-static int
-rts_peeraddr(struct socket *so, struct sockaddr **nam)
-{
-
- return (raw_usrreqs.pru_peeraddr(so, nam));
-}
-
-/* pru_rcvd is EOPNOTSUPP */
-/* pru_rcvoob is EOPNOTSUPP */
-
-static int
-rts_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
- struct mbuf *control, struct thread *td)
-{
-
- return (raw_usrreqs.pru_send(so, flags, m, nam, control, td));
-}
-
-/* pru_sense is null */
-
static int
rts_shutdown(struct socket *so)
{
- return (raw_usrreqs.pru_shutdown(so));
-}
-
-static int
-rts_sockaddr(struct socket *so, struct sockaddr **nam)
-{
-
- return (raw_usrreqs.pru_sockaddr(so, nam));
+ socantsendmore(so);
+ return (0);
}
-static struct pr_usrreqs route_usrreqs = {
- .pru_abort = rts_abort,
- .pru_attach = rts_attach,
- .pru_bind = rts_bind,
- .pru_connect = rts_connect,
- .pru_detach = rts_detach,
- .pru_disconnect = rts_disconnect,
- .pru_peeraddr = rts_peeraddr,
- .pru_send = rts_send,
- .pru_shutdown = rts_shutdown,
- .pru_sockaddr = rts_sockaddr,
- .pru_close = rts_close,
-};
-
#ifndef _SOCKADDR_UNION_DEFINED
#define _SOCKADDR_UNION_DEFINED
/*
@@ -1021,9 +961,9 @@
}
#endif
-/*ARGSUSED*/
static int
-route_output(struct mbuf *m, struct socket *so, ...)
+rts_send(struct socket *so, int flags, struct mbuf *m,
+ struct sockaddr *nam, struct mbuf *control, struct thread *td)
{
struct rt_msghdr *rtm = NULL;
struct rt_addrinfo info;
@@ -1038,6 +978,13 @@
struct rib_cmd_info rc;
struct nhop_object *nh;
+ if ((flags & PRUS_OOB) || control != NULL) {
+ m_freem(m);
+ if (control != NULL)
+ m_freem(control);
+ return (EOPNOTSUPP);
+ }
+
fibnum = so->so_fibnum;
#define senderr(e) { error = e; goto flush;}
if (m == NULL || ((m->m_len < sizeof(long)) &&
@@ -1231,7 +1178,7 @@
send_rtm_reply(struct socket *so, struct rt_msghdr *rtm, struct mbuf *m,
sa_family_t saf, u_int fibnum, int rtm_errno)
{
- struct rawcb *rp = NULL;
+ struct rcb *rcb = NULL;
/*
* Check to see if we don't want our own messages.
@@ -1244,7 +1191,7 @@
return;
}
/* There is another listener, so construct message */
- rp = sotorawcb(so);
+ rcb = so->so_pcb;
}
if (rtm != NULL) {
@@ -1265,15 +1212,15 @@
if (m != NULL) {
M_SETFIB(m, fibnum);
m->m_flags |= RTS_FILTER_FIB;
- if (rp) {
+ if (rcb) {
/*
* XXX insure we don't get a copy by
* invalidating our protocol
*/
- unsigned short family = rp->rcb_proto.sp_family;
- rp->rcb_proto.sp_family = 0;
+ sa_family_t family = rcb->rcb_family;
+ rcb->rcb_family = AF_UNSPEC;
rt_dispatch(m, saf);
- rp->rcb_proto.sp_family = family;
+ rcb->rcb_family = family;
} else
rt_dispatch(m, saf);
}
@@ -2696,13 +2643,20 @@
static struct domain routedomain; /* or at least forward */
+static struct pr_usrreqs route_usrreqs = {
+ .pru_abort = rts_close,
+ .pru_attach = rts_attach,
+ .pru_detach = rts_detach,
+ .pru_send = rts_send,
+ .pru_shutdown = rts_shutdown,
+ .pru_close = rts_close,
+};
+
static struct protosw routesw[] = {
{
.pr_type = SOCK_RAW,
.pr_domain = &routedomain,
.pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_output = route_output,
- .pr_ctlinput = raw_ctlinput,
.pr_usrreqs = &route_usrreqs
}
};

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 1, 1:39 PM (5 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13253828
Default Alt Text
D36122.diff (9 KB)

Event Timeline