10.2 Implementing ATM in Linux

   


Figure 10-2 shows how the ATM support is structured in the Linux kernel. This implementation comprises two major parts:

  • Extension of the socket interface to support the ATM protocol. We will not further discuss this part in this chapter, because the socket interface will be described in detail in Chapters 26 and 27.

  • General ATM support within the operating system kernel. Various additional functions are available, depending on whether a connection is a permanent or a signaled virtual connection. This part will be described in detail below.

  • Support of various ATM network cards. Again, this is divided into a general part, which is independent of the type of hardware used, and a part that includes the driver for the respective network card and some support functions.

Figure 10-2. Structure of the ATM support in the Linux kernel.

graphics/10fig02.gif


The following sections begin with a description of the data transmission over a permanent virtual channel (PVC). Subsequently, we describe how the signaled virtual channel (SVC) is supported in the Linux kernel.

10.2.1 Permanent Virtual Channels

An application accesses a permanent virtual channel (PVC) over a socket. A PVC socket can take any of four states; closed, created, connected, and connecting (as shown in Figure 10-3).

Figure 10-3. State transition diagram when opening a socket for a permanent virtual channel.

graphics/10fig03.gif


First, an application creates a socket. When an application creates a socket, the following functions in the kernel are addressed:

pvc_create()

net/atm/pvc.c


In this function, the operations that belong to the protocol family PF_ATMPVC and should be available over the socket are announced. This is done by the allocation sock->ops = &pvc_proto_ops;. Subsequently, atm_create(sock,protocol, PF_ATMPVC) is used to create a new socket.

atm_create()

net/atm/common.c


This function handles a number of memory reservations and initializations required for an ATM socket. In particular, it initializes the structure atm_vcc specified in include/linux/atmdev.h. The following code fragment was taken from this structure:

 struct atm_vcc {        atm_vcc_flags_t flags;          /* VCC flags (ATM_VF_*) */        unsigned char   family;         /* address family; 0 if unused */        short           vpi;            /* VPI and VCI (types must be */        int             vci;            /* equal with sockaddr) */        unsigned long   aal_options;    /* AAL layer options */        unsigned long   atm_options;    /* ATM layer options */        struct atm_dev  *dev;           /* device back pointer */        struct atm_qos  qos;            /* QOS */        atomic_t        tx_inuse,rx_inuse; /* buffer space in use */        void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);        void (*pop)(struct atm_vcc *vcc, struct sk_buff *skb); /* optional */        struct sk_buff *(*alloc_tx)(struct atm_vcc *vcc,unsigned int size);                                        /* TX allocation routine can be */                                        /* modified by protocol or by                                        /* driver. NOTE: */                                        /* this interface will change */        int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);        void            *dev_data;      /* per-device data */        void            *proto_data;    /* per-protocol data */        struct timeval  timestamp;      /* AAL timestamps */        struct sk_buff_head recvq;      /* receive queue */        struct k_atm_aal_stats *stats;  /* pointer to AAL stats group */        wait_queue_head_t sleep;        /* if socket is busy */        struct sock     *sk;            /* socket backpointer */        struct atm_vcc  *prev,*next; }; 

Most entries in this structure are set to null when they are created (e.g., the values for VPI and VCI, the atm_options, and the aal_options).

In the next step, the application can specify QoS parameters for the socket previously created. To this end, an application calls setsockopt() and uses the options SOL_ATM and SO_ATMQOS.

atm_do_setsockopt()

net/atm/common.c


In the function atm_do_setsockopt(), the values specified by the application are entered in the structure struct atm_qos (from include/linux/atm.h) contained in the structure atm_vcc. The structure atm_qos includes two additional structures and one value:

 struct atm_qos {        struct atm_trafprm txtp;          /* parameters in TX direction */        struct atm_trafprm rxtp;          /* parameters in RX direction */        unsigned char aal; }; 

The structure atm_trafprm (also from include/linux/atm.h) is used to specify traffic parameters for the ATM connection. This structure includes the following entries:

 struct atm_trafprm {        unsigned char  traffic_class;  /* traffic class (ATM_UBR, ...) */        int            max_pcr;        /* maximum PCR in cells per second */        int            pcr;            /* desired PCR in cells per second */        int            min_pcr;        /* minimum PCR in cells per second */        int            max_cdv;        /* maximum CDV in microseconds */        int            max_sdu;        /* maximum SDU in bytes */        ...        /* A number of parameters for the ABR service class follows here. */ }; 

The parameter traffic_class can take the following values, which are defined in include/linux/atm.h: ATM_NONE (no traffic class specified), ATM_UBR (UBR Unspecified Bit Rate), ATM_CBR (CBR Constant Bit Rate), ATM_VBR (VBR Variable Bit Rate), ATM_ABR (ABR Available Bit Rate), and ATM_ANYCLASS (any traffic class).

The function atm_do_setsockopt() is used to run a few checks on the socket status. Subsequently, the function check_qos() is invoked.

check_qos()

net/atm/common.c


This function merely checks on whether the parameters of the transmit and receive directions are identical or are specified for one direction only (different parameters are currently not supported); subsequently, the function check_tp() is invoked.

check_tp()

net/atm/common.c


This function is used to check a few combinations of QoS parameters with regard to their admissibility. If these checks run successfully, then the function atm_do_setsockopt() invokes the function atm_change_qos(), which uses the function adjust_tp() to run further checks. For a PVC, vcc->dev->ops->change_qos() is used to invoke the function supplied by the driver to change QoS parameters. For an SVC, the function svc_change_qos() defined in net/atm/svc.c is called to change QoS parameters.

pvc_bind()

net/atm/pvc.c


Next, the function pvc_bind() is invoked when the application wants to open the socket to send or receive data. The implementation does not distinguish between the socket calls bind() and connect(). The function pvc_bind() is used to initialize the address structure struct sockaddr_atmpvc, which is used for PVC only. The other functions are located in the file net/atm/common.c, because they are used both for PVC and for SVC.

atm_connect(), atm_connect_vcc(),

net/atm/common.c

atm_do_connect(), atm_do_connect_dev()

 


These functions are used in the order shown here. First, atm_connect() checks the socket status. Next, the function atm_do_connect() or the function atm_do_connect_dev() is invoked, depending on whether a network interface was specified. If no network interface was specified, then atm_do_connect() is invoked, and the function atm_find_dev() available in net/atm/resources.h is used to search the list of ATM network cards for an interface with the matching identifier. If this search is successful, then the open() function supplied by the driver (over dev->ops->open()) is invoked, much as for the function atm_do_connect_dev().

atm_sendmsg()

net/atm/common.c


The transmission of data is identical over PVC and SVC, so this functionality is maintained in the file net/atm/common.c. First, the function atm_sendmsg() waits for a transmission possibility; next, the transmit data are sent by the driver-specific transmit routine, which is addressed over vcc->dev->ops->send().

atm_recvmsg()

net/atm/common.c


Like the function atm_sendmsg(), the function atm_recvmsg() is used for both PVC and SVC connections. The function waits in a loop for incoming data, which is then copied from the socket buffer into the user space by the function copy_to_user().

atm_release(), atm_release_vcc_sk()

net/atm/common.c


We mention the function for orderly release of an ATM socket for the sake of completeness. This is done by the two functions, atm_release() and atm_release_vcc_sk(), which eventually use the close() function supplied by the driver to release all pertinent resources in the driver.

10.2.2 Signaled Virtual Channels

As with PPPoE, a large part of the connection management for the support of signaled virtual channels was moved into a daemon in the user space, as shown in Figure 10-4.

Figure 10-4. SVC support in Linux.

graphics/10fig04.gif


Requests to establish or tear down connections and other tasks pertaining to connection management are handled by the signaling daemon, atmsigd. More specifically, all corresponding requests, which can originate both from applications and from the network, are forwarded to the signaling daemon. Requests are put asynchronously into a message queue, from which the signaling daemon fetches messages. In most cases, the kernel performs a synchronous (i.e., blocking) wait for the daemon's response.

Many of the functions available in the file net/atm/svc.c correspond to the previously introduced functions in net/atm/pvc.c, so we will not describe them here in detail. For example, as with the function pvc_create(), the function svc_create() is initially used to announce operations that belong to the protocol family PF_ATMSVC and should be made available over the socket. Subsequently, atm_create(sock, protocol, PF_ATMSVC) creates a new socket.

svc_bind()

net/atm/svc.c


The function svc_bind(), which is normally invoked at this point of the procedure, serves as an example for the communication between the kernel and the signaling daemon. The following code fragment was taken from the source code:

 ... sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local); add_wait_queue(&vcc->sleep,&wait); while (vcc->reply == WAITING && sigd) {        set_current_state(TASK_UNINTERRUPTIBLE);        schedule(); } remove_wait_queue(&vcc->sleep,&wait); ... return vcc->reply; 

First, the function sigd_enq() for the input queue of the signaling daemon, defined in net/atm/signaling.c, is passed the message type as_bind, together with a pointer to the structure atm_vcc, which belongs to the connection. Subsequently, the relevant process remains in the TASK_UNINTERRUPTIBLE state until the signaling daemon has fetched the message from the input queue and changed the field vcc->reply from WAITING to another value (say, 0 when the action was successful). This value is returned to the function svc_bind().

The full set of messages that can be exchanged between the kernel and the signaling daemon is specified in the atmsvc_msg_type structure, stored in the file include/linux/atmsvc.h:

 enum atmsvc_msg_type {        as_catch_null,as_bind,as_connect,as_accept,as_reject,        as_listen,as_okay,as_error,as_indicate,as_close,as_itf_notify,        as_modify,as_identify,as_terminate }; 

