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