summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2004-08-03 06:45:38 +0000
committerbz <bz@FreeBSD.org>2004-08-03 06:45:38 +0000
commit3fbdc1b5aae3aa923dacb0fe39d145634773d164 (patch)
tree76b973445c982d543b8fc1e5e160439272adb623
parentf953a8bf192d15b2e06c34f625e961a8c5ab5a3f (diff)
downloadFreeBSD-src-3fbdc1b5aae3aa923dacb0fe39d145634773d164.zip
FreeBSD-src-3fbdc1b5aae3aa923dacb0fe39d145634773d164.tar.gz
add a new control message to set sequence numbers on an uninitialized node.
Reviewed by: archie Approved by: pjd (mentor)
-rw-r--r--share/man/man4/ng_l2tp.418
-rw-r--r--sys/netgraph/ng_l2tp.c63
-rw-r--r--sys/netgraph/ng_l2tp.h18
3 files changed, 96 insertions, 3 deletions
diff --git a/share/man/man4/ng_l2tp.4 b/share/man/man4/ng_l2tp.4
index 7e4496d..a54cd3a 100644
--- a/share/man/man4/ng_l2tp.4
+++ b/share/man/man4/ng_l2tp.4
@@ -37,7 +37,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 22, 2002
+.Dd August 2, 2004
.Dt NG_L2TP 4
.Os
.Sh NAME
@@ -273,6 +273,22 @@ The corresponding session hook must be connected.
Same as
.Dv NGM_L2TP_GET_STATS ,
but also atomically clears the statistics as well.
+.It Dv NGM_L2TP_SET_SEQ
+This command sets the sequence numbers of a not yet enabled node.
+It takes a
+.Vt "struct ng_l2tp_seq_config"
+as argument, where
+.Va xack
+and
+.Va nr
+respectively
+.Va ns
+and
+.Va rack
+must be the same.
+This option is particularly useful if one receives and processes
+the first packet entirely in userspace and wants to hand over further
+processing to the node.
.El
.Sh SHUTDOWN
This node shuts down upon receipt of a
diff --git a/sys/netgraph/ng_l2tp.c b/sys/netgraph/ng_l2tp.c
index b3b36c1..4d7efc7 100644
--- a/sys/netgraph/ng_l2tp.c
+++ b/sys/netgraph/ng_l2tp.c
@@ -171,6 +171,8 @@ static int ng_l2tp_recv_data(node_p node, item_p item, hookpriv_p hpriv);
static int ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns);
static void ng_l2tp_seq_init(priv_p priv);
+static int ng_l2tp_seq_set(priv_p priv,
+ const struct ng_l2tp_seq_config *conf);
static int ng_l2tp_seq_adjust(priv_p priv,
const struct ng_l2tp_config *conf);
static void ng_l2tp_seq_reset(priv_p priv);
@@ -187,6 +189,14 @@ static ng_fn_eachhook ng_l2tp_reset_session;
static void ng_l2tp_seq_check(struct l2tp_seq *seq);
#endif
+/* Parse type for struct ng_l2tp_seq_config. */
+static const struct ng_parse_struct_field
+ ng_l2tp_seq_config_fields[] = NG_L2TP_SEQ_CONFIG_TYPE_INFO;
+static const struct ng_parse_type ng_l2tp_seq_config_type = {
+ &ng_parse_struct_type,
+ &ng_l2tp_seq_config_fields
+};
+
/* Parse type for struct ng_l2tp_config */
static const struct ng_parse_struct_field
ng_l2tp_config_type_fields[] = NG_L2TP_CONFIG_TYPE_INFO;
@@ -269,6 +279,13 @@ static const struct ng_cmdlist ng_l2tp_cmdlist[] = {
NULL,
NULL
},
+ {
+ NGM_L2TP_COOKIE,
+ NGM_L2TP_SET_SEQ,
+ "setsequence",
+ &ng_l2tp_seq_config_type,
+ NULL
+ },
{ 0 }
};
@@ -457,7 +474,7 @@ ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook)
hookpriv_p hpriv;
hook_p hook;
- /* Check for invalid or illegal config */
+ /* Check for invalid or illegal config. */
if (msg->header.arglen != sizeof(*conf)) {
error = EINVAL;
break;
@@ -536,6 +553,25 @@ ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook)
memset(&priv->stats, 0, sizeof(priv->stats));
break;
}
+ case NGM_L2TP_SET_SEQ:
+ {
+ struct ng_l2tp_seq_config *const conf =
+ (struct ng_l2tp_seq_config *)msg->data;
+
+ /* Check for invalid or illegal seq config. */
+ if (msg->header.arglen != sizeof(*conf)) {
+ error = EINVAL;
+ break;
+ }
+ conf->ns = htons(conf->ns);
+ conf->nr = htons(conf->nr);
+ conf->rack = htons(conf->rack);
+ conf->xack = htons(conf->xack);
+
+ /* Set sequence numbers. */
+ error = ng_l2tp_seq_set(priv, conf);
+ break;
+ }
default:
error = EINVAL;
break;
@@ -1057,6 +1093,31 @@ ng_l2tp_seq_init(priv_p priv)
}
/*
+ * Set sequence number state as given from user.
+ */
+static int
+ng_l2tp_seq_set(priv_p priv, const struct ng_l2tp_seq_config *conf)
+{
+ struct l2tp_seq *const seq = &priv->seq;
+
+ /* If node is enabled, deny update to sequence numbers. */
+ if (priv->conf.enabled)
+ return (EBUSY);
+
+ /* We only can handle the simple cases. */
+ if (conf->xack != conf->nr || conf->ns != conf->rack)
+ return (EINVAL);
+
+ /* Set ns,nr,rack,xack parameters. */
+ seq->ns = conf->ns;
+ seq->nr = conf->nr;
+ seq->rack = conf->rack;
+ seq->xack = conf->xack;
+
+ return (0);
+}
+
+/*
* Adjust sequence number state accordingly after reconfiguration.
*/
static int
diff --git a/sys/netgraph/ng_l2tp.h b/sys/netgraph/ng_l2tp.h
index 4fe1d50..9ceb343 100644
--- a/sys/netgraph/ng_l2tp.h
+++ b/sys/netgraph/ng_l2tp.h
@@ -45,7 +45,7 @@
/* Node type name and magic cookie */
#define NG_L2TP_NODE_TYPE "l2tp"
-#define NGM_L2TP_COOKIE 1011392401
+#define NGM_L2TP_COOKIE 1091448040
/* Hook names */
#define NG_L2TP_HOOK_CTRL "ctrl" /* control channel hook */
@@ -55,6 +55,21 @@
#define NG_L2TP_HOOK_SESSION_P "session_" /* session data hook (prefix) */
#define NG_L2TP_HOOK_SESSION_F "session_%04x" /* session data hook (format) */
+/* Set intial sequence numbers to not yet enabled node. */
+struct ng_l2tp_seq_config {
+ u_int16_t ns; /* sequence number to send next */
+ u_int16_t nr; /* sequence number to be recved next */
+ u_int16_t rack; /* last 'nr' received */
+ u_int16_t xack; /* last 'nr' sent */
+};
+
+/* Keep this in sync with the above structure definition. */
+#define NG_L2TP_SEQ_CONFIG_TYPE_INFO { \
+ { "ns", &ng_parse_uint16_type }, \
+ { "nr", &ng_parse_uint16_type }, \
+ { NULL } \
+}
+
/* Configuration for a node */
struct ng_l2tp_config {
u_char enabled; /* enables traffic flow */
@@ -156,6 +171,7 @@ enum {
NGM_L2TP_CLR_STATS, /* clears stats */
NGM_L2TP_GETCLR_STATS, /* returns & clears stats */
NGM_L2TP_ACK_FAILURE, /* sent *from* node after ack timeout */
+ NGM_L2TP_SET_SEQ /* supply a struct ng_l2tp_seq_config */
};
#endif /* _NETGRAPH_NG_L2TP_H_ */
OpenPOWER on IntegriCloud