Page MenuHomeFreeBSD

D26755.1778509418.diff
No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None

D26755.1778509418.diff

Index: sys/netinet6/raw_ip6.c
===================================================================
--- sys/netinet6/raw_ip6.c
+++ sys/netinet6/raw_ip6.c
@@ -133,6 +133,44 @@
#endif /* VIMAGE */
/*
+ * Hash functions
+ */
+
+#define INP_PCBHASH_RAW_SIZE 256
+#define INP_PCBHASH_RAW(proto, laddr, faddr, mask) \
+ (((proto) + (*laddr) + (*faddr)) % (mask) + 1)
+
+static void
+rip6_inshash(struct inpcb *inp)
+{
+ struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
+ struct inpcbhead *pcbhash;
+ int hash;
+
+ INP_INFO_WLOCK_ASSERT(pcbinfo);
+ INP_WLOCK_ASSERT(inp);
+
+ if (inp->inp_ip_p != 0 && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
+ IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
+ hash = INP_PCBHASH_RAW(inp->inp_ip_p, inp->in6p_laddr.s6_addr,
+ inp->in6p_faddr.s6_addr, pcbinfo->ipi_hashmask);
+ } else
+ hash = 0;
+ pcbhash = &pcbinfo->ipi_hashbase[hash];
+ CK_LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
+}
+
+static void
+rip6_delhash(struct inpcb *inp)
+{
+
+ INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
+ INP_WLOCK_ASSERT(inp);
+
+ CK_LIST_REMOVE(inp, inp_hash);
+}
+
+/*
* Hooks for multicast routing. They all default to NULL, so leave them not
* initialized and rely on BSS being set to 0.
*/
@@ -151,6 +189,64 @@
int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *);
int (*mrt6_ioctl)(u_long, caddr_t);
+static void
+rip6_hash_lookup(struct mbuf *m, struct inpcb *inp, struct inpcb *last,
+ struct ip6_hdr *ip6, struct sockaddr_in6 fromsa, struct mbuf *opts,
+ int *offp, int hash, int proto)
+{
+ CK_LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[hash], inp_hash) {
+ if (inp->inp_ip_p != proto)
+ continue;
+ /* XXX inp locking */
+ if ((inp->inp_vflag & INP_IPV6) == 0)
+ continue;
+ if (inp->in6p_laddr.s6_addr != ip6->ip6_dst.s6_addr)
+ continue;
+ if (inp->in6p_faddr.s6_addr != ip6->ip6_src.s6_addr)
+ continue;
+ if (last != NULL) {
+ struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+
+ if (n != NULL) {
+ if (last->inp_flags & INP_CONTROLOPTS ||
+ last->inp_socket->so_options & SO_TIMESTAMP)
+ ip6_savecontrol(last, n, &opts);
+ /* strip intermediate headers */
+ m_adj(n, *offp);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&fromsa,
+ n, opts) == 0) {
+ m_freem(n);
+ if (opts)
+ m_freem(opts);
+ RIP6STAT_INC(rip6s_fullsock);
+ } else
+ sorwakeup(last->inp_socket);
+ }
+ /* XXX count dropped packet */
+ INP_RUNLOCK(last);
+ last = NULL;
+ }
+ INP_RLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED))
+ goto skip_1;
+ if (jailed_without_vnet(inp->inp_cred)) {
+ /*
+ * XXX: If faddr was bound to multicast group,
+ * jailed raw socket will drop datagram.
+ */
+ if (prison_check_ip6(inp->inp_cred, &ip6->ip6_dst) != 0)
+ goto skip_1;
+ }
+ last = inp;
+ continue;
+ skip_1:
+ INP_RUNLOCK(inp);
+ }
+
+
+}
+
/*
* Setup generic address and protocol structures for raw_input routine, then
* pass them along with mbuf chain.
@@ -161,10 +257,11 @@
struct ifnet *ifp;
struct mbuf *m = *mp;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct inpcb *inp;
+ struct inpcb *inp = NULL;
struct inpcb *last = NULL;
struct mbuf *opts = NULL;
struct sockaddr_in6 fromsa;
+ int hash;
NET_EPOCH_ASSERT();
@@ -174,7 +271,11 @@
ifp = m->m_pkthdr.rcvif;
- CK_LIST_FOREACH(inp, &V_ripcb, inp_list) {
+ hash = INP_PCBHASH_RAW(proto, ip6->ip6_src.s6_addr,
+ ip6->ip6_dst.s6_addr, V_ripcbinfo.ipi_hashmask);
+ rip6_hash_lookup(m, inp, last, ip6, fromsa, opts, offp, hash, proto);
+
+ CK_LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[0], inp_hash) {
/* XXX inp locking */
if ((inp->inp_vflag & INP_IPV6) == 0)
continue;
@@ -665,13 +766,14 @@
return (error);
}
inp = (struct inpcb *)so->so_pcb;
- INP_INFO_WUNLOCK(&V_ripcbinfo);
inp->inp_vflag |= INP_IPV6;
inp->inp_ip_p = (long)proto;
inp->in6p_hops = -1; /* use kernel default */
inp->in6p_cksum = -1;
inp->in6p_icmp6filt = filter;
ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt);
+ rip6_inshash(inp);
+ INP_INFO_WUNLOCK(&V_ripcbinfo);
INP_WUNLOCK(inp);
return (0);
}
@@ -689,6 +791,7 @@
/* xxx: RSVP */
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
+ rip6_delhash(inp);
free(inp->in6p_icmp6filt, M_PCB);
in_pcbdetach(inp);
in_pcbfree(inp);
@@ -770,7 +873,9 @@
NET_EPOCH_EXIT(et);
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
+ rip6_delhash(inp);
inp->in6p_laddr = addr->sin6_addr;
+ rip6_inshash(inp);
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_ripcbinfo);
return (0);
@@ -809,6 +914,7 @@
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
+ rip6_delhash(inp);
/* Source address selection. XXX: need pcblookup? */
error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
inp, so->so_cred, scope_ambiguous, &in6a, NULL);
@@ -820,6 +926,7 @@
inp->in6p_faddr = addr->sin6_addr;
inp->in6p_laddr = in6a;
+ rip6_inshash(inp);
soisconnected(so);
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_ripcbinfo);
Index: tests/sys/netinet6/Makefile
===================================================================
--- tests/sys/netinet6/Makefile
+++ tests/sys/netinet6/Makefile
@@ -14,18 +14,21 @@
forward6 \
output6 \
lpm6 \
- fibs6
+ fibs6 \
+ rawsocket
TEST_METADATA.output6+= required_programs="python"
${PACKAGE}FILES+= exthdr.py
${PACKAGE}FILES+= mld.py
${PACKAGE}FILES+= scapyi386.py
${PACKAGE}FILES+= redirect.py
+${PACKAGE}FILES+= rawsocket.py
${PACKAGE}FILESMODE_exthdr.py= 0555
${PACKAGE}FILESMODE_mld.py= 0555
${PACKAGE}FILESMODE_scapyi386.py=0555
${PACKAGE}FILESMODE_redirect.py=0555
+${PACKAGE}FILESMODE_rawsocket.py=0555
TESTS_SUBDIRS+= frag6
Index: tests/sys/netinet6/rawsocket.py
===================================================================
--- tests/sys/netinet6/rawsocket.py
+++ tests/sys/netinet6/rawsocket.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2020 Neel Chauhan
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+import argparse
+import socket
+
+
+def parse_args():
+ parser = argparse.ArgumentParser(description='Raw Socket ICMPv6 Ping')
+ parser.add_argument('--ip', type=str, required=True,
+ help='destination ip')
+ return parser.parse_args()
+
+
+def ping(ip):
+ proto = 58 # ICMP
+
+ msg = b'\x80\0\0\0\0\0\0\0' # Barebones ICMPv6 message
+
+ s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, proto)
+ s.sendto(msg, (ip, 0))
+
+
+def main():
+ args = parse_args()
+ ping(args.ip)
+
+
+if __name__ == '__main__':
+ main()
Index: tests/sys/netinet6/rawsocket.sh
===================================================================
--- tests/sys/netinet6/rawsocket.sh
+++ tests/sys/netinet6/rawsocket.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env atf-sh
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2020 Neel Chauhan
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+atf_test_case "raw_ping" "cleanup"
+raw_ping_head() {
+
+ atf_set descr 'Test valid ICMPv6 raw socket'
+ atf_set require.user root
+}
+
+raw_ping_body() {
+
+ script_name="rawsocket.py"
+ ip="::1"
+
+ atf_check -s exit:0 $(atf_get_srcdir)/${script_name} --ip ${ip}
+}
+
+raw_ping_cleanup() {
+
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case "raw_ping"
+}
+
+# end
+

File Metadata

Mime Type
text/plain
Expires
Mon, May 11, 2:23 PM (7 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28683028
Default Alt Text
D26755.1778509418.diff (9 KB)

Event Timeline