Date: Mon, 23 Feb 2004 08:30:34 -0800 (PST) From: Alexander Motin <mav@alkar.net> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/62957: When created dummynet pipe on output routerinterface with lower MTU system stops to generate 'Fragment Needed but DF was Set' ICMP in cases when it must Message-ID: <200402231630.i1NGUYHw008305@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/62957; it has been noted by GNATS.
From: Alexander Motin <mav@alkar.net>
To: freebsd-gnats-submit@FreeBSD.org
Cc:
Subject: Re: kern/62957: When created 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
Date: Mon, 23 Feb 2004 18:23:33 +0200
This is a multi-part message in MIME format.
--------------070208060804030100000702
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Here are my patches for this problem for 4.8 and 5.2.
Review them please.
--
Alexander Motin mav@alkar.net
ISP "Alkar-Teleport"
--------------070208060804030100000702
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 <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h> /* for struct arpcom */
#include <net/bridge.h>
@@ -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 ;
--------------070208060804030100000702
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 <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h> /* for struct arpcom */
#include <net/bridge.h>
@@ -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 ;
--------------070208060804030100000702--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200402231630.i1NGUYHw008305>
