Deleted Added
full compact
ip_input.c (125952) ip_input.c (126239)
1/*
2 * Copyright (c) 1982, 1986, 1988, 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

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
1/*
2 * Copyright (c) 1982, 1986, 1988, 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

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/netinet/ip_input.c 125952 2004-02-18 00:04:52Z mlaier $
34 * $FreeBSD: head/sys/netinet/ip_input.c 126239 2004-02-25 19:55:29Z mlaier $
35 */
36
37#include "opt_bootp.h"
38#include "opt_ipfw.h"
39#include "opt_ipdn.h"
40#include "opt_ipdivert.h"
41#include "opt_ipfilter.h"
42#include "opt_ipstealth.h"

--- 30 unchanged lines hidden (view full) ---

73#include <netinet/in_pcb.h>
74#include <netinet/ip_var.h>
75#include <netinet/ip_icmp.h>
76#include <machine/in_cksum.h>
77
78#include <sys/socketvar.h>
79
80#include <netinet/ip_fw.h>
35 */
36
37#include "opt_bootp.h"
38#include "opt_ipfw.h"
39#include "opt_ipdn.h"
40#include "opt_ipdivert.h"
41#include "opt_ipfilter.h"
42#include "opt_ipstealth.h"

--- 30 unchanged lines hidden (view full) ---

73#include <netinet/in_pcb.h>
74#include <netinet/ip_var.h>
75#include <netinet/ip_icmp.h>
76#include <machine/in_cksum.h>
77
78#include <sys/socketvar.h>
79
80#include <netinet/ip_fw.h>
81#include <netinet/ip_divert.h>
81#include <netinet/ip_dummynet.h>
82
83#ifdef IPSEC
84#include <netinet6/ipsec.h>
85#include <netkey/key.h>
86#endif
87
88#ifdef FAST_IPSEC

--- 145 unchanged lines hidden (view full) ---

234} ip_srcrt;
235
236static void save_rte(u_char *, struct in_addr);
237static int ip_dooptions(struct mbuf *m, int,
238 struct sockaddr_in *next_hop);
239static void ip_forward(struct mbuf *m, int srcrt,
240 struct sockaddr_in *next_hop);
241static void ip_freef(struct ipqhead *, struct ipq *);
82#include <netinet/ip_dummynet.h>
83
84#ifdef IPSEC
85#include <netinet6/ipsec.h>
86#include <netkey/key.h>
87#endif
88
89#ifdef FAST_IPSEC

--- 145 unchanged lines hidden (view full) ---

