Add hooks into the networking layer to support if_bridge. This changes struct

ifnet so a buildworld is necessary.

Approved by:	mlaier (mentor)
Obtained from:	NetBSD
This commit is contained in:
Andrew Thompson 2005-06-05 03:13:13 +00:00
parent 31997bf223
commit 8f86751705
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146986
8 changed files with 80 additions and 4 deletions

View File

@ -93,6 +93,7 @@ SYSCTL_INT(_net_link, OID_AUTO, log_link_state_change, CTLFLAG_RW,
&log_link_state_change, 0,
"log interface link state change events");
void (*bstp_linkstate_p)(struct ifnet *ifp, int state);
void (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
@ -337,6 +338,7 @@ if_findindex(struct ifnet *ifp)
case IFT_XETHER:
case IFT_ISO88025:
case IFT_L2VLAN:
case IFT_BRIDGE:
snprintf(eaddr, 18, "%6D", IFP2AC(ifp)->ac_enaddr, ":");
break;
default:
@ -1049,6 +1051,11 @@ do_link_state_change(void *arg, int pending)
if (ifp->if_carp)
carp_carpdev_state(ifp->if_carp);
#endif
if (ifp->if_bridge) {
KASSERT(bstp_linkstate_p != NULL,("if_bridge bstp not loaded!"));
(*bstp_linkstate_p)(ifp, link_state);
}
if (pending > 1)
if_printf(ifp, "%d link states coalesced\n", pending);
if (log_link_state_change)
@ -1932,6 +1939,7 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
case IFT_XETHER:
case IFT_ISO88025:
case IFT_L2VLAN:
case IFT_BRIDGE:
bcopy(lladdr, IFP2AC(ifp)->ac_enaddr, len);
/*
* XXX We also need to store the lladdr in LLADDR(sdl),

View File

@ -281,6 +281,13 @@ struct ifmediareq {
int *ifm_ulist; /* media words */
};
struct ifdrv {
char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */
unsigned long ifd_cmd;
size_t ifd_len;
void *ifd_data;
};
/*
* Structure used to retrieve aux status data from interfaces.
* Kernel suppliers to this interface should respect the formatting

View File

@ -114,6 +114,10 @@ bdg_forward_t *bdg_forward_ptr;
bdgtakeifaces_t *bdgtakeifaces_ptr;
struct bdg_softc *ifp2sc;
struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
int (*bridge_output_p)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *);
static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@ -283,6 +287,15 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
(void)memcpy(eh->ether_shost, IFP2AC(ifp)->ac_enaddr,
sizeof(eh->ether_shost));
/*
* Bridges require special output handling.
*/
if (ifp->if_bridge) {
KASSERT(bridge_output_p != NULL,
("ether_input: if_bridge not loaded!"));
return ((*bridge_output_p)(ifp, m, NULL, NULL));
}
/*
* If a simplex interface, and the packet is being sent to our
* Ethernet address or a broadcast address, loopback a copy.
@ -577,6 +590,41 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
return;
}
/*
* Tap the packet off here for a bridge. bridge_input()
* will return NULL if it has consumed the packet, otherwise
* it gets processed as normal. Note that bridge_input()
* will always return the original packet if we need to
* process it locally.
*/
if (ifp->if_bridge) {
KASSERT(bridge_input_p != NULL,
("ether_input: if_bridge not loaded!"));
/* Mark the packet as broadcast or multicast. This is also set
* further down the code in ether_demux() but since the bridge
* input routine rarely returns a mbuf for further processing,
* it is an acceptable duplication.
*/
if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
if (bcmp(etherbroadcastaddr, eh->ether_dhost,
sizeof(etherbroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
}
m = (*bridge_input_p)(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;
}
/* Check for bridging mode */
if (BDG_ACTIVE(ifp) )
if ((m = bridge_in_ptr(ifp, m)) == NULL)

View File

@ -149,6 +149,7 @@ struct frmrinfo {
/*
* ISO PDTR 10178 contains among others
*/
#define LLC_8021D_LSAP 0x42
#define LLC_X25_LSAP 0x7e
#define LLC_SNAP_LSAP 0xaa
#define LLC_ISO_LSAP 0xfe

View File

@ -238,6 +238,7 @@
#define IFT_ATMVCIENDPT 0xc2 /* ATM VCI End Point */
#define IFT_OPTICALCHANNEL 0xc3 /* Optical Channel */
#define IFT_OPTICALTRANSPORT 0xc4 /* Optical Transport */
#define IFT_BRIDGE 0xd1 /* Transparent bridge interface */
#define IFT_STF 0xd7 /* 6to4 interface */

View File

@ -184,6 +184,8 @@ struct ifnet {
struct ifaltq if_snd; /* output queue (includes altq) */
const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
void *if_bridge; /* bridge glue */
struct lltable *lltables; /* list of L3-L2 resolution tables */
struct label *if_label; /* interface MAC label */

View File

@ -553,10 +553,14 @@ in_arpinput(m)
u_int8_t *enaddr = NULL;
int op, rif_len;
int req_len;
int bridged = 0;
#ifdef DEV_CARP
int carp_match = 0;
#endif
if (do_bridge || ifp->if_bridge)
bridged = 1;
req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) {
log(LOG_ERR, "in_arp: runt packet -- m_pullup failed\n");
@ -578,7 +582,7 @@ in_arpinput(m)
* XXX: This is really ugly!
*/
LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
if ((do_bridge || (ia->ia_ifp == ifp)) &&
if ((bridged || (ia->ia_ifp == ifp)) &&
itaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
goto match;
#ifdef DEV_CARP
@ -591,7 +595,7 @@ in_arpinput(m)
#endif
}
LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
if ((do_bridge || (ia->ia_ifp == ifp)) &&
if ((bridged || (ia->ia_ifp == ifp)) &&
isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
goto match;
/*
@ -606,7 +610,7 @@ in_arpinput(m)
/*
* If bridging, fall back to using any inet address.
*/
if (!do_bridge || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL)
if (!bridged || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL)
goto drop;
match:
if (!enaddr)
@ -639,7 +643,7 @@ in_arpinput(m)
la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
/* the following is not an error when doing bridging */
if (!do_bridge && rt->rt_ifp != ifp
if (!bridged && rt->rt_ifp != ifp
#ifdef DEV_CARP
&& (ifp->if_type != IFT_CARP || !carp_match)
#endif

View File

@ -105,6 +105,11 @@
#define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) /* device private 0 */
#define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) /* device private 1 */
#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific
parameters */
#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific
parameters */
#define SIOCIFCREATE _IOWR('i', 122, struct ifreq) /* create clone if */
#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */
#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */