- const struct odp_sflow_sample_header *hdr;
- const union odp_action *actions;
- struct ofpbuf payload;
- size_t n_actions, n_outputs;
- size_t min_size;
- flow_t flow;
- size_t i;
-
- /* Get odp_sflow_sample_header. */
- min_size = sizeof *msg + sizeof *hdr;
- if (min_size > msg->length) {
- VLOG_WARN_RL(&rl, "sFlow packet too small (%"PRIu32" < %zu)",
- msg->length, min_size);
- return;
- }
- hdr = (const struct odp_sflow_sample_header *) (msg + 1);
-
- /* Get actions. */
- n_actions = hdr->n_actions;
- if (n_actions > 65536 / sizeof *actions) {
- VLOG_WARN_RL(&rl, "too many actions in sFlow packet (%zu > %zu)",
- 65536 / sizeof *actions, n_actions);
- return;
- }
- min_size += n_actions * sizeof *actions;
- if (min_size > msg->length) {
- VLOG_WARN_RL(&rl, "sFlow packet with %zu actions too small "
- "(%"PRIu32" < %zu)",
- n_actions, msg->length, min_size);
- return;
- }
- actions = (const union odp_action *) (hdr + 1);
-
- /* Get packet payload and extract flow. */
- payload.data = (union odp_action *) (actions + n_actions);
- payload.size = msg->length - min_size;
- flow_extract(&payload, 0, msg->port, &flow);