ip_fastfwd.c (145863) | ip_fastfwd.c (148324) |
---|---|
1/*- 2 * Copyright (c) 2003 Andre Oppermann, Internet Business Solutions AG 3 * 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) 2003 Andre Oppermann, Internet Business Solutions AG 3 * 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_fastfwd.c 145863 2005-05-04 13:09:19Z andre $ | 29 * $FreeBSD: head/sys/netinet/ip_fastfwd.c 148324 2005-07-23 00:59:13Z keramida $ |
30 */ 31 32/* 33 * ip_fastforward gets its speed from processing the forwarded packet to 34 * completion (if_output on the other side) without any queues or netisr's. 35 * The receiving interface DMAs the packet into memory, the upper half of 36 * driver calls ip_fastforward, we do our routing table lookup and directly | 30 */ 31 32/* 33 * ip_fastforward gets its speed from processing the forwarded packet to 34 * completion (if_output on the other side) without any queues or netisr's. 35 * The receiving interface DMAs the packet into memory, the upper half of 36 * driver calls ip_fastforward, we do our routing table lookup and directly |
37 * send it off to the outgoing interface which DMAs the packet to the | 37 * send it off to the outgoing interface, which DMAs the packet to the |
38 * network card. The only part of the packet we touch with the CPU is the 39 * IP header (unless there are complex firewall rules touching other parts 40 * of the packet, but that is up to you). We are essentially limited by bus 41 * bandwidth and how fast the network card/driver can set up receives and 42 * transmits. 43 * | 38 * network card. The only part of the packet we touch with the CPU is the 39 * IP header (unless there are complex firewall rules touching other parts 40 * of the packet, but that is up to you). We are essentially limited by bus 41 * bandwidth and how fast the network card/driver can set up receives and 42 * transmits. 43 * |
44 * We handle basic errors, ip header errors, checksum errors, | 44 * We handle basic errors, IP header errors, checksum errors, |
45 * destination unreachable, fragmentation and fragmentation needed and | 45 * destination unreachable, fragmentation and fragmentation needed and |
46 * report them via icmp to the sender. | 46 * report them via ICMP to the sender. |
47 * 48 * Else if something is not pure IPv4 unicast forwarding we fall back to 49 * the normal ip_input processing path. We should only be called from 50 * interfaces connected to the outside world. 51 * 52 * Firewalling is fully supported including divert, ipfw fwd and ipfilter 53 * ipnat and address rewrite. 54 * 55 * IPSEC is not supported if this host is a tunnel broker. IPSEC is 56 * supported for connections to/from local host. 57 * 58 * We try to do the least expensive (in CPU ops) checks and operations 59 * first to catch junk with as little overhead as possible. 60 * | 47 * 48 * Else if something is not pure IPv4 unicast forwarding we fall back to 49 * the normal ip_input processing path. We should only be called from 50 * interfaces connected to the outside world. 51 * 52 * Firewalling is fully supported including divert, ipfw fwd and ipfilter 53 * ipnat and address rewrite. 54 * 55 * IPSEC is not supported if this host is a tunnel broker. IPSEC is 56 * supported for connections to/from local host. 57 * 58 * We try to do the least expensive (in CPU ops) checks and operations 59 * first to catch junk with as little overhead as possible. 60 * |
61 * We take full advantage of hardware support for ip checksum and | 61 * We take full advantage of hardware support for IP checksum and |
62 * fragmentation offloading. 63 * 64 * We don't do ICMP redirect in the fast forwarding path. I have had my own 65 * cases where two core routers with Zebra routing suite would send millions | 62 * fragmentation offloading. 63 * 64 * We don't do ICMP redirect in the fast forwarding path. I have had my own 65 * cases where two core routers with Zebra routing suite would send millions |
66 * ICMP redirects to connected hosts if the router to dest was not the default 67 * gateway. In one case it was filling the routing table of a host with close 68 * 300'000 cloned redirect entries until it ran out of kernel memory. However 69 * the networking code proved very robust and it didn't crash or went ill 70 * otherwise. | 66 * ICMP redirects to connected hosts if the destination router was not the 67 * default gateway. In one case it was filling the routing table of a host 68 * with approximately 300.000 cloned redirect entries until it ran out of 69 * kernel memory. However the networking code proved very robust and it didn't 70 * crash or fail in other ways. |
71 */ 72 73/* 74 * Many thanks to Matt Thomas of NetBSD for basic structure of ip_flow.c which 75 * is being followed here. 76 */ 77 78#include "opt_ipfw.h" --- 159 unchanged lines hidden (view full) --- 238 sum = in_cksum(m, hlen); 239 } 240 if (sum) { 241 ipstat.ips_badsum++; 242 goto drop; 243 } 244 245 /* | 71 */ 72 73/* 74 * Many thanks to Matt Thomas of NetBSD for basic structure of ip_flow.c which 75 * is being followed here. 76 */ 77 78#include "opt_ipfw.h" --- 159 unchanged lines hidden (view full) --- 238 sum = in_cksum(m, hlen); 239 } 240 if (sum) { 241 ipstat.ips_badsum++; 242 goto drop; 243 } 244 245 /* |
246 * Remeber that we have checked the IP header and found it valid. | 246 * Remember that we have checked the IP header and found it valid. |
247 */ 248 m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); 249 250 ip_len = ntohs(ip->ip_len); 251 252 /* 253 * Is IP length longer than packet we have got? 254 */ --- 277 unchanged lines hidden (view full) --- 532 * Check if media link state of interface is not down 533 */ 534 if (ifp->if_link_state == LINK_STATE_DOWN) { 535 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); 536 goto consumed; 537 } 538 539 /* | 247 */ 248 m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); 249 250 ip_len = ntohs(ip->ip_len); 251 252 /* 253 * Is IP length longer than packet we have got? 254 */ --- 277 unchanged lines hidden (view full) --- 532 * Check if media link state of interface is not down 533 */ 534 if (ifp->if_link_state == LINK_STATE_DOWN) { 535 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); 536 goto consumed; 537 } 538 539 /* |
540 * Check if packet fits MTU or if hardware will fragement for us | 540 * Check if packet fits MTU or if hardware will fragment for us |
541 */ 542 if (ro.ro_rt->rt_rmx.rmx_mtu) 543 mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); 544 else 545 mtu = ifp->if_mtu; 546 547 if (ip->ip_len <= mtu || 548 (ifp->if_hwassist & CSUM_FRAGMENT && (ip->ip_off & IP_DF) == 0)) { --- 13 unchanged lines hidden (view full) --- 562 */ 563 if (ip->ip_off & IP_DF) { 564 ipstat.ips_cantfrag++; 565 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 566 0, mtu); 567 goto consumed; 568 } else { 569 /* | 541 */ 542 if (ro.ro_rt->rt_rmx.rmx_mtu) 543 mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); 544 else 545 mtu = ifp->if_mtu; 546 547 if (ip->ip_len <= mtu || 548 (ifp->if_hwassist & CSUM_FRAGMENT && (ip->ip_off & IP_DF) == 0)) { --- 13 unchanged lines hidden (view full) --- 562 */ 563 if (ip->ip_off & IP_DF) { 564 ipstat.ips_cantfrag++; 565 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 566 0, mtu); 567 goto consumed; 568 } else { 569 /* |
570 * We have to fragement the packet | 570 * We have to fragment the packet |
571 */ 572 m->m_pkthdr.csum_flags |= CSUM_IP; 573 /* 574 * ip_fragment expects ip_len and ip_off in host byte 575 * order but returns all packets in network byte order 576 */ 577 if (ip_fragment(ip, &m, mtu, ifp->if_hwassist, 578 (~ifp->if_hwassist & CSUM_DELAY_IP))) { --- 44 unchanged lines hidden --- | 571 */ 572 m->m_pkthdr.csum_flags |= CSUM_IP; 573 /* 574 * ip_fragment expects ip_len and ip_off in host byte 575 * order but returns all packets in network byte order 576 */ 577 if (ip_fragment(ip, &m, mtu, ifp->if_hwassist, 578 (~ifp->if_hwassist & CSUM_DELAY_IP))) { --- 44 unchanged lines hidden --- |