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:
parent
31997bf223
commit
8f86751705
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146986
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user