The following message types are used for connection control:

  • as_okay

    The signaling daemon acknowledges a previous message.

  • as_error

    The signaling daemon reports an error.

  • as_close

    The kernel informs the daemon that a connection is to be closed.

  • as_bind

    The kernel sends this message to obtain a local address.

  • as_connect

    The kernel sends a request to establish a connection to the signaling daemon.

  • as_listen

    The kernel uses this message to notify that an endpoint was opened, where it will wait for a connection-establishment request.

  • as_indicate

    The kernel informs the signaling daemon that a connection-establishment request has arrived.

  • as_accept

    The kernel notifies the signaling daemon that it wants to accept a connection.

  • as_reject

    The kernel informs the signaling daemon that an incoming connection-establishment request was rejected.

The parameters for these message types are specified in the structure atmsvc_msg in the file include/linux/atmsvc.h. They include addresses and QoS parameters for SVC connections.

10.2.3 ATM Device Drivers

In contrast to Ethernet network cards, ATM network cards handle a large part of the protocol-processing work themselves. Normally, an ATM network card is responsible not only for forming ATM cells, but also for composing these cells into protocol data units for the higher ATM adaptation layer (AAL). This means that the operating system is relieved from these tasks. On the other hand, it means that ATM network cards are more expensive, because the hardware is more costly.

For ATM device drivers, we distinguish between one part that manages the physical layer (PHY driver) and another part that reserves resources and coordinates the protocol and hardware.

The structure atm_dev (in include/linux/atmdev.h) groups device-independent parameters:

 struct atm_dev {        const struct atmdev_ops *ops;  /* device operations; NULL if unused */        const struct atmphy_ops *phy;  /* PHY operations, may be undefined */                                       /* (NULL) */        const char      *type;         /* device type name */        int             number;        /* device index */        struct atm_vcc  *vccs;         /* VCC table (or NULL) */        struct atm_vcc  *last;         /* last VCC (or undefined) */        void            *dev_data;     /* per-device data */        void            *phy_data;     /* private PHY date */        atm_dev_flags_t flags;         /* device flags (ATM_DF_*) */        struct atm_dev_addr  *local;   /* local ATM addresses */        unsigned char   esi[ESI_LEN];  /* ESI ("MAC" addr) */        struct atm_cirange ci_range;   /* VPI/VCI range */        struct k_atm_dev_stats stats;  /* statistics */        char            signal;        /* signal status (ATM_PHY_SIG_*) */        int             link_rate;     /* link rate (default: OC3) */ #ifdef CONFIG_PROC_FS        struct proc_dir_entry *proc_entry; /* proc entry */        char *proc_name;              /* proc entry name */ #endif        struct atm_dev  *prev,*next;  /* linkage */ }; 

These structures are linked in a list by the pointers prev and next. The structure serves as an interface between the kernel and the driver; this is where all parameters required by the driver for further protocol handling are made available, plus those that the driver must make available to the kernel (e.g., the MAC address of the ATM card). The entries vccs and last are used to manage a list of descriptors for virtual connections, which are known to the ATM network card. The first two elements of the structure atm_dev point to the driver operations supplied by the driver over the structure atmdev_ops and to the PHY driver operations, which are available from the structure atmphy_ops. (Both structures are also defined in include/linux/atmdev.h.)

The most important operations available from the structure atmdev_ops are the following:

  • open() reserves resources on the hardware for a new virtual connection; the VPI and the VCI for the connection are passed to the driver.

  • The function ioctl() is used to pass ioctl() commands to the driver. If the driver does not know these commands, then it forwards them to the PHY driver.

  • The function send() passes data units for transmission.

  • The function phy_put() and phy_get() are used by the PHY driver to write a byte to or read one from a hardware register of the network card.

10.2.4 Further ATM Support

The support of "pure" ATM described above (i.e., the support of applications that access ATM sockets directly) was extended by the support of protocols, which convert IP packets to ATM, in a very early stage.

This support includes the following protocols:

  • Classical IP: Classical IP [Laub94] is the simplest from for transporting IP data traffic over ATM networks. The functions included in net/atm/clip.c are used to support Classical IP.

  • LAN Emulation: The LAN Emulation [Foru95] represents a second approach to IP over ATM, which, in contrast to Classical IP, uses signaled virtual connections rather than permanent virtual connections. The Linux kernel includes functions for this emulation in the file net/atm/lec.c.

  • MPOA: The abbreviation "MPOA" [Hein93] stands for "Multiple Protocols over ATM" and represents a more recent approach for the support of IP over ATM. The Linux kernel includes functions for MPOA in the files net/atm/mpc.c, mpoa_caches.c, and net/atm/mpoa_proc.c for corresponding entries in the proc directory.

The functions used by all of these approaches are grouped in net/atm/ ipcommon.c.


       


    Linux Network Architecture
    Linux Network Architecture
    ISBN: 131777203
    EAN: N/A
    Year: 2004
    Pages: 187

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net