linux/include/net/ip_mp_alg.h
Thomas Graf 47dcf0cb10 [NET]: Rethink mark field in struct flowi
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>
2006-12-02 21:21:39 -08:00

96 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 */