diff options
| author | Simon Wunderlich <simon@open-mesh.com> | 2013-07-29 11:56:44 -0400 |
|---|---|---|
| committer | Antonio Quartulli <ordex@autistici.org> | 2013-08-28 05:31:50 -0400 |
| commit | c54f38c9aa22ff65ca9f4c1bdbf2a11d017205f3 (patch) | |
| tree | e12190c69088c2fee771a49e94c5ab6619ec3817 | |
| parent | 5b2941b18dc5f60a5c14a5c15693f9c58b0dd922 (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.c | 1 | ||||
| -rw-r--r-- | net/batman-adv/icmp_socket.c | 1 | ||||
| -rw-r--r-- | net/batman-adv/main.c | 58 | ||||
| -rw-r--r-- | net/batman-adv/main.h | 1 | ||||
| -rw-r--r-- | net/batman-adv/routing.c | 20 | ||||
| -rw-r--r-- | net/batman-adv/send.c | 1 | ||||
| -rw-r--r-- | net/batman-adv/soft-interface.c | 2 | ||||
| -rw-r--r-- | net/batman-adv/translation-table.c | 5 | ||||
| -rw-r--r-- | net/batman-adv/unicast.c | 2 | ||||
| -rw-r--r-- | net/batman-adv/vis.c | 2 |
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 | */ | ||
| 264 | void 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), ðhdr_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 | |||
| 252 | static int batadv_recv_unhandled_packet(struct sk_buff *skb, | 310 | static 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); | |||
| 184 | int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); | 184 | int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); |
| 185 | struct batadv_hard_iface * | 185 | struct batadv_hard_iface * |
| 186 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); | 186 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); |
| 187 | void batadv_skb_set_priority(struct sk_buff *skb, int offset); | ||
| 187 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | 188 | int 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)); |
