aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/datapath.c2
-rw-r--r--net/openvswitch/flow.c15
-rw-r--r--net/openvswitch/flow_netlink.c16
3 files changed, 21 insertions, 12 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 99cfafc2a139..ef38e5aecd28 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -308,7 +308,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
308 const struct dp_upcall_info *upcall_info, 308 const struct dp_upcall_info *upcall_info,
309 uint32_t cutlen) 309 uint32_t cutlen)
310{ 310{
311 unsigned short gso_type = skb_shinfo(skb)->gso_type; 311 unsigned int gso_type = skb_shinfo(skb)->gso_type;
312 struct sw_flow_key later_key; 312 struct sw_flow_key later_key;
313 struct sk_buff *segs, *nskb; 313 struct sk_buff *segs, *nskb;
314 int err; 314 int err;
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index dbe2379329c5..f039064ce922 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -579,6 +579,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
579 return -EINVAL; 579 return -EINVAL;
580 580
581 skb_reset_network_header(skb); 581 skb_reset_network_header(skb);
582 key->eth.type = skb->protocol;
582 } else { 583 } else {
583 eth = eth_hdr(skb); 584 eth = eth_hdr(skb);
584 ether_addr_copy(key->eth.src, eth->h_source); 585 ether_addr_copy(key->eth.src, eth->h_source);
@@ -592,15 +593,23 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
592 if (unlikely(parse_vlan(skb, key))) 593 if (unlikely(parse_vlan(skb, key)))
593 return -ENOMEM; 594 return -ENOMEM;
594 595
595 skb->protocol = parse_ethertype(skb); 596 key->eth.type = parse_ethertype(skb);
596 if (unlikely(skb->protocol == htons(0))) 597 if (unlikely(key->eth.type == htons(0)))
597 return -ENOMEM; 598 return -ENOMEM;
598 599
600 /* Multiple tagged packets need to retain TPID to satisfy
601 * skb_vlan_pop(), which will later shift the ethertype into
602 * skb->protocol.
603 */
604 if (key->eth.cvlan.tci & htons(VLAN_TAG_PRESENT))
605 skb->protocol = key->eth.cvlan.tpid;
606 else
607 skb->protocol = key->eth.type;
608
599 skb_reset_network_header(skb); 609 skb_reset_network_header(skb);
600 __skb_push(skb, skb->data - skb_mac_header(skb)); 610 __skb_push(skb, skb->data - skb_mac_header(skb));
601 } 611 }
602 skb_reset_mac_len(skb); 612 skb_reset_mac_len(skb);
603 key->eth.type = skb->protocol;
604 613
605 /* Network layer. */ 614 /* Network layer. */
606 if (key->eth.type == htons(ETH_P_IP)) { 615 if (key->eth.type == htons(ETH_P_IP)) {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index dc424798ba6f..624ea74353dd 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -2241,14 +2241,11 @@ int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb)
2241 2241
2242#define MAX_ACTIONS_BUFSIZE (32 * 1024) 2242#define MAX_ACTIONS_BUFSIZE (32 * 1024)
2243 2243
2244static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log) 2244static struct sw_flow_actions *nla_alloc_flow_actions(int size)
2245{ 2245{
2246 struct sw_flow_actions *sfa; 2246 struct sw_flow_actions *sfa;
2247 2247
2248 if (size > MAX_ACTIONS_BUFSIZE) { 2248 WARN_ON_ONCE(size > MAX_ACTIONS_BUFSIZE);
2249 OVS_NLERR(log, "Flow action size %u bytes exceeds max", size);
2250 return ERR_PTR(-EINVAL);
2251 }
2252 2249
2253 sfa = kmalloc(sizeof(*sfa) + size, GFP_KERNEL); 2250 sfa = kmalloc(sizeof(*sfa) + size, GFP_KERNEL);
2254 if (!sfa) 2251 if (!sfa)
@@ -2321,12 +2318,15 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
2321 new_acts_size = ksize(*sfa) * 2; 2318 new_acts_size = ksize(*sfa) * 2;
2322 2319
2323 if (new_acts_size > MAX_ACTIONS_BUFSIZE) { 2320 if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
2324 if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) 2321 if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {
2322 OVS_NLERR(log, "Flow action size exceeds max %u",
2323 MAX_ACTIONS_BUFSIZE);
2325 return ERR_PTR(-EMSGSIZE); 2324 return ERR_PTR(-EMSGSIZE);
2325 }
2326 new_acts_size = MAX_ACTIONS_BUFSIZE; 2326 new_acts_size = MAX_ACTIONS_BUFSIZE;
2327 } 2327 }
2328 2328
2329 acts = nla_alloc_flow_actions(new_acts_size, log); 2329 acts = nla_alloc_flow_actions(new_acts_size);
2330 if (IS_ERR(acts)) 2330 if (IS_ERR(acts))
2331 return (void *)acts; 2331 return (void *)acts;
2332 2332
@@ -3059,7 +3059,7 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
3059{ 3059{
3060 int err; 3060 int err;
3061 3061
3062 *sfa = nla_alloc_flow_actions(nla_len(attr), log); 3062 *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE));
3063 if (IS_ERR(*sfa)) 3063 if (IS_ERR(*sfa))
3064 return PTR_ERR(*sfa); 3064 return PTR_ERR(*sfa);
3065 3065