Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.203 retrieving revision 1.211 diff -u -p -r1.203 -r1.211 --- src/sys/netinet/ip_input.c 2004/05/25 04:34:00 1.203 +++ src/sys/netinet/ip_input.c 2005/02/03 22:56:42 1.211 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.203 2004/05/25 04:34:00 atatat Exp $ */ +/* $NetBSD: ip_input.c,v 1.211 2005/02/03 22:56:42 perry Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -98,7 +98,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.203 2004/05/25 04:34:00 atatat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.211 2005/02/03 22:56:42 perry Exp $"); #include "opt_inet.h" #include "opt_gateway.h" @@ -200,6 +200,7 @@ int ipprintfs = 0; #endif int ip_do_randomid = 0; +int ip_do_loopback_cksum = 0; /* * XXX - Setting ip_checkinterface mostly implements the receive side of @@ -240,7 +241,7 @@ struct pfil_head inet_pfil_hook; * recalculate IP parameters derived from nmbclusters. */ static int ip_nmbclusters; /* copy of nmbclusters */ -static void ip_nmbclusters_changed __P((void)); /* recalc limits */ +static void ip_nmbclusters_changed(void); /* recalc limits */ #define CHECK_NMBCLUSTER_PARAMS() \ do { \ @@ -274,15 +275,15 @@ int ip_maxfrags; /* limit on fr * repeatedly deleting single packets under heavy fragmentation load * (e.g., from lossy NFS peers). */ -static u_int ip_reass_ttl_decr __P((u_int ticks)); -static void ip_reass_drophalf __P((void)); +static u_int ip_reass_ttl_decr(u_int ticks); +static void ip_reass_drophalf(void); -static __inline int ipq_lock_try __P((void)); -static __inline void ipq_unlock __P((void)); +static __inline int ipq_lock_try(void); +static __inline void ipq_unlock(void); static __inline int -ipq_lock_try() +ipq_lock_try(void) { int s; @@ -301,7 +302,7 @@ ipq_lock_try() } static __inline void -ipq_unlock() +ipq_unlock(void) { int s; @@ -372,7 +373,7 @@ static struct ip_srcrt { struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)]; } ip_srcrt; -static void save_rte __P((u_char *, struct in_addr)); +static void save_rte(u_char *, struct in_addr); #ifdef MBUFTRACE struct mowner ip_rx_mowner = { "internet", "rx" }; @@ -394,7 +395,7 @@ ip_nmbclusters_changed(void) * All protocols not implemented in kernel go to raw IP protocol handler. */ void -ip_init() +ip_init(void) { const struct protosw *pr; int i; @@ -451,7 +452,7 @@ struct route ipforward_rt; * IP software interrupt routine */ void -ipintr() +ipintr(void) { int s; struct mbuf *m; @@ -572,10 +573,16 @@ ip_input(struct mbuf *m) break; default: - /* Must compute it ourselves. */ - INET_CSUM_COUNTER_INCR(&ip_swcsum); - if (in_cksum(m, hlen) != 0) - goto bad; + /* + * Must compute it ourselves. Maybe skip checksum on + * loopback interfaces. + */ + if (__predict_true(!(m->m_pkthdr.rcvif->if_flags & + IFF_LOOPBACK) || ip_do_loopback_cksum)) { + INET_CSUM_COUNTER_INCR(&ip_swcsum); + if (in_cksum(m, hlen) != 0) + goto badcsum; + } break; } @@ -649,6 +656,20 @@ ip_input(struct mbuf *m) return; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; + /* + * XXX The setting of "srcrt" here is to prevent ip_forward() + * from generating ICMP redirects for packets that have + * been redirected by a hook back out on to the same LAN that + * they came from and is not an indication that the packet + * is being inffluenced by source routing options. This + * allows things like + * "rdr tlp0 0/0 port 80 -> 1.1.1.200 3128 tcp" + * where tlp0 is both on the 1.1.1.0/24 network and is the + * default route for hosts on 1.1.1.0/24. Of course this + * also requires a "map tlp0 ..." to complete the story. + * One might argue whether or not this kind of network config. + * should be supported in this manner... + */ srcrt = (odst.s_addr != ip->ip_dst.s_addr); } #endif /* PFIL_HOOKS */ @@ -712,7 +733,7 @@ ip_input(struct mbuf *m) if (ia != NULL) goto ours; if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { - TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrlist, ifa_list) { + IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { if (ifa->ifa_addr->sa_family != AF_INET) continue; ia = ifatoia(ifa); @@ -1023,10 +1044,7 @@ badcsum: * is given as fp; otherwise have to make a chain. */ struct mbuf * -ip_reass(ipqe, fp, ipqhead) - struct ipqent *ipqe; - struct ipq *fp; - struct ipqhead *ipqhead; +ip_reass(struct ipqent *ipqe, struct ipq *fp, struct ipqhead *ipqhead) { struct mbuf *m = ipqe->ipqe_m; struct ipqent *nq, *p, *q; @@ -1226,8 +1244,7 @@ dropfrag: * associated datagrams. */ void -ip_freef(fp) - struct ipq *fp; +ip_freef(struct ipq *fp) { struct ipqent *q, *p; u_int nfrags = 0; @@ -1324,7 +1341,7 @@ ip_reass_drophalf(void) * queue, discard it. */ void -ip_slowtimo() +ip_slowtimo(void) { static u_int dropscanidx = 0; u_int i; @@ -1381,7 +1398,7 @@ ip_slowtimo() * Drain off all datagram fragments. */ void -ip_drain() +ip_drain(void) { /* @@ -1408,8 +1425,7 @@ ip_drain() * 0 if the packet should be processed further. */ int -ip_dooptions(m) - struct mbuf *m; +ip_dooptions(struct mbuf *m) { struct ip *ip = mtod(m, struct ip *); u_char *cp, *cp0; @@ -1638,8 +1654,7 @@ bad: * return internet address info of interface to be used to get there. */ struct in_ifaddr * -ip_rtaddr(dst) - struct in_addr dst; +ip_rtaddr(struct in_addr dst) { struct sockaddr_in *sin; @@ -1666,9 +1681,7 @@ ip_rtaddr(dst) * to be picked up later by ip_srcroute if the receiver is interested. */ void -save_rte(option, dst) - u_char *option; - struct in_addr dst; +save_rte(u_char *option, struct in_addr dst) { unsigned olen; @@ -1690,7 +1703,7 @@ save_rte(option, dst) * The first hop is placed before the options, will be removed later. */ struct mbuf * -ip_srcroute() +ip_srcroute(void) { struct in_addr *p, *q; struct mbuf *m; @@ -1762,9 +1775,7 @@ ip_srcroute() * XXX should be deleted; last arg currently ignored. */ void -ip_stripoptions(m, mopt) - struct mbuf *m; - struct mbuf *mopt; +ip_stripoptions(struct mbuf *m, struct mbuf *mopt) { int i; struct ip *ip = mtod(m, struct ip *); @@ -1806,9 +1817,7 @@ const int inetctlerrmap[PRC_NCMDS] = { * via a source route. */ void -ip_forward(m, srcrt) - struct mbuf *m; - int srcrt; +ip_forward(struct mbuf *m, int srcrt) { struct ip *ip = mtod(m, struct ip *); struct sockaddr_in *sin; @@ -2036,11 +2045,8 @@ ip_forward(m, srcrt) } void -ip_savecontrol(inp, mp, ip, m) - struct inpcb *inp; - struct mbuf **mp; - struct ip *ip; - struct mbuf *m; +ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip, + struct mbuf *m) { if (inp->inp_socket->so_options & SO_TIMESTAMP) { @@ -2328,4 +2334,11 @@ SYSCTL_SETUP(sysctl_net_inet_ip_setup, " NULL, 0, &ip_do_randomid, 0, CTL_NET, PF_INET, IPPROTO_IP, IPCTL_RANDOMID, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "do_loopback_cksum", + SYSCTL_DESCR("Perform IP checksum on loopback"), + NULL, 0, &ip_do_loopback_cksum, 0, + CTL_NET, PF_INET, IPPROTO_IP, + IPCTL_LOOPBACKCKSUM, CTL_EOL); }