235} ip_srcrt;
236
237static void save_rte(u_char *, struct in_addr);
238static int ip_dooptions(struct mbuf *m, int,
239 struct sockaddr_in *next_hop);
240static void ip_forward(struct mbuf *m, int srcrt,
241 struct sockaddr_in *next_hop);
242static void ip_freef(struct ipqhead *, struct ipq *);
242static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *,
243 struct ipq *, u_int32_t *, u_int16_t *);
243static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *, struct ipq *);
244
245/*
246 * IP initialization: fill in IP protocol switch table.
247 * All protocols not implemented in kernel go to raw IP protocol handler.
248 */
249void
250ip_init()
251{

--- 43 unchanged lines hidden (view full) ---

295void
296ip_input(struct mbuf *m)
297{
298 struct ip *ip = NULL;
299 struct ipq *fp;
300 struct in_ifaddr *ia = NULL;
301 struct ifaddr *ifa;
302 int i, checkif, hlen = 0;
244
245/*
246 * IP initialization: fill in IP protocol switch table.
247 * All protocols not implemented in kernel go to raw IP protocol handler.
248 */
249void
250ip_init()
251{

--- 43 unchanged lines hidden (view full) ---

295void
296ip_input(struct mbuf *m)
297{
298 struct ip *ip = NULL;
299 struct ipq *fp;
300 struct in_ifaddr *ia = NULL;
301 struct ifaddr *ifa;
302 int i, checkif, hlen = 0;
303 int ours = 0;
304 u_short sum;
305 struct in_addr pkt_dst;
303 u_short sum;
304 struct in_addr pkt_dst;
306 u_int32_t divert_info = 0; /* packet divert/tee info */
305#ifdef IPDIVERT
306 u_int32_t divert_info; /* packet divert/tee info */
307#endif
307 struct ip_fw_args args;
308 int dchg = 0; /* dest changed after fw */
309#ifdef PFIL_HOOKS
310 struct in_addr odst; /* original dst address */
311#endif
312#ifdef FAST_IPSEC
313 struct m_tag *mtag;
314 struct tdb_ident *tdbi;
315 struct secpolicy *sp;
316 int s, error;
317#endif /* FAST_IPSEC */
318
319 args.eh = NULL;
320 args.oif = NULL;
308 struct ip_fw_args args;
309 int dchg = 0; /* dest changed after fw */
310#ifdef PFIL_HOOKS
311 struct in_addr odst; /* original dst address */
312#endif
313#ifdef FAST_IPSEC
314 struct m_tag *mtag;
315 struct tdb_ident *tdbi;
316 struct secpolicy *sp;
317 int s, error;
318#endif /* FAST_IPSEC */
319
320 args.eh = NULL;
321 args.oif = NULL;
321 args.rule = NULL;
322 args.divert_rule = 0; /* divert cookie */
323 args.next_hop = NULL;
324
322
325 /*
326 * Grab info from MT_TAG mbufs prepended to the chain.
327 *
328 * XXX: This is ugly. These pseudo mbuf prepend tags should really
329 * be real m_tags. Before these have always been allocated on the
330 * callers stack, so we didn't have to free them. Now with
331 * ip_fastforward they are true mbufs and we have to free them
332 * otherwise we have a leak. Must rewrite ipfw to use m_tags.
333 */
334 for (; m && m->m_type == MT_TAG;) {
335 struct mbuf *m0;
336
337 switch(m->_m_tag_id) {
338 default:
339 printf("ip_input: unrecognised MT_TAG tag %d\n",
340 m->_m_tag_id);
341 break;
342
343 case PACKET_TAG_DUMMYNET:
344 args.rule = ((struct dn_pkt *)m)->rule;
345 break;
346
347 case PACKET_TAG_DIVERT:
348 args.divert_rule = (intptr_t)m->m_hdr.mh_data & 0xffff;
349 break;
350
351 case PACKET_TAG_IPFORWARD:
352 args.next_hop = (struct sockaddr_in *)m->m_hdr.mh_data;
353 break;
354
355 case PACKET_TAG_IPFASTFWD_OURS:
356 ours = 1;
357 break;
358 }
359
360 m0 = m;
361 m = m->m_next;
362 /* XXX: This is set by ip_fastforward */
363 if (m0->m_nextpkt == (struct mbuf *)1)
364 m_free(m0);
365 }
366
367 M_ASSERTPKTHDR(m);
323 M_ASSERTPKTHDR(m);
324
325 args.next_hop = ip_claim_next_hop(m);
326 args.rule = ip_dn_claim_rule(m);
368
327
369 if (ours) /* ip_fastforward firewall changed dest to local */
328 if (m->m_flags & M_FASTFWD_OURS) {
329 /* ip_fastforward firewall changed dest to local */
330 m->m_flags &= ~M_FASTFWD_OURS; /* for reflected mbufs */
370 goto ours;
331 goto ours;
332 }
371
372 if (args.rule) { /* dummynet already filtered us */
373 ip = mtod(m, struct ip *);
374 hlen = ip->ip_hl << 2;
375 goto iphack ;
376 }
377
378 ipstat.ips_total++;

--- 147 unchanged lines hidden (view full) ---

526 if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
527 /* Send packet to the appropriate pipe */
528 ip_dn_io_ptr(m, i&0xffff, DN_TO_IP_IN, &args);
529 return;
530 }
531#ifdef IPDIVERT
532 if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) {
533 /* Divert or tee packet */
333
334 if (args.rule) { /* dummynet already filtered us */
335 ip = mtod(m, struct ip *);
336 hlen = ip->ip_hl << 2;
337 goto iphack ;
338 }
339
340 ipstat.ips_total++;

--- 147 unchanged lines hidden (view full) ---

488 if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
489 /* Send packet to the appropriate pipe */
490 ip_dn_io_ptr(m, i&0xffff, DN_TO_IP_IN, &args);
491 return;
492 }
493#ifdef IPDIVERT
494 if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) {
495 /* Divert or tee packet */
534 divert_info = i;
535 goto ours;
536 }
537#endif
538 if (i == 0 && args.next_hop != NULL)
539 goto pass;
540 /*
541 * if we get here, the packet must be dropped
542 */

--- 291 unchanged lines hidden (view full) ---

834 }
835 m->m_flags |= M_FRAG;
836 } else
837 m->m_flags &= ~M_FRAG;
838 ip->ip_off <<= 3;
839
840 /*
841 * Attempt reassembly; if it succeeds, proceed.
496 goto ours;
497 }
498#endif
499 if (i == 0 && args.next_hop != NULL)
500 goto pass;
501 /*
502 * if we get here, the packet must be dropped
503 */

