diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index 6bcc6234a05e..cc8a46000ee2 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -235,7 +235,7 @@ struct sess_con { ng_ID_t creator; /* who to notify */ struct pppoe_full_hdr pkt_hdr; /* used when connected */ negp neg; /* used when negotiating */ - TAILQ_ENTRY(sess_con) sessions; + LIST_ENTRY(sess_con) sessions; }; typedef struct sess_con *sessp; @@ -244,7 +244,7 @@ typedef struct sess_con *sessp; struct sess_hash_entry { struct mtx mtx; - TAILQ_HEAD(hhead, sess_con) head; + LIST_HEAD(hhead, sess_con) head; }; /* @@ -260,6 +260,7 @@ struct PPPoE { #define COMPAT_3COM 0x00000001 #define COMPAT_DLINK 0x00000002 struct ether_header eh; + LIST_HEAD(, sess_con) listeners; struct sess_hash_entry sesshash[SESSHASHSIZE]; }; typedef struct PPPoE *priv_p; @@ -415,21 +416,11 @@ make_packet(sessp sp) { static hook_p pppoe_match_svc(node_p node, const struct pppoe_tag *tag) { - hook_p hook; + const priv_p privp = NG_NODE_PRIVATE(node); + sessp sp; - LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) { - sessp sp = NG_HOOK_PRIVATE(hook); - negp neg; - - /* Skip any nonsession hook. */ - if (sp == NULL) - continue; - - /* Skip any sessions which are not in LISTEN mode. */ - if (sp->state != PPPOE_LISTENING) - continue; - - neg = sp->neg; + LIST_FOREACH(sp, &privp->listeners, sessions) { + negp neg = sp->neg; /* Empty Service-Name matches any service. */ if (neg->service_len == 0) @@ -447,9 +438,10 @@ pppoe_match_svc(node_p node, const struct pppoe_tag *tag) ntohs(tag->tag_len)) == 0) break; } - CTR3(KTR_NET, "%20s: matched %p for %s", __func__, hook, tag->tag_data); + CTR3(KTR_NET, "%20s: matched %p for %s", __func__, + sp?sp->hook:NULL, tag->tag_data); - return (hook); + return (sp?sp->hook:NULL); } /* @@ -461,27 +453,17 @@ pppoe_match_svc(node_p node, const struct pppoe_tag *tag) static int pppoe_broadcast_padi(node_p node, struct mbuf *m0) { - hook_p hook; + const priv_p privp = NG_NODE_PRIVATE(node); + sessp sp; int error = 0; - LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) { - sessp sp = NG_HOOK_PRIVATE(hook); + LIST_FOREACH(sp, &privp->listeners, sessions) { struct mbuf *m; - /* - * Go through all listening hooks and - * broadcast the PADI packet up there - */ - if (sp == NULL) - continue; - - if (sp->state != PPPOE_LISTENING) - continue; - m = m_dup(m0, M_DONTWAIT); if (m == NULL) return (ENOMEM); - NG_SEND_DATA_ONLY(error, hook, m); + NG_SEND_DATA_ONLY(error, sp->hook, m); if (error) return (error); } @@ -495,25 +477,15 @@ pppoe_broadcast_padi(node_p node, struct mbuf *m0) static hook_p pppoe_find_svc(node_p node, const char *svc_name, int svc_len) { - hook_p hook; + const priv_p privp = NG_NODE_PRIVATE(node); + sessp sp; - LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) { - sessp sp = NG_HOOK_PRIVATE(hook); - negp neg; - - /* Skip any nonsession hook. */ - if (sp == NULL) - continue; - - /* Skip any sessions which are not in LISTEN mode. */ - if (sp->state != PPPOE_LISTENING) - continue; - - neg = sp->neg; + LIST_FOREACH(sp, &privp->listeners, sessions) { + negp neg = sp->neg; if (neg->service_len == svc_len && strncmp(svc_name, neg->service.data, svc_len) == 0) - return (hook); + return (sp->hook); } return (NULL); @@ -541,13 +513,13 @@ restart: /* Check it isn't already in use. */ hash = SESSHASH(val); mtx_lock(&privp->sesshash[hash].mtx); - TAILQ_FOREACH(tsp, &privp->sesshash[hash].head, sessions) { + LIST_FOREACH(tsp, &privp->sesshash[hash].head, sessions) { if (tsp->Session_ID == val) break; } if (!tsp) { sp->Session_ID = val; - TAILQ_INSERT_HEAD(&privp->sesshash[hash].head, sp, sessions); + LIST_INSERT_HEAD(&privp->sesshash[hash].head, sp, sessions); } mtx_unlock(&privp->sesshash[hash].mtx); if (tsp) @@ -566,7 +538,7 @@ pppoe_addsession(sessp sp) uint16_t hash = SESSHASH(sp->Session_ID); mtx_lock(&privp->sesshash[hash].mtx); - TAILQ_INSERT_HEAD(&privp->sesshash[hash].head, sp, sessions); + LIST_INSERT_HEAD(&privp->sesshash[hash].head, sp, sessions); mtx_unlock(&privp->sesshash[hash].mtx); } @@ -578,7 +550,7 @@ pppoe_delsession(sessp sp) uint16_t hash = SESSHASH(sp->Session_ID); mtx_lock(&privp->sesshash[hash].mtx); - TAILQ_REMOVE(&privp->sesshash[hash].head, sp, sessions); + LIST_REMOVE(sp, sessions); mtx_unlock(&privp->sesshash[hash].mtx); } @@ -591,7 +563,7 @@ pppoe_findsession(priv_p privp, const struct pppoe_full_hdr *wh) sessp sp = NULL; mtx_lock(&privp->sesshash[hash].mtx); - TAILQ_FOREACH(sp, &privp->sesshash[hash].head, sessions) { + LIST_FOREACH(sp, &privp->sesshash[hash].head, sessions) { if (sp->Session_ID == session && bcmp(sp->pkt_hdr.eh.ether_dhost, wh->eh.ether_shost, ETHER_ADDR_LEN) == 0) { @@ -651,9 +623,10 @@ ng_pppoe_constructor(node_p node) memset(&privp->eh.ether_dhost, 0xff, ETHER_ADDR_LEN); privp->eh.ether_type = ETHERTYPE_PPPOE_DISC; + LIST_INIT(&privp->listeners); for (i = 0; i < SESSHASHSIZE; i++) { mtx_init(&privp->sesshash[i].mtx, "PPPoE hash mutex", NULL, MTX_DEF); - TAILQ_INIT(&privp->sesshash[i].head); + LIST_INIT(&privp->sesshash[i].head); } CTR3(KTR_NET, "%20s: created node [%x] (%p)", @@ -789,18 +762,12 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook) /* Make sure strcmp will terminate safely. */ ourmsg->hook[sizeof(ourmsg->hook) - 1] = '\0'; - /* Cycle through all known hooks. */ - LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) { - if (NG_HOOK_NAME(hook) && - strcmp(NG_HOOK_NAME(hook), ourmsg->hook) == - 0) - break; - } + /* Find hook by name. */ + hook = ng_findhook(node, ourmsg->hook); if (hook == NULL) LEAVE(ENOENT); sp = NG_HOOK_PRIVATE(hook); - if (sp == NULL) LEAVE(EINVAL); @@ -922,6 +889,7 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook) * Wait for PADI packet coming from Ethernet. */ sp->state = PPPOE_LISTENING; + LIST_INSERT_HEAD(&privp->listeners, sp, sessions); break; case NGM_PPPOE_OFFER: /* @@ -1810,7 +1778,9 @@ ng_pppoe_disconnect(hook_p hook) privp->ethernet_hook, m); } } - if (sp->Session_ID) + if (sp->state == PPPOE_LISTENING) + LIST_REMOVE(sp, sessions); + else if (sp->Session_ID) pppoe_delsession(sp); /* * As long as we have somewhere to store the timeout handle,