Fix ng_pppoe(4) after turning off "autosrc feature" on ng_ether(4).
- Store the Ethernet header in node softc. - Initialize header with dst addr and ethertype in node constructor method. - In node connect method send NGM_ETHER_GET_ENADDR message downwards. - If received reply from ng_ether(4) store the src addr in softc. - Add NGM_PPPOE_SETENDADDR message that allows user to override the address with whatever he/she wants.
This commit is contained in:
parent
de6f1c7c6c
commit
b1ba28df1d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=161117
@ -35,7 +35,7 @@
|
||||
.\" $FreeBSD$
|
||||
.\" $Whistle: ng_pppoe.8,v 1.1 1999/01/25 23:46:27 archie Exp $
|
||||
.\"
|
||||
.Dd January 27, 2006
|
||||
.Dd August 9, 2006
|
||||
.Dt NG_PPPOE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -70,7 +70,14 @@ This node type supports the following hooks:
|
||||
.Pp
|
||||
.Bl -tag -width [unspecified]
|
||||
.It Dv ethernet
|
||||
The hook that should normally be connected to an Ethernet node.
|
||||
The hook that should normally be connected to an
|
||||
.Xr ng_ether 4
|
||||
node.
|
||||
Once connected,
|
||||
.Nm
|
||||
will send a message down this hook to determine Ethernet address of
|
||||
the underlying node.
|
||||
Obtained address will be stored and then used for outgoing datagrams.
|
||||
.It Dv debug
|
||||
Presently no use.
|
||||
.It Dv [unspecified]
|
||||
@ -227,6 +234,15 @@ the next session in the proprietary 3Com mode:
|
||||
.Bd -literal -offset indent
|
||||
ngctl msg fxp0:orphans pppoe_setmode '"3Com"'
|
||||
.Ed
|
||||
.It Dv NGM_PPPOE_SETENADDR
|
||||
Set the node Ethernet address for outgoing datagrams.
|
||||
This message is important when node failed to obtain Ethernet address
|
||||
from peer on
|
||||
.Dv ethernet
|
||||
hook, or when user wants to override this address with another one.
|
||||
.Tn ASCII
|
||||
form of this message is
|
||||
.Qq Li setenaddr .
|
||||
.El
|
||||
.Sh SHUTDOWN
|
||||
This node shuts down upon receipt of a
|
||||
@ -466,6 +482,7 @@ setup(char *ethername, char *service, char *sessname,
|
||||
.Sh SEE ALSO
|
||||
.Xr netgraph 3 ,
|
||||
.Xr netgraph 4 ,
|
||||
.Xr ng_ether 4 ,
|
||||
.Xr ng_ppp 4 ,
|
||||
.Xr ng_socket 4 ,
|
||||
.Xr ngctl 8 ,
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <netgraph/netgraph.h>
|
||||
#include <netgraph/ng_parse.h>
|
||||
#include <netgraph/ng_pppoe.h>
|
||||
#include <netgraph/ng_ether.h>
|
||||
|
||||
#ifdef NG_SEPARATE_MALLOC
|
||||
MALLOC_DEFINE(M_NETGRAPH_PPPOE, "netgraph_pppoe", "netgraph pppoe node");
|
||||
@ -74,6 +75,7 @@ static ng_constructor_t ng_pppoe_constructor;
|
||||
static ng_rcvmsg_t ng_pppoe_rcvmsg;
|
||||
static ng_shutdown_t ng_pppoe_shutdown;
|
||||
static ng_newhook_t ng_pppoe_newhook;
|
||||
static ng_connect_t ng_pppoe_connect;
|
||||
static ng_rcvdata_t ng_pppoe_rcvdata;
|
||||
static ng_disconnect_t ng_pppoe_disconnect;
|
||||
|
||||
@ -158,6 +160,13 @@ static const struct ng_cmdlist ng_pppoe_cmds[] = {
|
||||
NULL,
|
||||
&ng_parse_string_type
|
||||
},
|
||||
{
|
||||
NGM_PPPOE_COOKIE,
|
||||
NGM_PPPOE_SETENADDR,
|
||||
"setenaddr",
|
||||
&ng_parse_enaddr_type,
|
||||
NULL
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -169,6 +178,7 @@ static struct ng_type typestruct = {
|
||||
.rcvmsg = ng_pppoe_rcvmsg,
|
||||
.shutdown = ng_pppoe_shutdown,
|
||||
.newhook = ng_pppoe_newhook,
|
||||
.connect = ng_pppoe_connect,
|
||||
.rcvdata = ng_pppoe_rcvdata,
|
||||
.disconnect = ng_pppoe_disconnect,
|
||||
.cmdlist = ng_pppoe_cmds,
|
||||
@ -229,16 +239,6 @@ typedef struct sess_con *sessp;
|
||||
|
||||
#define NG_PPPOE_SESSION_NODE(sp) NG_HOOK_NODE(sp->hook)
|
||||
|
||||
static const struct ether_header eh_standard =
|
||||
{{0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
ETHERTYPE_PPPOE_DISC};
|
||||
|
||||
static const struct ether_header eh_3Com =
|
||||
{{0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
ETHERTYPE_PPPOE_3COM_DISC};
|
||||
|
||||
/*
|
||||
* Information we store for each node
|
||||
*/
|
||||
@ -251,7 +251,7 @@ struct PPPoE {
|
||||
uint32_t flags;
|
||||
#define COMPAT_3COM 0x00000001
|
||||
#define COMPAT_DLINK 0x00000002
|
||||
const struct ether_header *eh; /* standard PPPoE or 3Com? */
|
||||
struct ether_header eh;
|
||||
};
|
||||
typedef struct PPPoE *priv_p;
|
||||
|
||||
@ -635,7 +635,8 @@ ng_pppoe_constructor(node_p node)
|
||||
privp->node = node;
|
||||
|
||||
/* Initialize to standard mode. */
|
||||
privp->eh = &eh_standard;
|
||||
memset(&privp->eh.ether_dhost, 0xff, ETHER_ADDR_LEN);
|
||||
privp->eh.ether_type = ETHERTYPE_PPPOE_DISC;
|
||||
|
||||
CTR3(KTR_NET, "%20s: created node [%x] (%p)",
|
||||
__func__, node->nd_ID, node);
|
||||
@ -683,6 +684,38 @@ ng_pppoe_newhook(node_p node, hook_p hook, const char *name)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook has been added successfully. Request the MAC address of
|
||||
* the underlying Ethernet node.
|
||||
*/
|
||||
static int
|
||||
ng_pppoe_connect(hook_p hook)
|
||||
{
|
||||
const priv_p privp = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
|
||||
struct ng_mesg *msg;
|
||||
int error = 0;
|
||||
|
||||
if (hook != privp->ethernet_hook)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* If this is Ethernet hook, then request MAC address
|
||||
* from our downstream.
|
||||
*/
|
||||
NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_GET_ENADDR, 0, M_NOWAIT);
|
||||
if (msg == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
/*
|
||||
* Our hook and peer hook have HK_INVALID flag set,
|
||||
* so we can't use NG_SEND_MSG_HOOK() macro here.
|
||||
*/
|
||||
NG_SEND_MSG_ID(error, privp->node, msg,
|
||||
NG_NODE_ID(NG_PEER_NODE(privp->ethernet_hook)),
|
||||
NG_NODE_ID(privp->node));
|
||||
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* Get a netgraph control message.
|
||||
* Check it is one we understand. If needed, send a response.
|
||||
@ -797,8 +830,7 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
neg->m->m_len = sizeof(struct pppoe_full_hdr);
|
||||
neg->pkt = mtod(neg->m, union packet*);
|
||||
memcpy((void *)&neg->pkt->pkt_header.eh,
|
||||
(const void *)privp->eh,
|
||||
sizeof(struct ether_header));
|
||||
&privp->eh, sizeof(struct ether_header));
|
||||
neg->pkt->pkt_header.ph.ver = 0x1;
|
||||
neg->pkt->pkt_header.ph.type = 0x1;
|
||||
neg->pkt->pkt_header.ph.sid = 0x0000;
|
||||
@ -917,13 +949,14 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
if (len == strlen(NG_PPPOE_STANDARD) &&
|
||||
(strncmp(NG_PPPOE_STANDARD, s, len) == 0)) {
|
||||
privp->flags = 0;
|
||||
privp->eh = &eh_standard;
|
||||
privp->eh.ether_type = ETHERTYPE_PPPOE_DISC;
|
||||
break;
|
||||
}
|
||||
if (len == strlen(NG_PPPOE_3COM) &&
|
||||
(strncmp(NG_PPPOE_3COM, s, len) == 0)) {
|
||||
privp->flags |= COMPAT_3COM;
|
||||
privp->eh = &eh_3Com;
|
||||
privp->eh.ether_type =
|
||||
ETHERTYPE_PPPOE_3COM_DISC;
|
||||
break;
|
||||
}
|
||||
if (len == strlen(NG_PPPOE_DLINK) &&
|
||||
@ -969,10 +1002,30 @@ ng_pppoe_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NGM_PPPOE_SETENADDR:
|
||||
if (msg->header.arglen != ETHER_ADDR_LEN)
|
||||
LEAVE(EINVAL);
|
||||
bcopy(msg->data, &privp->eh.ether_shost,
|
||||
ETHER_ADDR_LEN);
|
||||
break;
|
||||
default:
|
||||
LEAVE(EINVAL);
|
||||
}
|
||||
break;
|
||||
case NGM_ETHER_COOKIE:
|
||||
if (!(msg->header.flags & NGF_RESP))
|
||||
LEAVE(EINVAL);
|
||||
switch (msg->header.cmd) {
|
||||
case NGM_ETHER_GET_ENADDR:
|
||||
if (msg->header.arglen != ETHER_ADDR_LEN)
|
||||
LEAVE(EINVAL);
|
||||
bcopy(msg->data, &privp->eh.ether_shost,
|
||||
ETHER_ADDR_LEN);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LEAVE(EINVAL);
|
||||
}
|
||||
@ -1006,11 +1059,10 @@ pppoe_start(sessp sp)
|
||||
sp->state = PPPOE_SINIT;
|
||||
/*
|
||||
* Reset the packet header to broadcast. Since we are
|
||||
* in a client
|
||||
* mode use configured ethertype.
|
||||
* in a client mode use configured ethertype.
|
||||
*/
|
||||
memcpy((void *)&sp->neg->pkt->pkt_header.eh,
|
||||
(const void *)privp->eh, sizeof(struct ether_header));
|
||||
memcpy((void *)&sp->neg->pkt->pkt_header.eh, &privp->eh,
|
||||
sizeof(struct ether_header));
|
||||
sp->neg->pkt->pkt_header.ph.code = PADI_CODE;
|
||||
uniqtag.hdr.tag_type = PTT_HOST_UNIQ;
|
||||
uniqtag.hdr.tag_len = htons((u_int16_t)sizeof(uniqtag.data));
|
||||
|
@ -85,8 +85,9 @@ enum cmd {
|
||||
NGM_PPPOE_ACNAME = 9, /* AC_NAME for informational purposes */
|
||||
NGM_PPPOE_GET_STATUS = 10, /* data in/out */
|
||||
NGM_PPPOE_SESSIONID = 11, /* Session_ID for informational purposes */
|
||||
NGM_PPPOE_SETMODE = 12, /* set to standard or 3Com mode */
|
||||
NGM_PPPOE_SETMODE = 12, /* set to standard or compat modes */
|
||||
NGM_PPPOE_GETMODE = 13, /* see current mode */
|
||||
NGM_PPPOE_SETENADDR = 14, /* set Ethernet address */
|
||||
};
|
||||
|
||||
/***********************
|
||||
|
Loading…
Reference in New Issue
Block a user