ip_input.c (189a0ba4e7490ac3ea73972547d9f6635ed33c68) | ip_input.c (36e8826ffbfb16b1970dec46e3dd8487c014788a) |
---|---|
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 --- 64 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> | 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 --- 64 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> | |
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 *); | 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 *); |
243static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *, struct ipq *); | 242static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *, 243 struct ipq *, u_int32_t *, u_int16_t *); |
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; |
|
303 u_short sum; 304 struct in_addr pkt_dst; | 304 u_short sum; 305 struct in_addr pkt_dst; |
305 struct m_tag *mtag; 306#ifdef IPDIVERT 307 u_int32_t divert_info; /* packet divert/tee info */ 308#endif | 306 u_int32_t divert_info = 0; /* packet divert/tee info */ |
309 struct ip_fw_args args; 310 int dchg = 0; /* dest changed after fw */ 311#ifdef PFIL_HOOKS 312 struct in_addr odst; /* original dst address */ 313#endif 314#ifdef FAST_IPSEC | 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; |
|
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; | 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; |
322 args.next_hop = ip_claim_next_hop(m); 323 args.rule = ip_dn_find_rule(m); | 321 args.rule = NULL; 322 args.divert_rule = 0; /* divert cookie */ 323 args.next_hop = NULL; |
324 | 324 |
325 M_ASSERTPKTHDR(m); | 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; |
326 | 336 |
327 if (m->m_flags & M_FASTFWD_OURS) { 328 /* ip_fastforward firewall changed dest to local */ 329 m->m_flags &= ~M_FASTFWD_OURS; /* just in case... */ 330 goto ours; | 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); |
331 } | 365 } |
332 if (args.rule) { /* dummynet already filtered us */ 333 ip = mtod(m, struct ip *); 334 hlen = ip->ip_hl << 2; | 366 367 M_ASSERTPKTHDR(m); 368 369 if (ours) /* ip_fastforward firewall changed dest to local */ 370 goto ours; 371 372 if (args.rule) { /* dummynet already filtered us */ 373 ip = mtod(m, struct ip *); 374 hlen = ip->ip_hl << 2; |
335 goto iphack ; 336 } 337 338 ipstat.ips_total++; 339 340 if (m->m_pkthdr.len < sizeof(struct ip)) 341 goto tooshort; 342 --- 143 unchanged lines hidden (view full) --- 486 if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) { 487 /* Send packet to the appropriate pipe */ 488 ip_dn_io_ptr(m, i&0xffff, DN_TO_IP_IN, &args); 489 return; 490 } 491#ifdef IPDIVERT 492 if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { 493 /* Divert or tee packet */ | 375 goto iphack ; 376 } 377 378 ipstat.ips_total++; 379 380 if (m->m_pkthdr.len < sizeof(struct ip)) 381 goto tooshort; 382 --- 143 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 */ |
534 divert_info = i; |
|
494 goto ours; 495 } 496#endif 497 if (i == 0 && args.next_hop != NULL) 498 goto pass; 499 /* 500 * if we get here, the packet must be dropped 501 */ --- 291 unchanged lines hidden (view full) --- 793 } 794 m->m_flags |= M_FRAG; 795 } else 796 m->m_flags &= ~M_FRAG; 797 ip->ip_off <<= 3; 798 799 /* 800 * Attempt reassembly; if it succeeds, proceed. | 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. |
801 * ip_reass() will return a different mbuf. | 842 * ip_reass() will return a different mbuf, and update 843 * the divert info in divert_info and args.divert_rule. |
802 */ 803 ipstat.ips_fragments++; 804 m->m_pkthdr.header = ip; | 844 */ 845 ipstat.ips_fragments++; 846 m->m_pkthdr.header = ip; |
805 m = ip_reass(m, &ipq[sum], fp); | 847 m = ip_reass(m, 848 &ipq[sum], fp, &divert_info, &args.divert_rule); |
806 IPQ_UNLOCK(); 807 if (m == 0) 808 return; 809 ipstat.ips_reassembled++; 810 ip = mtod(m, struct ip *); 811 /* Get the header length of the reassembled packet */ 812 hlen = ip->ip_hl << 2; 813#ifdef IPDIVERT 814 /* Restore original checksum before diverting packet */ | 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 */ |
815 if (divert_find_info(m) != 0) { | 858 if (divert_info != 0) { |
816 ip->ip_len += hlen; 817 ip->ip_len = htons(ip->ip_len); 818 ip->ip_off = htons(ip->ip_off); 819 ip->ip_sum = 0; 820 if (hlen == sizeof(struct ip)) 821 ip->ip_sum = in_cksum_hdr(ip); 822 else 823 ip->ip_sum = in_cksum(m, hlen); --- 4 unchanged lines hidden (view full) --- 828#endif 829 } else 830 ip->ip_len -= hlen; 831 832#ifdef IPDIVERT 833 /* 834 * Divert or tee packet to the divert protocol if required. 835 */ | 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 */ |
836 divert_info = divert_find_info(m); | |
837 if (divert_info != 0) { | 879 if (divert_info != 0) { |
838 struct mbuf *clone; | 880 struct mbuf *clone = NULL; |
839 840 /* Clone packet if we're doing a 'tee' */ 841 if ((divert_info & IP_FW_PORT_TEE_FLAG) != 0) | 881 882 /* Clone packet if we're doing a 'tee' */ 883 if ((divert_info & IP_FW_PORT_TEE_FLAG) != 0) |
842 clone = divert_clone(m); 843 else 844 clone = NULL; | 884 clone = m_dup(m, M_DONTWAIT); |
845 846 /* Restore packet header fields to original values */ 847 ip->ip_len += hlen; 848 ip->ip_len = htons(ip->ip_len); 849 ip->ip_off = htons(ip->ip_off); 850 851 /* Deliver packet to divert input routine */ | 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 */ |
852 divert_packet(m, 1); | 892 divert_packet(m, 1, divert_info & 0xffff, args.divert_rule); |
853 ipstat.ips_delivered++; 854 855 /* If 'tee', continue with original packet */ 856 if (clone == NULL) 857 return; 858 m = clone; 859 ip = mtod(m, struct ip *); 860 ip->ip_len += hlen; 861 /* 862 * Jump backwards to complete processing of the | 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 |
863 * packet. We do not need to clear args.next_hop 864 * as that will not be used again and the cloned packet 865 * doesn't contain a divert packet tag so we won't 866 * re-entry this block. | 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. |
867 */ | 907 */ |
908 divert_info = 0; |
|
868 goto pass; 869 } 870#endif 871 872#ifdef IPSEC 873 /* 874 * enforce IPsec policy checking if we are seeing last header. 875 * note that we do not visit this with protocols with pcb layer --- 46 unchanged lines hidden (view full) --- 922#endif /* FAST_IPSEC */ 923 924 /* 925 * Switch out to protocol's input routine. 926 */ 927 ipstat.ips_delivered++; 928 NET_PICKUP_GIANT(); 929 if (args.next_hop && ip->ip_p == IPPROTO_TCP) { | 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 --- 46 unchanged lines hidden (view full) --- 963#endif /* FAST_IPSEC */ 964 965 /* 966 * Switch out to protocol's input routine. 967 */ 968 ipstat.ips_delivered++; 969 NET_PICKUP_GIANT(); 970 if (args.next_hop && ip->ip_p == IPPROTO_TCP) { |
930 /* attach next hop info for TCP */ 931 mtag = m_tag_get(PACKET_TAG_IPFORWARD, 932 sizeof(struct sockaddr_in *), M_NOWAIT); 933 if (mtag == NULL) { 934 /* XXX statistic */ 935 NET_DROP_GIANT(); 936 goto bad; 937 } 938 *(struct sockaddr_in **)(mtag+1) = args.next_hop; 939 m_tag_prepend(m, mtag); 940 } 941 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); | 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); |
942 NET_DROP_GIANT(); 943 return; 944bad: 945 m_freem(m); 946} 947 948/* 949 * Take incoming datagram fragment and try to reassemble it into 950 * whole datagram. If a chain for reassembly of this datagram already 951 * exists, then it is given as fp; otherwise have to make a chain. 952 * 953 * When IPDIVERT enabled, keep additional state with each packet that 954 * tells us if we need to divert or tee the packet we're building. 955 * In particular, *divinfo includes the port and TEE flag, 956 * *divert_rule is the number of the matching rule. 957 */ 958 959static struct mbuf * | 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 * |
960ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp) | 1002ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp, 1003 u_int32_t *divinfo, u_int16_t *divert_rule) |
961{ 962 struct ip *ip = mtod(m, struct ip *); 963 register struct mbuf *p, *q, *nq; 964 struct mbuf *t; 965 int hlen = ip->ip_hl << 2; 966 int i, next; 967 u_int8_t ecn, ecn0; 968 --- 25 unchanged lines hidden (view full) --- 994 fp->ipq_nfrags = 1; 995 fp->ipq_ttl = IPFRAGTTL; 996 fp->ipq_p = ip->ip_p; 997 fp->ipq_id = ip->ip_id; 998 fp->ipq_src = ip->ip_src; 999 fp->ipq_dst = ip->ip_dst; 1000 fp->ipq_frags = m; 1001 m->m_nextpkt = NULL; | 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; |
1045#ifdef IPDIVERT 1046 fp->ipq_div_info = 0; 1047 fp->ipq_div_cookie = 0; 1048#endif |
|
1002 goto inserted; 1003 } else { 1004 fp->ipq_nfrags++; 1005#ifdef MAC 1006 mac_update_ipq(m, fp); 1007#endif 1008 } 1009 --- 67 unchanged lines hidden (view full) --- 1077 ipstat.ips_fragdropped++; 1078 fp->ipq_nfrags--; 1079 m_freem(q); 1080 } 1081 1082inserted: 1083 1084#ifdef IPDIVERT | 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 |
1085 if (ip->ip_off != 0) { 1086 /* 1087 * Strip any divert information; only the info 1088 * on the first fragment is used/kept. 1089 */ 1090 struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL); 1091 if (mtag) 1092 m_tag_delete(m, mtag); | 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; |
1093 } | 1139 } |
1140 *divinfo = 0; 1141 *divert_rule = 0; |
|
1094#endif 1095 1096 /* 1097 * Check for complete reassembly and perform frag per packet 1098 * limiting. 1099 * 1100 * Frag limiting is performed here so that the nth frag has 1101 * a chance to complete the packet before we drop the packet. --- 49 unchanged lines hidden (view full) --- 1151 m->m_pkthdr.csum_data += q->m_pkthdr.csum_data; 1152 m_cat(m, q); 1153 } 1154#ifdef MAC 1155 mac_create_datagram_from_ipq(fp, m); 1156 mac_destroy_ipq(fp); 1157#endif 1158 | 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 |
1207#ifdef IPDIVERT |
|
1159 /* | 1208 /* |
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 /* |
|
1160 * Create header for new ip packet by 1161 * modifying header of first packet; 1162 * dequeue and discard fragment reassembly header. 1163 * Make header visible. 1164 */ 1165 ip->ip_len = next; 1166 ip->ip_src = fp->ipq_src; 1167 ip->ip_dst = fp->ipq_dst; 1168 TAILQ_REMOVE(head, fp, ipq_list); 1169 nipq--; 1170 (void) m_free(dtom(fp)); 1171 m->m_len += (ip->ip_hl << 2); 1172 m->m_data -= (ip->ip_hl << 2); 1173 /* some debugging cruft by sklower, below, will go away soon */ 1174 if (m->m_flags & M_PKTHDR) /* XXX this should be done elsewhere */ 1175 m_fixhdr(m); 1176 return (m); 1177 1178dropfrag: | 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: |
1235#ifdef IPDIVERT 1236 *divinfo = 0; 1237 *divert_rule = 0; 1238#endif |
|
1179 ipstat.ips_fragdropped++; 1180 if (fp != NULL) 1181 fp->ipq_nfrags--; 1182 m_freem(m); 1183 return (0); 1184 1185#undef GETIP 1186} --- 529 unchanged lines hidden (view full) --- 1716 */ 1717static void 1718ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) 1719{ 1720 struct ip *ip = mtod(m, struct ip *); 1721 struct in_ifaddr *ia; 1722 int error, type = 0, code = 0; 1723 struct mbuf *mcopy; | 1239 ipstat.ips_fragdropped++; 1240 if (fp != NULL) 1241 fp->ipq_nfrags--; 1242 m_freem(m); 1243 return (0); 1244 1245#undef GETIP 1246} --- 529 unchanged lines hidden (view full) --- 1776 */ 1777static void 1778ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) 1779{ 1780 struct ip *ip = mtod(m, struct ip *); 1781 struct in_ifaddr *ia; 1782 int error, type = 0, code = 0; 1783 struct mbuf *mcopy; |
1724 struct m_tag *mtag; | |
1725 n_long dest; 1726 struct in_addr pkt_dst; 1727 struct ifnet *destifp; 1728#if defined(IPSEC) || defined(FAST_IPSEC) 1729 struct ifnet dummyifp; 1730#endif 1731 1732 /* --- 116 unchanged lines hidden (view full) --- 1849 printf("redirect (%d) to %lx\n", code, (u_long)dest); 1850#endif 1851 } 1852 } 1853 if (rt) 1854 RTFREE(rt); 1855 } 1856 | 1784 n_long dest; 1785 struct in_addr pkt_dst; 1786 struct ifnet *destifp; 1787#if defined(IPSEC) || defined(FAST_IPSEC) 1788 struct ifnet dummyifp; 1789#endif 1790 1791 /* --- 116 unchanged lines hidden (view full) --- 1908 printf("redirect (%d) to %lx\n", code, (u_long)dest); 1909#endif 1910 } 1911 } 1912 if (rt) 1913 RTFREE(rt); 1914 } 1915 |
1916 { 1917 struct m_hdr tag; 1918 |
|
1857 if (next_hop) { | 1919 if (next_hop) { |
1858 mtag = m_tag_get(PACKET_TAG_IPFORWARD, 1859 sizeof(struct sockaddr_in *), M_NOWAIT); 1860 if (mtag == NULL) { 1861 /* XXX statistic */ 1862 m_freem(m); 1863 return; 1864 } 1865 *(struct sockaddr_in **)(mtag+1) = next_hop; 1866 m_tag_prepend(m, mtag); | 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; |
1867 } 1868 error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL); | 1928 } 1929 error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL); |
1930 } |
|
1869 if (error) 1870 ipstat.ips_cantforward++; 1871 else { 1872 ipstat.ips_forward++; 1873 if (type) 1874 ipstat.ips_redirectsent++; 1875 else { 1876 if (mcopy) --- 286 unchanged lines hidden --- | 1931 if (error) 1932 ipstat.ips_cantforward++; 1933 else { 1934 ipstat.ips_forward++; 1935 if (type) 1936 ipstat.ips_redirectsent++; 1937 else { 1938 if (mcopy) --- 286 unchanged lines hidden --- |