aboutsummaryrefslogtreecommitdiffstats
path: root/net/mpd5/files/patch-max-payload
blob: f4018811369fd420a28ae8860741d9e23fe329fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
Index: src/link.c
===================================================================
--- src/link.c	(revision 2481)
+++ src/link.c	(working copy)
@@ -435,7 +435,8 @@ LinkCreate(Context ctx, int ac, const char *const av[]
 
 	/* Initialize link configuration with defaults */
 	l->conf.mru = LCP_DEFAULT_MRU;
-        l->conf.mtu = LCP_DEFAULT_MRU;
+	/* Do not assume any MTU value for this moment */
+	l->conf.mtu = 0;
 	l->conf.mrru = MP_DEFAULT_MRRU;
         l->conf.accmap = 0x000a0000;
         l->conf.max_redial = -1;
@@ -1549,9 +1562,9 @@ LinkSetCommand(Context ctx, int ac, const char *const 
     	    name = ((intptr_t)arg == SET_MTU) ? "MTU" : "MRU";
     	    if (val < LCP_MIN_MRU)
 		Error("min %s is %d", name, LCP_MIN_MRU);
-    	    else if (l->type && (val > l->type->mru)) {
+    	    else if (l->type && (val > l->type->mtu)) {
 		Error("max %s on type \"%s\" links is %d",
-		    name, l->type->name, l->type->mru);
+		    name, l->type->name, l->type->mtu);
     	    } else if ((intptr_t)arg == SET_MTU)
 		l->conf.mtu = val;
     	    else
Index: src/phys.c
===================================================================
--- src/phys.c	(revision 2481)
+++ src/phys.c	(working copy)
@@ -483,7 +483,7 @@ PhysGetMtu(Link l, int conf)
 	    else
 		return (0);
 	} else
-	    return (l->conf.mtu);
+	    return (l->conf.mtu ? l->conf.mtu : LCP_DEFAULT_MRU);
     } else
 	return (0);
 }
Index: src/pppoe.c
===================================================================
--- src/pppoe.c	(revision 2481)
+++ src/pppoe.c	(working copy)
@@ -31,6 +31,7 @@
  * DEFINITIONS
  */
 
+#define PPPOE_MTU_MAX		(ETHER_MAX_LEN_JUMBO - 8)
 #define PPPOE_MTU		1492	/* allow room for PPPoE overhead */
 #define PPPOE_MRU		1492
 
@@ -181,7 +182,7 @@ static void	PppoeDoClose(Link l);
 const struct phystype gPppoePhysType = {
     .name		= "pppoe",
     .descr		= "PPP over Ethernet",
-    .mtu		= PPPOE_MTU,
+    .mtu		= PPPOE_MTU_MAX,
     .mru		= PPPOE_MRU,
     .tmpl		= 1,
     .init		= PppoeInit,
@@ -886,7 +887,7 @@ PppoeGetMtu(Link l, int conf)
 	    if (conf == 0)
 		return (l->type->mtu);
 	    else
-		return (l->conf.mtu);
+		return (l->conf.mtu ? l->conf.mtu : PPPOE_MTU);
 }
 
 static u_short
@@ -1712,6 +1718,7 @@ PppoeSetCommand(Context ctx, int ac, const char *const
 	unsigned i;
 #ifdef NGM_PPPOE_SETMAXP_COOKIE
 	int ap;
+	uint16_t mtu;
 #endif
 	switch ((intptr_t)arg) {
 	case SET_IFACE:
@@ -1732,6 +1739,20 @@ PppoeSetCommand(Context ctx, int ac, const char *const
 				}
 			}
 			strlcpy(pi->hook, hookname, sizeof(pi->hook));
+
+#ifdef NGM_PPPOE_SETMAXP_COOKIE
+			if (pi->max_payload > 0) {
+				mtu = GetSystemIfaceMTU(pi->iface);
+				if (mtu == 0)
+					mtu = ETHER_MAX_LEN;
+				if (pi->max_payload > mtu - 8) {
+					pi->max_payload = mtu - 8;
+					Perror("[%s] PPPoE: PPP-Max-Payload"
+					       " value reduced to %hu",
+						pi->iface, pi->max_payload);
+				}
+			}
+#endif
 			break;
 		default:
 			return(-1);
@@ -1762,8 +1783,18 @@ PppoeSetCommand(Context ctx, int ac, const char *const
 		if (ac != 1)
 			return(-1);
 		ap = atoi(av[0]);
-		if (ap < PPPOE_MRU || ap > ETHER_MAX_LEN - 8)
-			Error("PPP-Max-Payload value \"%s\"", av[0]);
+		if (pi->iface[0] == '\0') {
+			if (ap < PPPOE_MRU)	/* postpone check for MTU */
+			    Error("PPP-Max-Payload value \"%s\" less than %d",
+				av[0], PPPOE_MRU);
+		} else {
+			mtu = GetSystemIfaceMTU(pi->iface);
+			if (mtu == 0)
+				mtu = ETHER_MAX_LEN;
+			if (ap < PPPOE_MRU || ap > mtu - 8)
+			    Error("PPP-Max-Payload value \"%s\" not in a range of %d..%hu",
+				av[0], PPPOE_MRU, mtu);
+		}
 		pi->max_payload = ap;
 		break;
 #endif
Index: src/util.c
===================================================================
--- src/util.c	(revision 2481)
+++ src/util.c	(revision 2483)
@@ -1597,3 +1597,25 @@ ssize_t GetDataAddrs(int sock, void *dbuf, size_t dbuf
 
 	return (size);
 }
+
+uint16_t GetSystemIfaceMTU(const char *ifname)
+{
+	struct ifreq ifr;
+	static int sock = -1;
+
+	if (sock == -1 &&
+	    (sock = socket(PF_INET, socktype(SOCK_DGRAM), 0)) == -1) {
+		Perror("[%s] %s: Socket creation error", ifname, __FUNCTION__);
+		return (0);
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+	if (ioctl(sock, SIOCGIFMTU, (caddr_t)&ifr) == -1) {
+		Perror("[%s] %s: SIOCGIFMTU failed", ifname, __FUNCTION__);
+		return (0);
+	}
+	/* Let _exit() close sock */
+	return (ifr.ifr_mtu);
+}
Index: src/util.h
===================================================================
--- src/util.h	(revision 2481)
+++ src/util.h	(revision 2483)
@@ -98,6 +98,7 @@ extern u_int32_t GenerateMagic(void);
 extern int GetAnyIpAddress(struct u_addr *ipaddr, const char *ifname);
 extern int GetEther(struct u_addr *addr, struct sockaddr_dl *hwaddr);
 extern int GetPeerEther(struct u_addr *addr, struct sockaddr_dl *hwaddr);
+extern uint16_t GetSystemIfaceMTU(const char *ifname);
 extern void ppp_util_ascify(char *buf, size_t max, const char *bytes, size_t len);
 extern int IfaceSetFlag(const char *ifname, unsigned value);