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_u32(&rate
, *argv
, 10) != 0) {
69 fprintf(stderr
, "Illegal rate %s\n", *argv
);
74 } else if (matches(*argv
, "group") == 0) {
76 if (get_u32(&group
, *argv
, 10) != 0) {
77 fprintf(stderr
, "Illegal group num %s\n",
83 } else if (matches(*argv
, "trunc") == 0) {
85 if (get_u32(&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
);
104 if (matches(*argv
, "index") == 0) {
106 if (get_u32(&p
.index
, *argv
, 10)) {
107 fprintf(stderr
, "sample: Illegal \"index\"\n");
114 if (!p
.index
&& !group_set
) {
115 fprintf(stderr
, "param \"group\" not set\n");
119 if (!p
.index
&& !rate_set
) {
120 fprintf(stderr
, "param \"rate\" not set\n");
124 tail
= addattr_nest(n
, MAX_MSG
, tca_id
);
125 addattr_l(n
, MAX_MSG
, TCA_SAMPLE_PARMS
, &p
, sizeof(p
));
127 addattr32(n
, MAX_MSG
, TCA_SAMPLE_RATE
, rate
);
129 addattr32(n
, MAX_MSG
, TCA_SAMPLE_PSAMPLE_GROUP
, group
);
131 addattr32(n
, MAX_MSG
, TCA_SAMPLE_TRUNC_SIZE
, trunc
);
133 addattr_nest_end(n
, tail
);
140 static int print_sample(struct action_util
*au
, FILE *f
, struct rtattr
*arg
)
142 struct rtattr
*tb
[TCA_SAMPLE_MAX
+ 1];
148 parse_rtattr_nested(tb
, TCA_SAMPLE_MAX
, arg
);
150 if (!tb
[TCA_SAMPLE_PARMS
] || !tb
[TCA_SAMPLE_RATE
] ||
151 !tb
[TCA_SAMPLE_PSAMPLE_GROUP
]) {
152 print_string(PRINT_FP
, NULL
, "%s", "[NULL sample parameters]");
155 p
= RTA_DATA(tb
[TCA_SAMPLE_PARMS
]);
157 print_string(PRINT_ANY
, "kind", "%s ", "sample");
158 print_uint(PRINT_ANY
, "rate", "rate 1/%u ",
159 rta_getattr_u32(tb
[TCA_SAMPLE_RATE
]));
160 print_uint(PRINT_ANY
, "group", "group %u",
161 rta_getattr_u32(tb
[TCA_SAMPLE_PSAMPLE_GROUP
]));
163 if (tb
[TCA_SAMPLE_TRUNC_SIZE
])
164 print_uint(PRINT_ANY
, "trunc_size", " trunc_size %u",
165 rta_getattr_u32(tb
[TCA_SAMPLE_TRUNC_SIZE
]));
167 print_action_control(f
, " ", p
->action
, "");
169 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
170 print_uint(PRINT_ANY
, "index", "\t index %u", p
->index
);
171 print_int(PRINT_ANY
, "ref", " ref %d", p
->refcnt
);
172 print_int(PRINT_ANY
, "bind", " bind %d", p
->bindcnt
);
175 if (tb
[TCA_SAMPLE_TM
]) {
176 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_SAMPLE_TM
]);
181 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
185 struct action_util sample_action_util
= {
187 .parse_aopt
= parse_sample
,
188 .print_aopt
= print_sample
,