Deleted Added
full compact
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 ---