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 $
27 * @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_load.c,v 1.3 2003/08/07 21:17:34 dillon Exp $
34 * Support for running as a loadable kernel module
42 #include <netatm/kern_include.h>
45 #include "ipatm_var.h"
51 int ipatm_vcidle = IPATM_VCIDLE;
53 u_long last_map_ipdst = 0;
54 struct ipvcc* last_map_ipvcc = NULL;
56 struct ip_nif *ipatm_nif_head = NULL;
58 struct ipatm_stat ipatm_stat = {0};
60 struct atm_time ipatm_itimer = {0, 0}; /* VCC idle timer */
62 Atm_endpoint ipatm_endpt = {
80 struct sp_info ipatm_vcpool = {
81 "ipatm vcc pool", /* si_name */
82 sizeof(struct ipvcc), /* si_blksiz */
87 struct sp_info ipatm_nifpool = {
88 "ipatm nif pool", /* si_name */
89 sizeof(struct ip_nif), /* si_blksiz */
98 static int ipatm_start __P((void));
99 static int ipatm_stop __P((void));
105 static struct atm_ncm ipatm_ncm = {
112 static struct ipatm_listener {
114 Atm_connection *conn;
115 } ipatm_listeners[] = {
118 CMAPI_CPCS, /* api */
185 T_ATM_NETWORK_CODING,
205 CMAPI_CPCS, /* api */
259 T_ATM_NETWORK_CODING,
279 CMAPI_CPCS, /* api */
333 T_ATM_NETWORK_CODING,
353 static struct t_atm_cause ipatm_cause = {
356 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
362 * Initialize ipatm processing
364 * This will be called during module loading. We'll just register
365 * ourselves and wait for the packets to start flying.
371 * 0 startup was successful
372 * errno startup failed - reason indicated
383 * Verify software version
385 if (atm_version != ATM_VERSION) {
386 log(LOG_ERR, "version mismatch: ipatm=%d.%d kernel=%d.%d\n",
387 ATM_VERS_MAJ(ATM_VERSION), ATM_VERS_MIN(ATM_VERSION),
388 ATM_VERS_MAJ(atm_version), ATM_VERS_MIN(atm_version));
393 * Register ourselves as a network convergence module
395 err = atm_netconv_register(&ipatm_ncm);
400 * Register ourselves as an ATM endpoint
402 err = atm_endpoint_register(&ipatm_endpt);
407 * Get current system configuration
410 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
412 * Process each network interface
414 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
415 struct ifnet *ifp = (struct ifnet *)nip;
416 struct in_ifaddr *ia;
421 err = ipatm_nifstat(NCM_ATTACH, nip, 0);
428 * If IP address has been set, register it
430 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
431 if (ia->ia_ifp == ifp)
435 err = ipatm_nifstat(NCM_SETADDR, nip, (int)ia);
446 * Fill in union fields
448 ipatm_aal5llc.aal.v.aal5.forward_max_SDU_size =
449 ATM_NIF_MTU + IPATM_LLC_LEN;
450 ipatm_aal5llc.aal.v.aal5.backward_max_SDU_size =
451 ATM_NIF_MTU + IPATM_LLC_LEN;
452 ipatm_aal5llc.aal.v.aal5.SSCS_type = T_ATM_NULL;
453 ipatm_aal5llc.blli.v.layer_2_protocol.ID.simple_ID = T_ATM_BLLI2_I8802;
455 ipatm_aal5null.aal.v.aal5.forward_max_SDU_size = ATM_NIF_MTU;
456 ipatm_aal5null.aal.v.aal5.backward_max_SDU_size = ATM_NIF_MTU;
457 ipatm_aal5null.aal.v.aal5.SSCS_type = T_ATM_NULL;
459 ipatm_aal4null.aal.v.aal4.forward_max_SDU_size = ATM_NIF_MTU;
460 ipatm_aal4null.aal.v.aal4.backward_max_SDU_size = ATM_NIF_MTU;
461 ipatm_aal4null.aal.v.aal4.SSCS_type = T_ATM_NULL;
462 ipatm_aal4null.aal.v.aal4.mid_low = 0;
463 ipatm_aal4null.aal.v.aal4.mid_high = 1023;
466 * Listen for incoming calls
469 i < (sizeof(ipatm_listeners) / sizeof(struct ipatm_listener));
471 struct attr_aal *aalp = &ipatm_listeners[i].attr.aal;
472 int maxsdu = ATM_NIF_MTU;
475 * Fill in union fields
477 if (ipatm_listeners[i].attr.blli.tag_l2 == T_ATM_PRESENT) {
478 struct t_atm_blli *bp = &ipatm_listeners[i].attr.blli.v;
480 bp->layer_2_protocol.ID.simple_ID = T_ATM_BLLI2_I8802;
481 maxsdu += IPATM_LLC_LEN;
483 if (aalp->type == ATM_AAL5) {
484 aalp->v.aal5.forward_max_SDU_size = maxsdu;
485 aalp->v.aal5.backward_max_SDU_size = maxsdu;
486 aalp->v.aal5.SSCS_type = T_ATM_NULL;
488 aalp->v.aal4.forward_max_SDU_size = maxsdu;
489 aalp->v.aal4.backward_max_SDU_size = maxsdu;
490 aalp->v.aal4.SSCS_type = T_ATM_NULL;
491 aalp->v.aal4.mid_low = 0;
492 aalp->v.aal4.mid_high = 1023;
496 * Now start listening
498 if ((err = atm_cm_listen(&ipatm_endpt, (void *)i,
499 &ipatm_listeners[i].attr,
500 &ipatm_listeners[i].conn)) != 0)
505 * Start background VCC idle timer
507 atm_timeout(&ipatm_itimer, IPATM_IDLE_TIME, ipatm_itimeout);
515 * Halt ipatm processing
517 * This will be called just prior to unloading the module from
518 * memory. All IP VCCs must be terminated before the protocol can
525 * 0 shutdown was successful
526 * errno shutdown failed - reason indicated
537 * Any VCCs still open??
541 /* Yes, can't stop now */
547 * Kill VCC idle timer
549 (void) atm_untimeout(&ipatm_itimer);
552 * Stop listening for incoming calls
555 i < (sizeof(ipatm_listeners) / sizeof(struct ipatm_listener));
557 if (ipatm_listeners[i].conn != NULL) {
558 (void) atm_cm_release(ipatm_listeners[i].conn,
564 * Detach all our interfaces
566 while ((inp = ipatm_nif_head) != NULL) {
567 (void) ipatm_nifstat(NCM_DETACH, inp->inf_nif, 0);
571 * De-register from system
573 (void) atm_netconv_deregister(&ipatm_ncm);
574 (void) atm_endpoint_deregister(&ipatm_endpt);
577 * Free up our storage pools
579 atm_release_pool(&ipatm_vcpool);
580 atm_release_pool(&ipatm_nifpool);
590 *******************************************************************
592 * Loadable Module Support
594 *******************************************************************
596 static int ipatm_doload __P((void));
597 static int ipatm_dounload __P((void));
600 * Generic module load processing
602 * This function is called by an OS-specific function when this
603 * module is being loaded.
609 * 0 load was successful
610 * errno load failed - reason indicated
623 /* Problems, clean up */
631 * Generic module unload processing
633 * This function is called by an OS-specific function when this
634 * module is being unloaded.
640 * 0 unload was successful
641 * errno unload failed - reason indicated
650 * OK, try to clean up our mess
660 * Loadable driver description
662 struct vdldrv ipatm_drv = {
663 VDMAGIC_PSEUDO, /* Pseudo Driver */
664 "ipatm_mod", /* name */
674 * Loadable module support entry point
676 * This is the routine called by the vd driver for all loadable module
677 * functions for this pseudo driver. This routine name must be specified
678 * on the modload(1) command. This routine will be called whenever the
679 * modload(1), modunload(1) or modstat(1) commands are issued for this
683 * cmd vd command code
684 * vdp pointer to vd driver's structure
685 * vdi pointer to command-specific vdioctl_* structure
686 * vds pointer to status structure (VDSTAT only)
689 * 0 command was successful
690 * errno command failed - reason indicated
694 ipatm_mod(cmd, vdp, vdi, vds)
708 * We dont support any user configuration
710 err = ipatm_doload();
712 /* Let vd driver know about us */
713 vdp->vdd_vdtab = (struct vdlinkage *)&ipatm_drv;
720 err = ipatm_dounload();
728 /* Not much to say at the moment */
733 log(LOG_ERR, "ipatm_mod: Unknown vd command 0x%x\n", cmd);
743 #include <sys/exec.h>
744 #include <sys/sysent.h>
748 * Loadable miscellaneous module description
754 * Loadable module support "load" entry point
756 * This is the routine called by the lkm driver whenever the
757 * modload(1) command is issued for this module.
760 * lkmtp pointer to lkm drivers's structure
761 * cmd lkm command code
764 * 0 command was successful
765 * errno command failed - reason indicated
769 ipatm_load(lkmtp, cmd)
770 struct lkm_table *lkmtp;
773 return(ipatm_doload());
778 * Loadable module support "unload" entry point
780 * This is the routine called by the lkm driver whenever the
781 * modunload(1) command is issued for this module.
784 * lkmtp pointer to lkm drivers's structure
785 * cmd lkm command code
788 * 0 command was successful
789 * errno command failed - reason indicated
793 ipatm_unload(lkmtp, cmd)
794 struct lkm_table *lkmtp;
797 return(ipatm_dounload());
802 * Loadable module support entry point
804 * This is the routine called by the lkm driver for all loadable module
805 * functions for this driver. This routine name must be specified
806 * on the modload(1) command. This routine will be called whenever the
807 * modload(1), modunload(1) or modstat(1) commands are issued for this
811 * lkmtp pointer to lkm drivers's structure
812 * cmd lkm command code
816 * 0 command was successful
817 * errno command failed - reason indicated
821 ipatm_mod(lkmtp, cmd, ver)
822 struct lkm_table *lkmtp;
826 MOD_DISPATCH(ipatm, lkmtp, cmd, ver,
827 ipatm_load, ipatm_unload, lkm_nullcmd);
829 #endif /* __FreeBSD__ */
831 #else /* !ATM_IP_MODULE */
834 *******************************************************************
836 * Kernel Compiled Module Support
838 *******************************************************************
840 static void ipatm_doload __P((void *));
842 SYSINIT(atmipatm, SI_SUB_PROTO_END, SI_ORDER_ANY, ipatm_doload, NULL)
845 * Kernel initialization
855 ipatm_doload(void *arg)
864 /* Problems, clean up */
867 log(LOG_ERR, "IP over ATM unable to initialize (%d)!!\n", err);
871 #endif /* ATM_IP_MODULE */