]>
Commit | Line | Data |
---|---|---|
0d71302e BP |
1 | /* |
2 | * Copyright (c) 2008-2017 Nicira, Inc. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | #include "openvswitch/ofp-ipfix.h" | |
19 | #include <stdlib.h> | |
20 | #include "byte-order.h" | |
21 | #include "openflow/nicira-ext.h" | |
22 | #include "openvswitch/ofp-errors.h" | |
23 | #include "openvswitch/ofp-msgs.h" | |
24 | #include "openvswitch/ofpbuf.h" | |
25 | #include "util.h" | |
26 | ||
27 | static void | |
28 | ofputil_ipfix_stats_to_reply(const struct ofputil_ipfix_stats *ois, | |
29 | struct nx_ipfix_stats_reply *reply) | |
30 | { | |
31 | reply->collector_set_id = htonl(ois->collector_set_id); | |
32 | reply->total_flows = htonll(ois->total_flows); | |
33 | reply->current_flows = htonll(ois->current_flows); | |
34 | reply->pkts = htonll(ois->pkts); | |
35 | reply->ipv4_pkts = htonll(ois->ipv4_pkts); | |
36 | reply->ipv6_pkts = htonll(ois->ipv6_pkts); | |
37 | reply->error_pkts = htonll(ois->error_pkts); | |
38 | reply->ipv4_error_pkts = htonll(ois->ipv4_error_pkts); | |
39 | reply->ipv6_error_pkts = htonll(ois->ipv6_error_pkts); | |
40 | reply->tx_pkts = htonll(ois->tx_pkts); | |
41 | reply->tx_errors = htonll(ois->tx_errors); | |
42 | memset(reply->pad, 0, sizeof reply->pad); | |
43 | } | |
44 | ||
45 | /* Encode a ipfix stat for 'ois' and append it to 'replies'. */ | |
46 | void | |
47 | ofputil_append_ipfix_stat(struct ovs_list *replies, | |
48 | const struct ofputil_ipfix_stats *ois) | |
49 | { | |
50 | struct nx_ipfix_stats_reply *reply = ofpmp_append(replies, sizeof *reply); | |
51 | ofputil_ipfix_stats_to_reply(ois, reply); | |
52 | } | |
53 | ||
54 | static enum ofperr | |
55 | ofputil_ipfix_stats_from_nx(struct ofputil_ipfix_stats *is, | |
56 | const struct nx_ipfix_stats_reply *reply) | |
57 | { | |
58 | is->collector_set_id = ntohl(reply->collector_set_id); | |
59 | is->total_flows = ntohll(reply->total_flows); | |
60 | is->current_flows = ntohll(reply->current_flows); | |
61 | is->pkts = ntohll(reply->pkts); | |
62 | is->ipv4_pkts = ntohll(reply->ipv4_pkts); | |
63 | is->ipv6_pkts = ntohll(reply->ipv6_pkts); | |
64 | is->error_pkts = ntohll(reply->error_pkts); | |
65 | is->ipv4_error_pkts = ntohll(reply->ipv4_error_pkts); | |
66 | is->ipv6_error_pkts = ntohll(reply->ipv6_error_pkts); | |
67 | is->tx_pkts = ntohll(reply->tx_pkts); | |
68 | is->tx_errors = ntohll(reply->tx_errors); | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | int | |
74 | ofputil_pull_ipfix_stats(struct ofputil_ipfix_stats *is, struct ofpbuf *msg) | |
75 | { | |
76 | enum ofperr error; | |
77 | enum ofpraw raw; | |
78 | ||
79 | memset(is, 0xFF, sizeof (*is)); | |
80 | ||
81 | error = (msg->header ? ofpraw_decode(&raw, msg->header) | |
82 | : ofpraw_pull(&raw, msg)); | |
83 | if (error) { | |
84 | return error; | |
85 | } | |
86 | ||
87 | if (!msg->size) { | |
88 | return EOF; | |
89 | } else if (raw == OFPRAW_NXST_IPFIX_BRIDGE_REPLY || | |
90 | raw == OFPRAW_NXST_IPFIX_FLOW_REPLY) { | |
91 | struct nx_ipfix_stats_reply *reply; | |
92 | ||
93 | reply = ofpbuf_try_pull(msg, sizeof *reply); | |
94 | return ofputil_ipfix_stats_from_nx(is, reply); | |
95 | } else { | |
96 | OVS_NOT_REACHED(); | |
97 | } | |
98 | } | |
99 | ||
100 | ||
101 | /* Returns the number of ipfix stats elements in | |
102 | * OFPTYPE_IPFIX_BRIDGE_STATS_REPLY or OFPTYPE_IPFIX_FLOW_STATS_REPLY | |
103 | * message 'oh'. */ | |
104 | size_t | |
105 | ofputil_count_ipfix_stats(const struct ofp_header *oh) | |
106 | { | |
107 | struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); | |
108 | ofpraw_pull_assert(&b); | |
109 | ||
110 | return b.size / sizeof(struct ofputil_ipfix_stats); | |
111 | } | |
fe2c69f4 BP |
112 | |
113 | static void | |
114 | print_ipfix_stat(struct ds *string, const char *leader, uint64_t stat, | |
115 | int more) | |
116 | { | |
117 | ds_put_cstr(string, leader); | |
118 | if (stat != UINT64_MAX) { | |
119 | ds_put_format(string, "%"PRIu64, stat); | |
120 | } else { | |
121 | ds_put_char(string, '?'); | |
122 | } | |
123 | if (more) { | |
124 | ds_put_cstr(string, ", "); | |
125 | } else { | |
126 | ds_put_cstr(string, "\n"); | |
127 | } | |
128 | } | |
129 | ||
130 | static void | |
131 | format_ipfix_stats(struct ds *string, const struct ofputil_ipfix_stats *is, | |
132 | int indent) | |
133 | { | |
134 | print_ipfix_stat(string, "flows=", is->total_flows, 1); | |
135 | print_ipfix_stat(string, "current flows=", is->current_flows, 1); | |
136 | print_ipfix_stat(string, "sampled pkts=", is->pkts, 1); | |
137 | print_ipfix_stat(string, "ipv4 ok=", is->ipv4_pkts, 1); | |
138 | print_ipfix_stat(string, "ipv6 ok=", is->ipv6_pkts, 1); | |
139 | print_ipfix_stat(string, "tx pkts=", is->tx_pkts, 0); | |
140 | ds_put_char_multiple(string, ' ', indent); | |
141 | print_ipfix_stat(string, "pkts errs=", is->error_pkts, 1); | |
142 | print_ipfix_stat(string, "ipv4 errs=", is->ipv4_error_pkts, 1); | |
143 | print_ipfix_stat(string, "ipv6 errs=", is->ipv6_error_pkts, 1); | |
144 | print_ipfix_stat(string, "tx errs=", is->tx_errors, 0); | |
145 | } | |
146 | ||
147 | void | |
148 | ofputil_format_ipfix_stats_bridge(struct ds *string, | |
149 | const struct ofputil_ipfix_stats *is) | |
150 | { | |
151 | ds_put_cstr(string, "\n bridge ipfix: "); | |
152 | format_ipfix_stats(string, is, 16); | |
153 | } | |
154 | ||
155 | void | |
156 | ofputil_format_ipfix_stats_flow(struct ds *string, | |
157 | const struct ofputil_ipfix_stats *is) | |
158 | { | |
159 | ds_put_cstr(string, " id"); | |
160 | ds_put_format(string, " %3"PRIuSIZE": ", (size_t) is->collector_set_id); | |
161 | format_ipfix_stats(string, is, 10); | |
162 | } |