Changeset 1600

Show
Ignore:
Timestamp:
11/05/08 13:59:34 (2 months ago)
Author:
peet
Message:

threaded code from get_route.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/0.4.7/lib/cxnet/cxnet/netlink/util.py

    r1354 r1600  
    2222 
    2323from cxnet.netlink.rtnl import * 
    24 from cxutil.ip import * 
     24from cxnet.common import hprint 
     25from cxnet.utils import * 
    2526from ctypes import * 
    26 from socket import htonl 
    27 from cxnet.common import hprint 
    28  
    29  
    30 def get_route(addr=None,mask=0,table=254,debug=False): 
    31         """ 
    32         Get route by host address 
    33         """ 
    34         socket = rtnl_socket() 
    35         parser = rtnl_msg_parser() 
    36         result = [] 
    37         end = False 
     27# import socket as _s 
     28 
     29from threading import Thread, Lock 
     30from Queue import Queue 
     31 
     32 
     33class py_iproute2(Thread): 
    3834         
    39         if addr and not mask: 
    40                 mask = 32 
    41  
    42         h = nlmsghdr() 
    43         h.type = RTM_GETROUTE 
    44         h.flags = NLM_F_REQUEST 
    45  
    46         _p = rtmsg() 
    47         _p.family = 2 
    48         _p.table = table 
    49         _p.dst_len = mask 
    50         _p.type = RTN_UNICAST 
    51          
    52         p = rtnl_payload() 
    53         p.route = _p 
    54  
    55         msgx = rtnl_msg() 
    56         msgx.hdr = h 
    57         msgx.data = p 
    58  
    59         if addr: 
    60                 ptr = addressof(msgx) + sizeof(nlmsghdr) + sizeof(rtmsg) 
    61                 a = t_attr() 
    62                 ptr = a.set(ptr,RTA_DST,c_uint32(htonl(dqn_to_int(addr)))) 
    63                 ptr = a.set(ptr,RTA_TABLE,c_uint32(table)) 
    64  
    65         if debug: 
    66                 print("send:") 
    67                 hprint(msgx,ptr - addressof(msgx)) 
    68  
    69         socket.send(msgx,ptr - addressof(msgx)) 
    70  
    71  
    72         while not end: 
    73                 bias = 0 
    74                 (l,msgx) = socket.recv() 
    75          
    76                 while l >= 0: 
    77                         x = rtnl_msg.from_address(addressof(msgx) + bias) 
    78                         if debug and (x.hdr.length > 0): 
    79                                 print("receive:") 
    80                                 hprint(x, x.hdr.length) 
    81                         bias += x.hdr.length 
    82                         l -= bias 
    83                         if (x.hdr.length == 0) or (x.hdr.type <= NLMSG_DONE): 
    84                                 end = True 
    85                                 break 
    86  
    87                         result.append(parser.parse(x)) 
    88  
    89         socket.close() 
    90  
    91         return result 
     35        def __init__(self): 
     36                Thread.__init__(self) 
     37                self.setName("RT network subsystem interface") 
     38                self.setDaemon(True) 
     39                self.listeners = { 
     40                        0:      Queue(), 
     41                } 
     42                self.socket = rtnl_socket(groups = RTNLGRP_IPV4_IFADDR | RTNLGRP_IPV4_ROUTE | RTNLGRP_LINK | RTNLGRP_NEIGH) 
     43                self.parser = rtnl_msg_parser() 
     44                self.nonceLock = Lock() 
     45                self.__nonce = 1 
     46                self.__shutdown = False 
     47                self.start() 
     48 
     49        def nonce(self): 
     50 
     51                self.nonceLock.acquire() 
     52                if self.__nonce == 0xffffffff: 
     53                        self.__nonce = 1 
     54                else: 
     55                        self.__nonce += 1 
     56                self.nonceLock.release() 
     57 
     58                return self.__nonce 
     59 
     60        def status(self,key=0): 
     61                assert self.listeners.has_key(key) 
     62 
     63                return self.listeners[key].qsize() 
     64 
     65        def get(self,key=0): 
     66                assert self.listeners.has_key(key) 
     67 
     68                end = False 
     69                result = [] 
     70                while not end: 
     71                        bias = 0 
     72 
     73                        if self.listeners[key].empty(): 
     74                                assert not self.__shutdown 
     75 
     76                        (l,msg) = self.listeners[key].get() 
     77                        while l > 0: 
     78                                x = rtnl_msg.from_address(addressof(msg) + bias) 
     79                                bias += x.hdr.length 
     80                                l -= x.hdr.length 
     81                                parsed = self.parser.parse(x) 
     82                                result.append(parsed) 
     83                                if not ((x.hdr.type > NLMSG_DONE) and (x.hdr.flags & NLM_F_MULTI)): 
     84                                        end = True 
     85                                        break 
     86                return result 
     87 
     88        def stop(self): 
     89                self.__shutdown = True 
     90 
     91        def run(self): 
     92                while not self.__shutdown: 
     93 
     94                        (l,msg) = self.socket.recv() 
     95                        if msg.hdr.sequence_number in self.listeners.keys(): 
     96                                key = msg.hdr.sequence_number 
     97                        else: 
     98                                key = 0 
     99 
     100                        ### 
     101                        # 
     102                        # Enqueue message into appropriate decoder queue 
     103                        # 
     104                        ### 
     105 
     106                        self.listeners[key].put((l,msg)) 
     107 
     108        def queryNL(self,msg,size=None): 
     109                key = self.nonce() 
     110                self.listeners[key] = Queue() 
     111                msg.hdr.sequence_number = key 
     112                self.socket.send(msg,size) 
     113                ret = self.get(key) 
     114                del self.listeners[key] 
     115                return ret 
     116 
     117 
     118        def getAllNeigh(self): 
     119                msg = rtnl_msg() 
     120                msg.hdr.type = RTM_GETNEIGH 
     121                msg.hdr.flags = NLM_F_DUMP | NLM_F_REQUEST 
     122                msg.data.neigh.family = 2 
     123                ptr = addressof(msg) + sizeof(nlmsghdr) + sizeof(ndmsg) 
     124                return self.queryNL(msg,ptr - addressof(msg)) 
     125 
     126        def getNeigh(self,addr=None): 
     127                if addr is None: 
     128                        return self.getAllNeigh() 
     129                for i in self.getAllNeigh(): 
     130                        if i.has_key("dest"): 
     131                                if i["dest"] == addr: 
     132                                        return i 
     133 
     134                # no direct entries in the arp cache 
     135                ret = self.getRoute(addr)[0] 
     136                if ret.has_key("gateway"): 
     137                        return self.getNeigh(ret["gateway"]) 
     138 
     139                return None 
     140 
     141 
     142        def getAllRoute(self): 
     143                msg = rtnl_msg() 
     144                msg.hdr.type = RTM_GETROUTE 
     145                msg.hdr.flags = NLM_F_DUMP | NLM_F_REQUEST 
     146                msg.data.route.family = 2 
     147                msg.data.route.table = 254 
     148                ptr = addressof(msg.data) + sizeof(msg.data.route) 
     149                return self.queryNL(msg,ptr - addressof(msg)) 
     150 
     151        def getRoute(self,addr=None): 
     152                if not addr: 
     153                        return self.getAllRoute() 
     154 
     155                ### 
     156                # 
     157                # it's unsafe for now 
     158                # 
     159                ### 
     160 
     161                #msg = rtnl_msg() 
     162                #msg.hdr.type = RTM_GETROUTE 
     163                #msg.hdr.flags = NLM_F_REQUEST 
     164                #msg.data.route.family = 2 
     165                #msg.data.route.table = 254 
     166                #msg.data.route.dst_len = 32 
     167                #msg.data.route.type = RTN_UNICAST 
     168                #a = t_attr() 
     169                #ptr = addressof(msg.data) + sizeof(msg.data.route) 
     170                #ptr = a.set(ptr,RTA_DST,c_uint32(_s.htonl(dqn_to_int(addr)))) 
     171                #ptr = a.set(ptr,RTA_TABLE,c_uint32(254)) 
     172 
     173                #ret = self.queryNL(msg,ptr - addressof(msg)) 
     174 
     175                ret = self.getAllRoute() 
     176                result = {} 
     177                dst = dqn_to_int(addr) 
     178                for i in ret: 
     179                        if i.has_key('dst_prefix') and i.has_key('dst_len'): 
     180                                if dqn_to_int(i['dst_prefix']) == ((((1 << i['dst_len']) - 1) << (32 - i['dst_len'])) & dst): 
     181                                        result['static'] = i 
     182                        elif i.has_key('dst_len') and i.has_key('src_len'): 
     183                                if i['dst_len'] == 0 and i['src_len'] == 0: 
     184                                        result['default'] = i 
     185                                         
     186                if result.has_key('static'): 
     187                        ret = [result['static'],] 
     188                elif result.has_key('default'): 
     189                        ret = [result['default'],] 
     190                else: 
     191                        ret = [] 
     192                return ret 
     193 
     194 
     195        def getLink(self,num=None): 
     196                if isinstance(num,int): 
     197                        key = "index" 
     198                elif isinstance(num,str): 
     199                        key = "dev" 
     200                else: 
     201                        return self.getAllLink() 
     202                for i in self.getAllLink(): 
     203                        if i[key] == num: 
     204                                return i 
     205 
     206        def getAllLink(self): 
     207                msg = rtnl_msg() 
     208                msg.hdr.type = RTM_GETLINK 
     209                msg.hdr.flags = NLM_F_DUMP | NLM_F_REQUEST 
     210                return self.queryNL(msg) 
     211 
     212        def getAddr(self,link=None,addr=None): 
     213                ret = self.getAllAddr() 
     214                if addr is None and link is None: 
     215                        return ret 
     216                result = [] 
     217                for i in ret: 
     218                        if i.has_key('dev'): 
     219                                if i['dev'] == link: 
     220                                        result.append(i) 
     221                        elif i.has_key('address'): 
     222                                if i['address'] == addr: 
     223                                        result.append(i) 
     224                return result 
     225 
     226        def getAllAddr(self): 
     227                msg = rtnl_msg() 
     228                msg.hdr.type = RTM_GETADDR 
     229                msg.hdr.flags = NLM_F_DUMP | NLM_F_REQUEST 
     230                return self.queryNL(msg)