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