PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/nw-sae-gw/NwSaeGwMain.c

https://github.com/drb999/nwEPC---EPC-SAE-Gateway
C | 440 lines | 310 code | 65 blank | 65 comment | 88 complexity | 0127b47c6e20a16f5101c45310119a19 MD5 | raw file
  1. /*----------------------------------------------------------------------------*
  2. * *
  3. * n w - e p c *
  4. * L T E / S A E S E R V I N G / P D N G A T E W A Y *
  5. * *
  6. * *
  7. * Copyright (c) 2010-2011 Amit Chawre *
  8. * All rights reserved. *
  9. * *
  10. * Redistribution and use in source and binary forms, with or without *
  11. * modification, are permitted provided that the following conditions *
  12. * are met: *
  13. * *
  14. * 1. Redistributions of source code must retain the above copyright *
  15. * notice, this list of conditions and the following disclaimer. *
  16. * 2. Redistributions in binary form must reproduce the above copyright *
  17. * notice, this list of conditions and the following disclaimer in the *
  18. * documentation and/or other materials provided with the distribution. *
  19. * 3. The name of the author may not be used to endorse or promote products *
  20. * derived from this software without specific prior written permission. *
  21. * *
  22. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
  24. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
  25. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
  27. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
  28. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
  29. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
  32. *----------------------------------------------------------------------------*/
  33. /**
  34. * @file NwSaeGwMain.c
  35. * @brief This main file demostrates usage of nw-gtpv2c library for a SAE gateway(SGW/PGW)
  36. * application.
  37. */
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include <assert.h>
  41. #include <sys/socket.h>
  42. #include <arpa/inet.h>
  43. #include <stdio.h>
  44. #include <unistd.h>
  45. #include <errno.h>
  46. #include <fcntl.h>
  47. #include "NwEvt.h"
  48. #include "NwLog.h"
  49. #include "NwMem.h"
  50. #include "NwUtils.h"
  51. #include "NwSaeGwLog.h"
  52. #include "NwLogMgr.h"
  53. #include "NwGtpv2c.h"
  54. #include "NwSaeGwUe.h"
  55. #include "NwSaeGwUlp.h"
  56. #include "NwGtpv2cIf.h"
  57. #include "NwSaeGwDpe.h"
  58. #ifdef __cplusplus
  59. extern "C" {
  60. #endif
  61. #define NW_SAE_GW_MAX_GW_INSTANCE (10)
  62. typedef struct
  63. {
  64. NwU8T isCombinedGw;
  65. NwU8T apn[1024];
  66. NwU32T ippoolSubnet;
  67. NwU32T ippoolMask;
  68. NwU32T numOfUe;
  69. NwGtpv2cIfT udp;
  70. struct {
  71. NwU32T s11cIpv4Addr;
  72. NwU32T s5cIpv4Addr;
  73. NwU32T s4cIpv4Addr;
  74. NwU32T s1uIpv4Addr;
  75. NwSaeGwUlpT *pGw;
  76. } sgwUlp;
  77. struct {
  78. NwU32T s5cIpv4Addr;
  79. NwU32T s5uIpv4Addr;
  80. NwSaeGwUlpT *pGw;
  81. } pgwUlp;
  82. struct {
  83. NwSaeGwDpeT *pDpe; /*< Data Plane Entity */
  84. NwU32T gtpuIpv4Addr;
  85. NwU8T sgiNwIfName[128];
  86. } dataPlane;
  87. } NwSaeGwT;
  88. NwRcT
  89. nwSaeGwCmdLineHelp()
  90. {
  91. printf("\nSupported command line arguments are:\n");
  92. printf("\n+----------------------+-------------+----------------------------------------+");
  93. printf("\n| ARGUMENT | PRESENCE | DESCRIPTION |");
  94. printf("\n+----------------------+-------------+----------------------------------------+");
  95. printf("\n| --sgw-s11-ip | -ss11 | MANDATORY | S11 control IP address of the SGW. |");
  96. printf("\n| --sgw-s5-ip | -ss5 | MANDATORY | S5 control IP address of the SGW. |");
  97. printf("\n| --sgw-s4-ip | -ss4 | OPTIONAL | S4 control IP address of the SGW. |");
  98. printf("\n| --pgw-s5-ip | -ps5 | MANDATORY | S5 control IP address of the PGW. |");
  99. printf("\n| --gtpu-ip | -gi | MANDATORY | IP address for the GTPU User Plane. |");
  100. printf("\n| --apn | -ap | MANDATORY | Access Point Name to be served. |");
  101. printf("\n| --ippool-subnet| -is | MANDATORY | IPv4 address pool for UEs. |");
  102. printf("\n| --ippool-mask | -im | MANDATORY | IPv4 address pool for UEs. |");
  103. printf("\n| --sgi-if | -si | OPTIONAL | Network interface name for the SGi. |");
  104. printf("\n| --max-ue | -mu | OPTIONAL | Maximum number of UEs to support. |");
  105. printf("\n| --combined-gw | -cgw | OPTIONAL | Combine SGW and PGW funtions. |");
  106. printf("\n+----------------------+-------------+----------------------------------------+");
  107. printf("\n\nExample Usage: \n$ nwLteSaeGw --sgw-s11-ip 10.124.25.153 --sgw-s5-ip 192.168.0.1 --pgw-s5-ip 192.168.139.5 --gtpu-ip 10.124.25.153 --sgi-if eth0 --ippool-subnet 10.66.10.0 --ippool-mask 255.255.255.0 -cgw");
  108. printf("\n");
  109. exit(0);
  110. }
  111. NwRcT
  112. nwSaeGwParseCmdLineOpts(NwSaeGwT* thiz, int argc, char* argv[])
  113. {
  114. NwRcT rc = NW_OK;
  115. int i = 0;
  116. if(argc < 2)
  117. return NW_FAILURE;
  118. /* Set default values */
  119. thiz->isCombinedGw = NW_FALSE;
  120. thiz->numOfUe = 1000;
  121. thiz->ippoolSubnet = ntohl(inet_addr("192.168.128.0"));
  122. thiz->ippoolMask = ntohl(inet_addr("255.255.255.0"));
  123. strcpy((char*)thiz->dataPlane.sgiNwIfName, "");
  124. i++;
  125. while( i < argc )
  126. {
  127. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "Processing cmdline arg %s", argv[i]);
  128. if((strcmp("--sgw-s11-ip", argv[i]) == 0)
  129. || (strcmp(argv[i], "-ss11") == 0))
  130. {
  131. i++;
  132. if(i >= argc)
  133. return NW_FAILURE;
  134. thiz->sgwUlp.s11cIpv4Addr = ntohl(inet_addr(argv[i]));
  135. }
  136. else if((strcmp("--sgw-s5-ip", argv[i]) == 0)
  137. || (strcmp(argv[i], "-ss5") == 0))
  138. {
  139. i++;
  140. if(i >= argc)
  141. return NW_FAILURE;
  142. thiz->sgwUlp.s5cIpv4Addr = ntohl(inet_addr(argv[i]));
  143. }
  144. else if((strcmp("--sgw-s4-ip", argv[i]) == 0)
  145. || (strcmp(argv[i], "-ss4") == 0))
  146. {
  147. i++;
  148. if(i >= argc)
  149. return NW_FAILURE;
  150. thiz->sgwUlp.s4cIpv4Addr = ntohl(inet_addr(argv[i]));
  151. }
  152. else if((strcmp("--pgw-s5-ip", argv[i]) == 0)
  153. || (strcmp(argv[i], "-ps5") == 0))
  154. {
  155. i++;
  156. if(i >= argc)
  157. return NW_FAILURE;
  158. thiz->pgwUlp.s5cIpv4Addr = ntohl(inet_addr(argv[i]));
  159. }
  160. else if((strcmp("--apn", argv[i]) == 0)
  161. || (strcmp(argv[i], "-ap") == 0))
  162. {
  163. i++;
  164. if(i >= argc)
  165. return NW_FAILURE;
  166. strncpy((char*)thiz->apn, argv[i], 1023);
  167. }
  168. else if((strcmp("--ippool-subnet", argv[i]) == 0)
  169. || (strcmp(argv[i], "-is") == 0))
  170. {
  171. i++;
  172. if(i >= argc)
  173. return NW_FAILURE;
  174. thiz->ippoolSubnet = ntohl(inet_addr(argv[i]));
  175. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "IP pool subnet address %s", argv[i]);
  176. }
  177. else if((strcmp("--ippool-mask", argv[i]) == 0)
  178. || (strcmp(argv[i], "-im") == 0))
  179. {
  180. i++;
  181. if(i >= argc)
  182. return NW_FAILURE;
  183. thiz->ippoolMask = ntohl(inet_addr(argv[i]));
  184. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "Ip pool mask %s", argv[i]);
  185. }
  186. else if((strcmp("--gtpu-ip", argv[i]) == 0)
  187. || (strcmp(argv[i], "-gi") == 0))
  188. {
  189. i++;
  190. if(i >= argc)
  191. return NW_FAILURE;
  192. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "User Plane IP address %s", argv[i]);
  193. thiz->dataPlane.gtpuIpv4Addr = ntohl(inet_addr(argv[i]));
  194. }
  195. else if((strcmp("--sgi-if", argv[i]) == 0)
  196. || (strcmp(argv[i], "-si") == 0))
  197. {
  198. i++;
  199. if(i >= argc)
  200. return NW_FAILURE;
  201. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "SGi network inteface name %s", argv[i]);
  202. strcpy((char*)thiz->dataPlane.sgiNwIfName, (argv[i]));
  203. }
  204. else if((strcmp("--num-of-ue", argv[i]) == 0)
  205. || (strcmp(argv[i], "-nu") == 0))
  206. {
  207. i++;
  208. if(i >= argc)
  209. return NW_FAILURE;
  210. NW_SAE_GW_LOG(NW_LOG_LEVEL_DEBG, "number of UE %s", argv[i]);
  211. thiz->numOfUe = atoi(argv[i]);
  212. }
  213. else if((strcmp("--combined-gw", argv[i]) == 0)
  214. || (strcmp(argv[i], "-cgw") == 0))
  215. {
  216. thiz->isCombinedGw = NW_TRUE;
  217. }
  218. else if((strcmp("--help", argv[i]) == 0)
  219. || (strcmp(argv[i], "-h") == 0))
  220. {
  221. nwSaeGwCmdLineHelp();
  222. }
  223. else
  224. {
  225. rc = NW_FAILURE;
  226. }
  227. i++;
  228. }
  229. return rc;
  230. }
  231. NwRcT
  232. nwSaeGwInitialize(NwSaeGwT* thiz)
  233. {
  234. NwRcT rc = NW_OK;
  235. NwSaeGwUlpT* pGw;
  236. NwSaeGwUlpConfigT cfg;
  237. /* Create Data Plane instance. */
  238. thiz->dataPlane.pDpe = nwSaeGwDpeInitialize();
  239. /* Create SGW and PGW ULP instances. */
  240. if(thiz->sgwUlp.s11cIpv4Addr)
  241. {
  242. NW_SAE_GW_LOG(NW_LOG_LEVEL_NOTI, "Creating SGW instance with S11 IPv4 address "NW_IPV4_ADDR, NW_IPV4_ADDR_FORMAT(htonl(thiz->sgwUlp.s11cIpv4Addr)));
  243. cfg.maxUeSessions = thiz->numOfUe;
  244. cfg.ippoolSubnet = thiz->ippoolSubnet;
  245. cfg.ippoolMask = thiz->ippoolMask;
  246. cfg.s11cIpv4Addr = thiz->sgwUlp.s11cIpv4Addr;
  247. cfg.s5cIpv4AddrSgw = thiz->sgwUlp.s5cIpv4Addr;
  248. cfg.s4cIpv4AddrSgw = thiz->sgwUlp.s4cIpv4Addr;
  249. cfg.pDpe = thiz->dataPlane.pDpe;
  250. strncpy((char*)cfg.apn, (const char*)thiz->apn, 1023);
  251. pGw = nwSaeGwUlpNew();
  252. rc = nwSaeGwUlpInitialize(pGw, NW_SAE_GW_TYPE_SGW, &cfg);
  253. NW_ASSERT( NW_OK == rc );
  254. thiz->sgwUlp.pGw = pGw;
  255. }
  256. if(thiz->pgwUlp.s5cIpv4Addr)
  257. {
  258. NW_SAE_GW_LOG(NW_LOG_LEVEL_NOTI, "Creating PGW instance with S5 Ipv4 address "NW_IPV4_ADDR, NW_IPV4_ADDR_FORMAT(htonl(thiz->pgwUlp.s5cIpv4Addr)));
  259. cfg.maxUeSessions = thiz->numOfUe;
  260. cfg.ippoolSubnet = thiz->ippoolSubnet;
  261. cfg.ippoolMask = thiz->ippoolMask;
  262. cfg.s5cIpv4AddrPgw = thiz->pgwUlp.s5cIpv4Addr;
  263. cfg.pDpe = thiz->dataPlane.pDpe;
  264. strncpy((char*)cfg.apn, (const char*)thiz->apn, 1023);
  265. pGw = nwSaeGwUlpNew();
  266. rc = nwSaeGwUlpInitialize(pGw, NW_SAE_GW_TYPE_PGW, &cfg);
  267. NW_ASSERT( NW_OK == rc );
  268. thiz->pgwUlp.pGw = pGw;
  269. }
  270. /* Register collocated PGW, if any */
  271. if(thiz->isCombinedGw &&
  272. (thiz->sgwUlp.pGw && thiz->pgwUlp.pGw))
  273. {
  274. rc = nwSaeGwUlpRegisterCollocatedPgw(thiz->sgwUlp.pGw, thiz->pgwUlp.pGw);
  275. NW_ASSERT(NW_OK == rc);
  276. }
  277. if(thiz->dataPlane.gtpuIpv4Addr)
  278. {
  279. rc = nwSaeGwDpeCreateGtpuService(thiz->dataPlane.pDpe, thiz->dataPlane.gtpuIpv4Addr);
  280. }
  281. if(strlen((const char*)(thiz->dataPlane.sgiNwIfName)) != 0)
  282. {
  283. rc = nwSaeGwDpeCreateIpv4Service(thiz->dataPlane.pDpe, thiz->dataPlane.sgiNwIfName);
  284. }
  285. return rc;
  286. }
  287. NwRcT
  288. nwSaeGwFinalize(NwSaeGwT* thiz)
  289. {
  290. return NW_OK;
  291. }
  292. /*---------------------------------------------------------------------------
  293. * T H E M A I N F U N C T I O N
  294. *--------------------------------------------------------------------------*/
  295. int main(int argc, char* argv[])
  296. {
  297. NwRcT rc;
  298. NwSaeGwT saeGw;
  299. memset(&saeGw, 0, sizeof(NwSaeGwT));
  300. /*---------------------------------------------------------------------------
  301. * Parse Commandline Arguments
  302. *--------------------------------------------------------------------------*/
  303. rc = nwSaeGwParseCmdLineOpts(&saeGw, argc, argv);
  304. if(rc != NW_OK)
  305. {
  306. printf("\nUsage error. Please refer help.\n\n");
  307. exit(0);
  308. }
  309. printf("\n");
  310. printf(" *----------------------------------------------------------------------------*\n");
  311. printf(" * n w - e p c *\n");
  312. printf(" * L T E / S A E S E R V I N G / P D N G A T E W A Y *\n");
  313. printf(" * *\n");
  314. printf(" * Copyright (c) 2010-2011 Amit Chawre *\n");
  315. printf(" * All rights reserved. *\n");
  316. printf(" * *\n");
  317. printf(" * Redistribution and use in source and binary forms, with or without *\n");
  318. printf(" * modification, are permitted provided that the following conditions *\n");
  319. printf(" * are met: *\n");
  320. printf(" * *\n");
  321. printf(" * 1. Redistributions of source code must retain the above copyright *\n");
  322. printf(" * notice, this list of conditions and the following disclaimer. *\n");
  323. printf(" * 2. Redistributions in binary form must reproduce the above copyright *\n");
  324. printf(" * notice, this list of conditions and the following disclaimer in the *\n");
  325. printf(" * documentation and/or other materials provided with the distribution. *\n");
  326. printf(" * 3. The name of the author may not be used to endorse or promote products *\n");
  327. printf(" * derived from this software without specific prior written permission. *\n");
  328. printf(" * *\n");
  329. printf(" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *\n");
  330. printf(" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *\n");
  331. printf(" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *\n");
  332. printf(" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *\n");
  333. printf(" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *\n");
  334. printf(" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *\n");
  335. printf(" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *\n");
  336. printf(" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *\n");
  337. printf(" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *\n");
  338. printf(" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *\n");
  339. printf(" *----------------------------------------------------------------------------*\n\n");
  340. /*---------------------------------------------------------------------------
  341. * Initialize event library
  342. *--------------------------------------------------------------------------*/
  343. NW_EVT_INIT();
  344. /*---------------------------------------------------------------------------
  345. * Initialize Memory Manager
  346. *--------------------------------------------------------------------------*/
  347. rc = nwMemInitialize();
  348. NW_ASSERT(NW_OK == rc);
  349. /*---------------------------------------------------------------------------
  350. * Initialize LogMgr
  351. *--------------------------------------------------------------------------*/
  352. rc = nwLogMgrInit(nwLogMgrGetInstance(), (NwU8T*)"NW-SAEGW", getpid());
  353. NW_ASSERT(NW_OK == rc);
  354. /*---------------------------------------------------------------------------
  355. * Initialize SAE GW
  356. *--------------------------------------------------------------------------*/
  357. rc = nwSaeGwInitialize(&saeGw);
  358. NW_ASSERT(NW_OK == rc);
  359. /*---------------------------------------------------------------------------
  360. * Event Loop
  361. *--------------------------------------------------------------------------*/
  362. NW_EVT_LOOP();
  363. NW_SAE_GW_LOG(NW_LOG_LEVEL_ERRO, "Exit from eventloop, no events to process!");
  364. /*---------------------------------------------------------------------------
  365. * Finalize SAE GW
  366. *--------------------------------------------------------------------------*/
  367. rc = nwSaeGwFinalize(&saeGw);
  368. NW_ASSERT(NW_OK == rc);
  369. rc = nwMemFinalize();
  370. NW_ASSERT(NW_OK == rc);
  371. return 0;
  372. }
  373. #ifdef __cplusplus
  374. }
  375. #endif