|
|
1.1 ! root 1: /* ! 2: * INET An implementation of the TCP/IP protocol suite for the LINUX ! 3: * operating system. INET is implemented using the BSD Socket ! 4: * interface as the means of communication with the user level. ! 5: * ! 6: * Definitions for the IP router. ! 7: * ! 8: * Version: @(#)route.h 1.0.4 05/27/93 ! 9: * ! 10: * Authors: Ross Biro, <[email protected]> ! 11: * Fred N. van Kempen, <[email protected]> ! 12: * Fixes: ! 13: * Alan Cox : Reformatted. Added ip_rt_local() ! 14: * Alan Cox : Support for TCP parameters. ! 15: * Alexey Kuznetsov: Major changes for new routing code. ! 16: * ! 17: * FIXME: ! 18: * Modules stuff is broken at the moment. ! 19: * Make atomic ops more generic and hide them in asm/... ! 20: * ! 21: * This program is free software; you can redistribute it and/or ! 22: * modify it under the terms of the GNU General Public License ! 23: * as published by the Free Software Foundation; either version ! 24: * 2 of the License, or (at your option) any later version. ! 25: */ ! 26: #ifndef _ROUTE_H ! 27: #define _ROUTE_H ! 28: ! 29: #include <linux/config.h> ! 30: ! 31: /* ! 32: * 0 - no debugging messages ! 33: * 1 - rare events and bugs situations (default) ! 34: * 2 - trace mode. ! 35: */ ! 36: #define RT_CACHE_DEBUG 1 ! 37: ! 38: #define RT_HASH_DIVISOR 256 ! 39: #define RT_CACHE_SIZE_MAX 256 ! 40: ! 41: #define RTZ_HASH_DIVISOR 256 ! 42: ! 43: #if RT_CACHE_DEBUG >= 2 ! 44: #define RTZ_HASHING_LIMIT 0 ! 45: #else ! 46: #define RTZ_HASHING_LIMIT 16 ! 47: #endif ! 48: ! 49: /* ! 50: * Maximal time to live for unused entry. ! 51: */ ! 52: #define RT_CACHE_TIMEOUT (HZ*300) ! 53: ! 54: /* ! 55: * Prevents LRU trashing, entries considered equivalent, ! 56: * if the difference between last use times is less then this number. ! 57: */ ! 58: #define RT_CACHE_BUBBLE_THRESHOULD (HZ*5) ! 59: ! 60: #include <linux/route.h> ! 61: ! 62: #ifdef __KERNEL__ ! 63: #define RTF_LOCAL 0x8000 ! 64: #endif ! 65: ! 66: /* ! 67: * Semaphores. ! 68: */ ! 69: #if defined(__alpha__) ! 70: ! 71: static __inline__ void ATOMIC_INCR(unsigned int * addr) ! 72: { ! 73: unsigned tmp; ! 74: ! 75: __asm__ __volatile__( ! 76: "1:\n\ ! 77: ldl_l %1,%2\n\ ! 78: addl %1,1,%1\n\ ! 79: stl_c %1,%0\n\ ! 80: beq %1,1b\n" ! 81: : "m=" (*addr), "r=&" (tmp) ! 82: : "m"(*addr)); ! 83: } ! 84: ! 85: static __inline__ void ATOMIC_DECR(unsigned int * addr) ! 86: { ! 87: unsigned tmp; ! 88: ! 89: __asm__ __volatile__( ! 90: "1:\n\ ! 91: ldl_l %1,%2\n\ ! 92: subl %1,1,%1\n\ ! 93: stl_c %1,%0\n\ ! 94: beq %1,1b\n" ! 95: : "m=" (*addr), "r=&" (tmp) ! 96: : "m"(*addr)); ! 97: } ! 98: ! 99: static __inline__ int ATOMIC_DECR_AND_CHECK (unsigned int * addr) ! 100: { ! 101: unsigned tmp; ! 102: int result; ! 103: ! 104: __asm__ __volatile__( ! 105: "1:\n\ ! 106: ldl_l %1,%3\n\ ! 107: subl %1,1,%1\n\ ! 108: mov %1,%2\n\ ! 109: stl_c %1,%0\n\ ! 110: beq %1,1b\n" ! 111: : "m=" (*addr), "r=&" (tmp), "r=&"(result) ! 112: : "m"(*addr)); ! 113: return result; ! 114: } ! 115: ! 116: #elif defined(__i386__) ! 117: #include <asm/bitops.h> ! 118: ! 119: extern __inline__ void ATOMIC_INCR(void * addr) ! 120: { ! 121: __asm__ __volatile__( ! 122: "incl %0" ! 123: :"=m" (ADDR)); ! 124: } ! 125: ! 126: extern __inline__ void ATOMIC_DECR(void * addr) ! 127: { ! 128: __asm__ __volatile__( ! 129: "decl %0" ! 130: :"=m" (ADDR)); ! 131: } ! 132: ! 133: /* ! 134: * It is DECR that is ATOMIC, not CHECK! ! 135: * If you want to do atomic checks, use cli()/sti(). --ANK ! 136: */ ! 137: ! 138: extern __inline__ unsigned long ATOMIC_DECR_AND_CHECK(void * addr) ! 139: { ! 140: unsigned long retval; ! 141: __asm__ __volatile__( ! 142: "decl %0\nmovl %0,%1" ! 143: : "=m" (ADDR), "=r"(retval)); ! 144: return retval; ! 145: } ! 146: ! 147: ! 148: #else ! 149: ! 150: static __inline__ void ATOMIC_INCR(unsigned int * addr) ! 151: { ! 152: (*(__volatile__ unsigned int*)addr)++; ! 153: } ! 154: ! 155: static __inline__ void ATOMIC_DECR(unsigned int * addr) ! 156: { ! 157: (*(__volatile__ unsigned int*)addr)--; ! 158: } ! 159: ! 160: static __inline__ int ATOMIC_DECR_AND_CHECK (unsigned int * addr) ! 161: { ! 162: ATOMIC_DECR(addr); ! 163: return *(volatile unsigned int*)addr; ! 164: } ! 165: ! 166: #endif ! 167: ! 168: ! 169: ! 170: struct rtable ! 171: { ! 172: struct rtable *rt_next; ! 173: __u32 rt_dst; ! 174: __u32 rt_src; ! 175: __u32 rt_gateway; ! 176: unsigned rt_refcnt; ! 177: unsigned rt_use; ! 178: unsigned long rt_window; ! 179: unsigned long rt_lastuse; ! 180: struct hh_cache *rt_hh; ! 181: struct device *rt_dev; ! 182: unsigned short rt_flags; ! 183: unsigned short rt_mtu; ! 184: unsigned short rt_irtt; ! 185: unsigned char rt_tos; ! 186: }; ! 187: ! 188: extern void ip_rt_flush(struct device *dev); ! 189: extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev); ! 190: extern struct rtable *ip_rt_slow_route(__u32 daddr, int local); ! 191: extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy); ! 192: extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy); ! 193: extern int ip_rt_ioctl(unsigned int cmd, void *arg); ! 194: extern int ip_rt_new(struct rtentry *rt); ! 195: extern void ip_rt_check_expire(void); ! 196: extern void ip_rt_advice(struct rtable **rp, int advice); ! 197: ! 198: extern void ip_rt_run_bh(void); ! 199: extern int ip_rt_lock; ! 200: extern unsigned ip_rt_bh_mask; ! 201: extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR]; ! 202: ! 203: extern __inline__ void ip_rt_fast_lock(void) ! 204: { ! 205: ATOMIC_INCR(&ip_rt_lock); ! 206: } ! 207: ! 208: extern __inline__ void ip_rt_fast_unlock(void) ! 209: { ! 210: ATOMIC_DECR(&ip_rt_lock); ! 211: } ! 212: ! 213: extern __inline__ void ip_rt_unlock(void) ! 214: { ! 215: if (!ATOMIC_DECR_AND_CHECK(&ip_rt_lock) && ip_rt_bh_mask) ! 216: ip_rt_run_bh(); ! 217: } ! 218: ! 219: extern __inline__ unsigned ip_rt_hash_code(__u32 addr) ! 220: { ! 221: unsigned tmp = addr + (addr>>16); ! 222: return (tmp + (tmp>>8)) & 0xFF; ! 223: } ! 224: ! 225: ! 226: extern __inline__ void ip_rt_put(struct rtable * rt) ! 227: #ifndef MODULE ! 228: { ! 229: if (rt) ! 230: ATOMIC_DECR(&rt->rt_refcnt); ! 231: } ! 232: #else ! 233: ; ! 234: #endif ! 235: ! 236: #ifdef CONFIG_KERNELD ! 237: extern struct rtable * ip_rt_route(__u32 daddr, int local); ! 238: #else ! 239: extern __inline__ struct rtable * ip_rt_route(__u32 daddr, int local) ! 240: #ifndef MODULE ! 241: { ! 242: struct rtable * rth; ! 243: ! 244: ip_rt_fast_lock(); ! 245: ! 246: for (rth=ip_rt_hash_table[ip_rt_hash_code(daddr)^local]; rth; rth=rth->rt_next) ! 247: { ! 248: if (rth->rt_dst == daddr) ! 249: { ! 250: rth->rt_lastuse = jiffies; ! 251: ATOMIC_INCR(&rth->rt_use); ! 252: ATOMIC_INCR(&rth->rt_refcnt); ! 253: ip_rt_unlock(); ! 254: return rth; ! 255: } ! 256: } ! 257: return ip_rt_slow_route (daddr, local); ! 258: } ! 259: #else ! 260: ; ! 261: #endif ! 262: #endif ! 263: ! 264: extern __inline__ struct rtable * ip_check_route(struct rtable ** rp, ! 265: __u32 daddr, int local) ! 266: { ! 267: struct rtable * rt = *rp; ! 268: ! 269: if (!rt || rt->rt_dst != daddr || !(rt->rt_flags&RTF_UP) ! 270: || ((local==1)^((rt->rt_flags&RTF_LOCAL) != 0))) ! 271: { ! 272: ip_rt_put(rt); ! 273: rt = ip_rt_route(daddr, local); ! 274: *rp = rt; ! 275: } ! 276: return rt; ! 277: } ! 278: ! 279: ! 280: #endif /* _ROUTE_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.