--- 291 unchanged lines hidden (view full) ---

795 }
796 m->m_flags |= M_FRAG;
797 } else
798 m->m_flags &= ~M_FRAG;
799 ip->ip_off <<= 3;
800
801 /*
802 * Attempt reassembly; if it succeeds, proceed.
842 * ip_reass() will return a different mbuf, and update
843 * the divert info in divert_info and args.divert_rule.
803 * ip_reass() will return a different mbuf.
844 */
845 ipstat.ips_fragments++;
846 m->m_pkthdr.header = ip;
804 */
805 ipstat.ips_fragments++;
806 m->m_pkthdr.header = ip;
847 m = ip_reass(m,
848 &ipq[sum], fp, &divert_info, &args.divert_rule);
807 m = ip_reass(m, &ipq[sum], fp);
849 IPQ_UNLOCK();
850 if (m == 0)
851 return;
852 ipstat.ips_reassembled++;
853 ip = mtod(m, struct ip *);
854 /* Get the header length of the reassembled packet */
855 hlen = ip->ip_hl << 2;
856#ifdef IPDIVERT
857 /* Restore original checksum before diverting packet */
808 IPQ_UNLOCK();
809 if (m == 0)
810 return;
811 ipstat.ips_reassembled++;
812 ip = mtod(m, struct ip *);
813 /* Get the header length of the reassembled packet */
814 hlen = ip->ip_hl << 2;
815#ifdef IPDIVERT
816 /* Restore original checksum before diverting packet */
858 if (divert_info != 0) {
817 if (divert_find_info(m) != 0) {
859 ip->ip_len += hlen;
860 ip->ip_len = htons(ip->ip_len);
861 ip->ip_off = htons(ip->ip_off);
862 ip->ip_sum = 0;
863 if (hlen == sizeof(struct ip))
864 ip->ip_sum = in_cksum_hdr(ip);
865 else
866 ip->ip_sum = in_cksum(m, hlen);

--- 4 unchanged lines hidden (view full) ---

871#endif
872 } else
873 ip->ip_len -= hlen;
874
875#ifdef IPDIVERT
876 /*
877 * Divert or tee packet to the divert protocol if required.
878 */
818 ip->ip_len += hlen;
819 ip->ip_len = htons(ip->ip_len);
820 ip->ip_off = htons(ip->ip_off);
821 ip->ip_sum = 0;
822 if (hlen == sizeof(struct ip))
823 ip->ip_sum = in_cksum_hdr(ip);
824 else
825 ip->ip_sum = in_cksum(m, hlen);

--- 4 unchanged lines hidden (view full) ---

830#endif
831 } else
832 ip->ip_len -= hlen;
833
834#ifdef IPDIVERT
835 /*
836 * Divert or tee packet to the divert protocol if required.
837 */
838 divert_info = divert_find_info(m);
879 if (divert_info != 0) {
839 if (divert_info != 0) {
880 struct mbuf *clone = NULL;
840 struct mbuf *clone;
881
882 /* Clone packet if we're doing a 'tee' */
883 if ((divert_info & IP_FW_PORT_TEE_FLAG) != 0)
841
842 /* Clone packet if we're doing a 'tee' */
843 if ((divert_info & IP_FW_PORT_TEE_FLAG) != 0)
884 clone = m_dup(m, M_DONTWAIT);
844 clone = divert_clone(m);
845 else
846 clone = NULL;
885
886 /* Restore packet header fields to original values */
887 ip->ip_len += hlen;
888 ip->ip_len = htons(ip->ip_len);
889 ip->ip_off = htons(ip->ip_off);
890
891 /* Deliver packet to divert input routine */
847
848 /* Restore packet header fields to original values */
849 ip->ip_len += hlen;
850 ip->ip_len = htons(ip->ip_len);
851 ip->ip_off = htons(ip->ip_off);
852
853 /* Deliver packet to divert input routine */
892 divert_packet(m, 1, divert_info & 0xffff, args.divert_rule);
854 divert_packet(m, 1);
893 ipstat.ips_delivered++;
894
895 /* If 'tee', continue with original packet */
896 if (clone == NULL)
897 return;
898 m = clone;
899 ip = mtod(m, struct ip *);
900 ip->ip_len += hlen;
901 /*
902 * Jump backwards to complete processing of the
855 ipstat.ips_delivered++;
856
857 /* If 'tee', continue with original packet */
858 if (clone == NULL)
859 return;
860 m = clone;
861 ip = mtod(m, struct ip *);
862 ip->ip_len += hlen;
863 /*
864 * Jump backwards to complete processing of the
903 * packet. But first clear divert_info to avoid
904 * entering this block again.
905 * We do not need to clear args.divert_rule
906 * or args.next_hop as they will not be used.
865 * packet. We do not need to clear args.next_hop
866 * as that will not be used again and the cloned packet
867 * doesn't contain a divert packet tag so we won't
868 * re-entry this block.
907 */
869 */
908 divert_info = 0;
909 goto pass;
910 }
911#endif
912
913#ifdef IPSEC
914 /*
915 * enforce IPsec policy checking if we are seeing last header.
916 * note that we do not visit this with protocols with pcb layer

--- 44 unchanged lines hidden (view full) ---

961 goto bad;
962 }
963#endif /* FAST_IPSEC */
964
965 /*
966 * Switch out to protocol's input routine.
967 */
968 ipstat.ips_delivered++;
870 goto pass;
871 }
872#endif
873
874#ifdef IPSEC
875 /*
876 * enforce IPsec policy checking if we are seeing last header.
877 * note that we do not visit this with protocols with pcb layer

--- 44 unchanged lines hidden (view full) ---

922 goto bad;
923 }
924#endif /* FAST_IPSEC */
925
926 /*
927 * Switch out to protocol's input routine.
928 */
929 ipstat.ips_delivered++;
969 NET_PICKUP_GIANT();
970 if (args.next_hop && ip->ip_p == IPPROTO_TCP) {
930 if (args.next_hop && ip->ip_p == IPPROTO_TCP) {
971 /* TCP needs IPFORWARD info if available */
972 struct m_hdr tag;
973
974 tag.mh_type = MT_TAG;
975 tag.mh_flags = PACKET_TAG_IPFORWARD;
976 tag.mh_data = (caddr_t)args.next_hop;
977 tag.mh_next = m;
978 tag.mh_nextpkt = NULL;
979
980 (*inetsw[ip_protox[ip->ip_p]].pr_input)(
981 (struct mbuf *)&tag, hlen);
982 } else
983 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
931 /* attach next hop info for TCP */
932 struct m_tag *mtag = m_tag_get(PACKET_TAG_IPFORWARD,
933 sizeof(struct sockaddr_in *), M_NOWAIT);
934 if (mtag == NULL)
935 goto bad;
936 *(struct sockaddr_in **)(mtag+1) = args.next_hop;
937 m_tag_prepend(m, mtag);
938 }
939 NET_PICKUP_GIANT();
940 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
984 NET_DROP_GIANT();
985 return;
986bad:
987 m_freem(m);
988}
989
990/*
991 * Take incoming datagram fragment and try to reassemble it into
992 * whole datagram. If a chain for reassembly of this datagram already
993 * exists, then it is given as fp; otherwise have to make a chain.
994 *
995 * When IPDIVERT enabled, keep additional state with each packet that
996 * tells us if we need to divert or tee the packet we're building.
997 * In particular, *divinfo includes the port and TEE flag,
998 * *divert_rule is the number of the matching rule.
999 */
1000
1001static struct mbuf *
941 NET_DROP_GIANT();
942 return;
943bad:
944 m_freem(m);
945}
946
947/*
948 * Take incoming datagram fragment and try to reassemble it into
949 * whole datagram. If a chain for reassembly of this datagram already
950 * exists, then it is given as fp; otherwise have to make a chain.
951 *
952 * When IPDIVERT enabled, keep additional state with each packet that
953 * tells us if we need to divert or tee the packet we're building.
954 * In particular, *divinfo includes the port and TEE flag,
955 * *divert_rule is the number of the matching rule.
956 */
957
958static struct mbuf *
1002ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp,
1003 u_int32_t *divinfo, u_int16_t *divert_rule)
959ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp)
1004{
1005 struct ip *ip = mtod(m, struct ip *);
1006 register struct mbuf *p, *q, *nq;
1007 struct mbuf *t;
1008 int hlen = ip->ip_hl << 2;
1009 int i, next;
1010 u_int8_t ecn, ecn0;
1011

--- 25 unchanged lines hidden (view full) ---

1037 fp->ipq_nfrags = 1;
1038 fp->ipq_ttl = IPFRAGTTL;
1039 fp->ipq_p = ip->ip_p;
1040 fp->ipq_id = ip->ip_id;
1041 fp->ipq_src = ip->ip_src;
1042 fp->ipq_dst = ip->ip_dst;
1043 fp->ipq_frags = m;
1044 m->m_nextpkt = NULL;
960{
961 struct ip *ip = mtod(m, struct ip *);
962 register struct mbuf *p, *q, *nq;
963 struct mbuf *t;
964 int hlen = ip->ip_hl << 2;
965 int i, next;
966 u_int8_t ecn, ecn0;
967

--- 25 unchanged lines hidden (view full) ---

993 fp->ipq_nfrags = 1;
994 fp->ipq_ttl = IPFRAGTTL;
995 fp->ipq_p = ip->ip_p;
996 fp->ipq_id = ip->ip_id;
997 fp->ipq_src = ip->ip_src;
998 fp->ipq_dst = ip->ip_dst;
999 fp->ipq_frags = m;
1000 m->m_nextpkt = NULL;
1045#ifdef IPDIVERT
1046 fp->ipq_div_info = 0;
1047 fp->ipq_div_cookie = 0;
1048#endif
1049 goto inserted;
1050 } else {
1051 fp->ipq_nfrags++;
1052#ifdef MAC
1053 mac_update_ipq(m, fp);
1054#endif
1055 }
1056

--- 67 unchanged lines hidden (view full) ---

1124 ipstat.ips_fragdropped++;
1125 fp->ipq_nfrags--;
1126 m_freem(q);
1127 }
1128
1129inserted:
1130
1131#ifdef IPDIVERT
1001 goto inserted;
1002 } else {
1003 fp->ipq_nfrags++;
1004#ifdef MAC
1005 mac_update_ipq(m, fp);
1006#endif
1007 }
1008

