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
Alexander Motin
mav at alkar.net
Mon Feb 23 08:30:35 PST 2004
The following reply was made to PR kern/62957; it has been noted by GNATS.
From: Alexander Motin <mav at alkar.net>
To: freebsd-gnats-submit at 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 at 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--
More information about the freebsd-bugs
mailing list