* Receive a control message. */
| 444 | * Receive a control message. |
| 445 | */ |
| 446 | static int |
| 447 | ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook) |
| 448 | { |
| 449 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 450 | struct ng_mesg *resp = NULL; |
| 451 | struct ng_mesg *msg; |
| 452 | int error = 0; |
| 453 | |
| 454 | NGI_GET_MSG(item, msg); |
| 455 | switch (msg->header.typecookie) { |
| 456 | case NGM_L2TP_COOKIE: |
| 457 | switch (msg->header.cmd) { |
| 458 | case NGM_L2TP_SET_CONFIG: |
| 459 | { |
| 460 | struct ng_l2tp_config *const conf = |
| 461 | (struct ng_l2tp_config *)msg->data; |
| 462 | |
| 463 | /* Check for invalid or illegal config */ |
| 464 | if (msg->header.arglen != sizeof(*conf)) { |
| 465 | error = EINVAL; |
| 466 | break; |
| 467 | } |
| 468 | conf->enabled = !!conf->enabled; |
| 469 | conf->match_id = !!conf->match_id; |
| 470 | if (priv->conf.enabled |
| 471 | && ((priv->conf.tunnel_id != 0 |
| 472 | && conf->tunnel_id != priv->conf.tunnel_id) |
| 473 | || ((priv->conf.peer_id != 0 |
| 474 | && conf->peer_id != priv->conf.peer_id)))) { |
| 475 | error = EBUSY; |
| 476 | break; |
| 477 | } |
| 478 | |
| 479 | /* Save calling node as failure target */ |
| 480 | priv->ftarget = NGI_RETADDR(item); |
| 481 | |
| 482 | /* Adjust sequence number state */ |
| 483 | if ((error = ng_l2tp_seq_adjust(priv, conf)) != 0) |
| 484 | break; |
| 485 | |
| 486 | /* Update node's config */ |
| 487 | priv->conf = *conf; |
| 488 | break; |
| 489 | } |
| 490 | case NGM_L2TP_GET_CONFIG: |
| 491 | { |
| 492 | struct ng_l2tp_config *conf; |
| 493 | |
| 494 | NG_MKRESPONSE(resp, msg, sizeof(*conf), M_NOWAIT); |
| 495 | if (resp == NULL) { |
| 496 | error = ENOMEM; |
| 497 | break; |
| 498 | } |
| 499 | conf = (struct ng_l2tp_config *)resp->data; |
| 500 | *conf = priv->conf; |
| 501 | break; |
| 502 | } |
| 503 | case NGM_L2TP_SET_SESS_CONFIG: |
nothing calls this directly
no test coverage detected