Line 0
Link Here
|
|
|
1 |
--- src/pppoe.c 2013-06-11 10:00:00.000000000 +0100 |
2 |
+++ src/pppoe.c 2015-09-22 20:49:57.000000000 +0100 |
3 |
@@ -50,12 +50,14 @@ |
4 |
char hook[NG_HOOKSIZ]; /* hook on that node */ |
5 |
char session[MAX_SESSION]; /* session name */ |
6 |
char acname[PPPOE_SERVICE_NAME_SIZE]; /* AC name */ |
7 |
+ uint16_t max_payload; /* PPP-Max-Payload (RFC4638) */ |
8 |
u_char peeraddr[6]; /* Peer MAC address */ |
9 |
char real_session[MAX_SESSION]; /* real session name */ |
10 |
char agent_cid[64]; /* Agent Circuit ID */ |
11 |
char agent_rid[64]; /* Agent Remote ID */ |
12 |
u_char incoming; /* incoming vs. outgoing */ |
13 |
u_char opened; /* PPPoE opened by phys */ |
14 |
+ u_char mp_reply; /* PPP-Max-Payload reply from server */ |
15 |
struct optinfo options; |
16 |
struct PppoeIf *PIf; /* pointer on parent ng_pppoe info */ |
17 |
struct PppoeList *list; |
18 |
@@ -69,7 +71,8 @@ |
19 |
enum { |
20 |
SET_IFACE, |
21 |
SET_SESSION, |
22 |
- SET_ACNAME |
23 |
+ SET_ACNAME, |
24 |
+ SET_MAX_PAYLOAD |
25 |
}; |
26 |
|
27 |
/* |
28 |
@@ -113,6 +116,8 @@ |
29 |
static int PppoeCalledNum(Link l, void *buf, size_t buf_len); |
30 |
static int PppoeSelfName(Link l, void *buf, size_t buf_len); |
31 |
static int PppoePeerName(Link l, void *buf, size_t buf_len); |
32 |
+static u_short PppoeGetMtu(Link l, int conf); |
33 |
+static u_short PppoeGetMru(Link l, int conf); |
34 |
static void PppoeCtrlReadEvent(int type, void *arg); |
35 |
static void PppoeConnectTimeout(void *arg); |
36 |
static void PppoeStat(Context ctx); |
37 |
@@ -155,6 +160,8 @@ |
38 |
.callednum = PppoeCalledNum, |
39 |
.selfname = PppoeSelfName, |
40 |
.peername = PppoePeerName, |
41 |
+ .getmtu = PppoeGetMtu, |
42 |
+ .getmru = PppoeGetMru |
43 |
}; |
44 |
|
45 |
const struct cmdtab PppoeSetCmds[] = { |
46 |
@@ -164,6 +171,10 @@ |
47 |
PppoeSetCommand, NULL, 2, (void *)SET_SESSION }, |
48 |
{ "acname {name}", "Set PPPoE access concentrator name", |
49 |
PppoeSetCommand, NULL, 2, (void *)SET_ACNAME }, |
50 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
51 |
+ { "max-payload {size}", "Set PPP-Max-Payload tag", |
52 |
+ PppoeSetCommand, NULL, 2, (void *)SET_MAX_PAYLOAD }, |
53 |
+#endif |
54 |
{ NULL }, |
55 |
}; |
56 |
|
57 |
@@ -213,6 +224,8 @@ |
58 |
pe->agent_cid[0] = 0; |
59 |
pe->agent_rid[0] = 0; |
60 |
pe->PIf = NULL; |
61 |
+ pe->max_payload = 0; |
62 |
+ pe->mp_reply = 0; |
63 |
|
64 |
/* Done */ |
65 |
return(0); |
66 |
@@ -327,6 +340,20 @@ |
67 |
l->name, path, cn.ourhook, cn.path, cn.peerhook); |
68 |
goto fail2; |
69 |
} |
70 |
+ |
71 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
72 |
+ const uint16_t max_payload = pe->max_payload; |
73 |
+ if (pe->max_payload > 0) { |
74 |
+ Log(LG_PHYS, ("[%s] PPPoE: Set PPP-Max-Payload to '%d'", |
75 |
+ l->name, max_payload)); |
76 |
+ } |
77 |
+ /* Tell the PPPoE node to set PPP-Max-Payload value (unset if 0). */ |
78 |
+ if (NgSendMsg(pe->PIf->csock, path, NGM_PPPOE_COOKIE, NGM_PPPOE_SETMAXP, |
79 |
+ &max_payload, sizeof(uint16_t)) < 0) { |
80 |
+ Perror("[%s] PPPoE can't set PPP-Max-Payload value", l->name); |
81 |
+ goto fail2; |
82 |
+ } |
83 |
+#endif |
84 |
|
85 |
Log(LG_PHYS, ("[%s] PPPoE: Connecting to '%s'", l->name, pe->session)); |
86 |
|
87 |
@@ -351,6 +378,7 @@ |
88 |
strlcpy(pe->real_session, pe->session, sizeof(pe->real_session)); |
89 |
pe->agent_cid[0] = 0; |
90 |
pe->agent_rid[0] = 0; |
91 |
+ pe->mp_reply = 0; |
92 |
return; |
93 |
|
94 |
fail3: |
95 |
@@ -433,6 +461,7 @@ |
96 |
pi->real_session[0] = 0; |
97 |
pi->agent_cid[0] = 0; |
98 |
pi->agent_rid[0] = 0; |
99 |
+ pi->mp_reply = 0; |
100 |
} |
101 |
|
102 |
/* |
103 |
@@ -444,7 +473,11 @@ |
104 |
PppoeCtrlReadEvent(int type, void *arg) |
105 |
{ |
106 |
union { |
107 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
108 |
+ u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_maxp)]; |
109 |
+#else |
110 |
u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)]; |
111 |
+#endif |
112 |
struct ng_mesg resp; |
113 |
} u; |
114 |
char path[NG_PATHSIZ]; |
115 |
@@ -468,6 +501,9 @@ |
116 |
case NGM_PPPOE_SUCCESS: |
117 |
case NGM_PPPOE_FAIL: |
118 |
case NGM_PPPOE_CLOSE: |
119 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
120 |
+ case NGM_PPPOE_SETMAXP: |
121 |
+#endif |
122 |
{ |
123 |
char ppphook[NG_HOOKSIZ]; |
124 |
char *linkname, *rest; |
125 |
@@ -535,6 +571,28 @@ |
126 |
Log(LG_PHYS, ("PPPoE: rec'd ACNAME \"%s\"", |
127 |
((struct ngpppoe_sts *)u.resp.data)->hook)); |
128 |
break; |
129 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
130 |
+ case NGM_PPPOE_SETMAXP: |
131 |
+ { |
132 |
+ struct ngpppoe_maxp *maxp; |
133 |
+ |
134 |
+ maxp = ((struct ngpppoe_maxp *)u.resp.data); |
135 |
+ Log(LG_PHYS, ("[%s] PPPoE: rec'd PPP-Max-Payload '%u'", |
136 |
+ l->name, maxp->data)); |
137 |
+ if (pi->max_payload > 0) { |
138 |
+ if (pi->max_payload == maxp->data) |
139 |
+ pi->mp_reply = 1; |
140 |
+ else |
141 |
+ Log(LG_PHYS, |
142 |
+ ("[%s] PPPoE: sent and returned values are not equal", |
143 |
+ l->name)); |
144 |
+ } else |
145 |
+ Log(LG_PHYS, ("[%s] PPPoE: server sent tag PPP-Max-Payload" |
146 |
+ " without request from the client", |
147 |
+ l->name)); |
148 |
+ break; |
149 |
+ } |
150 |
+#endif |
151 |
default: |
152 |
Log(LG_PHYS, ("PPPoE: rec'd command %lu from \"%s\"", |
153 |
(u_long)u.resp.header.cmd, path)); |
154 |
@@ -555,6 +613,9 @@ |
155 |
Printf("\tIface Node : %s\r\n", pe->path); |
156 |
Printf("\tIface Hook : %s\r\n", pe->hook); |
157 |
Printf("\tSession : %s\r\n", pe->session); |
158 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
159 |
+ Printf("\tMax-Payload : %u\r\n", pe->max_payload); |
160 |
+#endif |
161 |
Printf("PPPoE status:\r\n"); |
162 |
if (ctx->lnk->state != PHYS_STATE_DOWN) { |
163 |
Printf("\tOpened : %s\r\n", (pe->opened?"YES":"NO")); |
164 |
@@ -562,6 +623,7 @@ |
165 |
PppoePeerMacAddr(ctx->lnk, buf, sizeof(buf)); |
166 |
Printf("\tCurrent peer : %s\r\n", buf); |
167 |
Printf("\tSession : %s\r\n", pe->real_session); |
168 |
+ Printf("\tMax-Payload : %s\r\n", (pe->mp_reply?"YES":"NO")); |
169 |
Printf("\tCircuit-ID : %s\r\n", pe->agent_cid); |
170 |
Printf("\tRemote-ID : %s\r\n", pe->agent_rid); |
171 |
} |
172 |
@@ -657,6 +719,34 @@ |
173 |
return (0); |
174 |
} |
175 |
|
176 |
+static u_short |
177 |
+PppoeGetMtu(Link l, int conf) |
178 |
+{ |
179 |
+ PppoeInfo const pppoe = (PppoeInfo)l->info; |
180 |
+ |
181 |
+ if (pppoe->max_payload > 0 && pppoe->mp_reply > 0) |
182 |
+ return (pppoe->max_payload); |
183 |
+ else |
184 |
+ if (conf == 0) |
185 |
+ return (l->type->mtu); |
186 |
+ else |
187 |
+ return (l->conf.mtu); |
188 |
+} |
189 |
+ |
190 |
+static u_short |
191 |
+PppoeGetMru(Link l, int conf) |
192 |
+{ |
193 |
+ PppoeInfo const pppoe = (PppoeInfo)l->info; |
194 |
+ |
195 |
+ if (pppoe->max_payload > 0 && pppoe->mp_reply > 0) |
196 |
+ return (pppoe->max_payload); |
197 |
+ else |
198 |
+ if (conf == 0) |
199 |
+ return (l->type->mru); |
200 |
+ else |
201 |
+ return (l->conf.mru); |
202 |
+} |
203 |
+ |
204 |
static int |
205 |
CreatePppoeNode(struct PppoeIf *PIf, const char *path, const char *hook) |
206 |
{ |
207 |
@@ -1340,7 +1430,9 @@ |
208 |
const PppoeInfo pi = (PppoeInfo) ctx->lnk->info; |
209 |
const char *hookname = ETHER_DEFAULT_HOOK; |
210 |
const char *colon; |
211 |
- |
212 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
213 |
+ int ap; |
214 |
+#endif |
215 |
switch ((intptr_t)arg) { |
216 |
case SET_IFACE: |
217 |
switch (ac) { |
218 |
@@ -1377,6 +1469,16 @@ |
219 |
return(-1); |
220 |
strlcpy(pi->acname, av[0], sizeof(pi->acname)); |
221 |
break; |
222 |
+#ifdef NGM_PPPOE_SETMAXP_COOKIE |
223 |
+ case SET_MAX_PAYLOAD: |
224 |
+ if (ac != 1) |
225 |
+ return(-1); |
226 |
+ ap = atoi(av[0]); |
227 |
+ if (ap < PPPOE_MRU || ap > ETHER_MAX_LEN - 8) |
228 |
+ Error("PPP-Max-Payload value \"%s\"", av[0]); |
229 |
+ pi->max_payload = ap; |
230 |
+ break; |
231 |
+#endif |
232 |
default: |
233 |
assert(0); |
234 |
} |