--- 67 unchanged lines hidden (view full) ---

1076 ipstat.ips_fragdropped++;
1077 fp->ipq_nfrags--;
1078 m_freem(q);
1079 }
1080
1081inserted:
1082
1083#ifdef IPDIVERT
1132 /*
1133 * Transfer firewall instructions to the fragment structure.
1134 * Only trust info in the fragment at offset 0.
1135 */
1136 if (ip->ip_off == 0) {
1137 fp->ipq_div_info = *divinfo;
1138 fp->ipq_div_cookie = *divert_rule;
1084 if (ip->ip_off != 0) {
1085 /*
1086 * Strip any divert information; only the info
1087 * on the first fragment is used/kept.
1088 */
1089 struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
1090 if (mtag)
1091 m_tag_delete(m, mtag);
1139 }
1092 }
1140 *divinfo = 0;
1141 *divert_rule = 0;
1142#endif
1143
1144 /*
1145 * Check for complete reassembly and perform frag per packet
1146 * limiting.
1147 *
1148 * Frag limiting is performed here so that the nth frag has
1149 * a chance to complete the packet before we drop the packet.

--- 49 unchanged lines hidden (view full) ---

1199 m->m_pkthdr.csum_data += q->m_pkthdr.csum_data;
1200 m_cat(m, q);
1201 }
1202#ifdef MAC
1203 mac_create_datagram_from_ipq(fp, m);
1204 mac_destroy_ipq(fp);
1205#endif
1206
1093#endif
1094
1095 /*
1096 * Check for complete reassembly and perform frag per packet
1097 * limiting.
1098 *
1099 * Frag limiting is performed here so that the nth frag has
1100 * a chance to complete the packet before we drop the packet.

--- 49 unchanged lines hidden (view full) ---

1150 m->m_pkthdr.csum_data += q->m_pkthdr.csum_data;
1151 m_cat(m, q);
1152 }
1153#ifdef MAC
1154 mac_create_datagram_from_ipq(fp, m);
1155 mac_destroy_ipq(fp);
1156#endif
1157
1207#ifdef IPDIVERT
1208 /*
1158 /*
1209 * Extract firewall instructions from the fragment structure.
1210 */
1211 *divinfo = fp->ipq_div_info;
1212 *divert_rule = fp->ipq_div_cookie;
1213#endif
1214
1215 /*
1216 * Create header for new ip packet by
1217 * modifying header of first packet;
1218 * dequeue and discard fragment reassembly header.
1219 * Make header visible.
1220 */
1221 ip->ip_len = next;
1222 ip->ip_src = fp->ipq_src;
1223 ip->ip_dst = fp->ipq_dst;
1224 TAILQ_REMOVE(head, fp, ipq_list);
1225 nipq--;
1226 (void) m_free(dtom(fp));
1227 m->m_len += (ip->ip_hl << 2);
1228 m->m_data -= (ip->ip_hl << 2);
1229 /* some debugging cruft by sklower, below, will go away soon */
1230 if (m->m_flags & M_PKTHDR) /* XXX this should be done elsewhere */
1231 m_fixhdr(m);
1232 return (m);
1233
1234dropfrag:
1159 * Create header for new ip packet by
1160 * modifying header of first packet;
1161 * dequeue and discard fragment reassembly header.
1162 * Make header visible.
1163 */
1164 ip->ip_len = next;
1165 ip->ip_src = fp->ipq_src;
1166 ip->ip_dst = fp->ipq_dst;
1167 TAILQ_REMOVE(head, fp, ipq_list);
1168 nipq--;
1169 (void) m_free(dtom(fp));
1170 m->m_len += (ip->ip_hl << 2);
1171 m->m_data -= (ip->ip_hl << 2);
1172 /* some debugging cruft by sklower, below, will go away soon */
1173 if (m->m_flags & M_PKTHDR) /* XXX this should be done elsewhere */
1174 m_fixhdr(m);
1175 return (m);
1176
1177dropfrag:
1235#ifdef IPDIVERT
1236 *divinfo = 0;
1237 *divert_rule = 0;
1238#endif
1239 ipstat.ips_fragdropped++;
1240 if (fp != NULL)
1241 fp->ipq_nfrags--;
1242 m_freem(m);
1243 return (0);
1244
1245#undef GETIP
1246}

