summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/flow.h1
-rw-r--r--include/net/inetpeer.h3
-rw-r--r--include/net/ip_fib.h16
-rw-r--r--include/net/ip_mp_alg.h97
-rw-r--r--include/net/route.h7
-rw-r--r--include/net/sock.h5
7 files changed, 122 insertions, 8 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index fd8f1b1d2fcc..f392a559b5b4 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -48,6 +48,7 @@ struct dst_entry
#define DST_NOXFRM 2
#define DST_NOPOLICY 4
#define DST_NOHASH 8
+#define DST_BALANCED 0x10
unsigned long lastuse;
unsigned long expires;
diff --git a/include/net/flow.h b/include/net/flow.h
index 025579ddb925..9a5c94b1a0ec 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -51,6 +51,7 @@ struct flowi {
__u8 proto;
__u8 flags;
+#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
union {
struct {
__u16 sport;
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 5fd62eb25a04..7fda471002b6 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -19,9 +19,9 @@ struct inet_peer
{
struct inet_peer *avl_left, *avl_right;
struct inet_peer *unused_next, **unused_prevp;
- atomic_t refcnt;
unsigned long dtime; /* the time of last use of not
* referenced entries */
+ atomic_t refcnt;
__u32 v4daddr; /* peer's address */
__u16 avl_height;
__u16 ip_id_count; /* IP ID for the next packet */
@@ -35,7 +35,6 @@ void inet_initpeers(void) __init;
struct inet_peer *inet_getpeer(__u32 daddr, int create);
extern spinlock_t inet_peer_unused_lock;
-extern struct inet_peer *inet_peer_unused_head;
extern struct inet_peer **inet_peer_unused_tailp;
/* can be called from BH context or outside */
static inline void inet_putpeer(struct inet_peer *p)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 9f28dfffb6c6..e5a5f6b62f88 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -37,6 +37,7 @@ struct kern_rta {
u32 *rta_flow;
struct rta_cacheinfo *rta_ci;
struct rta_session *rta_sess;
+ u32 *rta_mp_alg;
};
struct fib_info;
@@ -81,6 +82,9 @@ struct fib_info {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
#endif
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ u32 fib_mp_alg;
+#endif
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].nh_dev
};
@@ -95,6 +99,10 @@ struct fib_result {
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ __u32 network;
+ __u32 netmask;
+#endif
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule *r;
@@ -119,6 +127,14 @@ struct fib_result {
#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+#define FIB_RES_NETWORK(res) ((res).network)
+#define FIB_RES_NETMASK(res) ((res).netmask)
+#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
+#define FIB_RES_NETWORK(res) (0)
+#define FIB_RES_NETMASK(res) (0)
+#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
+
struct fib_table {
unsigned char tb_id;
unsigned tb_stamp;
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h
new file mode 100644
index 000000000000..9431df22782c
--- /dev/null
+++ b/include/net/ip_mp_alg.h
@@ -0,0 +1,97 @@
+/* ip_mp_alg.h: IPV4 multipath algorithm support.
+ *
+ * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
+ * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
+ */
+
+#ifndef _NET_IP_MP_ALG_H
+#define _NET_IP_MP_ALG_H
+
+#include <linux/config.h>
+#include <linux/ip_mp_alg.h>
+#include <net/flow.h>
+#include <net/route.h>
+
+struct fib_nh;
+
+struct ip_mp_alg_ops {
+ void (*mp_alg_select_route)(const struct flowi *flp,
+ struct rtable *rth, struct rtable **rp);
+ void (*mp_alg_flush)(void);
+ void (*mp_alg_set_nhinfo)(__u32 network, __u32 netmask,
+ unsigned char prefixlen,
+ const struct fib_nh *nh);
+ void (*mp_alg_remove)(struct rtable *rth);
+};
+
+extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg);
+extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg);
+
+extern struct ip_mp_alg_ops *ip_mp_alg_table[];
+
+static inline int multipath_select_route(const struct flowi *flp,
+ struct rtable *rth,
+ struct rtable **rp)
+{
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
+
+ if (ops && (rth->u.dst.flags & DST_BALANCED)) {
+ ops->mp_alg_select_route(flp, rth, rp);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static inline void multipath_flush(void)
+{
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ int i;
+
+ for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) {
+ struct ip_mp_alg_ops *ops = ip_mp_alg_table[i];
+
+ if (ops)
+ ops->mp_alg_flush();
+ }
+#endif
+}
+
+static inline void multipath_set_nhinfo(struct rtable *rth,
+ __u32 network, __u32 netmask,
+ unsigned char prefixlen,
+ const struct fib_nh *nh)
+{
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
+
+ if (ops)
+ ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh);
+#endif
+}
+
+static inline void multipath_remove(struct rtable *rth)
+{
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
+
+ if (ops && (rth->u.dst.flags & DST_BALANCED))
+ ops->mp_alg_remove(rth);
+#endif
+}
+
+static inline int multipath_comparekeys(const struct flowi *flp1,
+ const struct flowi *flp2)
+{
+ return flp1->fl4_dst == flp2->fl4_dst &&
+ flp1->fl4_src == flp2->fl4_src &&
+ flp1->oif == flp2->oif &&
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ flp1->fl4_fwmark == flp2->fl4_fwmark &&
+#endif
+ !((flp1->fl4_tos ^ flp2->fl4_tos) &
+ (IPTOS_RT_MASK | RTO_ONLINK));
+}
+
+#endif /* _NET_IP_MP_ALG_H */
diff --git a/include/net/route.h b/include/net/route.h
index 8bbbe3f02719..22da7579d5de 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -46,6 +46,7 @@
#define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
+struct fib_nh;
struct inet_peer;
struct rtable
{
@@ -58,7 +59,8 @@ struct rtable
struct in_device *idev;
unsigned rt_flags;
- unsigned rt_type;
+ __u16 rt_type;
+ __u16 rt_multipath_alg;
__u32 rt_dst; /* Path destination */
__u32 rt_src; /* Path source */
@@ -179,6 +181,9 @@ static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport,
memcpy(&fl, &(*rp)->fl, sizeof(fl));
fl.fl_ip_sport = sport;
fl.fl_ip_dport = dport;
+#if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED)
+ fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE;
+#endif
ip_rt_put(*rp);
*rp = NULL;
return ip_route_output_flow(rp, &fl, sk, 0);
diff --git a/include/net/sock.h b/include/net/sock.h
index 812592fb9b48..fb789af4ab08 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -561,11 +561,6 @@ struct proto {
extern int sk_alloc_slab(struct proto *prot, char *name);
extern void sk_free_slab(struct proto *prot);
-static inline void sk_alloc_slab_error(struct proto *proto)
-{
- printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n", proto->name);
-}
-
static __inline__ void sk_set_owner(struct sock *sk, struct module *owner)
{
/*