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 ---