sysfs.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. /* Copyright (C) 2010-2014 B.A.T.M.A.N. contributors:
  2. *
  3. * Marek Lindner
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of version 2 of the GNU General Public
  7. * License as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "main.h"
  18. #include "sysfs.h"
  19. #include "translation-table.h"
  20. #include "distributed-arp-table.h"
  21. #include "network-coding.h"
  22. #include "originator.h"
  23. #include "hard-interface.h"
  24. #include "soft-interface.h"
  25. #include "gateway_common.h"
  26. #include "gateway_client.h"
  27. static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
  28. {
  29. struct device *dev = container_of(obj->parent, struct device, kobj);
  30. return to_net_dev(dev);
  31. }
  32. static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
  33. {
  34. struct net_device *net_dev = batadv_kobj_to_netdev(obj);
  35. return netdev_priv(net_dev);
  36. }
  37. /**
  38. * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
  39. * @obj: kobject to covert
  40. *
  41. * Returns the associated batadv_priv struct.
  42. */
  43. static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
  44. {
  45. /* VLAN specific attributes are located in the root sysfs folder if they
  46. * refer to the untagged VLAN..
  47. */
  48. if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
  49. return batadv_kobj_to_batpriv(obj);
  50. /* ..while the attributes for the tagged vlans are located in
  51. * the in the corresponding "vlan%VID" subfolder
  52. */
  53. return batadv_kobj_to_batpriv(obj->parent);
  54. }
  55. /**
  56. * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct
  57. * @obj: kobject to covert
  58. *
  59. * Returns the associated softif_vlan struct if found, NULL otherwise.
  60. */
  61. static struct batadv_softif_vlan *
  62. batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
  63. {
  64. struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
  65. rcu_read_lock();
  66. hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
  67. if (vlan_tmp->kobj != obj)
  68. continue;
  69. if (!atomic_inc_not_zero(&vlan_tmp->refcount))
  70. continue;
  71. vlan = vlan_tmp;
  72. break;
  73. }
  74. rcu_read_unlock();
  75. return vlan;
  76. }
  77. #define BATADV_UEV_TYPE_VAR "BATTYPE="
  78. #define BATADV_UEV_ACTION_VAR "BATACTION="
  79. #define BATADV_UEV_DATA_VAR "BATDATA="
  80. static char *batadv_uev_action_str[] = {
  81. "add",
  82. "del",
  83. "change"
  84. };
  85. static char *batadv_uev_type_str[] = {
  86. "gw"
  87. };
  88. /* Use this, if you have customized show and store functions for vlan attrs */
  89. #define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \
  90. struct batadv_attribute batadv_attr_vlan_##_name = { \
  91. .attr = {.name = __stringify(_name), \
  92. .mode = _mode }, \
  93. .show = _show, \
  94. .store = _store, \
  95. }
  96. /* Use this, if you have customized show and store functions */
  97. #define BATADV_ATTR(_name, _mode, _show, _store) \
  98. struct batadv_attribute batadv_attr_##_name = { \
  99. .attr = {.name = __stringify(_name), \
  100. .mode = _mode }, \
  101. .show = _show, \
  102. .store = _store, \
  103. }
  104. #define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
  105. ssize_t batadv_store_##_name(struct kobject *kobj, \
  106. struct attribute *attr, char *buff, \
  107. size_t count) \
  108. { \
  109. struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
  110. struct batadv_priv *bat_priv = netdev_priv(net_dev); \
  111. \
  112. return __batadv_store_bool_attr(buff, count, _post_func, attr, \
  113. &bat_priv->_name, net_dev); \
  114. }
  115. #define BATADV_ATTR_SIF_SHOW_BOOL(_name) \
  116. ssize_t batadv_show_##_name(struct kobject *kobj, \
  117. struct attribute *attr, char *buff) \
  118. { \
  119. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
  120. \
  121. return sprintf(buff, "%s\n", \
  122. atomic_read(&bat_priv->_name) == 0 ? \
  123. "disabled" : "enabled"); \
  124. } \
  125. /* Use this, if you are going to turn a [name] in the soft-interface
  126. * (bat_priv) on or off
  127. */
  128. #define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \
  129. static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
  130. static BATADV_ATTR_SIF_SHOW_BOOL(_name) \
  131. static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
  132. batadv_store_##_name)
  133. #define BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \
  134. ssize_t batadv_store_##_name(struct kobject *kobj, \
  135. struct attribute *attr, char *buff, \
  136. size_t count) \
  137. { \
  138. struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
  139. struct batadv_priv *bat_priv = netdev_priv(net_dev); \
  140. \
  141. return __batadv_store_uint_attr(buff, count, _min, _max, \
  142. _post_func, attr, \
  143. &bat_priv->_name, net_dev); \
  144. }
  145. #define BATADV_ATTR_SIF_SHOW_UINT(_name) \
  146. ssize_t batadv_show_##_name(struct kobject *kobj, \
  147. struct attribute *attr, char *buff) \
  148. { \
  149. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
  150. \
  151. return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \
  152. } \
  153. /* Use this, if you are going to set [name] in the soft-interface
  154. * (bat_priv) to an unsigned integer value
  155. */
  156. #define BATADV_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \
  157. static BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func)\
  158. static BATADV_ATTR_SIF_SHOW_UINT(_name) \
  159. static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
  160. batadv_store_##_name)
  161. #define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
  162. ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
  163. struct attribute *attr, char *buff, \
  164. size_t count) \
  165. { \
  166. struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
  167. struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
  168. kobj); \
  169. size_t res = __batadv_store_bool_attr(buff, count, _post_func, \
  170. attr, &vlan->_name, \
  171. bat_priv->soft_iface); \
  172. \
  173. batadv_softif_vlan_free_ref(vlan); \
  174. return res; \
  175. }
  176. #define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
  177. ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
  178. struct attribute *attr, char *buff) \
  179. { \
  180. struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
  181. struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
  182. kobj); \
  183. size_t res = sprintf(buff, "%s\n", \
  184. atomic_read(&vlan->_name) == 0 ? \
  185. "disabled" : "enabled"); \
  186. \
  187. batadv_softif_vlan_free_ref(vlan); \
  188. return res; \
  189. }
  190. /* Use this, if you are going to turn a [name] in the vlan struct on or off */
  191. #define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \
  192. static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
  193. static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
  194. static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
  195. batadv_store_vlan_##_name)
  196. static int batadv_store_bool_attr(char *buff, size_t count,
  197. struct net_device *net_dev,
  198. const char *attr_name, atomic_t *attr)
  199. {
  200. int enabled = -1;
  201. if (buff[count - 1] == '\n')
  202. buff[count - 1] = '\0';
  203. if ((strncmp(buff, "1", 2) == 0) ||
  204. (strncmp(buff, "enable", 7) == 0) ||
  205. (strncmp(buff, "enabled", 8) == 0))
  206. enabled = 1;
  207. if ((strncmp(buff, "0", 2) == 0) ||
  208. (strncmp(buff, "disable", 8) == 0) ||
  209. (strncmp(buff, "disabled", 9) == 0))
  210. enabled = 0;
  211. if (enabled < 0) {
  212. batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
  213. attr_name, buff);
  214. return -EINVAL;
  215. }
  216. if (atomic_read(attr) == enabled)
  217. return count;
  218. batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name,
  219. atomic_read(attr) == 1 ? "enabled" : "disabled",
  220. enabled == 1 ? "enabled" : "disabled");
  221. atomic_set(attr, (unsigned int)enabled);
  222. return count;
  223. }
  224. static inline ssize_t
  225. __batadv_store_bool_attr(char *buff, size_t count,
  226. void (*post_func)(struct net_device *),
  227. struct attribute *attr,
  228. atomic_t *attr_store, struct net_device *net_dev)
  229. {
  230. int ret;
  231. ret = batadv_store_bool_attr(buff, count, net_dev, attr->name,
  232. attr_store);
  233. if (post_func && ret)
  234. post_func(net_dev);
  235. return ret;
  236. }
  237. static int batadv_store_uint_attr(const char *buff, size_t count,
  238. struct net_device *net_dev,
  239. const char *attr_name,
  240. unsigned int min, unsigned int max,
  241. atomic_t *attr)
  242. {
  243. unsigned long uint_val;
  244. int ret;
  245. ret = kstrtoul(buff, 10, &uint_val);
  246. if (ret) {
  247. batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
  248. attr_name, buff);
  249. return -EINVAL;
  250. }
  251. if (uint_val < min) {
  252. batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n",
  253. attr_name, uint_val, min);
  254. return -EINVAL;
  255. }
  256. if (uint_val > max) {
  257. batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n",
  258. attr_name, uint_val, max);
  259. return -EINVAL;
  260. }
  261. if (atomic_read(attr) == uint_val)
  262. return count;
  263. batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
  264. attr_name, atomic_read(attr), uint_val);
  265. atomic_set(attr, uint_val);
  266. return count;
  267. }
  268. static inline ssize_t
  269. __batadv_store_uint_attr(const char *buff, size_t count,
  270. int min, int max,
  271. void (*post_func)(struct net_device *),
  272. const struct attribute *attr,
  273. atomic_t *attr_store, struct net_device *net_dev)
  274. {
  275. int ret;
  276. ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
  277. attr_store);
  278. if (post_func && ret)
  279. post_func(net_dev);
  280. return ret;
  281. }
  282. static ssize_t batadv_show_bat_algo(struct kobject *kobj,
  283. struct attribute *attr, char *buff)
  284. {
  285. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
  286. return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name);
  287. }
  288. static void batadv_post_gw_reselect(struct net_device *net_dev)
  289. {
  290. struct batadv_priv *bat_priv = netdev_priv(net_dev);
  291. batadv_gw_reselect(bat_priv);
  292. }
  293. static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
  294. char *buff)
  295. {
  296. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
  297. int bytes_written;
  298. switch (atomic_read(&bat_priv->gw_mode)) {
  299. case BATADV_GW_MODE_CLIENT:
  300. bytes_written = sprintf(buff, "%s\n",
  301. BATADV_GW_MODE_CLIENT_NAME);
  302. break;
  303. case BATADV_GW_MODE_SERVER:
  304. bytes_written = sprintf(buff, "%s\n",
  305. BATADV_GW_MODE_SERVER_NAME);
  306. break;
  307. default:
  308. bytes_written = sprintf(buff, "%s\n",
  309. BATADV_GW_MODE_OFF_NAME);
  310. break;
  311. }
  312. return bytes_written;
  313. }
  314. static ssize_t batadv_store_gw_mode(struct kobject *kobj,
  315. struct attribute *attr, char *buff,
  316. size_t count)
  317. {
  318. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  319. struct batadv_priv *bat_priv = netdev_priv(net_dev);
  320. char *curr_gw_mode_str;
  321. int gw_mode_tmp = -1;
  322. if (buff[count - 1] == '\n')
  323. buff[count - 1] = '\0';
  324. if (strncmp(buff, BATADV_GW_MODE_OFF_NAME,
  325. strlen(BATADV_GW_MODE_OFF_NAME)) == 0)
  326. gw_mode_tmp = BATADV_GW_MODE_OFF;
  327. if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME,
  328. strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0)
  329. gw_mode_tmp = BATADV_GW_MODE_CLIENT;
  330. if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME,
  331. strlen(BATADV_GW_MODE_SERVER_NAME)) == 0)
  332. gw_mode_tmp = BATADV_GW_MODE_SERVER;
  333. if (gw_mode_tmp < 0) {
  334. batadv_info(net_dev,
  335. "Invalid parameter for 'gw mode' setting received: %s\n",
  336. buff);
  337. return -EINVAL;
  338. }
  339. if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp)
  340. return count;
  341. switch (atomic_read(&bat_priv->gw_mode)) {
  342. case BATADV_GW_MODE_CLIENT:
  343. curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
  344. break;
  345. case BATADV_GW_MODE_SERVER:
  346. curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME;
  347. break;
  348. default:
  349. curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME;
  350. break;
  351. }
  352. batadv_info(net_dev, "Changing gw mode from: %s to: %s\n",
  353. curr_gw_mode_str, buff);
  354. /* Invoking batadv_gw_reselect() is not enough to really de-select the
  355. * current GW. It will only instruct the gateway client code to perform
  356. * a re-election the next time that this is needed.
  357. *
  358. * When gw client mode is being switched off the current GW must be
  359. * de-selected explicitly otherwise no GW_ADD uevent is thrown on
  360. * client mode re-activation. This is operation is performed in
  361. * batadv_gw_check_client_stop().
  362. */
  363. batadv_gw_reselect(bat_priv);
  364. /* always call batadv_gw_check_client_stop() before changing the gateway
  365. * state
  366. */
  367. batadv_gw_check_client_stop(bat_priv);
  368. atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
  369. batadv_gw_tvlv_container_update(bat_priv);
  370. return count;
  371. }
  372. static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
  373. struct attribute *attr, char *buff)
  374. {
  375. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
  376. uint32_t down, up;
  377. down = atomic_read(&bat_priv->gw.bandwidth_down);
  378. up = atomic_read(&bat_priv->gw.bandwidth_up);
  379. return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
  380. down % 10, up / 10, up % 10);
  381. }
  382. static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
  383. struct attribute *attr, char *buff,
  384. size_t count)
  385. {
  386. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  387. if (buff[count - 1] == '\n')
  388. buff[count - 1] = '\0';
  389. return batadv_gw_bandwidth_set(net_dev, buff, count);
  390. }
  391. /**
  392. * batadv_show_isolation_mark - print the current isolation mark/mask
  393. * @kobj: kobject representing the private mesh sysfs directory
  394. * @attr: the batman-adv attribute the user is interacting with
  395. * @buff: the buffer that will contain the data to send back to the user
  396. *
  397. * Returns the number of bytes written into 'buff' on success or a negative
  398. * error code in case of failure
  399. */
  400. static ssize_t batadv_show_isolation_mark(struct kobject *kobj,
  401. struct attribute *attr, char *buff)
  402. {
  403. struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
  404. return sprintf(buff, "%#.8x/%#.8x\n", bat_priv->isolation_mark,
  405. bat_priv->isolation_mark_mask);
  406. }
  407. /**
  408. * batadv_store_isolation_mark - parse and store the isolation mark/mask entered
  409. * by the user
  410. * @kobj: kobject representing the private mesh sysfs directory
  411. * @attr: the batman-adv attribute the user is interacting with
  412. * @buff: the buffer containing the user data
  413. * @count: number of bytes in the buffer
  414. *
  415. * Returns 'count' on success or a negative error code in case of failure
  416. */
  417. static ssize_t batadv_store_isolation_mark(struct kobject *kobj,
  418. struct attribute *attr, char *buff,
  419. size_t count)
  420. {
  421. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  422. struct batadv_priv *bat_priv = netdev_priv(net_dev);
  423. uint32_t mark, mask;
  424. char *mask_ptr;
  425. /* parse the mask if it has been specified, otherwise assume the mask is
  426. * the biggest possible
  427. */
  428. mask = 0xFFFFFFFF;
  429. mask_ptr = strchr(buff, '/');
  430. if (mask_ptr) {
  431. *mask_ptr = '\0';
  432. mask_ptr++;
  433. /* the mask must be entered in hex base as it is going to be a
  434. * bitmask and not a prefix length
  435. */
  436. if (kstrtou32(mask_ptr, 16, &mask) < 0)
  437. return -EINVAL;
  438. }
  439. /* the mark can be entered in any base */
  440. if (kstrtou32(buff, 0, &mark) < 0)
  441. return -EINVAL;
  442. bat_priv->isolation_mark_mask = mask;
  443. /* erase bits not covered by the mask */
  444. bat_priv->isolation_mark = mark & bat_priv->isolation_mark_mask;
  445. batadv_info(net_dev,
  446. "New skb mark for extended isolation: %#.8x/%#.8x\n",
  447. bat_priv->isolation_mark, bat_priv->isolation_mark_mask);
  448. return count;
  449. }
  450. BATADV_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
  451. BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
  452. #ifdef CONFIG_BATMAN_ADV_BLA
  453. BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
  454. #endif
  455. #ifdef CONFIG_BATMAN_ADV_DAT
  456. BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
  457. batadv_dat_status_update);
  458. #endif
  459. BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
  460. static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
  461. static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
  462. batadv_store_gw_mode);
  463. BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * BATADV_JITTER,
  464. INT_MAX, NULL);
  465. BATADV_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, BATADV_TQ_MAX_VALUE,
  466. NULL);
  467. BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE,
  468. batadv_post_gw_reselect);
  469. static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
  470. batadv_store_gw_bwidth);
  471. #ifdef CONFIG_BATMAN_ADV_MCAST
  472. BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL);
  473. #endif
  474. #ifdef CONFIG_BATMAN_ADV_DEBUG
  475. BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
  476. #endif
  477. #ifdef CONFIG_BATMAN_ADV_NC
  478. BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR,
  479. batadv_nc_status_update);
  480. #endif
  481. static BATADV_ATTR(isolation_mark, S_IRUGO | S_IWUSR,
  482. batadv_show_isolation_mark, batadv_store_isolation_mark);
  483. static struct batadv_attribute *batadv_mesh_attrs[] = {
  484. &batadv_attr_aggregated_ogms,
  485. &batadv_attr_bonding,
  486. #ifdef CONFIG_BATMAN_ADV_BLA
  487. &batadv_attr_bridge_loop_avoidance,
  488. #endif
  489. #ifdef CONFIG_BATMAN_ADV_DAT
  490. &batadv_attr_distributed_arp_table,
  491. #endif
  492. #ifdef CONFIG_BATMAN_ADV_MCAST
  493. &batadv_attr_multicast_mode,
  494. #endif
  495. &batadv_attr_fragmentation,
  496. &batadv_attr_routing_algo,
  497. &batadv_attr_gw_mode,
  498. &batadv_attr_orig_interval,
  499. &batadv_attr_hop_penalty,
  500. &batadv_attr_gw_sel_class,
  501. &batadv_attr_gw_bandwidth,
  502. #ifdef CONFIG_BATMAN_ADV_DEBUG
  503. &batadv_attr_log_level,
  504. #endif
  505. #ifdef CONFIG_BATMAN_ADV_NC
  506. &batadv_attr_network_coding,
  507. #endif
  508. &batadv_attr_isolation_mark,
  509. NULL,
  510. };
  511. BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
  512. /**
  513. * batadv_vlan_attrs - array of vlan specific sysfs attributes
  514. */
  515. static struct batadv_attribute *batadv_vlan_attrs[] = {
  516. &batadv_attr_vlan_ap_isolation,
  517. NULL,
  518. };
  519. int batadv_sysfs_add_meshif(struct net_device *dev)
  520. {
  521. struct kobject *batif_kobject = &dev->dev.kobj;
  522. struct batadv_priv *bat_priv = netdev_priv(dev);
  523. struct batadv_attribute **bat_attr;
  524. int err;
  525. bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR,
  526. batif_kobject);
  527. if (!bat_priv->mesh_obj) {
  528. batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
  529. BATADV_SYSFS_IF_MESH_SUBDIR);
  530. goto out;
  531. }
  532. for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) {
  533. err = sysfs_create_file(bat_priv->mesh_obj,
  534. &((*bat_attr)->attr));
  535. if (err) {
  536. batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
  537. dev->name, BATADV_SYSFS_IF_MESH_SUBDIR,
  538. ((*bat_attr)->attr).name);
  539. goto rem_attr;
  540. }
  541. }
  542. return 0;
  543. rem_attr:
  544. for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
  545. sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
  546. kobject_put(bat_priv->mesh_obj);
  547. bat_priv->mesh_obj = NULL;
  548. out:
  549. return -ENOMEM;
  550. }
  551. void batadv_sysfs_del_meshif(struct net_device *dev)
  552. {
  553. struct batadv_priv *bat_priv = netdev_priv(dev);
  554. struct batadv_attribute **bat_attr;
  555. for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
  556. sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
  557. kobject_put(bat_priv->mesh_obj);
  558. bat_priv->mesh_obj = NULL;
  559. }
  560. /**
  561. * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
  562. * @dev: netdev of the mesh interface
  563. * @vlan: private data of the newly added VLAN interface
  564. *
  565. * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
  566. */
  567. int batadv_sysfs_add_vlan(struct net_device *dev,
  568. struct batadv_softif_vlan *vlan)
  569. {
  570. char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
  571. struct batadv_priv *bat_priv = netdev_priv(dev);
  572. struct batadv_attribute **bat_attr;
  573. int err;
  574. if (vlan->vid & BATADV_VLAN_HAS_TAG) {
  575. sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
  576. vlan->vid & VLAN_VID_MASK);
  577. vlan->kobj = kobject_create_and_add(vlan_subdir,
  578. bat_priv->mesh_obj);
  579. if (!vlan->kobj) {
  580. batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
  581. dev->name, vlan_subdir);
  582. goto out;
  583. }
  584. } else {
  585. /* the untagged LAN uses the root folder to store its "VLAN
  586. * specific attributes"
  587. */
  588. vlan->kobj = bat_priv->mesh_obj;
  589. kobject_get(bat_priv->mesh_obj);
  590. }
  591. for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
  592. err = sysfs_create_file(vlan->kobj,
  593. &((*bat_attr)->attr));
  594. if (err) {
  595. batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
  596. dev->name, vlan_subdir,
  597. ((*bat_attr)->attr).name);
  598. goto rem_attr;
  599. }
  600. }
  601. return 0;
  602. rem_attr:
  603. for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
  604. sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
  605. kobject_put(vlan->kobj);
  606. vlan->kobj = NULL;
  607. out:
  608. return -ENOMEM;
  609. }
  610. /**
  611. * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
  612. * @bat_priv: the bat priv with all the soft interface information
  613. * @vlan: the private data of the VLAN to destroy
  614. */
  615. void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
  616. struct batadv_softif_vlan *vlan)
  617. {
  618. struct batadv_attribute **bat_attr;
  619. for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
  620. sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
  621. kobject_put(vlan->kobj);
  622. vlan->kobj = NULL;
  623. }
  624. static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
  625. struct attribute *attr, char *buff)
  626. {
  627. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  628. struct batadv_hard_iface *hard_iface;
  629. ssize_t length;
  630. const char *ifname;
  631. hard_iface = batadv_hardif_get_by_netdev(net_dev);
  632. if (!hard_iface)
  633. return 0;
  634. if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
  635. ifname = "none";
  636. else
  637. ifname = hard_iface->soft_iface->name;
  638. length = sprintf(buff, "%s\n", ifname);
  639. batadv_hardif_free_ref(hard_iface);
  640. return length;
  641. }
  642. static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
  643. struct attribute *attr, char *buff,
  644. size_t count)
  645. {
  646. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  647. struct batadv_hard_iface *hard_iface;
  648. int status_tmp = -1;
  649. int ret = count;
  650. hard_iface = batadv_hardif_get_by_netdev(net_dev);
  651. if (!hard_iface)
  652. return count;
  653. if (buff[count - 1] == '\n')
  654. buff[count - 1] = '\0';
  655. if (strlen(buff) >= IFNAMSIZ) {
  656. pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
  657. buff);
  658. batadv_hardif_free_ref(hard_iface);
  659. return -EINVAL;
  660. }
  661. if (strncmp(buff, "none", 4) == 0)
  662. status_tmp = BATADV_IF_NOT_IN_USE;
  663. else
  664. status_tmp = BATADV_IF_I_WANT_YOU;
  665. if (hard_iface->if_status == status_tmp)
  666. goto out;
  667. if ((hard_iface->soft_iface) &&
  668. (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
  669. goto out;
  670. rtnl_lock();
  671. if (status_tmp == BATADV_IF_NOT_IN_USE) {
  672. batadv_hardif_disable_interface(hard_iface,
  673. BATADV_IF_CLEANUP_AUTO);
  674. goto unlock;
  675. }
  676. /* if the interface already is in use */
  677. if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
  678. batadv_hardif_disable_interface(hard_iface,
  679. BATADV_IF_CLEANUP_AUTO);
  680. ret = batadv_hardif_enable_interface(hard_iface, buff);
  681. unlock:
  682. rtnl_unlock();
  683. out:
  684. batadv_hardif_free_ref(hard_iface);
  685. return ret;
  686. }
  687. static ssize_t batadv_show_iface_status(struct kobject *kobj,
  688. struct attribute *attr, char *buff)
  689. {
  690. struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
  691. struct batadv_hard_iface *hard_iface;
  692. ssize_t length;
  693. hard_iface = batadv_hardif_get_by_netdev(net_dev);
  694. if (!hard_iface)
  695. return 0;
  696. switch (hard_iface->if_status) {
  697. case BATADV_IF_TO_BE_REMOVED:
  698. length = sprintf(buff, "disabling\n");
  699. break;
  700. case BATADV_IF_INACTIVE:
  701. length = sprintf(buff, "inactive\n");
  702. break;
  703. case BATADV_IF_ACTIVE:
  704. length = sprintf(buff, "active\n");
  705. break;
  706. case BATADV_IF_TO_BE_ACTIVATED:
  707. length = sprintf(buff, "enabling\n");
  708. break;
  709. case BATADV_IF_NOT_IN_USE:
  710. default:
  711. length = sprintf(buff, "not in use\n");
  712. break;
  713. }
  714. batadv_hardif_free_ref(hard_iface);
  715. return length;
  716. }
  717. static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
  718. batadv_store_mesh_iface);
  719. static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
  720. static struct batadv_attribute *batadv_batman_attrs[] = {
  721. &batadv_attr_mesh_iface,
  722. &batadv_attr_iface_status,
  723. NULL,
  724. };
  725. int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
  726. {
  727. struct kobject *hardif_kobject = &dev->dev.kobj;
  728. struct batadv_attribute **bat_attr;
  729. int err;
  730. *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR,
  731. hardif_kobject);
  732. if (!*hardif_obj) {
  733. batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
  734. BATADV_SYSFS_IF_BAT_SUBDIR);
  735. goto out;
  736. }
  737. for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) {
  738. err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
  739. if (err) {
  740. batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
  741. dev->name, BATADV_SYSFS_IF_BAT_SUBDIR,
  742. ((*bat_attr)->attr).name);
  743. goto rem_attr;
  744. }
  745. }
  746. return 0;
  747. rem_attr:
  748. for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr)
  749. sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
  750. out:
  751. return -ENOMEM;
  752. }
  753. void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
  754. {
  755. kobject_put(*hardif_obj);
  756. *hardif_obj = NULL;
  757. }
  758. int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
  759. enum batadv_uev_action action, const char *data)
  760. {
  761. int ret = -ENOMEM;
  762. struct kobject *bat_kobj;
  763. char *uevent_env[4] = { NULL, NULL, NULL, NULL };
  764. bat_kobj = &bat_priv->soft_iface->dev.kobj;
  765. uevent_env[0] = kasprintf(GFP_ATOMIC,
  766. "%s%s", BATADV_UEV_TYPE_VAR,
  767. batadv_uev_type_str[type]);
  768. if (!uevent_env[0])
  769. goto out;
  770. uevent_env[1] = kasprintf(GFP_ATOMIC,
  771. "%s%s", BATADV_UEV_ACTION_VAR,
  772. batadv_uev_action_str[action]);
  773. if (!uevent_env[1])
  774. goto out;
  775. /* If the event is DEL, ignore the data field */
  776. if (action != BATADV_UEV_DEL) {
  777. uevent_env[2] = kasprintf(GFP_ATOMIC,
  778. "%s%s", BATADV_UEV_DATA_VAR, data);
  779. if (!uevent_env[2])
  780. goto out;
  781. }
  782. ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
  783. out:
  784. kfree(uevent_env[0]);
  785. kfree(uevent_env[1]);
  786. kfree(uevent_env[2]);
  787. if (ret)
  788. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  789. "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
  790. batadv_uev_type_str[type],
  791. batadv_uev_action_str[action],
  792. (action == BATADV_UEV_DEL ? "NULL" : data), ret);
  793. return ret;
  794. }