All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabio Ludovici <fabio.ludovici@yahoo.it>
To: netdev@vger.kernel.org
Subject: Re: [PATCH] netem/iproute2 solving correlated loss issues [5/5]
Date: Fri, 18 Dec 2009 12:30:55 +0100	[thread overview]
Message-ID: <4B2B67EF.6030507@yahoo.it> (raw)
In-Reply-To: <4B2B5A65.1060300@uniroma2.it>

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

patch 5/5 : iproute2-2.6.29-1/tc/q_netem.c


[-- Attachment #2: tc_patch_5_of_5 --]
[-- Type: text/plain, Size: 16662 bytes --]

diff -uNr iproute2-2.6.29-1/tc/q_netem.c iproute2-2.6.29-1-netem/tc/q_netem.c
--- iproute2-2.6.29-1/tc/q_netem.c	2009-03-24 23:40:54.000000000 +0100
+++ iproute2-2.6.29-1-netem/tc/q_netem.c	2009-12-11 16:41:14.766468716 +0100
@@ -7,7 +7,6 @@
  *		2 of the License, or (at your option) any later version.
  *
  * Authors:	Stephen Hemminger <shemminger@osdl.org>
- *
  */
 
 #include <stdio.h>
@@ -29,9 +28,19 @@
 {
 	fprintf(stderr,
 "Usage: ... netem [ limit PACKETS ] \n" \
+"                 [ logging LEVEL ] \n" \
+"		  [ query ] \n" \
 "                 [ delay TIME [ JITTER [CORRELATION]]]\n" \
 "                 [ distribution {uniform|normal|pareto|paretonormal} ]\n" \
 "                 [ drop PERCENT [CORRELATION]] \n" \
+"		  [ loss_GI ploss [burst_length [density [pisol [good_burst_length]]]]] \n" \
+"		  [ loss_GI_tran p13 p31 [p32 p23 [p14]]]  \n" \
+"		  [ loss_bern p ] \n" \
+"		  [ loss_gilb_4s p r [1-h]] \n" \
+"		  [ loss_gilbell_4s p r [1-h [1-k]]] \n" \
+"		  [ loss_gilb p r [1-h]] \n" \
+"		  [ loss_gilbell p r [1-h [1-k]]] \n" \
+"                 [ loss_pattern [filename [repetitions]]] \n" \
 "                 [ corrupt PERCENT [CORRELATION]] \n" \
 "                 [ duplicate PERCENT [CORRELATION]]\n" \
 "                 [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n");
@@ -138,6 +147,10 @@
 
 	memset(&opt, 0, sizeof(opt));
 	opt.limit = 1000;
+	opt.query = 0; 
+	opt.logging = 0; 
+	opt.pattern_length = 0;
+	opt.pattern_repetitions = 0; 
 	memset(&cor, 0, sizeof(cor));
 	memset(&reorder, 0, sizeof(reorder));
 	memset(&corrupt, 0, sizeof(corrupt));
@@ -150,6 +163,14 @@
 				explain1("limit");
 				return -1;
 			}
+		} else if (matches(*argv, "logging") == 0) {		
+			NEXT_ARG();
+			if (get_size(&opt.logging, *argv)) {
+				explain1("logging");
+				return -1;
+			}
+		} else if (matches(*argv, "query") == 0) {		
+			opt.query=1;			
 		} else if (matches(*argv, "latency") == 0 ||
 			   matches(*argv, "delay") == 0) {
 			NEXT_ARG();
@@ -189,6 +210,506 @@
 					return -1;
 				}
 			}
