Add support for the optional key in the GRE header.
PR: kern/114714 Submitted by: Cristian KLEIN
This commit is contained in:
parent
bf94b8a5bf
commit
0c235e44e0
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 11, 2008
|
||||
.Dd June 20, 2008
|
||||
.Dt IFCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -2011,6 +2011,16 @@ Another name for the
|
||||
parameter.
|
||||
.El
|
||||
.Pp
|
||||
The following parameters are specific to GRE tunnel interfaces,
|
||||
.Xr gre 4 :
|
||||
.Bl -tag -width indent
|
||||
.It Cm grekey Ar key
|
||||
Configure the GRE key to be used for outgoing packets.
|
||||
Note that
|
||||
.Xr gre 4 will always accept GRE packets with invalid or absent keys.
|
||||
This command will result in a four byte MTU reduction on the interface.
|
||||
.El
|
||||
.Pp
|
||||
The following parameters are specific to
|
||||
.Xr pfsync 4
|
||||
interfaces:
|
||||
|
@ -51,6 +51,7 @@ static const char rcsid[] =
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_gre.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
@ -748,6 +749,18 @@ setifmtu(const char *val, int dummy __unused, int s,
|
||||
warn("ioctl (set mtu)");
|
||||
}
|
||||
|
||||
static void
|
||||
setifgrekey(const char *val, int dummy __unused, int s,
|
||||
const struct afswtch *afp)
|
||||
{
|
||||
uint32_t grekey = atol(val);
|
||||
|
||||
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
|
||||
ifr.ifr_data = (caddr_t)&grekey;
|
||||
if (ioctl(s, GRESKEY, (caddr_t)&ifr) < 0)
|
||||
warn("ioctl (set grekey)");
|
||||
}
|
||||
|
||||
static void
|
||||
setifname(const char *val, int dummy __unused, int s,
|
||||
const struct afswtch *afp)
|
||||
@ -863,6 +876,12 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
|
||||
if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0)
|
||||
printf("%s", ifs.ascii);
|
||||
|
||||
int grekey = 0;
|
||||
ifr.ifr_data = (caddr_t)&grekey;
|
||||
if (ioctl(s, GREGKEY, &ifr) == 0)
|
||||
if (grekey != 0)
|
||||
printf("\tgrekey: %d\n", grekey);
|
||||
|
||||
close(s);
|
||||
return;
|
||||
}
|
||||
@ -1034,6 +1053,7 @@ static struct cmd basic_cmds[] = {
|
||||
DEF_CMD("noicmp", IFF_LINK1, setifflags),
|
||||
DEF_CMD_ARG("mtu", setifmtu),
|
||||
DEF_CMD_ARG("name", setifname),
|
||||
DEF_CMD_ARG("grekey", setifgrekey),
|
||||
};
|
||||
|
||||
static __constructor void
|
||||
|
@ -36,7 +36,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 9, 2002
|
||||
.Dd June 20, 2008
|
||||
.Dt GRE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -167,6 +167,12 @@ internal route search for the remote tunnel endpoint, see the
|
||||
section below.
|
||||
.It Dv GREGPROTO
|
||||
Query operation mode.
|
||||
.It Dv GRESKEY
|
||||
Set the GRE key used for outgoing packets.
|
||||
A value of 0 disables the key option.
|
||||
.It Dv GREGKEY
|
||||
Get the GRE key currently used for outgoing packets.
|
||||
0 means no outgoing key.
|
||||
.El
|
||||
.Pp
|
||||
Note that the IP addresses of the tunnel endpoints may be the same as the
|
||||
@ -264,6 +270,7 @@ section below) may (and probably should) be set.
|
||||
The MTU of
|
||||
.Nm
|
||||
interfaces is set to 1476 by default, to match the value used by Cisco routers.
|
||||
If grekey is set this is lowered to 1472.
|
||||
This may not be an optimal value, depending on the link between the two tunnel
|
||||
endpoints.
|
||||
It can be adjusted via
|
||||
@ -332,4 +339,9 @@ over the
|
||||
.Nm
|
||||
interface itself.
|
||||
.Pp
|
||||
The GRE RFCs are not yet fully implemented (no GRE options).
|
||||
The current implementation uses the key only for outgoing packets.
|
||||
Incomming packets with a different key or without a key will be treated as if they
|
||||
would belong to this interface.
|
||||
.Pp
|
||||
RFC1701 is not fully supported, however all unsupported features have been
|
||||
deprecated in RFC2784.
|
||||
|
@ -204,6 +204,7 @@ gre_clone_create(ifc, unit, params)
|
||||
sc->called = 0;
|
||||
sc->gre_fibnum = curthread->td_proc->p_fibnum;
|
||||
sc->wccp_ver = WCCP_V1;
|
||||
sc->key = 0;
|
||||
if_attach(GRE2IFP(sc));
|
||||
bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
|
||||
mtx_lock(&gre_mtx);
|
||||
@ -383,7 +384,12 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
error = EAFNOSUPPORT;
|
||||
goto end;
|
||||
}
|
||||
M_PREPEND(m, sizeof(struct greip), M_DONTWAIT);
|
||||
|
||||
/* Reserve space for GRE header + optional GRE key */
|
||||
int hdrlen = sizeof(struct greip);
|
||||
if (sc->key)
|
||||
hdrlen += sizeof(uint32_t);
|
||||
M_PREPEND(m, hdrlen, M_DONTWAIT);
|
||||
} else {
|
||||
_IF_DROP(&ifp->if_snd);
|
||||
m_freem(m);
|
||||
@ -401,9 +407,18 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
|
||||
gh = mtod(m, struct greip *);
|
||||
if (sc->g_proto == IPPROTO_GRE) {
|
||||
/* we don't have any GRE flags for now */
|
||||
uint32_t *options = gh->gi_options;
|
||||
|
||||
memset((void *)gh, 0, sizeof(struct greip));
|
||||
gh->gi_ptype = htons(etype);
|
||||
gh->gi_flags = 0;
|
||||
|
||||
/* Add key option */
|
||||
if (sc->key)
|
||||
{
|
||||
gh->gi_flags |= htons(GRE_KP);
|
||||
*(options++) = htonl(sc->key);
|
||||
}
|
||||
}
|
||||
|
||||
gh->gi_pr = sc->g_proto;
|
||||
@ -444,10 +459,12 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
int s;
|
||||
struct sockaddr_in si;
|
||||
struct sockaddr *sa = NULL;
|
||||
int error;
|
||||
int error, adj;
|
||||
struct sockaddr_in sp, sm, dp, dm;
|
||||
uint32_t key;
|
||||
|
||||
error = 0;
|
||||
adj = 0;
|
||||
|
||||
s = splnet();
|
||||
switch (cmd) {
|
||||
@ -722,6 +739,30 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
si.sin_addr.s_addr = sc->g_dst.s_addr;
|
||||
bcopy(&si, &ifr->ifr_addr, sizeof(ifr->ifr_addr));
|
||||
break;
|
||||
case GRESKEY:
|
||||
error = priv_check(curthread, PRIV_NET_GRE);
|
||||
if (error)
|
||||
break;
|
||||
error = copyin(ifr->ifr_data, &key, sizeof(key));
|
||||
if (error)
|
||||
break;
|
||||
/* adjust MTU for option header */
|
||||
if (key == 0 && sc->key != 0) /* clear */
|
||||
adj += sizeof(key);
|
||||
else if (key != 0 && sc->key == 0) /* set */
|
||||
adj -= sizeof(key);
|
||||
|
||||
if (ifp->if_mtu + adj < 576) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ifp->if_mtu += adj;
|
||||
sc->key = key;
|
||||
break;
|
||||
case GREGKEY:
|
||||
error = copyout(&sc->key, ifr->ifr_data, sizeof(sc->key));
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -70,6 +70,9 @@ struct gre_softc {
|
||||
|
||||
int called; /* infinite recursion preventer */
|
||||
|
||||
uint32_t key; /* key included in outgoing GRE packets */
|
||||
/* zero means none */
|
||||
|
||||
wccp_ver_t wccp_ver; /* version of the WCCP */
|
||||
};
|
||||
#define GRE2IFP(sc) ((sc)->sc_ifp)
|
||||
@ -79,6 +82,7 @@ struct gre_h {
|
||||
u_int16_t flags; /* GRE flags */
|
||||
u_int16_t ptype; /* protocol type of payload typically
|
||||
Ether protocol type*/
|
||||
uint32_t options[0]; /* optional options */
|
||||
/*
|
||||
* from here on: fields are optional, presence indicated by flags
|
||||
*
|
||||
@ -111,6 +115,7 @@ struct greip {
|
||||
#define gi_dst gi_i.ip_dst
|
||||
#define gi_ptype gi_g.ptype
|
||||
#define gi_flags gi_g.flags
|
||||
#define gi_options gi_g.options
|
||||
|
||||
#define GRE_CP 0x8000 /* Checksum Present */
|
||||
#define GRE_RP 0x4000 /* Routing Present */
|
||||
@ -175,6 +180,8 @@ struct mobip_h {
|
||||
#define GREGADDRD _IOWR('i', 104, struct ifreq)
|
||||
#define GRESPROTO _IOW('i' , 105, struct ifreq)
|
||||
#define GREGPROTO _IOWR('i', 106, struct ifreq)
|
||||
#define GREGKEY _IOWR('i', 107, struct ifreq)
|
||||
#define GRESKEY _IOW('i', 108, struct ifreq)
|
||||
|
||||
#ifdef _KERNEL
|
||||
LIST_HEAD(gre_softc_head, gre_softc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user