Thread (3 messages) flat view 3 messages, 3 authors, 2005-03-11
STALE7815d

[PATCH] updated, ethernet-bridge: update skb->priority in case forwarded frame has VLAN-header

From: Leo Yuriev <hidden>
Date: 2005-03-11 14:31:15
Also in: lkml

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 [off-list ref]

--
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;
 

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help