+		} else if (matches(*argv, "loss_GI") == 0)  {		
+			NEXT_ARG();
+
+			double p13=0;
+			double p31=1;
+			double p32=0;
+			double p23=1;
+			double p14=0;
+			double ploss=0;
+			double burst_length=1;
+			double rho=1;
+			double pisol=0;
+			double good_burst_length=0;
+
+			opt.algorithm=0;	//algorithm 0 is GI, 1 is gilbell
+			
+			ploss=strtod(*argv,(char **)NULL)/100;
+
+			if (NEXT_IS_NUMBER()) {			
+			NEXT_ARG();
+			burst_length=strtod(*argv,(char **)NULL);
+			
+			if (NEXT_IS_NUMBER()) {
+			NEXT_ARG();			
+			rho=strtod(*argv,(char **)NULL)/100;
+			
+			if (ploss>rho) {
+			printf("\nError: ploss>density \n");
+			break;
+			}
+			
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			pisol=strtod(*argv,(char **)NULL)/100;
+			
+			if (pisol>ploss) {
+			printf("\nError: pisol>ploss \n");
+			break;
+			}
+
+			if (ploss>(rho-pisol*(rho-1))) {
+			printf("\nError: ploss>density-pisol(density-1) \n");
+			break;
+			}
+			
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			good_burst_length=strtod(*argv,(char **)NULL);
+			if (good_burst_length>burst_length) {printf("\nError: good burst length>burst length \n ");
+			break;
+							}
+						}		
+					}
+				}
+			}
+					
+			if(burst_length==0) {
+			p13=ploss;
+			p31=1-ploss;
+			}
+			
+			else if((burst_length!=0) & (rho==1) & (pisol==0)) {
+			p13=ploss/(burst_length*(1-ploss));
+			p31=1/burst_length;
+			} 
+			
+			else if ((burst_length!=0) & (rho!=1) & (pisol==0)) {
+			p13=(-ploss)/(burst_length*ploss-burst_length*rho);
+			p31=1/(burst_length*rho);
+			}
+			
+			else if ((burst_length!=0) & (rho!=1) & (pisol!=0)) {
+			p13=(pisol-ploss)/(burst_length*(pisol-1)*(rho-ploss));
+			p31=1/(burst_length*rho);
+			p14=pisol/(1-pisol);
+			}
+				
+			if((burst_length!=0) & (rho!=1))	{
+			
+				if(good_burst_length==0)	{
+				p23=(burst_length*rho-1) / (burst_length-1);
+				p32=(1+rho*rho*burst_length-rho-burst_length*rho) / (rho-rho*burst_length);
+							        					}				
+				else	{
+				p23=1/good_burst_length;
+				p32=(1-rho) / (rho*good_burst_length);				
+					}	
+					
+								}
+					
+			if (burst_length==0) burst_length=1/p31;						
+						
+			printf("\nTransition probabilities are:\n ");
+			printf("--------------------------------");
+			printf("\np13 is %.3f%% ", 100*p13);
+			printf("\np31 is %.3f%% ", 100*p31);
+			printf("\np32 is %.3f%% ", 100*p32);
+			printf("\np23 is %.3f%% ", 100*p23);
+			printf("\np14 is %.3f%%\n ", 100*p14);
+			
+			printf("\nGI (General and Intuitive) parameters will be: \n");
+			printf("--------------------------------");
+			printf("\nploss is %.3f%% ", 100*ploss);
+			printf("\nburst length is %.3f", burst_length);
+			printf("\nburst density is %.3f%% ", 100*rho);
+			printf("\nisolated ploss is %.3f%% ", 100*pisol);
+			printf("\ngood burst length is %.3f\n ", good_burst_length);
+
+			if(opt.query==0)	{
+			opt.p13=4294967295u*p13;
+			opt.p31=4294967295u*p31;
+			opt.p32=4294967295u*p32;
+			opt.p23=4294967295u*p23;
+			opt.p14=4294967295u*p14;			
+			}
+			
+			if(opt.query==1) return -1;	
+
+		} else if (matches(*argv, "loss_GI_tran") == 0)  {
+
+			double p13=0;
+			double p31=1;
+			double p32=0;
+			double p23=1;
+			double p14=0;
+			double ploss;
+			double burst_length;
+			double rho;
+			double pisol;
+			double good_burst_length;
+
+			opt.algorithm=0; 	//algorithm 0 is 4-state, 1 is gilbell
+
+			NEXT_ARG();
+			p13=strtod(*argv,(char **)NULL)/100;
+
+			if (NEXT_IS_NUMBER()) {			
+			NEXT_ARG();
+			p31=strtod(*argv,(char **)NULL)/100;
+			if (NEXT_IS_NUMBER()) {
+			NEXT_ARG();
+			p32=strtod(*argv,(char **)NULL)/100;
+			if (NEXT_IS_NUMBER()) {
+			NEXT_ARG();
+			p23=strtod(*argv,(char **)NULL)/100;
+			if (NEXT_IS_NUMBER()) {
+			NEXT_ARG();
+			p14=strtod(*argv,(char **)NULL)/100;
+			}
+			}
+			}
+			}
+
+			else p31=1-p13;
+			
+			printf("\nTransition probabilities are:\n ");
+			printf("--------------------------------");
+			printf("\np13 is %.3f%% ", 100*p13);
+			printf("\np31 is %.3f%% ", 100*p31);
+			printf("\np32 is %.3f%% ", 100*p32);
+			printf("\np23 is %.3f%% ", 100*p23);
+			printf("\np14 is %.3f%%\n ", 100*p14);
+
+			ploss=(p13*p23+p14*p23*p31) / (p13*p23+p23*p31+p14*p23*p31+p13*p32);
+			burst_length=(p32+p23) / (p23*p31);
+			rho=(p13*p23) / (p13*p23+p13*p32);
+			pisol=(p14*p23*p31) / (p14*p23*p31+p23*p31);
+			good_burst_length=1/p23;
+
+			printf("\nGI (General and Intuitive) parameters will be: \n");
+			printf("--------------------------------");
+			printf("\nploss is %.3f%%", 100*ploss);
+			printf("\nburst length is %.3f", burst_length);
+			printf("\nburst density is %.3f%% ", 100*rho);
+			printf("\nisolated ploss is %.3f%% ", 100*pisol);
+			printf("\ngood burst length is %.3f\n ", good_burst_length);
+
+			if(opt.query==0)	{
+			opt.p13=4294967295u*p13;
+			opt.p31=4294967295u*p31;
+			opt.p32=4294967295u*p32;
+			opt.p23=4294967295u*p23;
+			opt.p14=4294967295u*p14;			
+			}
+			
+			if(opt.query==1) return -1;
+			
+		} else if (matches(*argv, "loss_gilb") == 0)  {
+			
+			double p=0;
+			double r=0;
+			double h=0;
+									
+			opt.algorithm=1;	//algorithm 1 is gilbell
+					
+			NEXT_ARG();
+			p=strtod(*argv,(char **)NULL)/100;
+			
+			NEXT_ARG();
+			r=strtod(*argv,(char **)NULL)/100;
+						
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			h=(100-strtod(*argv,(char **)NULL))/100;						
+			}
+
+			printf("\nGilbert parameters will be: \n");
+			printf("--------------------------------");
+			printf("\np is %.3f%% ", 100*p);
+			printf("\nr is %.3f%%", 100*r);
+			printf("\n1-h is %.3f%%\n", 100*(1-h));	
+			
+			opt.gilb_p=4294967295u*p;
+			opt.gilb_r=4294967295u*r;
+			opt.gilb_h=4294967295u*h;
+														
+		} else if (matches(*argv, "loss_gilbell") == 0)  {
+			
+			double p=0;
+			double r=0;
+			double h=0;
+			double k=1;
+			
+			opt.algorithm=1;	//algorithm 1 is gilbell
+					
+			NEXT_ARG();
+			p=strtod(*argv,(char **)NULL)/100;
+			
+			NEXT_ARG();
+			r=strtod(*argv,(char **)NULL)/100;
+						
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			h=(100-strtod(*argv,(char **)NULL))/100;
+						
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			k=(100-strtod(*argv,(char **)NULL))/100;			
+						}
+						}
+
+			printf("\nGilbert-Elliot parameters will be: \n");
+			printf("--------------------------------");
+			printf("\np is %.3f%% ", 100*p);
+			printf("\nr is %.3f%%", 100*r);
+			printf("\n1-h is %.3f%% ", 100*(1-h));
+			printf("\n1-k is %.3f%%\n", 100*(1-k));		
+			
+			opt.gilb_p=4294967295u*p;
+			opt.gilb_r=4294967295u*r;
+			opt.gilb_h=4294967295u*h;
+			opt.gilb_k=4294967295u*k;		
+
+		} else if (matches(*argv, "loss_bern") == 0)  {		
+			
+			double p=0;
+			double r=0;
+			double ploss=0;
+			double burst_length=1;
+			double p13=0;
+			double p31=0;
+			
+			opt.algorithm=0;	//algorithm 0 is 4-state, 1 is gilbell
+					
+			NEXT_ARG();
+			p=strtod(*argv,(char **)NULL)/100;
+			r=1-p;
+			
+			ploss=p/(p+r);
+			burst_length=1/r;
+			
+			p13=p;
+			p31=r;
+
+			printf("\nTransition probabilities are:\n ");
+			printf("--------------------------------");
+			printf("\np13 is %.3f%% ", 100*p13);
+			printf("\np31 is %.3f%% ", 100*p31);
+			printf("\np32 is 0.000%% ");
+			printf("\np23 is 100.000%% ");
+			printf("\np14 is 0.000%%\n ");
+			
+			printf("\nGI (General and Intuitive) parameters will be: \n");
+			printf("--------------------------------");
+			printf("\nploss is %.3f%% ", 100*ploss);
+			printf("\nburst length is %.3f", burst_length);
+			printf("\nburst density is 100.000%% ");
+			printf("\nisolated ploss is 0.000%% ");
+			printf("\ngood burst length is 1.000%%\n "); 
+
+			if(opt.query==0)	{
+			opt.p13=4294967295u*p13;
+			opt.p31=4294967295u*p31;
+			opt.p32=0;
+			opt.p23=4294967295u;
+			opt.p14=0;			
+			}
+			
+			if(opt.query==1) return -1;			
+
+		} else if (matches(*argv, "loss_gilb_4s") == 0)  {
+			double p=0;
+			double r=0;
+			double h=0;
+			double ploss=0;
+			double burst_length=1;
+			double rho=1;
+			double p13=0;
+			double p31=1;
+			double p23=1;
+			double p32=0;
+			
+			opt.algorithm=0;	//algorithm 0 is 4-state, 1 is gilbell
+					
+			NEXT_ARG();
+			p=strtod(*argv,(char **)NULL)/100;
+			
+			NEXT_ARG();
+			r=strtod(*argv,(char **)NULL)/100;						
+			
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			h=(100-strtod(*argv,(char **)NULL))/100;
+						
+						}
+
+			ploss=(r-+p-h*p)/(p+r);
+			burst_length=(1/(r-r*h))*((h*h*(1-h+2*r*h*h-6*r*h+2*r))+(2*h*(1-h)*(1-h+r*h*h-3*h*r+r))+((1-h)*(1-h)*(1-h)));
+			
+			if(h!=0) rho=(1-h)/(r*burst_length);
+			else rho=1;
+	
+			p13=(-ploss)/(burst_length*(-rho+ploss));
+			p31=1/(burst_length*rho);
+
+			if (rho<1)	{	
+        		p32=(1+rho*rho*burst_length-rho-burst_length*rho) / (rho-rho*burst_length);
+			p23=(burst_length*rho-1) / (burst_length-1);			
+			}
+
+			else 	{
+			p32=0;
+			p23=1;
+			}
+
+			printf("\nTransition probabilities are:\n ");
+			printf("--------------------------------");
+			printf("\np13 is %.3f%% ", 100*p13);
+			printf("\np31 is %.3f%% ", 100*p31);
+			printf("\np32 is %.3f%% ", 100*p32);
+			printf("\np23 is %.3f%% ", 100*p23);
+			printf("\np14 is 0.000%%\n");
+			
+			printf("\nGI (General and Intuitive) parameters will be: \n");
+			printf("--------------------------------");
+			printf("\nploss is %.3f%% ", 100*ploss);
+			printf("\nburst length is %.3f", burst_length);
+			printf("\nburst density is %.3f%% ", 100*rho);
+			printf("\nisolated ploss is 0.000%% ");
+			printf("\ngood burst length is %.3f\n ", 1/p23); 
+
+			if(opt.query==0)	{
+			opt.p13=4294967295u*p13;
+			opt.p31=4294967295u*p31;
+			if(rho!=1) {
+			opt.p32=4294967295u*p32;
+			opt.p23=4294967295u*p23;
+			}
+			else {
+			opt.p32=0;
+			opt.p23=4294967295u;
+			}
+						}	
+			
+			if(opt.query==1) return -1;	
+
+		} else if (matches(*argv, "loss_gilbell_4s") == 0)  {
+			
+			double p=0;
+			double r=0;
+			double h=0;
+			double k=1;
+			double ploss=0;
+			double burst_length=1;
+			double rho=1;
+			double pisol=0;	
+			double p13=0;
+			double p31=1;
+			double p23=1;
+			double p32=0;
+			double p14=0;
+
+			opt.algorithm=0;	//algoritnm 1 is gilbell
+					
+			NEXT_ARG();
+			p=strtod(*argv,(char **)NULL)/100;
+			
+			NEXT_ARG();
+			r=strtod(*argv,(char **)NULL)/100;
+						
+			
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			h=(100-strtod(*argv,(char **)NULL))/100;
+						
+			if (NEXT_IS_NUMBER())	{
+			NEXT_ARG();
+			k=(100-strtod(*argv,(char **)NULL))/100;
+			
+						}
+						}
+
+			ploss=(r-k*r+p-h*p)/(p+r);
+			burst_length=(1/(r-r*h))*((h*h*(1-h+2*r*h*h-6*r*h+2*r))+(2*h*(1-h)*(1-h+r*h*h-3*h*r+r))+((1-h)*(1-h)*(1-h)));
+			
+			if(h!=0) rho=(1-h)/(r*burst_length);
+			else rho=1;
+	
+			if(k!=1) pisol=1-k;
+			else pisol=0;
+	
+			p13=(pisol-ploss)/(burst_length*(pisol*(rho-1)-rho+ploss));
+			p31=1/(burst_length*rho);
+
+			if (rho<1)	{	
+        		p32=(1+rho*rho*burst_length-rho-burst_length*rho) / (rho-rho*burst_length);
+			p23=(burst_length*rho-1) / (burst_length-1);			
+			}
+
+			else 	{
+			p32=0;
+			p23=1;
+			}
+
+			if (pisol!=0) p14=(pisol) / (1-pisol);
+			else p14=0;			
+			
+			printf("\nTransition probabilities are:\n ");
+			printf("--------------------------------");
+			printf("\np13 is %.3f%% ", 100*p13);
+			printf("\np31 is %.3f%% ", 100*p31);
+			printf("\np32 is %.3f%% ", 100*p32);
+			printf("\np23 is %.3f%% ", 100*p23);
+			printf("\np14 is %.3f%%\n ", 100*p14);
+			
+			printf("\nGI (General and Intuitive) parameters will be: \n");
+			printf("--------------------------------");
+			printf("\nploss is %.3f%% ", 100*ploss);
+			printf("\nburst length is %.3f", burst_length);
+			printf("\nburst density is %.3f%% ", 100*rho);
+			printf("\nisolated ploss is %.3f%% ", 100*pisol);
+			printf("\ngood burst length is %.3f\n ", 1/p23); 
+
+			if(opt.query==0)	{
+			opt.p13=4294967295u*p13;
+			opt.p31=4294967295u*p31;
+			if(rho!=1) {
+			opt.p32=4294967295u*p32;
+			opt.p23=4294967295u*p23;
+			}
+			else {
+			opt.p32=0;
+			opt.p23=4294967295u;
+			}
+			if(pisol>0) opt.p14=4294967295u*p14;
+			else opt.p14=0;		
+						}
+						
+			if(opt.query==1) return -1;				
+					
+		} else if (matches(*argv, "loss_pattern") == 0)  {	//LOSS PATTERN		
+			NEXT_ARG();
+						
+			int i; 
+					
+			FILE *sequence;
+			
+			sequence=fopen(*argv, "r");
+			
+			if (sequence == NULL) {
+				printf("Could not open the file %s \n", *argv);
+				exit(1);  } 				
+
+			fseek(sequence, 0, SEEK_END);
+			fgetpos(sequence, &opt.pattern_length);
+			rewind(sequence);
+
+			opt.user_pattern=malloc(opt.pattern_length*sizeof(int));
+			opt.pattern_repetitions=0;  			
+
+			for(i=1; i<opt.pattern_length; i++) {
+			if(fgetc(sequence)=='1') opt.user_pattern[i-1]=1;			
+			else opt.user_pattern[i-1]=0; }
+
+  			fclose(sequence);
+   			
+   			if (NEXT_IS_NUMBER()) {			
+			NEXT_ARG();
+			opt.pattern_repetitions=strtod(*argv,(char **)NULL);
+						}
 		} else if (matches(*argv, "reorder") == 0) {
 			NEXT_ARG();
 			present[TCA_NETEM_REORDER] = 1;
@@ -344,6 +865,46 @@
 	}
 
 	fprintf(f, "limit %d", qopt.limit);
