summaryrefslogtreecommitdiffstats
path: root/sys/net/if_spppsubr.c
diff options
context:
space:
mode:
authorrik <rik@FreeBSD.org>2004-12-28 00:07:57 +0000
committerrik <rik@FreeBSD.org>2004-12-28 00:07:57 +0000
commit43775c98bdbe446ff68bfc14cd23d9f53625b95e (patch)
tree7433bf1374127facc9c84e9711fd78a06a4b0727 /sys/net/if_spppsubr.c
parent4eebca2138d71cf530bfe31fb0500b951dd9a7ea (diff)
downloadFreeBSD-src-43775c98bdbe446ff68bfc14cd23d9f53625b95e.zip
FreeBSD-src-43775c98bdbe446ff68bfc14cd23d9f53625b95e.tar.gz
Add FR support to sppp (MFCronyx).
Silence on: net@, current@, hackers@. No objections: joerg Requested by: by many (mostly Cronyx) users for a long long time. MFC after: 10 days PR: kern/21771, kern/66348
Diffstat (limited to 'sys/net/if_spppsubr.c')
-rw-r--r--sys/net/if_spppsubr.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 638f91f..94f9c83 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -1,8 +1,8 @@
/*
- * Synchronous PPP/Cisco link level subroutines.
+ * Synchronous PPP/Cisco/Frame Relay link level subroutines.
* Keepalive protocol implemented in both Cisco and PPP modes.
*
- * Copyright (C) 1994-1996 Cronyx Engineering Ltd.
+ * Copyright (C) 1994-2000 Cronyx Engineering.
* Author: Serge Vakulenko, <vak@cronyx.ru>
*
* Heavily revamped to conform to RFC 1661.
@@ -409,8 +409,6 @@ static const char *sppp_proto_name(u_short proto);
static const char *sppp_state_name(int state);
static int sppp_params(struct sppp *sp, u_long cmd, void *data);
static int sppp_strnlen(u_char *p, int max);
-static void sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst,
- u_long *srcmask);
static void sppp_keepalive(void *dummy);
static void sppp_phase_network(struct sppp *sp);
static void sppp_print_bytes(const u_char *p, u_short len);
@@ -551,6 +549,12 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
return;
}
+ if (sp->pp_mode == PP_FR) {
+ sppp_fr_input (sp, m);
+ SPPP_UNLOCK(sp);
+ return;
+ }
+
/* Get PPP header. */
h = mtod (m, struct ppp_header*);
m_adj (m, PPP_HEADER_LEN);
@@ -887,7 +891,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
/*
* Do IP Header compression
*/
- if (sp->pp_mode != IFF_CISCO &&
+ if (sp->pp_mode != IFF_CISCO && sp->pp_mode != PP_FR &&
(sp->ipcp.flags & IPCP_VJ) && ip->ip_p == IPPROTO_TCP)
switch (sl_compress_tcp(m, ip, sp->pp_comp,
sp->ipcp.compress_cid)) {
@@ -915,12 +919,20 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
}
#endif
+ if (sp->pp_mode == PP_FR) {
+ /* Add frame relay header. */
+ m = sppp_fr_header (sp, m, dst->sa_family);
+ if (! m)
+ goto nobufs;
+ goto out;
+ }
+
/*
* Prepend general data packet PPP header. For now, IP only.
*/
M_PREPEND (m, PPP_HEADER_LEN, M_DONTWAIT);
if (! m) {
- if (debug)
+nobufs: if (debug)
log(LOG_DEBUG, SPP_FMT "no memory for transmit header\n",
SPP_ARGS(ifp));
++ifp->if_oerrors;
@@ -1000,6 +1012,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
* Queue message on interface, and start output if interface
* not yet active.
*/
+out:
if (ifq != NULL)
error = !(IF_HANDOFF_ADJ(ifq, m, ifp, 3));
else
@@ -1162,7 +1175,8 @@ sppp_dequeue(struct ifnet *ifp)
*/
IF_DEQUEUE(&sp->pp_cpq, m);
if (m == NULL &&
- (sppp_ncp_check(sp) || sp->pp_mode == IFF_CISCO)) {
+ (sppp_ncp_check(sp) || sp->pp_mode == IFF_CISCO ||
+ sp->pp_mode == PP_FR)) {
IF_DEQUEUE(&sp->pp_fastq, m);
if (m == NULL)
IF_DEQUEUE (&sp->pp_if.if_snd, m);
@@ -1188,7 +1202,8 @@ sppp_pick(struct ifnet *ifp)
m = sp->pp_cpq.ifq_head;
if (m == NULL &&
(sp->pp_phase == PHASE_NETWORK ||
- sp->pp_mode == IFF_CISCO))
+ sp->pp_mode == IFF_CISCO ||
+ sp->pp_mode == PP_FR))
if ((m = sp->pp_fastq.ifq_head) == NULL)
m = sp->pp_if.if_snd.ifq_head;
SPPP_UNLOCK(sp);
@@ -1233,6 +1248,9 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
ifp->if_flags &= ~(IFF_PASSIVE | IFF_AUTO | IFF_CISCO);
ifp->if_flags |= newmode;
+ if (!newmode)
+ newmode = sp->pp_flags & PP_FR;
+
if (newmode != sp->pp_mode) {
going_down = 1;
if (!going_up)
@@ -1240,7 +1258,8 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
}
if (going_down) {
- if (sp->pp_mode != IFF_CISCO)
+ if (sp->pp_mode != IFF_CISCO &&
+ sp->pp_mode != PP_FR)
lcp.Close(sp);
else if (sp->pp_tlf)
(sp->pp_tlf)(sp);
@@ -1250,14 +1269,16 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
}
if (going_up) {
- if (sp->pp_mode != IFF_CISCO)
+ if (sp->pp_mode != IFF_CISCO &&
+ sp->pp_mode != PP_FR)
lcp.Close(sp);
sp->pp_mode = newmode;
if (sp->pp_mode == 0) {
ifp->if_flags |= IFF_RUNNING;
lcp.Open(sp);
}
- if (sp->pp_mode == IFF_CISCO) {
+ if ((sp->pp_mode == IFF_CISCO) ||
+ (sp->pp_mode == PP_FR)) {
if (sp->pp_tls)
(sp->pp_tls)(sp);
ifp->if_flags |= IFF_RUNNING;
@@ -4769,6 +4790,11 @@ sppp_keepalive(void *dummy)
! (ifp->if_flags & IFF_RUNNING))
goto out;
+ if (sp->pp_mode == PP_FR) {
+ sppp_fr_keepalive (sp);
+ goto out;
+ }
+
/* No keepalive in PPP mode if LCP not opened yet. */
if (sp->pp_mode != IFF_CISCO &&
sp->pp_phase < PHASE_AUTHENTICATE)
@@ -4808,7 +4834,7 @@ out:
/*
* Get both IP addresses.
*/
-static void
+void
sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
{
struct ifnet *ifp = &sp->pp_if;
OpenPOWER on IntegriCloud