diff options
-rw-r--r-- | drivers/net/vxlan.c | 34 | ||||
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/ipv4/geneve.c | 6 | ||||
-rw-r--r-- | net/mpls/mpls_gso.c | 5 | ||||
-rw-r--r-- | net/openvswitch/actions.c | 3 | ||||
-rw-r--r-- | net/openvswitch/flow_netlink.c | 13 | ||||
-rw-r--r-- | net/openvswitch/vport-geneve.c | 3 | ||||
-rw-r--r-- | net/openvswitch/vport-gre.c | 18 | ||||
-rw-r--r-- | net/openvswitch/vport-vxlan.c | 2 | ||||
-rw-r--r-- | net/openvswitch/vport.c | 5 |
10 files changed, 52 insertions, 39 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 49d9f2291998..7fbd89fbe107 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1579,8 +1579,10 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); | 1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); |
1580 | 1580 | ||
1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
1582 | if (IS_ERR(skb)) | 1582 | if (IS_ERR(skb)) { |
1583 | return -EINVAL; | 1583 | err = -EINVAL; |
1584 | goto err; | ||
1585 | } | ||
1584 | 1586 | ||
1585 | skb_scrub_packet(skb, xnet); | 1587 | skb_scrub_packet(skb, xnet); |
1586 | 1588 | ||
@@ -1590,12 +1592,16 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1590 | 1592 | ||
1591 | /* Need space for new headers (invalidates iph ptr) */ | 1593 | /* Need space for new headers (invalidates iph ptr) */ |
1592 | err = skb_cow_head(skb, min_headroom); | 1594 | err = skb_cow_head(skb, min_headroom); |
1593 | if (unlikely(err)) | 1595 | if (unlikely(err)) { |
1594 | return err; | 1596 | kfree_skb(skb); |
1597 | goto err; | ||
1598 | } | ||
1595 | 1599 | ||
1596 | skb = vlan_hwaccel_push_inside(skb); | 1600 | skb = vlan_hwaccel_push_inside(skb); |
1597 | if (WARN_ON(!skb)) | 1601 | if (WARN_ON(!skb)) { |
1598 | return -ENOMEM; | 1602 | err = -ENOMEM; |
1603 | goto err; | ||
1604 | } | ||
1599 | 1605 | ||
1600 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); | 1606 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); |
1601 | vxh->vx_flags = htonl(VXLAN_FLAGS); | 1607 | vxh->vx_flags = htonl(VXLAN_FLAGS); |
@@ -1606,6 +1612,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1606 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, | 1612 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, |
1607 | ttl, src_port, dst_port); | 1613 | ttl, src_port, dst_port); |
1608 | return 0; | 1614 | return 0; |
1615 | err: | ||
1616 | dst_release(dst); | ||
1617 | return err; | ||
1609 | } | 1618 | } |
1610 | #endif | 1619 | #endif |
1611 | 1620 | ||
@@ -1621,7 +1630,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
1621 | 1630 | ||
1622 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1631 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
1623 | if (IS_ERR(skb)) | 1632 | if (IS_ERR(skb)) |
1624 | return -EINVAL; | 1633 | return PTR_ERR(skb); |
1625 | 1634 | ||
1626 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 1635 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
1627 | + VXLAN_HLEN + sizeof(struct iphdr) | 1636 | + VXLAN_HLEN + sizeof(struct iphdr) |
@@ -1629,8 +1638,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
1629 | 1638 | ||
1630 | /* Need space for new headers (invalidates iph ptr) */ | 1639 | /* Need space for new headers (invalidates iph ptr) */ |
1631 | err = skb_cow_head(skb, min_headroom); | 1640 | err = skb_cow_head(skb, min_headroom); |
1632 | if (unlikely(err)) | 1641 | if (unlikely(err)) { |
1642 | kfree_skb(skb); | ||
1633 | return err; | 1643 | return err; |
1644 | } | ||
1634 | 1645 | ||
1635 | skb = vlan_hwaccel_push_inside(skb); | 1646 | skb = vlan_hwaccel_push_inside(skb); |
1636 | if (WARN_ON(!skb)) | 1647 | if (WARN_ON(!skb)) |
@@ -1776,9 +1787,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1776 | tos, ttl, df, src_port, dst_port, | 1787 | tos, ttl, df, src_port, dst_port, |
1777 | htonl(vni << 8), | 1788 | htonl(vni << 8), |
1778 | !net_eq(vxlan->net, dev_net(vxlan->dev))); | 1789 | !net_eq(vxlan->net, dev_net(vxlan->dev))); |
1779 | 1790 | if (err < 0) { | |
1780 | if (err < 0) | 1791 | /* skb is already freed. */ |
1792 | skb = NULL; | ||
1781 | goto rt_tx_error; | 1793 | goto rt_tx_error; |
1794 | } | ||
1795 | |||
1782 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 1796 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
1783 | #if IS_ENABLED(CONFIG_IPV6) | 1797 | #if IS_ENABLED(CONFIG_IPV6) |
1784 | } else { | 1798 | } else { |
diff --git a/net/core/dev.c b/net/core/dev.c index c97ae6fec040..67b6210a589a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2522,7 +2522,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | |||
2522 | /* If MPLS offload request, verify we are testing hardware MPLS features | 2522 | /* If MPLS offload request, verify we are testing hardware MPLS features |
2523 | * instead of standard features for the netdev. | 2523 | * instead of standard features for the netdev. |
2524 | */ | 2524 | */ |
2525 | #ifdef CONFIG_NET_MPLS_GSO | 2525 | #if IS_ENABLED(CONFIG_NET_MPLS_GSO) |
2526 | static netdev_features_t net_mpls_features(struct sk_buff *skb, | 2526 | static netdev_features_t net_mpls_features(struct sk_buff *skb, |
2527 | netdev_features_t features, | 2527 | netdev_features_t features, |
2528 | __be16 type) | 2528 | __be16 type) |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 95e47c97585e..394a200f93c1 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
@@ -122,14 +122,18 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
122 | int err; | 122 | int err; |
123 | 123 | ||
124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); | 124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); |
125 | if (IS_ERR(skb)) | ||
126 | return PTR_ERR(skb); | ||
125 | 127 | ||
126 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 128 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
127 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) | 129 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) |
128 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | 130 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); |
129 | 131 | ||
130 | err = skb_cow_head(skb, min_headroom); | 132 | err = skb_cow_head(skb, min_headroom); |
131 | if (unlikely(err)) | 133 | if (unlikely(err)) { |
134 | kfree_skb(skb); | ||
132 | return err; | 135 | return err; |
136 | } | ||
133 | 137 | ||
134 | skb = vlan_hwaccel_push_inside(skb); | 138 | skb = vlan_hwaccel_push_inside(skb); |
135 | if (unlikely(!skb)) | 139 | if (unlikely(!skb)) |
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c index ca27837974fe..349295d21946 100644 --- a/net/mpls/mpls_gso.c +++ b/net/mpls/mpls_gso.c | |||
@@ -31,10 +31,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, | |||
31 | SKB_GSO_TCPV6 | | 31 | SKB_GSO_TCPV6 | |
32 | SKB_GSO_UDP | | 32 | SKB_GSO_UDP | |
33 | SKB_GSO_DODGY | | 33 | SKB_GSO_DODGY | |
34 | SKB_GSO_TCP_ECN | | 34 | SKB_GSO_TCP_ECN))) |
35 | SKB_GSO_GRE | | ||
36 | SKB_GSO_GRE_CSUM | | ||
37 | SKB_GSO_IPIP))) | ||
38 | goto out; | 35 | goto out; |
39 | 36 | ||
40 | /* Setup inner SKB. */ | 37 | /* Setup inner SKB. */ |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 764fdc39c63b..770064c83711 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -147,7 +147,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, | |||
147 | hdr = eth_hdr(skb); | 147 | hdr = eth_hdr(skb); |
148 | hdr->h_proto = mpls->mpls_ethertype; | 148 | hdr->h_proto = mpls->mpls_ethertype; |
149 | 149 | ||
150 | skb_set_inner_protocol(skb, skb->protocol); | 150 | if (!skb->inner_protocol) |
151 | skb_set_inner_protocol(skb, skb->protocol); | ||
151 | skb->protocol = mpls->mpls_ethertype; | 152 | skb->protocol = mpls->mpls_ethertype; |
152 | 153 | ||
153 | invalidate_flow_key(key); | 154 | invalidate_flow_key(key); |
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 9645a21d9eaa..d1eecf707613 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -1753,7 +1753,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1753 | __be16 eth_type, __be16 vlan_tci, bool log) | 1753 | __be16 eth_type, __be16 vlan_tci, bool log) |
1754 | { | 1754 | { |
1755 | const struct nlattr *a; | 1755 | const struct nlattr *a; |
1756 | bool out_tnl_port = false; | ||
1757 | int rem, err; | 1756 | int rem, err; |
1758 | 1757 | ||
1759 | if (depth >= SAMPLE_ACTION_DEPTH) | 1758 | if (depth >= SAMPLE_ACTION_DEPTH) |
@@ -1796,8 +1795,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1796 | case OVS_ACTION_ATTR_OUTPUT: | 1795 | case OVS_ACTION_ATTR_OUTPUT: |
1797 | if (nla_get_u32(a) >= DP_MAX_PORTS) | 1796 | if (nla_get_u32(a) >= DP_MAX_PORTS) |
1798 | return -EINVAL; | 1797 | return -EINVAL; |
1799 | out_tnl_port = false; | ||
1800 | |||
1801 | break; | 1798 | break; |
1802 | 1799 | ||
1803 | case OVS_ACTION_ATTR_HASH: { | 1800 | case OVS_ACTION_ATTR_HASH: { |
@@ -1832,12 +1829,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1832 | case OVS_ACTION_ATTR_PUSH_MPLS: { | 1829 | case OVS_ACTION_ATTR_PUSH_MPLS: { |
1833 | const struct ovs_action_push_mpls *mpls = nla_data(a); | 1830 | const struct ovs_action_push_mpls *mpls = nla_data(a); |
1834 | 1831 | ||
1835 | /* Networking stack do not allow simultaneous Tunnel | ||
1836 | * and MPLS GSO. | ||
1837 | */ | ||
1838 | if (out_tnl_port) | ||
1839 | return -EINVAL; | ||
1840 | |||
1841 | if (!eth_p_mpls(mpls->mpls_ethertype)) | 1832 | if (!eth_p_mpls(mpls->mpls_ethertype)) |
1842 | return -EINVAL; | 1833 | return -EINVAL; |
1843 | /* Prohibit push MPLS other than to a white list | 1834 | /* Prohibit push MPLS other than to a white list |
@@ -1873,11 +1864,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1873 | 1864 | ||
1874 | case OVS_ACTION_ATTR_SET: | 1865 | case OVS_ACTION_ATTR_SET: |
1875 | err = validate_set(a, key, sfa, | 1866 | err = validate_set(a, key, sfa, |
1876 | &out_tnl_port, eth_type, log); | 1867 | &skip_copy, eth_type, log); |
1877 | if (err) | 1868 | if (err) |
1878 | return err; | 1869 | return err; |
1879 | |||
1880 | skip_copy = out_tnl_port; | ||
1881 | break; | 1870 | break; |
1882 | 1871 | ||
1883 | case OVS_ACTION_ATTR_SAMPLE: | 1872 | case OVS_ACTION_ATTR_SAMPLE: |
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 347fa2325b22..484864dd0e68 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
@@ -219,7 +219,10 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
219 | false); | 219 | false); |
220 | if (err < 0) | 220 | if (err < 0) |
221 | ip_rt_put(rt); | 221 | ip_rt_put(rt); |
222 | return err; | ||
223 | |||
222 | error: | 224 | error: |
225 | kfree_skb(skb); | ||
223 | return err; | 226 | return err; |
224 | } | 227 | } |
225 | 228 | ||
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 6b69df545b1d..28f54e9a6b80 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -73,7 +73,7 @@ static struct sk_buff *__build_header(struct sk_buff *skb, | |||
73 | 73 | ||
74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); | 74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); |
75 | if (IS_ERR(skb)) | 75 | if (IS_ERR(skb)) |
76 | return NULL; | 76 | return skb; |
77 | 77 | ||
78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); | 78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); |
79 | tpi.proto = htons(ETH_P_TEB); | 79 | tpi.proto = htons(ETH_P_TEB); |
@@ -144,7 +144,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
144 | 144 | ||
145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { | 145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { |
146 | err = -EINVAL; | 146 | err = -EINVAL; |
147 | goto error; | 147 | goto err_free_skb; |
148 | } | 148 | } |
149 | 149 | ||
150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; | 150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; |
@@ -157,8 +157,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
157 | fl.flowi4_proto = IPPROTO_GRE; | 157 | fl.flowi4_proto = IPPROTO_GRE; |
158 | 158 | ||
159 | rt = ip_route_output_key(net, &fl); | 159 | rt = ip_route_output_key(net, &fl); |
160 | if (IS_ERR(rt)) | 160 | if (IS_ERR(rt)) { |
161 | return PTR_ERR(rt); | 161 | err = PTR_ERR(rt); |
162 | goto err_free_skb; | ||
163 | } | ||
162 | 164 | ||
163 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); | 165 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); |
164 | 166 | ||
@@ -183,8 +185,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
183 | 185 | ||
184 | /* Push Tunnel header. */ | 186 | /* Push Tunnel header. */ |
185 | skb = __build_header(skb, tunnel_hlen); | 187 | skb = __build_header(skb, tunnel_hlen); |
186 | if (unlikely(!skb)) { | 188 | if (IS_ERR(skb)) { |
187 | err = 0; | 189 | err = PTR_ERR(rt); |
190 | skb = NULL; | ||
188 | goto err_free_rt; | 191 | goto err_free_rt; |
189 | } | 192 | } |
190 | 193 | ||
@@ -198,7 +201,8 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
198 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); | 201 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); |
199 | err_free_rt: | 202 | err_free_rt: |
200 | ip_rt_put(rt); | 203 | ip_rt_put(rt); |
201 | error: | 204 | err_free_skb: |
205 | kfree_skb(skb); | ||
202 | return err; | 206 | return err; |
203 | } | 207 | } |
204 | 208 | ||
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 38f95a52241b..d7c46b301024 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
@@ -187,7 +187,9 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
187 | false); | 187 | false); |
188 | if (err < 0) | 188 | if (err < 0) |
189 | ip_rt_put(rt); | 189 | ip_rt_put(rt); |
190 | return err; | ||
190 | error: | 191 | error: |
192 | kfree_skb(skb); | ||
191 | return err; | 193 | return err; |
192 | } | 194 | } |
193 | 195 | ||
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 9584526c0778..53f3ebbfceab 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -519,10 +519,9 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb) | |||
519 | u64_stats_update_end(&stats->syncp); | 519 | u64_stats_update_end(&stats->syncp); |
520 | } else if (sent < 0) { | 520 | } else if (sent < 0) { |
521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); | 521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); |
522 | kfree_skb(skb); | 522 | } else { |
523 | } else | ||
524 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); | 523 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); |
525 | 524 | } | |
526 | return sent; | 525 | return sent; |
527 | } | 526 | } |
528 | 527 | ||