+	if(qopt.logging!=0) fprintf(f, " logging %d", qopt.logging); 
+	if(qopt.pattern_length!=0) fprintf(f, " pattern_length %d", qopt.pattern_length);
+	if(qopt.pattern_repetitions!=0) fprintf(f, " pattern_repetitions %d", qopt.pattern_repetitions);
+	int j;
+	for (j=1; j<qopt.pattern_length; j++) {
+	fprintf(f, " pattern element %d is %d\n", j-1, qopt.user_pattern[j-1]);
+						}
+	
+	if (qopt.latency) {
+		fprintf(f, " delay %s", sprint_ticks(qopt.latency, b1));
+
+		if (qopt.jitter) {
+			fprintf(f, "  %s", sprint_ticks(qopt.jitter, b1));
+			if (cor && cor->delay_corr)
+				fprintf(f, " %s", sprint_percent(cor->delay_corr, b1));
+		}
+	}
+
+	if (qopt.loss) {
+		fprintf(f, " loss %s", sprint_percent(qopt.loss, b1));
+		if (cor && cor->loss_corr)
+			fprintf(f, " %s", sprint_percent(cor->loss_corr, b1));
+	}
+	
+	if (qopt.p13) {								
+		fprintf(f, " p13 %s", sprint_percent(qopt.p13, b1));
+		fprintf(f, " p31 %s", sprint_percent(qopt.p31, b1));
+		fprintf(f, " p32 %s", sprint_percent(qopt.p32, b1));
+		fprintf(f, " p23 %s", sprint_percent(qopt.p23, b1));
+		fprintf(f, " p14 %s", sprint_percent(qopt.p14, b1));
+			}	
+			
+	if (qopt.gilb_p) {								
+		fprintf(f, " p %s", sprint_percent(qopt.gilb_p, b1));
+		fprintf(f, " r %s", sprint_percent(qopt.gilb_r, b1));
+		fprintf(f, " h %s", sprint_percent(qopt.gilb_h, b1));
+		if (qopt.gilb_k) fprintf(f, " k %s", sprint_percent(qopt.gilb_k, b1));
+			}		
+
+	fprintf(f, "limit %d", qopt.limit);
 
 	if (qopt.latency) {
 		fprintf(f, " delay %s", sprint_ticks(qopt.latency, b1));

      parent reply	other threads:[~2009-12-18 11:30 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <4B2B5A26.8050400@uniroma2.it>
2009-12-18 11:24 ` [PATCH] netem/iproute2 solving correlated loss issues [2/5] Fabio Ludovici
2009-12-18 17:36   ` Stephen Hemminger
2009-12-18 23:49     ` Stefano Salsano
2009-12-19  4:01     ` David Miller
2009-12-19  9:48       ` Stefano Salsano
2009-12-18 11:27 ` [PATCH] netem/iproute2 solving correlated loss issues [3/5] Fabio Ludovici
2009-12-18 11:30 ` [PATCH] netem/iproute2 solving correlated loss issues [4/5] Fabio Ludovici
     [not found] ` <4B2B5A65.1060300@uniroma2.it>
2009-12-18 11:30   ` Fabio Ludovici [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B2B67EF.6030507@yahoo.it \
    --to=fabio.ludovici@yahoo.it \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.