Add RFC 3378 EtherIP support, ported from OpenBSD to NetBSD by
Hans Rosenfeld (rosenfeld at grumpf.hope-2000.org) This change makes it possible to add gif interfaces to bridges, which will then send and receive IP protocol 97 packets. Packets are Ethernet frames with an EtherIP header prepended.
This commit is contained in:
parent
36eef77064
commit
c9f56c04dc
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_bridge.c,v 1.27 2004/12/04 18:31:43 peter Exp $ */
|
||||
/* $NetBSD: if_bridge.c,v 1.28 2005/01/31 23:49:36 kim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Wasabi Systems, Inc.
|
||||
@ -80,12 +80,13 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.27 2004/12/04 18:31:43 peter Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.28 2005/01/31 23:49:36 kim Exp $");
|
||||
|
||||
#include "opt_bridge_ipf.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_pfil_hooks.h"
|
||||
#include "bpfilter.h"
|
||||
#include "gif.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -580,7 +581,10 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
|
||||
*/
|
||||
(void) ifpromisc(ifs, 0);
|
||||
break;
|
||||
|
||||
#if NGIF > 0
|
||||
case IFT_GIF:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifdef DIAGNOSTIC
|
||||
panic("bridge_delete_member: impossible");
|
||||
@ -633,7 +637,10 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
||||
if (error)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
#if NGIF > 0
|
||||
case IFT_GIF:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
@ -1157,6 +1164,7 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
|
||||
#endif /* ALTQ */
|
||||
|
||||
len = m->m_pkthdr.len;
|
||||
m->m_flags |= M_PROTO1;
|
||||
mflags = m->m_flags;
|
||||
IFQ_ENQUEUE(&dst_ifp->if_snd, m, &pktattr, error);
|
||||
if (error) {
|
||||
@ -1480,6 +1488,20 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
|
||||
return (m);
|
||||
|
||||
/* Perform the bridge forwarding function with the copy. */
|
||||
#if NGIF > 0
|
||||
if (ifp->if_type == IFT_GIF) {
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
if (bif->bif_ifp->if_type == IFT_ETHER)
|
||||
break;
|
||||
}
|
||||
if (bif != NULL) {
|
||||
m->m_flags |= M_PROTO1;
|
||||
m->m_pkthdr.rcvif = bif->bif_ifp;
|
||||
(*bif->bif_ifp->if_input)(bif->bif_ifp, m);
|
||||
m = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bridge_forward(sc, mc);
|
||||
|
||||
/* Return the original packet for local processing. */
|
||||
@ -1499,6 +1521,8 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
|
||||
* Unicast. Make sure it's not for us.
|
||||
*/
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
if(bif->bif_ifp->if_type != IFT_ETHER)
|
||||
continue;
|
||||
/* It is destined for us. */
|
||||
if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost,
|
||||
ETHER_ADDR_LEN) == 0) {
|
||||
@ -1506,6 +1530,14 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
|
||||
(void) bridge_rtupdate(sc,
|
||||
eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
|
||||
m->m_pkthdr.rcvif = bif->bif_ifp;
|
||||
#if NGIF > 0
|
||||
if (ifp->if_type == IFT_GIF) {
|
||||
m->m_flags |= M_PROTO1;
|
||||
m->m_pkthdr.rcvif = bif->bif_ifp;
|
||||
(*bif->bif_ifp->if_input)(bif->bif_ifp, m);
|
||||
m = NULL;
|
||||
}
|
||||
#endif
|
||||
return (m);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_ethersubr.c,v 1.118 2005/01/08 03:18:18 yamt Exp $ */
|
||||
/* $NetBSD: if_ethersubr.c,v 1.119 2005/01/31 23:49:36 kim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.118 2005/01/08 03:18:18 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.119 2005/01/31 23:49:36 kim Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_atalk.h"
|
||||
@ -726,18 +726,22 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
|
||||
* process it locally.
|
||||
*/
|
||||
if (ifp->if_bridge) {
|
||||
/* clear M_PROMISC, in case the packets comes from a vlan */
|
||||
m->m_flags &= ~M_PROMISC;
|
||||
m = bridge_input(ifp, m);
|
||||
if (m == NULL)
|
||||
return;
|
||||
if(m->m_flags & M_PROTO1) {
|
||||
m->m_flags &= ~M_PROTO1;
|
||||
} else {
|
||||
/* clear M_PROMISC, in case the packets comes from a vlan */
|
||||
m->m_flags &= ~M_PROMISC;
|
||||
m = bridge_input(ifp, m);
|
||||
if (m == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Bridge has determined that the packet is for us.
|
||||
* Update our interface pointer -- we may have had
|
||||
* to "bridge" the packet locally.
|
||||
*/
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
/*
|
||||
* Bridge has determined that the packet is for us.
|
||||
* Update our interface pointer -- we may have had
|
||||
* to "bridge" the packet locally.
|
||||
*/
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
}
|
||||
} else
|
||||
#endif /* NBRIDGE > 0 */
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_gif.c,v 1.47 2004/12/04 18:31:43 peter Exp $ */
|
||||
/* $NetBSD: if_gif.c,v 1.48 2005/01/31 23:49:36 kim Exp $ */
|
||||
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
|
||||
|
||||
/*
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.47 2004/12/04 18:31:43 peter Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.48 2005/01/31 23:49:36 kim Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_iso.h"
|
||||
@ -82,9 +82,12 @@ __KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.47 2004/12/04 18:31:43 peter Exp $");
|
||||
#endif
|
||||
|
||||
#include <netinet/ip_encap.h>
|
||||
#include <net/if_ether.h>
|
||||
#include <net/if_bridgevar.h>
|
||||
#include <net/if_gif.h>
|
||||
|
||||
#include "bpfilter.h"
|
||||
#include "bridge.h"
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
@ -93,6 +96,7 @@ void gifattach __P((int));
|
||||
void gifnetisr __P((void));
|
||||
#endif
|
||||
void gifintr __P((void *));
|
||||
void gif_start __P((struct ifnet *));
|
||||
#ifdef ISO
|
||||
static struct mbuf *gif_eon_encap __P((struct mbuf *));
|
||||
static struct mbuf *gif_eon_decap __P((struct ifnet *, struct mbuf *));
|
||||
@ -163,6 +167,7 @@ gifattach0(sc)
|
||||
sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
|
||||
sc->gif_if.if_ioctl = gif_ioctl;
|
||||
sc->gif_if.if_output = gif_output;
|
||||
sc->gif_if.if_start = gif_start;
|
||||
sc->gif_if.if_type = IFT_GIF;
|
||||
sc->gif_if.if_dlt = DLT_NULL;
|
||||
IFQ_SET_READY(&sc->gif_if.if_snd);
|
||||
@ -198,6 +203,18 @@ gif_clone_destroy(ifp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
gif_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
|
||||
softintr_schedule(((struct gif_softc*)ifp)->gif_si);
|
||||
#else
|
||||
/* XXX bad spl level? */
|
||||
gifnetisr();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GIF_ENCAPCHECK
|
||||
int
|
||||
gif_encapcheck(m, off, proto, arg)
|
||||
@ -232,6 +249,10 @@ gif_encapcheck(m, off, proto, arg)
|
||||
#ifdef ISO
|
||||
case IPPROTO_EON:
|
||||
break;
|
||||
#endif
|
||||
#if NBRIDGE > 0
|
||||
case IPPROTO_ETHERIP:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@ -391,6 +412,17 @@ gifintr(arg)
|
||||
if (m == NULL)
|
||||
break;
|
||||
|
||||
#if NBRIDGE > 0
|
||||
if(m->m_flags & M_PROTO1) {
|
||||
M_PREPEND(m, sizeof(int), M_DONTWAIT);
|
||||
if (!m) {
|
||||
ifp->if_oerrors++;
|
||||
continue;
|
||||
}
|
||||
*mtod(m, int *) = AF_LINK;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* grab and chop off inner af type */
|
||||
if (sizeof(int) > m->m_len) {
|
||||
m = m_pullup(m, sizeof(int));
|
||||
@ -443,6 +475,7 @@ gif_input(m, af, ifp)
|
||||
{
|
||||
int s, isr;
|
||||
struct ifqueue *ifq = NULL;
|
||||
struct ether_header *eh;
|
||||
|
||||
if (ifp == NULL) {
|
||||
/* just in case */
|
||||
@ -489,6 +522,37 @@ gif_input(m, af, ifp)
|
||||
ifq = &clnlintrq;
|
||||
isr = NETISR_ISO;
|
||||
break;
|
||||
#endif
|
||||
#if NBRIDGE > 0
|
||||
case AF_LINK:
|
||||
m_adj(m, sizeof(struct etherip_header));
|
||||
if (sizeof(struct ether_header) > m->m_len) {
|
||||
m = m_pullup(m, sizeof(struct ether_header));
|
||||
if (!m) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_flags &= ~(M_BCAST|M_MCAST);
|
||||
if (eh->ether_dhost[0] & 1) {
|
||||
if (bcmp((caddr_t) etherbroadcastaddr,
|
||||
(caddr_t)eh->ether_dhost, sizeof(etherbroadcastaddr)) == 0)
|
||||
m->m_flags |= M_BCAST;
|
||||
else
|
||||
m->m_flags |= M_MCAST;
|
||||
}
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
if(ifp->if_bridge) {
|
||||
if (m->m_flags & (M_BCAST|M_MCAST))
|
||||
ifp->if_imcasts++;
|
||||
|
||||
s = splnet();
|
||||
m = bridge_input(ifp, m);
|
||||
splx(s);
|
||||
if (m == NULL)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in.h,v 1.69 2004/12/15 04:25:19 thorpej Exp $ */
|
||||
/* $NetBSD: in.h,v 1.70 2005/01/31 23:49:36 kim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
@ -97,6 +97,7 @@ typedef __sa_family_t sa_family_t;
|
||||
#define IPPROTO_NONE 59 /* IP6 no next header */
|
||||
#define IPPROTO_DSTOPTS 60 /* IP6 destination option */
|
||||
#define IPPROTO_EON 80 /* ISO cnlp */
|
||||
#define IPPROTO_ETHERIP 97 /* Ethernet-in-IP */
|
||||
#define IPPROTO_ENCAP 98 /* encapsulation header */
|
||||
#define IPPROTO_PIM 103 /* Protocol indep. multicast */
|
||||
#define IPPROTO_IPCOMP 108 /* IP Payload Comp. Protocol */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_gif.c,v 1.36 2004/04/26 01:31:56 matt Exp $ */
|
||||
/* $NetBSD: in_gif.c,v 1.37 2005/01/31 23:49:36 kim Exp $ */
|
||||
/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.36 2004/04/26 01:31:56 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.37 2005/01/31 23:49:36 kim Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_iso.h"
|
||||
@ -65,6 +65,8 @@ __KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.36 2004/04/26 01:31:56 matt Exp $");
|
||||
#include <net/if_gif.h>
|
||||
|
||||
#include "gif.h"
|
||||
#include "bridge.h"
|
||||
#include <net/if_ether.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
@ -97,6 +99,7 @@ in_gif_output(ifp, family, m)
|
||||
struct sockaddr_in *sin_src = (struct sockaddr_in *)sc->gif_psrc;
|
||||
struct sockaddr_in *sin_dst = (struct sockaddr_in *)sc->gif_pdst;
|
||||
struct ip iphdr; /* capsule IP header, host byte ordered */
|
||||
struct etherip_header eiphdr;
|
||||
int proto, error;
|
||||
u_int8_t tos;
|
||||
|
||||
@ -144,6 +147,20 @@ in_gif_output(ifp, family, m)
|
||||
proto = IPPROTO_EON;
|
||||
tos = 0;
|
||||
break;
|
||||
#endif
|
||||
#if NBRIDGE > 0
|
||||
case AF_LINK:
|
||||
proto = IPPROTO_ETHERIP;
|
||||
eiphdr.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK;
|
||||
eiphdr.eip_pad = 0;
|
||||
/* prepend Ethernet-in-IP header */
|
||||
M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
|
||||
if (m && m->m_len < sizeof(struct etherip_header))
|
||||
m = m_pullup(m, sizeof(struct etherip_header));
|
||||
if (m == NULL)
|
||||
return ENOBUFS;
|
||||
bcopy(&eiphdr, mtod(m, struct etherip_header *), sizeof(struct etherip_header));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
@ -291,6 +308,11 @@ in_gif_input(struct mbuf *m, ...)
|
||||
case IPPROTO_EON:
|
||||
af = AF_ISO;
|
||||
break;
|
||||
#endif
|
||||
#if NBRIDGE > 0
|
||||
case IPPROTO_ETHERIP:
|
||||
af = AF_LINK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ipstat.ips_nogif++;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_gif.h,v 1.10 2004/04/21 17:49:46 itojun Exp $ */
|
||||
/* $NetBSD: in_gif.h,v 1.11 2005/01/31 23:49:36 kim Exp $ */
|
||||
/* $KAME: in_gif.h,v 1.6 2001/07/25 00:55:48 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -46,4 +46,12 @@ int gif_encapcheck4(const struct mbuf *, int, int, void *);
|
||||
int in_gif_attach(struct gif_softc *);
|
||||
int in_gif_detach(struct gif_softc *);
|
||||
|
||||
struct etherip_header {
|
||||
u_int8_t eip_ver; /* version/reserved */
|
||||
u_int8_t eip_pad; /* required padding byte */
|
||||
};
|
||||
#define ETHERIP_VER_VERS_MASK 0x0f
|
||||
#define ETHERIP_VER_RSVD_MASK 0xf0
|
||||
#define ETHERIP_VERSION 0x03
|
||||
|
||||
#endif /*_NETINET_IN_GIF_H_*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_proto.c,v 1.66 2005/01/23 18:41:57 matt Exp $ */
|
||||
/* $NetBSD: in_proto.c,v 1.67 2005/01/31 23:49:36 kim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.66 2005/01/23 18:41:57 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.67 2005/01/31 23:49:36 kim Exp $");
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_eon.h" /* ISO CLNL over IP */
|
||||
@ -146,6 +146,8 @@ __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.66 2005/01/23 18:41:57 matt Exp $");
|
||||
#include <netinet/ip_gre.h>
|
||||
#endif
|
||||
|
||||
#include "bridge.h"
|
||||
|
||||
DOMAIN_DEFINE(inetdomain); /* forward declare and add to link set */
|
||||
|
||||
const struct protosw inetsw[] = {
|
||||
@ -224,6 +226,13 @@ const struct protosw inetsw[] = {
|
||||
encap_init, 0, 0, 0,
|
||||
},
|
||||
#endif /* INET6 */
|
||||
#if NBRIDGE > 0
|
||||
{ SOCK_RAW, &inetdomain, IPPROTO_ETHERIP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
|
||||
encap4_input, rip_output, rip_ctlinput, rip_ctloutput,
|
||||
rip_usrreq,
|
||||
encap_init, 0, 0, 0,
|
||||
},
|
||||
#endif
|
||||
#if NGRE > 0
|
||||
{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
|
||||
gre_input, rip_output, rip_ctlinput, rip_ctloutput,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mbuf.h,v 1.99 2004/09/21 21:57:30 yamt Exp $ */
|
||||
/* $NetBSD: mbuf.h,v 1.100 2005/01/31 23:49:36 kim Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc.
|
||||
@ -272,6 +272,7 @@ MBUF_DEFINE(mbuf, MHLEN, MLEN);
|
||||
#define M_EXT 0x0001 /* has associated external storage */
|
||||
#define M_PKTHDR 0x0002 /* start of record */
|
||||
#define M_EOR 0x0004 /* end of record */
|
||||
#define M_PROTO1 0x0008 /* protocol-specific */
|
||||
|
||||
/* mbuf pkthdr flags, also in m_flags */
|
||||
#define M_AUTHIPHDR 0x0010 /* data origin authentication for IP header */
|
||||
|
Loading…
Reference in New Issue
Block a user