Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F97644530
D36122.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D36122.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D36122: rtsock: do not use raw socket code
Attached
Detach File
Event Timeline
Log In to Comment