diff options
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 21 |
1 files changed, 5 insertions, 16 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index b7f38b161909..98c70630ad06 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions) | |||
203 | int actions_len = nla_len(actions); | 203 | int actions_len = nla_len(actions); |
204 | struct sw_flow_actions *sfa; | 204 | struct sw_flow_actions *sfa; |
205 | 205 | ||
206 | /* At least DP_MAX_PORTS actions are required to be able to flood a | 206 | if (actions_len > MAX_ACTIONS_BUFSIZE) |
207 | * packet to every port. Factor of 2 allows for setting VLAN tags, | ||
208 | * etc. */ | ||
209 | if (actions_len > 2 * DP_MAX_PORTS * nla_total_size(4)) | ||
210 | return ERR_PTR(-EINVAL); | 207 | return ERR_PTR(-EINVAL); |
211 | 208 | ||
212 | sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); | 209 | sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); |
@@ -427,19 +424,11 @@ void ovs_flow_deferred_free(struct sw_flow *flow) | |||
427 | call_rcu(&flow->rcu, rcu_free_flow_callback); | 424 | call_rcu(&flow->rcu, rcu_free_flow_callback); |
428 | } | 425 | } |
429 | 426 | ||
430 | /* RCU callback used by ovs_flow_deferred_free_acts. */ | ||
431 | static void rcu_free_acts_callback(struct rcu_head *rcu) | ||
432 | { | ||
433 | struct sw_flow_actions *sf_acts = container_of(rcu, | ||
434 | struct sw_flow_actions, rcu); | ||
435 | kfree(sf_acts); | ||
436 | } | ||
437 | |||
438 | /* Schedules 'sf_acts' to be freed after the next RCU grace period. | 427 | /* Schedules 'sf_acts' to be freed after the next RCU grace period. |
439 | * The caller must hold rcu_read_lock for this to be sensible. */ | 428 | * The caller must hold rcu_read_lock for this to be sensible. */ |
440 | void ovs_flow_deferred_free_acts(struct sw_flow_actions *sf_acts) | 429 | void ovs_flow_deferred_free_acts(struct sw_flow_actions *sf_acts) |
441 | { | 430 | { |
442 | call_rcu(&sf_acts->rcu, rcu_free_acts_callback); | 431 | kfree_rcu(sf_acts, rcu); |
443 | } | 432 | } |
444 | 433 | ||
445 | static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) | 434 | static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) |
@@ -1000,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1000 | swkey->phy.in_port = in_port; | 989 | swkey->phy.in_port = in_port; |
1001 | attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); | 990 | attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); |
1002 | } else { | 991 | } else { |
1003 | swkey->phy.in_port = USHRT_MAX; | 992 | swkey->phy.in_port = DP_MAX_PORTS; |
1004 | } | 993 | } |
1005 | 994 | ||
1006 | /* Data attributes. */ | 995 | /* Data attributes. */ |
@@ -1143,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1143 | const struct nlattr *nla; | 1132 | const struct nlattr *nla; |
1144 | int rem; | 1133 | int rem; |
1145 | 1134 | ||
1146 | *in_port = USHRT_MAX; | 1135 | *in_port = DP_MAX_PORTS; |
1147 | *priority = 0; | 1136 | *priority = 0; |
1148 | 1137 | ||
1149 | nla_for_each_nested(nla, attr, rem) { | 1138 | nla_for_each_nested(nla, attr, rem) { |
@@ -1180,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1180 | nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) | 1169 | nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) |
1181 | goto nla_put_failure; | 1170 | goto nla_put_failure; |
1182 | 1171 | ||
1183 | if (swkey->phy.in_port != USHRT_MAX && | 1172 | if (swkey->phy.in_port != DP_MAX_PORTS && |
1184 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) | 1173 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) |
1185 | goto nla_put_failure; | 1174 | goto nla_put_failure; |
1186 | 1175 | ||