This source file includes following definitions.
- batadv_v_iface_activate
- batadv_v_iface_enable
- batadv_v_iface_disable
- batadv_v_primary_iface_set
- batadv_v_iface_update_mac
- batadv_v_hardif_neigh_init
- batadv_v_orig_print_neigh
- batadv_v_hardif_neigh_print
- batadv_v_neigh_print
- batadv_v_neigh_dump_neigh
- batadv_v_neigh_dump_hardif
- batadv_v_neigh_dump
- batadv_v_orig_print
- batadv_v_orig_dump_subentry
- batadv_v_orig_dump_entry
- batadv_v_orig_dump_bucket
- batadv_v_orig_dump
- batadv_v_neigh_cmp
- batadv_v_neigh_is_sob
- batadv_v_init_sel_class
- batadv_v_store_sel_class
- batadv_v_show_sel_class
- batadv_v_gw_throughput_get
- batadv_v_gw_get_best_gw_node
- batadv_v_gw_is_eligible
- batadv_v_gw_write_buffer_text
- batadv_v_gw_print
- batadv_v_gw_dump_entry
- batadv_v_gw_dump
- batadv_v_hardif_init
- batadv_v_mesh_init
- batadv_v_mesh_free
- batadv_v_init
   1 
   2 
   3 
   4 
   5 
   6 
   7 #include "bat_v.h"
   8 #include "main.h"
   9 
  10 #include <linux/atomic.h>
  11 #include <linux/cache.h>
  12 #include <linux/errno.h>
  13 #include <linux/if_ether.h>
  14 #include <linux/init.h>
  15 #include <linux/jiffies.h>
  16 #include <linux/kernel.h>
  17 #include <linux/kref.h>
  18 #include <linux/list.h>
  19 #include <linux/netdevice.h>
  20 #include <linux/netlink.h>
  21 #include <linux/rculist.h>
  22 #include <linux/rcupdate.h>
  23 #include <linux/seq_file.h>
  24 #include <linux/skbuff.h>
  25 #include <linux/spinlock.h>
  26 #include <linux/stddef.h>
  27 #include <linux/types.h>
  28 #include <linux/workqueue.h>
  29 #include <net/genetlink.h>
  30 #include <net/netlink.h>
  31 #include <uapi/linux/batadv_packet.h>
  32 #include <uapi/linux/batman_adv.h>
  33 
  34 #include "bat_algo.h"
  35 #include "bat_v_elp.h"
  36 #include "bat_v_ogm.h"
  37 #include "gateway_client.h"
  38 #include "gateway_common.h"
  39 #include "hard-interface.h"
  40 #include "hash.h"
  41 #include "log.h"
  42 #include "netlink.h"
  43 #include "originator.h"
  44 
  45 static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface)
  46 {
  47         struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
  48         struct batadv_hard_iface *primary_if;
  49 
  50         primary_if = batadv_primary_if_get_selected(bat_priv);
  51 
  52         if (primary_if) {
  53                 batadv_v_elp_iface_activate(primary_if, hard_iface);
  54                 batadv_hardif_put(primary_if);
  55         }
  56 
  57         
  58 
  59 
  60 
  61         if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
  62                 hard_iface->if_status = BATADV_IF_ACTIVE;
  63 }
  64 
  65 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
  66 {
  67         int ret;
  68 
  69         ret = batadv_v_elp_iface_enable(hard_iface);
  70         if (ret < 0)
  71                 return ret;
  72 
  73         ret = batadv_v_ogm_iface_enable(hard_iface);
  74         if (ret < 0)
  75                 batadv_v_elp_iface_disable(hard_iface);
  76 
  77         return ret;
  78 }
  79 
  80 static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface)
  81 {
  82         batadv_v_ogm_iface_disable(hard_iface);
  83         batadv_v_elp_iface_disable(hard_iface);
  84 }
  85 
  86 static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
  87 {
  88         batadv_v_elp_primary_iface_set(hard_iface);
  89         batadv_v_ogm_primary_iface_set(hard_iface);
  90 }
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface)
 100 {
 101         struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 102         struct batadv_hard_iface *primary_if;
 103 
 104         primary_if = batadv_primary_if_get_selected(bat_priv);
 105         if (primary_if != hard_iface)
 106                 goto out;
 107 
 108         batadv_v_primary_iface_set(hard_iface);
 109 out:
 110         if (primary_if)
 111                 batadv_hardif_put(primary_if);
 112 }
 113 
 114 static void
 115 batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
 116 {
 117         ewma_throughput_init(&hardif_neigh->bat_v.throughput);
 118         INIT_WORK(&hardif_neigh->bat_v.metric_work,
 119                   batadv_v_elp_throughput_metric_update);
 120 }
 121 
 122 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 static void
 132 batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node,
 133                           struct batadv_hard_iface *if_outgoing,
 134                           struct seq_file *seq)
 135 {
 136         struct batadv_neigh_node *neigh_node;
 137         struct batadv_neigh_ifinfo *n_ifinfo;
 138 
 139         hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
 140                 n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
 141                 if (!n_ifinfo)
 142                         continue;
 143 
 144                 seq_printf(seq, " %pM (%9u.%1u)",
 145                            neigh_node->addr,
 146                            n_ifinfo->bat_v.throughput / 10,
 147                            n_ifinfo->bat_v.throughput % 10);
 148 
 149                 batadv_neigh_ifinfo_put(n_ifinfo);
 150         }
 151 }
 152 
 153 
 154 
 155 
 156 
 157 
 158 static void
 159 batadv_v_hardif_neigh_print(struct seq_file *seq,
 160                             struct batadv_hardif_neigh_node *hardif_neigh)
 161 {
 162         int last_secs, last_msecs;
 163         u32 throughput;
 164 
 165         last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000;
 166         last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000;
 167         throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
 168 
 169         seq_printf(seq, "%pM %4i.%03is (%9u.%1u) [%10s]\n",
 170                    hardif_neigh->addr, last_secs, last_msecs, throughput / 10,
 171                    throughput % 10, hardif_neigh->if_incoming->net_dev->name);
 172 }
 173 
 174 
 175 
 176 
 177 
 178 
 179 static void batadv_v_neigh_print(struct batadv_priv *bat_priv,
 180                                  struct seq_file *seq)
 181 {
 182         struct net_device *net_dev = (struct net_device *)seq->private;
 183         struct batadv_hardif_neigh_node *hardif_neigh;
 184         struct batadv_hard_iface *hard_iface;
 185         int batman_count = 0;
 186 
 187         seq_puts(seq,
 188                  "  Neighbor        last-seen ( throughput) [        IF]\n");
 189 
 190         rcu_read_lock();
 191         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
 192                 if (hard_iface->soft_iface != net_dev)
 193                         continue;
 194 
 195                 hlist_for_each_entry_rcu(hardif_neigh,
 196                                          &hard_iface->neigh_list, list) {
 197                         batadv_v_hardif_neigh_print(seq, hardif_neigh);
 198                         batman_count++;
 199                 }
 200         }
 201         rcu_read_unlock();
 202 
 203         if (batman_count == 0)
 204                 seq_puts(seq, "No batman nodes in range ...\n");
 205 }
 206 #endif
 207 
 208 
 209 
 210 
 211 
 212 
 213 
 214 
 215 
 216 
 217 static int
 218 batadv_v_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
 219                           struct batadv_hardif_neigh_node *hardif_neigh)
 220 {
 221         void *hdr;
 222         unsigned int last_seen_msecs;
 223         u32 throughput;
 224 
 225         last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
 226         throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
 227         throughput = throughput * 100;
 228 
 229         hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
 230                           BATADV_CMD_GET_NEIGHBORS);
 231         if (!hdr)
 232                 return -ENOBUFS;
 233 
 234         if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
 235                     hardif_neigh->addr) ||
 236             nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
 237                         hardif_neigh->if_incoming->net_dev->ifindex) ||
 238             nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
 239                         last_seen_msecs) ||
 240             nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput))
 241                 goto nla_put_failure;
 242 
 243         genlmsg_end(msg, hdr);
 244         return 0;
 245 
 246  nla_put_failure:
 247         genlmsg_cancel(msg, hdr);
 248         return -EMSGSIZE;
 249 }
 250 
 251 
 252 
 253 
 254 
 255 
 256 
 257 
 258 
 259 
 260 
 261 
 262 
 263 
 264 
 265 static int
 266 batadv_v_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
 267                            struct batadv_priv *bat_priv,
 268                            struct batadv_hard_iface *hard_iface,
 269                            int *idx_s)
 270 {
 271         struct batadv_hardif_neigh_node *hardif_neigh;
 272         int idx = 0;
 273 
 274         hlist_for_each_entry_rcu(hardif_neigh,
 275                                  &hard_iface->neigh_list, list) {
 276                 if (idx++ < *idx_s)
 277                         continue;
 278 
 279                 if (batadv_v_neigh_dump_neigh(msg, portid, seq, hardif_neigh)) {
 280                         *idx_s = idx - 1;
 281                         return -EMSGSIZE;
 282                 }
 283         }
 284 
 285         *idx_s = 0;
 286         return 0;
 287 }
 288 
 289 
 290 
 291 
 292 
 293 
 294 
 295 
 296 
 297 static void
 298 batadv_v_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
 299                     struct batadv_priv *bat_priv,
 300                     struct batadv_hard_iface *single_hardif)
 301 {
 302         struct batadv_hard_iface *hard_iface;
 303         int i_hardif = 0;
 304         int i_hardif_s = cb->args[0];
 305         int idx = cb->args[1];
 306         int portid = NETLINK_CB(cb->skb).portid;
 307 
 308         rcu_read_lock();
 309         if (single_hardif) {
 310                 if (i_hardif_s == 0) {
 311                         if (batadv_v_neigh_dump_hardif(msg, portid,
 312                                                        cb->nlh->nlmsg_seq,
 313                                                        bat_priv, single_hardif,
 314                                                        &idx) == 0)
 315                                 i_hardif++;
 316                 }
 317         } else {
 318                 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
 319                         if (hard_iface->soft_iface != bat_priv->soft_iface)
 320                                 continue;
 321 
 322                         if (i_hardif++ < i_hardif_s)
 323                                 continue;
 324 
 325                         if (batadv_v_neigh_dump_hardif(msg, portid,
 326                                                        cb->nlh->nlmsg_seq,
 327                                                        bat_priv, hard_iface,
 328                                                        &idx)) {
 329                                 i_hardif--;
 330                                 break;
 331                         }
 332                 }
 333         }
 334         rcu_read_unlock();
 335 
 336         cb->args[0] = i_hardif;
 337         cb->args[1] = idx;
 338 }
 339 
 340 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
 341 
 342 
 343 
 344 
 345 
 346 
 347 static void batadv_v_orig_print(struct batadv_priv *bat_priv,
 348                                 struct seq_file *seq,
 349                                 struct batadv_hard_iface *if_outgoing)
 350 {
 351         struct batadv_neigh_node *neigh_node;
 352         struct batadv_hashtable *hash = bat_priv->orig_hash;
 353         int last_seen_msecs, last_seen_secs;
 354         struct batadv_orig_node *orig_node;
 355         struct batadv_neigh_ifinfo *n_ifinfo;
 356         unsigned long last_seen_jiffies;
 357         struct hlist_head *head;
 358         int batman_count = 0;
 359         u32 i;
 360 
 361         seq_puts(seq,
 362                  "  Originator      last-seen ( throughput)           Nexthop [outgoingIF]:   Potential nexthops ...\n");
 363 
 364         for (i = 0; i < hash->size; i++) {
 365                 head = &hash->table[i];
 366 
 367                 rcu_read_lock();
 368                 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
 369                         neigh_node = batadv_orig_router_get(orig_node,
 370                                                             if_outgoing);
 371                         if (!neigh_node)
 372                                 continue;
 373 
 374                         n_ifinfo = batadv_neigh_ifinfo_get(neigh_node,
 375                                                            if_outgoing);
 376                         if (!n_ifinfo)
 377                                 goto next;
 378 
 379                         last_seen_jiffies = jiffies - orig_node->last_seen;
 380                         last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
 381                         last_seen_secs = last_seen_msecs / 1000;
 382                         last_seen_msecs = last_seen_msecs % 1000;
 383 
 384                         seq_printf(seq, "%pM %4i.%03is (%9u.%1u) %pM [%10s]:",
 385                                    orig_node->orig, last_seen_secs,
 386                                    last_seen_msecs,
 387                                    n_ifinfo->bat_v.throughput / 10,
 388                                    n_ifinfo->bat_v.throughput % 10,
 389                                    neigh_node->addr,
 390                                    neigh_node->if_incoming->net_dev->name);
 391 
 392                         batadv_v_orig_print_neigh(orig_node, if_outgoing, seq);
 393                         seq_putc(seq, '\n');
 394                         batman_count++;
 395 
 396 next:
 397                         batadv_neigh_node_put(neigh_node);
 398                         if (n_ifinfo)
 399                                 batadv_neigh_ifinfo_put(n_ifinfo);
 400                 }
 401                 rcu_read_unlock();
 402         }
 403 
 404         if (batman_count == 0)
 405                 seq_puts(seq, "No batman nodes in range ...\n");
 406 }
 407 #endif
 408 
 409 
 410 
 411 
 412 
 413 
 414 
 415 
 416 
 417 
 418 
 419 
 420 
 421 
 422 static int
 423 batadv_v_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
 424                             struct batadv_priv *bat_priv,
 425                             struct batadv_hard_iface *if_outgoing,
 426                             struct batadv_orig_node *orig_node,
 427                             struct batadv_neigh_node *neigh_node,
 428                             bool best)
 429 {
 430         struct batadv_neigh_ifinfo *n_ifinfo;
 431         unsigned int last_seen_msecs;
 432         u32 throughput;
 433         void *hdr;
 434 
 435         n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
 436         if (!n_ifinfo)
 437                 return 0;
 438 
 439         throughput = n_ifinfo->bat_v.throughput * 100;
 440 
 441         batadv_neigh_ifinfo_put(n_ifinfo);
 442 
 443         last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
 444 
 445         if (if_outgoing != BATADV_IF_DEFAULT &&
 446             if_outgoing != neigh_node->if_incoming)
 447                 return 0;
 448 
 449         hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
 450                           BATADV_CMD_GET_ORIGINATORS);
 451         if (!hdr)
 452                 return -ENOBUFS;
 453 
 454         if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) ||
 455             nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
 456                     neigh_node->addr) ||
 457             nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
 458                         neigh_node->if_incoming->net_dev->ifindex) ||
 459             nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput) ||
 460             nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
 461                         last_seen_msecs))
 462                 goto nla_put_failure;
 463 
 464         if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
 465                 goto nla_put_failure;
 466 
 467         genlmsg_end(msg, hdr);
 468         return 0;
 469 
 470  nla_put_failure:
 471         genlmsg_cancel(msg, hdr);
 472         return -EMSGSIZE;
 473 }
 474 
 475 
 476 
 477 
 478 
 479 
 480 
 481 
 482 
 483 
 484 
 485 
 486 
 487 
 488 
 489 static int
 490 batadv_v_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
 491                          struct batadv_priv *bat_priv,
 492                          struct batadv_hard_iface *if_outgoing,
 493                          struct batadv_orig_node *orig_node, int *sub_s)
 494 {
 495         struct batadv_neigh_node *neigh_node_best;
 496         struct batadv_neigh_node *neigh_node;
 497         int sub = 0;
 498         bool best;
 499 
 500         neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
 501         if (!neigh_node_best)
 502                 goto out;
 503 
 504         hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
 505                 if (sub++ < *sub_s)
 506                         continue;
 507 
 508                 best = (neigh_node == neigh_node_best);
 509 
 510                 if (batadv_v_orig_dump_subentry(msg, portid, seq, bat_priv,
 511                                                 if_outgoing, orig_node,
 512                                                 neigh_node, best)) {
 513                         batadv_neigh_node_put(neigh_node_best);
 514 
 515                         *sub_s = sub - 1;
 516                         return -EMSGSIZE;
 517                 }
 518         }
 519 
 520  out:
 521         if (neigh_node_best)
 522                 batadv_neigh_node_put(neigh_node_best);
 523 
 524         *sub_s = 0;
 525         return 0;
 526 }
 527 
 528 
 529 
 530 
 531 
 532 
 533 
 534 
 535 
 536 
 537 
 538 
 539 
 540 
 541 static int
 542 batadv_v_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
 543                           struct batadv_priv *bat_priv,
 544                           struct batadv_hard_iface *if_outgoing,
 545                           struct hlist_head *head, int *idx_s, int *sub)
 546 {
 547         struct batadv_orig_node *orig_node;
 548         int idx = 0;
 549 
 550         rcu_read_lock();
 551         hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
 552                 if (idx++ < *idx_s)
 553                         continue;
 554 
 555                 if (batadv_v_orig_dump_entry(msg, portid, seq, bat_priv,
 556                                              if_outgoing, orig_node, sub)) {
 557                         rcu_read_unlock();
 558                         *idx_s = idx - 1;
 559                         return -EMSGSIZE;
 560                 }
 561         }
 562         rcu_read_unlock();
 563 
 564         *idx_s = 0;
 565         *sub = 0;
 566         return 0;
 567 }
 568 
 569 
 570 
 571 
 572 
 573 
 574 
 575 
 576 static void
 577 batadv_v_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
 578                    struct batadv_priv *bat_priv,
 579                    struct batadv_hard_iface *if_outgoing)
 580 {
 581         struct batadv_hashtable *hash = bat_priv->orig_hash;
 582         struct hlist_head *head;
 583         int bucket = cb->args[0];
 584         int idx = cb->args[1];
 585         int sub = cb->args[2];
 586         int portid = NETLINK_CB(cb->skb).portid;
 587 
 588         while (bucket < hash->size) {
 589                 head = &hash->table[bucket];
 590 
 591                 if (batadv_v_orig_dump_bucket(msg, portid,
 592                                               cb->nlh->nlmsg_seq,
 593                                               bat_priv, if_outgoing, head, &idx,
 594                                               &sub))
 595                         break;
 596 
 597                 bucket++;
 598         }
 599 
 600         cb->args[0] = bucket;
 601         cb->args[1] = idx;
 602         cb->args[2] = sub;
 603 }
 604 
 605 static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
 606                               struct batadv_hard_iface *if_outgoing1,
 607                               struct batadv_neigh_node *neigh2,
 608                               struct batadv_hard_iface *if_outgoing2)
 609 {
 610         struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
 611         int ret = 0;
 612 
 613         ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
 614         if (!ifinfo1)
 615                 goto err_ifinfo1;
 616 
 617         ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
 618         if (!ifinfo2)
 619                 goto err_ifinfo2;
 620 
 621         ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
 622 
 623         batadv_neigh_ifinfo_put(ifinfo2);
 624 err_ifinfo2:
 625         batadv_neigh_ifinfo_put(ifinfo1);
 626 err_ifinfo1:
 627         return ret;
 628 }
 629 
 630 static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
 631                                   struct batadv_hard_iface *if_outgoing1,
 632                                   struct batadv_neigh_node *neigh2,
 633                                   struct batadv_hard_iface *if_outgoing2)
 634 {
 635         struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
 636         u32 threshold;
 637         bool ret = false;
 638 
 639         ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
 640         if (!ifinfo1)
 641                 goto err_ifinfo1;
 642 
 643         ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
 644         if (!ifinfo2)
 645                 goto err_ifinfo2;
 646 
 647         threshold = ifinfo1->bat_v.throughput / 4;
 648         threshold = ifinfo1->bat_v.throughput - threshold;
 649 
 650         ret = ifinfo2->bat_v.throughput > threshold;
 651 
 652         batadv_neigh_ifinfo_put(ifinfo2);
 653 err_ifinfo2:
 654         batadv_neigh_ifinfo_put(ifinfo1);
 655 err_ifinfo1:
 656         return ret;
 657 }
 658 
 659 
 660 
 661 
 662 
 663 static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
 664 {
 665         
 666         atomic_set(&bat_priv->gw.sel_class, 50);
 667 }
 668 
 669 static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
 670                                         char *buff, size_t count)
 671 {
 672         u32 old_class, class;
 673 
 674         if (!batadv_parse_throughput(bat_priv->soft_iface, buff,
 675                                      "B.A.T.M.A.N. V GW selection class",
 676                                      &class))
 677                 return -EINVAL;
 678 
 679         old_class = atomic_read(&bat_priv->gw.sel_class);
 680         atomic_set(&bat_priv->gw.sel_class, class);
 681 
 682         if (old_class != class)
 683                 batadv_gw_reselect(bat_priv);
 684 
 685         return count;
 686 }
 687 
 688 static ssize_t batadv_v_show_sel_class(struct batadv_priv *bat_priv, char *buff)
 689 {
 690         u32 class = atomic_read(&bat_priv->gw.sel_class);
 691 
 692         return sprintf(buff, "%u.%u MBit\n", class / 10, class % 10);
 693 }
 694 
 695 
 696 
 697 
 698 
 699 
 700 
 701 
 702 
 703 
 704 static int batadv_v_gw_throughput_get(struct batadv_gw_node *gw_node, u32 *bw)
 705 {
 706         struct batadv_neigh_ifinfo *router_ifinfo = NULL;
 707         struct batadv_orig_node *orig_node;
 708         struct batadv_neigh_node *router;
 709         int ret = -1;
 710 
 711         orig_node = gw_node->orig_node;
 712         router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
 713         if (!router)
 714                 goto out;
 715 
 716         router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
 717         if (!router_ifinfo)
 718                 goto out;
 719 
 720         
 721 
 722 
 723 
 724 
 725         *bw = router_ifinfo->bat_v.throughput;
 726         *bw = min_t(u32, *bw, gw_node->bandwidth_down);
 727 
 728         ret = 0;
 729 out:
 730         if (router)
 731                 batadv_neigh_node_put(router);
 732         if (router_ifinfo)
 733                 batadv_neigh_ifinfo_put(router_ifinfo);
 734 
 735         return ret;
 736 }
 737 
 738 
 739 
 740 
 741 
 742 
 743 
 744 static struct batadv_gw_node *
 745 batadv_v_gw_get_best_gw_node(struct batadv_priv *bat_priv)
 746 {
 747         struct batadv_gw_node *gw_node, *curr_gw = NULL;
 748         u32 max_bw = 0, bw;
 749 
 750         rcu_read_lock();
 751         hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
 752                 if (!kref_get_unless_zero(&gw_node->refcount))
 753                         continue;
 754 
 755                 if (batadv_v_gw_throughput_get(gw_node, &bw) < 0)
 756                         goto next;
 757 
 758                 if (curr_gw && bw <= max_bw)
 759                         goto next;
 760 
 761                 if (curr_gw)
 762                         batadv_gw_node_put(curr_gw);
 763 
 764                 curr_gw = gw_node;
 765                 kref_get(&curr_gw->refcount);
 766                 max_bw = bw;
 767 
 768 next:
 769                 batadv_gw_node_put(gw_node);
 770         }
 771         rcu_read_unlock();
 772 
 773         return curr_gw;
 774 }
 775 
 776 
 777 
 778 
 779 
 780 
 781 
 782 
 783 
 784 static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
 785                                     struct batadv_orig_node *curr_gw_orig,
 786                                     struct batadv_orig_node *orig_node)
 787 {
 788         struct batadv_gw_node *curr_gw, *orig_gw = NULL;
 789         u32 gw_throughput, orig_throughput, threshold;
 790         bool ret = false;
 791 
 792         threshold = atomic_read(&bat_priv->gw.sel_class);
 793 
 794         curr_gw = batadv_gw_node_get(bat_priv, curr_gw_orig);
 795         if (!curr_gw) {
 796                 ret = true;
 797                 goto out;
 798         }
 799 
 800         if (batadv_v_gw_throughput_get(curr_gw, &gw_throughput) < 0) {
 801                 ret = true;
 802                 goto out;
 803         }
 804 
 805         orig_gw = batadv_gw_node_get(bat_priv, orig_node);
 806         if (!orig_gw)
 807                 goto out;
 808 
 809         if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)
 810                 goto out;
 811 
 812         if (orig_throughput < gw_throughput)
 813                 goto out;
 814 
 815         if ((orig_throughput - gw_throughput) < threshold)
 816                 goto out;
 817 
 818         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 819                    "Restarting gateway selection: better gateway found (throughput curr: %u, throughput new: %u)\n",
 820                    gw_throughput, orig_throughput);
 821 
 822         ret = true;
 823 out:
 824         if (curr_gw)
 825                 batadv_gw_node_put(curr_gw);
 826         if (orig_gw)
 827                 batadv_gw_node_put(orig_gw);
 828 
 829         return ret;
 830 }
 831 
 832 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
 833 
 834 static int batadv_v_gw_write_buffer_text(struct batadv_priv *bat_priv,
 835                                          struct seq_file *seq,
 836                                          const struct batadv_gw_node *gw_node)
 837 {
 838         struct batadv_gw_node *curr_gw;
 839         struct batadv_neigh_node *router;
 840         struct batadv_neigh_ifinfo *router_ifinfo = NULL;
 841         int ret = -1;
 842 
 843         router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
 844         if (!router)
 845                 goto out;
 846 
 847         router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
 848         if (!router_ifinfo)
 849                 goto out;
 850 
 851         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
 852 
 853         seq_printf(seq, "%s %pM (%9u.%1u) %pM [%10s]: %u.%u/%u.%u MBit\n",
 854                    (curr_gw == gw_node ? "=>" : "  "),
 855                    gw_node->orig_node->orig,
 856                    router_ifinfo->bat_v.throughput / 10,
 857                    router_ifinfo->bat_v.throughput % 10, router->addr,
 858                    router->if_incoming->net_dev->name,
 859                    gw_node->bandwidth_down / 10,
 860                    gw_node->bandwidth_down % 10,
 861                    gw_node->bandwidth_up / 10,
 862                    gw_node->bandwidth_up % 10);
 863         ret = seq_has_overflowed(seq) ? -1 : 0;
 864 
 865         if (curr_gw)
 866                 batadv_gw_node_put(curr_gw);
 867 out:
 868         if (router_ifinfo)
 869                 batadv_neigh_ifinfo_put(router_ifinfo);
 870         if (router)
 871                 batadv_neigh_node_put(router);
 872         return ret;
 873 }
 874 
 875 
 876 
 877 
 878 
 879 
 880 static void batadv_v_gw_print(struct batadv_priv *bat_priv,
 881                               struct seq_file *seq)
 882 {
 883         struct batadv_gw_node *gw_node;
 884         int gw_count = 0;
 885 
 886         seq_puts(seq,
 887                  "      Gateway        ( throughput)           Nexthop [outgoingIF]: advertised uplink bandwidth\n");
 888 
 889         rcu_read_lock();
 890         hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
 891                 
 892                 if (batadv_v_gw_write_buffer_text(bat_priv, seq, gw_node) < 0)
 893                         continue;
 894 
 895                 gw_count++;
 896         }
 897         rcu_read_unlock();
 898 
 899         if (gw_count == 0)
 900                 seq_puts(seq, "No gateways in range ...\n");
 901 }
 902 #endif
 903 
 904 
 905 
 906 
 907 
 908 
 909 
 910 
 911 
 912 
 913 
 914 static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid,
 915                                   struct netlink_callback *cb,
 916                                   struct batadv_priv *bat_priv,
 917                                   struct batadv_gw_node *gw_node)
 918 {
 919         struct batadv_neigh_ifinfo *router_ifinfo = NULL;
 920         struct batadv_neigh_node *router;
 921         struct batadv_gw_node *curr_gw = NULL;
 922         int ret = 0;
 923         void *hdr;
 924 
 925         router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
 926         if (!router)
 927                 goto out;
 928 
 929         router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
 930         if (!router_ifinfo)
 931                 goto out;
 932 
 933         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
 934 
 935         hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
 936                           &batadv_netlink_family, NLM_F_MULTI,
 937                           BATADV_CMD_GET_GATEWAYS);
 938         if (!hdr) {
 939                 ret = -ENOBUFS;
 940                 goto out;
 941         }
 942 
 943         genl_dump_check_consistent(cb, hdr);
 944 
 945         ret = -EMSGSIZE;
 946 
 947         if (curr_gw == gw_node) {
 948                 if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
 949                         genlmsg_cancel(msg, hdr);
 950                         goto out;
 951                 }
 952         }
 953 
 954         if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
 955                     gw_node->orig_node->orig)) {
 956                 genlmsg_cancel(msg, hdr);
 957                 goto out;
 958         }
 959 
 960         if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT,
 961                         router_ifinfo->bat_v.throughput)) {
 962                 genlmsg_cancel(msg, hdr);
 963                 goto out;
 964         }
 965 
 966         if (nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN, router->addr)) {
 967                 genlmsg_cancel(msg, hdr);
 968                 goto out;
 969         }
 970 
 971         if (nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
 972                            router->if_incoming->net_dev->name)) {
 973                 genlmsg_cancel(msg, hdr);
 974                 goto out;
 975         }
 976 
 977         if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
 978                         gw_node->bandwidth_down)) {
 979                 genlmsg_cancel(msg, hdr);
 980                 goto out;
 981         }
 982 
 983         if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP, gw_node->bandwidth_up)) {
 984                 genlmsg_cancel(msg, hdr);
 985                 goto out;
 986         }
 987 
 988         genlmsg_end(msg, hdr);
 989         ret = 0;
 990 
 991 out:
 992         if (curr_gw)
 993                 batadv_gw_node_put(curr_gw);
 994         if (router_ifinfo)
 995                 batadv_neigh_ifinfo_put(router_ifinfo);
 996         if (router)
 997                 batadv_neigh_node_put(router);
 998         return ret;
 999 }
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 static void batadv_v_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
1008                              struct batadv_priv *bat_priv)
1009 {
1010         int portid = NETLINK_CB(cb->skb).portid;
1011         struct batadv_gw_node *gw_node;
1012         int idx_skip = cb->args[0];
1013         int idx = 0;
1014 
1015         spin_lock_bh(&bat_priv->gw.list_lock);
1016         cb->seq = bat_priv->gw.generation << 1 | 1;
1017 
1018         hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
1019                 if (idx++ < idx_skip)
1020                         continue;
1021 
1022                 if (batadv_v_gw_dump_entry(msg, portid, cb, bat_priv,
1023                                            gw_node)) {
1024                         idx_skip = idx - 1;
1025                         goto unlock;
1026                 }
1027         }
1028 
1029         idx_skip = idx;
1030 unlock:
1031         spin_unlock_bh(&bat_priv->gw.list_lock);
1032 
1033         cb->args[0] = idx_skip;
1034 }
1035 
1036 static struct batadv_algo_ops batadv_batman_v __read_mostly = {
1037         .name = "BATMAN_V",
1038         .iface = {
1039                 .activate = batadv_v_iface_activate,
1040                 .enable = batadv_v_iface_enable,
1041                 .disable = batadv_v_iface_disable,
1042                 .update_mac = batadv_v_iface_update_mac,
1043                 .primary_set = batadv_v_primary_iface_set,
1044         },
1045         .neigh = {
1046                 .hardif_init = batadv_v_hardif_neigh_init,
1047                 .cmp = batadv_v_neigh_cmp,
1048                 .is_similar_or_better = batadv_v_neigh_is_sob,
1049 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
1050                 .print = batadv_v_neigh_print,
1051 #endif
1052                 .dump = batadv_v_neigh_dump,
1053         },
1054         .orig = {
1055 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
1056                 .print = batadv_v_orig_print,
1057 #endif
1058                 .dump = batadv_v_orig_dump,
1059         },
1060         .gw = {
1061                 .init_sel_class = batadv_v_init_sel_class,
1062                 .store_sel_class = batadv_v_store_sel_class,
1063                 .show_sel_class = batadv_v_show_sel_class,
1064                 .get_best_gw_node = batadv_v_gw_get_best_gw_node,
1065                 .is_eligible = batadv_v_gw_is_eligible,
1066 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
1067                 .print = batadv_v_gw_print,
1068 #endif
1069                 .dump = batadv_v_gw_dump,
1070         },
1071 };
1072 
1073 
1074 
1075 
1076 
1077 
1078 void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface)
1079 {
1080         
1081 
1082 
1083         atomic_set(&hard_iface->bat_v.throughput_override, 0);
1084         atomic_set(&hard_iface->bat_v.elp_interval, 500);
1085 
1086         hard_iface->bat_v.aggr_len = 0;
1087         skb_queue_head_init(&hard_iface->bat_v.aggr_list);
1088         spin_lock_init(&hard_iface->bat_v.aggr_list_lock);
1089         INIT_DELAYED_WORK(&hard_iface->bat_v.aggr_wq,
1090                           batadv_v_ogm_aggr_work);
1091 }
1092 
1093 
1094 
1095 
1096 
1097 
1098 
1099 
1100 int batadv_v_mesh_init(struct batadv_priv *bat_priv)
1101 {
1102         int ret = 0;
1103 
1104         ret = batadv_v_ogm_init(bat_priv);
1105         if (ret < 0)
1106                 return ret;
1107 
1108         return 0;
1109 }
1110 
1111 
1112 
1113 
1114 
1115 void batadv_v_mesh_free(struct batadv_priv *bat_priv)
1116 {
1117         batadv_v_ogm_free(bat_priv);
1118 }
1119 
1120 
1121 
1122 
1123 
1124 
1125 
1126 
1127 
1128 int __init batadv_v_init(void)
1129 {
1130         int ret;
1131 
1132         
1133         ret = batadv_recv_handler_register(BATADV_ELP,
1134                                            batadv_v_elp_packet_recv);
1135         if (ret < 0)
1136                 return ret;
1137 
1138         ret = batadv_recv_handler_register(BATADV_OGM2,
1139                                            batadv_v_ogm_packet_recv);
1140         if (ret < 0)
1141                 goto elp_unregister;
1142 
1143         ret = batadv_algo_register(&batadv_batman_v);
1144         if (ret < 0)
1145                 goto ogm_unregister;
1146 
1147         return ret;
1148 
1149 ogm_unregister:
1150         batadv_recv_handler_unregister(BATADV_OGM2);
1151 
1152 elp_unregister:
1153         batadv_recv_handler_unregister(BATADV_ELP);
1154 
1155         return ret;
1156 }