1Description of the "concap" encapsulation protocol interface
   4The "concap" interface is intended to be used by network device
   5drivers that need to process an encapsulation protocol. 
   6It is assumed that the protocol interacts with a linux network device by
   7- data transmission
   8- connection control (establish, release)
   9Thus, the mnemonic: "CONnection CONtrolling eNCAPsulation Protocol".
  11This is currently only used inside the isdn subsystem. But it might
  12also be useful to other kinds of network devices. Thus, if you want
  13to suggest changes that improve usability or performance of the
  14interface, please let me know. I'm willing to include them in future
  15releases (even if I needed to adapt the current isdn code to the
  16changed interface).
  19Why is this useful?
  22The encapsulation protocol used on top of WAN connections or permanent
  23point-to-point links are frequently chosen upon bilateral agreement.
  24Thus, a device driver for a certain type of hardware must support
  25several different encapsulation protocols at once.
  27The isdn device driver did already support several different
  28encapsulation protocols. The encapsulation protocol is configured by a
  29user space utility (isdnctrl). The isdn network interface code then
  30uses several case statements which select appropriate actions
  31depending on the currently configured encapsulation protocol.
  33In contrast, LAN network interfaces always used a single encapsulation
  34protocol which is unique to the hardware type of the interface. The LAN
  35encapsulation is usually done by just sticking a header on the data. Thus,
  36traditional linux network device drivers used to process the
  37encapsulation protocol directly (usually by just providing a hard_header()
  38method in the device structure) using some hardware type specific support
  39functions. This is simple, direct and efficient. But it doesn't fit all
  40the requirements for complex WAN encapsulations. 
  43   The configurability of the encapsulation protocol to be used
  44   makes isdn network interfaces more flexible, but also much more
  45   complex than traditional lan network interfaces.
  48Many Encapsulation protocols used on top of WAN connections will not just
  49stick a header on the data. They also might need to set up or release
  50the WAN connection. They also might want to send other data for their
  51private purpose over the wire, e.g. ppp does a lot of link level
  52negotiation before the first piece of user data can be transmitted.
  53Such encapsulation protocols for WAN devices are typically more complex
  54than encapsulation protocols for lan devices. Thus, network interface
  55code for typical WAN devices also tends to be more complex.
  58In order to support Linux' x25 PLP implementation on top of
  59isdn network interfaces I could have introduced yet another branch to
  60the various case statements inside drivers/isdn/isdn_net.c.
  61This eventually made isdn_net.c even more complex. In addition, it made
  62isdn_net.c harder to maintain. Thus, by identifying an abstract
  63interface between the network interface code and the encapsulation
  64protocol, complexity could be reduced and maintainability could be
  68Likewise, a similar encapsulation protocol will frequently be needed by
  69several different interfaces of even different hardware type, e.g. the
  70synchronous ppp implementation used by the isdn driver and the
  71asynchronous ppp implementation used by the ppp driver have a lot of
  72similar code in them. By cleanly separating the encapsulation protocol
  73from the hardware specific interface stuff such code could be shared
  74better in future.
  77When operating over dial-up-connections (e.g. telephone lines via modem,
  78non-permanent virtual circuits of wide area networks, ISDN) many
  79encapsulation protocols will need to control the connection. Therefore,
  80some basic connection control primitives are supported. The type and
  81semantics of the connection (i.e the ISO layer where connection service
  82is provided) is outside our scope and might be different depending on
  83the encapsulation protocol used, e.g. for a ppp module using our service
  84on top of a modem connection a connect_request will result in dialing
  85a (somewhere else configured) remote phone number. For an X25-interface
  86module (LAPB semantics, as defined in Documentation/networking/x25-iface.txt)
  87a connect_request will ask for establishing a reliable lapb
  88datalink connection.
  91The encapsulation protocol currently provides the following
  92service primitives to the network device.
  94- create a new encapsulation protocol instance
  95- delete encapsulation protocol instance and free all its resources
  96- initialize (open) the encapsulation protocol instance for use.
  97- deactivate (close) an encapsulation protocol instance.
  98- process (xmit) data handed down by upper protocol layer
  99- receive data from lower (hardware) layer
 100- process connect indication from lower (hardware) layer
 101- process disconnect indication from lower (hardware) layer
 104The network interface driver accesses those primitives via callbacks
 105provided by the encapsulation protocol instance within a
 106struct concap_proto_ops.
 108struct concap_proto_ops{
 110        /* create a new encapsulation protocol instance of same type */
 111        struct concap_proto *  (*proto_new) (void);
 113        /* delete encapsulation protocol instance and free all its resources.
 114           cprot may no longer be referenced after calling this */
 115        void (*proto_del)(struct concap_proto *cprot);
 117        /* initialize the protocol's data. To be called at interface startup
 118           or when the device driver resets the interface. All services of the
 119           encapsulation protocol may be used after this*/
 120        int (*restart)(struct concap_proto *cprot, 
 121                       struct net_device *ndev,
 122                       struct concap_device_ops *dops);
 124        /* deactivate an encapsulation protocol instance. The encapsulation
 125           protocol may not call any *dops methods after this. */
 126        int (*close)(struct concap_proto *cprot);
 128        /* process a frame handed down to us by upper layer */
 129        int (*encap_and_xmit)(struct concap_proto *cprot, struct sk_buff *skb);
 131        /* to be called for each data entity received from lower layer*/ 
 132        int (*data_ind)(struct concap_proto *cprot, struct sk_buff *skb);
 134        /* to be called when a connection was set up/down.
 135           Protocols that don't process these primitives might fill in
 136           dummy methods here */
 137        int (*connect_ind)(struct concap_proto *cprot);
 138        int (*disconn_ind)(struct concap_proto *cprot);
 142The data structures are defined in the header file include/linux/concap.h.
 145A Network interface using encapsulation protocols must also provide
 146some service primitives to the encapsulation protocol:
 148- request data being submitted by lower layer (device hardware) 
 149- request a connection being set up by lower layer 
 150- request a connection being released by lower layer
 152The encapsulation protocol accesses those primitives via callbacks
 153provided by the network interface within a struct concap_device_ops.
 155struct concap_device_ops{
 157        /* to request data be submitted by device */ 
 158        int (*data_req)(struct concap_proto *, struct sk_buff *);
 160        /* Control methods must be set to NULL by devices which do not
 161           support connection control. */
 162        /* to request a connection be set up */ 
 163        int (*connect_req)(struct concap_proto *);
 165        /* to request a connection be released */
 166        int (*disconn_req)(struct concap_proto *);      
 169The network interface does not explicitly provide a receive service
 170because the encapsulation protocol directly calls netif_rx(). 
 175An encapsulation protocol itself is actually the
 176struct concap_proto{
 177        struct net_device *net_dev;             /* net device using our service  */
 178        struct concap_device_ops *dops; /* callbacks provided by device */
 179        struct concap_proto_ops  *pops; /* callbacks provided by us */
 180        int flags;
 181        void *proto_data;               /* protocol specific private data, to
 182                                           be accessed via *pops methods only*/
 183        /*
 184          :
 185          whatever 
 186          :
 187          */
 190Most of this is filled in when the device requests the protocol to 
 191be reset (opend). The network interface must provide the net_dev and
 192dops pointers. Other concap_proto members should be considered private
 193data that are only accessed by the pops callback functions. Likewise,
 194a concap proto should access the network device's private data
 195only by means of the callbacks referred to by the dops pointer.
 198A possible extended device structure which uses the connection controlling
 199encapsulation services could look like this:
 201struct concap_device{
 202        struct net_device net_dev;
 203        struct my_priv  /* device->local stuff */
 204                        /* the my_priv struct might contain a 
 205                           struct concap_device_ops *dops;
 206                           to provide the device specific callbacks
 207                        */
 208        struct concap_proto *cprot;        /* callbacks provided by protocol */
 213Misc Thoughts
 216The concept of the concap proto might help to reuse protocol code and
 217reduce the complexity of certain network interface implementations.
 218The trade off is that it introduces yet another procedure call layer
 219when processing the protocol. This has of course some impact on
 220performance. However, typically the concap interface will be used by
 221devices attached to slow lines (like telephone, isdn, leased synchronous
 222lines). For such slow lines, the overhead is probably negligible.
 223This might no longer hold for certain high speed WAN links (like
 227If general linux network interfaces explicitly supported concap
 228protocols (e.g. by a member struct concap_proto* in struct net_device)
 229then the interface of the service function could be changed
 230by passing a pointer of type (struct net_device*) instead of
 231type (struct concap_proto*). Doing so would make many of the service
 232functions compatible to network device support functions.
 234e.g. instead of the concap protocol's service function
 236  int (*encap_and_xmit)(struct concap_proto *cprot, struct sk_buff *skb);
 238we could have
 240  int (*encap_and_xmit)(struct net_device *ndev, struct sk_buff *skb);
 242As this is compatible to the dev->hard_start_xmit() method, the device
 243driver could directly register the concap protocol's encap_and_xmit()
 244function as its hard_start_xmit() method. This would eliminate one
 245procedure call layer.
 248The device's data request function could also be defined as
 250  int (*data_req)(struct net_device *ndev, struct sk_buff *skb);
 252This might even allow for some protocol stacking. And the network
 253interface might even register the same data_req() function directly
 254as its hard_start_xmit() method when a zero layer encapsulation
 255protocol is configured. Thus, eliminating the performance penalty
 256of the concap interface when a trivial concap protocol is used.
 257Nevertheless, the device remains able to support encapsulation
 258protocol configuration.
 260 kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.