Page MenuHomeFreeBSD

D42980.1790560107.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D42980.1790560107.diff

diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
--- a/sbin/ipfw/dummynet.c
+++ b/sbin/ipfw/dummynet.c
@@ -471,7 +471,7 @@
{
int l;
char qs[30];
- char plr[30];
+ char plr[40];
char red[200]; /* Display RED parameters */
l = fs->qsize;
@@ -482,9 +482,17 @@
sprintf(qs, "%d B", l);
} else
sprintf(qs, "%3d sl.", l);
- if (fs->plr)
- sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
- else
+ if (fs->plr[0] || fs->plr[1]) {
+ if (fs->plr[1] == 0)
+ sprintf(plr, "plr %f",
+ 1.0 * fs->plr[0] / (double)(0x7fffffff));
+ else
+ sprintf(plr, "plr %f,%f,%f,%f",
+ 1.0 * fs->plr[0] / (double)(0x7fffffff),
+ 1.0 * fs->plr[1] / (double)(0x7fffffff),
+ 1.0 * fs->plr[2] / (double)(0x7fffffff),
+ 1.0 * fs->plr[3] / (double)(0x7fffffff));
+ } else
plr[0] = '\0';
if (fs->flags & DN_IS_RED) { /* RED parameters */
@@ -1408,13 +1416,27 @@
case TOK_PLR:
NEED(fs, "plr is only for pipes");
- NEED1("plr needs argument 0..1\n");
- d = strtod(av[0], NULL);
- if (d > 1)
- d = 1;
- else if (d < 0)
- d = 0;
- fs->plr = (int)(d*0x7fffffff);
+ NEED1("plr needs one or four arguments 0..1\n");
+ if ((end = strsep(&av[0], ","))) {
+ d = strtod(end, NULL);
+ d = (d < 0) ? 0 : (d <= 1) ? d : 1;
+ fs->plr[0] = (int)(d*0x7fffffff);
+ }
+ if ((end = strsep(&av[0], ","))) {
+ d = strtod(end, NULL);
+ d = (d < 0) ? 0 : (d <= 1) ? d : 1;
+ fs->plr[1] = (int)(d*0x7fffffff);
+ }
+ if ((end = strsep(&av[0], ","))) {
+ d = strtod(end, NULL);
+ d = (d < 0) ? 0 : (d <= 1) ? d : 1;
+ fs->plr[2] = (int)(d*0x7fffffff);
+ }
+ if ((end = strsep(&av[0], ","))) {
+ d = strtod(end, NULL);
+ d = (d < 0) ? 0 : (d <= 1) ? d : 1;
+ fs->plr[3] = (int)(d*0x7fffffff);
+ }
ac--; av++;
break;
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,5 +1,5 @@
.\"
-.Dd September 28, 2023
+.Dd December 9, 2023
.Dt IPFW 8
.Os
.Sh NAME
@@ -3039,6 +3039,7 @@
loss or congestion at a remote router.
.Pp
.It Cm plr Ar packet-loss-rate
+.It Cm plr Ar G-loss,change-to-B,B-loss,change-to-G
Packet loss rate.
Argument
.Ar packet-loss-rate
@@ -3046,6 +3047,18 @@
loss, 1 meaning 100% loss.
The loss rate is internally represented on 31 bits.
.Pp
+When invoked with four arguments, the simple Gilbert-Elliott
+channel model with two states (Good and Bad) is used with
+associated loss probabilities
+.Po Ar G-loss
+and
+.Ar B-loss Pc
+and state change probabilities
+.Po Ar change-to-B
+and
+.Ar change-to-A Pc
+.
+.Pp
.It Cm queue Brq Ar slots | size Ns Cm Kbytes
Queue size, in
.Ar slots
diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h
--- a/sys/netinet/ip_dummynet.h
+++ b/sys/netinet/ip_dummynet.h
@@ -145,7 +145,7 @@
uint32_t fs_nr; /* the flowset number */
uint32_t flags; /* userland flags */
int qsize; /* queue size in slots or bytes */
- int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */
+ int32_t pl_state; /* packet loss state */
uint32_t buckets; /* buckets used for the queue hash table */
struct ipfw_flow_id flow_mask;
@@ -168,6 +168,7 @@
int min_th ; /* minimum threshold for queue (scaled) */
int max_p ; /* maximum value for p_b (scaled) */
+ int32_t plr[4]; /* PLR, pkt loss rate (2^31-1 means 100%) */
};
/*
diff --git a/sys/netpfil/ipfw/ip_dn_glue.c b/sys/netpfil/ipfw/ip_dn_glue.c
--- a/sys/netpfil/ipfw/ip_dn_glue.c
+++ b/sys/netpfil/ipfw/ip_dn_glue.c
@@ -77,35 +77,35 @@
/* Common to 7.2 and 8 */
struct dn_flow_set {
- SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
+ SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
- u_short fs_nr ; /* flow_set number */
+ u_short fs_nr ; /* flow_set number */
u_short flags_fs;
#define DNOLD_HAVE_FLOW_MASK 0x0001
-#define DNOLD_IS_RED 0x0002
+#define DNOLD_IS_RED 0x0002
#define DNOLD_IS_GENTLE_RED 0x0004
-#define DNOLD_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
-#define DNOLD_NOERROR 0x0010 /* do not report ENOBUFS on drops */
-#define DNOLD_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
-#define DNOLD_IS_PIPE 0x4000
-#define DNOLD_IS_QUEUE 0x8000
+#define DNOLD_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
+#define DNOLD_NOERROR 0x0010 /* do not report ENOBUFS on drops */
+#define DNOLD_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
+#define DNOLD_IS_PIPE 0x4000
+#define DNOLD_IS_QUEUE 0x8000
- struct dn_pipe7 *pipe ; /* pointer to parent pipe */
- u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
+ struct dn_pipe7 *pipe ; /* pointer to parent pipe */
+ u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
- int weight ; /* WFQ queue weight */
- int qsize ; /* queue size in slots or bytes */
- int plr ; /* pkt loss rate (2^31-1 means 100%) */
+ int weight ; /* WFQ queue weight */
+ int qsize ; /* queue size in slots or bytes */
+ int plr[4] ; /* pkt loss rate (2^31-1 means 100%) */
struct ipfw_flow_id flow_mask ;
/* hash table of queues onto this flow_set */
- int rq_size ; /* number of slots */
- int rq_elements ; /* active elements */
- struct dn_flow_queue7 **rq; /* array of rq_size entries */
+ int rq_size ; /* number of slots */
+ int rq_elements ; /* active elements */
+ struct dn_flow_queue7 **rq ; /* array of rq_size entries */
- u_int32_t last_expired ; /* do not expire too frequently */
- int backlogged ; /* #active queues for this flowset */
+ u_int32_t last_expired ; /* do not expire too frequently */
+ int backlogged ; /* #active queues for this flowset */
/* RED parameters */
#define SCALE_RED 16
@@ -420,7 +420,10 @@
fs->flow_mask = f->flow_mask;
fs->buckets = f->rq_size;
fs->qsize = f->qsize;
- fs->plr = f->plr;
+ fs->plr[0] = f->plr[0];
+ fs->plr[1] = f->plr[1];
+ fs->plr[2] = f->plr[2];
+ fs->plr[3] = f->plr[3];
fs->par[0] = f->weight;
fs->flags = convertflags2new(f->flags_fs);
if (fs->flags & DN_IS_GENTLE_RED || fs->flags & DN_IS_RED) {
@@ -645,7 +648,10 @@
fs->parent_nr = l->link_nr - DN_MAX_ID;
fs->qsize = f->fs.qsize;
- fs->plr = f->fs.plr;
+ fs->plr[0] = f->fs.plr[0];
+ fs->plr[1] = f->fs.plr[1];
+ fs->plr[2] = f->fs.plr[2];
+ fs->plr[3] = f->fs.plr[3];
fs->w_q = f->fs.w_q;
fs->max_th = f->max_th;
fs->min_th = f->min_th;
@@ -698,7 +704,10 @@
fs->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
fs->fs_nr = f->fs.fs_nr;
fs->qsize = f->fs.qsize;
- fs->plr = f->fs.plr;
+ fs->plr[0] = f->fs.plr[0];
+ fs->plr[1] = f->fs.plr[1];
+ fs->plr[2] = f->fs.plr[2];
+ fs->plr[3] = f->fs.plr[3];
fs->w_q = f->fs.w_q;
fs->max_th = f->max_th;
fs->min_th = f->min_th;
diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c
--- a/sys/netpfil/ipfw/ip_dn_io.c
+++ b/sys/netpfil/ipfw/ip_dn_io.c
@@ -497,8 +497,22 @@
ni->tot_pkts++;
if (drop)
goto drop;
- if (f->plr && random() < f->plr)
- goto drop;
+ if (f->plr[0] || f->plr[1]) {
+ switch (f->pl_state) {
+ default: /* FALLTHROUGH */
+ case 0: if (__predict_false(f->plr[1]) &&
+ random() < f->plr[1])
+ f->pl_state = 1;
+ if (random() < f->plr[0])
+ goto drop;
+ break;
+ case 1: if (random() < f->plr[3])
+ f->pl_state = 0;
+ if (random() < f->plr[2])
+ goto drop;
+ break;
+ }
+ }
if (m->m_pkthdr.rcvif != NULL)
m_rcvif_serialize(m);
#ifdef NEW_AQM

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 1:48 AM (16 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29946531
Default Alt Text
D42980.1790560107.diff (7 KB)

Event Timeline