Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

batman-adv: Add wrapper to look up neighbor and send skb

By adding batadv_send_skb_to_orig() in send.c, we can remove duplicate
code that looks up the next hop and then calls batadv_send_skb_packet().

Furthermore, this prepares the upcoming new implementation of
fragmentation, which requires the next hop to route packets.

Please note that this doesn't entirely remove the next-hop lookup in
routing.c and unicast.c, since it is used by the current fragmentation
code.

Also note that the next-hop info is removed from debug messages in
translation-table.c, since it is looked up elsewhere.

Signed-off-by: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>

authored by

Martin Hundebøll and committed by
Antonio Quartulli
bb351ba0 637fbd12

+74 -107
+8 -29
net/batman-adv/routing.c
··· 285 285 { 286 286 struct batadv_hard_iface *primary_if = NULL; 287 287 struct batadv_orig_node *orig_node = NULL; 288 - struct batadv_neigh_node *router = NULL; 289 288 struct batadv_icmp_packet_rr *icmp_packet; 290 289 int ret = NET_RX_DROP; 291 290 ··· 306 307 if (!orig_node) 307 308 goto out; 308 309 309 - router = batadv_orig_node_get_router(orig_node); 310 - if (!router) 311 - goto out; 312 - 313 310 /* create a copy of the skb, if needed, to modify it. */ 314 311 if (skb_cow(skb, ETH_HLEN) < 0) 315 312 goto out; ··· 317 322 icmp_packet->msg_type = BATADV_ECHO_REPLY; 318 323 icmp_packet->header.ttl = BATADV_TTL; 319 324 320 - batadv_send_skb_packet(skb, router->if_incoming, router->addr); 321 - ret = NET_RX_SUCCESS; 325 + if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 326 + ret = NET_RX_SUCCESS; 322 327 323 328 out: 324 329 if (primary_if) 325 330 batadv_hardif_free_ref(primary_if); 326 - if (router) 327 - batadv_neigh_node_free_ref(router); 328 331 if (orig_node) 329 332 batadv_orig_node_free_ref(orig_node); 330 333 return ret; ··· 333 340 { 334 341 struct batadv_hard_iface *primary_if = NULL; 335 342 struct batadv_orig_node *orig_node = NULL; 336 - struct batadv_neigh_node *router = NULL; 337 343 struct batadv_icmp_packet *icmp_packet; 338 344 int ret = NET_RX_DROP; 339 345 ··· 354 362 if (!orig_node) 355 363 goto out; 356 364 357 - router = batadv_orig_node_get_router(orig_node); 358 - if (!router) 359 - goto out; 360 - 361 365 /* create a copy of the skb, if needed, to modify it. */ 362 366 if (skb_cow(skb, ETH_HLEN) < 0) 363 367 goto out; ··· 365 377 icmp_packet->msg_type = BATADV_TTL_EXCEEDED; 366 378 icmp_packet->header.ttl = BATADV_TTL; 367 379 368 - batadv_send_skb_packet(skb, router->if_incoming, router->addr); 369 - ret = NET_RX_SUCCESS; 380 + if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 381 + ret = NET_RX_SUCCESS; 370 382 371 383 out: 372 384 if (primary_if) 373 385 batadv_hardif_free_ref(primary_if); 374 - if (router) 375 - batadv_neigh_node_free_ref(router); 376 386 if (orig_node) 377 387 batadv_orig_node_free_ref(orig_node); 378 388 return ret; ··· 384 398 struct batadv_icmp_packet_rr *icmp_packet; 385 399 struct ethhdr *ethhdr; 386 400 struct batadv_orig_node *orig_node = NULL; 387 - struct batadv_neigh_node *router = NULL; 388 401 int hdr_size = sizeof(struct batadv_icmp_packet); 389 402 int ret = NET_RX_DROP; 390 403 ··· 432 447 if (!orig_node) 433 448 goto out; 434 449 435 - router = batadv_orig_node_get_router(orig_node); 436 - if (!router) 437 - goto out; 438 - 439 450 /* create a copy of the skb, if needed, to modify it. */ 440 451 if (skb_cow(skb, ETH_HLEN) < 0) 441 452 goto out; ··· 442 461 icmp_packet->header.ttl--; 443 462 444 463 /* route it */ 445 - batadv_send_skb_packet(skb, router->if_incoming, router->addr); 446 - ret = NET_RX_SUCCESS; 464 + if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) 465 + ret = NET_RX_SUCCESS; 447 466 448 467 out: 449 - if (router) 450 - batadv_neigh_node_free_ref(router); 451 468 if (orig_node) 452 469 batadv_orig_node_free_ref(orig_node); 453 470 return ret; ··· 861 882 skb->len + ETH_HLEN); 862 883 863 884 /* route it */ 864 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 865 - ret = NET_RX_SUCCESS; 885 + if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) 886 + ret = NET_RX_SUCCESS; 866 887 867 888 out: 868 889 if (neigh_node)
+33
net/batman-adv/send.c
··· 78 78 return NET_XMIT_DROP; 79 79 } 80 80 81 + /** 82 + * batadv_send_skb_to_orig - Lookup next-hop and transmit skb. 83 + * @skb: Packet to be transmitted. 84 + * @orig_node: Final destination of the packet. 85 + * @recv_if: Interface used when receiving the packet (can be NULL). 86 + * 87 + * Looks up the best next-hop towards the passed originator and passes the 88 + * skb on for preparation of MAC header. If the packet originated from this 89 + * host, NULL can be passed as recv_if and no interface alternating is 90 + * attempted. 91 + * 92 + * Returns TRUE on success; FALSE otherwise. 93 + */ 94 + bool batadv_send_skb_to_orig(struct sk_buff *skb, 95 + struct batadv_orig_node *orig_node, 96 + struct batadv_hard_iface *recv_if) 97 + { 98 + struct batadv_priv *bat_priv = orig_node->bat_priv; 99 + struct batadv_neigh_node *neigh_node; 100 + 101 + /* batadv_find_router() increases neigh_nodes refcount if found. */ 102 + neigh_node = batadv_find_router(bat_priv, orig_node, recv_if); 103 + if (!neigh_node) 104 + return false; 105 + 106 + /* route it */ 107 + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 108 + 109 + batadv_neigh_node_free_ref(neigh_node); 110 + 111 + return true; 112 + } 113 + 81 114 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) 82 115 { 83 116 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+3
net/batman-adv/send.h
··· 23 23 int batadv_send_skb_packet(struct sk_buff *skb, 24 24 struct batadv_hard_iface *hard_iface, 25 25 const uint8_t *dst_addr); 26 + bool batadv_send_skb_to_orig(struct sk_buff *skb, 27 + struct batadv_orig_node *orig_node, 28 + struct batadv_hard_iface *recv_if); 26 29 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface); 27 30 int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, 28 31 const struct sk_buff *skb,
+17 -48
net/batman-adv/translation-table.c
··· 1642 1642 { 1643 1643 struct sk_buff *skb = NULL; 1644 1644 struct batadv_tt_query_packet *tt_request; 1645 - struct batadv_neigh_node *neigh_node = NULL; 1646 1645 struct batadv_hard_iface *primary_if; 1647 1646 struct batadv_tt_req_node *tt_req_node = NULL; 1648 1647 int ret = 1; ··· 1679 1680 if (full_table) 1680 1681 tt_request->flags |= BATADV_TT_FULL_TABLE; 1681 1682 1682 - neigh_node = batadv_orig_node_get_router(dst_orig_node); 1683 - if (!neigh_node) 1684 - goto out; 1685 - 1686 - batadv_dbg(BATADV_DBG_TT, bat_priv, 1687 - "Sending TT_REQUEST to %pM via %pM [%c]\n", 1688 - dst_orig_node->orig, neigh_node->addr, 1689 - (full_table ? 'F' : '.')); 1683 + batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n", 1684 + dst_orig_node->orig, (full_table ? 'F' : '.')); 1690 1685 1691 1686 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); 1692 1687 1693 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1694 - ret = 0; 1688 + if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL)) 1689 + ret = 0; 1695 1690 1696 1691 out: 1697 - if (neigh_node) 1698 - batadv_neigh_node_free_ref(neigh_node); 1699 1692 if (primary_if) 1700 1693 batadv_hardif_free_ref(primary_if); 1701 1694 if (ret) ··· 1707 1716 { 1708 1717 struct batadv_orig_node *req_dst_orig_node; 1709 1718 struct batadv_orig_node *res_dst_orig_node = NULL; 1710 - struct batadv_neigh_node *neigh_node = NULL; 1711 1719 struct batadv_hard_iface *primary_if = NULL; 1712 1720 uint8_t orig_ttvn, req_ttvn, ttvn; 1713 1721 int ret = false; ··· 1730 1740 1731 1741 res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1732 1742 if (!res_dst_orig_node) 1733 - goto out; 1734 - 1735 - neigh_node = batadv_orig_node_get_router(res_dst_orig_node); 1736 - if (!neigh_node) 1737 1743 goto out; 1738 1744 1739 1745 primary_if = batadv_primary_if_get_selected(bat_priv); ··· 1803 1817 tt_response->flags |= BATADV_TT_FULL_TABLE; 1804 1818 1805 1819 batadv_dbg(BATADV_DBG_TT, bat_priv, 1806 - "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n", 1807 - res_dst_orig_node->orig, neigh_node->addr, 1808 - req_dst_orig_node->orig, req_ttvn); 1820 + "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n", 1821 + res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn); 1809 1822 1810 1823 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1811 1824 1812 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1813 - ret = true; 1825 + if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL)) 1826 + ret = true; 1814 1827 goto out; 1815 1828 1816 1829 unlock: ··· 1820 1835 batadv_orig_node_free_ref(res_dst_orig_node); 1821 1836 if (req_dst_orig_node) 1822 1837 batadv_orig_node_free_ref(req_dst_orig_node); 1823 - if (neigh_node) 1824 - batadv_neigh_node_free_ref(neigh_node); 1825 1838 if (primary_if) 1826 1839 batadv_hardif_free_ref(primary_if); 1827 1840 if (!ret) ··· 1833 1850 struct batadv_tt_query_packet *tt_request) 1834 1851 { 1835 1852 struct batadv_orig_node *orig_node; 1836 - struct batadv_neigh_node *neigh_node = NULL; 1837 1853 struct batadv_hard_iface *primary_if = NULL; 1838 1854 uint8_t my_ttvn, req_ttvn, ttvn; 1839 1855 int ret = false; ··· 1855 1873 1856 1874 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1857 1875 if (!orig_node) 1858 - goto out; 1859 - 1860 - neigh_node = batadv_orig_node_get_router(orig_node); 1861 - if (!neigh_node) 1862 1876 goto out; 1863 1877 1864 1878 primary_if = batadv_primary_if_get_selected(bat_priv); ··· 1920 1942 tt_response->flags |= BATADV_TT_FULL_TABLE; 1921 1943 1922 1944 batadv_dbg(BATADV_DBG_TT, bat_priv, 1923 - "Sending TT_RESPONSE to %pM via %pM [%c]\n", 1924 - orig_node->orig, neigh_node->addr, 1945 + "Sending TT_RESPONSE to %pM [%c]\n", 1946 + orig_node->orig, 1925 1947 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1926 1948 1927 1949 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1928 1950 1929 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1930 - ret = true; 1951 + if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 1952 + ret = true; 1931 1953 goto out; 1932 1954 1933 1955 unlock: ··· 1935 1957 out: 1936 1958 if (orig_node) 1937 1959 batadv_orig_node_free_ref(orig_node); 1938 - if (neigh_node) 1939 - batadv_neigh_node_free_ref(neigh_node); 1940 1960 if (primary_if) 1941 1961 batadv_hardif_free_ref(primary_if); 1942 1962 if (!ret) ··· 2199 2223 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 2200 2224 struct batadv_orig_node *orig_node) 2201 2225 { 2202 - struct batadv_neigh_node *neigh_node = NULL; 2203 2226 struct sk_buff *skb = NULL; 2204 2227 struct batadv_roam_adv_packet *roam_adv_packet; 2205 2228 int ret = 1; ··· 2231 2256 memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); 2232 2257 memcpy(roam_adv_packet->client, client, ETH_ALEN); 2233 2258 2234 - neigh_node = batadv_orig_node_get_router(orig_node); 2235 - if (!neigh_node) 2236 - goto out; 2237 - 2238 2259 batadv_dbg(BATADV_DBG_TT, bat_priv, 2239 - "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", 2240 - orig_node->orig, client, neigh_node->addr); 2260 + "Sending ROAMING_ADV to %pM (client %pM)\n", 2261 + orig_node->orig, client); 2241 2262 2242 2263 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 2243 2264 2244 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 2245 - ret = 0; 2265 + if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 2266 + ret = 0; 2246 2267 2247 2268 out: 2248 - if (neigh_node) 2249 - batadv_neigh_node_free_ref(neigh_node); 2250 - if (ret) 2269 + if (ret && skb) 2251 2270 kfree_skb(skb); 2252 2271 return; 2253 2272 }
+4 -4
net/batman-adv/unicast.c
··· 402 402 struct batadv_orig_node *orig_node; 403 403 struct batadv_neigh_node *neigh_node; 404 404 int data_len = skb->len; 405 - int ret = 1; 405 + int ret = NET_RX_DROP; 406 406 unsigned int dev_mtu; 407 407 408 408 /* get routing information */ ··· 466 466 goto out; 467 467 } 468 468 469 - batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 470 - ret = 0; 469 + if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 470 + ret = 0; 471 471 472 472 out: 473 473 if (neigh_node) 474 474 batadv_neigh_node_free_ref(neigh_node); 475 475 if (orig_node) 476 476 batadv_orig_node_free_ref(orig_node); 477 - if (ret == 1) 477 + if (ret == NET_RX_DROP) 478 478 kfree_skb(skb); 479 479 return ret; 480 480 }
+9 -26
net/batman-adv/vis.c
··· 698 698 static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv, 699 699 struct batadv_vis_info *info) 700 700 { 701 - struct batadv_neigh_node *router; 702 701 struct batadv_hashtable *hash = bat_priv->orig_hash; 703 702 struct hlist_node *node; 704 703 struct hlist_head *head; 705 704 struct batadv_orig_node *orig_node; 706 705 struct batadv_vis_packet *packet; 707 706 struct sk_buff *skb; 708 - struct batadv_hard_iface *hard_iface; 709 - uint8_t dstaddr[ETH_ALEN]; 710 707 uint32_t i; 711 708 712 709 ··· 719 722 if (!(orig_node->flags & BATADV_VIS_SERVER)) 720 723 continue; 721 724 722 - router = batadv_orig_node_get_router(orig_node); 723 - if (!router) 724 - continue; 725 - 726 725 /* don't send it if we already received the packet from 727 726 * this node. 728 727 */ 729 728 if (batadv_recv_list_is_in(bat_priv, &info->recv_list, 730 - orig_node->orig)) { 731 - batadv_neigh_node_free_ref(router); 729 + orig_node->orig)) 732 730 continue; 733 - } 734 731 735 732 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 736 - hard_iface = router->if_incoming; 737 - memcpy(dstaddr, router->addr, ETH_ALEN); 738 - 739 - batadv_neigh_node_free_ref(router); 740 - 741 733 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 742 - if (skb) 743 - batadv_send_skb_packet(skb, hard_iface, 744 - dstaddr); 734 + if (!skb) 735 + continue; 745 736 737 + if (!batadv_send_skb_to_orig(skb, orig_node, NULL)) 738 + kfree_skb(skb); 746 739 } 747 740 rcu_read_unlock(); 748 741 } ··· 742 755 struct batadv_vis_info *info) 743 756 { 744 757 struct batadv_orig_node *orig_node; 745 - struct batadv_neigh_node *router = NULL; 746 758 struct sk_buff *skb; 747 759 struct batadv_vis_packet *packet; 748 760 ··· 751 765 if (!orig_node) 752 766 goto out; 753 767 754 - router = batadv_orig_node_get_router(orig_node); 755 - if (!router) 768 + skb = skb_clone(info->skb_packet, GFP_ATOMIC); 769 + if (!skb) 756 770 goto out; 757 771 758 - skb = skb_clone(info->skb_packet, GFP_ATOMIC); 759 - if (skb) 760 - batadv_send_skb_packet(skb, router->if_incoming, router->addr); 772 + if (!batadv_send_skb_to_orig(skb, orig_node, NULL)) 773 + kfree_skb(skb); 761 774 762 775 out: 763 - if (router) 764 - batadv_neigh_node_free_ref(router); 765 776 if (orig_node) 766 777 batadv_orig_node_free_ref(orig_node); 767 778 }