summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-06 13:10:21 +0000
committermav <mav@FreeBSD.org>2015-10-06 13:10:21 +0000
commit342fcd5139a9a94688a4bad61f1adc310737c197 (patch)
treee0fe5811b6840a986af63837d12de9f687e6e71f /sys/netgraph
parent81d5da8e194608accbb7ab7cfcbad4949f4f491f (diff)
downloadFreeBSD-src-342fcd5139a9a94688a4bad61f1adc310737c197.zip
FreeBSD-src-342fcd5139a9a94688a4bad61f1adc310737c197.tar.gz
MFC r287654: Add support for PPP-Max-Payload PPPoE tag (RFC4638).
Submitted by: Dmitry Luhtionov <dmitryluhtionov@gmail.com>
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_pppoe.c45
-rw-r--r--sys/netgraph/ng_pppoe.h13
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c
index 6c2ed67..382410c 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 6ef81b7..3b74f07 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
OpenPOWER on IntegriCloud