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