Add support for PPP-Max-Payload PPPoE tag (RFC4638).

Submitted by:	Dmitry Luhtionov <dmitryluhtionov@gmail.com>
MFC after:	2 weeks
This commit is contained in:
Alexander Motin 2015-09-11 09:15:27 +00:00
parent 4d54c313b2
commit 5b363c09dc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287654
2 changed files with 58 additions and 0 deletions

View File

@ -168,6 +168,13 @@ static const struct ng_cmdlist ng_pppoe_cmds[] = {
&ng_parse_enaddr_type, &ng_parse_enaddr_type,
NULL NULL
}, },
{
NGM_PPPOE_COOKIE,
NGM_PPPOE_SETMAXP,
"setmaxp",
&ng_parse_uint16_type,
NULL
},
{ 0 } { 0 }
}; };
@ -262,6 +269,7 @@ struct PPPoE {
struct ether_header eh; struct ether_header eh;
LIST_HEAD(, sess_con) listeners; LIST_HEAD(, sess_con) listeners;
struct sess_hash_entry sesshash[SESSHASHSIZE]; struct sess_hash_entry sesshash[SESSHASHSIZE];
struct maxptag max_payload; /* PPP-Max-Payload (RFC4638) */
}; };
typedef struct PPPoE *priv_p; 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, bcopy(msg->data, &privp->eh.ether_shost,
ETHER_ADDR_LEN); ETHER_ADDR_LEN);
break; 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: default:
LEAVE(EINVAL); LEAVE(EINVAL);
} }
@ -1071,6 +1086,8 @@ pppoe_start(sessp sp)
init_tags(sp); init_tags(sp);
insert_tag(sp, &uniqtag.hdr); insert_tag(sp, &uniqtag.hdr);
insert_tag(sp, &neg->service.hdr); insert_tag(sp, &neg->service.hdr);
if (privp->max_payload.data != 0)
insert_tag(sp, &privp->max_payload.hdr);
make_packet(sp); make_packet(sp);
/* /*
* Send packet and prepare to retransmit it after timeout. * Send packet and prepare to retransmit it after timeout.
@ -1124,6 +1141,28 @@ send_sessionid(sessp sp)
return (error); 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. * 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 */ insert_tag(sp, tag); /* return it */
send_acname(sp, tag); 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 */ insert_tag(sp, &neg->service.hdr); /* Service */
scan_tags(sp, ph); scan_tags(sp, ph);
make_packet(sp); make_packet(sp);
@ -1602,6 +1644,9 @@ ng_pppoe_rcvdata_ether(hook_p hook, item_p item)
m_freem(neg->m); m_freem(neg->m);
free(sp->neg, M_NETGRAPH_PPPOE); free(sp->neg, M_NETGRAPH_PPPOE);
sp->neg = NULL; 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); pppoe_send_event(sp, NGM_PPPOE_SUCCESS);
break; break;
case PADT_CODE: case PADT_CODE:

View File

@ -51,6 +51,7 @@
#define NG_PPPOE_NODE_TYPE "pppoe" #define NG_PPPOE_NODE_TYPE "pppoe"
#define NGM_PPPOE_COOKIE 1089893072 #define NGM_PPPOE_COOKIE 1089893072
#define NGM_PPPOE_SETMAXP_COOKIE 1441624322
#define PPPOE_SERVICE_NAME_SIZE 64 /* for now */ #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_SETMODE = 12, /* set to standard or compat modes */
NGM_PPPOE_GETMODE = 13, /* see current mode */ NGM_PPPOE_GETMODE = 13, /* see current mode */
NGM_PPPOE_SETENADDR = 14, /* set Ethernet address */ NGM_PPPOE_SETENADDR = 14, /* set Ethernet address */
NGM_PPPOE_SETMAXP = 15 /* Set PPP-Max-Payload value */
}; };
/*********************** /***********************
@ -147,6 +149,13 @@ struct ngpppoe_sts {
{ NULL } \ { 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 * Constants and definitions specific to pppoe
@ -229,6 +238,10 @@ struct datatag {
u_int8_t data[PPPOE_SERVICE_NAME_SIZE]; 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 * Define the order in which we will place tags in packets