forked from Minki/linux
47dcf0cb10
Now that all protocols have been made aware of the mark field it can be moved out of the union thus simplyfing its usage. The config options in the IPv4/IPv6/DECnet subsystems to enable respectively disable mark based routing only obfuscate the code with ifdefs, the cost for the additional comparison in the flow key is insignificant, and most distributions have all these options enabled by default anyway. Therefore it makes sense to remove the config options and enable mark based routing by default. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
97 lines
2.5 KiB
C
97 lines
2.5 KiB
C
/* 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/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)(__be32 network, __be32 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];
|
|
|
|
/* mp_alg_select_route _MUST_ be implemented */
|
|
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)
|
|
ops->mp_alg_flush();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static inline void multipath_set_nhinfo(struct rtable *rth,
|
|
__be32 network, __be32 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)
|
|
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 && ops->mp_alg_remove &&
|
|
(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 &&
|
|
flp1->mark == flp2->mark &&
|
|
!((flp1->fl4_tos ^ flp2->fl4_tos) &
|
|
(IPTOS_RT_MASK | RTO_ONLINK));
|
|
}
|
|
|
|
#endif /* _NET_IP_MP_ALG_H */
|