ip_divert.c (169462) | ip_divert.c (171746) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/sys/netinet/ip_divert.c 169462 2007-05-11 10:20:51Z rwatson $ | 29 * $FreeBSD: head/sys/netinet/ip_divert.c 171746 2007-08-06 22:06:36Z csjp $ |
30 */ 31 32#if !defined(KLD_MODULE) 33#include "opt_inet.h" 34#include "opt_ipfw.h" 35#include "opt_mac.h" 36#ifndef INET 37#error "IPDIVERT requires INET." --- 18 unchanged lines hidden (view full) --- 56#include <sys/socketvar.h> 57#include <sys/sx.h> 58#include <sys/sysctl.h> 59#include <sys/systm.h> 60 61#include <vm/uma.h> 62 63#include <net/if.h> | 30 */ 31 32#if !defined(KLD_MODULE) 33#include "opt_inet.h" 34#include "opt_ipfw.h" 35#include "opt_mac.h" 36#ifndef INET 37#error "IPDIVERT requires INET." --- 18 unchanged lines hidden (view full) --- 56#include <sys/socketvar.h> 57#include <sys/sx.h> 58#include <sys/sysctl.h> 59#include <sys/systm.h> 60 61#include <vm/uma.h> 62 63#include <net/if.h> |
64#include <net/netisr.h> |
|
64#include <net/route.h> 65 66#include <netinet/in.h> 67#include <netinet/in_pcb.h> 68#include <netinet/in_systm.h> 69#include <netinet/in_var.h> 70#include <netinet/ip.h> 71#include <netinet/ip_divert.h> --- 228 unchanged lines hidden (view full) --- 300 */ 301static int 302div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, 303 struct mbuf *control) 304{ 305 struct m_tag *mtag; 306 struct divert_tag *dt; 307 int error = 0; | 65#include <net/route.h> 66 67#include <netinet/in.h> 68#include <netinet/in_pcb.h> 69#include <netinet/in_systm.h> 70#include <netinet/in_var.h> 71#include <netinet/ip.h> 72#include <netinet/ip_divert.h> --- 228 unchanged lines hidden (view full) --- 301 */ 302static int 303div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, 304 struct mbuf *control) 305{ 306 struct m_tag *mtag; 307 struct divert_tag *dt; 308 int error = 0; |
309 struct mbuf *options; |
|
308 309 /* 310 * An mbuf may hasn't come from userland, but we pretend 311 * that it has. 312 */ 313 m->m_pkthdr.rcvif = NULL; 314 m->m_nextpkt = NULL; 315 --- 40 unchanged lines hidden (view full) --- 356 INP_LOCK(inp); 357 /* 358 * Don't allow both user specified and setsockopt options, 359 * and don't allow packet length sizes that will crash 360 */ 361 if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) || 362 ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { 363 error = EINVAL; | 310 311 /* 312 * An mbuf may hasn't come from userland, but we pretend 313 * that it has. 314 */ 315 m->m_pkthdr.rcvif = NULL; 316 m->m_nextpkt = NULL; 317 --- 40 unchanged lines hidden (view full) --- 358 INP_LOCK(inp); 359 /* 360 * Don't allow both user specified and setsockopt options, 361 * and don't allow packet length sizes that will crash 362 */ 363 if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) || 364 ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { 365 error = EINVAL; |
366 INP_UNLOCK(inp); 367 INP_INFO_WUNLOCK(&divcbinfo); |
|
364 m_freem(m); 365 } else { 366 /* Convert fields to host order for ip_output() */ 367 ip->ip_len = ntohs(ip->ip_len); 368 ip->ip_off = ntohs(ip->ip_off); 369 370 /* Send packet to output processing */ 371 ipstat.ips_rawout++; /* XXX */ 372 373#ifdef MAC 374 mac_create_mbuf_from_inpcb(inp, m); 375#endif | 368 m_freem(m); 369 } else { 370 /* Convert fields to host order for ip_output() */ 371 ip->ip_len = ntohs(ip->ip_len); 372 ip->ip_off = ntohs(ip->ip_off); 373 374 /* Send packet to output processing */ 375 ipstat.ips_rawout++; /* XXX */ 376 377#ifdef MAC 378 mac_create_mbuf_from_inpcb(inp, m); 379#endif |
376 error = ip_output(m, 377 inp->inp_options, NULL, 378 ((so->so_options & SO_DONTROUTE) ? 379 IP_ROUTETOIF : 0) | 380 IP_ALLOWBROADCAST | IP_RAWOUTPUT, 381 inp->inp_moptions, NULL); | 380 /* 381 * Get ready to inject the packet into ip_output(). 382 * Just in case socket options were specified on the 383 * divert socket, we duplicate them. This is done 384 * to avoid having to hold the PCB locks over the call 385 * to ip_output(), as doing this results in a number of 386 * lock ordering complexities. 387 * 388 * Note that we set the multicast options argument for 389 * ip_output() to NULL since it should be invariant that 390 * they are not present. 391 */ 392 KASSERT(inp->inp_moptions == NULL, 393 ("multicast options set on a divert socket")); 394 options = NULL; 395 /* 396 * XXXCSJP: It is unclear to me whether or not it makes 397 * sense for divert sockets to have options. However, 398 * for now we will duplicate them with the INP locks 399 * held so we can use them in ip_output() without 400 * requring a reference to the pcb. 401 */ 402 if (inp->inp_options != NULL) { 403 options = m_dup(inp->inp_options, M_DONTWAIT); 404 if (options == NULL) 405 error = ENOBUFS; 406 } 407 INP_UNLOCK(inp); 408 INP_INFO_WUNLOCK(&divcbinfo); 409 if (error == ENOBUFS) { 410 m_freem(m); 411 return (error); 412 } 413 error = ip_output(m, options, NULL, 414 ((so->so_options & SO_DONTROUTE) ? 415 IP_ROUTETOIF : 0) | IP_ALLOWBROADCAST | 416 IP_RAWOUTPUT, NULL, NULL); 417 if (options != NULL) 418 m_freem(options); |
382 } | 419 } |
383 INP_UNLOCK(inp); 384 INP_INFO_WUNLOCK(&divcbinfo); | |
385 } else { 386 dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG; 387 if (m->m_pkthdr.rcvif == NULL) { 388 /* 389 * No luck with the name, check by IP address. 390 * Clear the port and the ifname to make sure 391 * there are no distractions for ifa_ifwithaddr. 392 */ --- 8 unchanged lines hidden (view full) --- 401 } 402 m->m_pkthdr.rcvif = ifa->ifa_ifp; 403 } 404#ifdef MAC 405 SOCK_LOCK(so); 406 mac_create_mbuf_from_socket(so, m); 407 SOCK_UNLOCK(so); 408#endif | 420 } else { 421 dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG; 422 if (m->m_pkthdr.rcvif == NULL) { 423 /* 424 * No luck with the name, check by IP address. 425 * Clear the port and the ifname to make sure 426 * there are no distractions for ifa_ifwithaddr. 427 */ --- 8 unchanged lines hidden (view full) --- 436 } 437 m->m_pkthdr.rcvif = ifa->ifa_ifp; 438 } 439#ifdef MAC 440 SOCK_LOCK(so); 441 mac_create_mbuf_from_socket(so, m); 442 SOCK_UNLOCK(so); 443#endif |
409 /* Send packet to input processing */ 410 ip_input(m); | 444 /* Send packet to input processing via netisr */ 445 netisr_queue(NETISR_IP, m); |
411 } 412 413 return error; 414 415cantsend: 416 m_freem(m); 417 return error; 418} --- 302 unchanged lines hidden --- | 446 } 447 448 return error; 449 450cantsend: 451 m_freem(m); 452 return error; 453} --- 302 unchanged lines hidden --- |