NG_PPTPGRE(4)
π NG_PPTPGRE π
okay bestie, sit DOWN, because we're talking about ng_pptpgre β that's the PPTP GRE protocol netgraph node type from the Kernel Interfaces Manual. yes it's a mouthful, no you're not gonna pronounce it right the first time, and yes it is lowkey iconic. let's get into it π
β¨ SYNOPSIS β¨
like all the cool netgraph kids, you gotta include the headers first:
#include <sys/types.h>
#include <netgraph/ng_pptpgre.h>
π¦ DESCRIPTION π¦
so. this node type does Generic Routing Encapsulation (GRE) over IP for the PPTP protocol, exactly as specified by RFC 2637. and when I say "does" I mean it handles the whole glow-up: packet encapsulation, sequencing, acknowledgement, AND an adaptive timeout sliding window mechanism. she's doing a lot, honestly.
π«Ά heads up though: this node does NOT touch any of the TCP control protocol or call negotiation that PPTP defines. that's somebody else's job, not hers.
the vibe on the hooks is very specific and you need to get it right:
- she expects to receive complete IP packets, including the IP header, on the
lowerhook. - but she transmits outgoing frames without any IP header. asymmetry queen π
the typical setup β and this is the classic combo, iykyk β is to connect the upper hook to one of the link hooks of an ng_ppp(4) node, and the lower hook to the inet/raw/gre hook of an ng_ksocket(4) node. match made in heaven fr fr β¨
π HOOKS π
this node type supports the following hooks, and there are literally three of them, so no excuses:
session_hhhhβ Session0xhhhhdata packets headed up to the upper protocol layers πΈupperβ same assession_hhhh, but for a single session with a configurablecid(the legacy route, respect your elders)lowerβ the connection down to the lower protocol layers π«Ά
π CONTROL MESSAGES π
she supports all the generic control messages (obviously, she's not a monster), plus these ones:
NGM_PPTPGRE_SET_CONFIG(also known assetconfig) β this command resets and configures the hook for a session. here's the little detail that trips people up: if the correspondingsession_hhhhhook is not connected, then theupperhook gets configured instead. sneaky but fair. this command takes astruct ng_pptpgre_confas its argument:
/* Configuration for a session */
struct ng_pptpgre_conf {
u_char enabled; /* enables traffic flow */
u_char enableDelayedAck; /* enables delayed acks */
u_char enableAlwaysAck; /* always include ack with data */
u_char enableWindowing; /* enable windowing algorithm */
uint16_t cid; /* my call id */
uint16_t peerCid; /* peer call id */
uint16_t recvWin; /* peer recv window size */
uint16_t peerPpd; /* peer packet processing delay
(in 1/10 of a second) */
};
okay let's break down the fields because they all matter:
enabledβ turns traffic flow through the node on. the on/off switch, the vibe gate.enableDelayedAckβ enables delayed acknowledgement, max 250 milliseconds. this is a genuinely useful optimization and you should generally have it turned ON. bestie, leave it on.enableAlwaysAckβ sends acknowledgements with every data packet. probably helpful as well, so like, sure πenableWindowingβ enables the PPTP packet windowing mechanism as specified by the protocol. and here's the tea: disabling it makes the node violate the protocol, which can confuse other PPTP peersβ¦ but it often results in better performance. the windowing mechanism is, and I quote, a design error in the PPTP protocol β L2TP, PPTP's successor, straight up removes it. not me defending a protocol's mistakes but ok π- the remaining fields are as supplied by the PPTP virtual call setup process. you don't make those up, you get them handed to you.
NGM_PPTPGRE_GET_CONFIG(akagetconfig) β takes a two byte argument ascidand returns the current configuration as astruct ng_pptpgre_conf. give her a cid, she gives you the config. transactional icon πNGM_PPTPGRE_GET_STATS(akagetstats) β returns astruct ng_pptpgre_statsstuffed with various node statistics. numbers! love that for us πNGM_PPTPGRE_CLR_STATS(akaclrstats) β resets the node statistics. clean slate energy β¨NGM_PPTPGRE_GETCLR_STATS(akagetclrstats) β atomically gets AND resets the node statistics, returning astruct ng_pptpgre_stats. one message, two jobs, main character behavior π
π SHUTDOWN π
this node shuts down when she receives a NGM_SHUTDOWN control message β or when both hooks have been disconnected. she's not sticking around if nobody's talking to her. bye bestie π
β SYSCTL VARIABLES β
there's a whole set of sysctl(8) variables that control how well this node deals with a certain amount of packet reorder that sometimes happens in transit. and why does that matter? because packet reorder results in packet drops β unless the order gets restored β since the PPP protocol cannot deliver reordered data. periodt.
here they are, with their default values and what they mean:
net.graph.pptpgre.reorder_max: 1β defines the maximum length of the node's private reorder queue, which is what she uses to keep data waiting for late packets. a value of zero disables reordering entirely. the default value lets the node restore the order for two packets swapped in transit. bigger values let the node deliver packets that are late after more packets in sequence β but at the cost of increased kernel memory usage. so like, more patience, more RAM, your call πnet.graph.pptpgre.reorder_timeout: 1β defines the time value, in miliseconds, used to wait for late packets. she'll wait. but only for that long. β³
π SEE ALSO π
and the reading list, because we stay educated π:
- K. Hamzeh, G. Pall, W. Verthein, J. Taarud, W. Little, and G. Zorn, Point-to-Point Tunneling Protocol (PPTP), RFC 2637.
- S. Hanks, T. Li, D. Farinacci, and P. Traina, Generic Routing Encapsulation over IPv4 networks, RFC 1702.
πΈ HISTORY πΈ
the ng_pptpgre node type was implemented in FreeBSD 4.0. vintage, honestly. she's been serving since before some of us could read π«Ά
π AUTHORS π
Archie Cobbs <archie@FreeBSD.org> β thank you for your service, king π
π BUGS π
okay so, the one thing to know: the node should not expect incoming GRE packets to have an IP header. this behavior is inherited from the (converse) behavior of raw IP sockets β it's a whole thing, it's legacy, don't @ her. the fix, per the docs, is to use an intermediate node that strips IP headers in one direction instead. that's the move. do that. π
and that's the whole page, bestie!! πβ¨π¦
this was served up as part of the Debian build of the manual, dated November 4, 2018. go forth and encapsulate responsibly π
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 1996-1999 Whistle Communications, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms