1 /* net/atm/svc.c - ATM SVC sockets */ 2 3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 4 5 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ 6 7 #include <linux/string.h> 8 #include <linux/net.h> /* struct socket, struct proto_ops */ 9 #include <linux/errno.h> /* error codes */ 10 #include <linux/kernel.h> /* printk */ 11 #include <linux/skbuff.h> 12 #include <linux/wait.h> 13 #include <linux/sched.h> /* jiffies and HZ */ 14 #include <linux/fcntl.h> /* O_NONBLOCK */ 15 #include <linux/init.h> 16 #include <linux/atm.h> /* ATM stuff */ 17 #include <linux/atmsap.h> 18 #include <linux/atmsvc.h> 19 #include <linux/atmdev.h> 20 #include <linux/bitops.h> 21 #include <net/sock.h> /* for sock_no_* */ 22 #include <linux/uaccess.h> 23 24 #include "resources.h" 25 #include "common.h" /* common for PVCs and SVCs */ 26 #include "signaling.h" 27 #include "addr.h" 28 29 static int svc_create(struct net *net, struct socket *sock, int protocol, 30 int kern); 31 32 /* 33 * Note: since all this is still nicely synchronized with the signaling demon, 34 * there's no need to protect sleep loops with clis. If signaling is 35 * moved into the kernel, that would change. 36 */ 37 38 39 static int svc_shutdown(struct socket *sock, int how) 40 { 41 return 0; 42 } 43 44 static void svc_disconnect(struct atm_vcc *vcc) 45 { 46 DEFINE_WAIT(wait); 47 struct sk_buff *skb; 48 struct sock *sk = sk_atm(vcc); 49 50 pr_debug("%p\n", vcc); 51 if (test_bit(ATM_VF_REGIS, &vcc->flags)) { 52 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 53 sigd_enq(vcc, as_close, NULL, NULL, NULL); 54 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { 55 schedule(); 56 prepare_to_wait(sk_sleep(sk), &wait, 57 TASK_UNINTERRUPTIBLE); 58 } 59 finish_wait(sk_sleep(sk), &wait); 60 } 61 /* beware - socket is still in use by atmsigd until the last 62 as_indicate has been answered */ 63 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 64 atm_return(vcc, skb->truesize); 65 pr_debug("LISTEN REL\n"); 66 sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0); 67 dev_kfree_skb(skb); 68 } 69 clear_bit(ATM_VF_REGIS, &vcc->flags); 70 /* ... may retry later */ 71 } 72 73 static int svc_release(struct socket *sock) 74 { 75 struct sock *sk = sock->sk; 76 struct atm_vcc *vcc; 77 78 if (sk) { 79 vcc = ATM_SD(sock); 80 pr_debug("%p\n", vcc); 81 clear_bit(ATM_VF_READY, &vcc->flags); 82 /* 83 * VCC pointer is used as a reference, 84 * so we must not free it (thereby subjecting it to re-use) 85 * before all pending connections are closed 86 */ 87 svc_disconnect(vcc); 88 vcc_release(sock); 89 } 90 return 0; 91 } 92 93 static int svc_bind(struct socket *sock, struct sockaddr *sockaddr, 94 int sockaddr_len) 95 { 96 DEFINE_WAIT(wait); 97 struct sock *sk = sock->sk; 98 struct sockaddr_atmsvc *addr; 99 struct atm_vcc *vcc; 100 int error; 101 102 if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) 103 return -EINVAL; 104 lock_sock(sk); 105 if (sock->state == SS_CONNECTED) { 106 error = -EISCONN; 107 goto out; 108 } 109 if (sock->state != SS_UNCONNECTED) { 110 error = -EINVAL; 111 goto out; 112 } 113 vcc = ATM_SD(sock); 114 addr = (struct sockaddr_atmsvc *) sockaddr; 115 if (addr->sas_family != AF_ATMSVC) { 116 error = -EAFNOSUPPORT; 117 goto out; 118 } 119 clear_bit(ATM_VF_BOUND, &vcc->flags); 120 /* failing rebind will kill old binding */ 121 /* @@@ check memory (de)allocation on rebind */ 122 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { 123 error = -EBADFD; 124 goto out; 125 } 126 vcc->local = *addr; 127 set_bit(ATM_VF_WAITING, &vcc->flags); 128 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 129 sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local); 130 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 131 schedule(); 132 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 133 } 134 finish_wait(sk_sleep(sk), &wait); 135 clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */ 136 if (!sigd) { 137 error = -EUNATCH; 138 goto out; 139 } 140 if (!sk->sk_err) 141 set_bit(ATM_VF_BOUND, &vcc->flags); 142 error = -sk->sk_err; 143 out: 144 release_sock(sk); 145 return error; 146 } 147 148 static int svc_connect(struct socket *sock, struct sockaddr *sockaddr, 149 int sockaddr_len, int flags) 150 { 151 DEFINE_WAIT(wait); 152 struct sock *sk = sock->sk; 153 struct sockaddr_atmsvc *addr; 154 struct atm_vcc *vcc = ATM_SD(sock); 155 int error; 156 157 pr_debug("%p\n", vcc); 158 lock_sock(sk); 159 if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) { 160 error = -EINVAL; 161 goto out; 162 } 163 164 switch (sock->state) { 165 default: 166 error = -EINVAL; 167 goto out; 168 case SS_CONNECTED: 169 error = -EISCONN; 170 goto out; 171 case SS_CONNECTING: 172 if (test_bit(ATM_VF_WAITING, &vcc->flags)) { 173 error = -EALREADY; 174 goto out; 175 } 176 sock->state = SS_UNCONNECTED; 177 if (sk->sk_err) { 178 error = -sk->sk_err; 179 goto out; 180 } 181 break; 182 case SS_UNCONNECTED: 183 addr = (struct sockaddr_atmsvc *) sockaddr; 184 if (addr->sas_family != AF_ATMSVC) { 185 error = -EAFNOSUPPORT; 186 goto out; 187 } 188 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { 189 error = -EBADFD; 190 goto out; 191 } 192 if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || 193 vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) { 194 error = -EINVAL; 195 goto out; 196 } 197 if (!vcc->qos.txtp.traffic_class && 198 !vcc->qos.rxtp.traffic_class) { 199 error = -EINVAL; 200 goto out; 201 } 202 vcc->remote = *addr; 203 set_bit(ATM_VF_WAITING, &vcc->flags); 204 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 205 sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote); 206 if (flags & O_NONBLOCK) { 207 finish_wait(sk_sleep(sk), &wait); 208 sock->state = SS_CONNECTING; 209 error = -EINPROGRESS; 210 goto out; 211 } 212 error = 0; 213 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 214 schedule(); 215 if (!signal_pending(current)) { 216 prepare_to_wait(sk_sleep(sk), &wait, 217 TASK_INTERRUPTIBLE); 218 continue; 219 } 220 pr_debug("*ABORT*\n"); 221 /* 222 * This is tricky: 223 * Kernel ---close--> Demon 224 * Kernel <--close--- Demon 225 * or 226 * Kernel ---close--> Demon 227 * Kernel <--error--- Demon 228 * or 229 * Kernel ---close--> Demon 230 * Kernel <--okay---- Demon 231 * Kernel <--close--- Demon 232 */ 233 sigd_enq(vcc, as_close, NULL, NULL, NULL); 234 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 235 prepare_to_wait(sk_sleep(sk), &wait, 236 TASK_INTERRUPTIBLE); 237 schedule(); 238 } 239 if (!sk->sk_err) 240 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && 241 sigd) { 242 prepare_to_wait(sk_sleep(sk), &wait, 243 TASK_INTERRUPTIBLE); 244 schedule(); 245 } 246 clear_bit(ATM_VF_REGIS, &vcc->flags); 247 clear_bit(ATM_VF_RELEASED, &vcc->flags); 248 clear_bit(ATM_VF_CLOSE, &vcc->flags); 249 /* we're gone now but may connect later */ 250 error = -EINTR; 251 break; 252 } 253 finish_wait(sk_sleep(sk), &wait); 254 if (error) 255 goto out; 256 if (!sigd) { 257 error = -EUNATCH; 258 goto out; 259 } 260 if (sk->sk_err) { 261 error = -sk->sk_err; 262 goto out; 263 } 264 } 265 /* 266 * Not supported yet 267 * 268 * #ifndef CONFIG_SINGLE_SIGITF 269 */ 270 vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp); 271 vcc->qos.txtp.pcr = 0; 272 vcc->qos.txtp.min_pcr = 0; 273 /* 274 * #endif 275 */ 276 error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci); 277 if (!error) 278 sock->state = SS_CONNECTED; 279 else 280 (void)svc_disconnect(vcc); 281 out: 282 release_sock(sk); 283 return error; 284 } 285 286 static int svc_listen(struct socket *sock, int backlog) 287 { 288 DEFINE_WAIT(wait); 289 struct sock *sk = sock->sk; 290 struct atm_vcc *vcc = ATM_SD(sock); 291 int error; 292 293 pr_debug("%p\n", vcc); 294 lock_sock(sk); 295 /* let server handle listen on unbound sockets */ 296 if (test_bit(ATM_VF_SESSION, &vcc->flags)) { 297 error = -EINVAL; 298 goto out; 299 } 300 if (test_bit(ATM_VF_LISTEN, &vcc->flags)) { 301 error = -EADDRINUSE; 302 goto out; 303 } 304 set_bit(ATM_VF_WAITING, &vcc->flags); 305 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 306 sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local); 307 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 308 schedule(); 309 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 310 } 311 finish_wait(sk_sleep(sk), &wait); 312 if (!sigd) { 313 error = -EUNATCH; 314 goto out; 315 } 316 set_bit(ATM_VF_LISTEN, &vcc->flags); 317 vcc_insert_socket(sk); 318 sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT; 319 error = -sk->sk_err; 320 out: 321 release_sock(sk); 322 return error; 323 } 324 325 static int svc_accept(struct socket *sock, struct socket *newsock, int flags) 326 { 327 struct sock *sk = sock->sk; 328 struct sk_buff *skb; 329 struct atmsvc_msg *msg; 330 struct atm_vcc *old_vcc = ATM_SD(sock); 331 struct atm_vcc *new_vcc; 332 int error; 333 334 lock_sock(sk); 335 336 error = svc_create(sock_net(sk), newsock, 0, 0); 337 if (error) 338 goto out; 339 340 new_vcc = ATM_SD(newsock); 341 342 pr_debug("%p -> %p\n", old_vcc, new_vcc); 343 while (1) { 344 DEFINE_WAIT(wait); 345 346 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 347 while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && 348 sigd) { 349 if (test_bit(ATM_VF_RELEASED, &old_vcc->flags)) 350 break; 351 if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) { 352 error = -sk->sk_err; 353 break; 354 } 355 if (flags & O_NONBLOCK) { 356 error = -EAGAIN; 357 break; 358 } 359 release_sock(sk); 360 schedule(); 361 lock_sock(sk); 362 if (signal_pending(current)) { 363 error = -ERESTARTSYS; 364 break; 365 } 366 prepare_to_wait(sk_sleep(sk), &wait, 367 TASK_INTERRUPTIBLE); 368 } 369 finish_wait(sk_sleep(sk), &wait); 370 if (error) 371 goto out; 372 if (!skb) { 373 error = -EUNATCH; 374 goto out; 375 } 376 msg = (struct atmsvc_msg *)skb->data; 377 new_vcc->qos = msg->qos; 378 set_bit(ATM_VF_HASQOS, &new_vcc->flags); 379 new_vcc->remote = msg->svc; 380 new_vcc->local = msg->local; 381 new_vcc->sap = msg->sap; 382 error = vcc_connect(newsock, msg->pvc.sap_addr.itf, 383 msg->pvc.sap_addr.vpi, 384 msg->pvc.sap_addr.vci); 385 dev_kfree_skb(skb); 386 sk->sk_ack_backlog--; 387 if (error) { 388 sigd_enq2(NULL, as_reject, old_vcc, NULL, NULL, 389 &old_vcc->qos, error); 390 error = error == -EAGAIN ? -EBUSY : error; 391 goto out; 392 } 393 /* wait should be short, so we ignore the non-blocking flag */ 394 set_bit(ATM_VF_WAITING, &new_vcc->flags); 395 prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait, 396 TASK_UNINTERRUPTIBLE); 397 sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL); 398 while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) { 399 release_sock(sk); 400 schedule(); 401 lock_sock(sk); 402 prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait, 403 TASK_UNINTERRUPTIBLE); 404 } 405 finish_wait(sk_sleep(sk_atm(new_vcc)), &wait); 406 if (!sigd) { 407 error = -EUNATCH; 408 goto out; 409 } 410 if (!sk_atm(new_vcc)->sk_err) 411 break; 412 if (sk_atm(new_vcc)->sk_err != ERESTARTSYS) { 413 error = -sk_atm(new_vcc)->sk_err; 414 goto out; 415 } 416 } 417 newsock->state = SS_CONNECTED; 418 out: 419 release_sock(sk); 420 return error; 421 } 422 423 static int svc_getname(struct socket *sock, struct sockaddr *sockaddr, 424 int *sockaddr_len, int peer) 425 { 426 struct sockaddr_atmsvc *addr; 427 428 *sockaddr_len = sizeof(struct sockaddr_atmsvc); 429 addr = (struct sockaddr_atmsvc *) sockaddr; 430 memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local, 431 sizeof(struct sockaddr_atmsvc)); 432 return 0; 433 } 434 435 int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos) 436 { 437 struct sock *sk = sk_atm(vcc); 438 DEFINE_WAIT(wait); 439 440 set_bit(ATM_VF_WAITING, &vcc->flags); 441 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 442 sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0); 443 while (test_bit(ATM_VF_WAITING, &vcc->flags) && 444 !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { 445 schedule(); 446 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 447 } 448 finish_wait(sk_sleep(sk), &wait); 449 if (!sigd) 450 return -EUNATCH; 451 return -sk->sk_err; 452 } 453 454 static int svc_setsockopt(struct socket *sock, int level, int optname, 455 char __user *optval, unsigned int optlen) 456 { 457 struct sock *sk = sock->sk; 458 struct atm_vcc *vcc = ATM_SD(sock); 459 int value, error = 0; 460 461 lock_sock(sk); 462 switch (optname) { 463 case SO_ATMSAP: 464 if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) { 465 error = -EINVAL; 466 goto out; 467 } 468 if (copy_from_user(&vcc->sap, optval, optlen)) { 469 error = -EFAULT; 470 goto out; 471 } 472 set_bit(ATM_VF_HASSAP, &vcc->flags); 473 break; 474 case SO_MULTIPOINT: 475 if (level != SOL_ATM || optlen != sizeof(int)) { 476 error = -EINVAL; 477 goto out; 478 } 479 if (get_user(value, (int __user *)optval)) { 480 error = -EFAULT; 481 goto out; 482 } 483 if (value == 1) 484 set_bit(ATM_VF_SESSION, &vcc->flags); 485 else if (value == 0) 486 clear_bit(ATM_VF_SESSION, &vcc->flags); 487 else 488 error = -EINVAL; 489 break; 490 default: 491 error = vcc_setsockopt(sock, level, optname, optval, optlen); 492 } 493 494 out: 495 release_sock(sk); 496 return error; 497 } 498 499 static int svc_getsockopt(struct socket *sock, int level, int optname, 500 char __user *optval, int __user *optlen) 501 { 502 struct sock *sk = sock->sk; 503 int error = 0, len; 504 505 lock_sock(sk); 506 if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) { 507 error = vcc_getsockopt(sock, level, optname, optval, optlen); 508 goto out; 509 } 510 if (get_user(len, optlen)) { 511 error = -EFAULT; 512 goto out; 513 } 514 if (len != sizeof(struct atm_sap)) { 515 error = -EINVAL; 516 goto out; 517 } 518 if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) { 519 error = -EFAULT; 520 goto out; 521 } 522 out: 523 release_sock(sk); 524 return error; 525 } 526 527 static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr, 528 int sockaddr_len, int flags) 529 { 530 DEFINE_WAIT(wait); 531 struct sock *sk = sock->sk; 532 struct atm_vcc *vcc = ATM_SD(sock); 533 int error; 534 535 lock_sock(sk); 536 set_bit(ATM_VF_WAITING, &vcc->flags); 537 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 538 sigd_enq(vcc, as_addparty, NULL, NULL, 539 (struct sockaddr_atmsvc *) sockaddr); 540 if (flags & O_NONBLOCK) { 541 finish_wait(sk_sleep(sk), &wait); 542 error = -EINPROGRESS; 543 goto out; 544 } 545 pr_debug("added wait queue\n"); 546 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 547 schedule(); 548 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 549 } 550 finish_wait(sk_sleep(sk), &wait); 551 error = xchg(&sk->sk_err_soft, 0); 552 out: 553 release_sock(sk); 554 return error; 555 } 556 557 static int svc_dropparty(struct socket *sock, int ep_ref) 558 { 559 DEFINE_WAIT(wait); 560 struct sock *sk = sock->sk; 561 struct atm_vcc *vcc = ATM_SD(sock); 562 int error; 563 564 lock_sock(sk); 565 set_bit(ATM_VF_WAITING, &vcc->flags); 566 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 567 sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref); 568 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 569 schedule(); 570 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 571 } 572 finish_wait(sk_sleep(sk), &wait); 573 if (!sigd) { 574 error = -EUNATCH; 575 goto out; 576 } 577 error = xchg(&sk->sk_err_soft, 0); 578 out: 579 release_sock(sk); 580 return error; 581 } 582 583 static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 584 { 585 int error, ep_ref; 586 struct sockaddr_atmsvc sa; 587 struct atm_vcc *vcc = ATM_SD(sock); 588 589 switch (cmd) { 590 case ATM_ADDPARTY: 591 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 592 return -EINVAL; 593 if (copy_from_user(&sa, (void __user *) arg, sizeof(sa))) 594 return -EFAULT; 595 error = svc_addparty(sock, (struct sockaddr *)&sa, sizeof(sa), 596 0); 597 break; 598 case ATM_DROPPARTY: 599 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 600 return -EINVAL; 601 if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int))) 602 return -EFAULT; 603 error = svc_dropparty(sock, ep_ref); 604 break; 605 default: 606 error = vcc_ioctl(sock, cmd, arg); 607 } 608 609 return error; 610 } 611 612 #ifdef CONFIG_COMPAT 613 static int svc_compat_ioctl(struct socket *sock, unsigned int cmd, 614 unsigned long arg) 615 { 616 /* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf. 617 But actually it takes a struct sockaddr_atmsvc, which doesn't need 618 compat handling. So all we have to do is fix up cmd... */ 619 if (cmd == COMPAT_ATM_ADDPARTY) 620 cmd = ATM_ADDPARTY; 621 622 if (cmd == ATM_ADDPARTY || cmd == ATM_DROPPARTY) 623 return svc_ioctl(sock, cmd, arg); 624 else 625 return vcc_compat_ioctl(sock, cmd, arg); 626 } 627 #endif /* CONFIG_COMPAT */ 628 629 static const struct proto_ops svc_proto_ops = { 630 .family = PF_ATMSVC, 631 .owner = THIS_MODULE, 632 633 .release = svc_release, 634 .bind = svc_bind, 635 .connect = svc_connect, 636 .socketpair = sock_no_socketpair, 637 .accept = svc_accept, 638 .getname = svc_getname, 639 .poll = vcc_poll, 640 .ioctl = svc_ioctl, 641 #ifdef CONFIG_COMPAT 642 .compat_ioctl = svc_compat_ioctl, 643 #endif 644 .listen = svc_listen, 645 .shutdown = svc_shutdown, 646 .setsockopt = svc_setsockopt, 647 .getsockopt = svc_getsockopt, 648 .sendmsg = vcc_sendmsg, 649 .recvmsg = vcc_recvmsg, 650 .mmap = sock_no_mmap, 651 .sendpage = sock_no_sendpage, 652 }; 653 654 655 static int svc_create(struct net *net, struct socket *sock, int protocol, 656 int kern) 657 { 658 int error; 659 660 if (!net_eq(net, &init_net)) 661 return -EAFNOSUPPORT; 662 663 sock->ops = &svc_proto_ops; 664 error = vcc_create(net, sock, protocol, AF_ATMSVC); 665 if (error) 666 return error; 667 ATM_SD(sock)->local.sas_family = AF_ATMSVC; 668 ATM_SD(sock)->remote.sas_family = AF_ATMSVC; 669 return 0; 670 } 671 672 static const struct net_proto_family svc_family_ops = { 673 .family = PF_ATMSVC, 674 .create = svc_create, 675 .owner = THIS_MODULE, 676 }; 677 678 679 /* 680 * Initialize the ATM SVC protocol family 681 */ 682 683 int __init atmsvc_init(void) 684 { 685 return sock_register(&svc_family_ops); 686 } 687 688 void atmsvc_exit(void) 689 { 690 sock_unregister(PF_ATMSVC); 691 } 692