From owner-freebsd-net@FreeBSD.ORG Mon Feb 23 08:41:16 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B62F716A4CE; Mon, 23 Feb 2004 08:41:16 -0800 (PST) Received: from kozlik.carrier.kiev.ua (kozlik.carrier.kiev.ua [193.193.193.111]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0FC3443D2D; Mon, 23 Feb 2004 08:41:16 -0800 (PST) (envelope-from news@pandora.alkar.net) Received: from news.lucky.net (IDENT:root@news.lucky.net [193.193.193.102]) by kozlik.carrier.kiev.ua with ESMTP id i2NGfBcl055656; Mon, 23 Feb 2004 18:41:12 +0200 (EET) (envelope-from news@pandora.alkar.net) Received: (from mail@localhost) by news.lucky.net (8.Who.Cares/8.Who.Cares) id SNX13265; Mon, 23 Feb 2004 18:36:09 +0200 (envelope-from news@pandora.alkar.net) From: Alexander Motin To: freebsd-net@freebsd.org, freebsd-ipfw@freebsd.org Date: Mon, 23 Feb 2004 18:25:49 +0200 Organization: Alkar Teleport News Server Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080204090202030100030402" X-Trace: pandora.alkar.net 1077553549 33615 212.86.226.11 (23 Feb 2004 16:25:49 GMT) X-Complaints-To: abuse@alkar.net User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.6) Gecko/20040119 X-Accept-Language: ru, en-us, en In-Reply-To: Sender: Alkar Teleport News Subsystem X-Verify-Sender: verified Subject: Re: Generating 'Fragment Needed but DF was Set' ICMP & Dummynet X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Feb 2004 16:41:16 -0000 This is a multi-part message in MIME format. --------------080204090202030100030402 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Here are my patches for this problem for FreeBSD 4.8 and 5.2. Review them please. Alexander Motin wrote: > I observe a strange thing. When I create dummynet pipe on output router > interface with lower MTU system stops to generate 'Fragment Needed but > DF was Set' ICMP in cases when it must. If I create this pipe on > incoming interface there is no problem. > > I check this on many routers under 4.8 and 5.2 FreeBSD. > > Is this a bug or feature? :) How pipes can be created leaving ICMP > generation working? -- Alexander Motin --------------080204090202030100030402 Content-Type: text/plain; name="dn_df_48.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dn_df_48.patch" --- ip_dummynet.c.orig Wed May 28 01:36:02 2003 +++ ip_dummynet.c Sat Feb 21 12:49:11 2004 @@ -81,6 +81,7 @@ #include #include #include +#include #include /* for struct arpcom */ #include @@ -407,6 +408,9 @@ transmit_event(struct dn_pipe *pipe) { struct dn_pkt *pkt ; + struct mbuf *mcopy; + struct ip *ip; + int error, type, code; while ( (pkt = pipe->head) && DN_KEY_LEQ(pkt->output_time, curr_time) ) { /* @@ -426,7 +430,39 @@ */ switch (pkt->dn_dir) { case DN_TO_IP_OUT: - (void)ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL, NULL); + MGET(mcopy, M_DONTWAIT, pkt->dn_m->m_type); + if (mcopy != NULL && !m_dup_pkthdr(mcopy, pkt->dn_m, M_DONTWAIT)) { + m_free(mcopy); + mcopy = NULL; + } + if (mcopy != NULL) { + ip = mtod(pkt->dn_m, struct ip *); + mcopy->m_len = imin((ip->ip_hl << 2) + 8, + (int)ip->ip_len); + m_copydata(pkt->dn_m, 0, mcopy->m_len, mtod(mcopy, caddr_t)); + } + + error = ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL, NULL); + + if (mcopy != NULL) { + switch (error) { + case ENETUNREACH: + case EHOSTUNREACH: + case ENETDOWN: + case EHOSTDOWN: + type = ICMP_UNREACH; + code = ICMP_UNREACH_HOST; + icmp_error(mcopy, type, code, 0, pkt->ifp); + break; + case EMSGSIZE: + type = ICMP_UNREACH; + code = ICMP_UNREACH_NEEDFRAG; + icmp_error(mcopy, type, code, 0, pkt->ifp); + break; + default: + m_freem(mcopy); + }; + }; rt_unref (pkt->ro.ro_rt) ; break ; --------------080204090202030100030402 Content-Type: text/plain; name="dn_df_52.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dn_df_52.patch" --- ip_dummynet.c.orig Mon Dec 8 11:50:54 2003 +++ ip_dummynet.c Sat Feb 21 12:17:44 2004 @@ -73,6 +73,7 @@ #include #include #include +#include #include /* for struct arpcom */ #include @@ -426,6 +427,9 @@ transmit_event(struct dn_pipe *pipe) { struct dn_pkt *pkt ; + struct mbuf *mcopy; + struct ip *ip; + int error, type, code; DUMMYNET_LOCK_ASSERT(); @@ -449,7 +453,39 @@ */ switch (pkt->dn_dir) { case DN_TO_IP_OUT: - (void)ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL, NULL); + MGET(mcopy, M_DONTWAIT, pkt->dn_m->m_type); + if (mcopy != NULL && !m_dup_pkthdr(mcopy, pkt->dn_m, M_DONTWAIT)) { + m_free(mcopy); + mcopy = NULL; + } + if (mcopy != NULL) { + ip = mtod(pkt->dn_m, struct ip *); + mcopy->m_len = imin((ip->ip_hl << 2) + 8, + (int)ip->ip_len); + m_copydata(pkt->dn_m, 0, mcopy->m_len, mtod(mcopy, caddr_t)); + } + + error = ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL, NULL); + + if (mcopy != NULL) { + switch (error) { + case ENETUNREACH: + case EHOSTUNREACH: + case ENETDOWN: + case EHOSTDOWN: + type = ICMP_UNREACH; + code = ICMP_UNREACH_HOST; + icmp_error(mcopy, type, code, 0, pkt->ifp); + break; + case EMSGSIZE: + type = ICMP_UNREACH; + code = ICMP_UNREACH_NEEDFRAG; + icmp_error(mcopy, type, code, 0, pkt->ifp); + break; + default: + m_freem(mcopy); + }; + }; rt_unref (pkt->ro.ro_rt, __func__) ; break ; --------------080204090202030100030402--