diff options
author | Joe Stringer <joestringer@nicira.com> | 2015-10-06 13:59:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-07 08:03:03 -0400 |
commit | b8f2257069f179c7bdedc9501c1623070c4c37bb (patch) | |
tree | 123345db5a1b910ab007d7fcbd2d2bc0489e4203 | |
parent | 0a7cc172a01e4a203667fb601cd80131db8d0c9a (diff) |
openvswitch: Fix skb leak in ovs_fragment()
If ovs_fragment() was unable to fragment the skb due to an L2 header
that exceeds the supported length, skbs would be leaked. Fix the bug.
Fixes: 7f8a436eaa2c "openvswitch: Add conntrack action"
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/openvswitch/actions.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index e23a61cc3d5c..4cb93f92d6be 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -684,7 +684,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, | |||
684 | { | 684 | { |
685 | if (skb_network_offset(skb) > MAX_L2_LEN) { | 685 | if (skb_network_offset(skb) > MAX_L2_LEN) { |
686 | OVS_NLERR(1, "L2 header too long to fragment"); | 686 | OVS_NLERR(1, "L2 header too long to fragment"); |
687 | return; | 687 | goto err; |
688 | } | 688 | } |
689 | 689 | ||
690 | if (ethertype == htons(ETH_P_IP)) { | 690 | if (ethertype == htons(ETH_P_IP)) { |
@@ -708,8 +708,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, | |||
708 | struct rt6_info ovs_rt; | 708 | struct rt6_info ovs_rt; |
709 | 709 | ||
710 | if (!v6ops) { | 710 | if (!v6ops) { |
711 | kfree_skb(skb); | 711 | goto err; |
712 | return; | ||
713 | } | 712 | } |
714 | 713 | ||
715 | prepare_frag(vport, skb); | 714 | prepare_frag(vport, skb); |
@@ -728,8 +727,12 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, | |||
728 | WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.", | 727 | WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.", |
729 | ovs_vport_name(vport), ntohs(ethertype), mru, | 728 | ovs_vport_name(vport), ntohs(ethertype), mru, |
730 | vport->dev->mtu); | 729 | vport->dev->mtu); |
731 | kfree_skb(skb); | 730 | goto err; |
732 | } | 731 | } |
732 | |||
733 | return; | ||
734 | err: | ||
735 | kfree_skb(skb); | ||
733 | } | 736 | } |
734 | 737 | ||
735 | static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port, | 738 | static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port, |