return output_all(dp, skb, 0);
case OFPP_CONTROLLER:
- return dp_output_control(dp, skb, fwd_save_skb(skb), 0,
- OFPR_ACTION);
+ return dp_output_control(dp, skb, 0, OFPR_ACTION);
case OFPP_LOCAL: {
struct net_device *dev = dp->netdev;
return -ENOENT;
}
-/* Takes ownership of 'skb' and transmits it to 'dp''s control path. If
- * 'buffer_id' != -1, then only the first 64 bytes of 'skb' are sent;
- * otherwise, all of 'skb' is sent. 'reason' indicates why 'skb' is being
- * sent. 'max_len' sets the maximum number of bytes that the caller
- * wants to be sent; a value of 0 indicates the entire packet should be
- * sent. */
+/* Takes ownership of 'skb' and transmits it to 'dp''s control path. 'reason'
+ * indicates why 'skb' is being sent. 'max_len' sets the maximum number of
+ * bytes that the caller wants to be sent; a value of 0 indicates the entire
+ * packet should be sent. */
int
dp_output_control(struct datapath *dp, struct sk_buff *skb,
- uint32_t buffer_id, size_t max_len, int reason)
+ size_t max_len, int reason)
{
/* FIXME? Can we avoid creating a new skbuff in the case where we
* forward the whole packet? */
struct sk_buff *f_skb;
struct ofp_packet_in *opi;
size_t fwd_len, opi_len;
+ uint32_t buffer_id;
int err;
+ buffer_id = fwd_save_skb(skb);
+
fwd_len = skb->len;
if ((buffer_id != (uint32_t) -1) && max_len)
fwd_len = min(fwd_len, max_len);
int dp_xmit_skb(struct sk_buff *skb);
int dp_output_port(struct datapath *, struct sk_buff *, int out_port,
int ignore_no_fwd);
-int dp_output_control(struct datapath *, struct sk_buff *, uint32_t,
- size_t, int);
+int dp_output_control(struct datapath *, struct sk_buff *, size_t, int);
void dp_set_origin(struct datapath *, uint16_t, struct sk_buff *);
int dp_send_features_reply(struct datapath *, const struct sender *);
int dp_send_config_reply(struct datapath *, const struct sender *);
return -ENOMEM;
return (likely(out_port != OFPP_CONTROLLER)
? dp_output_port(dp, skb, out_port, ignore_no_fwd)
- : dp_output_control(dp, skb, fwd_save_skb(skb),
- max_len, OFPR_ACTION));
+ : dp_output_control(dp, skb, max_len, OFPR_ACTION));
}
WARN_ON_ONCE(skb_shared(skb));
WARN_ON_ONCE(skb->destructor);
if (run_flow_through_tables(chain, skb, p))
- dp_output_control(chain->dp, skb, fwd_save_skb(skb),
- chain->dp->miss_send_len,
+ dp_output_control(chain->dp, skb, chain->dp->miss_send_len,
OFPR_NO_MATCH);
}