PageRenderTime 22ms CodeModel.GetById 13ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

Unknown | 259 lines | 194 code | 65 blank | 0 comment | 0 complexity | 2f20e4a59afb8ebfbdb3f5829d2feac9 MD5 | raw file
  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 loger 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.