On Tue, Feb 11, 2014 at 4:07 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote: > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > --- > datapath/datapath.c | 60 > +++++++++++++++++++++++++++------------------------ > 1 file changed, 32 insertions(+), 28 deletions(-) > > diff --git a/datapath/datapath.c b/datapath/datapath.c > index a46ceb0..90fdc60 100644 > --- a/datapath/datapath.c > +++ b/datapath/datapath.c > @@ -492,14 +492,24 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, > struct genl_info *info) > { > struct ovs_header *ovs_header = info->userhdr; > struct nlattr **a = info->attrs; > - struct sw_flow_actions *acts; > struct sk_buff *packet; > - struct sw_flow *flow; > struct datapath *dp; > struct ethhdr *eth; > + struct sw_flow flow; > + struct { > + struct sw_flow_actions acts; > + u64 buf[512 / sizeof (u64)]; > + } sw_acts; > + struct sw_flow_actions *acts; > int len; > int err; >
I am not sure about stack usage here. Specifically on platforms with 4KB stack we can overrun kernel stack. > + /* Start with actions in the stack with enough space for most cases. > */ > + acts = &sw_acts.acts; > + acts->actions_len = 0; > + acts->alloc_size = sizeof(sw_acts); > + acts->alloced = false; > + > err = -EINVAL; > if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || > !a[OVS_PACKET_ATTR_ACTIONS]) > @@ -525,54 +535,48 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, > struct genl_info *info) > else > packet->protocol = htons(ETH_P_802_2); > > - /* Build an sw_flow for sending this packet. */ > - flow = ovs_flow_alloc(); > - err = PTR_ERR(flow); > - if (IS_ERR(flow)) > - goto err_kfree_skb; > - > - err = ovs_flow_extract(packet, -1, &flow->key); > + /* Build an sw_flow for sending this packet. > + * We do not initialize mask, nor stats as they are not used > + * by a flow that is not in the flow table. */ > + err = ovs_flow_extract(packet, -1, &flow.key); > if (err) > - goto err_flow_free; > + goto err_free; > > - err = ovs_nla_get_flow_metadata(flow, a[OVS_PACKET_ATTR_KEY]); > + err = ovs_nla_get_flow_metadata(&flow, a[OVS_PACKET_ATTR_KEY]); > if (err) > - goto err_flow_free; > - acts = > ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS])); > - err = PTR_ERR(acts); > - if (IS_ERR(acts)) > - goto err_flow_free; > + goto err_free; > > err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], > - &flow->key, 0, &acts); > - rcu_assign_pointer(flow->sf_acts, acts); > + &flow.key, 0, &acts); > + rcu_assign_pointer(flow.sf_acts, acts); > if (err) > - goto err_flow_free; > + goto err_free_acts; > > - OVS_CB(packet)->flow = flow; > - OVS_CB(packet)->pkt_key = &flow->key; > - packet->priority = flow->key.phy.priority; > - packet->mark = flow->key.phy.skb_mark; > + OVS_CB(packet)->flow = &flow; > + OVS_CB(packet)->pkt_key = &flow.key; > + packet->priority = flow.key.phy.priority; > + packet->mark = flow.key.phy.skb_mark; > > rcu_read_lock(); > dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); > err = -ENODEV; > if (!dp) > goto err_unlock; > - > local_bh_disable(); > err = ovs_execute_actions(dp, packet); > local_bh_enable(); > rcu_read_unlock(); > > - ovs_flow_free(flow, false); > + /* Will free if actions were realloced. */ > + ovs_nla_free_flow_actions(acts, false); > + > return err; > > err_unlock: > rcu_read_unlock(); > -err_flow_free: > - ovs_flow_free(flow, false); > -err_kfree_skb: > +err_free_acts: > + ovs_nla_free_flow_actions(acts, false); > +err_free: > kfree_skb(packet); > err: > return err; > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev