Date: Fri, 16 Jul 2010 22:52:20 GMT From: Ana Kukec <anchie@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 181067 for review Message-ID: <201007162252.o6GMqKmD018641@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@181067?ac=10 Change 181067 by anchie@anchie_malimis on 2010/07/16 22:51:51 Conceptual and editorial changes (made/suggested by Bjoern). Affected files ... .. //depot/projects/soc2009/anchie_send/send_0.2/sendd/net.c#29 edit .. //depot/projects/soc2009/anchie_send/send_0.2/sendd/os-freebsd/addr.c#3 edit .. //depot/projects/soc2009/anchie_send/src/sys/kern/uipc_socket.c#8 edit .. //depot/projects/soc2009/anchie_send/src/sys/net/route.h#12 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet/icmp6.h#16 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet/in.h#7 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet/ip_var.h#11 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet/raw_ip.c#9 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/icmp6.c#43 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/in6_proto.c#7 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/nd6.c#33 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/nd6_nbr.c#19 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/raw_ip6.c#12 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.c#45 edit .. //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.h#22 edit Differences ... ==== //depot/projects/soc2009/anchie_send/send_0.2/sendd/net.c#29 (text+ko) ==== @@ -89,7 +89,7 @@ int ifidx; }; -void snd_sock_read(struct snd_ifinfo *p); +static void snd_sock_read(struct snd_ifinfo *p); #endif /* TODO: dynamically size according to MTU */ @@ -141,10 +141,10 @@ } void -snd_deliver_pkt(void *p, struct sbuff *b, int drop, int changed) +os_specific_deliver_pkt(void *p, struct sbuff *b, int drop, int changed) { struct snd_packet_info *pi; - struct snd_hdr *snd_hdr; + struct sockaddr_send sendsrc; if (drop) { snd_put_buf(b); @@ -152,13 +152,15 @@ } pi = (struct snd_packet_info *)(b->head); - b->data -= SEND_HDR_LEN; - b->len += SEND_HDR_LEN; - snd_hdr = sbuff_data(b); - snd_hdr->direction = pi->in; - snd_hdr->ifidx = pi->ifinfo->ifidx; + bzero(&sendsrc, sizeof(sendsrc)); + sendsrc.send_len = sizeof(sendsrc); + sendsrc.send_family = AF_INET6; + sendsrc.send_direction = pi->in; + sendsrc.send_ifidx = pi->ifinfo->ifidx; - if (send(sndsock, b->data, b->len, 0) < 0) { + DBG(&dbg_snd, "Sending %d bytes:\n", b->len); + if (sendto(sndsock, b->data, b->len, 0, (struct sockaddr *)&sendsrc, + sizeof(sendsrc)) < 0) { DBG(&dbg_snd, "Failed to send SEND message back to kernel."); perror("Failed"); snd_put_buf(b); @@ -166,7 +168,6 @@ } snd_put_buf(b); - return; } @@ -177,9 +178,9 @@ struct snd_ifinfo *p; list_for_each_entry(p, &ifaces, list) { - *maxfd = *maxfd > p->snds ? *maxfd : p->snds; p->snds = sock; FD_SET(p->snds, fds); + *maxfd = sendd_max(*maxfd, p->snds); } } #endif @@ -238,11 +239,11 @@ } #ifdef SND_OS_freebsd -void +static void snd_sock_read(struct snd_ifinfo *p) { - struct snd_hdr *snd_hdr; - int direction; + struct sockaddr_send sendsrc; + socklen_t len; struct sbuff *b; struct snd_packet_info *pi; int n; @@ -254,18 +255,18 @@ pi = sbuff_data(b); sbuff_advance(b, sizeof (*pi)); - n = recv(sndsock, b->data, b->rem, 0); + len = sizeof(sendsrc); + bzero(&sendsrc, sizeof(sendsrc)); + n = recvfrom(sndsock, b->data, b->rem, 0, (struct sockaddr *)&sendsrc, &len); if (n < 0) { - applog(LOG_ERR, "%s: read: %s", __FUNCTION__, strerror(errno)); + applog(LOG_ERR, "%s: read: %s", __func__, strerror(errno)); goto done; } else - DBG(&dbg_snd, "%d bytes received on routing socket. (%d)", n, b->rem); + DBG(&dbg_snd, "%d bytes received on send socket. (%d)", n, b->rem); b->len = n; - snd_hdr = sbuff_pull(b, SEND_HDR_LEN); - direction = snd_hdr->direction; - switch(direction) { + switch(sendsrc.send_direction) { case SND_IN: applog(LOG_ERR, "Direction: SND_IN"); pi->ifinfo = p; @@ -365,13 +366,11 @@ return (-1); } #endif + #ifdef SND_OS_freebsd #define IPPROTO_SEND 259 -#endif - -#ifdef SND_OS_freebsd - if ((*sndsocket = socket(PF_INET, SOCK_RAW, IPPROTO_SEND)) < 0) { - applog(LOG_ERR, "%s: socket: %s", __FUNCTION__, + if ((*sndsocket = socket(PF_INET6, SOCK_RAW, IPPROTO_SEND)) < 0) { + applog(LOG_ERR, "[%s:%d]: socket: %s", __func__, __LINE__, strerror(errno)); return(-1); } else { ==== //depot/projects/soc2009/anchie_send/send_0.2/sendd/os-freebsd/addr.c#3 (text+ko) ==== @@ -54,10 +54,10 @@ struct in6_aliasreq req[1]; struct in6_addr mask64[1]; int s; -#ifdef SND_OS_linux +#ifdef SND_OS_freebsd + unsigned long cmd; +#else int cmd; -#else - unsigned int long cmd; #endif int r = -1; ==== //depot/projects/soc2009/anchie_send/src/sys/kern/uipc_socket.c#8 (text+ko) ==== @@ -1187,15 +1187,12 @@ goto release; } } else if (addr == NULL) { - /* XXX-AK: */ - if (so->so_proto->pr_protocol != 259) { SOCKBUF_UNLOCK(&so->so_snd); if (so->so_proto->pr_flags & PR_CONNREQUIRED) error = ENOTCONN; else error = EDESTADDRREQ; goto release; - } } } space = sbspace(&so->so_snd); ==== //depot/projects/soc2009/anchie_send/src/sys/net/route.h#12 (text+ko) ==== @@ -234,6 +234,7 @@ u_long rtm_inits; /* which metrics we are initializing */ struct rt_metrics rtm_rmx; /* metrics themselves */ }; + #define RTM_VERSION 5 /* Up the ante and ignore older versions */ /* ==== //depot/projects/soc2009/anchie_send/src/sys/netinet/icmp6.h#16 (text+ko) ==== @@ -662,7 +662,6 @@ void icmp6_prepare(struct mbuf *); void icmp6_redirect_input(struct mbuf *, int); void icmp6_redirect_output(struct mbuf *, struct rtentry *); -int icmp6_rip6_input(struct mbuf **, int); struct ip6ctlparam; void icmp6_mtudisc_update(struct ip6ctlparam *, int); ==== //depot/projects/soc2009/anchie_send/src/sys/netinet/in.h#7 (text+ko) ==== @@ -252,7 +252,7 @@ /* Only used internally, so can be outside the range of valid IP protocols. */ #define IPPROTO_DIVERT 258 /* divert pseudo-protocol */ -#define IPPROTO_SEND 259 /* SeND socket pseudo-proto */ +#define IPPROTO_SEND 259 /* SeND pseudo-protocol */ /* * Defined to avoid confusion. The master value is defined by ==== //depot/projects/soc2009/anchie_send/src/sys/netinet/ip_var.h#11 (text+ko) ==== @@ -188,7 +188,6 @@ extern u_long (*ip_mcast_src)(int); VNET_DECLARE(int, rsvp_on); extern struct pr_usrreqs rip_usrreqs; -VNET_DECLARE(struct socket *, send_so); /* SeND daemon */ #define V_ipstat VNET(ipstat) #define V_ip_id VNET(ip_id) @@ -199,9 +198,7 @@ #endif #define V_ip_rsvpd VNET(ip_rsvpd) #define V_ip_mrouter VNET(ip_mrouter) - #define V_rsvp_on VNET(rsvp_on) -#define V_send_so VNET(send_so) void inp_freemoptions(struct ip_moptions *); int inp_getmoptions(struct inpcb *, struct sockopt *); ==== //depot/projects/soc2009/anchie_send/src/sys/netinet/raw_ip.c#9 (text+ko) ==== @@ -104,11 +104,6 @@ VNET_DEFINE(struct socket *, ip_mrouter); /* - * The socket used to communicate with the SeND daemon. - */ -VNET_DEFINE(struct socket *, send_so); - -/* * The various mrouter and rsvp functions. */ int (*ip_mrouter_set)(struct socket *, struct sockopt *); ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/icmp6.c#43 (text+ko) ==== @@ -94,7 +94,6 @@ #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/in_var.h> -#include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet/icmp6.h> #include <netinet/tcp_var.h> @@ -132,6 +131,7 @@ #define V_icmp6_nodeinfo VNET(icmp6_nodeinfo) static void icmp6_errcount(struct icmp6errstat *, int, int); +static int icmp6_rip6_input(struct mbuf **, int); static int icmp6_ratelimit(const struct in6_addr *, const int, const int); static const char *icmp6_redirect_diag __P((struct in6_addr *, struct in6_addr *, struct in6_addr *)); @@ -2008,7 +2008,7 @@ /* * XXX almost dup'ed code with rip6_input. */ -int +static int icmp6_rip6_input(struct mbuf **mp, int off) { struct mbuf *m = *mp; ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/in6_proto.c#7 (text+ko) ==== @@ -145,6 +145,14 @@ #define PR_LISTEN 0 #define PR_ABRTACPTDIS 0 +/* Spacer for loadable protocols. */ +#define IP6PROTOSPACER \ +{ \ + .pr_domain = &inet6domain, \ + .pr_protocol = PROTO_SPACER, \ + .pr_usrreqs = &nousrreqs \ +} + struct ip6protosw inet6sw[] = { { .pr_type = 0, @@ -340,6 +348,15 @@ .pr_usrreqs = &rip6_usrreqs }, #endif /* DEV_CARP */ +/* Spacer n-times for loadable protocols. */ +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, +IP6PROTOSPACER, /* raw wildcard */ { .pr_type = SOCK_RAW, ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/nd6.c#33 (text+ko) ==== @@ -62,7 +62,6 @@ #include <net/vnet.h> #include <netinet/in.h> -#include <netinet/ip_var.h> #include <net/if_llatbl.h> #define L3_ADDR_SIN6(le) ((struct sockaddr_in6 *) L3_ADDR(le)) #include <netinet/if_ether.h> ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/nd6_nbr.c#19 (text+ko) ==== @@ -64,7 +64,6 @@ #include <netinet/in.h> #include <netinet/in_var.h> -#include <netinet/ip_var.h> #include <net/if_llatbl.h> #define L3_ADDR_SIN6(le) ((struct sockaddr_in6 *) L3_ADDR(le)) #include <netinet6/in6_var.h> ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/raw_ip6.c#12 (text+ko) ==== @@ -536,7 +536,7 @@ * them to rtadvd/rtsol. */ if ((send_sendso_input_hook != NULL) && - so->so_proto->pr_protocol == IPPROTO_ICMPV6) { + so->so_proto->pr_protocol == IPPROTO_ICMPV6) { switch (type) { case ND_ROUTER_ADVERT: case ND_ROUTER_SOLICIT: ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.c#45 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2010 Ana Kukec <anchie@freebsd.org> + * Copyright (c) 2009-2010 Ana Kukec <anchie@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,17 +25,21 @@ */ #include <sys/param.h> +#include <sys/kernel.h> +#include <sys/mbuf.h> #include <sys/module.h> -#include <sys/kernel.h> +#include <sys/priv.h> +#include <sys/protosw.h> #include <sys/systm.h> -#include <sys/types.h> -#include <sys/protosw.h> #include <sys/socket.h> #include <sys/sockstate.h> #include <sys/sockbuf.h> #include <sys/socketvar.h> -#include <sys/mbuf.h> +#include <sys/types.h> +#include <net/route.h> +#include <net/if.h> +#include <net/if_var.h> #include <net/vnet.h> #include <netinet/in.h> @@ -43,251 +47,272 @@ #include <netinet/ip6.h> #include <netinet/icmp6.h> -#include <net/route.h> -#include <net/if.h> -#include <net/if_var.h> - #include <netinet6/in6_var.h> #include <netinet6/nd6.h> #include <netinet6/scope6_var.h> #include <netinet6/send.h> +MALLOC_DEFINE(M_SEND, "send", "Secure Neighbour Discovery"); -MALLOC_DEFINE(M_SEND, "send", "Secure Neighbour Discovery"); +/* + * The socket used to communicate with the SeND daemon. + */ +static VNET_DEFINE(struct socket *, send_so); +#define V_send_so VNET(send_so) + +u_long send_sendspace = 8 * (1024 + sizeof(struct sockaddr_send)); +u_long send_recvspace = 9216; static int -send_output(struct mbuf *m, struct ifnet *ifp, int direction) +send_attach(struct socket *so, int proto, struct thread *td) { - struct ip6_hdr *ip6; - struct sockaddr_in6 dst; - struct icmp6_hdr *icmp6; - int icmp6len; + int error; - /* - * Receive incoming (SEND-protected) or outgoing traffic - * (SEND-validated) from the SEND user space application. - * Outgoing packets are sent out using if_output(). - */ + if (V_send_so != NULL) + return (EEXIST); - switch (direction) { - case SND_IN: - if (m->m_len < (sizeof(struct ip6_hdr) + - sizeof(struct icmp6_hdr))) { - m = m_pullup(m, sizeof(struct ip6_hdr) + - sizeof(struct icmp6_hdr)); - if (!m) - return (ENOBUFS); - } + error = priv_check(td, PRIV_NETINET_RAW); + if (error) + return (error); + if (proto != IPPROTO_SEND) + return (EPROTONOSUPPORT); + error = soreserve(so, send_sendspace, send_recvspace); + if (error) + return (error); - /* Before passing off the mbuf record the proper interface. */ - m->m_pkthdr.rcvif = ifp; + V_send_so = so; - if (m->m_flags & M_PKTHDR) - icmp6len = m->m_pkthdr.len - sizeof(struct ip6_hdr); - else - panic("Doh! not the first mbuf."); + return (0); +} - ip6 = mtod(m, struct ip6_hdr *); - icmp6 = (struct icmp6_hdr *)(ip6 + 1); +static int +send_output(struct mbuf *m, struct ifnet *ifp, int direction) +{ + struct ip6_hdr *ip6; + struct sockaddr_in6 dst; + struct icmp6_hdr *icmp6; + int icmp6len; - /* - * Output the packet as icmp6.c:icpm6_input() would do. - * The mbuf is always consumed, so we do not have to - * care about that. - */ - switch (icmp6->icmp6_type) { - case ND_NEIGHBOR_SOLICIT: - nd6_ns_input(m, sizeof(struct ip6_hdr), icmp6len); - break; - case ND_NEIGHBOR_ADVERT: - nd6_na_input(m, sizeof(struct ip6_hdr), icmp6len); - break; - case ND_REDIRECT: - icmp6_redirect_input(m, sizeof(struct ip6_hdr)); - break; - case ND_ROUTER_SOLICIT: - nd6_rs_input(m, sizeof(struct ip6_hdr), icmp6len); - break; - case ND_ROUTER_ADVERT: - nd6_ra_input(m, sizeof(struct ip6_hdr), icmp6len); - break; - default: - return (ENOSYS); - } + /* + * Receive incoming (SeND-protected) or outgoing traffic + * (SeND-validated) from the SeND user space application. + */ - /* - * No error returned from nd6_??_input() so the only thing - * we can do is to pretend that it worked. - */ - return (0); + switch (direction) { + case SND_IN: + if (m->m_len < (sizeof(struct ip6_hdr) + + sizeof(struct icmp6_hdr))) { + m = m_pullup(m, sizeof(struct ip6_hdr) + + sizeof(struct icmp6_hdr)); + if (!m) + return (ENOBUFS); + } - case SND_OUT: - if (m->m_len < sizeof(struct ip6_hdr)) { - m = m_pullup(m, sizeof(struct ip6_hdr)); - if (!m) - return (ENOBUFS); - } - ip6 = mtod(m, struct ip6_hdr *); - if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) - m->m_flags |= M_MCAST; + /* Before passing off the mbuf record the proper interface. */ + m->m_pkthdr.rcvif = ifp; - zero(&dst, sizeof(dst)); - dst.sin6_family = AF_INET6; - dst.sin6_len = sizeof(dst); - dst.sin6_addr = ip6->ip6_dst; + if (m->m_flags & M_PKTHDR) + icmp6len = m->m_pkthdr.len - sizeof(struct ip6_hdr); + else + panic("Doh! not the first mbuf."); - /* - * Output the packet as nd6.c:nd6_output_lle() would do. - * The mbuf is always consumed, so we do not have to care - * about that. - */ - return ((*ifp->if_output)(ifp, m, (struct sockaddr *)&dst, - NULL)); + ip6 = mtod(m, struct ip6_hdr *); + icmp6 = (struct icmp6_hdr *)(ip6 + 1); - default: - panic("%s: direction must be either SND_IN or SND_OUT.", __func__); - } -} + /* + * Output the packet as icmp6.c:icpm6_input() would do. + * The mbuf is always consumed, so we do not have to + * care about that. + */ + switch (icmp6->icmp6_type) { + case ND_NEIGHBOR_SOLICIT: + nd6_ns_input(m, sizeof(struct ip6_hdr), icmp6len); + break; + case ND_NEIGHBOR_ADVERT: + nd6_na_input(m, sizeof(struct ip6_hdr), icmp6len); + break; + case ND_REDIRECT: + icmp6_redirect_input(m, sizeof(struct ip6_hdr)); + break; + case ND_ROUTER_SOLICIT: + nd6_rs_input(m, sizeof(struct ip6_hdr), icmp6len); + break; + case ND_ROUTER_ADVERT: + nd6_ra_input(m, sizeof(struct ip6_hdr), icmp6len); + break; + default: + return (ENOSYS); + } + return (0); -static int -send_uattach(struct socket *so, int proto, struct thread *td) -{ + case SND_OUT: + if (m->m_len < sizeof(struct ip6_hdr)) { + m = m_pullup(m, sizeof(struct ip6_hdr)); + if (!m) + return (ENOBUFS); + } + ip6 = mtod(m, struct ip6_hdr *); + if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) + m->m_flags |= M_MCAST; - if (V_send_so != NULL) - return (EEXIST); + bzero(&dst, sizeof(dst)); + dst.sin6_family = AF_INET6; + dst.sin6_len = sizeof(dst); + dst.sin6_addr = ip6->ip6_dst; - V_send_so = so; + /* + * Output the packet as nd6.c:nd6_output_lle() would do. + * The mbuf is always consumed, so we do not have to care + * about that. + * XXX-BZ as we added data, what about fragmenting, + * if now needed? + */ + int error; + error = ((*ifp->if_output)(ifp, m, (struct sockaddr *)&dst, + NULL)); + if (error) + error = ENOENT; + return (error); - return (0); + default: + panic("%s: direction %d neither SND_IN nor SND_OUT.", + __func__, direction); + } } +/* + * Receive a SeND message from user space to be either send out by the kernel + * or, with SeND ICMPv6 options removed, to be further processed by the icmp6 + * input path. + */ static int -sosend_rcv(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, - struct mbuf *control, struct thread *td) +send_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, + struct mbuf *control, struct thread *td) { - struct ifnet *ifp; - struct snd_hdr *snd_hdr; + struct sockaddr_send *sendsrc; + struct ifnet *ifp; + int error; - snd_hdr = mtod(m, struct snd_hdr *); + if (V_send_so == NULL) { + error = ENOTCONN; + goto err; + } - struct mbuf *m0; - m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - if (m0 == NULL) { - m_freem(m); - return (ENOBUFS); - } - m_move_pkthdr(m, m0); + sendsrc = (struct sockaddr_send *)nam; + ifp = ifnet_byindex_ref(sendsrc->send_ifidx); + if (ifp == NULL) { + error = ENETUNREACH; + goto err; + } - ifp = ifnet_byindex_ref(snd_hdr->ifidx); - m_adj(m, SEND_HDR_LEN); - m_fixhdr(m); - if (ifp) { - if (send_output(m, ifp, snd_hdr->direction)) - return (ENOENT); + error = send_output(m, ifp, sendsrc->send_direction); if_rele(ifp); - } else - return (ENETUNREACH); + m = NULL; + +err: + if (error && m != NULL) + m_freem(m); + return (error); +} + +static void +send_close(struct socket *so) +{ - return (0); + if (V_send_so) + V_send_so = NULL; } /* - * Send a message to the SEND daemon on the SEND socket. + * Send a SeND message to user space, that was either received and has to be + * validated or was about to be send out and has to be handled by the SEND + * daemon adding SeND ICMPv6 options. */ static int -send_sendso_input(struct mbuf *m, int direction, int msglen) +send_input(struct mbuf *m, int direction, int msglen __unused) { - u_int len; - struct ip6_hdr *ip6; - struct snd_hdr *snd_hdr = NULL; + struct ip6_hdr *ip6; + struct sockaddr_send sendsrc; - if (V_send_so == NULL) - return (-1); + if (V_send_so == NULL) + return (-1); - /* - * Make sure to clear any possible internally embedded scope before - * passing the packet to userspace for SeND cryptographic signature - * validation to succeed. - */ - ip6 = mtod(m, struct ip6_hdr *); - in6_clearscope(&ip6->ip6_src); - in6_clearscope(&ip6->ip6_dst); + /* + * Make sure to clear any possible internally embedded scope before + * passing the packet to user space for SeND cryptographic signature + * validation to succeed. + */ + ip6 = mtod(m, struct ip6_hdr *); + in6_clearscope(&ip6->ip6_src); + in6_clearscope(&ip6->ip6_dst); - len = m_length(m, NULL); + bzero(&sendsrc, sizeof(sendsrc)); + sendsrc.send_len = sizeof(sendsrc); + sendsrc.send_family = AF_INET6; + sendsrc.send_direction = direction; + sendsrc.send_ifidx = -1; - m = m_prepend(m, SEND_HDR_LEN, M_PKTHDR|M_DONTWAIT); - if (m == NULL) { - return (ENOBUFS); - } - snd_hdr = mtod(m, struct snd_hdr *); - snd_hdr->direction = direction; - snd_hdr->ifidx = -1; + /* + * Send incoming or outgoing traffic to user space either to be + * protected (outgoing) or validated (incoming) according to rfc3971. + */ + SOCKBUF_LOCK(&V_send_so->so_rcv); + if (sbappendaddr_locked(&V_send_so->so_rcv, + (struct sockaddr *)&sendsrc, m, NULL) == 0) { + SOCKBUF_UNLOCK(&V_send_so->so_rcv); + /* XXX stats. */ + m_freem(m); + } else { + sorwakeup_locked(V_send_so); + } - /* - * Send incoming or outgoing traffic to the user space either to be - * protected (outgoing) or validated (incoming) according to rfc3971. - */ - - SOCKBUF_LOCK(&s->so_rcv); - sbappendrecord_locked(&s->so_rcv, m); - sorwakeup_locked(s); - return (0); + return (0); } -static void -send_close(struct socket *so) -{ - - if (V_send_so) - V_send_so = NULL; -} - struct pr_usrreqs send_usrreqs = { - .pru_attach = send_uattach, - .pru_send = sosend_rcv, - .pru_detach = send_close + .pru_attach = send_attach, + .pru_send = send_send, + .pru_detach = send_close }; struct protosw send_protosw = { - .pr_type = SOCK_RAW, - .pr_protocol = IPPROTO_SEND, - .pr_usrreqs = &send_usrreqs + .pr_type = SOCK_RAW, + .pr_flags = PR_ATOMIC|PR_ADDR, + .pr_protocol = IPPROTO_SEND, + .pr_usrreqs = &send_usrreqs }; static int send_modevent(module_t mod, int type, void *unused) { - int error = 0; + int error = 0; - /* Add locking? icmp6.c and nd6.c are maybe using hooks.. */ + switch (type) { + case MOD_LOAD: + error = pf_proto_register(PF_INET6, &send_protosw); + if (error != 0) { + printf("%s:%d: MOD_LOAD pf_proto_register(): %d\n", + __func__, __LINE__, error); + break; + } + send_sendso_input_hook = send_input; + break; + case MOD_UNLOAD: + if (V_send_so != NULL) + return (EINVAL); + error = pf_proto_unregister(PF_INET6, IPPROTO_SEND, SOCK_RAW); + send_sendso_input_hook = NULL; + break; + default: + break; + } - switch (type) { - case MOD_LOAD: - error = pf_proto_register(PF_INET, &send_protosw); - if (error != 0) - break; - send_sendso_input_hook = send_sendso_input; - break; - case MOD_UNLOAD: - if (V_send_so != NULL) - return (EINVAL); - error = pf_proto_unregister(PF_INET, IPPROTO_SEND, SOCK_RAW); - send_sendso_input_hook = NULL; - break; - - default: - break; - } - - return (error); + return (error); } static moduledata_t sendmod = { - "send", - send_modevent, - 0 + "send", + send_modevent, + 0 }; -DECLARE_MODULE(send, sendmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); - - - +DECLARE_MODULE(send, sendmod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); ==== //depot/projects/soc2009/anchie_send/src/sys/netinet6/send.h#22 (text+ko) ==== @@ -1,6 +1,6 @@ /*- - * Copyright (c) 2009-2010 Ana Kukec <anchie@freebsd.org> - * All rights reserved. + * Copyright (c) 2009-2010 Ana Kukec <anchie@FreeBSD.org> + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,14 +24,20 @@ * SUCH DAMAGE. */ +#ifndef _NETINET6_SEND_H_ +#define _NETINET6_SEND_H_ + #define SND_OUT 0 /* Outgoing traffic */ #define SND_IN 1 /* Incoming traffic. */ -#define SEND_HDR_LEN sizeof(struct snd_hdr) +struct sockaddr_send { + unsigned char send_len; /* total length */ + sa_family_t send_family; /* address family */ + int send_direction; + int send_ifidx; + char send_zero[8]; +}; -struct snd_hdr { - int direction; - int ifidx; -}; +extern int (*send_sendso_input_hook)(struct mbuf *, int, int); -extern int (*send_sendso_input_hook)(struct mbuf *, int, int); +#endif /* _NETINET6_SEND_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007162252.o6GMqKmD018641>