98 lines
		
	
	
	
		
			2.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			98 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)(__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];
 | |
| 
 | |
| 	/* 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,
 | |
| 					__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)
 | |
| 		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 &&
 | |
| #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 */
 | 
