Messages in this thread Patch in this message | | | Date | Fri, 11 Mar 2005 17:20:22 +0300 | From | Leo Yuriev <> | Subject | [PATCH] updated, ethernet-bridge: update skb->priority in case forwarded frame has VLAN-header |
| |
Kernel 2.6 (2.6.11)
When ethernet-bridge forward a packet and such ethernet-frame has VLAN-tag, bridge should update skb->prioriry for properly QoS handling. This small patch does this.
Based upon discussion during last week I added pskb_may_pull() checking and simple mapping from 802.1p/user_priority to skb->priority.
Patch-by: Leo Yuriev <leo@yuriev.ru>
-- Best regards, Leo mailto:leo@yuriev.ru
-----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6
mQCPA0HMImkBbQEEALnWXpnchl1dHaCfwnXe2RO8ft9e7K5IGRW1lE9RERMy6R3L JnMXMPiuWm/4tx6H/yTRUML8LbuACzf2Np9oHTxbDWxP40wGxQKrPDlzv/9gLEp6 ZwGF8mSfvZrPHux1LwIbryQxjlmwfNCkE+qiVOBWMsD7yAFCWrZztbWTWJ6pABEB AAG0GkxlbyBZdXJpZXYgPGxlb0B5dXJpZXYucnU+iQCVAwUQQcwiabZztbWTWJ6p AQG6cAP9H0O+MMa0WDlGE2JGG+SWuu9Iuqg76Hp6tjtrz2pLWEzbq8oqCkE0THff /YUUaKqnrLELwEaptE+MrWSv9Zt1K/PauMpKUWXhlYqGcGB2NqJL69AONQte0M4B rPSSts4CU7gK2Zuds1DOLiON7e9Sbpjc5T+4D7Jw5XGKMz66nhY= =qGIk -----END PGP PUBLIC KEY BLOCK-----
--- net/bridge/br_input.c.orig 2005-03-02 10:37:50.000000000 +0300 +++ net/bridge/br_input.c 2005-03-11 16:28:02.000000000 +0300 @@ -5,6 +5,10 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * + * Changes: + * 11/Mar/2005 - LY (Leo Yuriev <leo@yuriev.ru>) + * Update skb->priority for packets with VLAN-tag. + * * $Id: br_input.c,v 1.10 2001/12/24 04:50:20 davem Exp $ * * This program is free software; you can redistribute it and/or @@ -17,6 +21,10 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/netfilter_bridge.h> +#ifdef CONFIG_NET_SCHED +# include <linux/pkt_sched.h> +# include <linux/if_vlan.h> +#endif /* CONFIG_NET_SCHED*/ #include "br_private.h" const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; @@ -45,6 +53,75 @@ static void br_pass_frame_up(struct net_ br_pass_frame_up_finish); } + +#ifdef CONFIG_NET_SCHED +/* + * LY (Leo Yuriev): + * Just update skb->priority for properly QoS handling in case + * frame in the skb is contain VLAN-header. + * + * SANITY NOTE: + * We are referencing to the VLAN_HDR frields, which MAY be + * stored UNALIGNED in the memory. + * According to Dave Miller & Alexey, it will always be aligned, + * so there doesn't need to be any of the unaligned stuff. + * + */ +static __inline__ void br_update_skb_priority_if_vlan(struct sk_buff *skb) +{ + /* + * MAC-Layer Prioritization (802.1p as part of 802.1D-1998) + * - priority 0: + * Noncritical traffic such as backups, noncritical + * replications, some electronic mail, and so on; + * - priority 1: + * The default mode if none is specified; + * - priority 2: + * Best-effort traffic; + * - priority 3: + * Better than best effort, which would include important + * business traffic that can tolerate some delay; + * - priority 4: + * Controlled load, latency-sensitive traffic + * such as SNA transactions; + * - priority 5: + * Video, which is high bandwidth and sensitive to jitter; + * - priority 6: + * Voice traffic, such as NetMeeting, that is especially + * sensitive to jitter; + * - priority 7: + * Network control traffic + * such as router configuration messages; + */ + static const __u8 mac_userprio2prio[8] = { + TC_PRIO_FILLER, /* prio 0 => band 2 */ + TC_PRIO_BULK, /* prio 1 => band 2 */ + TC_PRIO_BESTEFFORT, /* prio 2 => band 1 */ + TC_PRIO_BESTEFFORT, /* prio 3 => band 1 */ + TC_PRIO_INTERACTIVE_BULK, /* prio 4 => band 1 */ + TC_PRIO_INTERACTIVE_BULK, /* prio 5 => band 1 */ + TC_PRIO_INTERACTIVE, /* prio 6 => band 0 */ + TC_PRIO_CONTROL, /* prio 7 => band 0 */ + }; + unsigned short vlan_TCI; + struct vlan_hdr *vhdr; + + if (__constant_htons(ETH_P_8021Q) == skb->protocol && pskb_may_pull(skb, VLAN_HLEN)) { + vhdr = (struct vlan_hdr *)(skb->data); + /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */ + vlan_TCI = ntohs(vhdr->h_vlan_TCI); +#ifdef VLAN_DEBUG + printk(VLAN_DBG "%s: skb: %p vlan_id: %hx\n", + __FUNCTION__, skb, (vlan_TCI & VLAN_VID_MASK)); +#endif + /* LY: whether we can assume here vlan_TCI <= 65535 always ? + * I think yes, then "& 7" is needless after shifting. + */ + skb->priority = mac_userprio2prio[vlan_TCI >> 13]; + } +} +#endif /* CONFIG_NET_SCHED */ + /* note: already called with rcu_read_lock (preempt_disabled) */ int br_handle_frame_finish(struct sk_buff *skb) { @@ -54,6 +131,10 @@ int br_handle_frame_finish(struct sk_buf struct net_bridge_fdb_entry *dst; int passedup = 0; +#ifdef CONFIG_NET_SCHED + br_update_skb_priority_if_vlan(skb); +#endif /* CONFIG_NET_SCHED*/ + if (br->dev->flags & IFF_PROMISC) { struct sk_buff *skb2; [unhandled content-type:application/octet-stream][unhandled content-type:application/pgp-signature] | |