aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wunderlich <simon@open-mesh.com>2013-07-29 11:56:44 -0400
committerAntonio Quartulli <ordex@autistici.org>2013-08-28 05:31:50 -0400
commitc54f38c9aa22ff65ca9f4c1bdbf2a11d017205f3 (patch)
treee12190c69088c2fee771a49e94c5ab6619ec3817
parent5b2941b18dc5f60a5c14a5c15693f9c58b0dd922 (diff)
batman-adv: set skb priority according to content
The skb priority field may help the wireless driver to choose the right queue (e.g. WMM queues). This should be set in batman-adv, as this information is only available here. This patch adds support for IPv4/IPv6 DS fields and VLAN PCP. Note that only VLAN PCP is used if a VLAN header is present. Also initially set TC_PRIO_CONTROL only for self-generated packets, and keep the priority set by higher layers. Signed-off-by: Simon Wunderlich <simon@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
-rw-r--r--net/batman-adv/bat_iv_ogm.c1
-rw-r--r--net/batman-adv/icmp_socket.c1
-rw-r--r--net/batman-adv/main.c58
-rw-r--r--net/batman-adv/main.h1
-rw-r--r--net/batman-adv/routing.c20
-rw-r--r--net/batman-adv/send.c1
-rw-r--r--net/batman-adv/soft-interface.c2
-rw-r--r--net/batman-adv/translation-table.c5
-rw-r--r--net/batman-adv/unicast.c2
-rw-r--r--net/batman-adv/vis.c2
10 files changed, 91 insertions, 2 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 62da5278014a..9886a2f804fc 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -478,6 +478,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
478 kfree(forw_packet_aggr); 478 kfree(forw_packet_aggr);
479 goto out; 479 goto out;
480 } 480 }
481 forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
481 skb_reserve(forw_packet_aggr->skb, ETH_HLEN); 482 skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
482 483
483 skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 484 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index b27508b8085c..5a99bb4b6b82 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -183,6 +183,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
183 goto out; 183 goto out;
184 } 184 }
185 185
186 skb->priority = TC_PRIO_CONTROL;
186 skb_reserve(skb, ETH_HLEN); 187 skb_reserve(skb, ETH_HLEN);
187 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); 188 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
188 189
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 08125f3f6064..c72d1bcdcf49 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -19,6 +19,10 @@
19 19
20#include <linux/crc32c.h> 20#include <linux/crc32c.h>
21#include <linux/highmem.h> 21#include <linux/highmem.h>
22#include <linux/if_vlan.h>
23#include <net/ip.h>
24#include <net/ipv6.h>
25#include <net/dsfield.h>
22#include "main.h" 26#include "main.h"
23#include "sysfs.h" 27#include "sysfs.h"
24#include "debugfs.h" 28#include "debugfs.h"
@@ -249,6 +253,60 @@ out:
249 return primary_if; 253 return primary_if;
250} 254}
251 255
256/**
257 * batadv_skb_set_priority - sets skb priority according to packet content
258 * @skb: the packet to be sent
259 * @offset: offset to the packet content
260 *
261 * This function sets a value between 256 and 263 (802.1d priority), which
262 * can be interpreted by the cfg80211 or other drivers.
263 */
264void batadv_skb_set_priority(struct sk_buff *skb, int offset)
265{
266 struct iphdr ip_hdr_tmp, *ip_hdr;
267 struct ipv6hdr ip6_hdr_tmp, *ip6_hdr;
268 struct ethhdr ethhdr_tmp, *ethhdr;
269 struct vlan_ethhdr *vhdr, vhdr_tmp;
270 u32 prio;
271
272 /* already set, do nothing */
273 if (skb->priority >= 256 && skb->priority <= 263)
274 return;
275
276 ethhdr = skb_header_pointer(skb, offset, sizeof(*ethhdr), &ethhdr_tmp);
277 if (!ethhdr)
278 return;
279
280 switch (ethhdr->h_proto) {
281 case htons(ETH_P_8021Q):
282 vhdr = skb_header_pointer(skb, offset + sizeof(*vhdr),
283 sizeof(*vhdr), &vhdr_tmp);
284 if (!vhdr)
285 return;
286 prio = ntohs(vhdr->h_vlan_TCI) & VLAN_PRIO_MASK;
287 prio = prio >> VLAN_PRIO_SHIFT;
288 break;
289 case htons(ETH_P_IP):
290 ip_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
291 sizeof(*ip_hdr), &ip_hdr_tmp);
292 if (!ip_hdr)
293 return;
294 prio = (ipv4_get_dsfield(ip_hdr) & 0xfc) >> 5;
295 break;
296 case htons(ETH_P_IPV6):
297 ip6_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
298 sizeof(*ip6_hdr), &ip6_hdr_tmp);
299 if (!ip6_hdr)
300 return;
301 prio = (ipv6_get_dsfield(ip6_hdr) & 0xfc) >> 5;
302 break;
303 default:
304 return;
305 }
306
307 skb->priority = prio + 256;
308}
309
252static int batadv_recv_unhandled_packet(struct sk_buff *skb, 310static int batadv_recv_unhandled_packet(struct sk_buff *skb,
253 struct batadv_hard_iface *recv_if) 311 struct batadv_hard_iface *recv_if)
254{ 312{
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 5e9aebb7d56b..a7bca78a6251 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -184,6 +184,7 @@ void batadv_mesh_free(struct net_device *soft_iface);
184int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); 184int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
185struct batadv_hard_iface * 185struct batadv_hard_iface *
186batadv_seq_print_text_primary_if_get(struct seq_file *seq); 186batadv_seq_print_text_primary_if_get(struct seq_file *seq);
187void batadv_skb_set_priority(struct sk_buff *skb, int offset);
187int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, 188int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
188 struct packet_type *ptype, 189 struct packet_type *ptype,
189 struct net_device *orig_dev); 190 struct net_device *orig_dev);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 2f0bd3ffe6e8..0439395d7ba5 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -775,7 +775,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
775 struct batadv_neigh_node *neigh_node = NULL; 775 struct batadv_neigh_node *neigh_node = NULL;
776 struct batadv_unicast_packet *unicast_packet; 776 struct batadv_unicast_packet *unicast_packet;
777 struct ethhdr *ethhdr = eth_hdr(skb); 777 struct ethhdr *ethhdr = eth_hdr(skb);
778 int res, ret = NET_RX_DROP; 778 int res, hdr_len, ret = NET_RX_DROP;
779 struct sk_buff *new_skb; 779 struct sk_buff *new_skb;
780 780
781 unicast_packet = (struct batadv_unicast_packet *)skb->data; 781 unicast_packet = (struct batadv_unicast_packet *)skb->data;
@@ -835,6 +835,22 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
835 /* decrement ttl */ 835 /* decrement ttl */
836 unicast_packet->header.ttl--; 836 unicast_packet->header.ttl--;
837 837
838 switch (unicast_packet->header.packet_type) {
839 case BATADV_UNICAST_4ADDR:
840 hdr_len = sizeof(struct batadv_unicast_4addr_packet);
841 break;
842 case BATADV_UNICAST:
843 hdr_len = sizeof(struct batadv_unicast_packet);
844 break;
845 default:
846 /* other packet types not supported - yet */
847 hdr_len = -1;
848 break;
849 }
850
851 if (hdr_len > 0)
852 batadv_skb_set_priority(skb, hdr_len);
853
838 res = batadv_send_skb_to_orig(skb, orig_node, recv_if); 854 res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
839 855
840 /* translate transmit result into receive result */ 856 /* translate transmit result into receive result */
@@ -1193,6 +1209,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
1193 if (batadv_bla_check_bcast_duplist(bat_priv, skb)) 1209 if (batadv_bla_check_bcast_duplist(bat_priv, skb))
1194 goto out; 1210 goto out;
1195 1211
1212 batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet));
1213
1196 /* rebroadcast packet */ 1214 /* rebroadcast packet */
1197 batadv_add_bcast_packet_to_list(bat_priv, skb, 1); 1215 batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
1198 1216
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index e9ff8d801201..0266edd0fa7f 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -67,7 +67,6 @@ int batadv_send_skb_packet(struct sk_buff *skb,
67 ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); 67 ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
68 68
69 skb_set_network_header(skb, ETH_HLEN); 69 skb_set_network_header(skb, ETH_HLEN);
70 skb->priority = TC_PRIO_CONTROL;
71 skb->protocol = __constant_htons(ETH_P_BATMAN); 70 skb->protocol = __constant_htons(ETH_P_BATMAN);
72 71
73 skb->dev = hard_iface->net_dev; 72 skb->dev = hard_iface->net_dev;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 0f04e1c302b4..4493913f0d5c 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -229,6 +229,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
229 */ 229 */
230 } 230 }
231 231
232 batadv_skb_set_priority(skb, 0);
233
232 /* ethernet packet should be broadcasted */ 234 /* ethernet packet should be broadcasted */
233 if (do_bcast) { 235 if (do_bcast) {
234 primary_if = batadv_primary_if_get_selected(bat_priv); 236 primary_if = batadv_primary_if_get_selected(bat_priv);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 429aeef3d8b2..34510f38708f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1626,6 +1626,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1626 if (!skb) 1626 if (!skb)
1627 goto out; 1627 goto out;
1628 1628
1629 skb->priority = TC_PRIO_CONTROL;
1629 skb_reserve(skb, ETH_HLEN); 1630 skb_reserve(skb, ETH_HLEN);
1630 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); 1631 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
1631 tt_response->ttvn = ttvn; 1632 tt_response->ttvn = ttvn;
@@ -1691,6 +1692,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
1691 if (!skb) 1692 if (!skb)
1692 goto out; 1693 goto out;
1693 1694
1695 skb->priority = TC_PRIO_CONTROL;
1694 skb_reserve(skb, ETH_HLEN); 1696 skb_reserve(skb, ETH_HLEN);
1695 1697
1696 tt_req_len = sizeof(*tt_request); 1698 tt_req_len = sizeof(*tt_request);
@@ -1788,6 +1790,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1788 if (!skb) 1790 if (!skb)
1789 goto unlock; 1791 goto unlock;
1790 1792
1793 skb->priority = TC_PRIO_CONTROL;
1791 skb_reserve(skb, ETH_HLEN); 1794 skb_reserve(skb, ETH_HLEN);
1792 packet_pos = skb_put(skb, len); 1795 packet_pos = skb_put(skb, len);
1793 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1796 tt_response = (struct batadv_tt_query_packet *)packet_pos;
@@ -1906,6 +1909,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1906 if (!skb) 1909 if (!skb)
1907 goto unlock; 1910 goto unlock;
1908 1911
1912 skb->priority = TC_PRIO_CONTROL;
1909 skb_reserve(skb, ETH_HLEN); 1913 skb_reserve(skb, ETH_HLEN);
1910 packet_pos = skb_put(skb, len); 1914 packet_pos = skb_put(skb, len);
1911 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1915 tt_response = (struct batadv_tt_query_packet *)packet_pos;
@@ -2240,6 +2244,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2240 if (!skb) 2244 if (!skb)
2241 goto out; 2245 goto out;
2242 2246
2247 skb->priority = TC_PRIO_CONTROL;
2243 skb_reserve(skb, ETH_HLEN); 2248 skb_reserve(skb, ETH_HLEN);
2244 2249
2245 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); 2250 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 857e1b8349ee..48b31d33ce6b 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -242,6 +242,8 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
242 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); 242 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
243 if (!frag_skb) 243 if (!frag_skb)
244 goto dropped; 244 goto dropped;
245
246 skb->priority = TC_PRIO_CONTROL;
245 skb_reserve(frag_skb, ucf_hdr_len); 247 skb_reserve(frag_skb, ucf_hdr_len);
246 248
247 unicast_packet = (struct batadv_unicast_packet *)skb->data; 249 unicast_packet = (struct batadv_unicast_packet *)skb->data;
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 4983340f1943..d8ea31a58457 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -397,6 +397,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
397 kfree(info); 397 kfree(info);
398 return NULL; 398 return NULL;
399 } 399 }
400 info->skb_packet->priority = TC_PRIO_CONTROL;
400 skb_reserve(info->skb_packet, ETH_HLEN); 401 skb_reserve(info->skb_packet, ETH_HLEN);
401 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len); 402 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
402 403
@@ -861,6 +862,7 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
861 if (!bat_priv->vis.my_info->skb_packet) 862 if (!bat_priv->vis.my_info->skb_packet)
862 goto free_info; 863 goto free_info;
863 864
865 bat_priv->vis.my_info->skb_packet->priority = TC_PRIO_CONTROL;
864 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN); 866 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
865 tmp_skb = bat_priv->vis.my_info->skb_packet; 867 tmp_skb = bat_priv->vis.my_info->skb_packet;
866 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); 868 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));