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:
parent
b45dc7cef1
commit
1e0313242d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=133058
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user