net: Document dst->obsolete better.
Add a big comment explaining how the field works, and use defines instead of magic constants for the values assigned to it. Suggested by Joe Perches. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f8126f1d51
commit
f5b0a87436
@ -65,7 +65,19 @@ struct dst_entry {
|
|||||||
unsigned short pending_confirm;
|
unsigned short pending_confirm;
|
||||||
|
|
||||||
short error;
|
short error;
|
||||||
|
|
||||||
|
/* A non-zero value of dst->obsolete forces by-hand validation
|
||||||
|
* of the route entry. Positive values are set by the generic
|
||||||
|
* dst layer to indicate that the entry has been forcefully
|
||||||
|
* destroyed.
|
||||||
|
*
|
||||||
|
* Negative values are used by the implementation layer code to
|
||||||
|
* force invocation of the dst_ops->check() method.
|
||||||
|
*/
|
||||||
short obsolete;
|
short obsolete;
|
||||||
|
#define DST_OBSOLETE_NONE 0
|
||||||
|
#define DST_OBSOLETE_DEAD 2
|
||||||
|
#define DST_OBSOLETE_FORCE_CHK -1
|
||||||
unsigned short header_len; /* more space at head required */
|
unsigned short header_len; /* more space at head required */
|
||||||
unsigned short trailer_len; /* space to reserve at tail */
|
unsigned short trailer_len; /* space to reserve at tail */
|
||||||
#ifdef CONFIG_IP_ROUTE_CLASSID
|
#ifdef CONFIG_IP_ROUTE_CLASSID
|
||||||
@ -359,7 +371,7 @@ extern struct dst_entry *dst_destroy(struct dst_entry *dst);
|
|||||||
|
|
||||||
static inline void dst_free(struct dst_entry *dst)
|
static inline void dst_free(struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
if (dst->obsolete > 1)
|
if (dst->obsolete > 0)
|
||||||
return;
|
return;
|
||||||
if (!atomic_read(&dst->__refcnt)) {
|
if (!atomic_read(&dst->__refcnt)) {
|
||||||
dst = dst_destroy(dst);
|
dst = dst_destroy(dst);
|
||||||
|
@ -94,7 +94,7 @@ loop:
|
|||||||
* But we do not have state "obsoleted, but
|
* But we do not have state "obsoleted, but
|
||||||
* referenced by parent", so it is right.
|
* referenced by parent", so it is right.
|
||||||
*/
|
*/
|
||||||
if (dst->obsolete > 1)
|
if (dst->obsolete > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
___dst_free(dst);
|
___dst_free(dst);
|
||||||
@ -202,7 +202,7 @@ static void ___dst_free(struct dst_entry *dst)
|
|||||||
*/
|
*/
|
||||||
if (dst->dev == NULL || !(dst->dev->flags&IFF_UP))
|
if (dst->dev == NULL || !(dst->dev->flags&IFF_UP))
|
||||||
dst->input = dst->output = dst_discard;
|
dst->input = dst->output = dst_discard;
|
||||||
dst->obsolete = 2;
|
dst->obsolete = DST_OBSOLETE_DEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __dst_free(struct dst_entry *dst)
|
void __dst_free(struct dst_entry *dst)
|
||||||
|
@ -1176,7 +1176,7 @@ make_route:
|
|||||||
if (dev_out->flags & IFF_LOOPBACK)
|
if (dev_out->flags & IFF_LOOPBACK)
|
||||||
flags |= RTCF_LOCAL;
|
flags |= RTCF_LOCAL;
|
||||||
|
|
||||||
rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST);
|
rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
|
||||||
if (rt == NULL)
|
if (rt == NULL)
|
||||||
goto e_nobufs;
|
goto e_nobufs;
|
||||||
|
|
||||||
@ -1444,7 +1444,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_route:
|
make_route:
|
||||||
rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST);
|
rt = dst_alloc(&dn_dst_ops, out_dev, 0, DST_OBSOLETE_NONE, DST_HOST);
|
||||||
if (rt == NULL)
|
if (rt == NULL)
|
||||||
goto e_nobufs;
|
goto e_nobufs;
|
||||||
|
|
||||||
|
@ -1221,7 +1221,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4,
|
|||||||
static struct rtable *rt_dst_alloc(struct net_device *dev,
|
static struct rtable *rt_dst_alloc(struct net_device *dev,
|
||||||
bool nopolicy, bool noxfrm)
|
bool nopolicy, bool noxfrm)
|
||||||
{
|
{
|
||||||
return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
|
return dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
|
||||||
DST_HOST | DST_NOCACHE |
|
DST_HOST | DST_NOCACHE |
|
||||||
(nopolicy ? DST_NOPOLICY : 0) |
|
(nopolicy ? DST_NOPOLICY : 0) |
|
||||||
(noxfrm ? DST_NOXFRM : 0));
|
(noxfrm ? DST_NOXFRM : 0));
|
||||||
@ -1969,9 +1969,10 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
|
|||||||
|
|
||||||
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
|
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
|
||||||
{
|
{
|
||||||
struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0);
|
|
||||||
struct rtable *ort = (struct rtable *) dst_orig;
|
struct rtable *ort = (struct rtable *) dst_orig;
|
||||||
|
struct rtable *rt;
|
||||||
|
|
||||||
|
rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, 0);
|
||||||
if (rt) {
|
if (rt) {
|
||||||
struct dst_entry *new = &rt->dst;
|
struct dst_entry *new = &rt->dst;
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
|
|||||||
struct fib6_table *table)
|
struct fib6_table *table)
|
||||||
{
|
{
|
||||||
struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
|
struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
|
||||||
0, 0, flags);
|
0, DST_OBSOLETE_NONE, flags);
|
||||||
|
|
||||||
if (rt) {
|
if (rt) {
|
||||||
struct dst_entry *dst = &rt->dst;
|
struct dst_entry *dst = &rt->dst;
|
||||||
@ -985,7 +985,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
|
|||||||
struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
|
struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
|
||||||
struct dst_entry *new = NULL;
|
struct dst_entry *new = NULL;
|
||||||
|
|
||||||
rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
|
rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
|
||||||
if (rt) {
|
if (rt) {
|
||||||
new = &rt->dst;
|
new = &rt->dst;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ void sctp_transport_set_owner(struct sctp_transport *transport,
|
|||||||
void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
|
void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
|
||||||
{
|
{
|
||||||
/* If we don't have a fresh route, look one up */
|
/* If we don't have a fresh route, look one up */
|
||||||
if (!transport->dst || transport->dst->obsolete > 1) {
|
if (!transport->dst || transport->dst->obsolete) {
|
||||||
dst_release(transport->dst);
|
dst_release(transport->dst);
|
||||||
transport->af_specific->get_dst(transport, &transport->saddr,
|
transport->af_specific->get_dst(transport, &transport->saddr,
|
||||||
&transport->fl, sk);
|
&transport->fl, sk);
|
||||||
|
@ -1350,7 +1350,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
|
|||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
|
xdst = dst_alloc(dst_ops, NULL, 0, DST_OBSOLETE_NONE, 0);
|
||||||
|
|
||||||
if (likely(xdst)) {
|
if (likely(xdst)) {
|
||||||
struct dst_entry *dst = &xdst->u.dst;
|
struct dst_entry *dst = &xdst->u.dst;
|
||||||
@ -1477,7 +1477,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
|
|||||||
dst1->xfrm = xfrm[i];
|
dst1->xfrm = xfrm[i];
|
||||||
xdst->xfrm_genid = xfrm[i]->genid;
|
xdst->xfrm_genid = xfrm[i]->genid;
|
||||||
|
|
||||||
dst1->obsolete = -1;
|
dst1->obsolete = DST_OBSOLETE_FORCE_CHK;
|
||||||
dst1->flags |= DST_HOST;
|
dst1->flags |= DST_HOST;
|
||||||
dst1->lastuse = now;
|
dst1->lastuse = now;
|
||||||
|
|
||||||
@ -2219,12 +2219,13 @@ EXPORT_SYMBOL(__xfrm_route_forward);
|
|||||||
static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
|
static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
|
||||||
{
|
{
|
||||||
/* Code (such as __xfrm4_bundle_create()) sets dst->obsolete
|
/* Code (such as __xfrm4_bundle_create()) sets dst->obsolete
|
||||||
* to "-1" to force all XFRM destinations to get validated by
|
* to DST_OBSOLETE_FORCE_CHK to force all XFRM destinations to
|
||||||
* dst_ops->check on every use. We do this because when a
|
* get validated by dst_ops->check on every use. We do this
|
||||||
* normal route referenced by an XFRM dst is obsoleted we do
|
* because when a normal route referenced by an XFRM dst is
|
||||||
* not go looking around for all parent referencing XFRM dsts
|
* obsoleted we do not go looking around for all parent
|
||||||
* so that we can invalidate them. It is just too much work.
|
* referencing XFRM dsts so that we can invalidate them. It
|
||||||
* Instead we make the checks here on every use. For example:
|
* is just too much work. Instead we make the checks here on
|
||||||
|
* every use. For example:
|
||||||
*
|
*
|
||||||
* XFRM dst A --> IPv4 dst X
|
* XFRM dst A --> IPv4 dst X
|
||||||
*
|
*
|
||||||
@ -2234,9 +2235,9 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
|
|||||||
* stale_bundle() check.
|
* stale_bundle() check.
|
||||||
*
|
*
|
||||||
* When a policy's bundle is pruned, we dst_free() the XFRM
|
* When a policy's bundle is pruned, we dst_free() the XFRM
|
||||||
* dst which causes it's ->obsolete field to be set to a
|
* dst which causes it's ->obsolete field to be set to
|
||||||
* positive non-zero integer. If an XFRM dst has been pruned
|
* DST_OBSOLETE_DEAD. If an XFRM dst has been pruned like
|
||||||
* like this, we want to force a new route lookup.
|
* this, we want to force a new route lookup.
|
||||||
*/
|
*/
|
||||||
if (dst->obsolete < 0 && !stale_bundle(dst))
|
if (dst->obsolete < 0 && !stale_bundle(dst))
|
||||||
return dst;
|
return dst;
|
||||||
|
Loading…
Reference in New Issue
Block a user