ROUTE(4)

명칭
route - 커널 패킷 전송 데이타베이스

서식
#include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <net/if.h> #include <net/route.h> int socket(PF_ROUTE, SOCK_RAW, int family)

해설
UNIX (은)는 패킷 루팅 장치를 제공합니다. 커널은 루팅 정보 데이타베이스를 관리하고 있습니다. 그리고, 루팅 정보 데이타베이스는, 패킷을 전송 할 때에 적당한 네트워크 인터페이스를 선택하는데 사용됩니다.

유저 프로세스 (혹은 복수의 공동 프로세스)는, 특수한 소켓을 통해 메세지를 보내는 것에 의해 이 데이타베이스를 관리합니다. 이것은, 초기의 릴리스로 사용되고 있던 고정 사이즈의 ioctl(2) 에서의 관리를 대신한 것입니다. routing table의 변경은 슈퍼 유저에 의해서만 행해집니다.

operating system는, 리디렉트를 받았다든가, 요구에 대해서 적당한 경로를 설정하는 것에 실패했다고 하는 것 같은 외부 이벤트에 대한 반응으로서 자발적으로 루팅 메세지를 보낼지도 모릅니다. 이 메세지 타입의 자세한 것은 이하에 기술되고 있습니다.

루팅 데이타베이스의 엔트리는 2 종류로부터 됩니다. 1 개(살)은 특정의 호스트전용, 이제(벌써) 1 개(살)은 (비트 마스크와 마스크 후에 남는 값에 의해 지정된다) 일반적인 서스네트워크 워크내의 모든 호스트전용입니다. 와일드 카드나 디폴트 경로의 효과는, 모든 비트가 0 의 마스크를 사용하는 것에 의해 생깁니다. 그것은 계층적인 경로가 되어 있을지도 모릅니다.

시스템이 기동해 네트워크 인터페이스에 주소를 할당할 수 있을 때, 각 프로토콜 패밀리는, 트래픽에 대해서 준비를 할 수 있던 시점에서 각 인터페이스에 routing table 엔트리를 인스톨 합니다. 통상 프로토콜은, 각 인터페이스를 통해 행선지가 되는 호스트 또는 네트워크에 “직접” 접속하는 것으로서 경로를 지정합니다. 만약 경로가 직접이면, 패킷내에서 지정되어 있는 것과 같은 호스트에 그것이 보내지는 듯 프로토콜 패밀리의 트랜스폴트층이 요구합니다. 그렇지 않으면, 루팅 엔트리에 리스트 된 게이트웨이에 해당 패킷을 보내도록(듯이) 인터페이스가 요구됩니다 (즉, 패킷은 전송 됩니다).

패킷이 루팅 될 때, 커널은 행선지에 가장 명확하게 일치하는 경로를 찾아내려고 시도합니다. (만약 2 개(살)이 다른 마스크가 있어, 마스크를 쓴 후의 값이 일치하고 있는 페어가 있다면, 보다 명확하게 일치한다는 것은 마스크안의 비트가 보다 많이 서 있는 (분)편입니다. 호스트에의 경로는, 행선지안의 비트가 가장 많이 1 이 되어 있다 마스크를 가지고 있다고 보입니다). 엔트리가 발견되지 않으면, 행선지에는 도달 불능이다고 선언되어 이하로 기술되는 경로 제어 소켓상에서 메세지 대기를 하고 있다 리스너가 있으면 routing-miss 메세지가 생성됩니다.

와일드 카드 루팅 엔트리는, 행선지 주소가 0 으로 마스크도 모두 0 으로 지정됩니다. 와일드 카드 경로는, 시스템이 행선지에 일치하는 경로를 찾아내는데 실패했을 때에 사용됩니다. 와일드 카드 경로와 루팅 리디렉트를 조합해 사용하면(자), 루팅에 걸리는 트래픽을 합리적으로 경감할 수 있는 기구를 제공할 수 있습니다.

위의 서식에서 나타나는 소켓 콜을 사용해 경로 제어 메세지를 교환하면(자) 째의 채널을 오픈합니다.

family 파라미터는, 모든 주소 패밀리에 대한 경로 정보를 제공한다 AF_UNSPEC (을)를 취할 수가 있습니다. 혹은, 어느 주소 패밀리를 희망할까 지정하는 것에 의해 특정의 주소 패밀리인 만큼 한정할 수도 있습니다. 1 개의 시스템으로 1 개 이상의 루팅 소켓을 오픈할 수가 있습니다.

메세지는 헤더와 거기에 계속되는 몇개의 sockaddr (특히 ISO 의 경우, 가변장)에 의해 구성되어 위치에 의해 해석되어 sockaddr 의 새로운 length 엔트리에 의해 단락지어집니다. 예를 들면, 4 개의 주소를 가진 메세지는 ISO 리디렉트일지도 모릅니다. 즉 행선지, 넷 마스크, 게이트웨이, 리디렉트의 저자입니다. 어느 주소가 나타내지고 있을까의 해석은 헤더내의 비트 마스크로 주어집니다. 순서는, vector 내의 최하정도 비트로부터 최상정도 비트에의 순서가 됩니다.

커널에 보내지는 메세지는 모두 돌려주어 메세지 대기를 하고 있는 모든 리스너에는 그 카피가 보내집니다. 커널은 메세지를 보내는 프로세스의 프로세스 ID 를 제공합니다. 그리고, 메세지를 보내는 프로세스는, 미해결의 메세지끼리를 구별하기 위한 부가 identification sequence field를 이용할지도 모릅니다. 그러나, 커널 버퍼가 가득하다라고 메세지의 대답은 없어질지도 모릅니다.

