netlink.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (C) B.A.T.M.A.N. contributors:
  3. *
  4. * Matthias Schiffer
  5. */
  6. #include "netlink.h"
  7. #include "main.h"
  8. #include <linux/array_size.h>
  9. #include <linux/atomic.h>
  10. #include <linux/bitops.h>
  11. #include <linux/bug.h>
  12. #include <linux/byteorder/generic.h>
  13. #include <linux/cache.h>
  14. #include <linux/err.h>
  15. #include <linux/errno.h>
  16. #include <linux/gfp.h>
  17. #include <linux/if_ether.h>
  18. #include <linux/if_vlan.h>
  19. #include <linux/init.h>
  20. #include <linux/limits.h>
  21. #include <linux/list.h>
  22. #include <linux/minmax.h>
  23. #include <linux/netdevice.h>
  24. #include <linux/netlink.h>
  25. #include <linux/printk.h>
  26. #include <linux/rtnetlink.h>
  27. #include <linux/skbuff.h>
  28. #include <linux/stddef.h>
  29. #include <linux/types.h>
  30. #include <net/genetlink.h>
  31. #include <net/net_namespace.h>
  32. #include <net/netlink.h>
  33. #include <net/sock.h>
  34. #include <uapi/linux/batadv_packet.h>
  35. #include <uapi/linux/batman_adv.h>
  36. #include "bat_algo.h"
  37. #include "bridge_loop_avoidance.h"
  38. #include "distributed-arp-table.h"
  39. #include "gateway_client.h"
  40. #include "gateway_common.h"
  41. #include "hard-interface.h"
  42. #include "log.h"
  43. #include "multicast.h"
  44. #include "network-coding.h"
  45. #include "originator.h"
  46. #include "soft-interface.h"
  47. #include "tp_meter.h"
  48. #include "translation-table.h"
  49. struct genl_family batadv_netlink_family;
  50. /* multicast groups */
  51. enum batadv_netlink_multicast_groups {
  52. BATADV_NL_MCGRP_CONFIG,
  53. BATADV_NL_MCGRP_TPMETER,
  54. };
  55. /**
  56. * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags
  57. */
  58. enum batadv_genl_ops_flags {
  59. /**
  60. * @BATADV_FLAG_NEED_MESH: request requires valid soft interface in
  61. * attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be
  62. * saved in info->user_ptr[0]
  63. */
  64. BATADV_FLAG_NEED_MESH = BIT(0),
  65. /**
  66. * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in
  67. * attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be
  68. * saved in info->user_ptr[1]
  69. */
  70. BATADV_FLAG_NEED_HARDIF = BIT(1),
  71. /**
  72. * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in
  73. * attribute BATADV_ATTR_VLANID and expects a pointer to it to be
  74. * saved in info->user_ptr[1]
  75. */
  76. BATADV_FLAG_NEED_VLAN = BIT(2),
  77. };
  78. static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
  79. [BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG },
  80. [BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
  81. };
  82. static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
  83. [BATADV_ATTR_VERSION] = { .type = NLA_STRING },
  84. [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING },
  85. [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 },
  86. [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING },
  87. [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN },
  88. [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 },
  89. [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING },
  90. [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN },
  91. [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN },
  92. [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 },
  93. [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 },
  94. [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 },
  95. [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 },
  96. [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG },
  97. [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN },
  98. [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 },
  99. [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 },
  100. [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 },
  101. [BATADV_ATTR_TT_VID] = { .type = NLA_U16 },
  102. [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 },
  103. [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG },
  104. [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 },
  105. [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN },
  106. [BATADV_ATTR_TQ] = { .type = NLA_U8 },
  107. [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 },
  108. [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 },
  109. [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 },
  110. [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN },
  111. [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG },
  112. [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN },
  113. [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 },
  114. [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN },
  115. [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 },
  116. [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NLA_U32 },
  117. [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .len = ETH_ALEN },
  118. [BATADV_ATTR_DAT_CACHE_VID] = { .type = NLA_U16 },
  119. [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 },
  120. [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 },
  121. [BATADV_ATTR_VLANID] = { .type = NLA_U16 },
  122. [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NLA_U8 },
  123. [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NLA_U8 },
  124. [BATADV_ATTR_ISOLATION_MARK] = { .type = NLA_U32 },
  125. [BATADV_ATTR_ISOLATION_MASK] = { .type = NLA_U32 },
  126. [BATADV_ATTR_BONDING_ENABLED] = { .type = NLA_U8 },
  127. [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NLA_U8 },
  128. [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NLA_U8 },
  129. [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NLA_U8 },
  130. [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NLA_U32 },
  131. [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NLA_U32 },
  132. [BATADV_ATTR_GW_MODE] = { .type = NLA_U8 },
  133. [BATADV_ATTR_GW_SEL_CLASS] = { .type = NLA_U32 },
  134. [BATADV_ATTR_HOP_PENALTY] = { .type = NLA_U8 },
  135. [BATADV_ATTR_LOG_LEVEL] = { .type = NLA_U32 },
  136. [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NLA_U8 },
  137. [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NLA_U32 },
  138. [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NLA_U8 },
  139. [BATADV_ATTR_ORIG_INTERVAL] = { .type = NLA_U32 },
  140. [BATADV_ATTR_ELP_INTERVAL] = { .type = NLA_U32 },
  141. [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NLA_U32 },
  142. };
  143. /**
  144. * batadv_netlink_get_ifindex() - Extract an interface index from a message
  145. * @nlh: Message header
  146. * @attrtype: Attribute which holds an interface index
  147. *
  148. * Return: interface index, or 0.
  149. */
  150. int
  151. batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
  152. {
  153. struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
  154. return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0;
  155. }
  156. /**
  157. * batadv_netlink_mesh_fill_ap_isolation() - Add ap_isolation softif attribute
  158. * @msg: Netlink message to dump into
  159. * @bat_priv: the bat priv with all the soft interface information
  160. *
  161. * Return: 0 on success or negative error number in case of failure
  162. */
  163. static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg,
  164. struct batadv_priv *bat_priv)
  165. {
  166. struct batadv_softif_vlan *vlan;
  167. u8 ap_isolation;
  168. vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
  169. if (!vlan)
  170. return 0;
  171. ap_isolation = atomic_read(&vlan->ap_isolation);
  172. batadv_softif_vlan_put(vlan);
  173. return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
  174. !!ap_isolation);
  175. }
  176. /**
  177. * batadv_netlink_set_mesh_ap_isolation() - Set ap_isolation from genl msg
  178. * @attr: parsed BATADV_ATTR_AP_ISOLATION_ENABLED attribute
  179. * @bat_priv: the bat priv with all the soft interface information
  180. *
  181. * Return: 0 on success or negative error number in case of failure
  182. */
  183. static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr,
  184. struct batadv_priv *bat_priv)
  185. {
  186. struct batadv_softif_vlan *vlan;
  187. vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
  188. if (!vlan)
  189. return -ENOENT;
  190. atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
  191. batadv_softif_vlan_put(vlan);
  192. return 0;
  193. }
  194. /**
  195. * batadv_netlink_mesh_fill() - Fill message with mesh attributes
  196. * @msg: Netlink message to dump into
  197. * @bat_priv: the bat priv with all the soft interface information
  198. * @cmd: type of message to generate
  199. * @portid: Port making netlink request
  200. * @seq: sequence number for message
  201. * @flags: Additional flags for message
  202. *
  203. * Return: 0 on success or negative error number in case of failure
  204. */
  205. static int batadv_netlink_mesh_fill(struct sk_buff *msg,
  206. struct batadv_priv *bat_priv,
  207. enum batadv_nl_commands cmd,
  208. u32 portid, u32 seq, int flags)
  209. {
  210. struct net_device *soft_iface = bat_priv->soft_iface;
  211. struct batadv_hard_iface *primary_if = NULL;
  212. struct net_device *hard_iface;
  213. void *hdr;
  214. hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
  215. if (!hdr)
  216. return -ENOBUFS;
  217. if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) ||
  218. nla_put_string(msg, BATADV_ATTR_ALGO_NAME,
  219. bat_priv->algo_ops->name) ||
  220. nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, soft_iface->ifindex) ||
  221. nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, soft_iface->name) ||
  222. nla_put(msg, BATADV_ATTR_MESH_ADDRESS, ETH_ALEN,
  223. soft_iface->dev_addr) ||
  224. nla_put_u8(msg, BATADV_ATTR_TT_TTVN,
  225. (u8)atomic_read(&bat_priv->tt.vn)))
  226. goto nla_put_failure;
  227. #ifdef CONFIG_BATMAN_ADV_BLA
  228. if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
  229. ntohs(bat_priv->bla.claim_dest.group)))
  230. goto nla_put_failure;
  231. #endif
  232. if (batadv_mcast_mesh_info_put(msg, bat_priv))
  233. goto nla_put_failure;
  234. primary_if = batadv_primary_if_get_selected(bat_priv);
  235. if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) {
  236. hard_iface = primary_if->net_dev;
  237. if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
  238. hard_iface->ifindex) ||
  239. nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
  240. hard_iface->name) ||
  241. nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
  242. hard_iface->dev_addr))
  243. goto nla_put_failure;
  244. }
  245. if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED,
  246. !!atomic_read(&bat_priv->aggregated_ogms)))
  247. goto nla_put_failure;
  248. if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv))
  249. goto nla_put_failure;
  250. if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK,
  251. bat_priv->isolation_mark))
  252. goto nla_put_failure;
  253. if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK,
  254. bat_priv->isolation_mark_mask))
  255. goto nla_put_failure;
  256. if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED,
  257. !!atomic_read(&bat_priv->bonding)))
  258. goto nla_put_failure;
  259. #ifdef CONFIG_BATMAN_ADV_BLA
  260. if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
  261. !!atomic_read(&bat_priv->bridge_loop_avoidance)))
  262. goto nla_put_failure;
  263. #endif /* CONFIG_BATMAN_ADV_BLA */
  264. #ifdef CONFIG_BATMAN_ADV_DAT
  265. if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
  266. !!atomic_read(&bat_priv->distributed_arp_table)))
  267. goto nla_put_failure;
  268. #endif /* CONFIG_BATMAN_ADV_DAT */
  269. if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED,
  270. !!atomic_read(&bat_priv->fragmentation)))
  271. goto nla_put_failure;
  272. if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN,
  273. atomic_read(&bat_priv->gw.bandwidth_down)))
  274. goto nla_put_failure;
  275. if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP,
  276. atomic_read(&bat_priv->gw.bandwidth_up)))
  277. goto nla_put_failure;
  278. if (nla_put_u8(msg, BATADV_ATTR_GW_MODE,
  279. atomic_read(&bat_priv->gw.mode)))
  280. goto nla_put_failure;
  281. if (bat_priv->algo_ops->gw.get_best_gw_node &&
  282. bat_priv->algo_ops->gw.is_eligible) {
  283. /* GW selection class is not available if the routing algorithm
  284. * in use does not implement the GW API
  285. */
  286. if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS,
  287. atomic_read(&bat_priv->gw.sel_class)))
  288. goto nla_put_failure;
  289. }
  290. if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
  291. atomic_read(&bat_priv->hop_penalty)))
  292. goto nla_put_failure;
  293. #ifdef CONFIG_BATMAN_ADV_DEBUG
  294. if (nla_put_u32(msg, BATADV_ATTR_LOG_LEVEL,
  295. atomic_read(&bat_priv->log_level)))
  296. goto nla_put_failure;
  297. #endif /* CONFIG_BATMAN_ADV_DEBUG */
  298. #ifdef CONFIG_BATMAN_ADV_MCAST
  299. if (nla_put_u8(msg, BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED,
  300. !atomic_read(&bat_priv->multicast_mode)))
  301. goto nla_put_failure;
  302. if (nla_put_u32(msg, BATADV_ATTR_MULTICAST_FANOUT,
  303. atomic_read(&bat_priv->multicast_fanout)))
  304. goto nla_put_failure;
  305. #endif /* CONFIG_BATMAN_ADV_MCAST */
  306. #ifdef CONFIG_BATMAN_ADV_NC
  307. if (nla_put_u8(msg, BATADV_ATTR_NETWORK_CODING_ENABLED,
  308. !!atomic_read(&bat_priv->network_coding)))
  309. goto nla_put_failure;
  310. #endif /* CONFIG_BATMAN_ADV_NC */
  311. if (nla_put_u32(msg, BATADV_ATTR_ORIG_INTERVAL,
  312. atomic_read(&bat_priv->orig_interval)))
  313. goto nla_put_failure;
  314. batadv_hardif_put(primary_if);
  315. genlmsg_end(msg, hdr);
  316. return 0;
  317. nla_put_failure:
  318. batadv_hardif_put(primary_if);
  319. genlmsg_cancel(msg, hdr);
  320. return -EMSGSIZE;
  321. }
  322. /**
  323. * batadv_netlink_notify_mesh() - send softif attributes to listener
  324. * @bat_priv: the bat priv with all the soft interface information
  325. *
  326. * Return: 0 on success, < 0 on error
  327. */
  328. static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv)
  329. {
  330. struct sk_buff *msg;
  331. int ret;
  332. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  333. if (!msg)
  334. return -ENOMEM;
  335. ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_SET_MESH,
  336. 0, 0, 0);
  337. if (ret < 0) {
  338. nlmsg_free(msg);
  339. return ret;
  340. }
  341. genlmsg_multicast_netns(&batadv_netlink_family,
  342. dev_net(bat_priv->soft_iface), msg, 0,
  343. BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
  344. return 0;
  345. }
  346. /**
  347. * batadv_netlink_get_mesh() - Get softif attributes
  348. * @skb: Netlink message with request data
  349. * @info: receiver information
  350. *
  351. * Return: 0 on success or negative error number in case of failure
  352. */
  353. static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info)
  354. {
  355. struct batadv_priv *bat_priv = info->user_ptr[0];
  356. struct sk_buff *msg;
  357. int ret;
  358. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  359. if (!msg)
  360. return -ENOMEM;
  361. ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_GET_MESH,
  362. info->snd_portid, info->snd_seq, 0);
  363. if (ret < 0) {
  364. nlmsg_free(msg);
  365. return ret;
  366. }
  367. ret = genlmsg_reply(msg, info);
  368. return ret;
  369. }
  370. /**
  371. * batadv_netlink_set_mesh() - Set softif attributes
  372. * @skb: Netlink message with request data
  373. * @info: receiver information
  374. *
  375. * Return: 0 on success or negative error number in case of failure
  376. */
  377. static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
  378. {
  379. struct batadv_priv *bat_priv = info->user_ptr[0];
  380. struct nlattr *attr;
  381. if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) {
  382. attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED];
  383. atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr));
  384. }
  385. if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
  386. attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED];
  387. batadv_netlink_set_mesh_ap_isolation(attr, bat_priv);
  388. }
  389. if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) {
  390. attr = info->attrs[BATADV_ATTR_ISOLATION_MARK];
  391. bat_priv->isolation_mark = nla_get_u32(attr);
  392. }
  393. if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) {
  394. attr = info->attrs[BATADV_ATTR_ISOLATION_MASK];
  395. bat_priv->isolation_mark_mask = nla_get_u32(attr);
  396. }
  397. if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) {
  398. attr = info->attrs[BATADV_ATTR_BONDING_ENABLED];
  399. atomic_set(&bat_priv->bonding, !!nla_get_u8(attr));
  400. }
  401. #ifdef CONFIG_BATMAN_ADV_BLA
  402. if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]) {
  403. attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED];
  404. atomic_set(&bat_priv->bridge_loop_avoidance,
  405. !!nla_get_u8(attr));
  406. batadv_bla_status_update(bat_priv->soft_iface);
  407. }
  408. #endif /* CONFIG_BATMAN_ADV_BLA */
  409. #ifdef CONFIG_BATMAN_ADV_DAT
  410. if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]) {
  411. attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED];
  412. atomic_set(&bat_priv->distributed_arp_table,
  413. !!nla_get_u8(attr));
  414. batadv_dat_status_update(bat_priv->soft_iface);
  415. }
  416. #endif /* CONFIG_BATMAN_ADV_DAT */
  417. if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) {
  418. attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
  419. atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
  420. rtnl_lock();
  421. batadv_update_min_mtu(bat_priv->soft_iface);
  422. rtnl_unlock();
  423. }
  424. if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
  425. attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN];
  426. atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr));
  427. batadv_gw_tvlv_container_update(bat_priv);
  428. }
  429. if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) {
  430. attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP];
  431. atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr));
  432. batadv_gw_tvlv_container_update(bat_priv);
  433. }
  434. if (info->attrs[BATADV_ATTR_GW_MODE]) {
  435. u8 gw_mode;
  436. attr = info->attrs[BATADV_ATTR_GW_MODE];
  437. gw_mode = nla_get_u8(attr);
  438. if (gw_mode <= BATADV_GW_MODE_SERVER) {
  439. /* Invoking batadv_gw_reselect() is not enough to really
  440. * de-select the current GW. It will only instruct the
  441. * gateway client code to perform a re-election the next
  442. * time that this is needed.
  443. *
  444. * When gw client mode is being switched off the current
  445. * GW must be de-selected explicitly otherwise no GW_ADD
  446. * uevent is thrown on client mode re-activation. This
  447. * is operation is performed in
  448. * batadv_gw_check_client_stop().
  449. */
  450. batadv_gw_reselect(bat_priv);
  451. /* always call batadv_gw_check_client_stop() before
  452. * changing the gateway state
  453. */
  454. batadv_gw_check_client_stop(bat_priv);
  455. atomic_set(&bat_priv->gw.mode, gw_mode);
  456. batadv_gw_tvlv_container_update(bat_priv);
  457. }
  458. }
  459. if (info->attrs[BATADV_ATTR_GW_SEL_CLASS] &&
  460. bat_priv->algo_ops->gw.get_best_gw_node &&
  461. bat_priv->algo_ops->gw.is_eligible) {
  462. /* setting the GW selection class is allowed only if the routing
  463. * algorithm in use implements the GW API
  464. */
  465. u32 sel_class_max = bat_priv->algo_ops->gw.sel_class_max;
  466. u32 sel_class;
  467. attr = info->attrs[BATADV_ATTR_GW_SEL_CLASS];
  468. sel_class = nla_get_u32(attr);
  469. if (sel_class >= 1 && sel_class <= sel_class_max) {
  470. atomic_set(&bat_priv->gw.sel_class, sel_class);
  471. batadv_gw_reselect(bat_priv);
  472. }
  473. }
  474. if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
  475. attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
  476. atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr));
  477. }
  478. #ifdef CONFIG_BATMAN_ADV_DEBUG
  479. if (info->attrs[BATADV_ATTR_LOG_LEVEL]) {
  480. attr = info->attrs[BATADV_ATTR_LOG_LEVEL];
  481. atomic_set(&bat_priv->log_level,
  482. nla_get_u32(attr) & BATADV_DBG_ALL);
  483. }
  484. #endif /* CONFIG_BATMAN_ADV_DEBUG */
  485. #ifdef CONFIG_BATMAN_ADV_MCAST
  486. if (info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]) {
  487. attr = info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED];
  488. atomic_set(&bat_priv->multicast_mode, !nla_get_u8(attr));
  489. }
  490. if (info->attrs[BATADV_ATTR_MULTICAST_FANOUT]) {
  491. attr = info->attrs[BATADV_ATTR_MULTICAST_FANOUT];
  492. atomic_set(&bat_priv->multicast_fanout, nla_get_u32(attr));
  493. }
  494. #endif /* CONFIG_BATMAN_ADV_MCAST */
  495. #ifdef CONFIG_BATMAN_ADV_NC
  496. if (info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]) {
  497. attr = info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED];
  498. atomic_set(&bat_priv->network_coding, !!nla_get_u8(attr));
  499. batadv_nc_status_update(bat_priv->soft_iface);
  500. }
  501. #endif /* CONFIG_BATMAN_ADV_NC */
  502. if (info->attrs[BATADV_ATTR_ORIG_INTERVAL]) {
  503. u32 orig_interval;
  504. attr = info->attrs[BATADV_ATTR_ORIG_INTERVAL];
  505. orig_interval = nla_get_u32(attr);
  506. orig_interval = min_t(u32, orig_interval, INT_MAX);
  507. orig_interval = max_t(u32, orig_interval, 2 * BATADV_JITTER);
  508. atomic_set(&bat_priv->orig_interval, orig_interval);
  509. }
  510. batadv_netlink_notify_mesh(bat_priv);
  511. return 0;
  512. }
  513. /**
  514. * batadv_netlink_tp_meter_put() - Fill information of started tp_meter session
  515. * @msg: netlink message to be sent back
  516. * @cookie: tp meter session cookie
  517. *
  518. * Return: 0 on success, < 0 on error
  519. */
  520. static int
  521. batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie)
  522. {
  523. if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie))
  524. return -ENOBUFS;
  525. return 0;
  526. }
  527. /**
  528. * batadv_netlink_tpmeter_notify() - send tp_meter result via netlink to client
  529. * @bat_priv: the bat priv with all the soft interface information
  530. * @dst: destination of tp_meter session
  531. * @result: reason for tp meter session stop
  532. * @test_time: total time of the tp_meter session
  533. * @total_bytes: bytes acked to the receiver
  534. * @cookie: cookie of tp_meter session
  535. *
  536. * Return: 0 on success, < 0 on error
  537. */
  538. int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst,
  539. u8 result, u32 test_time, u64 total_bytes,
  540. u32 cookie)
  541. {
  542. struct sk_buff *msg;
  543. void *hdr;
  544. int ret;
  545. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  546. if (!msg)
  547. return -ENOMEM;
  548. hdr = genlmsg_put(msg, 0, 0, &batadv_netlink_family, 0,
  549. BATADV_CMD_TP_METER);
  550. if (!hdr) {
  551. ret = -ENOBUFS;
  552. goto err_genlmsg;
  553. }
  554. if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie))
  555. goto nla_put_failure;
  556. if (nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, test_time))
  557. goto nla_put_failure;
  558. if (nla_put_u64_64bit(msg, BATADV_ATTR_TPMETER_BYTES, total_bytes,
  559. BATADV_ATTR_PAD))
  560. goto nla_put_failure;
  561. if (nla_put_u8(msg, BATADV_ATTR_TPMETER_RESULT, result))
  562. goto nla_put_failure;
  563. if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst))
  564. goto nla_put_failure;
  565. genlmsg_end(msg, hdr);
  566. genlmsg_multicast_netns(&batadv_netlink_family,
  567. dev_net(bat_priv->soft_iface), msg, 0,
  568. BATADV_NL_MCGRP_TPMETER, GFP_KERNEL);
  569. return 0;
  570. nla_put_failure:
  571. genlmsg_cancel(msg, hdr);
  572. ret = -EMSGSIZE;
  573. err_genlmsg:
  574. nlmsg_free(msg);
  575. return ret;
  576. }
  577. /**
  578. * batadv_netlink_tp_meter_start() - Start a new tp_meter session
  579. * @skb: received netlink message
  580. * @info: receiver information
  581. *
  582. * Return: 0 on success, < 0 on error
  583. */
  584. static int
  585. batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
  586. {
  587. struct batadv_priv *bat_priv = info->user_ptr[0];
  588. struct sk_buff *msg = NULL;
  589. u32 test_length;
  590. void *msg_head;
  591. u32 cookie;
  592. u8 *dst;
  593. int ret;
  594. if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
  595. return -EINVAL;
  596. if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME])
  597. return -EINVAL;
  598. dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
  599. test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]);
  600. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  601. if (!msg) {
  602. ret = -ENOMEM;
  603. goto out;
  604. }
  605. msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq,
  606. &batadv_netlink_family, 0,
  607. BATADV_CMD_TP_METER);
  608. if (!msg_head) {
  609. ret = -ENOBUFS;
  610. goto out;
  611. }
  612. batadv_tp_start(bat_priv, dst, test_length, &cookie);
  613. ret = batadv_netlink_tp_meter_put(msg, cookie);
  614. out:
  615. if (ret) {
  616. if (msg)
  617. nlmsg_free(msg);
  618. return ret;
  619. }
  620. genlmsg_end(msg, msg_head);
  621. return genlmsg_reply(msg, info);
  622. }
  623. /**
  624. * batadv_netlink_tp_meter_cancel() - Cancel a running tp_meter session
  625. * @skb: received netlink message
  626. * @info: receiver information
  627. *
  628. * Return: 0 on success, < 0 on error
  629. */
  630. static int
  631. batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info)
  632. {
  633. struct batadv_priv *bat_priv = info->user_ptr[0];
  634. u8 *dst;
  635. int ret = 0;
  636. if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
  637. return -EINVAL;
  638. dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
  639. batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL);
  640. return ret;
  641. }
  642. /**
  643. * batadv_netlink_hardif_fill() - Fill message with hardif attributes
  644. * @msg: Netlink message to dump into
  645. * @bat_priv: the bat priv with all the soft interface information
  646. * @hard_iface: hard interface which was modified
  647. * @cmd: type of message to generate
  648. * @portid: Port making netlink request
  649. * @seq: sequence number for message
  650. * @flags: Additional flags for message
  651. * @cb: Control block containing additional options
  652. *
  653. * Return: 0 on success or negative error number in case of failure
  654. */
  655. static int batadv_netlink_hardif_fill(struct sk_buff *msg,
  656. struct batadv_priv *bat_priv,
  657. struct batadv_hard_iface *hard_iface,
  658. enum batadv_nl_commands cmd,
  659. u32 portid, u32 seq, int flags,
  660. struct netlink_callback *cb)
  661. {
  662. struct net_device *net_dev = hard_iface->net_dev;
  663. void *hdr;
  664. hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
  665. if (!hdr)
  666. return -ENOBUFS;
  667. if (cb)
  668. genl_dump_check_consistent(cb, hdr);
  669. if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
  670. bat_priv->soft_iface->ifindex))
  671. goto nla_put_failure;
  672. if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME,
  673. bat_priv->soft_iface->name))
  674. goto nla_put_failure;
  675. if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
  676. net_dev->ifindex) ||
  677. nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
  678. net_dev->name) ||
  679. nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
  680. net_dev->dev_addr))
  681. goto nla_put_failure;
  682. if (hard_iface->if_status == BATADV_IF_ACTIVE) {
  683. if (nla_put_flag(msg, BATADV_ATTR_ACTIVE))
  684. goto nla_put_failure;
  685. }
  686. if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
  687. atomic_read(&hard_iface->hop_penalty)))
  688. goto nla_put_failure;
  689. #ifdef CONFIG_BATMAN_ADV_BATMAN_V
  690. if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
  691. atomic_read(&hard_iface->bat_v.elp_interval)))
  692. goto nla_put_failure;
  693. if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE,
  694. atomic_read(&hard_iface->bat_v.throughput_override)))
  695. goto nla_put_failure;
  696. #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
  697. genlmsg_end(msg, hdr);
  698. return 0;
  699. nla_put_failure:
  700. genlmsg_cancel(msg, hdr);
  701. return -EMSGSIZE;
  702. }
  703. /**
  704. * batadv_netlink_notify_hardif() - send hardif attributes to listener
  705. * @bat_priv: the bat priv with all the soft interface information
  706. * @hard_iface: hard interface which was modified
  707. *
  708. * Return: 0 on success, < 0 on error
  709. */
  710. static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
  711. struct batadv_hard_iface *hard_iface)
  712. {
  713. struct sk_buff *msg;
  714. int ret;
  715. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  716. if (!msg)
  717. return -ENOMEM;
  718. ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
  719. BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL);
  720. if (ret < 0) {
  721. nlmsg_free(msg);
  722. return ret;
  723. }
  724. genlmsg_multicast_netns(&batadv_netlink_family,
  725. dev_net(bat_priv->soft_iface), msg, 0,
  726. BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
  727. return 0;
  728. }
  729. /**
  730. * batadv_netlink_get_hardif() - Get hardif attributes
  731. * @skb: Netlink message with request data
  732. * @info: receiver information
  733. *
  734. * Return: 0 on success or negative error number in case of failure
  735. */
  736. static int batadv_netlink_get_hardif(struct sk_buff *skb,
  737. struct genl_info *info)
  738. {
  739. struct batadv_hard_iface *hard_iface = info->user_ptr[1];
  740. struct batadv_priv *bat_priv = info->user_ptr[0];
  741. struct sk_buff *msg;
  742. int ret;
  743. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  744. if (!msg)
  745. return -ENOMEM;
  746. ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
  747. BATADV_CMD_GET_HARDIF,
  748. info->snd_portid, info->snd_seq, 0,
  749. NULL);
  750. if (ret < 0) {
  751. nlmsg_free(msg);
  752. return ret;
  753. }
  754. ret = genlmsg_reply(msg, info);
  755. return ret;
  756. }
  757. /**
  758. * batadv_netlink_set_hardif() - Set hardif attributes
  759. * @skb: Netlink message with request data
  760. * @info: receiver information
  761. *
  762. * Return: 0 on success or negative error number in case of failure
  763. */
  764. static int batadv_netlink_set_hardif(struct sk_buff *skb,
  765. struct genl_info *info)
  766. {
  767. struct batadv_hard_iface *hard_iface = info->user_ptr[1];
  768. struct batadv_priv *bat_priv = info->user_ptr[0];
  769. struct nlattr *attr;
  770. if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
  771. attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
  772. atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr));
  773. }
  774. #ifdef CONFIG_BATMAN_ADV_BATMAN_V
  775. if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {
  776. attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];
  777. atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr));
  778. }
  779. if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]) {
  780. attr = info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE];
  781. atomic_set(&hard_iface->bat_v.throughput_override,
  782. nla_get_u32(attr));
  783. }
  784. #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
  785. batadv_netlink_notify_hardif(bat_priv, hard_iface);
  786. return 0;
  787. }
  788. /**
  789. * batadv_netlink_dump_hardif() - Dump all hard interface into a messages
  790. * @msg: Netlink message to dump into
  791. * @cb: Parameters from query
  792. *
  793. * Return: error code, or length of reply message on success
  794. */
  795. static int
  796. batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
  797. {
  798. struct net *net = sock_net(cb->skb->sk);
  799. struct net_device *soft_iface;
  800. struct batadv_hard_iface *hard_iface;
  801. struct batadv_priv *bat_priv;
  802. int ifindex;
  803. int portid = NETLINK_CB(cb->skb).portid;
  804. int skip = cb->args[0];
  805. int i = 0;
  806. ifindex = batadv_netlink_get_ifindex(cb->nlh,
  807. BATADV_ATTR_MESH_IFINDEX);
  808. if (!ifindex)
  809. return -EINVAL;
  810. soft_iface = dev_get_by_index(net, ifindex);
  811. if (!soft_iface)
  812. return -ENODEV;
  813. if (!batadv_softif_is_valid(soft_iface)) {
  814. dev_put(soft_iface);
  815. return -ENODEV;
  816. }
  817. bat_priv = netdev_priv(soft_iface);
  818. rtnl_lock();
  819. cb->seq = batadv_hardif_generation << 1 | 1;
  820. list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
  821. if (hard_iface->soft_iface != soft_iface)
  822. continue;
  823. if (i++ < skip)
  824. continue;
  825. if (batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
  826. BATADV_CMD_GET_HARDIF,
  827. portid, cb->nlh->nlmsg_seq,
  828. NLM_F_MULTI, cb)) {
  829. i--;
  830. break;
  831. }
  832. }
  833. rtnl_unlock();
  834. dev_put(soft_iface);
  835. cb->args[0] = i;
  836. return msg->len;
  837. }
  838. /**
  839. * batadv_netlink_vlan_fill() - Fill message with vlan attributes
  840. * @msg: Netlink message to dump into
  841. * @bat_priv: the bat priv with all the soft interface information
  842. * @vlan: vlan which was modified
  843. * @cmd: type of message to generate
  844. * @portid: Port making netlink request
  845. * @seq: sequence number for message
  846. * @flags: Additional flags for message
  847. *
  848. * Return: 0 on success or negative error number in case of failure
  849. */
  850. static int batadv_netlink_vlan_fill(struct sk_buff *msg,
  851. struct batadv_priv *bat_priv,
  852. struct batadv_softif_vlan *vlan,
  853. enum batadv_nl_commands cmd,
  854. u32 portid, u32 seq, int flags)
  855. {
  856. void *hdr;
  857. hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
  858. if (!hdr)
  859. return -ENOBUFS;
  860. if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
  861. bat_priv->soft_iface->ifindex))
  862. goto nla_put_failure;
  863. if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME,
  864. bat_priv->soft_iface->name))
  865. goto nla_put_failure;
  866. if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK))
  867. goto nla_put_failure;
  868. if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
  869. !!atomic_read(&vlan->ap_isolation)))
  870. goto nla_put_failure;
  871. genlmsg_end(msg, hdr);
  872. return 0;
  873. nla_put_failure:
  874. genlmsg_cancel(msg, hdr);
  875. return -EMSGSIZE;
  876. }
  877. /**
  878. * batadv_netlink_notify_vlan() - send vlan attributes to listener
  879. * @bat_priv: the bat priv with all the soft interface information
  880. * @vlan: vlan which was modified
  881. *
  882. * Return: 0 on success, < 0 on error
  883. */
  884. static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
  885. struct batadv_softif_vlan *vlan)
  886. {
  887. struct sk_buff *msg;
  888. int ret;
  889. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  890. if (!msg)
  891. return -ENOMEM;
  892. ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan,
  893. BATADV_CMD_SET_VLAN, 0, 0, 0);
  894. if (ret < 0) {
  895. nlmsg_free(msg);
  896. return ret;
  897. }
  898. genlmsg_multicast_netns(&batadv_netlink_family,
  899. dev_net(bat_priv->soft_iface), msg, 0,
  900. BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
  901. return 0;
  902. }
  903. /**
  904. * batadv_netlink_get_vlan() - Get vlan attributes
  905. * @skb: Netlink message with request data
  906. * @info: receiver information
  907. *
  908. * Return: 0 on success or negative error number in case of failure
  909. */
  910. static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info)
  911. {
  912. struct batadv_softif_vlan *vlan = info->user_ptr[1];
  913. struct batadv_priv *bat_priv = info->user_ptr[0];
  914. struct sk_buff *msg;
  915. int ret;
  916. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  917. if (!msg)
  918. return -ENOMEM;
  919. ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN,
  920. info->snd_portid, info->snd_seq, 0);
  921. if (ret < 0) {
  922. nlmsg_free(msg);
  923. return ret;
  924. }
  925. ret = genlmsg_reply(msg, info);
  926. return ret;
  927. }
  928. /**
  929. * batadv_netlink_set_vlan() - Get vlan attributes
  930. * @skb: Netlink message with request data
  931. * @info: receiver information
  932. *
  933. * Return: 0 on success or negative error number in case of failure
  934. */
  935. static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info)
  936. {
  937. struct batadv_softif_vlan *vlan = info->user_ptr[1];
  938. struct batadv_priv *bat_priv = info->user_ptr[0];
  939. struct nlattr *attr;
  940. if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
  941. attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED];
  942. atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
  943. }
  944. batadv_netlink_notify_vlan(bat_priv, vlan);
  945. return 0;
  946. }
  947. /**
  948. * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
  949. * @net: the applicable net namespace
  950. * @info: receiver information
  951. *
  952. * Return: Pointer to soft interface (with increased refcnt) on success, error
  953. * pointer on error
  954. */
  955. static struct net_device *
  956. batadv_get_softif_from_info(struct net *net, struct genl_info *info)
  957. {
  958. struct net_device *soft_iface;
  959. int ifindex;
  960. if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
  961. return ERR_PTR(-EINVAL);
  962. ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
  963. soft_iface = dev_get_by_index(net, ifindex);
  964. if (!soft_iface)
  965. return ERR_PTR(-ENODEV);
  966. if (!batadv_softif_is_valid(soft_iface))
  967. goto err_put_softif;
  968. return soft_iface;
  969. err_put_softif:
  970. dev_put(soft_iface);
  971. return ERR_PTR(-EINVAL);
  972. }
  973. /**
  974. * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
  975. * @bat_priv: the bat priv with all the soft interface information
  976. * @net: the applicable net namespace
  977. * @info: receiver information
  978. *
  979. * Return: Pointer to hard interface (with increased refcnt) on success, error
  980. * pointer on error
  981. */
  982. static struct batadv_hard_iface *
  983. batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net,
  984. struct genl_info *info)
  985. {
  986. struct batadv_hard_iface *hard_iface;
  987. struct net_device *hard_dev;
  988. unsigned int hardif_index;
  989. if (!info->attrs[BATADV_ATTR_HARD_IFINDEX])
  990. return ERR_PTR(-EINVAL);
  991. hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]);
  992. hard_dev = dev_get_by_index(net, hardif_index);
  993. if (!hard_dev)
  994. return ERR_PTR(-ENODEV);
  995. hard_iface = batadv_hardif_get_by_netdev(hard_dev);
  996. if (!hard_iface)
  997. goto err_put_harddev;
  998. if (hard_iface->soft_iface != bat_priv->soft_iface)
  999. goto err_put_hardif;
  1000. /* hard_dev is referenced by hard_iface and not needed here */
  1001. dev_put(hard_dev);
  1002. return hard_iface;
  1003. err_put_hardif:
  1004. batadv_hardif_put(hard_iface);
  1005. err_put_harddev:
  1006. dev_put(hard_dev);
  1007. return ERR_PTR(-EINVAL);
  1008. }
  1009. /**
  1010. * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes
  1011. * @bat_priv: the bat priv with all the soft interface information
  1012. * @net: the applicable net namespace
  1013. * @info: receiver information
  1014. *
  1015. * Return: Pointer to vlan on success (with increased refcnt), error pointer
  1016. * on error
  1017. */
  1018. static struct batadv_softif_vlan *
  1019. batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net,
  1020. struct genl_info *info)
  1021. {
  1022. struct batadv_softif_vlan *vlan;
  1023. u16 vid;
  1024. if (!info->attrs[BATADV_ATTR_VLANID])
  1025. return ERR_PTR(-EINVAL);
  1026. vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]);
  1027. vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG);
  1028. if (!vlan)
  1029. return ERR_PTR(-ENOENT);
  1030. return vlan;
  1031. }
  1032. /**
  1033. * batadv_pre_doit() - Prepare batman-adv genl doit request
  1034. * @ops: requested netlink operation
  1035. * @skb: Netlink message with request data
  1036. * @info: receiver information
  1037. *
  1038. * Return: 0 on success or negative error number in case of failure
  1039. */
  1040. static int batadv_pre_doit(const struct genl_split_ops *ops,
  1041. struct sk_buff *skb,
  1042. struct genl_info *info)
  1043. {
  1044. struct net *net = genl_info_net(info);
  1045. struct batadv_hard_iface *hard_iface;
  1046. struct batadv_priv *bat_priv = NULL;
  1047. struct batadv_softif_vlan *vlan;
  1048. struct net_device *soft_iface;
  1049. u8 user_ptr1_flags;
  1050. u8 mesh_dep_flags;
  1051. int ret;
  1052. user_ptr1_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN;
  1053. if (WARN_ON(hweight8(ops->internal_flags & user_ptr1_flags) > 1))
  1054. return -EINVAL;
  1055. mesh_dep_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN;
  1056. if (WARN_ON((ops->internal_flags & mesh_dep_flags) &&
  1057. (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
  1058. return -EINVAL;
  1059. if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
  1060. soft_iface = batadv_get_softif_from_info(net, info);
  1061. if (IS_ERR(soft_iface))
  1062. return PTR_ERR(soft_iface);
  1063. bat_priv = netdev_priv(soft_iface);
  1064. info->user_ptr[0] = bat_priv;
  1065. }
  1066. if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) {
  1067. hard_iface = batadv_get_hardif_from_info(bat_priv, net, info);
  1068. if (IS_ERR(hard_iface)) {
  1069. ret = PTR_ERR(hard_iface);
  1070. goto err_put_softif;
  1071. }
  1072. info->user_ptr[1] = hard_iface;
  1073. }
  1074. if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) {
  1075. vlan = batadv_get_vlan_from_info(bat_priv, net, info);
  1076. if (IS_ERR(vlan)) {
  1077. ret = PTR_ERR(vlan);
  1078. goto err_put_softif;
  1079. }
  1080. info->user_ptr[1] = vlan;
  1081. }
  1082. return 0;
  1083. err_put_softif:
  1084. if (bat_priv)
  1085. dev_put(bat_priv->soft_iface);
  1086. return ret;
  1087. }
  1088. /**
  1089. * batadv_post_doit() - End batman-adv genl doit request
  1090. * @ops: requested netlink operation
  1091. * @skb: Netlink message with request data
  1092. * @info: receiver information
  1093. */
  1094. static void batadv_post_doit(const struct genl_split_ops *ops,
  1095. struct sk_buff *skb,
  1096. struct genl_info *info)
  1097. {
  1098. struct batadv_hard_iface *hard_iface;
  1099. struct batadv_softif_vlan *vlan;
  1100. struct batadv_priv *bat_priv;
  1101. if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF &&
  1102. info->user_ptr[1]) {
  1103. hard_iface = info->user_ptr[1];
  1104. batadv_hardif_put(hard_iface);
  1105. }
  1106. if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) {
  1107. vlan = info->user_ptr[1];
  1108. batadv_softif_vlan_put(vlan);
  1109. }
  1110. if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
  1111. bat_priv = info->user_ptr[0];
  1112. dev_put(bat_priv->soft_iface);
  1113. }
  1114. }
  1115. static const struct genl_small_ops batadv_netlink_ops[] = {
  1116. {
  1117. .cmd = BATADV_CMD_GET_MESH,
  1118. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1119. /* can be retrieved by unprivileged users */
  1120. .doit = batadv_netlink_get_mesh,
  1121. .internal_flags = BATADV_FLAG_NEED_MESH,
  1122. },
  1123. {
  1124. .cmd = BATADV_CMD_TP_METER,
  1125. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1126. .flags = GENL_UNS_ADMIN_PERM,
  1127. .doit = batadv_netlink_tp_meter_start,
  1128. .internal_flags = BATADV_FLAG_NEED_MESH,
  1129. },
  1130. {
  1131. .cmd = BATADV_CMD_TP_METER_CANCEL,
  1132. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1133. .flags = GENL_UNS_ADMIN_PERM,
  1134. .doit = batadv_netlink_tp_meter_cancel,
  1135. .internal_flags = BATADV_FLAG_NEED_MESH,
  1136. },
  1137. {
  1138. .cmd = BATADV_CMD_GET_ROUTING_ALGOS,
  1139. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1140. .flags = GENL_UNS_ADMIN_PERM,
  1141. .dumpit = batadv_algo_dump,
  1142. },
  1143. {
  1144. .cmd = BATADV_CMD_GET_HARDIF,
  1145. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1146. /* can be retrieved by unprivileged users */
  1147. .dumpit = batadv_netlink_dump_hardif,
  1148. .doit = batadv_netlink_get_hardif,
  1149. .internal_flags = BATADV_FLAG_NEED_MESH |
  1150. BATADV_FLAG_NEED_HARDIF,
  1151. },
  1152. {
  1153. .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
  1154. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1155. .flags = GENL_UNS_ADMIN_PERM,
  1156. .dumpit = batadv_tt_local_dump,
  1157. },
  1158. {
  1159. .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
  1160. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1161. .flags = GENL_UNS_ADMIN_PERM,
  1162. .dumpit = batadv_tt_global_dump,
  1163. },
  1164. {
  1165. .cmd = BATADV_CMD_GET_ORIGINATORS,
  1166. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1167. .flags = GENL_UNS_ADMIN_PERM,
  1168. .dumpit = batadv_orig_dump,
  1169. },
  1170. {
  1171. .cmd = BATADV_CMD_GET_NEIGHBORS,
  1172. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1173. .flags = GENL_UNS_ADMIN_PERM,
  1174. .dumpit = batadv_hardif_neigh_dump,
  1175. },
  1176. {
  1177. .cmd = BATADV_CMD_GET_GATEWAYS,
  1178. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1179. .flags = GENL_UNS_ADMIN_PERM,
  1180. .dumpit = batadv_gw_dump,
  1181. },
  1182. {
  1183. .cmd = BATADV_CMD_GET_BLA_CLAIM,
  1184. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1185. .flags = GENL_UNS_ADMIN_PERM,
  1186. .dumpit = batadv_bla_claim_dump,
  1187. },
  1188. {
  1189. .cmd = BATADV_CMD_GET_BLA_BACKBONE,
  1190. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1191. .flags = GENL_UNS_ADMIN_PERM,
  1192. .dumpit = batadv_bla_backbone_dump,
  1193. },
  1194. {
  1195. .cmd = BATADV_CMD_GET_DAT_CACHE,
  1196. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1197. .flags = GENL_UNS_ADMIN_PERM,
  1198. .dumpit = batadv_dat_cache_dump,
  1199. },
  1200. {
  1201. .cmd = BATADV_CMD_GET_MCAST_FLAGS,
  1202. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1203. .flags = GENL_UNS_ADMIN_PERM,
  1204. .dumpit = batadv_mcast_flags_dump,
  1205. },
  1206. {
  1207. .cmd = BATADV_CMD_SET_MESH,
  1208. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1209. .flags = GENL_UNS_ADMIN_PERM,
  1210. .doit = batadv_netlink_set_mesh,
  1211. .internal_flags = BATADV_FLAG_NEED_MESH,
  1212. },
  1213. {
  1214. .cmd = BATADV_CMD_SET_HARDIF,
  1215. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1216. .flags = GENL_UNS_ADMIN_PERM,
  1217. .doit = batadv_netlink_set_hardif,
  1218. .internal_flags = BATADV_FLAG_NEED_MESH |
  1219. BATADV_FLAG_NEED_HARDIF,
  1220. },
  1221. {
  1222. .cmd = BATADV_CMD_GET_VLAN,
  1223. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1224. /* can be retrieved by unprivileged users */
  1225. .doit = batadv_netlink_get_vlan,
  1226. .internal_flags = BATADV_FLAG_NEED_MESH |
  1227. BATADV_FLAG_NEED_VLAN,
  1228. },
  1229. {
  1230. .cmd = BATADV_CMD_SET_VLAN,
  1231. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  1232. .flags = GENL_UNS_ADMIN_PERM,
  1233. .doit = batadv_netlink_set_vlan,
  1234. .internal_flags = BATADV_FLAG_NEED_MESH |
  1235. BATADV_FLAG_NEED_VLAN,
  1236. },
  1237. };
  1238. struct genl_family batadv_netlink_family __ro_after_init = {
  1239. .hdrsize = 0,
  1240. .name = BATADV_NL_NAME,
  1241. .version = 1,
  1242. .maxattr = BATADV_ATTR_MAX,
  1243. .policy = batadv_netlink_policy,
  1244. .netnsok = true,
  1245. .pre_doit = batadv_pre_doit,
  1246. .post_doit = batadv_post_doit,
  1247. .module = THIS_MODULE,
  1248. .small_ops = batadv_netlink_ops,
  1249. .n_small_ops = ARRAY_SIZE(batadv_netlink_ops),
  1250. .resv_start_op = BATADV_CMD_SET_VLAN + 1,
  1251. .mcgrps = batadv_netlink_mcgrps,
  1252. .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps),
  1253. };
  1254. /**
  1255. * batadv_netlink_register() - register batadv genl netlink family
  1256. */
  1257. void __init batadv_netlink_register(void)
  1258. {
  1259. int ret;
  1260. ret = genl_register_family(&batadv_netlink_family);
  1261. if (ret)
  1262. pr_warn("unable to register netlink family");
  1263. }
  1264. /**
  1265. * batadv_netlink_unregister() - unregister batadv genl netlink family
  1266. */
  1267. void batadv_netlink_unregister(void)
  1268. {
  1269. genl_unregister_family(&batadv_netlink_family);
  1270. }