embms_kernel.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*************************************************************************
  2. * -----------------------------------------------------------------------
  3. * Copyright (c) 2013-2015, 2017, The Linux Foundation. All rights reserved.
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. * See the GNU General Public License for more details.
  11. * -----------------------------------------------------------------------
  12. * DESCRIPTION
  13. * Main file for eMBMs Tunneling Module in kernel.
  14. *************************************************************************
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <linux/fs.h>
  19. #include <net/ip.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/types.h>
  22. #include <linux/version.h>
  23. #include <linux/etherdevice.h>
  24. #include <linux/inetdevice.h>
  25. #include <linux/netfilter.h>
  26. #include <net/arp.h>
  27. #include <net/neighbour.h>
  28. #include <linux/skbuff.h>
  29. #include <linux/list.h>
  30. #include <linux/in.h>
  31. #include <net/netfilter/nf_conntrack.h>
  32. #include <linux/miscdevice.h>
  33. #include "embms_kernel.h"
  34. struct embms_info_internal embms_conf;
  35. /* Global structures used for tunneling. These include
  36. * iphdr and udphdr which are appended to skbs for
  37. * tunneling, net_device and tunnleing related
  38. * structs and params
  39. */
  40. unsigned char hdr_buff[sizeof(struct iphdr) + sizeof(struct udphdr)];
  41. struct iphdr *iph_global;
  42. struct udphdr *udph_global;
  43. struct net_device *dev_global;
  44. static struct tmgi_to_clnt_info tmgi_to_clnt_map_tbl;
  45. /* handle_multicast_stream - packet forwarding
  46. * function for multicast stream
  47. * Main use case is for EMBMS Over Softap feature
  48. */
  49. static int handle_multicast_stream(struct sk_buff *skb)
  50. {
  51. struct iphdr *iph;
  52. struct udphdr *udph;
  53. unsigned char *tmp_ptr = NULL;
  54. struct sk_buff *skb_new = NULL;
  55. struct sk_buff *skb_cpy = NULL;
  56. struct clnt_info *temp_client = NULL;
  57. struct tmgi_to_clnt_info *temp_tmgi = NULL;
  58. struct list_head *tmgi_entry_ptr, *prev_tmgi_entry_ptr;
  59. struct list_head *clnt_ptr, *prev_clnt_ptr;
  60. int hdr_size = sizeof(*udph) + sizeof(*iph) + ETH_HLEN;
  61. /* only IP packets */
  62. if (htons(ETH_P_IP) != skb->protocol) {
  63. embms_error("Not an IP packet\n");
  64. return 0;
  65. }
  66. if (embms_conf.embms_tunneling_status == TUNNELING_OFF) {
  67. embms_debug("Tunneling Disabled. Can't process packets\n");
  68. return 0;
  69. }
  70. if (unlikely(memcmp(skb->dev->name, embms_conf.embms_iface,
  71. strlen(embms_conf.embms_iface)) != 0)) {
  72. embms_error("Packet received on %s iface. NOT an EMBMS Iface\n",
  73. skb->dev->name);
  74. return 0;
  75. }
  76. /* Check if dst ip of packet is same as multicast ip of any tmgi*/
  77. iph = (struct iphdr *)skb->data;
  78. udph = (struct udphdr *)(skb->data + sizeof(struct iphdr));
  79. spin_lock_bh(&embms_conf.lock);
  80. list_for_each_safe(tmgi_entry_ptr, prev_tmgi_entry_ptr,
  81. &tmgi_to_clnt_map_tbl.tmgi_list_ptr) {
  82. temp_tmgi = list_entry(tmgi_entry_ptr,
  83. struct tmgi_to_clnt_info,
  84. tmgi_list_ptr);
  85. if ((temp_tmgi->tmgi_multicast_addr == iph->daddr) &&
  86. (temp_tmgi->tmgi_port == udph->dest))
  87. break;
  88. }
  89. if (tmgi_entry_ptr == &tmgi_to_clnt_map_tbl.tmgi_list_ptr) {
  90. embms_error("handle_multicast_stream:");
  91. embms_error("could not find matchin tmgi entry\n");
  92. spin_unlock_bh(&embms_conf.lock);
  93. return 0;
  94. }
  95. /* Found a matching tmgi entry. Realloc headroom to
  96. * accommodate new Ethernet, IP and UDP header
  97. */
  98. skb_new = skb_realloc_headroom(skb, hdr_size);
  99. if (unlikely(!skb_new)) {
  100. embms_error("Can't allocate headroom\n");
  101. spin_unlock_bh(&embms_conf.lock);
  102. return 0;
  103. }
  104. /* push skb->data and copy IP and UDP headers*/
  105. tmp_ptr = skb_push(skb_new,
  106. sizeof(struct udphdr) + sizeof(struct iphdr));
  107. iph = (struct iphdr *)tmp_ptr;
  108. udph = (struct udphdr *)(tmp_ptr + sizeof(struct iphdr));
  109. memcpy(tmp_ptr, hdr_buff, hdr_size - ETH_HLEN);
  110. udph->len = htons(skb_new->len - sizeof(struct iphdr));
  111. iph->tot_len = htons(skb_new->len);
  112. list_for_each_safe(clnt_ptr, prev_clnt_ptr,
  113. &temp_tmgi->client_list_head) {
  114. temp_client = list_entry(clnt_ptr,
  115. struct clnt_info,
  116. client_list_ptr);
  117. /* Make a copy of skb_new with new IP and UDP header.
  118. * We can't use skb_new or its clone here since we need to
  119. * constantly change dst ip and dst port which is not possible
  120. * for shared memory as is the case with skb_new.
  121. */
  122. skb_cpy = skb_copy(skb_new, GFP_ATOMIC);
  123. if (unlikely(!skb_cpy)) {
  124. embms_error("Can't copy skb\n");
  125. kfree_skb(skb_new);
  126. return 0;
  127. }
  128. iph = (struct iphdr *)skb_cpy->data;
  129. udph = (struct udphdr *)(skb_cpy->data + sizeof(struct iphdr));
  130. iph->id = htons(atomic_inc_return(&embms_conf.ip_ident));
  131. /* Calculate checksum for new IP and UDP header*/
  132. udph->dest = temp_client->port;
  133. skb_cpy->csum = csum_partial((char *)udph,
  134. ntohs(udph->len),
  135. skb_cpy->csum);
  136. iph->daddr = temp_client->addr;
  137. ip_send_check(iph);
  138. udph->check = 0;
  139. udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
  140. ntohs(udph->len),
  141. IPPROTO_UDP,
  142. skb_cpy->csum);
  143. if (udph->check == 0)
  144. udph->check = CSUM_MANGLED_0;
  145. if (unlikely(!dev_global)) {
  146. embms_error("Global device NULL\n");
  147. kfree_skb(skb_cpy);
  148. kfree_skb(skb_new);
  149. return 0;
  150. }
  151. /* update device info and add MAC header*/
  152. skb_cpy->dev = dev_global;
  153. skb_cpy->dev->header_ops->create(skb_cpy, skb_cpy->dev,
  154. ETH_P_IP, temp_client->dmac,
  155. NULL, skb_cpy->len);
  156. dev_queue_xmit(skb_cpy);
  157. }
  158. spin_unlock_bh(&embms_conf.lock);
  159. kfree_skb(skb_new);
  160. return 1;
  161. }
  162. static int check_embms_device(atomic_t *use_count)
  163. {
  164. int ret;
  165. if (atomic_inc_return(use_count) == 1) {
  166. ret = 0;
  167. } else {
  168. atomic_dec(use_count);
  169. ret = -EBUSY;
  170. }
  171. return ret;
  172. }
  173. static int embms_device_open(struct inode *inode, struct file *file)
  174. {
  175. /*Check if the device is busy*/
  176. if (check_embms_device(&embms_conf.device_under_use)) {
  177. embms_error("embms_tm_open : EMBMS device busy\n");
  178. return -EBUSY;
  179. }
  180. try_module_get(THIS_MODULE);
  181. return SUCCESS;
  182. }
  183. static int embms_device_release(struct inode *inode, struct file *file)
  184. {
  185. /* Reduce device use count before leaving*/
  186. embms_debug("Releasing EMBMS device..\n");
  187. atomic_dec(&embms_conf.device_under_use);
  188. embms_conf.embms_tunneling_status = TUNNELING_OFF;
  189. module_put(THIS_MODULE);
  190. return SUCCESS;
  191. }
  192. static struct tmgi_to_clnt_info *check_for_tmgi_entry(u32 addr,
  193. u16 port)
  194. {
  195. struct list_head *tmgi_ptr, *prev_tmgi_ptr;
  196. struct tmgi_to_clnt_info *temp_tmgi = NULL;
  197. embms_debug("check_for_tmgi_entry: mcast addr :%pI4, port %u\n",
  198. &addr, ntohs(port));
  199. list_for_each_safe(tmgi_ptr,
  200. prev_tmgi_ptr,
  201. &tmgi_to_clnt_map_tbl.tmgi_list_ptr) {
  202. temp_tmgi = list_entry(tmgi_ptr,
  203. struct tmgi_to_clnt_info,
  204. tmgi_list_ptr);
  205. if ((temp_tmgi->tmgi_multicast_addr == addr) &&
  206. (temp_tmgi->tmgi_port == port)) {
  207. embms_debug("check_for_tmgi_entry:TMGI entry found\n");
  208. return temp_tmgi;
  209. }
  210. }
  211. return NULL;
  212. }
  213. static struct clnt_info *chk_clnt_entry(struct tmgi_to_clnt_info *tmgi,
  214. struct tmgi_to_clnt_info_update *clnt)
  215. {
  216. struct list_head *clnt_ptr, *prev_clnt_ptr;
  217. struct clnt_info *temp_client = NULL;
  218. embms_debug("check_for_client_entry: clnt addr :%pI4, port %u\n",
  219. &clnt->client_addr, ntohs(clnt->client_port));
  220. list_for_each_safe(clnt_ptr,
  221. prev_clnt_ptr,
  222. &tmgi->client_list_head) {
  223. temp_client = list_entry(clnt_ptr,
  224. struct clnt_info,
  225. client_list_ptr);
  226. if ((temp_client->addr == clnt->client_addr) &&
  227. (temp_client->port == clnt->client_port)) {
  228. embms_debug("Clnt entry present\n");
  229. return temp_client;
  230. }
  231. }
  232. return NULL;
  233. }
  234. static int add_new_tmgi_entry(struct tmgi_to_clnt_info_update *info_update,
  235. struct clnt_info *clnt)
  236. {
  237. struct tmgi_to_clnt_info *new_tmgi = NULL;
  238. embms_debug("add_new_tmgi_entry:Enter\n");
  239. new_tmgi = kzalloc(sizeof(*new_tmgi),
  240. GFP_ATOMIC);
  241. if (!new_tmgi) {
  242. embms_error("add_new_tmgi_entry: mem alloc failed\n");
  243. return -ENOMEM;
  244. }
  245. memset(new_tmgi, 0, sizeof(struct tmgi_to_clnt_info));
  246. new_tmgi->tmgi_multicast_addr = info_update->multicast_addr;
  247. new_tmgi->tmgi_port = info_update->multicast_port;
  248. embms_debug("add_new_tmgi_entry:");
  249. embms_debug("New tmgi multicast addr :%pI4 , port %u\n",
  250. &info_update->multicast_addr,
  251. ntohs(info_update->multicast_port));
  252. embms_debug("add_new_tmgi_entry:Adding client entry\n");
  253. spin_lock_bh(&embms_conf.lock);
  254. INIT_LIST_HEAD(&new_tmgi->client_list_head);
  255. list_add(&clnt->client_list_ptr,
  256. &new_tmgi->client_list_head);
  257. new_tmgi->no_of_clients++;
  258. /* Once above steps are done successfully,
  259. * we add tmgi entry to our local table
  260. */
  261. list_add(&new_tmgi->tmgi_list_ptr,
  262. &tmgi_to_clnt_map_tbl.tmgi_list_ptr);
  263. embms_conf.no_of_tmgi_sessions++;
  264. spin_unlock_bh(&embms_conf.lock);
  265. return SUCCESS;
  266. }
  267. static void print_tmgi_to_client_table(void)
  268. {
  269. int i, j;
  270. struct clnt_info *temp_client = NULL;
  271. struct tmgi_to_clnt_info *temp_tmgi = NULL;
  272. struct list_head *tmgi_entry_ptr, *prev_tmgi_entry_ptr;
  273. struct list_head *clnt_ptr, *prev_clnt_ptr;
  274. embms_debug("====================================================\n");
  275. embms_debug("Printing TMGI to Client Table :\n");
  276. embms_debug("No of Active TMGIs : %d\n",
  277. embms_conf.no_of_tmgi_sessions);
  278. embms_debug("====================================================\n\n");
  279. if (embms_conf.no_of_tmgi_sessions > 0) {
  280. i = 1;
  281. list_for_each_safe(tmgi_entry_ptr, prev_tmgi_entry_ptr,
  282. &tmgi_to_clnt_map_tbl.tmgi_list_ptr) {
  283. temp_tmgi = list_entry(tmgi_entry_ptr,
  284. struct tmgi_to_clnt_info,
  285. tmgi_list_ptr);
  286. embms_debug("TMGI entry %d :\n", i);
  287. embms_debug("TMGI multicast addr : %pI4 , port %u\n\n",
  288. &temp_tmgi->tmgi_multicast_addr,
  289. ntohs(temp_tmgi->tmgi_port));
  290. embms_debug("No of clients : %d\n",
  291. temp_tmgi->no_of_clients);
  292. j = 1;
  293. list_for_each_safe(clnt_ptr, prev_clnt_ptr,
  294. &temp_tmgi->client_list_head) {
  295. temp_client = list_entry(clnt_ptr,
  296. struct clnt_info,
  297. client_list_ptr);
  298. embms_debug("Client entry %d :\n", j);
  299. embms_debug("client addr : %pI4 , port %u\n\n",
  300. &temp_client->addr,
  301. ntohs(temp_client->port));
  302. j++;
  303. }
  304. i++;
  305. embms_debug("===========================================\n\n");
  306. }
  307. } else {
  308. embms_debug("No TMGI entries to Display\n");
  309. }
  310. embms_debug("==================================================================\n\n");
  311. }
  312. /**
  313. * delete_tmgi_entry_from_table() - deletes tmgi from global tmgi-client table
  314. * @buffer: Buffer containing TMGI info for deletion.
  315. *
  316. * This function completely removes the TMGI from
  317. * global TMGI-client table, along with the client list
  318. * so that no packets for this TMGI are processed
  319. *
  320. * Return: Success on deleting TMGI entry, error otherwise.
  321. */
  322. int delete_tmgi_entry_from_table(char *buffer)
  323. {
  324. struct tmgi_to_clnt_info_update *info_update;
  325. struct clnt_info *temp_client = NULL;
  326. struct tmgi_to_clnt_info *temp_tmgi = NULL;
  327. struct list_head *clnt_ptr, *prev_clnt_ptr;
  328. embms_debug("delete_tmgi_entry_from_table: Enter\n");
  329. info_update = (struct tmgi_to_clnt_info_update *)buffer;
  330. if (!info_update) {
  331. embms_error("delete_tmgi_entry_from_table:");
  332. embms_error("NULL arguments passed\n");
  333. return -EBADPARAM;
  334. }
  335. /* This function is used to delete a specific TMGI entry
  336. * when that particular TMGI goes down
  337. * Search for the TMGI entry in our local table
  338. */
  339. if (embms_conf.no_of_tmgi_sessions == 0) {
  340. embms_error("TMGI count 0. Nothing to delete\n");
  341. return SUCCESS;
  342. }
  343. temp_tmgi = check_for_tmgi_entry(info_update->multicast_addr,
  344. info_update->multicast_port);
  345. if (!temp_tmgi) {
  346. /* TMGI entry was not found in our local table*/
  347. embms_error("delete_client_entry_from_table :");
  348. embms_error("Desired TMGI entry not found\n");
  349. return -EBADPARAM;
  350. }
  351. spin_lock_bh(&embms_conf.lock);
  352. /* We need to free memory allocated to client entries
  353. * for a particular TMGI entry
  354. */
  355. list_for_each_safe(clnt_ptr, prev_clnt_ptr,
  356. &temp_tmgi->client_list_head) {
  357. temp_client = list_entry(clnt_ptr,
  358. struct clnt_info,
  359. client_list_ptr);
  360. embms_debug("delete_tmgi_entry_from_table :");
  361. embms_debug("Client addr to delete :%pI4 , port %u\n",
  362. &temp_client->addr, ntohs(temp_client->port));
  363. list_del(&temp_client->client_list_ptr);
  364. temp_tmgi->no_of_clients--;
  365. kfree(temp_client);
  366. }
  367. /* Free memory allocated to tmgi entry*/
  368. list_del(&temp_tmgi->tmgi_list_ptr);
  369. kfree(temp_tmgi);
  370. embms_conf.no_of_tmgi_sessions--;
  371. spin_unlock_bh(&embms_conf.lock);
  372. embms_debug("delete_tmgi_entry_from_table : TMGI Entry deleted.\n");
  373. return SUCCESS;
  374. }
  375. /**
  376. * delete_client_entry_from_all_tmgi() - deletes client from all tmgi lists
  377. * @buffer: Buffer containing client info for deletion.
  378. *
  379. * This function completely removes a client from
  380. * all TMGIs in global TMGI-client table. Also delets TMGI
  381. * entries if no more clients are there
  382. *
  383. * Return: Success on deleting client entry, error otherwise.
  384. */
  385. int delete_client_entry_from_all_tmgi(char *buffer)
  386. {
  387. struct tmgi_to_clnt_info_update *info_update;
  388. struct clnt_info *temp_client = NULL;
  389. struct tmgi_to_clnt_info *tmgi = NULL;
  390. struct list_head *tmgi_entry_ptr, *prev_tmgi_entry_ptr;
  391. /* We use this function when we want to delete any
  392. * client entry from all TMGI entries. This scenario
  393. * happens when any client disconnects and hence
  394. * we need to clean all realted client entries
  395. * in our mapping table
  396. */
  397. embms_debug("del_clnt_from_all_tmgi: Enter\n");
  398. info_update = (struct tmgi_to_clnt_info_update *)buffer;
  399. if (!info_update) {
  400. embms_error("del_clnt_from_all_tmgi:");
  401. embms_error("NULL arguments passed\n");
  402. return -EBADPARAM;
  403. }
  404. /* We start checking from first TMGI entry and if client
  405. * entry is found in client entries of any TMGI, we clean
  406. * up that client entry from that TMGI entry
  407. */
  408. if (embms_conf.no_of_tmgi_sessions == 0)
  409. return SUCCESS;
  410. list_for_each_safe(tmgi_entry_ptr, prev_tmgi_entry_ptr,
  411. &tmgi_to_clnt_map_tbl.tmgi_list_ptr) {
  412. tmgi = list_entry(tmgi_entry_ptr,
  413. struct tmgi_to_clnt_info,
  414. tmgi_list_ptr);
  415. temp_client = chk_clnt_entry(tmgi, info_update);
  416. if (!temp_client)
  417. continue;
  418. spin_lock_bh(&embms_conf.lock);
  419. list_del(&temp_client->client_list_ptr);
  420. tmgi->no_of_clients--;
  421. kfree(temp_client);
  422. spin_unlock_bh(&embms_conf.lock);
  423. temp_client = NULL;
  424. if (tmgi->no_of_clients == 0) {
  425. /* Deleted clnt was the only clnt for
  426. * that TMGI we need to delete TMGI
  427. * entry from table
  428. */
  429. embms_debug("del_clnt_from_all_tmgi:");
  430. embms_debug("Deleted client was ");
  431. embms_debug("last client for tmgi\n");
  432. embms_debug("del_clnt_from_all_tmgi:");
  433. embms_debug("Delting tmgi as it has ");
  434. embms_debug("zero clients.TMGI IP ");
  435. embms_debug(":%pI4 , port %u\n",
  436. &tmgi->tmgi_multicast_addr,
  437. ntohs(tmgi->tmgi_port));
  438. spin_lock_bh(&embms_conf.lock);
  439. list_del(&tmgi->tmgi_list_ptr);
  440. embms_conf.no_of_tmgi_sessions--;
  441. kfree(tmgi);
  442. spin_unlock_bh(&embms_conf.lock);
  443. embms_debug("del_clnt_from_all_tmgi:");
  444. embms_debug("TMGI entry deleted\n");
  445. }
  446. }
  447. embms_debug("del_clnt_from_all_tmgi Successful\n");
  448. return SUCCESS;
  449. }
  450. /**
  451. * add_client_entry_to_table() - add client entry to specified TMGI
  452. * @buffer: Buffer containing client info for addition.
  453. *
  454. * This function adds a client to the specified TMGI in
  455. * the global TMGI-client table. If TMGI entry is not
  456. * present, it adds a new TMGI entry and adds client
  457. * entry to it.
  458. *
  459. * Return: Success on adding client entry, error otherwise.
  460. */
  461. int add_client_entry_to_table(char *buffer)
  462. {
  463. int ret;
  464. struct tmgi_to_clnt_info_update *info_update;
  465. struct clnt_info *new_client = NULL;
  466. struct tmgi_to_clnt_info *tmgi = NULL;
  467. struct neighbour *neigh_entry;
  468. embms_debug("add_client_entry_to_table: Enter\n");
  469. info_update = (struct tmgi_to_clnt_info_update *)buffer;
  470. if (!info_update) {
  471. embms_error("add_client_entry_to_table:");
  472. embms_error("NULL arguments passed\n");
  473. return -EBADPARAM;
  474. }
  475. new_client = kzalloc(sizeof(*new_client), GFP_ATOMIC);
  476. if (!new_client) {
  477. embms_error("add_client_entry_to_table:");
  478. embms_error("Cannot allocate memory\n");
  479. return -ENOMEM;
  480. }
  481. new_client->addr = info_update->client_addr;
  482. new_client->port = info_update->client_port;
  483. neigh_entry = __ipv4_neigh_lookup(dev_global,
  484. (u32)(new_client->addr));
  485. if (!neigh_entry) {
  486. embms_error("add_client_entry_to_table :");
  487. embms_error("Can't find neighbour entry\n");
  488. kfree(new_client);
  489. return -EBADPARAM;
  490. }
  491. ether_addr_copy(new_client->dmac, neigh_entry->ha);
  492. embms_debug("DMAC of client : %pM\n", new_client->dmac);
  493. embms_debug("add_client_entry_to_table:");
  494. embms_debug("New client addr :%pI4 , port %u\n",
  495. &info_update->client_addr,
  496. ntohs(info_update->client_port));
  497. if (embms_conf.no_of_tmgi_sessions == 0) {
  498. /* TMGI Client mapping table is empty.
  499. * First client entry is being added
  500. */
  501. embms_debug("tmgi_to_clnt_map_tbl is empty\n");
  502. ret = add_new_tmgi_entry(info_update, new_client);
  503. if (ret != SUCCESS) {
  504. kfree(new_client);
  505. new_client = NULL;
  506. }
  507. goto exit_add;
  508. }
  509. /* In this case, table already has some entries
  510. * and we need to search for the specific tmgi entry
  511. * for which client entry is to be added
  512. */
  513. tmgi = check_for_tmgi_entry(info_update->multicast_addr,
  514. info_update->multicast_port);
  515. if (tmgi) {
  516. if (chk_clnt_entry(tmgi, info_update)) {
  517. kfree(new_client);
  518. return -ENOEFFECT;
  519. }
  520. /* Adding client to the client list
  521. * for the specified TMGI
  522. */
  523. spin_lock_bh(&embms_conf.lock);
  524. list_add(&new_client->client_list_ptr,
  525. &tmgi->client_list_head);
  526. tmgi->no_of_clients++;
  527. spin_unlock_bh(&embms_conf.lock);
  528. ret = SUCCESS;
  529. } else {
  530. /* TMGI specified in the message was not found in
  531. * mapping table.Hence, we need to add a new entry
  532. * for this TMGI and add the specified client to the client
  533. * list
  534. */
  535. embms_debug("TMGI entry not present. Adding tmgi entry\n");
  536. ret = add_new_tmgi_entry(info_update, new_client);
  537. if (ret != SUCCESS) {
  538. kfree(new_client);
  539. new_client = NULL;
  540. }
  541. }
  542. exit_add:
  543. return ret;
  544. }
  545. /**
  546. * delete_client_entry_from_table() - delete client entry from specified TMGI
  547. * @buffer: Buffer containing client info for deletion.
  548. *
  549. * This function deletes a client from the specified TMGI in
  550. * the global TMGI-client table. If this was the last client
  551. * entry, it also deletes the TMGI entry.
  552. *
  553. * Return: Success on deleting client entry, error otherwise.
  554. */
  555. int delete_client_entry_from_table(char *buffer)
  556. {
  557. struct tmgi_to_clnt_info_update *info_update;
  558. struct clnt_info *temp_client = NULL;
  559. struct tmgi_to_clnt_info *temp_tmgi = NULL;
  560. embms_debug("delete_client_entry_from_table: Enter\n");
  561. info_update = (struct tmgi_to_clnt_info_update *)buffer;
  562. if (!info_update) {
  563. embms_error("delete_client_entry_from_table:");
  564. embms_error("NULL arguments passed\n");
  565. return -EBADPARAM;
  566. }
  567. /* Search for the TMGI entry*/
  568. if (embms_conf.no_of_tmgi_sessions == 0)
  569. return SUCCESS;
  570. temp_tmgi = check_for_tmgi_entry(info_update->multicast_addr,
  571. info_update->multicast_port);
  572. if (!temp_tmgi) {
  573. embms_error("delete_client_entry_from_table:TMGI not found\n");
  574. return -EBADPARAM;
  575. }
  576. /* Delete client entry for a specific tmgi*/
  577. embms_debug("delete_client_entry_from_table:clnt addr :%pI4,port %u\n",
  578. &info_update->client_addr,
  579. ntohs(info_update->client_port));
  580. temp_client = chk_clnt_entry(temp_tmgi, info_update);
  581. if (!temp_client) {
  582. /* Specified client entry was not found in client list
  583. * of specified TMGI
  584. */
  585. embms_error("delete_client_entry_from_table:Clnt not found\n");
  586. return -EBADPARAM;
  587. }
  588. spin_lock_bh(&embms_conf.lock);
  589. list_del(&temp_client->client_list_ptr);
  590. temp_tmgi->no_of_clients--;
  591. spin_unlock_bh(&embms_conf.lock);
  592. kfree(temp_client);
  593. temp_client = NULL;
  594. embms_debug("delete_client_entry_from_table:Client entry deleted\n");
  595. if (temp_tmgi->no_of_clients == 0) {
  596. /* If deleted client was the only client for that TMGI
  597. * we need to delete TMGI entry from table
  598. */
  599. embms_debug("delete_client_entry_from_table:");
  600. embms_debug("Deleted client was the last client for tmgi\n");
  601. embms_debug("delete_client_entry_from_table:");
  602. embms_debug("Deleting tmgi since it has zero clients\n");
  603. spin_lock_bh(&embms_conf.lock);
  604. list_del(&temp_tmgi->tmgi_list_ptr);
  605. embms_conf.no_of_tmgi_sessions--;
  606. kfree(temp_tmgi);
  607. spin_unlock_bh(&embms_conf.lock);
  608. embms_debug("delete_client_entry_from_table: TMGI deleted\n");
  609. }
  610. if (embms_conf.no_of_tmgi_sessions == 0)
  611. embms_conf.embms_tunneling_status = TUNNELING_OFF;
  612. return SUCCESS;
  613. }
  614. /**
  615. * embms_device_ioctl() - handle IOCTL calls to device
  616. * @file: File descriptor of file opened from userspace process
  617. * @ioctl_num: IOCTL to use
  618. * @ioctl_param: IOCTL parameters/arguments
  619. *
  620. * This function is called whenever a process tries to do
  621. * an ioctl on our device file. As per the IOCTL number,
  622. * it calls various functions to manipulate global
  623. * TMGI-client table
  624. *
  625. * Return: Success if functoin call returns SUCCESS, error otherwise.
  626. */
  627. long embms_device_ioctl(struct file *file, unsigned int ioctl_num,
  628. unsigned long ioctl_param)
  629. {
  630. int ret;
  631. char buffer[BUF_LEN];
  632. struct in_device *iface_dev;
  633. struct in_ifaddr *iface_info;
  634. struct tmgi_to_clnt_info_update *info_update;
  635. char __user *argp = (char __user *)ioctl_param;
  636. memset(buffer, 0, BUF_LEN);
  637. /* Switch according to the ioctl called*/
  638. switch (ioctl_num) {
  639. case ADD_EMBMS_TUNNEL:
  640. if (copy_from_user(buffer, argp,
  641. sizeof(struct tmgi_to_clnt_info_update)))
  642. return -EFAULT;
  643. ret = add_client_entry_to_table(buffer);
  644. print_tmgi_to_client_table();
  645. break;
  646. case DEL_EMBMS_TUNNEL:
  647. if (copy_from_user(buffer, argp,
  648. sizeof(struct tmgi_to_clnt_info_update)))
  649. return -EFAULT;
  650. ret = delete_client_entry_from_table(buffer);
  651. print_tmgi_to_client_table();
  652. break;
  653. case TMGI_DEACTIVATE:
  654. if (copy_from_user(buffer, argp,
  655. sizeof(struct tmgi_to_clnt_info_update)))
  656. return -EFAULT;
  657. ret = delete_tmgi_entry_from_table(buffer);
  658. print_tmgi_to_client_table();
  659. break;
  660. case CLIENT_DEACTIVATE:
  661. if (copy_from_user(buffer, argp,
  662. sizeof(struct tmgi_to_clnt_info_update)))
  663. return -EFAULT;
  664. ret = delete_client_entry_from_all_tmgi(buffer);
  665. print_tmgi_to_client_table();
  666. break;
  667. case GET_EMBMS_TUNNELING_STATUS:
  668. /* This ioctl is both input (ioctl_param) and
  669. * output (the return value of this function)
  670. */
  671. embms_debug("Sending tunneling status : %d\n",
  672. embms_conf.embms_tunneling_status);
  673. ret = embms_conf.embms_tunneling_status;
  674. break;
  675. case START_EMBMS_TUNNEL:
  676. if (copy_from_user(buffer, argp,
  677. sizeof(struct tmgi_to_clnt_info_update)))
  678. return -EFAULT;
  679. info_update = (struct tmgi_to_clnt_info_update *)buffer;
  680. embms_conf.embms_data_port = info_update->data_port;
  681. udph_global->source = embms_conf.embms_data_port;
  682. memset(embms_conf.embms_iface, 0, EMBMS_MAX_IFACE_NAME);
  683. memcpy(embms_conf.embms_iface, info_update->iface_name,
  684. EMBMS_MAX_IFACE_NAME);
  685. embms_conf.embms_tunneling_status = TUNNELING_ON;
  686. embms_debug("Starting Tunneling. Embms_data_port = %d\n",
  687. ntohs(embms_conf.embms_data_port));
  688. embms_debug("Embms Data Iface = %s\n", embms_conf.embms_iface);
  689. ret = SUCCESS;
  690. /*Initialise dev_global to bridge device*/
  691. dev_global = __dev_get_by_name(&init_net, BRIDGE_IFACE);
  692. if (!dev_global) {
  693. embms_error("Error in getting device info\n");
  694. ret = FAILURE;
  695. } else {
  696. iface_dev = (struct in_device *)dev_global->ip_ptr;
  697. iface_info = iface_dev->ifa_list;
  698. while (iface_info) {
  699. if (memcmp(iface_info->ifa_label,
  700. BRIDGE_IFACE,
  701. strlen(BRIDGE_IFACE)) == 0)
  702. break;
  703. iface_info = iface_info->ifa_next;
  704. }
  705. if (iface_info) {
  706. embms_debug("IP address of %s iface is %pI4\n",
  707. BRIDGE_IFACE,
  708. &iface_info->ifa_address);
  709. /*Populate source addr for header*/
  710. iph_global->saddr = iface_info->ifa_address;
  711. ret = SUCCESS;
  712. } else {
  713. embms_debug("Could not find iface address\n");
  714. ret = FAILURE;
  715. }
  716. }
  717. break;
  718. case STOP_EMBMS_TUNNEL:
  719. embms_conf.embms_tunneling_status = TUNNELING_OFF;
  720. embms_debug("Stopped Tunneling..\n");
  721. ret = SUCCESS;
  722. break;
  723. }
  724. return ret;
  725. }
  726. /* Module Declarations
  727. * This structure will hold the functions to be called
  728. * when a process does something to the device we
  729. * created. Since a pointer to this structure is kept in
  730. * the devices table, it can't be local to
  731. * init_module. NULL is for unimplemented functions.
  732. */
  733. static const struct file_operations embms_device_fops = {
  734. .owner = THIS_MODULE,
  735. .open = embms_device_open,
  736. .release = embms_device_release,
  737. .read = NULL,
  738. .write = NULL,
  739. .unlocked_ioctl = embms_device_ioctl,
  740. };
  741. static int embms_ioctl_init(void)
  742. {
  743. int ret;
  744. struct device *dev;
  745. ret = alloc_chrdev_region(&device, 0, dev_num, EMBMS_DEVICE_NAME);
  746. if (ret) {
  747. embms_error("device_alloc err\n");
  748. goto dev_alloc_err;
  749. }
  750. embms_class = class_create(THIS_MODULE, EMBMS_DEVICE_NAME);
  751. if (IS_ERR(embms_class)) {
  752. embms_error("class_create err\n");
  753. goto class_err;
  754. }
  755. dev = device_create(embms_class, NULL, device,
  756. &embms_conf, EMBMS_DEVICE_NAME);
  757. if (IS_ERR(dev)) {
  758. embms_error("device_create err\n");
  759. goto device_err;
  760. }
  761. cdev_init(&embms_device, &embms_device_fops);
  762. ret = cdev_add(&embms_device, device, dev_num);
  763. if (ret) {
  764. embms_error("cdev_add err\n");
  765. goto cdev_add_err;
  766. }
  767. embms_debug("ioctl init OK!!\n");
  768. return 0;
  769. cdev_add_err:
  770. device_destroy(embms_class, device);
  771. device_err:
  772. class_destroy(embms_class);
  773. class_err:
  774. unregister_chrdev_region(device, dev_num);
  775. dev_alloc_err:
  776. return -ENODEV;
  777. }
  778. static void embms_ioctl_deinit(void)
  779. {
  780. cdev_del(&embms_device);
  781. device_destroy(embms_class, device);
  782. class_destroy(embms_class);
  783. unregister_chrdev_region(device, dev_num);
  784. }
  785. /*Initialize the module - Register the misc device*/
  786. static int __init start_embms(void)
  787. {
  788. int ret = 0;
  789. iph_global = (struct iphdr *)hdr_buff;
  790. udph_global = (struct udphdr *)(hdr_buff + sizeof(struct iphdr));
  791. embms_conf.embms_tunneling_status = TUNNELING_OFF;
  792. embms_conf.no_of_tmgi_sessions = 0;
  793. embms_conf.embms_data_port = 0;
  794. atomic_set(&embms_conf.device_under_use, 0);
  795. atomic_set(&embms_conf.ip_ident, 0);
  796. spin_lock_init(&embms_conf.lock);
  797. embms_debug("Registering embms device\n");
  798. ret = embms_ioctl_init();
  799. if (ret) {
  800. embms_error("embms device failed to register");
  801. goto fail_init;
  802. }
  803. INIT_LIST_HEAD(&tmgi_to_clnt_map_tbl.tmgi_list_ptr);
  804. memset(hdr_buff, 0, sizeof(struct udphdr) + sizeof(struct iphdr));
  805. udph_global->check = UDP_CHECKSUM;
  806. iph_global->version = IP_VERSION;
  807. iph_global->ihl = IP_IHL;
  808. iph_global->tos = IP_TOS;
  809. iph_global->frag_off = IP_FRAG_OFFSET;
  810. iph_global->ttl = IP_TTL;
  811. iph_global->protocol = IPPROTO_UDP;
  812. dev_global = NULL;
  813. if (!embms_tm_multicast_recv)
  814. RCU_INIT_POINTER(embms_tm_multicast_recv,
  815. handle_multicast_stream);
  816. return ret;
  817. fail_init:
  818. embms_ioctl_deinit();
  819. return ret;
  820. }
  821. /*Cleanup - unregister the appropriate file from proc*/
  822. static void __exit stop_embms(void)
  823. {
  824. embms_ioctl_deinit();
  825. if (rcu_dereference(embms_tm_multicast_recv))
  826. RCU_INIT_POINTER(embms_tm_multicast_recv, NULL);
  827. embms_debug("unregister_chrdev done\n");
  828. }
  829. module_init(start_embms);
  830. module_exit(stop_embms);
  831. MODULE_LICENSE("GPL v2");