3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_load.c,v 1.6 2000/01/17 20:49:43 mks Exp $
34 * Support for running as a loadable kernel module
42 #include <netatm/kern_include.h>
44 #include <netatm/ipatm/ipatm.h>
45 #include <netatm/ipatm/ipatm_var.h>
48 __RCSID("@(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_load.c,v 1.6 2000/01/17 20:49:43 mks Exp $");
56 int ipatm_vcidle = IPATM_VCIDLE;
58 u_long last_map_ipdst = 0;
59 struct ipvcc* last_map_ipvcc = NULL;
61 struct ip_nif *ipatm_nif_head = NULL;
63 struct ipatm_stat ipatm_stat = {0};
65 struct atm_time ipatm_itimer = {0, 0}; /* VCC idle timer */
67 Atm_endpoint ipatm_endpt = {
85 struct sp_info ipatm_vcpool = {
86 "ipatm vcc pool", /* si_name */
87 sizeof(struct ipvcc), /* si_blksiz */
92 struct sp_info ipatm_nifpool = {
93 "ipatm nif pool", /* si_name */
94 sizeof(struct ip_nif), /* si_blksiz */
103 static int ipatm_start __P((void));
104 static int ipatm_stop __P((void));
110 static struct atm_ncm ipatm_ncm = {
117 static struct ipatm_listener {
119 Atm_connection *conn;
120 } ipatm_listeners[] = {
123 CMAPI_CPCS, /* api */
190 T_ATM_NETWORK_CODING,
210 CMAPI_CPCS, /* api */
264 T_ATM_NETWORK_CODING,
284 CMAPI_CPCS, /* api */
338 T_ATM_NETWORK_CODING,
358 static struct t_atm_cause ipatm_cause = {
361 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
367 * Initialize ipatm processing
369 * This will be called during module loading. We'll just register
370 * ourselves and wait for the packets to start flying.
376 * 0 startup was successful
377 * errno startup failed - reason indicated
388 * Verify software version
390 if (atm_version != ATM_VERSION) {
391 log(LOG_ERR, "version mismatch: ipatm=%d.%d kernel=%d.%d\n",
392 ATM_VERS_MAJ(ATM_VERSION), ATM_VERS_MIN(ATM_VERSION),
393 ATM_VERS_MAJ(atm_version), ATM_VERS_MIN(atm_version));
398 * Register ourselves as a network convergence module
400 err = atm_netconv_register(&ipatm_ncm);
405 * Register ourselves as an ATM endpoint
407 err = atm_endpoint_register(&ipatm_endpt);
412 * Get current system configuration
415 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
417 * Process each network interface
419 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
420 struct ifnet *ifp = (struct ifnet *)nip;
421 struct in_ifaddr *ia;
426 err = ipatm_nifstat(NCM_ATTACH, nip, 0);
433 * If IP address has been set, register it
435 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
436 if (ia->ia_ifp == ifp)
440 err = ipatm_nifstat(NCM_SETADDR, nip, (int)ia);
451 * Fill in union fields
453 ipatm_aal5llc.aal.v.aal5.forward_max_SDU_size =
454 ATM_NIF_MTU + IPATM_LLC_LEN;
455 ipatm_aal5llc.aal.v.aal5.backward_max_SDU_size =
456 ATM_NIF_MTU + IPATM_LLC_LEN;
457 ipatm_aal5llc.aal.v.aal5.SSCS_type = T_ATM_NULL;
458 ipatm_aal5llc.blli.v.layer_2_protocol.ID.simple_ID = T_ATM_BLLI2_I8802;
460 ipatm_aal5null.aal.v.aal5.forward_max_SDU_size = ATM_NIF_MTU;
461 ipatm_aal5null.aal.v.aal5.backward_max_SDU_size = ATM_NIF_MTU;
462 ipatm_aal5null.aal.v.aal5.SSCS_type = T_ATM_NULL;
464 ipatm_aal4null.aal.v.aal4.forward_max_SDU_size = ATM_NIF_MTU;
465 ipatm_aal4null.aal.v.aal4.backward_max_SDU_size = ATM_NIF_MTU;
466 ipatm_aal4null.aal.v.aal4.SSCS_type = T_ATM_NULL;
467 ipatm_aal4null.aal.v.aal4.mid_low = 0;
468 ipatm_aal4null.aal.v.aal4.mid_high = 1023;
471 * Listen for incoming calls
474 i < (sizeof(ipatm_listeners) / sizeof(struct ipatm_listener));
476 struct attr_aal *aalp = &ipatm_listeners[i].attr.aal;
477 int maxsdu = ATM_NIF_MTU;
480 * Fill in union fields
482 if (ipatm_listeners[i].attr.blli.tag_l2 == T_ATM_PRESENT) {
483 struct t_atm_blli *bp = &ipatm_listeners[i].attr.blli.v;
485 bp->layer_2_protocol.ID.simple_ID = T_ATM_BLLI2_I8802;
486 maxsdu += IPATM_LLC_LEN;
488 if (aalp->type == ATM_AAL5) {
489 aalp->v.aal5.forward_max_SDU_size = maxsdu;
490 aalp->v.aal5.backward_max_SDU_size = maxsdu;
491 aalp->v.aal5.SSCS_type = T_ATM_NULL;
493 aalp->v.aal4.forward_max_SDU_size = maxsdu;
494 aalp->v.aal4.backward_max_SDU_size = maxsdu;
495 aalp->v.aal4.SSCS_type = T_ATM_NULL;
496 aalp->v.aal4.mid_low = 0;
497 aalp->v.aal4.mid_high = 1023;
501 * Now start listening
503 if ((err = atm_cm_listen(&ipatm_endpt, (void *)i,
504 &ipatm_listeners[i].attr,
505 &ipatm_listeners[i].conn)) != 0)
510 * Start background VCC idle timer
512 atm_timeout(&ipatm_itimer, IPATM_IDLE_TIME, ipatm_itimeout);
520 * Halt ipatm processing
522 * This will be called just prior to unloading the module from
523 * memory. All IP VCCs must be terminated before the protocol can
530 * 0 shutdown was successful
531 * errno shutdown failed - reason indicated
542 * Any VCCs still open??
546 /* Yes, can't stop now */
552 * Kill VCC idle timer
554 (void) atm_untimeout(&ipatm_itimer);
557 * Stop listening for incoming calls
560 i < (sizeof(ipatm_listeners) / sizeof(struct ipatm_listener));
562 if (ipatm_listeners[i].conn != NULL) {
563 (void) atm_cm_release(ipatm_listeners[i].conn,
569 * Detach all our interfaces
571 while ((inp = ipatm_nif_head) != NULL) {
572 (void) ipatm_nifstat(NCM_DETACH, inp->inf_nif, 0);
576 * De-register from system
578 (void) atm_netconv_deregister(&ipatm_ncm);
579 (void) atm_endpoint_deregister(&ipatm_endpt);
582 * Free up our storage pools
584 atm_release_pool(&ipatm_vcpool);
585 atm_release_pool(&ipatm_nifpool);
595 *******************************************************************
597 * Loadable Module Support
599 *******************************************************************
601 static int ipatm_doload __P((void));
602 static int ipatm_dounload __P((void));
605 * Generic module load processing
607 * This function is called by an OS-specific function when this
608 * module is being loaded.
614 * 0 load was successful
615 * errno load failed - reason indicated
628 /* Problems, clean up */
636 * Generic module unload processing
638 * This function is called by an OS-specific function when this
639 * module is being unloaded.
645 * 0 unload was successful
646 * errno unload failed - reason indicated
655 * OK, try to clean up our mess
665 * Loadable driver description
667 struct vdldrv ipatm_drv = {
668 VDMAGIC_PSEUDO, /* Pseudo Driver */
669 "ipatm_mod", /* name */
679 * Loadable module support entry point
681 * This is the routine called by the vd driver for all loadable module
682 * functions for this pseudo driver. This routine name must be specified
683 * on the modload(1) command. This routine will be called whenever the
684 * modload(1), modunload(1) or modstat(1) commands are issued for this
688 * cmd vd command code
689 * vdp pointer to vd driver's structure
690 * vdi pointer to command-specific vdioctl_* structure
691 * vds pointer to status structure (VDSTAT only)
694 * 0 command was successful
695 * errno command failed - reason indicated
699 ipatm_mod(cmd, vdp, vdi, vds)
713 * We dont support any user configuration
715 err = ipatm_doload();
717 /* Let vd driver know about us */
718 vdp->vdd_vdtab = (struct vdlinkage *)&ipatm_drv;
725 err = ipatm_dounload();
733 /* Not much to say at the moment */
738 log(LOG_ERR, "ipatm_mod: Unknown vd command 0x%x\n", cmd);
748 #include <sys/exec.h>
749 #include <sys/sysent.h>
753 * Loadable miscellaneous module description
759 * Loadable module support "load" entry point
761 * This is the routine called by the lkm driver whenever the
762 * modload(1) command is issued for this module.
765 * lkmtp pointer to lkm drivers's structure
766 * cmd lkm command code
769 * 0 command was successful
770 * errno command failed - reason indicated
774 ipatm_load(lkmtp, cmd)
775 struct lkm_table *lkmtp;
778 return(ipatm_doload());
783 * Loadable module support "unload" entry point
785 * This is the routine called by the lkm driver whenever the
786 * modunload(1) command is issued for this module.
789 * lkmtp pointer to lkm drivers's structure
790 * cmd lkm command code
793 * 0 command was successful
794 * errno command failed - reason indicated
798 ipatm_unload(lkmtp, cmd)
799 struct lkm_table *lkmtp;
802 return(ipatm_dounload());
807 * Loadable module support entry point
809 * This is the routine called by the lkm driver for all loadable module
810 * functions for this driver. This routine name must be specified
811 * on the modload(1) command. This routine will be called whenever the
812 * modload(1), modunload(1) or modstat(1) commands are issued for this
816 * lkmtp pointer to lkm drivers's structure
817 * cmd lkm command code
821 * 0 command was successful
822 * errno command failed - reason indicated
826 ipatm_mod(lkmtp, cmd, ver)
827 struct lkm_table *lkmtp;
831 MOD_DISPATCH(ipatm, lkmtp, cmd, ver,
832 ipatm_load, ipatm_unload, lkm_nullcmd);
834 #endif /* __FreeBSD__ */
836 #else /* !ATM_IP_MODULE */
839 *******************************************************************
841 * Kernel Compiled Module Support
843 *******************************************************************
845 static void ipatm_doload __P((void *));
847 SYSINIT(atmipatm, SI_SUB_PROTO_END, SI_ORDER_ANY, ipatm_doload, NULL)
850 * Kernel initialization
860 ipatm_doload(void *arg)
869 /* Problems, clean up */
872 log(LOG_ERR, "IP over ATM unable to initialize (%d)!!\n", err);
876 #endif /* ATM_IP_MODULE */