summaryrefslogtreecommitdiffstats
path: root/include/net/route.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/route.h')
-rw-r--r--include/net/route.h56
1 files changed, 49 insertions, 7 deletions
diff --git a/include/net/route.h b/include/net/route.h
index 98705468ac0..a36ae429ed5 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -67,10 +67,44 @@ struct rtable {
/* Miscellaneous cached information */
__be32 rt_spec_dst; /* RFC1122 specific destination */
u32 rt_peer_genid;
- struct inet_peer *peer; /* long-living peer info */
+ unsigned long _peer; /* long-living peer info */
struct fib_info *fi; /* for client ref to shared metrics */
};
+static inline struct inet_peer *rt_peer_ptr(struct rtable *rt)
+{
+ return inetpeer_ptr(rt->_peer);
+}
+
+static inline bool rt_has_peer(struct rtable *rt)
+{
+ return inetpeer_ptr_is_peer(rt->_peer);
+}
+
+static inline void __rt_set_peer(struct rtable *rt, struct inet_peer *peer)
+{
+ __inetpeer_ptr_set_peer(&rt->_peer, peer);
+}
+
+static inline bool rt_set_peer(struct rtable *rt, struct inet_peer *peer)
+{
+ return inetpeer_ptr_set_peer(&rt->_peer, peer);
+}
+
+static inline void rt_init_peer(struct rtable *rt, struct inet_peer_base *base)
+{
+ inetpeer_init_ptr(&rt->_peer, base);
+}
+
+static inline void rt_transfer_peer(struct rtable *rt, struct rtable *ort)
+{
+ rt->_peer = ort->_peer;
+ if (rt_has_peer(ort)) {
+ struct inet_peer *peer = rt_peer_ptr(ort);
+ atomic_inc(&peer->refcnt);
+ }
+}
+
static inline bool rt_is_input_route(const struct rtable *rt)
{
return rt->rt_route_iif != 0;
@@ -181,8 +215,6 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s
return ip_route_input_common(skb, dst, src, tos, devin, true);
}
-extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
- unsigned short new_mtu, struct net_device *dev);
extern void ip_rt_send_redirect(struct sk_buff *skb);
extern unsigned int inet_addr_type(struct net *net, __be32 addr);
@@ -296,13 +328,23 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable
extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create);
+static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, int create)
+{
+ if (rt_has_peer(rt))
+ return rt_peer_ptr(rt);
+
+ rt_bind_peer(rt, daddr, create);
+ return (rt_has_peer(rt) ? rt_peer_ptr(rt) : NULL);
+}
+
static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr)
{
- if (rt->peer)
- return rt->peer;
+ return __rt_get_peer(rt, daddr, 0);
+}
- rt_bind_peer(rt, daddr, 0);
- return rt->peer;
+static inline struct inet_peer *rt_get_peer_create(struct rtable *rt, __be32 daddr)
+{
+ return __rt_get_peer(rt, daddr, 1);
}
static inline int inet_iif(const struct sk_buff *skb)