ip_fastfwd.c (6d4b97158fa99be390dba1c61c1d1f547852aef6) | ip_fastfwd.c (21d172a3f17d63c16991f0313fe5de2353043d5b) |
---|---|
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 --- 150 unchanged lines hidden (view full) --- 159ip_fastforward(struct mbuf *m) 160{ 161 struct ip *ip; 162 struct mbuf *m0 = NULL; 163 struct route ro; 164 struct sockaddr_in *dst = NULL; 165 struct ifnet *ifp; 166 struct in_addr odest, dest; | 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 --- 150 unchanged lines hidden (view full) --- 159ip_fastforward(struct mbuf *m) 160{ 161 struct ip *ip; 162 struct mbuf *m0 = NULL; 163 struct route ro; 164 struct sockaddr_in *dst = NULL; 165 struct ifnet *ifp; 166 struct in_addr odest, dest; |
167 u_short sum, ip_len; | 167 uint16_t sum, ip_len, ip_off; |
168 int error = 0; 169 int hlen, mtu; 170#ifdef IPFIREWALL_FORWARD 171 struct m_tag *fwd_tag; 172#endif 173 174 /* 175 * Are we active and forwarding packets? --- 159 unchanged lines hidden (view full) --- 335 return m; 336 337 IPSTAT_INC(ips_total); 338 339 /* 340 * Step 3: incoming packet firewall processing 341 */ 342 | 168 int error = 0; 169 int hlen, mtu; 170#ifdef IPFIREWALL_FORWARD 171 struct m_tag *fwd_tag; 172#endif 173 174 /* 175 * Are we active and forwarding packets? --- 159 unchanged lines hidden (view full) --- 335 return m; 336 337 IPSTAT_INC(ips_total); 338 339 /* 340 * Step 3: incoming packet firewall processing 341 */ 342 |
343 /* 344 * Convert to host representation 345 */ 346 ip->ip_len = ntohs(ip->ip_len); 347 ip->ip_off = ntohs(ip->ip_off); 348 | |
349 odest.s_addr = dest.s_addr = ip->ip_dst.s_addr; 350 351 /* 352 * Run through list of ipfilter hooks for input packets 353 */ 354 if (!PFIL_HOOKED(&V_inet_pfil_hook)) 355 goto passin; 356 --- 110 unchanged lines hidden (view full) --- 467#ifndef IPFIREWALL_FORWARD 468 if (in_localip(dest)) { 469#else 470 if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { 471#endif /* IPFIREWALL_FORWARD */ 472forwardlocal: 473 /* 474 * Return packet for processing by ip_input(). | 343 odest.s_addr = dest.s_addr = ip->ip_dst.s_addr; 344 345 /* 346 * Run through list of ipfilter hooks for input packets 347 */ 348 if (!PFIL_HOOKED(&V_inet_pfil_hook)) 349 goto passin; 350 --- 110 unchanged lines hidden (view full) --- 461#ifndef IPFIREWALL_FORWARD 462 if (in_localip(dest)) { 463#else 464 if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { 465#endif /* IPFIREWALL_FORWARD */ 466forwardlocal: 467 /* 468 * Return packet for processing by ip_input(). |
475 * Keep host byte order as expected at ip_input's 476 * "ours"-label. | |
477 */ 478 m->m_flags |= M_FASTFWD_OURS; 479 if (ro.ro_rt) 480 RTFREE(ro.ro_rt); 481 return m; 482 } 483 /* 484 * Redo route lookup with new destination address --- 10 unchanged lines hidden (view full) --- 495 return NULL; /* icmp unreach already sent */ 496 ifp = ro.ro_rt->rt_ifp; 497 } 498 499passout: 500 /* 501 * Step 6: send off the packet 502 */ | 469 */ 470 m->m_flags |= M_FASTFWD_OURS; 471 if (ro.ro_rt) 472 RTFREE(ro.ro_rt); 473 return m; 474 } 475 /* 476 * Redo route lookup with new destination address --- 10 unchanged lines hidden (view full) --- 487 return NULL; /* icmp unreach already sent */ 488 ifp = ro.ro_rt->rt_ifp; 489 } 490 491passout: 492 /* 493 * Step 6: send off the packet 494 */ |
495 ip_len = ntohs(ip->ip_len); 496 ip_off = ntohs(ip->ip_off); |
|
503 504 /* 505 * Check if route is dampned (when ARP is unable to resolve) 506 */ 507 if ((ro.ro_rt->rt_flags & RTF_REJECT) && 508 (ro.ro_rt->rt_rmx.rmx_expire == 0 || 509 time_uptime < ro.ro_rt->rt_rmx.rmx_expire)) { 510 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); 511 goto consumed; 512 } 513 514#ifndef ALTQ 515 /* 516 * Check if there is enough space in the interface queue 517 */ | 497 498 /* 499 * Check if route is dampned (when ARP is unable to resolve) 500 */ 501 if ((ro.ro_rt->rt_flags & RTF_REJECT) && 502 (ro.ro_rt->rt_rmx.rmx_expire == 0 || 503 time_uptime < ro.ro_rt->rt_rmx.rmx_expire)) { 504 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); 505 goto consumed; 506 } 507 508#ifndef ALTQ 509 /* 510 * Check if there is enough space in the interface queue 511 */ |
518 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= | 512 if ((ifp->if_snd.ifq_len + ip_len / ifp->if_mtu + 1) >= |
519 ifp->if_snd.ifq_maxlen) { 520 IPSTAT_INC(ips_odropped); 521 /* would send source quench here but that is depreciated */ 522 goto drop; 523 } 524#endif 525 526 /* --- 7 unchanged lines hidden (view full) --- 534 /* 535 * Check if packet fits MTU or if hardware will fragment for us 536 */ 537 if (ro.ro_rt->rt_rmx.rmx_mtu) 538 mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); 539 else 540 mtu = ifp->if_mtu; 541 | 513 ifp->if_snd.ifq_maxlen) { 514 IPSTAT_INC(ips_odropped); 515 /* would send source quench here but that is depreciated */ 516 goto drop; 517 } 518#endif 519 520 /* --- 7 unchanged lines hidden (view full) --- 528 /* 529 * Check if packet fits MTU or if hardware will fragment for us 530 */ 531 if (ro.ro_rt->rt_rmx.rmx_mtu) 532 mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); 533 else 534 mtu = ifp->if_mtu; 535 |
542 if (ip->ip_len <= mtu || 543 (ifp->if_hwassist & CSUM_FRAGMENT && (ip->ip_off & IP_DF) == 0)) { | 536 if (ip_len <= mtu || 537 (ifp->if_hwassist & CSUM_FRAGMENT && (ip_off & IP_DF) == 0)) { |
544 /* | 538 /* |
545 * Restore packet header fields to original values 546 */ 547 ip->ip_len = htons(ip->ip_len); 548 ip->ip_off = htons(ip->ip_off); 549 /* | |
550 * Send off the packet via outgoing interface 551 */ 552 error = (*ifp->if_output)(ifp, m, 553 (struct sockaddr *)dst, &ro); 554 } else { 555 /* 556 * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery 557 */ | 539 * Send off the packet via outgoing interface 540 */ 541 error = (*ifp->if_output)(ifp, m, 542 (struct sockaddr *)dst, &ro); 543 } else { 544 /* 545 * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery 546 */ |
558 if (ip->ip_off & IP_DF) { | 547 if (ip_off & IP_DF) { |
559 IPSTAT_INC(ips_cantfrag); 560 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 561 0, mtu); 562 goto consumed; 563 } else { 564 /* 565 * We have to fragment the packet 566 */ 567 m->m_pkthdr.csum_flags |= CSUM_IP; | 548 IPSTAT_INC(ips_cantfrag); 549 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 550 0, mtu); 551 goto consumed; 552 } else { 553 /* 554 * We have to fragment the packet 555 */ 556 m->m_pkthdr.csum_flags |= CSUM_IP; |
568 /* 569 * ip_fragment expects ip_len and ip_off in host byte 570 * order but returns all packets in network byte order 571 */ | |
572 if (ip_fragment(ip, &m, mtu, ifp->if_hwassist, 573 (~ifp->if_hwassist & CSUM_DELAY_IP))) { 574 goto drop; 575 } 576 KASSERT(m != NULL, ("null mbuf and no error")); 577 /* 578 * Send off the fragments via outgoing interface 579 */ --- 38 unchanged lines hidden --- | 557 if (ip_fragment(ip, &m, mtu, ifp->if_hwassist, 558 (~ifp->if_hwassist & CSUM_DELAY_IP))) { 559 goto drop; 560 } 561 KASSERT(m != NULL, ("null mbuf and no error")); 562 /* 563 * Send off the fragments via outgoing interface 564 */ --- 38 unchanged lines hidden --- |