커널은 특정의 메세지를 거부해, rtm_errno 필드를 묻는 것에 의해 그것을 나타냅니다. 루팅 코드는, 만약 벌써 존재하는 엔트리를 복사하려고 하면(자) EEXIST (을)를, 존재하지 않는 엔트리를 삭제하려고 하면(자) ESRCH (을)를, 새로운 경로를 도입하기 위해서 필요한 자원이 부족한 경우는 ENOBUFS (을)를 돌려줍니다. 현재의 실장에서는, 모든 루팅 프로세스는 로컬로 동작해 있으므로, 루팅 대답 메세지가 없어졌다고 해도 rtm_errno 의 값은, 통상의 errno 기구로부터 입수 가능합니다.

프로세스는, SOL_SOCKET 레벨에서의 SO_USELOOPBACK 옵션을 오프로 하는 것을 나타낸다 setsockopt(2) 콜을 발행하는 것으로, 자기 자신의 메세지에 대한 대답을 읽는 부하를 회피할 수가 있습니다. 프로세스는 더욱 shutdown(2) 시스템 콜을 행하는 것에 의해 루팅 소켓으로부터의 모든 메세지를 무시할 수가 있습니다.

만약 경로가 사용중에 삭제되면(자), 그 루팅 엔트리에는 다운과 마크 되어 경로표로부터 제외해집니다. 그러나 거기에 관련 지을 수 있었던 자원은, 경로에의 참조가 모두 해방될 때까지 반환되지 않습니다. 유저 프로세스는, RTM_GET 메세지를 사용하는지, /dev/kmem 디바이스를 읽든가, 혹은 getkerninfo(2) 시스템 콜을 발행하는 것에 의해 특정의 행선지에의 루팅 엔트리에 관한 정보를 취득하는 것이 할 수 있습니다.

메세지는 다음의 것을 포함하고 있습니다:

    #define	RTM_ADD		0x1    /* 경로 추가 */
    #define	RTM_DELETE	0x2    /* 경로 삭제 */
    #define	RTM_CHANGE	0x3    /* 시학이나 플래그나 게이트웨이를 변경 */
    #define	RTM_GET		0x4    /* 정보 보고 */
    #define	RTM_LOOSING	0x5    /* 커널은 partitioning 를 의심하고 있다 */
    #define	RTM_REDIRECT	0x6    /* 별의 경로를 사용하도록(듯이) 말한다 */
    #define	RTM_MISS	0x7    /* 주소 조합에 실패했다 */
    #define	RTM_RESOLVE	0xb    /* 행선지를 LL addr 에 해결하는 요구 */

1 개의 메세지헤더는 이하로부터 완성됩니다:

    struct rt_msghdr {
        u_short rmt_msglen;  /* 모르는 메세지를 스킵 하기 위한(해) */
        u_char  rtm_version; /* 장래의 binary level compatibility성 */
        u_char  rtm_type;    /* 메세지 타입 */
        u_short rmt_index;   /* 관련이 있는 ifp 의 인덱스 */
        int     rtm_flags;   /* 플래그, incl kern & message, 예를 들면 DONE */
        int     rtm_addrs;   /* msg 중의 sockaddr 를 식별하는 비트 마스크 */
        pid_t   rmt_pid;     /* 송신자를 식별한다 */
        int     rtm_seq;     /* 송신자에 대해서 동작을 식별한다 */
        int     rtm_errno;   /* 왜 실패했는지 */
        int     rtm_use;     /* rtentry 로부터 */
        u_long  rtm_inits;   /* 어느 값을 초기화할까 */
        struct  rt_metrics rtm_rmx;	/* 시학 자신 */
    };

여기서 “struct rt_metrics” 및 flag bit는 rtentry(9) 그리고 정의되고 있습니다.

rms_locks 와 rms_inits 의 시학치의 지정자는 다음과 같습니다:

    #define	RTV_SSTHRESH  0x1    /* _ssthresh 의 초기화 혹은 락 */
    #define	RTV_RPIPE     0x2    /* _recvpipe 의 초기화 혹은 락 */
    #define	RTV_SPIPE     0x4    /* _sendpipe 의 초기화 혹은 락 */
    #define	RTV_HOPCOUNT  0x8    /* _hopcount 의 초기화 혹은 락 */
    #define	RTV_RTT       0x10   /* _rtt 의 초기화 혹은 락 */
    #define	RTV_RTTVAR    0x20   /* _rttvar 의 초기화 혹은 락 */
    #define	RTV_MTU       0x40   /* _mtu 의 초기화 혹은 락 */

메세지중에서 어느 주소가 건네받았는지의 지정자는 다음과 같습니다:

    #define RTA_DST       0x1    /* 행선지 sockaddr 가 건네받았다 */
    #define RTA_GATEWAY   0x2    /* 게이트웨이 sockaddr 가 건네받았다 */
    #define RTA_NETMASK   0x4    /* 넷 마스크 sockaddr 가 건네받았다 */
    #define RTA_GENMASK   0x8    /* 클로닝 sockaddr 가 건네받았다 */
    #define RTA_IFP       0x10   /* 인터페이스명 sockaddr 가 건네받았다 */
    #define RTA_IFA       0x20   /* 인터페이스 주소 sockaddr 가 건네받았다 */
    #define RTA_AUTHOR    0x40   /* 리디렉트의 저자의 sockaddr */

관련 항목
route(8), rtentry(9)

역사
PF_ROUTE 프로토콜 패밀리는 4.3BSD reno 그리고 최초로 나타났습니다.