rt_socket.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. * Kernel routing table updates by routing socket.
  3. * Copyright (C) 1997, 98 Kunihiro Ishiguro
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  19. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. * 02111-1307, USA.
  21. */
  22. #include <zebra.h>
  23. #include "if.h"
  24. #include "prefix.h"
  25. #include "sockunion.h"
  26. #include "log.h"
  27. #include "str.h"
  28. #include "privs.h"
  29. #include "zebra/debug.h"
  30. #include "zebra/rib.h"
  31. extern struct zebra_privs_t zserv_privs;
  32. int
  33. rtm_write (int message,
  34. union sockunion *dest,
  35. union sockunion *mask,
  36. union sockunion *gate,
  37. unsigned int index,
  38. int zebra_flags,
  39. int metric);
  40. /* Adjust netmask socket length. Return value is a adjusted sin_len
  41. value. */
  42. int
  43. sin_masklen (struct in_addr mask)
  44. {
  45. char *p, *lim;
  46. int len;
  47. struct sockaddr_in sin;
  48. if (mask.s_addr == 0)
  49. return sizeof (long);
  50. sin.sin_addr = mask;
  51. len = sizeof (struct sockaddr_in);
  52. lim = (char *) &sin.sin_addr;
  53. p = lim + sizeof (sin.sin_addr);
  54. while (*--p == 0 && p >= lim)
  55. len--;
  56. return len;
  57. }
  58. /* Interface between zebra message and rtm message. */
  59. int
  60. kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
  61. {
  62. struct sockaddr_in *mask = NULL;
  63. struct sockaddr_in sin_dest, sin_mask, sin_gate;
  64. struct nexthop *nexthop;
  65. int nexthop_num = 0;
  66. unsigned int ifindex = 0;
  67. int gate = 0;
  68. int error;
  69. memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  70. sin_dest.sin_family = AF_INET;
  71. #ifdef HAVE_SIN_LEN
  72. sin_dest.sin_len = sizeof (struct sockaddr_in);
  73. #endif /* HAVE_SIN_LEN */
  74. sin_dest.sin_addr = p->u.prefix4;
  75. memset (&sin_mask, 0, sizeof (struct sockaddr_in));
  76. memset (&sin_gate, 0, sizeof (struct sockaddr_in));
  77. sin_gate.sin_family = AF_INET;
  78. #ifdef HAVE_SIN_LEN
  79. sin_gate.sin_len = sizeof (struct sockaddr_in);
  80. #endif /* HAVE_SIN_LEN */
  81. /* Make gateway. */
  82. for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  83. {
  84. gate = 0;
  85. if ((cmd == RTM_ADD
  86. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  87. || (cmd == RTM_DELETE
  88. #if 0
  89. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  90. #endif
  91. ))
  92. {
  93. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  94. {
  95. if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
  96. nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
  97. {
  98. sin_gate.sin_addr = nexthop->rgate.ipv4;
  99. gate = 1;
  100. }
  101. if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
  102. || nexthop->rtype == NEXTHOP_TYPE_IFNAME
  103. || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
  104. ifindex = nexthop->rifindex;
  105. }
  106. else
  107. {
  108. if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
  109. nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  110. {
  111. sin_gate.sin_addr = nexthop->gate.ipv4;
  112. gate = 1;
  113. }
  114. if (nexthop->type == NEXTHOP_TYPE_IFINDEX
  115. || nexthop->type == NEXTHOP_TYPE_IFNAME
  116. || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  117. ifindex = nexthop->ifindex;
  118. if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
  119. {
  120. struct in_addr loopback;
  121. loopback.s_addr = htonl (INADDR_LOOPBACK);
  122. sin_gate.sin_addr = loopback;
  123. gate = 1;
  124. }
  125. }
  126. if (cmd == RTM_ADD)
  127. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  128. if (gate && p->prefixlen == 32)
  129. mask = NULL;
  130. else
  131. {
  132. masklen2ip (p->prefixlen, &sin_mask.sin_addr);
  133. sin_mask.sin_family = AF_UNSPEC;
  134. #ifdef HAVE_SIN_LEN
  135. sin_mask.sin_len = sin_masklen (sin_mask.sin_addr);
  136. #endif /* HAVE_SIN_LEN */
  137. mask = &sin_mask;
  138. }
  139. }
  140. error = rtm_write (cmd,
  141. (union sockunion *)&sin_dest,
  142. (union sockunion *)mask,
  143. gate ? (union sockunion *)&sin_gate : NULL,
  144. ifindex,
  145. rib->flags,
  146. rib->metric);
  147. #if 0
  148. if (error)
  149. {
  150. zlog_info ("kernel_rtm_ipv4(): nexthop %d add error=%d.",
  151. nexthop_num, error);
  152. }
  153. #endif
  154. nexthop_num++;
  155. }
  156. /* If there is no useful nexthop then return. */
  157. if (nexthop_num == 0)
  158. {
  159. if (IS_ZEBRA_DEBUG_KERNEL)
  160. zlog_info ("kernel_rtm_ipv4(): No useful nexthop.");
  161. return 0;
  162. }
  163. return 0; /*XXX*/
  164. }
  165. int
  166. kernel_add_ipv4 (struct prefix *p, struct rib *rib)
  167. {
  168. int route;
  169. if (zserv_privs.change(ZPRIVS_RAISE))
  170. zlog (NULL, LOG_ERR, "Can't raise privileges");
  171. route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET);
  172. if (zserv_privs.change(ZPRIVS_LOWER))
  173. zlog (NULL, LOG_ERR, "Can't lower privileges");
  174. return route;
  175. }
  176. int
  177. kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
  178. {
  179. int route;
  180. if (zserv_privs.change(ZPRIVS_RAISE))
  181. zlog (NULL, LOG_ERR, "Can't raise privileges");
  182. route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET);
  183. if (zserv_privs.change(ZPRIVS_LOWER))
  184. zlog (NULL, LOG_ERR, "Can't lower privileges");
  185. return route;
  186. }
  187. #ifdef HAVE_IPV6
  188. /* Calculate sin6_len value for netmask socket value. */
  189. int
  190. sin6_masklen (struct in6_addr mask)
  191. {
  192. struct sockaddr_in6 sin6;
  193. char *p, *lim;
  194. int len;
  195. #if defined (INRIA)
  196. if (IN_ANYADDR6 (mask))
  197. return sizeof (long);
  198. #else /* ! INRIA */
  199. if (IN6_IS_ADDR_UNSPECIFIED (&mask))
  200. return sizeof (long);
  201. #endif /* ! INRIA */
  202. sin6.sin6_addr = mask;
  203. len = sizeof (struct sockaddr_in6);
  204. lim = (char *) & sin6.sin6_addr;
  205. p = lim + sizeof (sin6.sin6_addr);
  206. while (*--p == 0 && p >= lim)
  207. len--;
  208. return len;
  209. }
  210. /* Interface between zebra message and rtm message. */
  211. int
  212. kernel_rtm_ipv6 (int message, struct prefix_ipv6 *dest,
  213. struct in6_addr *gate, int index, int flags)
  214. {
  215. struct sockaddr_in6 *mask;
  216. struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
  217. memset (&sin_dest, 0, sizeof (struct sockaddr_in6));
  218. sin_dest.sin6_family = AF_INET6;
  219. #ifdef SIN6_LEN
  220. sin_dest.sin6_len = sizeof (struct sockaddr_in6);
  221. #endif /* SIN6_LEN */
  222. memset (&sin_mask, 0, sizeof (struct sockaddr_in6));
  223. memset (&sin_gate, 0, sizeof (struct sockaddr_in6));
  224. sin_gate.sin6_family = AF_INET6;
  225. #ifdef SIN6_LEN
  226. sin_gate.sin6_len = sizeof (struct sockaddr_in6);
  227. #endif /* SIN6_LEN */
  228. sin_dest.sin6_addr = dest->prefix;
  229. if (gate)
  230. memcpy (&sin_gate.sin6_addr, gate, sizeof (struct in6_addr));
  231. /* Under kame set interface index to link local address. */
  232. #ifdef KAME
  233. #define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
  234. do { \
  235. (a).s6_addr[2] = ((i) >> 8) & 0xff; \
  236. (a).s6_addr[3] = (i) & 0xff; \
  237. } while (0)
  238. if (gate && IN6_IS_ADDR_LINKLOCAL(gate))
  239. SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, index);
  240. #endif /* KAME */
  241. if (gate && dest->prefixlen == 128)
  242. mask = NULL;
  243. else
  244. {
  245. masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);
  246. sin_mask.sin6_family = AF_UNSPEC;
  247. #ifdef SIN6_LEN
  248. sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
  249. #endif /* SIN6_LEN */
  250. mask = &sin_mask;
  251. }
  252. return rtm_write (message,
  253. (union sockunion *) &sin_dest,
  254. (union sockunion *) mask,
  255. gate ? (union sockunion *)&sin_gate : NULL,
  256. index,
  257. flags,
  258. 0);
  259. }
  260. /* Interface between zebra message and rtm message. */
  261. int
  262. kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
  263. int family)
  264. {
  265. struct sockaddr_in6 *mask;
  266. struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
  267. struct nexthop *nexthop;
  268. int nexthop_num = 0;
  269. unsigned int ifindex = 0;
  270. int gate = 0;
  271. int error;
  272. memset (&sin_dest, 0, sizeof (struct sockaddr_in6));
  273. sin_dest.sin6_family = AF_INET6;
  274. #ifdef SIN6_LEN
  275. sin_dest.sin6_len = sizeof (struct sockaddr_in6);
  276. #endif /* SIN6_LEN */
  277. sin_dest.sin6_addr = p->u.prefix6;
  278. memset (&sin_mask, 0, sizeof (struct sockaddr_in6));
  279. memset (&sin_gate, 0, sizeof (struct sockaddr_in6));
  280. sin_gate.sin6_family = AF_INET6;
  281. #ifdef HAVE_SIN_LEN
  282. sin_gate.sin6_len = sizeof (struct sockaddr_in6);
  283. #endif /* HAVE_SIN_LEN */
  284. /* Make gateway. */
  285. for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  286. {
  287. gate = 0;
  288. if ((cmd == RTM_ADD
  289. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  290. || (cmd == RTM_DELETE
  291. #if 0
  292. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  293. #endif
  294. ))
  295. {
  296. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  297. {
  298. if (nexthop->rtype == NEXTHOP_TYPE_IPV6
  299. || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
  300. || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
  301. {
  302. sin_gate.sin6_addr = nexthop->rgate.ipv6;
  303. gate = 1;
  304. }
  305. if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
  306. || nexthop->rtype == NEXTHOP_TYPE_IFNAME
  307. || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
  308. || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
  309. ifindex = nexthop->rifindex;
  310. }
  311. else
  312. {
  313. if (nexthop->type == NEXTHOP_TYPE_IPV6
  314. || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  315. || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  316. {
  317. sin_gate.sin6_addr = nexthop->gate.ipv6;
  318. gate = 1;
  319. }
  320. if (nexthop->type == NEXTHOP_TYPE_IFINDEX
  321. || nexthop->type == NEXTHOP_TYPE_IFNAME
  322. || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  323. || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  324. ifindex = nexthop->ifindex;
  325. }
  326. if (cmd == RTM_ADD)
  327. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  328. }
  329. /* Under kame set interface index to link local address. */
  330. #ifdef KAME
  331. #define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
  332. do { \
  333. (a).s6_addr[2] = ((i) >> 8) & 0xff; \
  334. (a).s6_addr[3] = (i) & 0xff; \
  335. } while (0)
  336. if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr))
  337. SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, ifindex);
  338. #endif /* KAME */
  339. if (gate && p->prefixlen == 128)
  340. mask = NULL;
  341. else
  342. {
  343. masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr);
  344. sin_mask.sin6_family = AF_UNSPEC;
  345. #ifdef SIN6_LEN
  346. sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
  347. #endif /* SIN6_LEN */
  348. mask = &sin_mask;
  349. }
  350. error = rtm_write (cmd,
  351. (union sockunion *) &sin_dest,
  352. (union sockunion *) mask,
  353. gate ? (union sockunion *)&sin_gate : NULL,
  354. ifindex,
  355. rib->flags,
  356. rib->metric);
  357. #if 0
  358. if (error)
  359. {
  360. zlog_info ("kernel_rtm_ipv6_multipath(): nexthop %d add error=%d.",
  361. nexthop_num, error);
  362. }
  363. #endif
  364. nexthop_num++;
  365. }
  366. /* If there is no useful nexthop then return. */
  367. if (nexthop_num == 0)
  368. {
  369. if (IS_ZEBRA_DEBUG_KERNEL)
  370. zlog_info ("kernel_rtm_ipv6_multipath(): No useful nexthop.");
  371. return 0;
  372. }
  373. return 0; /*XXX*/
  374. }
  375. int
  376. kernel_add_ipv6 (struct prefix *p, struct rib *rib)
  377. {
  378. int route;
  379. if (zserv_privs.change(ZPRIVS_RAISE))
  380. zlog (NULL, LOG_ERR, "Can't raise privileges");
  381. route = kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6);
  382. if (zserv_privs.change(ZPRIVS_LOWER))
  383. zlog (NULL, LOG_ERR, "Can't lower privileges");
  384. return route;
  385. }
  386. int
  387. kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
  388. {
  389. int route;
  390. if (zserv_privs.change(ZPRIVS_RAISE))
  391. zlog (NULL, LOG_ERR, "Can't raise privileges");
  392. route = kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6);
  393. if (zserv_privs.change(ZPRIVS_LOWER))
  394. zlog (NULL, LOG_ERR, "Can't lower privileges");
  395. return route;
  396. }
  397. /* Delete IPv6 route from the kernel. */
  398. int
  399. kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
  400. int index, int flags, int table)
  401. {
  402. int route;
  403. if (zserv_privs.change(ZPRIVS_RAISE))
  404. zlog (NULL, LOG_ERR, "Can't raise privileges");
  405. route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags);
  406. if (zserv_privs.change(ZPRIVS_LOWER))
  407. zlog (NULL, LOG_ERR, "Can't lower privileges");
  408. return route;
  409. }
  410. #endif /* HAVE_IPV6 */