ng_ppp.c (129823) | ng_ppp.c (131155) |
---|---|
1 2/* 3 * ng_ppp.c 4 * 5 * Copyright (c) 1996-2000 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and --- 22 unchanged lines hidden (view full) --- 31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Author: Archie Cobbs <archie@freebsd.org> 38 * | 1 2/* 3 * ng_ppp.c 4 * 5 * Copyright (c) 1996-2000 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and --- 22 unchanged lines hidden (view full) --- 31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Author: Archie Cobbs <archie@freebsd.org> 38 * |
39 * $FreeBSD: head/sys/netgraph/ng_ppp.c 129823 2004-05-29 00:51:19Z julian $ | 39 * $FreeBSD: head/sys/netgraph/ng_ppp.c 131155 2004-06-26 22:24:16Z julian $ |
40 * $Whistle: ng_ppp.c,v 1.24 1999/11/01 09:24:52 julian Exp $ 41 */ 42 43/* 44 * PPP node type. 45 */ 46 47#include <sys/param.h> --- 85 unchanged lines hidden (view full) --- 133 134/* We store incoming fragments this way */ 135struct ng_ppp_frag { 136 int seq; /* fragment seq# */ 137 u_char first; /* First in packet? */ 138 u_char last; /* Last in packet? */ 139 struct timeval timestamp; /* time of reception */ 140 struct mbuf *data; /* Fragment data */ | 40 * $Whistle: ng_ppp.c,v 1.24 1999/11/01 09:24:52 julian Exp $ 41 */ 42 43/* 44 * PPP node type. 45 */ 46 47#include <sys/param.h> --- 85 unchanged lines hidden (view full) --- 133 134/* We store incoming fragments this way */ 135struct ng_ppp_frag { 136 int seq; /* fragment seq# */ 137 u_char first; /* First in packet? */ 138 u_char last; /* Last in packet? */ 139 struct timeval timestamp; /* time of reception */ 140 struct mbuf *data; /* Fragment data */ |
141 meta_p meta; /* Fragment meta */ | |
142 TAILQ_ENTRY(ng_ppp_frag) f_qent; /* Fragment queue */ 143}; 144 145/* We use integer indicies to refer to the non-link hooks */ 146static const char *const ng_ppp_hook_names[] = { 147 NG_PPP_HOOK_ATALK, 148#define HOOK_INDEX_ATALK 0 149 NG_PPP_HOOK_BYPASS, --- 72 unchanged lines hidden (view full) --- 222 223/* Helper functions */ 224static int ng_ppp_input(node_p node, int bypass, 225 int linkNum, item_p item); 226static int ng_ppp_output(node_p node, int bypass, int proto, 227 int linkNum, item_p item); 228static int ng_ppp_mp_input(node_p node, int linkNum, item_p item); 229static int ng_ppp_check_packet(node_p node); | 141 TAILQ_ENTRY(ng_ppp_frag) f_qent; /* Fragment queue */ 142}; 143 144/* We use integer indicies to refer to the non-link hooks */ 145static const char *const ng_ppp_hook_names[] = { 146 NG_PPP_HOOK_ATALK, 147#define HOOK_INDEX_ATALK 0 148 NG_PPP_HOOK_BYPASS, --- 72 unchanged lines hidden (view full) --- 221 222/* Helper functions */ 223static int ng_ppp_input(node_p node, int bypass, 224 int linkNum, item_p item); 225static int ng_ppp_output(node_p node, int bypass, int proto, 226 int linkNum, item_p item); 227static int ng_ppp_mp_input(node_p node, int linkNum, item_p item); 228static int ng_ppp_check_packet(node_p node); |
230static void ng_ppp_get_packet(node_p node, struct mbuf **mp, meta_p *metap); | 229static void ng_ppp_get_packet(node_p node, struct mbuf **mp); |
231static int ng_ppp_frag_process(node_p node); 232static int ng_ppp_frag_trim(node_p node); 233static void ng_ppp_frag_timeout(void *arg); 234static void ng_ppp_frag_checkstale(node_p node); 235static void ng_ppp_frag_reset(node_p node); | 230static int ng_ppp_frag_process(node_p node); 231static int ng_ppp_frag_trim(node_p node); 232static void ng_ppp_frag_timeout(void *arg); 233static void ng_ppp_frag_checkstale(node_p node); 234static void ng_ppp_frag_reset(node_p node); |
236static int ng_ppp_mp_output(node_p node, struct mbuf *m, meta_p meta); | 235static int ng_ppp_mp_output(node_p node, struct mbuf *m); |
237static void ng_ppp_mp_strategy(node_p node, int len, int *distrib); 238static int ng_ppp_intcmp(const void *v1, const void *v2); 239static struct mbuf *ng_ppp_addproto(struct mbuf *m, int proto, int compOK); 240static struct mbuf *ng_ppp_prepend(struct mbuf *m, const void *buf, int len); 241static int ng_ppp_config_valid(node_p node, 242 const struct ng_ppp_node_conf *newConf); 243static void ng_ppp_update(node_p node, int newConf); 244static void ng_ppp_start_frag_timer(node_p node); --- 753 unchanged lines hidden (view full) --- 998 linkNum == NG_PPP_BUNDLE_LINKNUM 999 || link->conf.enableProtoComp)) == NULL) { 1000 NG_FREE_ITEM(item); 1001 return (ENOBUFS); 1002 } 1003 1004 /* Special handling for the MP virtual link */ 1005 if (linkNum == NG_PPP_BUNDLE_LINKNUM) { | 236static void ng_ppp_mp_strategy(node_p node, int len, int *distrib); 237static int ng_ppp_intcmp(const void *v1, const void *v2); 238static struct mbuf *ng_ppp_addproto(struct mbuf *m, int proto, int compOK); 239static struct mbuf *ng_ppp_prepend(struct mbuf *m, const void *buf, int len); 240static int ng_ppp_config_valid(node_p node, 241 const struct ng_ppp_node_conf *newConf); 242static void ng_ppp_update(node_p node, int newConf); 243static void ng_ppp_start_frag_timer(node_p node); --- 753 unchanged lines hidden (view full) --- 997 linkNum == NG_PPP_BUNDLE_LINKNUM 998 || link->conf.enableProtoComp)) == NULL) { 999 NG_FREE_ITEM(item); 1000 return (ENOBUFS); 1001 } 1002 1003 /* Special handling for the MP virtual link */ 1004 if (linkNum == NG_PPP_BUNDLE_LINKNUM) { |
1006 meta_p meta; 1007 1008 /* strip off and discard the queue item */ 1009 NGI_GET_META(item, meta); | 1005 /* discard the queue item */ |
1010 NG_FREE_ITEM(item); | 1006 NG_FREE_ITEM(item); |
1011 return ng_ppp_mp_output(node, m, meta); | 1007 return ng_ppp_mp_output(node, m); |
1012 } 1013 1014 /* Prepend address and control field (unless compressed) */ 1015 if (proto == PROT_LCP || !link->conf.enableACFComp) { 1016 if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) { 1017 NG_FREE_ITEM(item); 1018 return (ENOBUFS); 1019 } --- 69 unchanged lines hidden (view full) --- 1089ng_ppp_mp_input(node_p node, int linkNum, item_p item) 1090{ 1091 const priv_p priv = NG_NODE_PRIVATE(node); 1092 struct ng_ppp_link *const link = &priv->links[linkNum]; 1093 struct ng_ppp_frag frag0, *frag = &frag0; 1094 struct ng_ppp_frag *qent; 1095 int i, diff, inserted; 1096 struct mbuf *m; | 1008 } 1009 1010 /* Prepend address and control field (unless compressed) */ 1011 if (proto == PROT_LCP || !link->conf.enableACFComp) { 1012 if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) { 1013 NG_FREE_ITEM(item); 1014 return (ENOBUFS); 1015 } --- 69 unchanged lines hidden (view full) --- 1085ng_ppp_mp_input(node_p node, int linkNum, item_p item) 1086{ 1087 const priv_p priv = NG_NODE_PRIVATE(node); 1088 struct ng_ppp_link *const link = &priv->links[linkNum]; 1089 struct ng_ppp_frag frag0, *frag = &frag0; 1090 struct ng_ppp_frag *qent; 1091 int i, diff, inserted; 1092 struct mbuf *m; |
1097 meta_p meta; | |
1098 1099 NGI_GET_M(item, m); | 1093 1094 NGI_GET_M(item, m); |
1100 NGI_GET_META(item, meta); | |
1101 NG_FREE_ITEM(item); 1102 /* Stats */ 1103 priv->bundleStats.recvFrames++; 1104 priv->bundleStats.recvOctets += m->m_pkthdr.len; 1105 1106 /* Extract fragment information from MP header */ 1107 if (priv->conf.recvShortSeq) { 1108 u_int16_t shdr; 1109 1110 if (m->m_pkthdr.len < 2) { 1111 link->stats.runts++; 1112 NG_FREE_M(m); | 1095 NG_FREE_ITEM(item); 1096 /* Stats */ 1097 priv->bundleStats.recvFrames++; 1098 priv->bundleStats.recvOctets += m->m_pkthdr.len; 1099 1100 /* Extract fragment information from MP header */ 1101 if (priv->conf.recvShortSeq) { 1102 u_int16_t shdr; 1103 1104 if (m->m_pkthdr.len < 2) { 1105 link->stats.runts++; 1106 NG_FREE_M(m); |
1113 NG_FREE_META(meta); | |
1114 return (EINVAL); 1115 } | 1107 return (EINVAL); 1108 } |
1116 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 1117 NG_FREE_META(meta); | 1109 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) |
1118 return (ENOBUFS); | 1110 return (ENOBUFS); |
1119 } | 1111 |
1120 shdr = ntohs(*mtod(m, u_int16_t *)); 1121 frag->seq = MP_SHORT_EXTEND(shdr); 1122 frag->first = (shdr & MP_SHORT_FIRST_FLAG) != 0; 1123 frag->last = (shdr & MP_SHORT_LAST_FLAG) != 0; 1124 diff = MP_SHORT_SEQ_DIFF(frag->seq, priv->mseq); 1125 m_adj(m, 2); 1126 } else { 1127 u_int32_t lhdr; 1128 1129 if (m->m_pkthdr.len < 4) { 1130 link->stats.runts++; 1131 NG_FREE_M(m); | 1112 shdr = ntohs(*mtod(m, u_int16_t *)); 1113 frag->seq = MP_SHORT_EXTEND(shdr); 1114 frag->first = (shdr & MP_SHORT_FIRST_FLAG) != 0; 1115 frag->last = (shdr & MP_SHORT_LAST_FLAG) != 0; 1116 diff = MP_SHORT_SEQ_DIFF(frag->seq, priv->mseq); 1117 m_adj(m, 2); 1118 } else { 1119 u_int32_t lhdr; 1120 1121 if (m->m_pkthdr.len < 4) { 1122 link->stats.runts++; 1123 NG_FREE_M(m); |
1132 NG_FREE_META(meta); | |
1133 return (EINVAL); 1134 } | 1124 return (EINVAL); 1125 } |
1135 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) { 1136 NG_FREE_META(meta); | 1126 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) |
1137 return (ENOBUFS); | 1127 return (ENOBUFS); |
1138 } | 1128 |
1139 lhdr = ntohl(*mtod(m, u_int32_t *)); 1140 frag->seq = MP_LONG_EXTEND(lhdr); 1141 frag->first = (lhdr & MP_LONG_FIRST_FLAG) != 0; 1142 frag->last = (lhdr & MP_LONG_LAST_FLAG) != 0; 1143 diff = MP_LONG_SEQ_DIFF(frag->seq, priv->mseq); 1144 m_adj(m, 4); 1145 } 1146 frag->data = m; | 1129 lhdr = ntohl(*mtod(m, u_int32_t *)); 1130 frag->seq = MP_LONG_EXTEND(lhdr); 1131 frag->first = (lhdr & MP_LONG_FIRST_FLAG) != 0; 1132 frag->last = (lhdr & MP_LONG_LAST_FLAG) != 0; 1133 diff = MP_LONG_SEQ_DIFF(frag->seq, priv->mseq); 1134 m_adj(m, 4); 1135 } 1136 frag->data = m; |
1147 frag->meta = meta; | |
1148 getmicrouptime(&frag->timestamp); 1149 1150 /* If sequence number is < MSEQ, we've already declared this 1151 fragment as lost, so we have no choice now but to drop it */ 1152 if (diff < 0) { 1153 link->stats.dropFragments++; 1154 NG_FREE_M(m); | 1137 getmicrouptime(&frag->timestamp); 1138 1139 /* If sequence number is < MSEQ, we've already declared this 1140 fragment as lost, so we have no choice now but to drop it */ 1141 if (diff < 0) { 1142 link->stats.dropFragments++; 1143 NG_FREE_M(m); |
1155 NG_FREE_META(meta); | |
1156 return (0); 1157 } 1158 1159 /* Update highest received sequence number on this link and MSEQ */ 1160 priv->mseq = link->seq = frag->seq; 1161 for (i = 0; i < priv->numActiveLinks; i++) { 1162 struct ng_ppp_link *const alink = 1163 &priv->links[priv->activeLinks[i]]; 1164 1165 if (MP_RECV_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) 1166 priv->mseq = alink->seq; 1167 } 1168 1169 /* Allocate a new frag struct for the queue */ 1170 MALLOC(frag, struct ng_ppp_frag *, sizeof(*frag), M_NETGRAPH_PPP, M_NOWAIT); 1171 if (frag == NULL) { 1172 NG_FREE_M(m); | 1144 return (0); 1145 } 1146 1147 /* Update highest received sequence number on this link and MSEQ */ 1148 priv->mseq = link->seq = frag->seq; 1149 for (i = 0; i < priv->numActiveLinks; i++) { 1150 struct ng_ppp_link *const alink = 1151 &priv->links[priv->activeLinks[i]]; 1152 1153 if (MP_RECV_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) 1154 priv->mseq = alink->seq; 1155 } 1156 1157 /* Allocate a new frag struct for the queue */ 1158 MALLOC(frag, struct ng_ppp_frag *, sizeof(*frag), M_NETGRAPH_PPP, M_NOWAIT); 1159 if (frag == NULL) { 1160 NG_FREE_M(m); |
1173 NG_FREE_META(meta); | |
1174 ng_ppp_frag_process(node); 1175 return (ENOMEM); 1176 } 1177 *frag = frag0; 1178 1179 /* Add fragment to queue, which is sorted by sequence number */ 1180 inserted = 0; 1181 TAILQ_FOREACH_REVERSE(qent, &priv->frags, ng_ppp_fraglist, f_qent) { 1182 diff = MP_RECV_SEQ_DIFF(priv, frag->seq, qent->seq); 1183 if (diff > 0) { 1184 TAILQ_INSERT_AFTER(&priv->frags, qent, frag, f_qent); 1185 inserted = 1; 1186 break; 1187 } else if (diff == 0) { /* should never happen! */ 1188 link->stats.dupFragments++; 1189 NG_FREE_M(frag->data); | 1161 ng_ppp_frag_process(node); 1162 return (ENOMEM); 1163 } 1164 *frag = frag0; 1165 1166 /* Add fragment to queue, which is sorted by sequence number */ 1167 inserted = 0; 1168 TAILQ_FOREACH_REVERSE(qent, &priv->frags, ng_ppp_fraglist, f_qent) { 1169 diff = MP_RECV_SEQ_DIFF(priv, frag->seq, qent->seq); 1170 if (diff > 0) { 1171 TAILQ_INSERT_AFTER(&priv->frags, qent, frag, f_qent); 1172 inserted = 1; 1173 break; 1174 } else if (diff == 0) { /* should never happen! */ 1175 link->stats.dupFragments++; 1176 NG_FREE_M(frag->data); |
1190 NG_FREE_META(frag->meta); | |
1191 FREE(frag, M_NETGRAPH_PPP); 1192 return (EINVAL); 1193 } 1194 } 1195 if (!inserted) 1196 TAILQ_INSERT_HEAD(&priv->frags, frag, f_qent); 1197 priv->qlen++; 1198 --- 35 unchanged lines hidden (view full) --- 1234 return (1); 1235} 1236 1237/* 1238 * Pull a completed packet off the head of the incoming fragment queue. 1239 * This assumes there is a completed packet there to pull off. 1240 */ 1241static void | 1177 FREE(frag, M_NETGRAPH_PPP); 1178 return (EINVAL); 1179 } 1180 } 1181 if (!inserted) 1182 TAILQ_INSERT_HEAD(&priv->frags, frag, f_qent); 1183 priv->qlen++; 1184 --- 35 unchanged lines hidden (view full) --- 1220 return (1); 1221} 1222 1223/* 1224 * Pull a completed packet off the head of the incoming fragment queue. 1225 * This assumes there is a completed packet there to pull off. 1226 */ 1227static void |
1242ng_ppp_get_packet(node_p node, struct mbuf **mp, meta_p *metap) | 1228ng_ppp_get_packet(node_p node, struct mbuf **mp) |
1243{ 1244 const priv_p priv = NG_NODE_PRIVATE(node); 1245 struct ng_ppp_frag *qent, *qnext; 1246 struct mbuf *m = NULL, *tail; 1247 1248 qent = TAILQ_FIRST(&priv->frags); 1249 KASSERT(!TAILQ_EMPTY(&priv->frags) && qent->first, 1250 ("%s: no packet", __func__)); 1251 for (tail = NULL; qent != NULL; qent = qnext) { 1252 qnext = TAILQ_NEXT(qent, f_qent); 1253 KASSERT(!TAILQ_EMPTY(&priv->frags), 1254 ("%s: empty q", __func__)); 1255 TAILQ_REMOVE(&priv->frags, qent, f_qent); | 1229{ 1230 const priv_p priv = NG_NODE_PRIVATE(node); 1231 struct ng_ppp_frag *qent, *qnext; 1232 struct mbuf *m = NULL, *tail; 1233 1234 qent = TAILQ_FIRST(&priv->frags); 1235 KASSERT(!TAILQ_EMPTY(&priv->frags) && qent->first, 1236 ("%s: no packet", __func__)); 1237 for (tail = NULL; qent != NULL; qent = qnext) { 1238 qnext = TAILQ_NEXT(qent, f_qent); 1239 KASSERT(!TAILQ_EMPTY(&priv->frags), 1240 ("%s: empty q", __func__)); 1241 TAILQ_REMOVE(&priv->frags, qent, f_qent); |
1256 if (tail == NULL) { | 1242 if (tail == NULL) |
1257 tail = m = qent->data; | 1243 tail = m = qent->data; |
1258 *metap = qent->meta; /* inherit first frag's meta */ 1259 } else { | 1244 else { |
1260 m->m_pkthdr.len += qent->data->m_pkthdr.len; 1261 tail->m_next = qent->data; | 1245 m->m_pkthdr.len += qent->data->m_pkthdr.len; 1246 tail->m_next = qent->data; |
1262 NG_FREE_META(qent->meta); /* drop other frags' metas */ | |
1263 } 1264 while (tail->m_next != NULL) 1265 tail = tail->m_next; 1266 if (qent->last) 1267 qnext = NULL; 1268 FREE(qent, M_NETGRAPH_PPP); 1269 priv->qlen--; 1270 } --- 38 unchanged lines hidden (view full) --- 1309 1310 /* Remove fragment and all others in the same packet */ 1311 while ((qent = TAILQ_FIRST(&priv->frags)) != qnext) { 1312 KASSERT(!TAILQ_EMPTY(&priv->frags), 1313 ("%s: empty q", __func__)); 1314 priv->bundleStats.dropFragments++; 1315 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1316 NG_FREE_M(qent->data); | 1247 } 1248 while (tail->m_next != NULL) 1249 tail = tail->m_next; 1250 if (qent->last) 1251 qnext = NULL; 1252 FREE(qent, M_NETGRAPH_PPP); 1253 priv->qlen--; 1254 } --- 38 unchanged lines hidden (view full) --- 1293 1294 /* Remove fragment and all others in the same packet */ 1295 while ((qent = TAILQ_FIRST(&priv->frags)) != qnext) { 1296 KASSERT(!TAILQ_EMPTY(&priv->frags), 1297 ("%s: empty q", __func__)); 1298 priv->bundleStats.dropFragments++; 1299 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1300 NG_FREE_M(qent->data); |
1317 NG_FREE_META(qent->meta); | |
1318 FREE(qent, M_NETGRAPH_PPP); 1319 priv->qlen--; 1320 removed = 1; 1321 } 1322 } 1323 return (removed); 1324} 1325 1326/* 1327 * Run the queue, restoring the queue invariants 1328 */ 1329static int 1330ng_ppp_frag_process(node_p node) 1331{ 1332 const priv_p priv = NG_NODE_PRIVATE(node); 1333 struct mbuf *m; | 1301 FREE(qent, M_NETGRAPH_PPP); 1302 priv->qlen--; 1303 removed = 1; 1304 } 1305 } 1306 return (removed); 1307} 1308 1309/* 1310 * Run the queue, restoring the queue invariants 1311 */ 1312static int 1313ng_ppp_frag_process(node_p node) 1314{ 1315 const priv_p priv = NG_NODE_PRIVATE(node); 1316 struct mbuf *m; |
1334 meta_p meta; | |
1335 item_p item; 1336 1337 /* Deliver any deliverable packets */ 1338 while (ng_ppp_check_packet(node)) { | 1317 item_p item; 1318 1319 /* Deliver any deliverable packets */ 1320 while (ng_ppp_check_packet(node)) { |
1339 ng_ppp_get_packet(node, &m, &meta); 1340 item = ng_package_data(m, meta); | 1321 ng_ppp_get_packet(node, &m); 1322 item = ng_package_data(m, NULL); |
1341 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1342 } 1343 1344 /* Delete dead fragments and try again */ 1345 if (ng_ppp_frag_trim(node)) { 1346 while (ng_ppp_check_packet(node)) { | 1323 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1324 } 1325 1326 /* Delete dead fragments and try again */ 1327 if (ng_ppp_frag_trim(node)) { 1328 while (ng_ppp_check_packet(node)) { |
1347 ng_ppp_get_packet(node, &m, &meta); 1348 item = ng_package_data(m, meta); | 1329 ng_ppp_get_packet(node, &m); 1330 item = ng_package_data(m, NULL); |
1349 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1350 } 1351 } 1352 1353 /* Check for stale fragments while we're here */ 1354 ng_ppp_frag_checkstale(node); 1355 1356 /* Check queue length */ --- 18 unchanged lines hidden (view full) --- 1375 alink->seq = priv->mseq; 1376 } 1377 } 1378 1379 /* Drop it */ 1380 priv->bundleStats.dropFragments++; 1381 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1382 NG_FREE_M(qent->data); | 1331 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1332 } 1333 } 1334 1335 /* Check for stale fragments while we're here */ 1336 ng_ppp_frag_checkstale(node); 1337 1338 /* Check queue length */ --- 18 unchanged lines hidden (view full) --- 1357 alink->seq = priv->mseq; 1358 } 1359 } 1360 1361 /* Drop it */ 1362 priv->bundleStats.dropFragments++; 1363 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1364 NG_FREE_M(qent->data); |
1383 NG_FREE_META(qent->meta); | |
1384 FREE(qent, M_NETGRAPH_PPP); 1385 priv->qlen--; 1386 1387 /* Process queue again */ 1388 return ng_ppp_frag_process(node); 1389 } 1390 1391 /* Done */ --- 14 unchanged lines hidden (view full) --- 1406 */ 1407static void 1408ng_ppp_frag_checkstale(node_p node) 1409{ 1410 const priv_p priv = NG_NODE_PRIVATE(node); 1411 struct ng_ppp_frag *qent, *beg, *end; 1412 struct timeval now, age; 1413 struct mbuf *m; | 1365 FREE(qent, M_NETGRAPH_PPP); 1366 priv->qlen--; 1367 1368 /* Process queue again */ 1369 return ng_ppp_frag_process(node); 1370 } 1371 1372 /* Done */ --- 14 unchanged lines hidden (view full) --- 1387 */ 1388static void 1389ng_ppp_frag_checkstale(node_p node) 1390{ 1391 const priv_p priv = NG_NODE_PRIVATE(node); 1392 struct ng_ppp_frag *qent, *beg, *end; 1393 struct timeval now, age; 1394 struct mbuf *m; |
1414 meta_p meta; | |
1415 int i, seq; 1416 item_p item; 1417 int endseq; 1418 1419 now.tv_sec = 0; /* uninitialized state */ 1420 while (1) { 1421 1422 /* If queue is empty, we're done */ --- 31 unchanged lines hidden (view full) --- 1454 1455 /* Throw away junk fragments in front of the completed packet */ 1456 while ((qent = TAILQ_FIRST(&priv->frags)) != beg) { 1457 KASSERT(!TAILQ_EMPTY(&priv->frags), 1458 ("%s: empty q", __func__)); 1459 priv->bundleStats.dropFragments++; 1460 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1461 NG_FREE_M(qent->data); | 1395 int i, seq; 1396 item_p item; 1397 int endseq; 1398 1399 now.tv_sec = 0; /* uninitialized state */ 1400 while (1) { 1401 1402 /* If queue is empty, we're done */ --- 31 unchanged lines hidden (view full) --- 1434 1435 /* Throw away junk fragments in front of the completed packet */ 1436 while ((qent = TAILQ_FIRST(&priv->frags)) != beg) { 1437 KASSERT(!TAILQ_EMPTY(&priv->frags), 1438 ("%s: empty q", __func__)); 1439 priv->bundleStats.dropFragments++; 1440 TAILQ_REMOVE(&priv->frags, qent, f_qent); 1441 NG_FREE_M(qent->data); |
1462 NG_FREE_META(qent->meta); | |
1463 FREE(qent, M_NETGRAPH_PPP); 1464 priv->qlen--; 1465 } 1466 1467 /* Extract completed packet */ 1468 endseq = end->seq; | 1442 FREE(qent, M_NETGRAPH_PPP); 1443 priv->qlen--; 1444 } 1445 1446 /* Extract completed packet */ 1447 endseq = end->seq; |
1469 ng_ppp_get_packet(node, &m, &meta); | 1448 ng_ppp_get_packet(node, &m); |
1470 1471 /* Bump MSEQ if necessary */ 1472 if (MP_RECV_SEQ_DIFF(priv, priv->mseq, endseq) < 0) { 1473 priv->mseq = endseq; 1474 for (i = 0; i < priv->numActiveLinks; i++) { 1475 struct ng_ppp_link *const alink = 1476 &priv->links[priv->activeLinks[i]]; 1477 1478 if (MP_RECV_SEQ_DIFF(priv, 1479 alink->seq, priv->mseq) < 0) 1480 alink->seq = priv->mseq; 1481 } 1482 } 1483 1484 /* Deliver packet */ | 1449 1450 /* Bump MSEQ if necessary */ 1451 if (MP_RECV_SEQ_DIFF(priv, priv->mseq, endseq) < 0) { 1452 priv->mseq = endseq; 1453 for (i = 0; i < priv->numActiveLinks; i++) { 1454 struct ng_ppp_link *const alink = 1455 &priv->links[priv->activeLinks[i]]; 1456 1457 if (MP_RECV_SEQ_DIFF(priv, 1458 alink->seq, priv->mseq) < 0) 1459 alink->seq = priv->mseq; 1460 } 1461 } 1462 1463 /* Deliver packet */ |
1485 item = ng_package_data(m, meta); | 1464 item = ng_package_data(m, NULL); |
1486 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1487 } 1488} 1489 1490/* 1491 * Periodically call ng_ppp_frag_checkstale() 1492 */ 1493static void --- 24 unchanged lines hidden (view full) --- 1518 splx(s); 1519} 1520 1521/* 1522 * Deliver a frame out on the bundle, i.e., figure out how to fragment 1523 * the frame across the individual PPP links and do so. 1524 */ 1525static int | 1465 ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item); 1466 } 1467} 1468 1469/* 1470 * Periodically call ng_ppp_frag_checkstale() 1471 */ 1472static void --- 24 unchanged lines hidden (view full) --- 1497 splx(s); 1498} 1499 1500/* 1501 * Deliver a frame out on the bundle, i.e., figure out how to fragment 1502 * the frame across the individual PPP links and do so. 1503 */ 1504static int |
1526ng_ppp_mp_output(node_p node, struct mbuf *m, meta_p meta) | 1505ng_ppp_mp_output(node_p node, struct mbuf *m) |
1527{ 1528 const priv_p priv = NG_NODE_PRIVATE(node); 1529 const int hdr_len = priv->conf.xmitShortSeq ? 2 : 4; 1530 int distrib[NG_PPP_MAX_LINKS]; 1531 int firstFragment; 1532 int activeLinkNum; 1533 item_p item; 1534 1535 /* At least one link must be active */ 1536 if (priv->numActiveLinks == 0) { 1537 NG_FREE_M(m); | 1506{ 1507 const priv_p priv = NG_NODE_PRIVATE(node); 1508 const int hdr_len = priv->conf.xmitShortSeq ? 2 : 4; 1509 int distrib[NG_PPP_MAX_LINKS]; 1510 int firstFragment; 1511 int activeLinkNum; 1512 item_p item; 1513 1514 /* At least one link must be active */ 1515 if (priv->numActiveLinks == 0) { 1516 NG_FREE_M(m); |
1538 NG_FREE_META(meta); | |
1539 return (ENETDOWN); 1540 } 1541 1542 /* Round-robin strategy */ 1543 if (priv->conf.enableRoundRobin || m->m_pkthdr.len < MP_MIN_FRAG_LEN) { 1544 activeLinkNum = priv->lastLink++ % priv->numActiveLinks; 1545 bzero(&distrib, priv->numActiveLinks * sizeof(distrib[0])); 1546 distrib[activeLinkNum] = m->m_pkthdr.len; --- 29 unchanged lines hidden (view full) --- 1576 activeLinkNum >= 0; activeLinkNum--) { 1577 const int linkNum = priv->activeLinks[activeLinkNum]; 1578 struct ng_ppp_link *const link = &priv->links[linkNum]; 1579 1580 /* Deliver fragment(s) out the next link */ 1581 for ( ; distrib[activeLinkNum] > 0; firstFragment = 0) { 1582 int len, lastFragment, error; 1583 struct mbuf *m2; | 1517 return (ENETDOWN); 1518 } 1519 1520 /* Round-robin strategy */ 1521 if (priv->conf.enableRoundRobin || m->m_pkthdr.len < MP_MIN_FRAG_LEN) { 1522 activeLinkNum = priv->lastLink++ % priv->numActiveLinks; 1523 bzero(&distrib, priv->numActiveLinks * sizeof(distrib[0])); 1524 distrib[activeLinkNum] = m->m_pkthdr.len; --- 29 unchanged lines hidden (view full) --- 1554 activeLinkNum >= 0; activeLinkNum--) { 1555 const int linkNum = priv->activeLinks[activeLinkNum]; 1556 struct ng_ppp_link *const link = &priv->links[linkNum]; 1557 1558 /* Deliver fragment(s) out the next link */ 1559 for ( ; distrib[activeLinkNum] > 0; firstFragment = 0) { 1560 int len, lastFragment, error; 1561 struct mbuf *m2; |
1584 meta_p meta2; | |
1585 1586 /* Calculate fragment length; don't exceed link MTU */ 1587 len = distrib[activeLinkNum]; 1588 if (len > link->conf.mru - hdr_len) 1589 len = link->conf.mru - hdr_len; 1590 distrib[activeLinkNum] -= len; 1591 lastFragment = (len == m->m_pkthdr.len); 1592 1593 /* Split off next fragment as "m2" */ 1594 m2 = m; 1595 if (!lastFragment) { 1596 struct mbuf *n = m_split(m, len, M_DONTWAIT); 1597 1598 if (n == NULL) { 1599 NG_FREE_M(m); | 1562 1563 /* Calculate fragment length; don't exceed link MTU */ 1564 len = distrib[activeLinkNum]; 1565 if (len > link->conf.mru - hdr_len) 1566 len = link->conf.mru - hdr_len; 1567 distrib[activeLinkNum] -= len; 1568 lastFragment = (len == m->m_pkthdr.len); 1569 1570 /* Split off next fragment as "m2" */ 1571 m2 = m; 1572 if (!lastFragment) { 1573 struct mbuf *n = m_split(m, len, M_DONTWAIT); 1574 1575 if (n == NULL) { 1576 NG_FREE_M(m); |
1600 NG_FREE_META(meta); | |
1601 return (ENOMEM); 1602 } 1603 m = n; 1604 } 1605 1606 /* Prepend MP header */ 1607 if (priv->conf.xmitShortSeq) { 1608 u_int16_t shdr; --- 18 unchanged lines hidden (view full) --- 1627 if (lastFragment) 1628 lhdr |= MP_LONG_LAST_FLAG; 1629 lhdr = htonl(lhdr); 1630 m2 = ng_ppp_prepend(m2, &lhdr, 4); 1631 } 1632 if (m2 == NULL) { 1633 if (!lastFragment) 1634 m_freem(m); | 1577 return (ENOMEM); 1578 } 1579 m = n; 1580 } 1581 1582 /* Prepend MP header */ 1583 if (priv->conf.xmitShortSeq) { 1584 u_int16_t shdr; --- 18 unchanged lines hidden (view full) --- 1603 if (lastFragment) 1604 lhdr |= MP_LONG_LAST_FLAG; 1605 lhdr = htonl(lhdr); 1606 m2 = ng_ppp_prepend(m2, &lhdr, 4); 1607 } 1608 if (m2 == NULL) { 1609 if (!lastFragment) 1610 m_freem(m); |
1635 NG_FREE_META(meta); | |
1636 return (ENOBUFS); 1637 } 1638 | 1611 return (ENOBUFS); 1612 } 1613 |
1639 /* Copy the meta information, if any */ 1640 meta2 = lastFragment ? meta : ng_copy_meta(meta); 1641 | |
1642 /* Send fragment */ | 1614 /* Send fragment */ |
1643 item = ng_package_data(m2, meta2); | 1615 item = ng_package_data(m2, NULL); |
1644 error = ng_ppp_output(node, 0, PROT_MP, linkNum, item); 1645 if (error != 0) { | 1616 error = ng_ppp_output(node, 0, PROT_MP, linkNum, item); 1617 if (error != 0) { |
1646 if (!lastFragment) { | 1618 if (!lastFragment) |
1647 NG_FREE_M(m); | 1619 NG_FREE_M(m); |
1648 NG_FREE_META(meta); 1649 } | |
1650 return (error); 1651 } 1652 } 1653 } 1654 1655 /* Done */ 1656 return (0); 1657} --- 393 unchanged lines hidden (view full) --- 2051ng_ppp_frag_reset(node_p node) 2052{ 2053 const priv_p priv = NG_NODE_PRIVATE(node); 2054 struct ng_ppp_frag *qent, *qnext; 2055 2056 for (qent = TAILQ_FIRST(&priv->frags); qent; qent = qnext) { 2057 qnext = TAILQ_NEXT(qent, f_qent); 2058 NG_FREE_M(qent->data); | 1620 return (error); 1621 } 1622 } 1623 } 1624 1625 /* Done */ 1626 return (0); 1627} --- 393 unchanged lines hidden (view full) --- 2021ng_ppp_frag_reset(node_p node) 2022{ 2023 const priv_p priv = NG_NODE_PRIVATE(node); 2024 struct ng_ppp_frag *qent, *qnext; 2025 2026 for (qent = TAILQ_FIRST(&priv->frags); qent; qent = qnext) { 2027 qnext = TAILQ_NEXT(qent, f_qent); 2028 NG_FREE_M(qent->data); |
2059 NG_FREE_META(qent->meta); | |
2060 FREE(qent, M_NETGRAPH_PPP); 2061 } 2062 TAILQ_INIT(&priv->frags); 2063 priv->qlen = 0; 2064} 2065 2066/* 2067 * Start fragment queue timer --- 31 unchanged lines hidden --- | 2029 FREE(qent, M_NETGRAPH_PPP); 2030 } 2031 TAILQ_INIT(&priv->frags); 2032 priv->qlen = 0; 2033} 2034 2035/* 2036 * Start fragment queue timer --- 31 unchanged lines hidden --- |