From 944716b2b2747176a9e56b32c4ac6d73047a033a Mon Sep 17 00:00:00 2001 From: mav Date: Tue, 6 Oct 2015 13:10:21 +0000 Subject: [PATCH] MFC r287654: Add support for PPP-Max-Payload PPPoE tag (RFC4638). Submitted by: Dmitry Luhtionov git-svn-id: svn://svn.freebsd.org/base/stable/10@288918 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/netgraph/ng_pppoe.c | 45 +++++++++++++++++++++++++++++++++++++++++ sys/netgraph/ng_pppoe.h | 13 ++++++++++++ 2 files changed, 58 insertions(+) diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index 6c2ed678d..382410c25 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -168,6 +168,13 @@ static const struct ng_cmdlist ng_pppoe_cmds[] = { &ng_parse_enaddr_type, NULL }, + { + NGM_PPPOE_COOKIE, + NGM_PPPOE_SETMAXP, + "setmaxp", + &ng_parse_uint16_type, + NULL + }, { 0 } }; @@ -262,6 +269,7 @@ struct PPPoE { struct ether_header eh; LIST_HEAD(, sess_con) listeners; struct sess_hash_entry sesshash[SESSHASHSIZE]; + struct maxptag max_payload; /* PPP-Max-Payload (RFC4638) */ }; typedef struct PPPoE *priv_p; @@ -1004,6 +1012,13 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook) bcopy(msg->data, &privp->eh.ether_shost, ETHER_ADDR_LEN); break; + case NGM_PPPOE_SETMAXP: + if (msg->header.arglen != sizeof(uint16_t)) + LEAVE(EINVAL); + privp->max_payload.hdr.tag_type = PTT_MAX_PAYL; + privp->max_payload.hdr.tag_len = htons(sizeof(uint16_t)); + privp->max_payload.data = htons(*((uint16_t *)msg->data)); + break; default: LEAVE(EINVAL); } @@ -1071,6 +1086,8 @@ pppoe_start(sessp sp) init_tags(sp); insert_tag(sp, &uniqtag.hdr); insert_tag(sp, &neg->service.hdr); + if (privp->max_payload.data != 0) + insert_tag(sp, &privp->max_payload.hdr); make_packet(sp); /* * Send packet and prepare to retransmit it after timeout. @@ -1124,6 +1141,28 @@ send_sessionid(sessp sp) return (error); } +static int +send_maxp(sessp sp, const struct pppoe_tag *tag) +{ + int error; + struct ng_mesg *msg; + struct ngpppoe_maxp *maxp; + + CTR2(KTR_NET, "%20s: called %d", __func__, sp->Session_ID); + + NG_MKMESSAGE(msg, NGM_PPPOE_COOKIE, NGM_PPPOE_SETMAXP, + sizeof(struct ngpppoe_maxp), M_NOWAIT); + if (msg == NULL) + return (ENOMEM); + + maxp = (struct ngpppoe_maxp *)msg->data; + strncpy(maxp->hook, NG_HOOK_NAME(sp->hook), NG_HOOKSIZ); + maxp->data = ntohs(((const struct maxptag *)tag)->data); + NG_SEND_MSG_ID(error, NG_HOOK_NODE(sp->hook), msg, sp->creator, 0); + + return (error); +} + /* * Receive data from session hook and do something with it. */ @@ -1464,6 +1503,9 @@ ng_pppoe_rcvdata_ether(hook_p hook, item_p item) insert_tag(sp, tag); /* return it */ send_acname(sp, tag); } + if ((tag = get_tag(ph, PTT_MAX_PAYL)) && + (privp->max_payload.data != 0)) + insert_tag(sp, tag); /* return it */ insert_tag(sp, &neg->service.hdr); /* Service */ scan_tags(sp, ph); make_packet(sp); @@ -1602,6 +1644,9 @@ ng_pppoe_rcvdata_ether(hook_p hook, item_p item) m_freem(neg->m); free(sp->neg, M_NETGRAPH_PPPOE); sp->neg = NULL; + if ((tag = get_tag(ph, PTT_MAX_PAYL)) && + (privp->max_payload.data != 0)) + send_maxp(sp, tag); pppoe_send_event(sp, NGM_PPPOE_SUCCESS); break; case PADT_CODE: diff --git a/sys/netgraph/ng_pppoe.h b/sys/netgraph/ng_pppoe.h index 6ef81b791..3b74f07b9 100644 --- a/sys/netgraph/ng_pppoe.h +++ b/sys/netgraph/ng_pppoe.h @@ -51,6 +51,7 @@ #define NG_PPPOE_NODE_TYPE "pppoe" #define NGM_PPPOE_COOKIE 1089893072 +#define NGM_PPPOE_SETMAXP_COOKIE 1441624322 #define PPPOE_SERVICE_NAME_SIZE 64 /* for now */ @@ -83,6 +84,7 @@ enum cmd { NGM_PPPOE_SETMODE = 12, /* set to standard or compat modes */ NGM_PPPOE_GETMODE = 13, /* see current mode */ NGM_PPPOE_SETENADDR = 14, /* set Ethernet address */ + NGM_PPPOE_SETMAXP = 15 /* Set PPP-Max-Payload value */ }; /*********************** @@ -147,6 +149,13 @@ struct ngpppoe_sts { { NULL } \ } +/* + * This structure is used to send PPP-Max-Payload value from server to client. + */ +struct ngpppoe_maxp { + char hook[NG_HOOKSIZ]; /* hook associated with event session */ + uint16_t data; +}; /******************************************************************** * Constants and definitions specific to pppoe @@ -229,6 +238,10 @@ struct datatag { u_int8_t data[PPPOE_SERVICE_NAME_SIZE]; }; +struct maxptag { + struct pppoe_tag hdr; + uint16_t data; +}; /* * Define the order in which we will place tags in packets -- 2.45.0