2 * m_sample.c ingress/egress packet sampling module
4 * This program is free software; you can distribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Yotam Gigi <yotamg@mellanox.com>
16 #include "tc_common.h"
17 #include <linux/tc_act/tc_sample.h>
19 static void explain(void)
21 fprintf(stderr
, "Usage: sample SAMPLE_CONF\n");
22 fprintf(stderr
, "where:\n");
23 fprintf(stderr
, "\tSAMPLE_CONF := SAMPLE_PARAMS | SAMPLE_INDEX\n");
24 fprintf(stderr
, "\tSAMPLE_PARAMS := rate RATE group GROUP [trunc SIZE] [SAMPLE_INDEX]\n");
25 fprintf(stderr
, "\tSAMPLE_INDEX := index INDEX\n");
26 fprintf(stderr
, "\tRATE := The ratio of packets observed at the data source to the samples generated.\n");
27 fprintf(stderr
, "\tGROUP := the psample sampling group\n");
28 fprintf(stderr
, "\tSIZE := the truncation size\n");
29 fprintf(stderr
, "\tINDEX := integer index of the sample action\n");
32 static void usage(void)
38 static int parse_sample(struct action_util
*a
, int *argc_p
, char ***argv_p
,
39 int tca_id
, struct nlmsghdr
*n
)
41 struct tc_sample p
= { 0 };
42 bool trunc_set
= false;
43 bool group_set
= false;
44 bool rate_set
= false;
45 char **argv
= *argv_p
;
53 fprintf(stderr
, "sample bad argument count %d\n", argc
);
58 if (matches(*argv
, "sample") == 0) {
61 fprintf(stderr
, "sample bad argument %s\n", *argv
);
66 if (matches(*argv
, "rate") == 0) {
68 if (get_unsigned(&rate
, *argv
, 10) != 0) {
69 fprintf(stderr
, "Illegal rate %s\n", *argv
);
74 } else if (matches(*argv
, "group") == 0) {
76 if (get_unsigned(&group
, *argv
, 10) != 0) {
77 fprintf(stderr
, "Illegal group num %s\n",
83 } else if (matches(*argv
, "trunc") == 0) {
85 if (get_unsigned(&trunc
, *argv
, 10) != 0) {
86 fprintf(stderr
, "Illegal truncation size %s\n",
92 } else if (matches(*argv
, "help") == 0) {
101 parse_action_control_dflt(&argc
, &argv
, &p
.action
, false, TC_ACT_PIPE
);
105 if (matches(*argv
, "index") == 0) {
107 if (get_u32(&p
.index
, *argv
, 10)) {
108 fprintf(stderr
, "sample: Illegal \"index\"\n");
115 if (!p
.index
&& !group_set
) {
116 fprintf(stderr
, "param \"group\" not set\n");
120 if (!p
.index
&& !rate_set
) {
121 fprintf(stderr
, "param \"rate\" not set\n");
125 tail
= addattr_nest(n
, MAX_MSG
, tca_id
);
126 addattr_l(n
, MAX_MSG
, TCA_SAMPLE_PARMS
, &p
, sizeof(p
));
128 addattr32(n
, MAX_MSG
, TCA_SAMPLE_RATE
, rate
);
130 addattr32(n
, MAX_MSG
, TCA_SAMPLE_PSAMPLE_GROUP
, group
);
132 addattr32(n
, MAX_MSG
, TCA_SAMPLE_TRUNC_SIZE
, trunc
);
134 addattr_nest_end(n
, tail
);
141 static int print_sample(struct action_util
*au
, FILE *f
, struct rtattr
*arg
)
143 struct rtattr
*tb
[TCA_SAMPLE_MAX
+ 1];
149 parse_rtattr_nested(tb
, TCA_SAMPLE_MAX
, arg
);
151 if (!tb
[TCA_SAMPLE_PARMS
] || !tb
[TCA_SAMPLE_RATE
] ||
152 !tb
[TCA_SAMPLE_PSAMPLE_GROUP
]) {
153 fprintf(f
, "[NULL sample parameters]");
156 p
= RTA_DATA(tb
[TCA_SAMPLE_PARMS
]);
158 fprintf(f
, "sample rate 1/%d group %d",
159 rta_getattr_u32(tb
[TCA_SAMPLE_RATE
]),
160 rta_getattr_u32(tb
[TCA_SAMPLE_PSAMPLE_GROUP
]));
162 if (tb
[TCA_SAMPLE_TRUNC_SIZE
])
163 fprintf(f
, " trunc_size %d",
164 rta_getattr_u32(tb
[TCA_SAMPLE_TRUNC_SIZE
]));
166 fprintf(f
, "\n\tindex %d ref %d bind %d", p
->index
, p
->refcnt
,
170 if (tb
[TCA_SAMPLE_TM
]) {
171 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_SAMPLE_TM
]);
180 struct action_util sample_action_util
= {
182 .parse_aopt
= parse_sample
,
183 .print_aopt
= print_sample
,