diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 2 | ||||
| -rw-r--r-- | net/core/fib_rules.c | 14 | ||||
| -rw-r--r-- | net/core/filter.c | 2 | ||||
| -rw-r--r-- | net/core/net-sysfs.c | 12 | ||||
| -rw-r--r-- | net/core/netpoll.c | 10 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 26 | ||||
| -rw-r--r-- | net/core/skbuff.c | 9 | ||||
| -rw-r--r-- | net/core/sock.c | 12 | 
8 files changed, 55 insertions, 32 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 877c84834d81..6bb6470f5b7b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4713,6 +4713,8 @@ void napi_disable(struct napi_struct *n)  	while (test_and_set_bit(NAPI_STATE_SCHED, &n->state))  		msleep(1); +	while (test_and_set_bit(NAPI_STATE_NPSVC, &n->state)) +		msleep(1);  	hrtimer_cancel(&n->timer); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index bf77e3639ce0..365de66436ac 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -631,15 +631,17 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,  {  	int idx = 0;  	struct fib_rule *rule; +	int err = 0;  	rcu_read_lock();  	list_for_each_entry_rcu(rule, &ops->rules_list, list) {  		if (idx < cb->args[1])  			goto skip; -		if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, -				     cb->nlh->nlmsg_seq, RTM_NEWRULE, -				     NLM_F_MULTI, ops) < 0) +		err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, +				       cb->nlh->nlmsg_seq, RTM_NEWRULE, +				       NLM_F_MULTI, ops); +		if (err)  			break;  skip:  		idx++; @@ -648,7 +650,7 @@ skip:  	cb->args[1] = idx;  	rules_ops_put(ops); -	return skb->len; +	return err;  }  static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb) @@ -664,7 +666,9 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)  		if (ops == NULL)  			return -EAFNOSUPPORT; -		return dump_rules(skb, cb, ops); +		dump_rules(skb, cb, ops); + +		return skb->len;  	}  	rcu_read_lock(); diff --git a/net/core/filter.c b/net/core/filter.c index 13079f03902e..05a04ea87172 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -478,9 +478,9 @@ do_pass:  				bpf_src = BPF_X;  			} else {  				insn->dst_reg = BPF_REG_A; -				insn->src_reg = BPF_REG_X;  				insn->imm = fp->k;  				bpf_src = BPF_SRC(fp->code); +				insn->src_reg = bpf_src == BPF_X ? BPF_REG_X : 0;  			}  			/* Common case where 'jump_false' is next insn. */ diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index b279077c3089..830f8a7c1cb1 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -31,7 +31,6 @@  static const char fmt_hex[] = "%#x\n";  static const char fmt_long_hex[] = "%#lx\n";  static const char fmt_dec[] = "%d\n"; -static const char fmt_udec[] = "%u\n";  static const char fmt_ulong[] = "%lu\n";  static const char fmt_u64[] = "%llu\n"; @@ -202,7 +201,7 @@ static ssize_t speed_show(struct device *dev,  	if (netif_running(netdev)) {  		struct ethtool_cmd cmd;  		if (!__ethtool_get_settings(netdev, &cmd)) -			ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd)); +			ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));  	}  	rtnl_unlock();  	return ret; @@ -1481,6 +1480,15 @@ static int of_dev_node_match(struct device *dev, const void *data)  	return ret == 0 ? dev->of_node == data : ret;  } +/* + * of_find_net_device_by_node - lookup the net device for the device node + * @np: OF device node + * + * Looks up the net_device structure corresponding with the device node. + * If successful, returns a pointer to the net_device with the embedded + * struct device refcount incremented by one, or NULL on failure. The + * refcount must be dropped when done with the net_device. + */  struct net_device *of_find_net_device_by_node(struct device_node *np)  {  	struct device *dev; diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 6aa3db8dfc3b..8bdada242a7d 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -142,7 +142,7 @@ static void queue_process(struct work_struct *work)   */  static int poll_one_napi(struct napi_struct *napi, int budget)  { -	int work; +	int work = 0;  	/* net_rx_action's ->poll() invocations and our's are  	 * synchronized by this test which is only made while @@ -151,7 +151,12 @@ static int poll_one_napi(struct napi_struct *napi, int budget)  	if (!test_bit(NAPI_STATE_SCHED, &napi->state))  		return budget; -	set_bit(NAPI_STATE_NPSVC, &napi->state); +	/* If we set this bit but see that it has already been set, +	 * that indicates that napi has been disabled and we need +	 * to abort this operation +	 */ +	if (test_and_set_bit(NAPI_STATE_NPSVC, &napi->state)) +		goto out;  	work = napi->poll(napi, budget);  	WARN_ONCE(work > budget, "%pF exceeded budget in poll\n", napi->poll); @@ -159,6 +164,7 @@ static int poll_one_napi(struct napi_struct *napi, int budget)  	clear_bit(NAPI_STATE_NPSVC, &napi->state); +out:  	return budget - work;  } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a466821d1441..0ec48403ed68 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3047,6 +3047,7 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)  	u32 portid = NETLINK_CB(cb->skb).portid;  	u32 seq = cb->nlh->nlmsg_seq;  	u32 filter_mask = 0; +	int err;  	if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) {  		struct nlattr *extfilt; @@ -3067,20 +3068,25 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)  		struct net_device *br_dev = netdev_master_upper_dev_get(dev);  		if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { -			if (idx >= cb->args[0] && -			    br_dev->netdev_ops->ndo_bridge_getlink( -				    skb, portid, seq, dev, filter_mask, -				    NLM_F_MULTI) < 0) -				break; +			if (idx >= cb->args[0]) { +				err = br_dev->netdev_ops->ndo_bridge_getlink( +						skb, portid, seq, dev, +						filter_mask, NLM_F_MULTI); +				if (err < 0 && err != -EOPNOTSUPP) +					break; +			}  			idx++;  		}  		if (ops->ndo_bridge_getlink) { -			if (idx >= cb->args[0] && -			    ops->ndo_bridge_getlink(skb, portid, seq, dev, -						    filter_mask, -						    NLM_F_MULTI) < 0) -				break; +			if (idx >= cb->args[0]) { +				err = ops->ndo_bridge_getlink(skb, portid, +							      seq, dev, +							      filter_mask, +							      NLM_F_MULTI); +				if (err < 0 && err != -EOPNOTSUPP) +					break; +			}  			idx++;  		}  	} diff --git a/net/core/skbuff.c b/net/core/skbuff.c index dad4dd37e2aa..fab4599ba8b2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2958,11 +2958,12 @@ EXPORT_SYMBOL_GPL(skb_append_pagefrags);   */  unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)  { +	unsigned char *data = skb->data; +  	BUG_ON(len > skb->len); -	skb->len -= len; -	BUG_ON(skb->len < skb->data_len); -	skb_postpull_rcsum(skb, skb->data, len); -	return skb->data += len; +	__skb_pull(skb, len); +	skb_postpull_rcsum(skb, data, len); +	return skb->data;  }  EXPORT_SYMBOL_GPL(skb_pull_rcsum); diff --git a/net/core/sock.c b/net/core/sock.c index ca2984afe16e..3307c02244d3 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2740,10 +2740,8 @@ static void req_prot_cleanup(struct request_sock_ops *rsk_prot)  		return;  	kfree(rsk_prot->slab_name);  	rsk_prot->slab_name = NULL; -	if (rsk_prot->slab) { -		kmem_cache_destroy(rsk_prot->slab); -		rsk_prot->slab = NULL; -	} +	kmem_cache_destroy(rsk_prot->slab); +	rsk_prot->slab = NULL;  }  static int req_prot_init(const struct proto *prot) @@ -2828,10 +2826,8 @@ void proto_unregister(struct proto *prot)  	list_del(&prot->node);  	mutex_unlock(&proto_list_mutex); -	if (prot->slab != NULL) { -		kmem_cache_destroy(prot->slab); -		prot->slab = NULL; -	} +	kmem_cache_destroy(prot->slab); +	prot->slab = NULL;  	req_prot_cleanup(prot->rsk_prot);  |