Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6450f651 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  ipv6: protocol for address routes
  icmp: icmp_sk() should not use smp_processor_id() in preemptible code
  pkt_sched: Fix qdisc list locking
  pkt_sched: Fix qdisc_watchdog() vs. dev_deactivate() race
  sctp: fix potential panics in the SCTP-AUTH API.
parents 7a8fc9b2 f410a1fb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ extern struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,

extern int register_qdisc(struct Qdisc_ops *qops);
extern int unregister_qdisc(struct Qdisc_ops *qops);
extern void qdisc_list_del(struct Qdisc *q);
extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
+5 −0
Original line number Diff line number Diff line
@@ -193,6 +193,11 @@ static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
	return qdisc->dev_queue->qdisc;
}

static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
{
	return qdisc->dev_queue->qdisc_sleeping;
}

/* The qdisc root lock is a mechanism by which to top level
 * of a qdisc tree can be locked from any qdisc node in the
 * forest.  This allows changing the configuration of some
+14 −8
Original line number Diff line number Diff line
@@ -204,18 +204,22 @@ static struct sock *icmp_sk(struct net *net)
	return net->ipv4.icmp_sk[smp_processor_id()];
}

static inline int icmp_xmit_lock(struct sock *sk)
static inline struct sock *icmp_xmit_lock(struct net *net)
{
	struct sock *sk;

	local_bh_disable();

	sk = icmp_sk(net);

	if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
		/* This can happen if the output path signals a
		 * dst_link_failure() for an outgoing ICMP packet.
		 */
		local_bh_enable();
		return 1;
		return NULL;
	}
	return 0;
	return sk;
}

static inline void icmp_xmit_unlock(struct sock *sk)
@@ -354,15 +358,17 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
	struct ipcm_cookie ipc;
	struct rtable *rt = skb->rtable;
	struct net *net = dev_net(rt->u.dst.dev);
	struct sock *sk = icmp_sk(net);
	struct inet_sock *inet = inet_sk(sk);
	struct sock *sk;
	struct inet_sock *inet;
	__be32 daddr;

	if (ip_options_echo(&icmp_param->replyopts, skb))
		return;

	if (icmp_xmit_lock(sk))
	sk = icmp_xmit_lock(net);
	if (sk == NULL)
		return;
	inet = inet_sk(sk);

	icmp_param->data.icmph.checksum = 0;

@@ -419,7 +425,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
	if (!rt)
		goto out;
	net = dev_net(rt->u.dst.dev);
	sk = icmp_sk(net);

	/*
	 *	Find the original header. It is expected to be valid, of course.
@@ -483,7 +488,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
		}
	}

	if (icmp_xmit_lock(sk))
	sk = icmp_xmit_lock(net);
	if (sk == NULL)
		return;

	/*
+1 −0
Original line number Diff line number Diff line
@@ -1688,6 +1688,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
		.fc_dst_len = plen,
		.fc_flags = RTF_UP | flags,
		.fc_nlinfo.nl_net = dev_net(dev),
		.fc_protocol = RTPROT_KERNEL,
	};

	ipv6_addr_copy(&cfg.fc_dst, pfx);
+12 −11
Original line number Diff line number Diff line
@@ -91,19 +91,22 @@ static struct inet6_protocol icmpv6_protocol = {
	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};

static __inline__ int icmpv6_xmit_lock(struct sock *sk)
static __inline__ struct sock *icmpv6_xmit_lock(struct net *net)
{
	struct sock *sk;

	local_bh_disable();

	sk = icmpv6_sk(net);
	if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
		/* This can happen if the output path (f.e. SIT or
		 * ip6ip6 tunnel) signals dst_link_failure() for an
		 * outgoing ICMP6 packet.
		 */
		local_bh_enable();
		return 1;
		return NULL;
	}
	return 0;
	return sk;
}

static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
@@ -392,11 +395,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
	fl.fl_icmp_code = code;
	security_skb_classify_flow(skb, &fl);

	sk = icmpv6_sk(net);
	np = inet6_sk(sk);

	if (icmpv6_xmit_lock(sk))
	sk = icmpv6_xmit_lock(net);
	if (sk == NULL)
		return;
	np = inet6_sk(sk);

	if (!icmpv6_xrlim_allow(sk, type, &fl))
		goto out;
@@ -539,11 +541,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
	fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
	security_skb_classify_flow(skb, &fl);

	sk = icmpv6_sk(net);
	np = inet6_sk(sk);

	if (icmpv6_xmit_lock(sk))
	sk = icmpv6_xmit_lock(net);
	if (sk == NULL)
		return;
	np = inet6_sk(sk);

	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
		fl.oif = np->mcast_oif;
Loading