@@ -27,6 +27,7 @@ enum {
SEG6_LOCAL_OIF,
SEG6_LOCAL_BPF,
SEG6_LOCAL_VRFTABLE,
+ SEG6_LOCAL_COUNTERS,
__SEG6_LOCAL_MAX,
};
#define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1)
@@ -78,4 +79,11 @@ enum {
#define SEG6_LOCAL_BPF_PROG_MAX (__SEG6_LOCAL_BPF_PROG_MAX - 1)
+/* SRv6 Behavior counters */
+struct seg6_local_counters {
+ __u64 rx_packets;
+ __u64 rx_bytes;
+ __u64 rx_errors;
+};
+
#endif
@@ -125,6 +125,27 @@ static void print_srh(FILE *fp, struct ipv6_sr_hdr *srh)
}
}
+static void print_seg6_local_counters(FILE *fp,
+ struct seg6_local_counters *lcounts)
+{
+ if (is_json_context()) {
+ open_json_object("stats64");
+
+ print_u64(PRINT_JSON, "packets", NULL, lcounts->rx_packets);
+ print_u64(PRINT_JSON, "bytes", NULL, lcounts->rx_bytes);
+ print_u64(PRINT_JSON, "errors", NULL, lcounts->rx_errors);
+
+ close_json_object();
+ } else {
+ print_string(PRINT_FP, NULL, "%s ", "packets");
+ print_num(fp, 1, lcounts->rx_packets);
+ print_string(PRINT_FP, NULL, "%s ", "bytes");
+ print_num(fp, 1, lcounts->rx_bytes);
+ print_string(PRINT_FP, NULL, "%s ", "errors");
+ print_num(fp, 1, lcounts->rx_errors);
+ }
+}
+
static const char *seg6_mode_types[] = {
[SEG6_IPTUN_MODE_INLINE] = "inline",
[SEG6_IPTUN_MODE_ENCAP] = "encap",
@@ -325,6 +346,9 @@ static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
if (tb[SEG6_LOCAL_BPF])
print_encap_bpf_prog(fp, tb[SEG6_LOCAL_BPF], "endpoint");
+
+ if (tb[SEG6_LOCAL_COUNTERS] && show_stats)
+ print_seg6_local_counters(fp, RTA_DATA(tb[SEG6_LOCAL_COUNTERS]));
}
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
@@ -866,9 +890,10 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
int segs_ok = 0, hmac_ok = 0, table_ok = 0, vrftable_ok = 0;
+ int action_ok = 0, srh_ok = 0, bpf_ok = 0, counters_ok = 0;
int nh4_ok = 0, nh6_ok = 0, iif_ok = 0, oif_ok = 0;
+ struct seg6_local_counters counters = { 0, 0, 0 };
__u32 action = 0, table, vrftable, iif, oif;
- int action_ok = 0, srh_ok = 0, bpf_ok = 0;
struct ipv6_sr_hdr *srh;
char **argv = *argvp;
int argc = *argcp;
@@ -932,6 +957,11 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
if (!oif)
exit(nodev(*argv));
ret = rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
+ } else if (strcmp(*argv, "count") == 0) {
+ if (counters_ok++)
+ duparg2("count", *argv);
+ ret = rta_addattr_l(rta, len, SEG6_LOCAL_COUNTERS,
+ &counters, sizeof(counters));
} else if (strcmp(*argv, "srh") == 0) {
NEXT_ARG();
if (srh_ok++)