aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c17
-rw-r--r--net/core/netpoll.c2
-rw-r--r--net/core/rtnetlink.c10
-rw-r--r--net/core/skbuff.c30
4 files changed, 40 insertions, 19 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index b1b0c8d4d7df..bc3c89792b0c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2286,7 +2286,7 @@ out:
2286} 2286}
2287EXPORT_SYMBOL(skb_checksum_help); 2287EXPORT_SYMBOL(skb_checksum_help);
2288 2288
2289__be16 skb_network_protocol(struct sk_buff *skb) 2289__be16 skb_network_protocol(struct sk_buff *skb, int *depth)
2290{ 2290{
2291 __be16 type = skb->protocol; 2291 __be16 type = skb->protocol;
2292 int vlan_depth = ETH_HLEN; 2292 int vlan_depth = ETH_HLEN;
@@ -2313,6 +2313,8 @@ __be16 skb_network_protocol(struct sk_buff *skb)
2313 vlan_depth += VLAN_HLEN; 2313 vlan_depth += VLAN_HLEN;
2314 } 2314 }
2315 2315
2316 *depth = vlan_depth;
2317
2316 return type; 2318 return type;
2317} 2319}
2318 2320
@@ -2326,12 +2328,13 @@ struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
2326{ 2328{
2327 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 2329 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
2328 struct packet_offload *ptype; 2330 struct packet_offload *ptype;
2329 __be16 type = skb_network_protocol(skb); 2331 int vlan_depth = skb->mac_len;
2332 __be16 type = skb_network_protocol(skb, &vlan_depth);
2330 2333
2331 if (unlikely(!type)) 2334 if (unlikely(!type))
2332 return ERR_PTR(-EINVAL); 2335 return ERR_PTR(-EINVAL);
2333 2336
2334 __skb_pull(skb, skb->mac_len); 2337 __skb_pull(skb, vlan_depth);
2335 2338
2336 rcu_read_lock(); 2339 rcu_read_lock();
2337 list_for_each_entry_rcu(ptype, &offload_base, list) { 2340 list_for_each_entry_rcu(ptype, &offload_base, list) {
@@ -2498,8 +2501,10 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
2498 const struct net_device *dev, 2501 const struct net_device *dev,
2499 netdev_features_t features) 2502 netdev_features_t features)
2500{ 2503{
2504 int tmp;
2505
2501 if (skb->ip_summed != CHECKSUM_NONE && 2506 if (skb->ip_summed != CHECKSUM_NONE &&
2502 !can_checksum_protocol(features, skb_network_protocol(skb))) { 2507 !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) {
2503 features &= ~NETIF_F_ALL_CSUM; 2508 features &= ~NETIF_F_ALL_CSUM;
2504 } else if (illegal_highdma(dev, skb)) { 2509 } else if (illegal_highdma(dev, skb)) {
2505 features &= ~NETIF_F_SG; 2510 features &= ~NETIF_F_SG;
@@ -4130,8 +4135,8 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
4130 struct softnet_data *next = remsd->rps_ipi_next; 4135 struct softnet_data *next = remsd->rps_ipi_next;
4131 4136
4132 if (cpu_online(remsd->cpu)) 4137 if (cpu_online(remsd->cpu))
4133 __smp_call_function_single(remsd->cpu, 4138 smp_call_function_single_async(remsd->cpu,
4134 &remsd->csd, 0); 4139 &remsd->csd);
4135 remsd = next; 4140 remsd = next;
4136 } 4141 }
4137 } else 4142 } else
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a664f7829a6d..df9e6b1a9759 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -742,7 +742,7 @@ static bool pkt_is_ns(struct sk_buff *skb)
742 struct nd_msg *msg; 742 struct nd_msg *msg;
743 struct ipv6hdr *hdr; 743 struct ipv6hdr *hdr;
744 744
745 if (skb->protocol != htons(ETH_P_ARP)) 745 if (skb->protocol != htons(ETH_P_IPV6))
746 return false; 746 return false;
747 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + sizeof(struct nd_msg))) 747 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + sizeof(struct nd_msg)))
748 return false; 748 return false;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1a0dac2ef9ad..120eecc0f5a4 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2121,12 +2121,13 @@ EXPORT_SYMBOL(rtmsg_ifinfo);
2121static int nlmsg_populate_fdb_fill(struct sk_buff *skb, 2121static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
2122 struct net_device *dev, 2122 struct net_device *dev,
2123 u8 *addr, u32 pid, u32 seq, 2123 u8 *addr, u32 pid, u32 seq,
2124 int type, unsigned int flags) 2124 int type, unsigned int flags,
2125 int nlflags)
2125{ 2126{
2126 struct nlmsghdr *nlh; 2127 struct nlmsghdr *nlh;
2127 struct ndmsg *ndm; 2128 struct ndmsg *ndm;
2128 2129
2129 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI); 2130 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags);
2130 if (!nlh) 2131 if (!nlh)
2131 return -EMSGSIZE; 2132 return -EMSGSIZE;
2132 2133
@@ -2164,7 +2165,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type)
2164 if (!skb) 2165 if (!skb)
2165 goto errout; 2166 goto errout;
2166 2167
2167 err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF); 2168 err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0);
2168 if (err < 0) { 2169 if (err < 0) {
2169 kfree_skb(skb); 2170 kfree_skb(skb);
2170 goto errout; 2171 goto errout;
@@ -2389,7 +2390,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
2389 2390
2390 err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 2391 err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,
2391 portid, seq, 2392 portid, seq,
2392 RTM_NEWNEIGH, NTF_SELF); 2393 RTM_NEWNEIGH, NTF_SELF,
2394 NLM_F_MULTI);
2393 if (err < 0) 2395 if (err < 0)
2394 return err; 2396 return err;
2395skip: 2397skip:
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 869c7afe3b07..90b96a11b974 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2127,25 +2127,31 @@ EXPORT_SYMBOL_GPL(skb_zerocopy_headlen);
2127 * 2127 *
2128 * The `hlen` as calculated by skb_zerocopy_headlen() specifies the 2128 * The `hlen` as calculated by skb_zerocopy_headlen() specifies the
2129 * headroom in the `to` buffer. 2129 * headroom in the `to` buffer.
2130 *
2131 * Return value:
2132 * 0: everything is OK
2133 * -ENOMEM: couldn't orphan frags of @from due to lack of memory
2134 * -EFAULT: skb_copy_bits() found some problem with skb geometry
2130 */ 2135 */
2131void 2136int
2132skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen) 2137skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen)
2133{ 2138{
2134 int i, j = 0; 2139 int i, j = 0;
2135 int plen = 0; /* length of skb->head fragment */ 2140 int plen = 0; /* length of skb->head fragment */
2141 int ret;
2136 struct page *page; 2142 struct page *page;
2137 unsigned int offset; 2143 unsigned int offset;
2138 2144
2139 BUG_ON(!from->head_frag && !hlen); 2145 BUG_ON(!from->head_frag && !hlen);
2140 2146
2141 /* dont bother with small payloads */ 2147 /* dont bother with small payloads */
2142 if (len <= skb_tailroom(to)) { 2148 if (len <= skb_tailroom(to))
2143 skb_copy_bits(from, 0, skb_put(to, len), len); 2149 return skb_copy_bits(from, 0, skb_put(to, len), len);
2144 return;
2145 }
2146 2150
2147 if (hlen) { 2151 if (hlen) {
2148 skb_copy_bits(from, 0, skb_put(to, hlen), hlen); 2152 ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
2153 if (unlikely(ret))
2154 return ret;
2149 len -= hlen; 2155 len -= hlen;
2150 } else { 2156 } else {
2151 plen = min_t(int, skb_headlen(from), len); 2157 plen = min_t(int, skb_headlen(from), len);
@@ -2163,6 +2169,11 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
2163 to->len += len + plen; 2169 to->len += len + plen;
2164 to->data_len += len + plen; 2170 to->data_len += len + plen;
2165 2171
2172 if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) {
2173 skb_tx_error(from);
2174 return -ENOMEM;
2175 }
2176
2166 for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { 2177 for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
2167 if (!len) 2178 if (!len)
2168 break; 2179 break;
@@ -2173,6 +2184,8 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
2173 j++; 2184 j++;
2174 } 2185 }
2175 skb_shinfo(to)->nr_frags = j; 2186 skb_shinfo(to)->nr_frags = j;
2187
2188 return 0;
2176} 2189}
2177EXPORT_SYMBOL_GPL(skb_zerocopy); 2190EXPORT_SYMBOL_GPL(skb_zerocopy);
2178 2191
@@ -2866,8 +2879,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
2866 int err = -ENOMEM; 2879 int err = -ENOMEM;
2867 int i = 0; 2880 int i = 0;
2868 int pos; 2881 int pos;
2882 int dummy;
2869 2883
2870 proto = skb_network_protocol(head_skb); 2884 proto = skb_network_protocol(head_skb, &dummy);
2871 if (unlikely(!proto)) 2885 if (unlikely(!proto))
2872 return ERR_PTR(-EINVAL); 2886 return ERR_PTR(-EINVAL);
2873 2887