From 43775c98bdbe446ff68bfc14cd23d9f53625b95e Mon Sep 17 00:00:00 2001 From: rik Date: Tue, 28 Dec 2004 00:07:57 +0000 Subject: 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 --- sys/net/if_spppsubr.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'sys/net/if_spppsubr.c') 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, * * 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; -- cgit v1.1