Index | Thread | Search

From:
Denis Fondras <openbsd@ledeuns.net>
Subject:
ppp(4) : Add IPv6 support
To:
tech@openbsd.org
Date:
Sun, 18 Feb 2024 20:49:24 +0100

Download raw body.

Thread
Here is a diff to add IPv6 support to ppp(4).
With this diff, I can send and receive IPv6 packets over a PPP connection.

Denis

Index: if_ppp.c
===================================================================
RCS file: /cvs/src/sys/net/if_ppp.c,v
retrieving revision 1.117
diff -u -p -r1.117 if_ppp.c
--- if_ppp.c	21 Aug 2020 22:59:27 -0000	1.117
+++ if_ppp.c	18 Feb 2024 19:45:18 -0000
@@ -494,6 +494,11 @@ pppioctl(struct ppp_softc *sc, u_long cm
 		case PPP_IP:
 			npx = NP_IP;
 			break;
+#ifdef INET6
+		case PPP_IPV6:
+			npx = NP_IPV6;
+			break;
+#endif
 		default:
 			return EINVAL;
 		}
@@ -564,7 +569,6 @@ static int
 pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct ppp_softc *sc = ifp->if_softc;
-	struct ifaddr *ifa = (struct ifaddr *)data;
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct ppp_stats *psp;
 #ifdef	PPP_COMPRESS
@@ -579,13 +583,9 @@ pppsioctl(struct ifnet *ifp, u_long cmd,
 		break;
 
 	case SIOCSIFADDR:
-		if (ifa->ifa_addr->sa_family != AF_INET)
-			error = EAFNOSUPPORT;
 		break;
 
 	case SIOCSIFDSTADDR:
-		if (ifa->ifa_addr->sa_family != AF_INET)
-			error = EAFNOSUPPORT;
 		break;
 
 	case SIOCSIFMTU:
@@ -674,6 +674,14 @@ pppoutput(struct ifnet *ifp, struct mbuf
 		protocol = PPP_IP;
 		mode = sc->sc_npmode[NP_IP];
 		break;
+#ifdef INET6
+	case AF_INET6:
+		address = PPP_ALLSTATIONS;
+		control = PPP_UI;
+		protocol = PPP_IPV6;
+		mode = sc->sc_npmode[NP_IPV6];
+		break;
+#endif
 	case AF_UNSPEC:
 		address = PPP_ADDRESS(dst->sa_data);
 		control = PPP_CONTROL(dst->sa_data);
@@ -804,6 +812,11 @@ ppp_requeue(struct ppp_softc *sc)
 		case PPP_IP:
 			mode = sc->sc_npmode[NP_IP];
 			break;
+#ifdef INET6
+		case PPP_IPV6:
+			mode = sc->sc_npmode[NP_IPV6];
+			break;
+#endif
 		default:
 			mode = NPMODE_PASS;
 		}
@@ -1391,7 +1404,25 @@ ppp_inproc(struct ppp_softc *sc, struct 
 		ipv4_input(ifp, m);
 		rv = 1;
 		break;
+#ifdef INET6
+	case PPP_IPV6:
+		/*
+		 * IPv6 packet - take off the ppp header and pass it up to IPv6.
+		 */
+		if ((ifp->if_flags & IFF_UP) == 0 ||
+		    sc->sc_npmode[NP_IPV6] != NPMODE_PASS) {
+			/* interface is down - drop the packet. */
+			m_freem(m);
+			return;
+		}
+		m->m_pkthdr.len -= PPP_HDRLEN;
+		m->m_data += PPP_HDRLEN;
+		m->m_len -= PPP_HDRLEN;
 
+		ipv6_input(ifp, m);
+		rv = 1;
+		break;
+#endif
 	default:
 		/*
 		 * Some other protocol - place on input queue for read().
Index: if_pppvar.h
===================================================================
RCS file: /cvs/src/sys/net/if_pppvar.h,v
retrieving revision 1.20
diff -u -p -r1.20 if_pppvar.h
--- if_pppvar.h	20 May 2020 06:44:30 -0000	1.20
+++ if_pppvar.h	18 Feb 2024 19:45:18 -0000
@@ -81,7 +81,8 @@
  * indexing sc_npmode.
  */
 #define NP_IP	0		/* Internet Protocol */
-#define NUM_NP	1		/* Number of NPs. */
+#define NP_IPV6	1		/* Internet Protocol */
+#define NUM_NP	2		/* Number of NPs. */
 
 struct ppp_pkt;