return 0;
}
-static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
+static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
{
- struct vport *vport;
+ struct vport *vport = ovs_vport_rcu(dp, out_port);
- if (unlikely(!skb))
- return -ENOMEM;
-
- vport = ovs_vport_rcu(dp, out_port);
- if (unlikely(!vport)) {
+ if (likely(vport))
+ ovs_vport_send(vport, skb);
+ else
kfree_skb(skb);
- return -ENODEV;
- }
-
- ovs_vport_send(vport, skb);
- return 0;
}
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
const struct nlattr *a;
int rem;
- BUG_ON(!OVS_CB(skb)->pkt_key);
-
upcall.cmd = OVS_PACKET_CMD_ACTION;
- upcall.key = OVS_CB(skb)->pkt_key;
upcall.userdata = NULL;
upcall.portid = 0;
skb_get(skb);
} else {
sample_skb = skb_clone(skb, GFP_ATOMIC);
+ if (!sample_skb)
+ /* Skip the sample action when out of memory. */
+ return 0;
}
/* Note that do_execute_actions() never consumes skb.
const struct nlattr *a)
{
struct sw_flow_key recirc_key;
- const struct vport *p = OVS_CB(skb)->input_vport;
uint32_t hash = OVS_CB(skb)->pkt_key->ovs_flow_hash;
int err;
- err = ovs_flow_extract(skb, p->port_no, &recirc_key);
+ err = ovs_flow_key_extract(skb, &recirc_key);
if (err) {
kfree_skb(skb);
return err;
a = nla_next(a, &rem)) {
int err = 0;
- if (prev_port != -1) {
- do_output(dp, skb_clone(skb, GFP_ATOMIC), prev_port);
+ if (unlikely(prev_port != -1)) {
+ struct sk_buff *out_skb = skb_clone(skb, GFP_ATOMIC);
+
+ if (out_skb)
+ do_output(dp, out_skb, prev_port);
+
prev_port = -1;
}