kern/152141: encapsulate vlan in ng_ether before output to if
Rozhuk Ivan
rozhuk.im at gmail.com
Thu Nov 11 17:20:09 UTC 2010
>Number: 152141
>Category: kern
>Synopsis: encapsulate vlan in ng_ether before output to if
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: maintainer-update
>Submitter-Id: current-users
>Arrival-Date: Thu Nov 11 17:20:08 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator: Rozhuk Ivan
>Release: 9.0-CURRENT
>Organization:
>Environment:
FreeBSD firewall 9.0-CURRENT FreeBSD 9.0-CURRENT #9: Sun Oct 31 16:36:54 IRKT 2010 root at firewall:/usr/obj/usr/src/sys/RIMx64 amd64
>Description:
ether_input decapsulate vlan from ethernet header and
add M_VLANTAG flag to mbuff
set m->m_pkthdr.ether_vtag
then packet transmited to ng_ether_input
but(!)
ng_ether_rcv_lower does not encapsulate vlan tag before send packet
if_bridge - encapsulate
>How-To-Repeat:
>Fix:
/*
* Handle an mbuf received on the "lower" or "orphan" hook.
*/
static int
ng_ether_rcv_lower(hook_p hook, item_p item)
{
struct mbuf *m;
const node_p node = NG_HOOK_NODE(hook);
const priv_p priv = NG_NODE_PRIVATE(node);
struct ifnet *const ifp = priv->ifp;
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
/* Check whether interface is ready for packets */
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING))) {
NG_FREE_M(m);
return (ENETDOWN);
}
/* Make sure header is fully pulled up */
if (m->m_pkthdr.len < sizeof(struct ether_header)) {
NG_FREE_M(m);
return (EINVAL);
}
if (m->m_len < sizeof(struct ether_header)
&& (m = m_pullup(m, sizeof(struct ether_header))) == NULL)
return (ENOBUFS);
/* Drop in the MAC address if desired */
if (priv->autoSrcAddr) {
/* Make the mbuf writable if it's not already */
if (!M_WRITABLE(m)
&& (m = m_pullup(m, sizeof(struct ether_header))) == NULL)
return (ENOBUFS);
/* Overwrite source MAC address */
bcopy(IF_LLADDR(ifp),
mtod(m, struct ether_header *)->ether_shost,
ETHER_ADDR_LEN);
}
/*
* If underlying interface can not do VLAN tag insertion itself
* then attach a packet tag that holds it.
*/
if ((m->m_flags & M_VLANTAG) &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) {
m = ether_vlanencap(m, m->m_pkthdr.ether_vtag);
if (m == NULL) {
ifp->if_oerrors++;
return (ENOBUFS);
}
m->m_flags &= ~M_VLANTAG;
}
/* Send it on its way */
return ether_output_frame(ifp, m);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list