blob: 25b56571e54bf5b4713ff2780abbdae3cc441cdb [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* ip_mp_alg.h: IPV4 multipath algorithm support.
2 *
3 * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
4 * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
5 */
6
7#ifndef _NET_IP_MP_ALG_H
8#define _NET_IP_MP_ALG_H
9
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/ip_mp_alg.h>
11#include <net/flow.h>
12#include <net/route.h>
13
14struct fib_nh;
15
16struct ip_mp_alg_ops {
17 void (*mp_alg_select_route)(const struct flowi *flp,
18 struct rtable *rth, struct rtable **rp);
19 void (*mp_alg_flush)(void);
Al Virod9cd66e2006-09-26 22:22:50 -070020 void (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 unsigned char prefixlen,
22 const struct fib_nh *nh);
23 void (*mp_alg_remove)(struct rtable *rth);
24};
25
26extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg);
27extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg);
28
29extern struct ip_mp_alg_ops *ip_mp_alg_table[];
30
31static inline int multipath_select_route(const struct flowi *flp,
32 struct rtable *rth,
33 struct rtable **rp)
34{
35#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
36 struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
37
38 /* mp_alg_select_route _MUST_ be implemented */
39 if (ops && (rth->u.dst.flags & DST_BALANCED)) {
40 ops->mp_alg_select_route(flp, rth, rp);
41 return 1;
42 }
43#endif
44 return 0;
45}
46
47static inline void multipath_flush(void)
48{
49#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
50 int i;
51
52 for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) {
53 struct ip_mp_alg_ops *ops = ip_mp_alg_table[i];
54
55 if (ops && ops->mp_alg_flush)
56 ops->mp_alg_flush();
57 }
58#endif
59}
60
61static inline void multipath_set_nhinfo(struct rtable *rth,
Al Virod9cd66e2006-09-26 22:22:50 -070062 __be32 network, __be32 netmask,
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 unsigned char prefixlen,
64 const struct fib_nh *nh)
65{
66#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
67 struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
68
69 if (ops && ops->mp_alg_set_nhinfo)
70 ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh);
71#endif
72}
73
74static inline void multipath_remove(struct rtable *rth)
75{
76#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
77 struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
78
79 if (ops && ops->mp_alg_remove &&
80 (rth->u.dst.flags & DST_BALANCED))
81 ops->mp_alg_remove(rth);
82#endif
83}
84
85static inline int multipath_comparekeys(const struct flowi *flp1,
86 const struct flowi *flp2)
87{
88 return flp1->fl4_dst == flp2->fl4_dst &&
89 flp1->fl4_src == flp2->fl4_src &&
90 flp1->oif == flp2->oif &&
Thomas Graf47dcf0c2006-11-09 15:20:38 -080091 flp1->mark == flp2->mark &&
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 !((flp1->fl4_tos ^ flp2->fl4_tos) &
93 (IPTOS_RT_MASK | RTO_ONLINK));
94}
95
96#endif /* _NET_IP_MP_ALG_H */