~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/llc/af_llc.c

Version: ~ [ linux-5.10-rc6 ] ~ [ linux-5.9.12 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.81 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.161 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.210 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.247 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.247 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * af_llc.c - LLC User Interface SAPs
  3  * Description:
  4  *   Functions in this module are implementation of socket based llc
  5  *   communications for the Linux operating system. Support of llc class
  6  *   one and class two is provided via SOCK_DGRAM and SOCK_STREAM
  7  *   respectively.
  8  *
  9  *   An llc2 connection is (mac + sap), only one llc2 sap connection
 10  *   is allowed per mac. Though one sap may have multiple mac + sap
 11  *   connections.
 12  *
 13  * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
 14  *               2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 15  *
 16  * This program can be redistributed or modified under the terms of the
 17  * GNU General Public License as published by the Free Software Foundation.
 18  * This program is distributed without any warranty or implied warranty
 19  * of merchantability or fitness for a particular purpose.
 20  *
 21  * See the GNU General Public License for more details.
 22  */
 23 #include <linux/compiler.h>
 24 #include <linux/kernel.h>
 25 #include <linux/module.h>
 26 #include <linux/rtnetlink.h>
 27 #include <linux/init.h>
 28 #include <linux/slab.h>
 29 #include <linux/sched/signal.h>
 30 
 31 #include <net/llc.h>
 32 #include <net/llc_sap.h>
 33 #include <net/llc_pdu.h>
 34 #include <net/llc_conn.h>
 35 #include <net/tcp_states.h>
 36 
 37 /* remember: uninitialized global data is zeroed because its in .bss */
 38 static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 39 static u16 llc_ui_sap_link_no_max[256];
 40 static struct sockaddr_llc llc_ui_addrnull;
 41 static const struct proto_ops llc_ui_ops;
 42 
 43 static bool llc_ui_wait_for_conn(struct sock *sk, long timeout);
 44 static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
 45 static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
 46 
 47 #if 0
 48 #define dprintk(args...) printk(KERN_DEBUG args)
 49 #else
 50 #define dprintk(args...) do {} while (0)
 51 #endif
 52 
 53 /* Maybe we'll add some more in the future. */
 54 #define LLC_CMSG_PKTINFO        1
 55 
 56 
 57 /**
 58  *      llc_ui_next_link_no - return the next unused link number for a sap
 59  *      @sap: Address of sap to get link number from.
 60  *
 61  *      Return the next unused link number for a given sap.
 62  */
 63 static inline u16 llc_ui_next_link_no(int sap)
 64 {
 65         return llc_ui_sap_link_no_max[sap]++;
 66 }
 67 
 68 /**
 69  *      llc_proto_type - return eth protocol for ARP header type
 70  *      @arphrd: ARP header type.
 71  *
 72  *      Given an ARP header type return the corresponding ethernet protocol.
 73  */
 74 static inline __be16 llc_proto_type(u16 arphrd)
 75 {
 76         return htons(ETH_P_802_2);
 77 }
 78 
 79 /**
 80  *      llc_ui_addr_null - determines if a address structure is null
 81  *      @addr: Address to test if null.
 82  */
 83 static inline u8 llc_ui_addr_null(struct sockaddr_llc *addr)
 84 {
 85         return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr));
 86 }
 87 
 88 /**
 89  *      llc_ui_header_len - return length of llc header based on operation
 90  *      @sk: Socket which contains a valid llc socket type.
 91  *      @addr: Complete sockaddr_llc structure received from the user.
 92  *
 93  *      Provide the length of the llc header depending on what kind of
 94  *      operation the user would like to perform and the type of socket.
 95  *      Returns the correct llc header length.
 96  */
 97 static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr)
 98 {
 99         u8 rc = LLC_PDU_LEN_U;
100 
101         if (addr->sllc_test || addr->sllc_xid)
102                 rc = LLC_PDU_LEN_U;
103         else if (sk->sk_type == SOCK_STREAM)
104                 rc = LLC_PDU_LEN_I;
105         return rc;
106 }
107 
108 /**
109  *      llc_ui_send_data - send data via reliable llc2 connection
110  *      @sk: Connection the socket is using.
111  *      @skb: Data the user wishes to send.
112  *      @noblock: can we block waiting for data?
113  *
114  *      Send data via reliable llc2 connection.
115  *      Returns 0 upon success, non-zero if action did not succeed.
116  *
117  *      This function always consumes a reference to the skb.
118  */
119 static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
120 {
121         struct llc_sock* llc = llc_sk(sk);
122 
123         if (unlikely(llc_data_accept_state(llc->state) ||
124                      llc->remote_busy_flag ||
125                      llc->p_flag)) {
126                 long timeout = sock_sndtimeo(sk, noblock);
127                 int rc;
128 
129                 rc = llc_ui_wait_for_busy_core(sk, timeout);
130                 if (rc) {
131                         kfree_skb(skb);
132                         return rc;
133                 }
134         }
135         return llc_build_and_send_pkt(sk, skb);
136 }
137 
138 static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
139 {
140         sock_graft(sk, sock);
141         sk->sk_type     = sock->type;
142         sock->ops       = &llc_ui_ops;
143 }
144 
145 static struct proto llc_proto = {
146         .name     = "LLC",
147         .owner    = THIS_MODULE,
148         .obj_size = sizeof(struct llc_sock),
149         .slab_flags = SLAB_TYPESAFE_BY_RCU,
150 };
151 
152 /**
153  *      llc_ui_create - alloc and init a new llc_ui socket
154  *      @net: network namespace (must be default network)
155  *      @sock: Socket to initialize and attach allocated sk to.
156  *      @protocol: Unused.
157  *      @kern: on behalf of kernel or userspace
158  *
159  *      Allocate and initialize a new llc_ui socket, validate the user wants a
160  *      socket type we have available.
161  *      Returns 0 upon success, negative upon failure.
162  */
163 static int llc_ui_create(struct net *net, struct socket *sock, int protocol,
164                          int kern)
165 {
166         struct sock *sk;
167         int rc = -ESOCKTNOSUPPORT;
168 
169         if (!ns_capable(net->user_ns, CAP_NET_RAW))
170                 return -EPERM;
171 
172         if (!net_eq(net, &init_net))
173                 return -EAFNOSUPPORT;
174 
175         if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
176                 rc = -ENOMEM;
177                 sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto, kern);
178                 if (sk) {
179                         rc = 0;
180                         llc_ui_sk_init(sock, sk);
181                 }
182         }
183         return rc;
184 }
185 
186 /**
187  *      llc_ui_release - shutdown socket
188  *      @sock: Socket to release.
189  *
190  *      Shutdown and deallocate an existing socket.
191  */
192 static int llc_ui_release(struct socket *sock)
193 {
194         struct sock *sk = sock->sk;
195         struct llc_sock *llc;
196 
197         if (unlikely(sk == NULL))
198                 goto out;
199         sock_hold(sk);
200         lock_sock(sk);
201         llc = llc_sk(sk);
202         dprintk("%s: closing local(%02X) remote(%02X)\n", __func__,
203                 llc->laddr.lsap, llc->daddr.lsap);
204         if (!llc_send_disc(sk))
205                 llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
206         if (!sock_flag(sk, SOCK_ZAPPED)) {
207                 struct llc_sap *sap = llc->sap;
208 
209                 /* Hold this for release_sock(), so that llc_backlog_rcv()
210                  * could still use it.
211                  */
212                 llc_sap_hold(sap);
213                 llc_sap_remove_socket(llc->sap, sk);
214                 release_sock(sk);
215                 llc_sap_put(sap);
216         } else {
217                 release_sock(sk);
218         }
219         if (llc->dev)
220                 dev_put(llc->dev);
221         sock_put(sk);
222         llc_sk_free(sk);
223 out:
224         return 0;
225 }
226 
227 /**
228  *      llc_ui_autoport - provide dynamically allocate SAP number
229  *
230  *      Provide the caller with a dynamically allocated SAP number according
231  *      to the rules that are set in this function. Returns: 0, upon failure,
232  *      SAP number otherwise.
233  */
234 static int llc_ui_autoport(void)
235 {
236         struct llc_sap *sap;
237         int i, tries = 0;
238 
239         while (tries < LLC_SAP_DYN_TRIES) {
240                 for (i = llc_ui_sap_last_autoport;
241                      i < LLC_SAP_DYN_STOP; i += 2) {
242                         sap = llc_sap_find(i);
243                         if (!sap) {
244                                 llc_ui_sap_last_autoport = i + 2;
245                                 goto out;
246                         }
247                         llc_sap_put(sap);
248                 }
249                 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
250                 tries++;
251         }
252         i = 0;
253 out:
254         return i;
255 }
256 
257 /**
258  *      llc_ui_autobind - automatically bind a socket to a sap
259  *      @sock: socket to bind
260  *      @addr: address to connect to
261  *
262  *      Used by llc_ui_connect and llc_ui_sendmsg when the user hasn't
263  *      specifically used llc_ui_bind to bind to an specific address/sap
264  *
265  *      Returns: 0 upon success, negative otherwise.
266  */
267 static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
268 {
269         struct sock *sk = sock->sk;
270         struct llc_sock *llc = llc_sk(sk);
271         struct llc_sap *sap;
272         int rc = -EINVAL;
273 
274         if (!sock_flag(sk, SOCK_ZAPPED))
275                 goto out;
276         if (!addr->sllc_arphrd)
277                 addr->sllc_arphrd = ARPHRD_ETHER;
278         if (addr->sllc_arphrd != ARPHRD_ETHER)
279                 goto out;
280         rc = -ENODEV;
281         if (sk->sk_bound_dev_if) {
282                 llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
283                 if (llc->dev && addr->sllc_arphrd != llc->dev->type) {
284                         dev_put(llc->dev);
285                         llc->dev = NULL;
286                 }
287         } else
288                 llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
289         if (!llc->dev)
290                 goto out;
291         rc = -EUSERS;
292         llc->laddr.lsap = llc_ui_autoport();
293         if (!llc->laddr.lsap)
294                 goto out;
295         rc = -EBUSY; /* some other network layer is using the sap */
296         sap = llc_sap_open(llc->laddr.lsap, NULL);
297         if (!sap)
298                 goto out;
299         memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
300         memcpy(&llc->addr, addr, sizeof(llc->addr));
301         /* assign new connection to its SAP */
302         llc_sap_add_socket(sap, sk);
303         sock_reset_flag(sk, SOCK_ZAPPED);
304         rc = 0;
305 out:
306         return rc;
307 }
308 
309 /**
310  *      llc_ui_bind - bind a socket to a specific address.
311  *      @sock: Socket to bind an address to.
312  *      @uaddr: Address the user wants the socket bound to.
313  *      @addrlen: Length of the uaddr structure.
314  *
315  *      Bind a socket to a specific address. For llc a user is able to bind to
316  *      a specific sap only or mac + sap.
317  *      If the user desires to bind to a specific mac + sap, it is possible to
318  *      have multiple sap connections via multiple macs.
319  *      Bind and autobind for that matter must enforce the correct sap usage
320  *      otherwise all hell will break loose.
321  *      Returns: 0 upon success, negative otherwise.
322  */
323 static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
324 {
325         struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
326         struct sock *sk = sock->sk;
327         struct llc_sock *llc = llc_sk(sk);
328         struct llc_sap *sap;
329         int rc = -EINVAL;
330 
331         lock_sock(sk);
332         if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
333                 goto out;
334         rc = -EAFNOSUPPORT;
335         if (!addr->sllc_arphrd)
336                 addr->sllc_arphrd = ARPHRD_ETHER;
337         if (unlikely(addr->sllc_family != AF_LLC || addr->sllc_arphrd != ARPHRD_ETHER))
338                 goto out;
339         dprintk("%s: binding %02X\n", __func__, addr->sllc_sap);
340         rc = -ENODEV;
341         rcu_read_lock();
342         if (sk->sk_bound_dev_if) {
343                 llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
344                 if (llc->dev) {
345                         if (is_zero_ether_addr(addr->sllc_mac))
346                                 memcpy(addr->sllc_mac, llc->dev->dev_addr,
347                                        IFHWADDRLEN);
348                         if (addr->sllc_arphrd != llc->dev->type ||
349                             !ether_addr_equal(addr->sllc_mac,
350                                               llc->dev->dev_addr)) {
351                                 rc = -EINVAL;
352                                 llc->dev = NULL;
353                         }
354                 }
355         } else
356                 llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
357                                            addr->sllc_mac);
358         if (llc->dev)
359                 dev_hold(llc->dev);
360         rcu_read_unlock();
361         if (!llc->dev)
362                 goto out;
363         if (!addr->sllc_sap) {
364                 rc = -EUSERS;
365                 addr->sllc_sap = llc_ui_autoport();
366                 if (!addr->sllc_sap)
367                         goto out;
368         }
369         sap = llc_sap_find(addr->sllc_sap);
370         if (!sap) {
371                 sap = llc_sap_open(addr->sllc_sap, NULL);
372                 rc = -EBUSY; /* some other network layer is using the sap */
373                 if (!sap)
374                         goto out;
375         } else {
376                 struct llc_addr laddr, daddr;
377                 struct sock *ask;
378 
379                 memset(&laddr, 0, sizeof(laddr));
380                 memset(&daddr, 0, sizeof(daddr));
381                 /*
382                  * FIXME: check if the address is multicast,
383                  *        only SOCK_DGRAM can do this.
384                  */
385                 memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
386                 laddr.lsap = addr->sllc_sap;
387                 rc = -EADDRINUSE; /* mac + sap clash. */
388                 ask = llc_lookup_established(sap, &daddr, &laddr);
389                 if (ask) {
390                         sock_put(ask);
391                         goto out_put;
392                 }
393         }
394         llc->laddr.lsap = addr->sllc_sap;
395         memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
396         memcpy(&llc->addr, addr, sizeof(llc->addr));
397         /* assign new connection to its SAP */
398         llc_sap_add_socket(sap, sk);
399         sock_reset_flag(sk, SOCK_ZAPPED);
400         rc = 0;
401 out_put:
402         llc_sap_put(sap);
403 out:
404         release_sock(sk);
405         return rc;
406 }
407 
408 /**
409  *      llc_ui_shutdown - shutdown a connect llc2 socket.
410  *      @sock: Socket to shutdown.
411  *      @how: What part of the socket to shutdown.
412  *
413  *      Shutdown a connected llc2 socket. Currently this function only supports
414  *      shutting down both sends and receives (2), we could probably make this
415  *      function such that a user can shutdown only half the connection but not
416  *      right now.
417  *      Returns: 0 upon success, negative otherwise.
418  */
419 static int llc_ui_shutdown(struct socket *sock, int how)
420 {
421         struct sock *sk = sock->sk;
422         int rc = -ENOTCONN;
423 
424         lock_sock(sk);
425         if (unlikely(sk->sk_state != TCP_ESTABLISHED))
426                 goto out;
427         rc = -EINVAL;
428         if (how != 2)
429                 goto out;
430         rc = llc_send_disc(sk);
431         if (!rc)
432                 rc = llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
433         /* Wake up anyone sleeping in poll */
434         sk->sk_state_change(sk);
435 out:
436         release_sock(sk);
437         return rc;
438 }
439 
440 /**
441  *      llc_ui_connect - Connect to a remote llc2 mac + sap.
442  *      @sock: Socket which will be connected to the remote destination.
443  *      @uaddr: Remote and possibly the local address of the new connection.
444  *      @addrlen: Size of uaddr structure.
445  *      @flags: Operational flags specified by the user.
446  *
447  *      Connect to a remote llc2 mac + sap. The caller must specify the
448  *      destination mac and address to connect to. If the user hasn't previously
449  *      called bind(2) with a smac the address of the first interface of the
450  *      specified arp type will be used.
451  *      This function will autobind if user did not previously call bind.
452  *      Returns: 0 upon success, negative otherwise.
453  */
454 static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
455                           int addrlen, int flags)
456 {
457         struct sock *sk = sock->sk;
458         struct llc_sock *llc = llc_sk(sk);
459         struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
460         int rc = -EINVAL;
461 
462         lock_sock(sk);
463         if (unlikely(addrlen != sizeof(*addr)))
464                 goto out;
465         rc = -EAFNOSUPPORT;
466         if (unlikely(addr->sllc_family != AF_LLC))
467                 goto out;
468         if (unlikely(sk->sk_type != SOCK_STREAM))
469                 goto out;
470         rc = -EALREADY;
471         if (unlikely(sock->state == SS_CONNECTING))
472                 goto out;
473         /* bind connection to sap if user hasn't done it. */
474         if (sock_flag(sk, SOCK_ZAPPED)) {
475                 /* bind to sap with null dev, exclusive */
476                 rc = llc_ui_autobind(sock, addr);
477                 if (rc)
478                         goto out;
479         }
480         llc->daddr.lsap = addr->sllc_sap;
481         memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
482         sock->state = SS_CONNECTING;
483         sk->sk_state   = TCP_SYN_SENT;
484         llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
485         rc = llc_establish_connection(sk, llc->dev->dev_addr,
486                                       addr->sllc_mac, addr->sllc_sap);
487         if (rc) {
488                 dprintk("%s: llc_ui_send_conn failed :-(\n", __func__);
489                 sock->state  = SS_UNCONNECTED;
490                 sk->sk_state = TCP_CLOSE;
491                 goto out;
492         }
493 
494         if (sk->sk_state == TCP_SYN_SENT) {
495                 const long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
496 
497                 if (!timeo || !llc_ui_wait_for_conn(sk, timeo))
498                         goto out;
499 
500                 rc = sock_intr_errno(timeo);
501                 if (signal_pending(current))
502                         goto out;
503         }
504 
505         if (sk->sk_state == TCP_CLOSE)
506                 goto sock_error;
507 
508         sock->state = SS_CONNECTED;
509         rc = 0;
510 out:
511         release_sock(sk);
512         return rc;
513 sock_error:
514         rc = sock_error(sk) ? : -ECONNABORTED;
515         sock->state = SS_UNCONNECTED;
516         goto out;
517 }
518 
519 /**
520  *      llc_ui_listen - allow a normal socket to accept incoming connections
521  *      @sock: Socket to allow incoming connections on.
522  *      @backlog: Number of connections to queue.
523  *
524  *      Allow a normal socket to accept incoming connections.
525  *      Returns 0 upon success, negative otherwise.
526  */
527 static int llc_ui_listen(struct socket *sock, int backlog)
528 {
529         struct sock *sk = sock->sk;
530         int rc = -EINVAL;
531 
532         lock_sock(sk);
533         if (unlikely(sock->state != SS_UNCONNECTED))
534                 goto out;
535         rc = -EOPNOTSUPP;
536         if (unlikely(sk->sk_type != SOCK_STREAM))
537                 goto out;
538         rc = -EAGAIN;
539         if (sock_flag(sk, SOCK_ZAPPED))
540                 goto out;
541         rc = 0;
542         if (!(unsigned int)backlog)     /* BSDism */
543                 backlog = 1;
544         sk->sk_max_ack_backlog = backlog;
545         if (sk->sk_state != TCP_LISTEN) {
546                 sk->sk_ack_backlog = 0;
547                 sk->sk_state       = TCP_LISTEN;
548         }
549         sk->sk_socket->flags |= __SO_ACCEPTCON;
550 out:
551         release_sock(sk);
552         return rc;
553 }
554 
555 static int llc_ui_wait_for_disc(struct sock *sk, long timeout)
556 {
557         DEFINE_WAIT_FUNC(wait, woken_wake_function);
558         int rc = 0;
559 
560         add_wait_queue(sk_sleep(sk), &wait);
561         while (1) {
562                 if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait))
563                         break;
564                 rc = -ERESTARTSYS;
565                 if (signal_pending(current))
566                         break;
567                 rc = -EAGAIN;
568                 if (!timeout)
569                         break;
570                 rc = 0;
571         }
572         remove_wait_queue(sk_sleep(sk), &wait);
573         return rc;
574 }
575 
576 static bool llc_ui_wait_for_conn(struct sock *sk, long timeout)
577 {
578         DEFINE_WAIT_FUNC(wait, woken_wake_function);
579 
580         add_wait_queue(sk_sleep(sk), &wait);
581         while (1) {
582                 if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait))
583                         break;
584                 if (signal_pending(current) || !timeout)
585                         break;
586         }
587         remove_wait_queue(sk_sleep(sk), &wait);
588         return timeout;
589 }
590 
591 static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
592 {
593         DEFINE_WAIT_FUNC(wait, woken_wake_function);
594         struct llc_sock *llc = llc_sk(sk);
595         int rc;
596 
597         add_wait_queue(sk_sleep(sk), &wait);
598         while (1) {
599                 rc = 0;
600                 if (sk_wait_event(sk, &timeout,
601                                   (sk->sk_shutdown & RCV_SHUTDOWN) ||
602                                   (!llc_data_accept_state(llc->state) &&
603                                    !llc->remote_busy_flag &&
604                                    !llc->p_flag), &wait))
605                         break;
606                 rc = -ERESTARTSYS;
607                 if (signal_pending(current))
608                         break;
609                 rc = -EAGAIN;
610                 if (!timeout)
611                         break;
612         }
613         remove_wait_queue(sk_sleep(sk), &wait);
614         return rc;
615 }
616 
617 static int llc_wait_data(struct sock *sk, long timeo)
618 {
619         int rc;
620 
621         while (1) {
622                 /*
623                  * POSIX 1003.1g mandates this order.
624                  */
625                 rc = sock_error(sk);
626                 if (rc)
627                         break;
628                 rc = 0;
629                 if (sk->sk_shutdown & RCV_SHUTDOWN)
630                         break;
631                 rc = -EAGAIN;
632                 if (!timeo)
633                         break;
634                 rc = sock_intr_errno(timeo);
635                 if (signal_pending(current))
636                         break;
637                 rc = 0;
638                 if (sk_wait_data(sk, &timeo, NULL))
639                         break;
640         }
641         return rc;
642 }
643 
644 static void llc_cmsg_rcv(struct msghdr *msg, struct sk_buff *skb)
645 {
646         struct llc_sock *llc = llc_sk(skb->sk);
647 
648         if (llc->cmsg_flags & LLC_CMSG_PKTINFO) {
649                 struct llc_pktinfo info;
650 
651                 memset(&info, 0, sizeof(info));
652                 info.lpi_ifindex = llc_sk(skb->sk)->dev->ifindex;
653                 llc_pdu_decode_dsap(skb, &info.lpi_sap);
654                 llc_pdu_decode_da(skb, info.lpi_mac);
655                 put_cmsg(msg, SOL_LLC, LLC_OPT_PKTINFO, sizeof(info), &info);
656         }
657 }
658 
659 /**
660  *      llc_ui_accept - accept a new incoming connection.
661  *      @sock: Socket which connections arrive on.
662  *      @newsock: Socket to move incoming connection to.
663  *      @flags: User specified operational flags.
664  *      @kern: If the socket is kernel internal
665  *
666  *      Accept a new incoming connection.
667  *      Returns 0 upon success, negative otherwise.
668  */
669 static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags,
670                          bool kern)
671 {
672         struct sock *sk = sock->sk, *newsk;
673         struct llc_sock *llc, *newllc;
674         struct sk_buff *skb;
675         int rc = -EOPNOTSUPP;
676 
677         dprintk("%s: accepting on %02X\n", __func__,
678                 llc_sk(sk)->laddr.lsap);
679         lock_sock(sk);
680         if (unlikely(sk->sk_type != SOCK_STREAM))
681                 goto out;
682         rc = -EINVAL;
683         if (unlikely(sock->state != SS_UNCONNECTED ||
684                      sk->sk_state != TCP_LISTEN))
685                 goto out;
686         /* wait for a connection to arrive. */
687         if (skb_queue_empty(&sk->sk_receive_queue)) {
688                 rc = llc_wait_data(sk, sk->sk_rcvtimeo);
689                 if (rc)
690                         goto out;
691         }
692         dprintk("%s: got a new connection on %02X\n", __func__,
693                 llc_sk(sk)->laddr.lsap);
694         skb = skb_dequeue(&sk->sk_receive_queue);
695         rc = -EINVAL;
696         if (!skb->sk)
697                 goto frees;
698         rc = 0;
699         newsk = skb->sk;
700         /* attach connection to a new socket. */
701         llc_ui_sk_init(newsock, newsk);
702         sock_reset_flag(newsk, SOCK_ZAPPED);
703         newsk->sk_state         = TCP_ESTABLISHED;
704         newsock->state          = SS_CONNECTED;
705         llc                     = llc_sk(sk);
706         newllc                  = llc_sk(newsk);
707         memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
708         newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
709 
710         /* put original socket back into a clean listen state. */
711         sk->sk_state = TCP_LISTEN;
712         sk_acceptq_removed(sk);
713         dprintk("%s: ok success on %02X, client on %02X\n", __func__,
714                 llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
715 frees:
716         kfree_skb(skb);
717 out:
718         release_sock(sk);
719         return rc;
720 }
721 
722 /**
723  *      llc_ui_recvmsg - copy received data to the socket user.
724  *      @sock: Socket to copy data from.
725  *      @msg: Various user space related information.
726  *      @len: Size of user buffer.
727  *      @flags: User specified flags.
728  *
729  *      Copy received data to the socket user.
730  *      Returns non-negative upon success, negative otherwise.
731  */
732 static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
733                           int flags)
734 {
735         DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);
736         const int nonblock = flags & MSG_DONTWAIT;
737         struct sk_buff *skb = NULL;
738         struct sock *sk = sock->sk;
739         struct llc_sock *llc = llc_sk(sk);
740         size_t copied = 0;
741         u32 peek_seq = 0;
742         u32 *seq, skb_len;
743         unsigned long used;
744         int target;     /* Read at least this many bytes */
745         long timeo;
746 
747         lock_sock(sk);
748         copied = -ENOTCONN;
749         if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
750                 goto out;
751 
752         timeo = sock_rcvtimeo(sk, nonblock);
753 
754         seq = &llc->copied_seq;
755         if (flags & MSG_PEEK) {
756                 peek_seq = llc->copied_seq;
757                 seq = &peek_seq;
758         }
759 
760         target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
761         copied = 0;
762 
763         do {
764                 u32 offset;
765 
766                 /*
767                  * We need to check signals first, to get correct SIGURG
768                  * handling. FIXME: Need to check this doesn't impact 1003.1g
769                  * and move it down to the bottom of the loop
770                  */
771                 if (signal_pending(current)) {
772                         if (copied)
773                                 break;
774                         copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
775                         break;
776                 }
777 
778                 /* Next get a buffer. */
779 
780                 skb = skb_peek(&sk->sk_receive_queue);
781                 if (skb) {
782                         offset = *seq;
783                         goto found_ok_skb;
784                 }
785                 /* Well, if we have backlog, try to process it now yet. */
786 
787                 if (copied >= target && !READ_ONCE(sk->sk_backlog.tail))
788                         break;
789 
790                 if (copied) {
791                         if (sk->sk_err ||
792                             sk->sk_state == TCP_CLOSE ||
793                             (sk->sk_shutdown & RCV_SHUTDOWN) ||
794                             !timeo ||
795                             (flags & MSG_PEEK))
796                                 break;
797                 } else {
798                         if (sock_flag(sk, SOCK_DONE))
799                                 break;
800 
801                         if (sk->sk_err) {
802                                 copied = sock_error(sk);
803                                 break;
804                         }
805                         if (sk->sk_shutdown & RCV_SHUTDOWN)
806                                 break;
807 
808                         if (sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_CLOSE) {
809                                 if (!sock_flag(sk, SOCK_DONE)) {
810                                         /*
811                                          * This occurs when user tries to read
812                                          * from never connected socket.
813                                          */
814                                         copied = -ENOTCONN;
815                                         break;
816                                 }
817                                 break;
818                         }
819                         if (!timeo) {
820                                 copied = -EAGAIN;
821                                 break;
822                         }
823                 }
824 
825                 if (copied >= target) { /* Do not sleep, just process backlog. */
826                         release_sock(sk);
827                         lock_sock(sk);
828                 } else
829                         sk_wait_data(sk, &timeo, NULL);
830 
831                 if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) {
832                         net_dbg_ratelimited("LLC(%s:%d): Application bug, race in MSG_PEEK\n",
833                                             current->comm,
834                                             task_pid_nr(current));
835                         peek_seq = llc->copied_seq;
836                 }
837                 continue;
838         found_ok_skb:
839                 skb_len = skb->len;
840                 /* Ok so how much can we use? */
841                 used = skb->len - offset;
842                 if (len < used)
843                         used = len;
844 
845                 if (!(flags & MSG_TRUNC)) {
846                         int rc = skb_copy_datagram_msg(skb, offset, msg, used);
847                         if (rc) {
848                                 /* Exception. Bailout! */
849                                 if (!copied)
850                                         copied = -EFAULT;
851                                 break;
852                         }
853                 }
854 
855                 *seq += used;
856                 copied += used;
857                 len -= used;
858 
859                 /* For non stream protcols we get one packet per recvmsg call */
860                 if (sk->sk_type != SOCK_STREAM)
861                         goto copy_uaddr;
862 
863                 if (!(flags & MSG_PEEK)) {
864                         skb_unlink(skb, &sk->sk_receive_queue);
865                         kfree_skb(skb);
866                         *seq = 0;
867                 }
868 
869                 /* Partial read */
870                 if (used + offset < skb_len)
871                         continue;
872         } while (len > 0);
873 
874 out:
875         release_sock(sk);
876         return copied;
877 copy_uaddr:
878         if (uaddr != NULL && skb != NULL) {
879                 memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
880                 msg->msg_namelen = sizeof(*uaddr);
881         }
882         if (llc_sk(sk)->cmsg_flags)
883                 llc_cmsg_rcv(msg, skb);
884 
885         if (!(flags & MSG_PEEK)) {
886                 skb_unlink(skb, &sk->sk_receive_queue);
887                 kfree_skb(skb);
888                 *seq = 0;
889         }
890 
891         goto out;
892 }
893 
894 /**
895  *      llc_ui_sendmsg - Transmit data provided by the socket user.
896  *      @sock: Socket to transmit data from.
897  *      @msg: Various user related information.
898  *      @len: Length of data to transmit.
899  *
900  *      Transmit data provided by the socket user.
901  *      Returns non-negative upon success, negative otherwise.
902  */
903 static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
904 {
905         struct sock *sk = sock->sk;
906         struct llc_sock *llc = llc_sk(sk);
907         DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name);
908         int flags = msg->msg_flags;
909         int noblock = flags & MSG_DONTWAIT;
910         struct sk_buff *skb = NULL;
911         size_t size = 0;
912         int rc = -EINVAL, copied = 0, hdrlen;
913 
914         dprintk("%s: sending from %02X to %02X\n", __func__,
915                 llc->laddr.lsap, llc->daddr.lsap);
916         lock_sock(sk);
917         if (addr) {
918                 if (msg->msg_namelen < sizeof(*addr))
919                         goto out;
920         } else {
921                 if (llc_ui_addr_null(&llc->addr))
922                         goto out;
923                 addr = &llc->addr;
924         }
925         /* must bind connection to sap if user hasn't done it. */
926         if (sock_flag(sk, SOCK_ZAPPED)) {
927                 /* bind to sap with null dev, exclusive. */
928                 rc = llc_ui_autobind(sock, addr);
929                 if (rc)
930                         goto out;
931         }
932         hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
933         size = hdrlen + len;
934         if (size > llc->dev->mtu)
935                 size = llc->dev->mtu;
936         copied = size - hdrlen;
937         rc = -EINVAL;
938         if (copied < 0)
939                 goto out;
940         release_sock(sk);
941         skb = sock_alloc_send_skb(sk, size, noblock, &rc);
942         lock_sock(sk);
943         if (!skb)
944                 goto out;
945         skb->dev      = llc->dev;
946         skb->protocol = llc_proto_type(addr->sllc_arphrd);
947         skb_reserve(skb, hdrlen);
948         rc = memcpy_from_msg(skb_put(skb, copied), msg, copied);
949         if (rc)
950                 goto out;
951         if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
952                 llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
953                                           addr->sllc_sap);
954                 skb = NULL;
955                 goto out;
956         }
957         if (addr->sllc_test) {
958                 llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
959                                             addr->sllc_sap);
960                 skb = NULL;
961                 goto out;
962         }
963         if (addr->sllc_xid) {
964                 llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
965                                            addr->sllc_sap);
966                 skb = NULL;
967                 goto out;
968         }
969         rc = -ENOPROTOOPT;
970         if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
971                 goto out;
972         rc = llc_ui_send_data(sk, skb, noblock);
973         skb = NULL;
974 out:
975         kfree_skb(skb);
976         if (rc)
977                 dprintk("%s: failed sending from %02X to %02X: %d\n",
978                         __func__, llc->laddr.lsap, llc->daddr.lsap, rc);
979         release_sock(sk);
980         return rc ? : copied;
981 }
982 
983 /**
984  *      llc_ui_getname - return the address info of a socket
985  *      @sock: Socket to get address of.
986  *      @uaddr: Address structure to return information.
987  *      @peer: Does user want local or remote address information.
988  *
989  *      Return the address information of a socket.
990  */
991 static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
992                           int peer)
993 {
994         struct sockaddr_llc sllc;
995         struct sock *sk = sock->sk;
996         struct llc_sock *llc = llc_sk(sk);
997         int rc = -EBADF;
998 
999         memset(&sllc, 0, sizeof(sllc));
1000         lock_sock(sk);
1001         if (sock_flag(sk, SOCK_ZAPPED))
1002                 goto out;
1003         if (peer) {
1004                 rc = -ENOTCONN;
1005                 if (sk->sk_state != TCP_ESTABLISHED)
1006                         goto out;
1007                 if(llc->dev)
1008                         sllc.sllc_arphrd = llc->dev->type;
1009                 sllc.sllc_sap = llc->daddr.lsap;
1010                 memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
1011         } else {
1012                 rc = -EINVAL;
1013                 if (!llc->sap)
1014                         goto out;
1015                 sllc.sllc_sap = llc->sap->laddr.lsap;
1016 
1017                 if (llc->dev) {
1018                         sllc.sllc_arphrd = llc->dev->type;
1019                         memcpy(&sllc.sllc_mac, llc->dev->dev_addr,
1020                                IFHWADDRLEN);
1021                 }
1022         }
1023         sllc.sllc_family = AF_LLC;
1024         memcpy(uaddr, &sllc, sizeof(sllc));
1025         rc = sizeof(sllc);
1026 out:
1027         release_sock(sk);
1028         return rc;
1029 }
1030 
1031 /**
1032  *      llc_ui_ioctl - io controls for PF_LLC
1033  *      @sock: Socket to get/set info
1034  *      @cmd: command
1035  *      @arg: optional argument for cmd
1036  *
1037  *      get/set info on llc sockets
1038  */
1039 static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
1040                         unsigned long arg)
1041 {
1042         return -ENOIOCTLCMD;
1043 }
1044 
1045 /**
1046  *      llc_ui_setsockopt - set various connection specific parameters.
1047  *      @sock: Socket to set options on.
1048  *      @level: Socket level user is requesting operations on.
1049  *      @optname: Operation name.
1050  *      @optval: User provided operation data.
1051  *      @optlen: Length of optval.
1052  *
1053  *      Set various connection specific parameters.
1054  */
1055 static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
1056                              sockptr_t optval, unsigned int optlen)
1057 {
1058         struct sock *sk = sock->sk;
1059         struct llc_sock *llc = llc_sk(sk);
1060         unsigned int opt;
1061         int rc = -EINVAL;
1062 
1063         lock_sock(sk);
1064         if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
1065                 goto out;
1066         rc = copy_from_sockptr(&opt, optval, sizeof(opt));
1067         if (rc)
1068                 goto out;
1069         rc = -EINVAL;
1070         switch (optname) {
1071         case LLC_OPT_RETRY:
1072                 if (opt > LLC_OPT_MAX_RETRY)
1073                         goto out;
1074                 llc->n2 = opt;
1075                 break;
1076         case LLC_OPT_SIZE:
1077                 if (opt > LLC_OPT_MAX_SIZE)
1078                         goto out;
1079                 llc->n1 = opt;
1080                 break;
1081         case LLC_OPT_ACK_TMR_EXP:
1082                 if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
1083                         goto out;
1084                 llc->ack_timer.expire = opt * HZ;
1085                 break;
1086         case LLC_OPT_P_TMR_EXP:
1087                 if (opt > LLC_OPT_MAX_P_TMR_EXP)
1088                         goto out;
1089                 llc->pf_cycle_timer.expire = opt * HZ;
1090                 break;
1091         case LLC_OPT_REJ_TMR_EXP:
1092                 if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
1093                         goto out;
1094                 llc->rej_sent_timer.expire = opt * HZ;
1095                 break;
1096         case LLC_OPT_BUSY_TMR_EXP:
1097                 if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
1098                         goto out;
1099                 llc->busy_state_timer.expire = opt * HZ;
1100                 break;
1101         case LLC_OPT_TX_WIN:
1102                 if (opt > LLC_OPT_MAX_WIN)
1103                         goto out;
1104                 llc->k = opt;
1105                 break;
1106         case LLC_OPT_RX_WIN:
1107                 if (opt > LLC_OPT_MAX_WIN)
1108                         goto out;
1109                 llc->rw = opt;
1110                 break;
1111         case LLC_OPT_PKTINFO:
1112                 if (opt)
1113                         llc->cmsg_flags |= LLC_CMSG_PKTINFO;
1114                 else
1115                         llc->cmsg_flags &= ~LLC_CMSG_PKTINFO;
1116                 break;
1117         default:
1118                 rc = -ENOPROTOOPT;
1119                 goto out;
1120         }
1121         rc = 0;
1122 out:
1123         release_sock(sk);
1124         return rc;
1125 }
1126 
1127 /**
1128  *      llc_ui_getsockopt - get connection specific socket info
1129  *      @sock: Socket to get information from.
1130  *      @level: Socket level user is requesting operations on.
1131  *      @optname: Operation name.
1132  *      @optval: Variable to return operation data in.
1133  *      @optlen: Length of optval.
1134  *
1135  *      Get connection specific socket information.
1136  */
1137 static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
1138                              char __user *optval, int __user *optlen)
1139 {
1140         struct sock *sk = sock->sk;
1141         struct llc_sock *llc = llc_sk(sk);
1142         int val = 0, len = 0, rc = -EINVAL;
1143 
1144         lock_sock(sk);
1145         if (unlikely(level != SOL_LLC))
1146                 goto out;
1147         rc = get_user(len, optlen);
1148         if (rc)
1149                 goto out;
1150         rc = -EINVAL;
1151         if (len != sizeof(int))
1152                 goto out;
1153         switch (optname) {
1154         case LLC_OPT_RETRY:
1155                 val = llc->n2;                                  break;
1156         case LLC_OPT_SIZE:
1157                 val = llc->n1;                                  break;
1158         case LLC_OPT_ACK_TMR_EXP:
1159                 val = llc->ack_timer.expire / HZ;               break;
1160         case LLC_OPT_P_TMR_EXP:
1161                 val = llc->pf_cycle_timer.expire / HZ;          break;
1162         case LLC_OPT_REJ_TMR_EXP:
1163                 val = llc->rej_sent_timer.expire / HZ;          break;
1164         case LLC_OPT_BUSY_TMR_EXP:
1165                 val = llc->busy_state_timer.expire / HZ;        break;
1166         case LLC_OPT_TX_WIN:
1167                 val = llc->k;                           break;
1168         case LLC_OPT_RX_WIN:
1169                 val = llc->rw;                          break;
1170         case LLC_OPT_PKTINFO:
1171                 val = (llc->cmsg_flags & LLC_CMSG_PKTINFO) != 0;
1172                 break;
1173         default:
1174                 rc = -ENOPROTOOPT;
1175                 goto out;
1176         }
1177         rc = 0;
1178         if (put_user(len, optlen) || copy_to_user(optval, &val, len))
1179                 rc = -EFAULT;
1180 out:
1181         release_sock(sk);
1182         return rc;
1183 }
1184 
1185 static const struct net_proto_family llc_ui_family_ops = {
1186         .family = PF_LLC,
1187         .create = llc_ui_create,
1188         .owner  = THIS_MODULE,
1189 };
1190 
1191 static const struct proto_ops llc_ui_ops = {
1192         .family      = PF_LLC,
1193         .owner       = THIS_MODULE,
1194         .release     = llc_ui_release,
1195         .bind        = llc_ui_bind,
1196         .connect     = llc_ui_connect,
1197         .socketpair  = sock_no_socketpair,
1198         .accept      = llc_ui_accept,
1199         .getname     = llc_ui_getname,
1200         .poll        = datagram_poll,
1201         .ioctl       = llc_ui_ioctl,
1202         .listen      = llc_ui_listen,
1203         .shutdown    = llc_ui_shutdown,
1204         .setsockopt  = llc_ui_setsockopt,
1205         .getsockopt  = llc_ui_getsockopt,
1206         .sendmsg     = llc_ui_sendmsg,
1207         .recvmsg     = llc_ui_recvmsg,
1208         .mmap        = sock_no_mmap,
1209         .sendpage    = sock_no_sendpage,
1210 };
1211 
1212 static const char llc_proc_err_msg[] __initconst =
1213         KERN_CRIT "LLC: Unable to register the proc_fs entries\n";
1214 static const char llc_sysctl_err_msg[] __initconst =
1215         KERN_CRIT "LLC: Unable to register the sysctl entries\n";
1216 static const char llc_sock_err_msg[] __initconst =
1217         KERN_CRIT "LLC: Unable to register the network family\n";
1218 
1219 static int __init llc2_init(void)
1220 {
1221         int rc = proto_register(&llc_proto, 0);
1222 
1223         if (rc != 0)
1224                 goto out;
1225 
1226         llc_build_offset_table();
1227         llc_station_init();
1228         llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
1229         rc = llc_proc_init();
1230         if (rc != 0) {
1231                 printk(llc_proc_err_msg);
1232                 goto out_station;
1233         }
1234         rc = llc_sysctl_init();
1235         if (rc) {
1236                 printk(llc_sysctl_err_msg);
1237                 goto out_proc;
1238         }
1239         rc = sock_register(&llc_ui_family_ops);
1240         if (rc) {
1241                 printk(llc_sock_err_msg);
1242                 goto out_sysctl;
1243         }
1244         llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
1245         llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
1246 out:
1247         return rc;
1248 out_sysctl:
1249         llc_sysctl_exit();
1250 out_proc:
1251         llc_proc_exit();
1252 out_station:
1253         llc_station_exit();
1254         proto_unregister(&llc_proto);
1255         goto out;
1256 }
1257 
1258 static void __exit llc2_exit(void)
1259 {
1260         llc_station_exit();
1261         llc_remove_pack(LLC_DEST_SAP);
1262         llc_remove_pack(LLC_DEST_CONN);
1263         sock_unregister(PF_LLC);
1264         llc_proc_exit();
1265         llc_sysctl_exit();
1266         proto_unregister(&llc_proto);
1267 }
1268 
1269 module_init(llc2_init);
1270 module_exit(llc2_exit);
1271 
1272 MODULE_LICENSE("GPL");
1273 MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
1274 MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
1275 MODULE_ALIAS_NETPROTO(PF_LLC);
1276 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp