add a new control message to set sequence numbers on an uninitialized node.

Reviewed by:	archie
Approved by:	pjd (mentor)
This commit is contained in:
Bjoern A. Zeeb 2004-08-03 06:45:38 +00:00
parent b45dc7cef1
commit 1e0313242d
3 changed files with 96 additions and 3 deletions

View File

@ -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

View File

@ -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;
@ -1056,6 +1092,31 @@ ng_l2tp_seq_init(priv_p priv)
L2TP_SEQ_CHECK(seq);
}
/*
* 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.
*/

View File

@ -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_ */