]>
Commit | Line | Data |
---|---|---|
064af421 BP |
1 | /* |
2 | * Copyright (c) 2009 Nicira Networks. | |
3 | * | |
a14bc59f BP |
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: | |
064af421 | 7 | * |
a14bc59f BP |
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. | |
064af421 BP |
15 | */ |
16 | ||
17 | #include <config.h> | |
18 | #include "odp-util.h" | |
19 | #include <inttypes.h> | |
20 | #include <stdlib.h> | |
21 | #include <string.h> | |
22 | #include "coverage.h" | |
23 | #include "dynamic-string.h" | |
24 | #include "flow.h" | |
25 | #include "packets.h" | |
26 | #include "timeval.h" | |
27 | #include "util.h" | |
28 | ||
29 | union odp_action * | |
30 | odp_actions_add(struct odp_actions *actions, uint16_t type) | |
31 | { | |
32 | union odp_action *a; | |
33 | if (actions->n_actions < MAX_ODP_ACTIONS) { | |
34 | a = &actions->actions[actions->n_actions++]; | |
35 | } else { | |
36 | COVERAGE_INC(odp_overflow); | |
37 | actions->n_actions = MAX_ODP_ACTIONS + 1; | |
38 | a = &actions->actions[MAX_ODP_ACTIONS - 1]; | |
39 | } | |
40 | memset(a, 0, sizeof *a); | |
41 | a->type = type; | |
42 | return a; | |
43 | } | |
44 | ||
45 | void | |
46 | format_odp_action(struct ds *ds, const union odp_action *a) | |
47 | { | |
48 | switch (a->type) { | |
49 | case ODPAT_OUTPUT: | |
50 | ds_put_format(ds, "%"PRIu16, a->output.port); | |
51 | break; | |
52 | case ODPAT_OUTPUT_GROUP: | |
53 | ds_put_format(ds, "g%"PRIu16, a->output_group.group); | |
54 | break; | |
55 | case ODPAT_CONTROLLER: | |
56 | ds_put_format(ds, "ctl(%"PRIu32")", a->controller.arg); | |
57 | break; | |
58 | case ODPAT_SET_VLAN_VID: | |
59 | ds_put_format(ds, "set_vlan(%"PRIu16")", ntohs(a->vlan_vid.vlan_vid)); | |
60 | break; | |
61 | case ODPAT_SET_VLAN_PCP: | |
62 | ds_put_format(ds, "set_vlan_pcp(%"PRIu8")", a->vlan_pcp.vlan_pcp); | |
63 | break; | |
64 | case ODPAT_STRIP_VLAN: | |
65 | ds_put_format(ds, "strip_vlan"); | |
66 | break; | |
67 | case ODPAT_SET_DL_SRC: | |
68 | ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", | |
69 | ETH_ADDR_ARGS(a->dl_addr.dl_addr)); | |
70 | break; | |
71 | case ODPAT_SET_DL_DST: | |
72 | ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", | |
73 | ETH_ADDR_ARGS(a->dl_addr.dl_addr)); | |
74 | break; | |
75 | case ODPAT_SET_NW_SRC: | |
76 | ds_put_format(ds, "set_nw_src("IP_FMT")", | |
77 | IP_ARGS(&a->nw_addr.nw_addr)); | |
78 | break; | |
79 | case ODPAT_SET_NW_DST: | |
80 | ds_put_format(ds, "set_nw_dst("IP_FMT")", | |
81 | IP_ARGS(&a->nw_addr.nw_addr)); | |
82 | break; | |
83 | case ODPAT_SET_TP_SRC: | |
84 | ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(a->tp_port.tp_port)); | |
85 | break; | |
86 | case ODPAT_SET_TP_DST: | |
87 | ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(a->tp_port.tp_port)); | |
88 | break; | |
89 | default: | |
90 | ds_put_format(ds, "***bad action %"PRIu16"***", a->type); | |
91 | break; | |
92 | } | |
93 | } | |
94 | ||
95 | void | |
96 | format_odp_actions(struct ds *ds, const union odp_action *actions, | |
97 | size_t n_actions) | |
98 | { | |
99 | size_t i; | |
100 | for (i = 0; i < n_actions; i++) { | |
101 | if (i) { | |
102 | ds_put_char(ds, ','); | |
103 | } | |
104 | format_odp_action(ds, &actions[i]); | |
105 | } | |
106 | if (!n_actions) { | |
107 | ds_put_cstr(ds, "drop"); | |
108 | } | |
109 | } | |
110 | ||
111 | void | |
112 | format_odp_flow_stats(struct ds *ds, const struct odp_flow_stats *s) | |
113 | { | |
114 | ds_put_format(ds, "packets:%"PRIu64", bytes:%"PRIu64", used:", | |
115 | s->n_packets, s->n_bytes); | |
116 | if (s->used_sec) { | |
117 | long long int used = s->used_sec * 1000 + s->used_nsec / 1000000; | |
118 | ds_put_format(ds, "%.3fs", (time_msec() - used) / 1000.0); | |
119 | } else { | |
120 | ds_put_format(ds, "never"); | |
121 | } | |
122 | } | |
123 | ||
124 | void | |
125 | format_odp_flow(struct ds *ds, const struct odp_flow *f) | |
126 | { | |
127 | flow_format(ds, &f->key); | |
128 | ds_put_cstr(ds, ", "); | |
129 | format_odp_flow_stats(ds, &f->stats); | |
130 | ds_put_cstr(ds, ", actions:"); | |
131 | format_odp_actions(ds, f->actions, f->n_actions); | |
132 | } | |
133 |