ip_reass.c (125952) | ip_reass.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 --- |