The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/ip_output.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1982, 1986, 1988, 1990, 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
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   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  *      @(#)ip_output.c 8.3 (Berkeley) 1/21/94
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include "opt_ipfw.h"
   36 #include "opt_ipsec.h"
   37 #include "opt_mac.h"
   38 #include "opt_mbuf_stress_test.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/kernel.h>
   43 #include <sys/malloc.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/priv.h>
   46 #include <sys/protosw.h>
   47 #include <sys/socket.h>
   48 #include <sys/socketvar.h>
   49 #include <sys/sysctl.h>
   50 
   51 #include <net/if.h>
   52 #include <net/netisr.h>
   53 #include <net/pfil.h>
   54 #include <net/route.h>
   55 
   56 #include <netinet/in.h>
   57 #include <netinet/in_systm.h>
   58 #include <netinet/ip.h>
   59 #include <netinet/in_pcb.h>
   60 #include <netinet/in_var.h>
   61 #include <netinet/ip_var.h>
   62 #include <netinet/ip_options.h>
   63 
   64 #ifdef IPSEC
   65 #include <netinet/ip_ipsec.h>
   66 #include <netipsec/ipsec.h>
   67 #endif /* IPSEC*/
   68 
   69 #include <machine/in_cksum.h>
   70 
   71 #include <security/mac/mac_framework.h>
   72 
   73 #define print_ip(x, a, y)        printf("%s %d.%d.%d.%d%s",\
   74                                 x, (ntohl(a.s_addr)>>24)&0xFF,\
   75                                   (ntohl(a.s_addr)>>16)&0xFF,\
   76                                   (ntohl(a.s_addr)>>8)&0xFF,\
   77                                   (ntohl(a.s_addr))&0xFF, y);
   78 
   79 u_short ip_id;
   80 
   81 #ifdef MBUF_STRESS_TEST
   82 int mbuf_frag_size = 0;
   83 SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_frag_size, CTLFLAG_RW,
   84         &mbuf_frag_size, 0, "Fragment outgoing mbufs to this size");
   85 #endif
   86 
   87 static void     ip_mloopback
   88         (struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
   89 
   90 
   91 extern  struct protosw inetsw[];
   92 
   93 /*
   94  * IP output.  The packet in mbuf chain m contains a skeletal IP
   95  * header (with len, off, ttl, proto, tos, src, dst).
   96  * The mbuf chain containing the packet will be freed.
   97  * The mbuf opt, if present, will not be freed.
   98  * In the IP forwarding case, the packet will arrive with options already
   99  * inserted, so must have a NULL opt pointer.
  100  */
  101 int
  102 ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
  103     struct ip_moptions *imo, struct inpcb *inp)
  104 {
  105         struct ip *ip;
  106         struct ifnet *ifp = NULL;       /* keep compiler happy */
  107         struct mbuf *m0;
  108         int hlen = sizeof (struct ip);
  109         int mtu;
  110         int len, error = 0;
  111         struct sockaddr_in *dst = NULL; /* keep compiler happy */
  112         struct in_ifaddr *ia = NULL;
  113         int isbroadcast, sw_csum;
  114         struct route iproute;
  115         struct in_addr odst;
  116 #ifdef IPFIREWALL_FORWARD
  117         struct m_tag *fwd_tag = NULL;
  118 #endif
  119         M_ASSERTPKTHDR(m);
  120 
  121         if (ro == NULL) {
  122                 ro = &iproute;
  123                 bzero(ro, sizeof (*ro));
  124         }
  125 
  126         if (inp != NULL)
  127                 INP_LOCK_ASSERT(inp);
  128 
  129         if (opt) {
  130                 len = 0;
  131                 m = ip_insertoptions(m, opt, &len);
  132                 if (len != 0)
  133                         hlen = len;
  134         }
  135         ip = mtod(m, struct ip *);
  136 
  137         /*
  138          * Fill in IP header.  If we are not allowing fragmentation,
  139          * then the ip_id field is meaningless, but we don't set it
  140          * to zero.  Doing so causes various problems when devices along
  141          * the path (routers, load balancers, firewalls, etc.) illegally
  142          * disable DF on our packet.  Note that a 16-bit counter
  143          * will wrap around in less than 10 seconds at 100 Mbit/s on a
  144          * medium with MTU 1500.  See Steven M. Bellovin, "A Technique
  145          * for Counting NATted Hosts", Proc. IMW'02, available at
  146          * <http://www.cs.columbia.edu/~smb/papers/fnat.pdf>.
  147          */
  148         if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
  149                 ip->ip_v = IPVERSION;
  150                 ip->ip_hl = hlen >> 2;
  151                 ip->ip_id = ip_newid();
  152                 ipstat.ips_localout++;
  153         } else {
  154                 hlen = ip->ip_hl << 2;
  155         }
  156 
  157         dst = (struct sockaddr_in *)&ro->ro_dst;
  158 again:
  159         /*
  160          * If there is a cached route,
  161          * check that it is to the same destination
  162          * and is still up.  If not, free it and try again.
  163          * The address family should also be checked in case of sharing the
  164          * cache with IPv6.
  165          */
  166         if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
  167                           dst->sin_family != AF_INET ||
  168                           dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
  169                 RTFREE(ro->ro_rt);
  170                 ro->ro_rt = (struct rtentry *)NULL;
  171         }
  172 #ifdef IPFIREWALL_FORWARD
  173         if (ro->ro_rt == NULL && fwd_tag == NULL) {
  174 #else
  175         if (ro->ro_rt == NULL) {
  176 #endif
  177                 bzero(dst, sizeof(*dst));
  178                 dst->sin_family = AF_INET;
  179                 dst->sin_len = sizeof(*dst);
  180                 dst->sin_addr = ip->ip_dst;
  181         }
  182         /*
  183          * If routing to interface only, short circuit routing lookup.
  184          * The use of an all-ones broadcast address implies this; an
  185          * interface is specified by the broadcast address of an interface,
  186          * or the destination address of a ptp interface.
  187          */
  188         if (flags & IP_SENDONES) {
  189                 if ((ia = ifatoia(ifa_ifwithbroadaddr(sintosa(dst)))) == NULL &&
  190                     (ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL) {
  191                         ipstat.ips_noroute++;
  192                         error = ENETUNREACH;
  193                         goto bad;
  194                 }
  195                 ip->ip_dst.s_addr = INADDR_BROADCAST;
  196                 dst->sin_addr = ip->ip_dst;
  197                 ifp = ia->ia_ifp;
  198                 ip->ip_ttl = 1;
  199                 isbroadcast = 1;
  200         } else if (flags & IP_ROUTETOIF) {
  201                 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL &&
  202                     (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == NULL) {
  203                         ipstat.ips_noroute++;
  204                         error = ENETUNREACH;
  205                         goto bad;
  206                 }
  207                 ifp = ia->ia_ifp;
  208                 ip->ip_ttl = 1;
  209                 isbroadcast = in_broadcast(dst->sin_addr, ifp);
  210         } else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
  211             imo != NULL && imo->imo_multicast_ifp != NULL) {
  212                 /*
  213                  * Bypass the normal routing lookup for multicast
  214                  * packets if the interface is specified.
  215                  */
  216                 ifp = imo->imo_multicast_ifp;
  217                 IFP_TO_IA(ifp, ia);
  218                 isbroadcast = 0;        /* fool gcc */
  219         } else {
  220                 /*
  221                  * We want to do any cloning requested by the link layer,
  222                  * as this is probably required in all cases for correct
  223                  * operation (as it is for ARP).
  224                  */
  225                 if (ro->ro_rt == NULL)
  226                         rtalloc_ign(ro, 0);
  227                 if (ro->ro_rt == NULL) {
  228                         ipstat.ips_noroute++;
  229                         error = EHOSTUNREACH;
  230                         goto bad;
  231                 }
  232                 ia = ifatoia(ro->ro_rt->rt_ifa);
  233                 ifp = ro->ro_rt->rt_ifp;
  234                 ro->ro_rt->rt_rmx.rmx_pksent++;
  235                 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
  236                         dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
  237                 if (ro->ro_rt->rt_flags & RTF_HOST)
  238                         isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
  239                 else
  240                         isbroadcast = in_broadcast(dst->sin_addr, ifp);
  241         }
  242         /*
  243          * Calculate MTU.  If we have a route that is up, use that,
  244          * otherwise use the interface's MTU.
  245          */
  246         if (ro->ro_rt != NULL && (ro->ro_rt->rt_flags & (RTF_UP|RTF_HOST))) {
  247                 /*
  248                  * This case can happen if the user changed the MTU
  249                  * of an interface after enabling IP on it.  Because
  250                  * most netifs don't keep track of routes pointing to
  251                  * them, there is no way for one to update all its
  252                  * routes when the MTU is changed.
  253                  */
  254                 if (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)
  255                         ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
  256                 mtu = ro->ro_rt->rt_rmx.rmx_mtu;
  257         } else {
  258                 mtu = ifp->if_mtu;
  259         }
  260         if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
  261                 struct in_multi *inm;
  262 
  263                 m->m_flags |= M_MCAST;
  264                 /*
  265                  * IP destination address is multicast.  Make sure "dst"
  266                  * still points to the address in "ro".  (It may have been
  267                  * changed to point to a gateway address, above.)
  268                  */
  269                 dst = (struct sockaddr_in *)&ro->ro_dst;
  270                 /*
  271                  * See if the caller provided any multicast options
  272                  */
  273                 if (imo != NULL) {
  274                         ip->ip_ttl = imo->imo_multicast_ttl;
  275                         if (imo->imo_multicast_vif != -1)
  276                                 ip->ip_src.s_addr =
  277                                     ip_mcast_src ?
  278                                     ip_mcast_src(imo->imo_multicast_vif) :
  279                                     INADDR_ANY;
  280                 } else
  281                         ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
  282                 /*
  283                  * Confirm that the outgoing interface supports multicast.
  284                  */
  285                 if ((imo == NULL) || (imo->imo_multicast_vif == -1)) {
  286                         if ((ifp->if_flags & IFF_MULTICAST) == 0) {
  287                                 ipstat.ips_noroute++;
  288                                 error = ENETUNREACH;
  289                                 goto bad;
  290                         }
  291                 }
  292                 /*
  293                  * If source address not specified yet, use address
  294                  * of outgoing interface.
  295                  */
  296                 if (ip->ip_src.s_addr == INADDR_ANY) {
  297                         /* Interface may have no addresses. */
  298                         if (ia != NULL)
  299                                 ip->ip_src = IA_SIN(ia)->sin_addr;
  300                 }
  301 
  302                 IN_MULTI_LOCK();
  303                 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
  304                 if (inm != NULL &&
  305                    (imo == NULL || imo->imo_multicast_loop)) {
  306                         IN_MULTI_UNLOCK();
  307                         /*
  308                          * If we belong to the destination multicast group
  309                          * on the outgoing interface, and the caller did not
  310                          * forbid loopback, loop back a copy.
  311                          */
  312                         ip_mloopback(ifp, m, dst, hlen);
  313                 }
  314                 else {
  315                         IN_MULTI_UNLOCK();
  316                         /*
  317                          * If we are acting as a multicast router, perform
  318                          * multicast forwarding as if the packet had just
  319                          * arrived on the interface to which we are about
  320                          * to send.  The multicast forwarding function
  321                          * recursively calls this function, using the
  322                          * IP_FORWARDING flag to prevent infinite recursion.
  323                          *
  324                          * Multicasts that are looped back by ip_mloopback(),
  325                          * above, will be forwarded by the ip_input() routine,
  326                          * if necessary.
  327                          */
  328                         if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
  329                                 /*
  330                                  * If rsvp daemon is not running, do not
  331                                  * set ip_moptions. This ensures that the packet
  332                                  * is multicast and not just sent down one link
  333                                  * as prescribed by rsvpd.
  334                                  */
  335                                 if (!rsvp_on)
  336                                         imo = NULL;
  337                                 if (ip_mforward &&
  338                                     ip_mforward(ip, ifp, m, imo) != 0) {
  339                                         m_freem(m);
  340                                         goto done;
  341                                 }
  342                         }
  343                 }
  344 
  345                 /*
  346                  * Multicasts with a time-to-live of zero may be looped-
  347                  * back, above, but must not be transmitted on a network.
  348                  * Also, multicasts addressed to the loopback interface
  349                  * are not sent -- the above call to ip_mloopback() will
  350                  * loop back a copy if this host actually belongs to the
  351                  * destination group on the loopback interface.
  352                  */
  353                 if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) {
  354                         m_freem(m);
  355                         goto done;
  356                 }
  357 
  358                 goto sendit;
  359         }
  360 
  361         /*
  362          * If the source address is not specified yet, use the address
  363          * of the outoing interface.
  364          */
  365         if (ip->ip_src.s_addr == INADDR_ANY) {
  366                 /* Interface may have no addresses. */
  367                 if (ia != NULL) {
  368                         ip->ip_src = IA_SIN(ia)->sin_addr;
  369                 }
  370         }
  371 
  372         /*
  373          * Verify that we have any chance at all of being able to queue the
  374          * packet or packet fragments, unless ALTQ is enabled on the given
  375          * interface in which case packetdrop should be done by queueing.
  376          */
  377 #ifdef ALTQ
  378         if ((!ALTQ_IS_ENABLED(&ifp->if_snd)) &&
  379             ((ifp->if_snd.ifq_len + ip->ip_len / mtu + 1) >=
  380             ifp->if_snd.ifq_maxlen))
  381 #else
  382         if ((ifp->if_snd.ifq_len + ip->ip_len / mtu + 1) >=
  383             ifp->if_snd.ifq_maxlen)
  384 #endif /* ALTQ */
  385         {
  386                 error = ENOBUFS;
  387                 ipstat.ips_odropped++;
  388                 ifp->if_snd.ifq_drops += (ip->ip_len / ifp->if_mtu + 1);
  389                 goto bad;
  390         }
  391 
  392         /*
  393          * Look for broadcast address and
  394          * verify user is allowed to send
  395          * such a packet.
  396          */
  397         if (isbroadcast) {
  398                 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
  399                         error = EADDRNOTAVAIL;
  400                         goto bad;
  401                 }
  402                 if ((flags & IP_ALLOWBROADCAST) == 0) {
  403                         error = EACCES;
  404                         goto bad;
  405                 }
  406                 /* don't allow broadcast messages to be fragmented */
  407                 if (ip->ip_len > mtu) {
  408                         error = EMSGSIZE;
  409                         goto bad;
  410                 }
  411                 m->m_flags |= M_BCAST;
  412         } else {
  413                 m->m_flags &= ~M_BCAST;
  414         }
  415 
  416 sendit:
  417 #ifdef IPSEC
  418         switch(ip_ipsec_output(&m, inp, &flags, &error, &ro, &iproute, &dst, &ia, &ifp)) {
  419         case 1:
  420                 goto bad;
  421         case -1:
  422                 goto done;
  423         case 0:
  424         default:
  425                 break;  /* Continue with packet processing. */
  426         }
  427         /* Update variables that are affected by ipsec4_output(). */
  428         ip = mtod(m, struct ip *);
  429         hlen = ip->ip_hl << 2;
  430 #endif /* IPSEC */
  431 
  432         /* Jump over all PFIL processing if hooks are not active. */
  433         if (!PFIL_HOOKED(&inet_pfil_hook))
  434                 goto passout;
  435 
  436         /* Run through list of hooks for output packets. */
  437         odst.s_addr = ip->ip_dst.s_addr;
  438         error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, inp);
  439         if (error != 0 || m == NULL)
  440                 goto done;
  441 
  442         ip = mtod(m, struct ip *);
  443 
  444         /* See if destination IP address was changed by packet filter. */
  445         if (odst.s_addr != ip->ip_dst.s_addr) {
  446                 m->m_flags |= M_SKIP_FIREWALL;
  447                 /* If destination is now ourself drop to ip_input(). */
  448                 if (in_localip(ip->ip_dst)) {
  449                         m->m_flags |= M_FASTFWD_OURS;
  450                         if (m->m_pkthdr.rcvif == NULL)
  451                                 m->m_pkthdr.rcvif = loif;
  452                         if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
  453                                 m->m_pkthdr.csum_flags |=
  454                                     CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
  455                                 m->m_pkthdr.csum_data = 0xffff;
  456                         }
  457                         m->m_pkthdr.csum_flags |=
  458                             CSUM_IP_CHECKED | CSUM_IP_VALID;
  459 
  460                         error = netisr_queue(NETISR_IP, m);
  461                         goto done;
  462                 } else
  463                         goto again;     /* Redo the routing table lookup. */
  464         }
  465 
  466 #ifdef IPFIREWALL_FORWARD
  467         /* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */
  468         if (m->m_flags & M_FASTFWD_OURS) {
  469                 if (m->m_pkthdr.rcvif == NULL)
  470                         m->m_pkthdr.rcvif = loif;
  471                 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
  472                         m->m_pkthdr.csum_flags |=
  473                             CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
  474                         m->m_pkthdr.csum_data = 0xffff;
  475                 }
  476                 m->m_pkthdr.csum_flags |=
  477                             CSUM_IP_CHECKED | CSUM_IP_VALID;
  478 
  479                 error = netisr_queue(NETISR_IP, m);
  480                 goto done;
  481         }
  482         /* Or forward to some other address? */
  483         fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
  484         if (fwd_tag) {
  485                 dst = (struct sockaddr_in *)&ro->ro_dst;
  486                 bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in));
  487                 m->m_flags |= M_SKIP_FIREWALL;
  488                 m_tag_delete(m, fwd_tag);
  489                 goto again;
  490         }
  491 #endif /* IPFIREWALL_FORWARD */
  492 
  493 passout:
  494         /* 127/8 must not appear on wire - RFC1122. */
  495         if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
  496             (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
  497                 if ((ifp->if_flags & IFF_LOOPBACK) == 0) {
  498                         ipstat.ips_badaddr++;
  499                         error = EADDRNOTAVAIL;
  500                         goto bad;
  501                 }
  502         }
  503 
  504         m->m_pkthdr.csum_flags |= CSUM_IP;
  505         sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
  506         if (sw_csum & CSUM_DELAY_DATA) {
  507                 in_delayed_cksum(m);
  508                 sw_csum &= ~CSUM_DELAY_DATA;
  509         }
  510         m->m_pkthdr.csum_flags &= ifp->if_hwassist;
  511 
  512         /*
  513          * If small enough for interface, or the interface will take
  514          * care of the fragmentation for us, we can just send directly.
  515          */
  516         if (ip->ip_len <= mtu ||
  517             (m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 ||
  518             ((ip->ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) {
  519                 ip->ip_len = htons(ip->ip_len);
  520                 ip->ip_off = htons(ip->ip_off);
  521                 ip->ip_sum = 0;
  522                 if (sw_csum & CSUM_DELAY_IP)
  523                         ip->ip_sum = in_cksum(m, hlen);
  524 
  525                 /*
  526                  * Record statistics for this interface address.
  527                  * With CSUM_TSO the byte/packet count will be slightly
  528                  * incorrect because we count the IP+TCP headers only
  529                  * once instead of for every generated packet.
  530                  */
  531                 if (!(flags & IP_FORWARDING) && ia) {
  532                         if (m->m_pkthdr.csum_flags & CSUM_TSO)
  533                                 ia->ia_ifa.if_opackets +=
  534                                     m->m_pkthdr.len / m->m_pkthdr.tso_segsz;
  535                         else
  536                                 ia->ia_ifa.if_opackets++;
  537                         ia->ia_ifa.if_obytes += m->m_pkthdr.len;
  538                 }
  539 #ifdef MBUF_STRESS_TEST
  540                 if (mbuf_frag_size && m->m_pkthdr.len > mbuf_frag_size)
  541                         m = m_fragment(m, M_DONTWAIT, mbuf_frag_size);
  542 #endif
  543                 /*
  544                  * Reset layer specific mbuf flags
  545                  * to avoid confusing lower layers.
  546                  */
  547                 m->m_flags &= ~(M_PROTOFLAGS);
  548 
  549                 error = (*ifp->if_output)(ifp, m,
  550                                 (struct sockaddr *)dst, ro->ro_rt);
  551                 goto done;
  552         }
  553 
  554         /* Balk when DF bit is set or the interface didn't support TSO. */
  555         if ((ip->ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) {
  556                 error = EMSGSIZE;
  557                 ipstat.ips_cantfrag++;
  558                 goto bad;
  559         }
  560 
  561         /*
  562          * Too large for interface; fragment if possible. If successful,
  563          * on return, m will point to a list of packets to be sent.
  564          */
  565         error = ip_fragment(ip, &m, mtu, ifp->if_hwassist, sw_csum);
  566         if (error)
  567                 goto bad;
  568         for (; m; m = m0) {
  569                 m0 = m->m_nextpkt;
  570                 m->m_nextpkt = 0;
  571                 if (error == 0) {
  572                         /* Record statistics for this interface address. */
  573                         if (ia != NULL) {
  574                                 ia->ia_ifa.if_opackets++;
  575                                 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
  576                         }
  577                         /*
  578                          * Reset layer specific mbuf flags
  579                          * to avoid confusing upper layers.
  580                          */
  581                         m->m_flags &= ~(M_PROTOFLAGS);
  582 
  583                         error = (*ifp->if_output)(ifp, m,
  584                             (struct sockaddr *)dst, ro->ro_rt);
  585                 } else
  586                         m_freem(m);
  587         }
  588 
  589         if (error == 0)
  590                 ipstat.ips_fragmented++;
  591 
  592 done:
  593         if (ro == &iproute && ro->ro_rt) {
  594                 RTFREE(ro->ro_rt);
  595         }
  596         return (error);
  597 bad:
  598         m_freem(m);
  599         goto done;
  600 }
  601 
  602 /*
  603  * Create a chain of fragments which fit the given mtu. m_frag points to the
  604  * mbuf to be fragmented; on return it points to the chain with the fragments.
  605  * Return 0 if no error. If error, m_frag may contain a partially built
  606  * chain of fragments that should be freed by the caller.
  607  *
  608  * if_hwassist_flags is the hw offload capabilities (see if_data.ifi_hwassist)
  609  * sw_csum contains the delayed checksums flags (e.g., CSUM_DELAY_IP).
  610  */
  611 int
  612 ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
  613     u_long if_hwassist_flags, int sw_csum)
  614 {
  615         int error = 0;
  616         int hlen = ip->ip_hl << 2;
  617         int len = (mtu - hlen) & ~7;    /* size of payload in each fragment */
  618         int off;
  619         struct mbuf *m0 = *m_frag;      /* the original packet          */
  620         int firstlen;
  621         struct mbuf **mnext;
  622         int nfrags;
  623 
  624         if (ip->ip_off & IP_DF) {       /* Fragmentation not allowed */
  625                 ipstat.ips_cantfrag++;
  626                 return EMSGSIZE;
  627         }
  628 
  629         /*
  630          * Must be able to put at least 8 bytes per fragment.
  631          */
  632         if (len < 8)
  633                 return EMSGSIZE;
  634 
  635         /*
  636          * If the interface will not calculate checksums on
  637          * fragmented packets, then do it here.
  638          */
  639         if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA &&
  640             (if_hwassist_flags & CSUM_IP_FRAGS) == 0) {
  641                 in_delayed_cksum(m0);
  642                 m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
  643         }
  644 
  645         if (len > PAGE_SIZE) {
  646                 /* 
  647                  * Fragment large datagrams such that each segment 
  648                  * contains a multiple of PAGE_SIZE amount of data, 
  649                  * plus headers. This enables a receiver to perform 
  650                  * page-flipping zero-copy optimizations.
  651                  *
  652                  * XXX When does this help given that sender and receiver
  653                  * could have different page sizes, and also mtu could
  654                  * be less than the receiver's page size ?
  655                  */
  656                 int newlen;
  657                 struct mbuf *m;
  658 
  659                 for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next)
  660                         off += m->m_len;
  661 
  662                 /*
  663                  * firstlen (off - hlen) must be aligned on an 
  664                  * 8-byte boundary
  665                  */
  666                 if (off < hlen)
  667                         goto smart_frag_failure;
  668                 off = ((off - hlen) & ~7) + hlen;
  669                 newlen = (~PAGE_MASK) & mtu;
  670                 if ((newlen + sizeof (struct ip)) > mtu) {
  671                         /* we failed, go back the default */
  672 smart_frag_failure:
  673                         newlen = len;
  674                         off = hlen + len;
  675                 }
  676                 len = newlen;
  677 
  678         } else {
  679                 off = hlen + len;
  680         }
  681 
  682         firstlen = off - hlen;
  683         mnext = &m0->m_nextpkt;         /* pointer to next packet */
  684 
  685         /*
  686          * Loop through length of segment after first fragment,
  687          * make new header and copy data of each part and link onto chain.
  688          * Here, m0 is the original packet, m is the fragment being created.
  689          * The fragments are linked off the m_nextpkt of the original
  690          * packet, which after processing serves as the first fragment.
  691          */
  692         for (nfrags = 1; off < ip->ip_len; off += len, nfrags++) {
  693                 struct ip *mhip;        /* ip header on the fragment */
  694                 struct mbuf *m;
  695                 int mhlen = sizeof (struct ip);
  696 
  697                 MGETHDR(m, M_DONTWAIT, MT_DATA);
  698                 if (m == NULL) {
  699                         error = ENOBUFS;
  700                         ipstat.ips_odropped++;
  701                         goto done;
  702                 }
  703                 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG;
  704                 /*
  705                  * In the first mbuf, leave room for the link header, then
  706                  * copy the original IP header including options. The payload
  707                  * goes into an additional mbuf chain returned by m_copy().
  708                  */
  709                 m->m_data += max_linkhdr;
  710                 mhip = mtod(m, struct ip *);
  711                 *mhip = *ip;
  712                 if (hlen > sizeof (struct ip)) {
  713                         mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
  714                         mhip->ip_v = IPVERSION;
  715                         mhip->ip_hl = mhlen >> 2;
  716                 }
  717                 m->m_len = mhlen;
  718                 /* XXX do we need to add ip->ip_off below ? */
  719                 mhip->ip_off = ((off - hlen) >> 3) + ip->ip_off;
  720                 if (off + len >= ip->ip_len) {  /* last fragment */
  721                         len = ip->ip_len - off;
  722                         m->m_flags |= M_LASTFRAG;
  723                 } else
  724                         mhip->ip_off |= IP_MF;
  725                 mhip->ip_len = htons((u_short)(len + mhlen));
  726                 m->m_next = m_copy(m0, off, len);
  727                 if (m->m_next == NULL) {        /* copy failed */
  728                         m_free(m);
  729                         error = ENOBUFS;        /* ??? */
  730                         ipstat.ips_odropped++;
  731                         goto done;
  732                 }
  733                 m->m_pkthdr.len = mhlen + len;
  734                 m->m_pkthdr.rcvif = NULL;
  735 #ifdef MAC
  736                 mac_create_fragment(m0, m);
  737 #endif
  738                 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
  739                 mhip->ip_off = htons(mhip->ip_off);
  740                 mhip->ip_sum = 0;
  741                 if (sw_csum & CSUM_DELAY_IP)
  742                         mhip->ip_sum = in_cksum(m, mhlen);
  743                 *mnext = m;
  744                 mnext = &m->m_nextpkt;
  745         }
  746         ipstat.ips_ofragments += nfrags;
  747 
  748         /* set first marker for fragment chain */
  749         m0->m_flags |= M_FIRSTFRAG | M_FRAG;
  750         m0->m_pkthdr.csum_data = nfrags;
  751 
  752         /*
  753          * Update first fragment by trimming what's been copied out
  754          * and updating header.
  755          */
  756         m_adj(m0, hlen + firstlen - ip->ip_len);
  757         m0->m_pkthdr.len = hlen + firstlen;
  758         ip->ip_len = htons((u_short)m0->m_pkthdr.len);
  759         ip->ip_off |= IP_MF;
  760         ip->ip_off = htons(ip->ip_off);
  761         ip->ip_sum = 0;
  762         if (sw_csum & CSUM_DELAY_IP)
  763                 ip->ip_sum = in_cksum(m0, hlen);
  764 
  765 done:
  766         *m_frag = m0;
  767         return error;
  768 }
  769 
  770 void
  771 in_delayed_cksum(struct mbuf *m)
  772 {
  773         struct ip *ip;
  774         u_short csum, offset;
  775 
  776         ip = mtod(m, struct ip *);
  777         offset = ip->ip_hl << 2 ;
  778         csum = in_cksum_skip(m, ip->ip_len, offset);
  779         if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
  780                 csum = 0xffff;
  781         offset += m->m_pkthdr.csum_data;        /* checksum offset */
  782 
  783         if (offset + sizeof(u_short) > m->m_len) {
  784                 printf("delayed m_pullup, m->len: %d  off: %d  p: %d\n",
  785                     m->m_len, offset, ip->ip_p);
  786                 /*
  787                  * XXX
  788                  * this shouldn't happen, but if it does, the
  789                  * correct behavior may be to insert the checksum
  790                  * in the appropriate next mbuf in the chain.
  791                  */
  792                 return;
  793         }
  794         *(u_short *)(m->m_data + offset) = csum;
  795 }
  796 
  797 /*
  798  * IP socket option processing.
  799  */
  800 int
  801 ip_ctloutput(struct socket *so, struct sockopt *sopt)
  802 {
  803         struct  inpcb *inp = sotoinpcb(so);
  804         int     error, optval;
  805 
  806         error = optval = 0;
  807         if (sopt->sopt_level != IPPROTO_IP) {
  808                 return (EINVAL);
  809         }
  810 
  811         switch (sopt->sopt_dir) {
  812         case SOPT_SET:
  813                 switch (sopt->sopt_name) {
  814                 case IP_OPTIONS:
  815 #ifdef notyet
  816                 case IP_RETOPTS:
  817 #endif
  818                 {
  819                         struct mbuf *m;
  820                         if (sopt->sopt_valsize > MLEN) {
  821                                 error = EMSGSIZE;
  822                                 break;
  823                         }
  824                         MGET(m, sopt->sopt_td ? M_TRYWAIT : M_DONTWAIT, MT_DATA);
  825                         if (m == NULL) {
  826                                 error = ENOBUFS;
  827                                 break;
  828                         }
  829                         m->m_len = sopt->sopt_valsize;
  830                         error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
  831                                             m->m_len);
  832                         if (error) {
  833                                 m_free(m);
  834                                 break;
  835                         }
  836                         INP_LOCK(inp);
  837                         error = ip_pcbopts(inp, sopt->sopt_name, m);
  838                         INP_UNLOCK(inp);
  839                         return (error);
  840                 }
  841 
  842                 case IP_TOS:
  843                 case IP_TTL:
  844                 case IP_MINTTL:
  845                 case IP_RECVOPTS:
  846                 case IP_RECVRETOPTS:
  847                 case IP_RECVDSTADDR:
  848                 case IP_RECVTTL:
  849                 case IP_RECVIF:
  850                 case IP_FAITH:
  851                 case IP_ONESBCAST:
  852                 case IP_DONTFRAG:
  853                         error = sooptcopyin(sopt, &optval, sizeof optval,
  854                                             sizeof optval);
  855                         if (error)
  856                                 break;
  857 
  858                         switch (sopt->sopt_name) {
  859                         case IP_TOS:
  860                                 inp->inp_ip_tos = optval;
  861                                 break;
  862 
  863                         case IP_TTL:
  864                                 inp->inp_ip_ttl = optval;
  865                                 break;
  866 
  867                         case IP_MINTTL:
  868                                 if (optval > 0 && optval <= MAXTTL)
  869                                         inp->inp_ip_minttl = optval;
  870                                 else
  871                                         error = EINVAL;
  872                                 break;
  873 
  874 #define OPTSET(bit) do {                                                \
  875         INP_LOCK(inp);                                                  \
  876         if (optval)                                                     \
  877                 inp->inp_flags |= bit;                                  \
  878         else                                                            \
  879                 inp->inp_flags &= ~bit;                                 \
  880         INP_UNLOCK(inp);                                                \
  881 } while (0)
  882 
  883                         case IP_RECVOPTS:
  884                                 OPTSET(INP_RECVOPTS);
  885                                 break;
  886 
  887                         case IP_RECVRETOPTS:
  888                                 OPTSET(INP_RECVRETOPTS);
  889                                 break;
  890 
  891                         case IP_RECVDSTADDR:
  892                                 OPTSET(INP_RECVDSTADDR);
  893                                 break;
  894 
  895                         case IP_RECVTTL:
  896                                 OPTSET(INP_RECVTTL);
  897                                 break;
  898 
  899                         case IP_RECVIF:
  900                                 OPTSET(INP_RECVIF);
  901                                 break;
  902 
  903                         case IP_FAITH:
  904                                 OPTSET(INP_FAITH);
  905                                 break;
  906 
  907                         case IP_ONESBCAST:
  908                                 OPTSET(INP_ONESBCAST);
  909                                 break;
  910                         case IP_DONTFRAG:
  911                                 OPTSET(INP_DONTFRAG);
  912                                 break;
  913                         }
  914                         break;
  915 #undef OPTSET
  916 
  917                 /*
  918                  * Multicast socket options are processed by the in_mcast
  919                  * module.
  920                  */
  921                 case IP_MULTICAST_IF:
  922                 case IP_MULTICAST_VIF:
  923                 case IP_MULTICAST_TTL:
  924                 case IP_MULTICAST_LOOP:
  925                 case IP_ADD_MEMBERSHIP:
  926                 case IP_DROP_MEMBERSHIP:
  927                 case IP_ADD_SOURCE_MEMBERSHIP:
  928                 case IP_DROP_SOURCE_MEMBERSHIP:
  929                 case IP_BLOCK_SOURCE:
  930                 case IP_UNBLOCK_SOURCE:
  931                 case IP_MSFILTER:
  932                 case MCAST_JOIN_GROUP:
  933                 case MCAST_LEAVE_GROUP:
  934                 case MCAST_JOIN_SOURCE_GROUP:
  935                 case MCAST_LEAVE_SOURCE_GROUP:
  936                 case MCAST_BLOCK_SOURCE:
  937                 case MCAST_UNBLOCK_SOURCE:
  938                         error = inp_setmoptions(inp, sopt);
  939                         break;
  940 
  941                 case IP_PORTRANGE:
  942                         error = sooptcopyin(sopt, &optval, sizeof optval,
  943                                             sizeof optval);
  944                         if (error)
  945                                 break;
  946 
  947                         INP_LOCK(inp);
  948                         switch (optval) {
  949                         case IP_PORTRANGE_DEFAULT:
  950                                 inp->inp_flags &= ~(INP_LOWPORT);
  951                                 inp->inp_flags &= ~(INP_HIGHPORT);
  952                                 break;
  953 
  954                         case IP_PORTRANGE_HIGH:
  955                                 inp->inp_flags &= ~(INP_LOWPORT);
  956                                 inp->inp_flags |= INP_HIGHPORT;
  957                                 break;
  958 
  959                         case IP_PORTRANGE_LOW:
  960                                 inp->inp_flags &= ~(INP_HIGHPORT);
  961                                 inp->inp_flags |= INP_LOWPORT;
  962                                 break;
  963 
  964                         default:
  965                                 error = EINVAL;
  966                                 break;
  967                         }
  968                         INP_UNLOCK(inp);
  969                         break;
  970 
  971 #ifdef IPSEC
  972                 case IP_IPSEC_POLICY:
  973                 {
  974                         caddr_t req;
  975                         size_t len = 0;
  976                         int priv;
  977                         struct mbuf *m;
  978                         int optname;
  979 
  980                         if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
  981                                 break;
  982                         if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
  983                                 break;
  984                         if (sopt->sopt_td != NULL) {
  985                                 /*
  986                                  * XXXRW: Would be more desirable to do this
  987                                  * one layer down so that we only exercise
  988                                  * privilege if it is needed.
  989                                  */
  990                                 error = priv_check(sopt->sopt_td,
  991                                     PRIV_NETINET_IPSEC);
  992                                 if (error)
  993                                         priv = 0;
  994                                 else
  995                                         priv = 1;
  996                         } else
  997                                 priv = 1;
  998                         req = mtod(m, caddr_t);
  999                         len = m->m_len;
 1000                         optname = sopt->sopt_name;
 1001                         error = ipsec4_set_policy(inp, optname, req, len, priv);
 1002                         m_freem(m);
 1003                         break;
 1004                 }
 1005 #endif /* IPSEC */
 1006 
 1007                 default:
 1008                         error = ENOPROTOOPT;
 1009                         break;
 1010                 }
 1011                 break;
 1012 
 1013         case SOPT_GET:
 1014                 switch (sopt->sopt_name) {
 1015                 case IP_OPTIONS:
 1016                 case IP_RETOPTS:
 1017                         if (inp->inp_options)
 1018                                 error = sooptcopyout(sopt, 
 1019                                                      mtod(inp->inp_options,
 1020                                                           char *),
 1021                                                      inp->inp_options->m_len);
 1022                         else
 1023                                 sopt->sopt_valsize = 0;
 1024                         break;
 1025 
 1026                 case IP_TOS:
 1027                 case IP_TTL:
 1028                 case IP_MINTTL:
 1029                 case IP_RECVOPTS:
 1030                 case IP_RECVRETOPTS:
 1031                 case IP_RECVDSTADDR:
 1032                 case IP_RECVTTL:
 1033                 case IP_RECVIF:
 1034                 case IP_PORTRANGE:
 1035                 case IP_FAITH:
 1036                 case IP_ONESBCAST:
 1037                 case IP_DONTFRAG:
 1038                         switch (sopt->sopt_name) {
 1039 
 1040                         case IP_TOS:
 1041                                 optval = inp->inp_ip_tos;
 1042                                 break;
 1043 
 1044                         case IP_TTL:
 1045                                 optval = inp->inp_ip_ttl;
 1046                                 break;
 1047 
 1048                         case IP_MINTTL:
 1049                                 optval = inp->inp_ip_minttl;
 1050                                 break;
 1051 
 1052 #define OPTBIT(bit)     (inp->inp_flags & bit ? 1 : 0)
 1053 
 1054                         case IP_RECVOPTS:
 1055                                 optval = OPTBIT(INP_RECVOPTS);
 1056                                 break;
 1057 
 1058                         case IP_RECVRETOPTS:
 1059                                 optval = OPTBIT(INP_RECVRETOPTS);
 1060                                 break;
 1061 
 1062                         case IP_RECVDSTADDR:
 1063                                 optval = OPTBIT(INP_RECVDSTADDR);
 1064                                 break;
 1065 
 1066                         case IP_RECVTTL:
 1067                                 optval = OPTBIT(INP_RECVTTL);
 1068                                 break;
 1069 
 1070                         case IP_RECVIF:
 1071                                 optval = OPTBIT(INP_RECVIF);
 1072                                 break;
 1073 
 1074                         case IP_PORTRANGE:
 1075                                 if (inp->inp_flags & INP_HIGHPORT)
 1076                                         optval = IP_PORTRANGE_HIGH;
 1077                                 else if (inp->inp_flags & INP_LOWPORT)
 1078                                         optval = IP_PORTRANGE_LOW;
 1079                                 else
 1080                                         optval = 0;
 1081                                 break;
 1082 
 1083                         case IP_FAITH:
 1084                                 optval = OPTBIT(INP_FAITH);
 1085                                 break;
 1086 
 1087                         case IP_ONESBCAST:
 1088                                 optval = OPTBIT(INP_ONESBCAST);
 1089                                 break;
 1090                         case IP_DONTFRAG:
 1091                                 optval = OPTBIT(INP_DONTFRAG);
 1092                                 break;
 1093                         }
 1094                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1095                         break;
 1096 
 1097                 /*
 1098                  * Multicast socket options are processed by the in_mcast
 1099                  * module.
 1100                  */
 1101                 case IP_MULTICAST_IF:
 1102                 case IP_MULTICAST_VIF:
 1103                 case IP_MULTICAST_TTL:
 1104                 case IP_MULTICAST_LOOP:
 1105                 case IP_MSFILTER:
 1106                         error = inp_getmoptions(inp, sopt);
 1107                         break;
 1108 
 1109 #ifdef IPSEC
 1110                 case IP_IPSEC_POLICY:
 1111                 {
 1112                         struct mbuf *m = NULL;
 1113                         caddr_t req = NULL;
 1114                         size_t len = 0;
 1115 
 1116                         if (m != 0) {
 1117                                 req = mtod(m, caddr_t);
 1118                                 len = m->m_len;
 1119                         }
 1120                         error = ipsec4_get_policy(sotoinpcb(so), req, len, &m);
 1121                         if (error == 0)
 1122                                 error = soopt_mcopyout(sopt, m); /* XXX */
 1123                         if (error == 0)
 1124                                 m_freem(m);
 1125                         break;
 1126                 }
 1127 #endif /* IPSEC */
 1128 
 1129                 default:
 1130                         error = ENOPROTOOPT;
 1131                         break;
 1132                 }
 1133                 break;
 1134         }
 1135         return (error);
 1136 }
 1137 
 1138 /*
 1139  * Routine called from ip_output() to loop back a copy of an IP multicast
 1140  * packet to the input queue of a specified interface.  Note that this
 1141  * calls the output routine of the loopback "driver", but with an interface
 1142  * pointer that might NOT be a loopback interface -- evil, but easier than
 1143  * replicating that code here.
 1144  */
 1145 static void
 1146 ip_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in *dst,
 1147     int hlen)
 1148 {
 1149         register struct ip *ip;
 1150         struct mbuf *copym;
 1151 
 1152         copym = m_copy(m, 0, M_COPYALL);
 1153         if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
 1154                 copym = m_pullup(copym, hlen);
 1155         if (copym != NULL) {
 1156                 /* If needed, compute the checksum and mark it as valid. */
 1157                 if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
 1158                         in_delayed_cksum(copym);
 1159                         copym->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 1160                         copym->m_pkthdr.csum_flags |=
 1161                             CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
 1162                         copym->m_pkthdr.csum_data = 0xffff;
 1163                 }
 1164                 /*
 1165                  * We don't bother to fragment if the IP length is greater
 1166                  * than the interface's MTU.  Can this possibly matter?
 1167                  */
 1168                 ip = mtod(copym, struct ip *);
 1169                 ip->ip_len = htons(ip->ip_len);
 1170                 ip->ip_off = htons(ip->ip_off);
 1171                 ip->ip_sum = 0;
 1172                 ip->ip_sum = in_cksum(copym, hlen);
 1173                 /*
 1174                  * NB:
 1175                  * It's not clear whether there are any lingering
 1176                  * reentrancy problems in other areas which might
 1177                  * be exposed by using ip_input directly (in
 1178                  * particular, everything which modifies the packet
 1179                  * in-place).  Yet another option is using the
 1180                  * protosw directly to deliver the looped back
 1181                  * packet.  For the moment, we'll err on the side
 1182                  * of safety by using if_simloop().
 1183                  */
 1184 #if 1 /* XXX */
 1185                 if (dst->sin_family != AF_INET) {
 1186                         printf("ip_mloopback: bad address family %d\n",
 1187                                                 dst->sin_family);
 1188                         dst->sin_family = AF_INET;
 1189                 }
 1190 #endif
 1191 
 1192 #ifdef notdef
 1193                 copym->m_pkthdr.rcvif = ifp;
 1194                 ip_input(copym);
 1195 #else
 1196                 if_simloop(ifp, copym, dst->sin_family, 0);
 1197 #endif
 1198         }
 1199 }

Cache object: 13e25874fedccae3f9fbcc7368b3ccd4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.