Blame view

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