Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* 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 | ||
1da177e4 LT |
10 | #include <linux/ip_mp_alg.h> |
11 | #include <net/flow.h> | |
12 | #include <net/route.h> | |
13 | ||
14 | struct fib_nh; | |
15 | ||
16 | struct 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); | |
d9cd66e0 | 20 | void (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask, |
1da177e4 LT |
21 | unsigned char prefixlen, |
22 | const struct fib_nh *nh); | |
23 | void (*mp_alg_remove)(struct rtable *rth); | |
24 | }; | |
25 | ||
26 | extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg); | |
27 | extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg); | |
28 | ||
29 | extern struct ip_mp_alg_ops *ip_mp_alg_table[]; | |
30 | ||
31 | static 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 | ||
47 | static 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 | ||
61 | static inline void multipath_set_nhinfo(struct rtable *rth, | |
d9cd66e0 | 62 | __be32 network, __be32 netmask, |
1da177e4 LT |
63 | 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 | ||
74 | static 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 | ||
85 | static 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 && | |
47dcf0cb | 91 | flp1->mark == flp2->mark && |
1da177e4 LT |
92 | !((flp1->fl4_tos ^ flp2->fl4_tos) & |
93 | (IPTOS_RT_MASK | RTO_ONLINK)); | |
94 | } | |
95 | ||
96 | #endif /* _NET_IP_MP_ALG_H */ |