summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_pppoe.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2001-07-25 03:34:07 +0000
committerbrian <brian@FreeBSD.org>2001-07-25 03:34:07 +0000
commitaa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf (patch)
tree2fcf4b2e1988ab52ce700a74dddc51bab9ee95d7 /sys/netgraph/ng_pppoe.c
parent28c44c45cbe37e450773f5aacb8d8219d2d415b6 (diff)
downloadFreeBSD-src-aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf.zip
FreeBSD-src-aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf.tar.gz
If an attempt is made to LISTEN for a service tag that's already being
LISTENed for, return EEXISTS. Only match the magic "*" service tag if no other LISTEN service tags match. Require an explicit LISTEN for an empty service tag in order to match empty service requests. Approved by: julian MFC after: 3 days
Diffstat (limited to 'sys/netgraph/ng_pppoe.c')
-rw-r--r--sys/netgraph/ng_pppoe.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c
index faa323c..2378e7a 100644
--- a/sys/netgraph/ng_pppoe.c
+++ b/sys/netgraph/ng_pppoe.c
@@ -451,13 +451,18 @@ AAA
* for testing allow a null string to match 1st found and a null service
* to match all requests. Also make '*' do the same.
*/
+
+#define NG_MATCH_EXACT 1
+#define NG_MATCH_ANY 2
+
static hook_p
-pppoe_match_svc(node_p node, char *svc_name, int svc_len)
+pppoe_match_svc(node_p node, char *svc_name, int svc_len, int match)
{
sessp sp = NULL;
negp neg = NULL;
priv_p privp = NG_NODE_PRIVATE(node);
- hook_p hook;
+ hook_p allhook = NULL;
+ hook_p hook;
AAA
LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
@@ -473,17 +478,12 @@ AAA
continue;
neg = sp->neg;
- /* XXX check validity of this */
- /* special case, NULL request. match 1st found. */
- if (svc_len == 0)
- break;
- /* XXX check validity of this */
/* Special case for a blank or "*" service name (wildcard) */
- if ((neg->service_len == 0)
- || ((neg->service_len == 1)
- && (neg->service.data[0] == '*'))) {
- break;
+ if (match == NG_MATCH_ANY && neg->service_len == 1 &&
+ neg->service.data[0] == '*') {
+ allhook = hook;
+ continue;
}
/* If the lengths don't match, that aint it. */
@@ -491,10 +491,13 @@ AAA
continue;
/* An exact match? */
+ if (svc_len == 0)
+ break;
+
if (strncmp(svc_name, neg->service.data, svc_len) == 0)
break;
}
- return (hook);
+ return (hook ? hook : allhook);
}
/**************************************************************************
* Routine to find a particular session that matches an incoming packet *
@@ -685,6 +688,17 @@ AAA
}
sp = NG_HOOK_PRIVATE(hook);
+ if (msg->header.cmd == NGM_PPPOE_LISTEN) {
+ /*
+ * Ensure we aren't already listening for this
+ * service.
+ */
+ if (pppoe_match_svc(node, ourmsg->data,
+ ourmsg->data_len, NG_MATCH_EXACT) != NULL) {
+ LEAVE(EEXIST);
+ }
+ }
+
/*
* PPPOE_SERVICE advertisments are set up
* on sessions that are in PRIMED state.
@@ -991,12 +1005,12 @@ AAA
LEAVE(ENETUNREACH);
}
sendhook = pppoe_match_svc(NG_HOOK_NODE(hook),
- tag->tag_data, ntohs(tag->tag_len));
+ tag->tag_data, ntohs(tag->tag_len),
+ NG_MATCH_ANY);
if (sendhook) {
NG_FWD_NEW_DATA(error, item,
sendhook, m);
} else {
- printf("no such service\n");
LEAVE(ENETUNREACH);
}
break;
OpenPOWER on IntegriCloud