--- 662 unchanged lines hidden (view full) ---

1909#endif
1910 }
1911 }
1912 if (rt)
1913 RTFREE(rt);
1914 }
1915
1916 {
1178 ipstat.ips_fragdropped++;
1179 if (fp != NULL)
1180 fp->ipq_nfrags--;
1181 m_freem(m);
1182 return (0);
1183
1184#undef GETIP
1185}

--- 662 unchanged lines hidden (view full) ---

1848#endif
1849 }
1850 }
1851 if (rt)
1852 RTFREE(rt);
1853 }
1854
1855 {
1917 struct m_hdr tag;
1918
1919 if (next_hop) {
1856 if (next_hop) {
1920 /* Pass IPFORWARD info if available */
1921
1922 tag.mh_type = MT_TAG;
1923 tag.mh_flags = PACKET_TAG_IPFORWARD;
1924 tag.mh_data = (caddr_t)next_hop;
1925 tag.mh_next = m;
1926 tag.mh_nextpkt = NULL;
1927 m = (struct mbuf *)&tag;
1857 struct m_tag *mtag = m_tag_get(PACKET_TAG_IPFORWARD,
1858 sizeof(struct sockaddr_in *), M_NOWAIT);
1859 if (mtag == NULL) {
1860 m_freem(m);
1861 return;
1862 }
1863 *(struct sockaddr_in **)(mtag+1) = next_hop;
1864 m_tag_prepend(m, mtag);
1928 }
1929 error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL);
1930 }
1931 if (error)
1932 ipstat.ips_cantforward++;
1933 else {
1934 ipstat.ips_forward++;
1935 if (type)

--- 289 unchanged lines hidden ---
1865 }
1866 error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL);
1867 }
1868 if (error)
1869 ipstat.ips_cantforward++;
1870 else {
1871 ipstat.ips_forward++;
1872 if (type)

--- 289 unchanged lines hidden ---