1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/kernel.h>
28#include <sys/malloc.h>
29#include <sys/mbuf.h>
30#include <sys/socket.h>
31#include <sys/sockio.h>
32#include <sys/sysctl.h>
33
34#include <sys/syslog.h>
35#include <mach/vm_types.h>
36#include <mach/kmod.h>
37#include <sys/socketvar.h>
38#include <sys/protosw.h>
39#include <sys/domain.h>
40#include <kern/thread.h>
41#include <kern/locks.h>
42#include <net/if.h>
43
44#include "../../../Family/if_ppplink.h"
45#include "../../../Family/ppp_domain.h"
46#include "PPPoE.h"
47#include "pppoe_proto.h"
48#include "pppoe_wan.h"
49#include "pppoe_rfc.h"
50
51
52/* -----------------------------------------------------------------------------
53Definitions
54----------------------------------------------------------------------------- */
55
56
57/* -----------------------------------------------------------------------------
58Forward declarations
59----------------------------------------------------------------------------- */
60int pppoe_domain_init(int);
61int pppoe_domain_terminate(int);
62
63/* this function has not prototype in the .h file */
64struct domain *pffinddomain(int pf);
65
66/* -----------------------------------------------------------------------------
67Globals
68----------------------------------------------------------------------------- */
69
70int 		pppoe_domain_inited = 0;
71
72extern lck_mtx_t   *ppp_domain_mutex;
73
74/* -----------------------------------------------------------------------------
75----------------------------------------------------------------------------- */
76int pppoe_domain_module_start(struct kmod_info *ki, void *data)
77{
78    //boolean_t 	funnel_state;
79    int		ret;
80
81    //funnel_state = thread_funnel_set(network_flock, TRUE);
82    ret = pppoe_domain_init(0);
83    //thread_funnel_set(network_flock, funnel_state);
84
85    return ret;
86}
87
88/* -----------------------------------------------------------------------------
89----------------------------------------------------------------------------- */
90int pppoe_domain_module_stop(struct kmod_info *ki, void *data)
91{
92    //boolean_t 	funnel_state;
93    int		ret;
94
95    //funnel_state = thread_funnel_set(network_flock, TRUE);
96    ret = pppoe_domain_terminate(0);
97    //thread_funnel_set(network_flock, funnel_state);
98
99    return ret;
100}
101
102/* -----------------------------------------------------------------------------
103----------------------------------------------------------------------------- */
104int pppoe_domain_init(int init_arg)
105{
106    int 	ret = KERN_SUCCESS;
107    struct domain *pppdomain;
108
109    IOLog("PPPoE domain init\n");
110
111    if (pppoe_domain_inited)
112        return(KERN_SUCCESS);
113
114    pppdomain = pffinddomain(PF_PPP);
115    if (!pppdomain) {
116        IOLog("PPPoE domain init : PF_PPP domain does not exist...\n");
117        return(KERN_FAILURE);
118    }
119
120	lck_mtx_lock(ppp_domain_mutex);
121
122    ret = pppoe_rfc_init();
123    if (ret) {
124        IOLog("PPPoE domain init : can't init PPPoE protocol RFC, err : %d\n", ret);
125        goto end;
126    }
127
128    ret = pppoe_add(pppdomain);
129    if (ret) {
130        IOLog("PPPoE domain init : can't add proto to PPPoE domain, err : %d\n", ret);
131        pppoe_rfc_dispose();
132        goto end;
133    }
134
135    pppoe_wan_init();
136
137    pppoe_domain_inited = 1;
138
139end:
140	lck_mtx_unlock(ppp_domain_mutex);
141    return ret;
142}
143
144
145/* -----------------------------------------------------------------------------
146----------------------------------------------------------------------------- */
147int pppoe_domain_terminate(int term_arg)
148{
149    int 	ret = KERN_SUCCESS;
150    struct domain *pppdomain;
151
152    IOLog("PPPoE domain terminate\n");
153
154    if (!pppoe_domain_inited)
155        return(KERN_SUCCESS);
156
157	pppdomain = pffinddomain(PF_PPP);
158    if (!pppdomain) {
159        // humm.. should not happen
160        IOLog("PPPoE domain terminate : PF_PPP domain does not exist...\n");
161        return KERN_FAILURE;
162    }
163
164	lck_mtx_lock(ppp_domain_mutex);
165
166    ret = pppoe_rfc_dispose();
167    if (ret) {
168        IOLog("PPPoE domain is in use and cannot terminate, err : %d\n", ret);
169        goto end;
170    }
171
172    ret = pppoe_wan_dispose();
173    if (ret) {
174        IOLog("PPPoE domain terminate : pppoe_wan_dispose, err : %d\n", ret);
175        goto end;
176    }
177
178    ret = pppoe_remove(pppdomain);
179    if (ret) {
180        IOLog("PPPoE domain terminate : can't del proto from PPPoE domain, err : %d\n", ret);
181        goto end;
182    }
183
184    pppoe_domain_inited = 0;
185
186end:
187	lck_mtx_unlock(ppp_domain_mutex);
188    return ret;
189}
190