rt_netlink.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005
  1. /* Kernel routing table updates using netlink over GNU/Linux system.
  2. * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. /* Hack for GNU libc version 2. */
  23. #ifndef MSG_TRUNC
  24. #define MSG_TRUNC 0x20
  25. #endif /* MSG_TRUNC */
  26. #include "linklist.h"
  27. #include "if.h"
  28. #include "log.h"
  29. #include "prefix.h"
  30. #include "connected.h"
  31. #include "table.h"
  32. #include "memory.h"
  33. #include "rib.h"
  34. #include "thread.h"
  35. #include "privs.h"
  36. #include "zebra/zserv.h"
  37. #include "zebra/rt.h"
  38. #include "zebra/redistribute.h"
  39. #include "zebra/interface.h"
  40. #include "zebra/debug.h"
  41. #include "rt_netlink.h"
  42. /* Socket interface to kernel */
  43. struct nlsock
  44. {
  45. int sock;
  46. int seq;
  47. struct sockaddr_nl snl;
  48. const char *name;
  49. } netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
  50. netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
  51. static const struct message nlmsg_str[] = {
  52. {RTM_NEWROUTE, "RTM_NEWROUTE"},
  53. {RTM_DELROUTE, "RTM_DELROUTE"},
  54. {RTM_GETROUTE, "RTM_GETROUTE"},
  55. {RTM_NEWLINK, "RTM_NEWLINK"},
  56. {RTM_DELLINK, "RTM_DELLINK"},
  57. {RTM_GETLINK, "RTM_GETLINK"},
  58. {RTM_NEWADDR, "RTM_NEWADDR"},
  59. {RTM_DELADDR, "RTM_DELADDR"},
  60. {RTM_GETADDR, "RTM_GETADDR"},
  61. {0, NULL}
  62. };
  63. extern struct zebra_t zebrad;
  64. extern struct zebra_privs_t zserv_privs;
  65. extern u_int32_t nl_rcvbufsize;
  66. /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
  67. names and ifindex values. */
  68. static void
  69. set_ifindex(struct interface *ifp, unsigned int ifi_index)
  70. {
  71. struct interface *oifp;
  72. if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
  73. {
  74. if (ifi_index == IFINDEX_INTERNAL)
  75. zlog_err("Netlink is setting interface %s ifindex to reserved "
  76. "internal value %u", ifp->name, ifi_index);
  77. else
  78. {
  79. if (IS_ZEBRA_DEBUG_KERNEL)
  80. zlog_debug("interface index %d was renamed from %s to %s",
  81. ifi_index, oifp->name, ifp->name);
  82. if (if_is_up(oifp))
  83. zlog_err("interface rename detected on up interface: index %d "
  84. "was renamed from %s to %s, results are uncertain!",
  85. ifi_index, oifp->name, ifp->name);
  86. if_delete_update(oifp);
  87. }
  88. }
  89. ifp->ifindex = ifi_index;
  90. }
  91. #ifndef SO_RCVBUFFORCE
  92. #define SO_RCVBUFFORCE (33)
  93. #endif
  94. static int
  95. netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
  96. {
  97. u_int32_t oldsize;
  98. socklen_t newlen = sizeof(newsize);
  99. socklen_t oldlen = sizeof(oldsize);
  100. int ret;
  101. ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
  102. if (ret < 0)
  103. {
  104. zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
  105. safe_strerror (errno));
  106. return -1;
  107. }
  108. /* Try force option (linux >= 2.6.14) and fall back to normal set */
  109. if ( zserv_privs.change (ZPRIVS_RAISE) )
  110. zlog_err ("routing_socket: Can't raise privileges");
  111. ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize,
  112. sizeof(nl_rcvbufsize));
  113. if ( zserv_privs.change (ZPRIVS_LOWER) )
  114. zlog_err ("routing_socket: Can't lower privileges");
  115. if (ret < 0)
  116. ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
  117. sizeof(nl_rcvbufsize));
  118. if (ret < 0)
  119. {
  120. zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
  121. safe_strerror (errno));
  122. return -1;
  123. }
  124. ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
  125. if (ret < 0)
  126. {
  127. zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
  128. safe_strerror (errno));
  129. return -1;
  130. }
  131. zlog (NULL, LOG_INFO,
  132. "Setting netlink socket receive buffer size: %u -> %u",
  133. oldsize, newsize);
  134. return 0;
  135. }
  136. /* Make socket for Linux netlink interface. */
  137. static int
  138. netlink_socket (struct nlsock *nl, unsigned long groups)
  139. {
  140. int ret;
  141. struct sockaddr_nl snl;
  142. int sock;
  143. int namelen;
  144. int save_errno;
  145. sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  146. if (sock < 0)
  147. {
  148. zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
  149. safe_strerror (errno));
  150. return -1;
  151. }
  152. memset (&snl, 0, sizeof snl);
  153. snl.nl_family = AF_NETLINK;
  154. snl.nl_groups = groups;
  155. /* Bind the socket to the netlink structure for anything. */
  156. if (zserv_privs.change (ZPRIVS_RAISE))
  157. {
  158. zlog (NULL, LOG_ERR, "Can't raise privileges");
  159. return -1;
  160. }
  161. ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
  162. save_errno = errno;
  163. if (zserv_privs.change (ZPRIVS_LOWER))
  164. zlog (NULL, LOG_ERR, "Can't lower privileges");
  165. if (ret < 0)
  166. {
  167. zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
  168. nl->name, snl.nl_groups, safe_strerror (save_errno));
  169. close (sock);
  170. return -1;
  171. }
  172. /* multiple netlink sockets will have different nl_pid */
  173. namelen = sizeof snl;
  174. ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
  175. if (ret < 0 || namelen != sizeof snl)
  176. {
  177. zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
  178. safe_strerror (errno));
  179. close (sock);
  180. return -1;
  181. }
  182. nl->snl = snl;
  183. nl->sock = sock;
  184. return ret;
  185. }
  186. /* Get type specified information from netlink. */
  187. static int
  188. netlink_request (int family, int type, struct nlsock *nl)
  189. {
  190. int ret;
  191. struct sockaddr_nl snl;
  192. int save_errno;
  193. struct
  194. {
  195. struct nlmsghdr nlh;
  196. struct rtgenmsg g;
  197. } req;
  198. /* Check netlink socket. */
  199. if (nl->sock < 0)
  200. {
  201. zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
  202. return -1;
  203. }
  204. memset (&snl, 0, sizeof snl);
  205. snl.nl_family = AF_NETLINK;
  206. memset (&req, 0, sizeof req);
  207. req.nlh.nlmsg_len = sizeof req;
  208. req.nlh.nlmsg_type = type;
  209. req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
  210. req.nlh.nlmsg_pid = nl->snl.nl_pid;
  211. req.nlh.nlmsg_seq = ++nl->seq;
  212. req.g.rtgen_family = family;
  213. /* linux appears to check capabilities on every message
  214. * have to raise caps for every message sent
  215. */
  216. if (zserv_privs.change (ZPRIVS_RAISE))
  217. {
  218. zlog (NULL, LOG_ERR, "Can't raise privileges");
  219. return -1;
  220. }
  221. ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
  222. (struct sockaddr *) &snl, sizeof snl);
  223. save_errno = errno;
  224. if (zserv_privs.change (ZPRIVS_LOWER))
  225. zlog (NULL, LOG_ERR, "Can't lower privileges");
  226. if (ret < 0)
  227. {
  228. zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
  229. safe_strerror (save_errno));
  230. return -1;
  231. }
  232. return 0;
  233. }
  234. /* Receive message from netlink interface and pass those information
  235. to the given function. */
  236. static int
  237. netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
  238. struct nlsock *nl)
  239. {
  240. int status;
  241. int ret = 0;
  242. int error;
  243. while (1)
  244. {
  245. char buf[NL_PKT_BUF_SIZE];
  246. struct iovec iov = { buf, sizeof buf };
  247. struct sockaddr_nl snl;
  248. struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
  249. struct nlmsghdr *h;
  250. status = recvmsg (nl->sock, &msg, 0);
  251. if (status < 0)
  252. {
  253. if (errno == EINTR)
  254. continue;
  255. if (errno == EWOULDBLOCK || errno == EAGAIN)
  256. break;
  257. zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
  258. nl->name, safe_strerror(errno));
  259. continue;
  260. }
  261. if (status == 0)
  262. {
  263. zlog (NULL, LOG_ERR, "%s EOF", nl->name);
  264. return -1;
  265. }
  266. if (msg.msg_namelen != sizeof snl)
  267. {
  268. zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
  269. nl->name, msg.msg_namelen);
  270. return -1;
  271. }
  272. for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
  273. h = NLMSG_NEXT (h, status))
  274. {
  275. /* Finish of reading. */
  276. if (h->nlmsg_type == NLMSG_DONE)
  277. return ret;
  278. /* Error handling. */
  279. if (h->nlmsg_type == NLMSG_ERROR)
  280. {
  281. struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
  282. int errnum = err->error;
  283. int msg_type = err->msg.nlmsg_type;
  284. /* If the error field is zero, then this is an ACK */
  285. if (err->error == 0)
  286. {
  287. if (IS_ZEBRA_DEBUG_KERNEL)
  288. {
  289. zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
  290. __FUNCTION__, nl->name,
  291. lookup (nlmsg_str, err->msg.nlmsg_type),
  292. err->msg.nlmsg_type, err->msg.nlmsg_seq,
  293. err->msg.nlmsg_pid);
  294. }
  295. /* return if not a multipart message, otherwise continue */
  296. if (!(h->nlmsg_flags & NLM_F_MULTI))
  297. {
  298. return 0;
  299. }
  300. continue;
  301. }
  302. if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
  303. {
  304. zlog (NULL, LOG_ERR, "%s error: message truncated",
  305. nl->name);
  306. return -1;
  307. }
  308. /* Deal with errors that occur because of races in link handling */
  309. if (nl == &netlink_cmd
  310. && ((msg_type == RTM_DELROUTE &&
  311. (-errnum == ENODEV || -errnum == ESRCH))
  312. || (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
  313. {
  314. if (IS_ZEBRA_DEBUG_KERNEL)
  315. zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
  316. nl->name, safe_strerror (-errnum),
  317. lookup (nlmsg_str, msg_type),
  318. msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
  319. return 0;
  320. }
  321. zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
  322. nl->name, safe_strerror (-errnum),
  323. lookup (nlmsg_str, msg_type),
  324. msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
  325. return -1;
  326. }
  327. /* OK we got netlink message. */
  328. if (IS_ZEBRA_DEBUG_KERNEL)
  329. zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
  330. nl->name,
  331. lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
  332. h->nlmsg_seq, h->nlmsg_pid);
  333. /* skip unsolicited messages originating from command socket
  334. * linux sets the originators port-id for {NEW|DEL}ADDR messages,
  335. * so this has to be checked here. */
  336. if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid
  337. && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
  338. {
  339. if (IS_ZEBRA_DEBUG_KERNEL)
  340. zlog_debug ("netlink_parse_info: %s packet comes from %s",
  341. netlink_cmd.name, nl->name);
  342. continue;
  343. }
  344. error = (*filter) (&snl, h);
  345. if (error < 0)
  346. {
  347. zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
  348. ret = error;
  349. }
  350. }
  351. /* After error care. */
  352. if (msg.msg_flags & MSG_TRUNC)
  353. {
  354. zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
  355. continue;
  356. }
  357. if (status)
  358. {
  359. zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
  360. status);
  361. return -1;
  362. }
  363. }
  364. return ret;
  365. }
  366. /* Utility function for parse rtattr. */
  367. static void
  368. netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
  369. int len)
  370. {
  371. while (RTA_OK (rta, len))
  372. {
  373. if (rta->rta_type <= max)
  374. tb[rta->rta_type] = rta;
  375. rta = RTA_NEXT (rta, len);
  376. }
  377. }
  378. /* Utility function to parse hardware link-layer address and update ifp */
  379. static void
  380. netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
  381. {
  382. int i;
  383. if (tb[IFLA_ADDRESS])
  384. {
  385. int hw_addr_len;
  386. hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
  387. if (hw_addr_len > INTERFACE_HWADDR_MAX)
  388. zlog_warn ("Hardware address is too large: %d", hw_addr_len);
  389. else
  390. {
  391. ifp->hw_addr_len = hw_addr_len;
  392. memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
  393. for (i = 0; i < hw_addr_len; i++)
  394. if (ifp->hw_addr[i] != 0)
  395. break;
  396. if (i == hw_addr_len)
  397. ifp->hw_addr_len = 0;
  398. else
  399. ifp->hw_addr_len = hw_addr_len;
  400. }
  401. }
  402. }
  403. /* Called from interface_lookup_netlink(). This function is only used
  404. during bootstrap. */
  405. static int
  406. netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
  407. {
  408. int len;
  409. struct ifinfomsg *ifi;
  410. struct rtattr *tb[IFLA_MAX + 1];
  411. struct interface *ifp;
  412. char *name;
  413. ifi = NLMSG_DATA (h);
  414. if (h->nlmsg_type != RTM_NEWLINK)
  415. return 0;
  416. len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
  417. if (len < 0)
  418. return -1;
  419. /* Looking up interface name. */
  420. memset (tb, 0, sizeof tb);
  421. netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
  422. #ifdef IFLA_WIRELESS
  423. /* check for wireless messages to ignore */
  424. if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
  425. {
  426. if (IS_ZEBRA_DEBUG_KERNEL)
  427. zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
  428. return 0;
  429. }
  430. #endif /* IFLA_WIRELESS */
  431. if (tb[IFLA_IFNAME] == NULL)
  432. return -1;
  433. name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
  434. /* Add interface. */
  435. ifp = if_get_by_name (name);
  436. set_ifindex(ifp, ifi->ifi_index);
  437. ifp->flags = ifi->ifi_flags & 0x0000fffff;
  438. ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
  439. ifp->metric = 1;
  440. /* Hardware type and address. */
  441. ifp->hw_type = ifi->ifi_type;
  442. netlink_interface_update_hw_addr (tb, ifp);
  443. if_add_update (ifp);
  444. return 0;
  445. }
  446. /* Lookup interface IPv4/IPv6 address. */
  447. static int
  448. netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
  449. {
  450. int len;
  451. struct ifaddrmsg *ifa;
  452. struct rtattr *tb[IFA_MAX + 1];
  453. struct interface *ifp;
  454. void *addr;
  455. void *broad;
  456. u_char flags = 0;
  457. char *label = NULL;
  458. ifa = NLMSG_DATA (h);
  459. if (ifa->ifa_family != AF_INET
  460. #ifdef HAVE_IPV6
  461. && ifa->ifa_family != AF_INET6
  462. #endif /* HAVE_IPV6 */
  463. )
  464. return 0;
  465. if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
  466. return 0;
  467. len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
  468. if (len < 0)
  469. return -1;
  470. memset (tb, 0, sizeof tb);
  471. netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
  472. ifp = if_lookup_by_index (ifa->ifa_index);
  473. if (ifp == NULL)
  474. {
  475. zlog_err ("netlink_interface_addr can't find interface by index %d",
  476. ifa->ifa_index);
  477. return -1;
  478. }
  479. if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
  480. {
  481. char buf[BUFSIZ];
  482. zlog_debug ("netlink_interface_addr %s %s:",
  483. lookup (nlmsg_str, h->nlmsg_type), ifp->name);
  484. if (tb[IFA_LOCAL])
  485. zlog_debug (" IFA_LOCAL %s/%d",
  486. inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
  487. buf, BUFSIZ), ifa->ifa_prefixlen);
  488. if (tb[IFA_ADDRESS])
  489. zlog_debug (" IFA_ADDRESS %s/%d",
  490. inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
  491. buf, BUFSIZ), ifa->ifa_prefixlen);
  492. if (tb[IFA_BROADCAST])
  493. zlog_debug (" IFA_BROADCAST %s/%d",
  494. inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
  495. buf, BUFSIZ), ifa->ifa_prefixlen);
  496. if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
  497. zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL]));
  498. if (tb[IFA_CACHEINFO])
  499. {
  500. struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
  501. zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
  502. ci->ifa_prefered, ci->ifa_valid);
  503. }
  504. }
  505. /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
  506. if (tb[IFA_LOCAL] == NULL)
  507. tb[IFA_LOCAL] = tb[IFA_ADDRESS];
  508. if (tb[IFA_ADDRESS] == NULL)
  509. tb[IFA_ADDRESS] = tb[IFA_LOCAL];
  510. /* local interface address */
  511. addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
  512. /* is there a peer address? */
  513. if (tb[IFA_ADDRESS] &&
  514. memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS])))
  515. {
  516. broad = RTA_DATA(tb[IFA_ADDRESS]);
  517. SET_FLAG (flags, ZEBRA_IFA_PEER);
  518. }
  519. else
  520. /* seeking a broadcast address */
  521. broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL);
  522. /* addr is primary key, SOL if we don't have one */
  523. if (addr == NULL)
  524. {
  525. zlog_debug ("%s: NULL address", __func__);
  526. return -1;
  527. }
  528. /* Flags. */
  529. if (ifa->ifa_flags & IFA_F_SECONDARY)
  530. SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
  531. /* Label */
  532. if (tb[IFA_LABEL])
  533. label = (char *) RTA_DATA (tb[IFA_LABEL]);
  534. if (ifp && label && strcmp (ifp->name, label) == 0)
  535. label = NULL;
  536. /* Register interface address to the interface. */
  537. if (ifa->ifa_family == AF_INET)
  538. {
  539. if (h->nlmsg_type == RTM_NEWADDR)
  540. connected_add_ipv4 (ifp, flags,
  541. (struct in_addr *) addr, ifa->ifa_prefixlen,
  542. (struct in_addr *) broad, label);
  543. else
  544. connected_delete_ipv4 (ifp, flags,
  545. (struct in_addr *) addr, ifa->ifa_prefixlen,
  546. (struct in_addr *) broad);
  547. }
  548. #ifdef HAVE_IPV6
  549. if (ifa->ifa_family == AF_INET6)
  550. {
  551. if (h->nlmsg_type == RTM_NEWADDR)
  552. connected_add_ipv6 (ifp, flags,
  553. (struct in6_addr *) addr, ifa->ifa_prefixlen,
  554. (struct in6_addr *) broad, label);
  555. else
  556. connected_delete_ipv6 (ifp,
  557. (struct in6_addr *) addr, ifa->ifa_prefixlen,
  558. (struct in6_addr *) broad);
  559. }
  560. #endif /* HAVE_IPV6 */
  561. return 0;
  562. }
  563. /* Looking up routing table by netlink interface. */
  564. static int
  565. netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
  566. {
  567. int len;
  568. struct rtmsg *rtm;
  569. struct rtattr *tb[RTA_MAX + 1];
  570. u_char flags = 0;
  571. char anyaddr[16] = { 0 };
  572. int index;
  573. int table;
  574. int metric;
  575. void *dest;
  576. void *gate;
  577. void *src;
  578. rtm = NLMSG_DATA (h);
  579. if (h->nlmsg_type != RTM_NEWROUTE)
  580. return 0;
  581. if (rtm->rtm_type != RTN_UNICAST)
  582. return 0;
  583. table = rtm->rtm_table;
  584. #if 0 /* we weed them out later in rib_weed_tables () */
  585. if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
  586. return 0;
  587. #endif
  588. len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
  589. if (len < 0)
  590. return -1;
  591. memset (tb, 0, sizeof tb);
  592. netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  593. if (rtm->rtm_flags & RTM_F_CLONED)
  594. return 0;
  595. if (rtm->rtm_protocol == RTPROT_REDIRECT)
  596. return 0;
  597. if (rtm->rtm_protocol == RTPROT_KERNEL)
  598. return 0;
  599. if (rtm->rtm_src_len != 0)
  600. return 0;
  601. /* Route which inserted by Zebra. */
  602. if (rtm->rtm_protocol == RTPROT_ZEBRA)
  603. flags |= ZEBRA_FLAG_SELFROUTE;
  604. index = 0;
  605. metric = 0;
  606. dest = NULL;
  607. gate = NULL;
  608. src = NULL;
  609. if (tb[RTA_OIF])
  610. index = *(int *) RTA_DATA (tb[RTA_OIF]);
  611. if (tb[RTA_DST])
  612. dest = RTA_DATA (tb[RTA_DST]);
  613. else
  614. dest = anyaddr;
  615. if (tb[RTA_PREFSRC])
  616. src = RTA_DATA (tb[RTA_PREFSRC]);
  617. if (tb[RTA_GATEWAY])
  618. gate = RTA_DATA (tb[RTA_GATEWAY]);
  619. if (tb[RTA_PRIORITY])
  620. metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
  621. if (rtm->rtm_family == AF_INET)
  622. {
  623. struct prefix_ipv4 p;
  624. p.family = AF_INET;
  625. memcpy (&p.prefix, dest, 4);
  626. p.prefixlen = rtm->rtm_dst_len;
  627. if (!tb[RTA_MULTIPATH])
  628. rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
  629. table, metric, 0, SAFI_UNICAST);
  630. else
  631. {
  632. /* This is a multipath route */
  633. struct rib *rib;
  634. struct rtnexthop *rtnh =
  635. (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
  636. len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
  637. rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
  638. rib->type = ZEBRA_ROUTE_KERNEL;
  639. rib->distance = 0;
  640. rib->flags = flags;
  641. rib->metric = metric;
  642. rib->table = table;
  643. rib->nexthop_num = 0;
  644. rib->uptime = time (NULL);
  645. for (;;)
  646. {
  647. if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
  648. break;
  649. rib->nexthop_num++;
  650. index = rtnh->rtnh_ifindex;
  651. gate = 0;
  652. if (rtnh->rtnh_len > sizeof (*rtnh))
  653. {
  654. memset (tb, 0, sizeof (tb));
  655. netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
  656. rtnh->rtnh_len - sizeof (*rtnh));
  657. if (tb[RTA_GATEWAY])
  658. gate = RTA_DATA (tb[RTA_GATEWAY]);
  659. }
  660. if (gate)
  661. {
  662. if (index)
  663. nexthop_ipv4_ifindex_add (rib, gate, src, index);
  664. else
  665. nexthop_ipv4_add (rib, gate, src);
  666. }
  667. else
  668. nexthop_ifindex_add (rib, index);
  669. len -= NLMSG_ALIGN(rtnh->rtnh_len);
  670. rtnh = RTNH_NEXT(rtnh);
  671. }
  672. if (rib->nexthop_num == 0)
  673. XFREE (MTYPE_RIB, rib);
  674. else
  675. rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST);
  676. }
  677. }
  678. #ifdef HAVE_IPV6
  679. if (rtm->rtm_family == AF_INET6)
  680. {
  681. struct prefix_ipv6 p;
  682. p.family = AF_INET6;
  683. memcpy (&p.prefix, dest, 16);
  684. p.prefixlen = rtm->rtm_dst_len;
  685. rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table,
  686. metric, 0, SAFI_UNICAST);
  687. }
  688. #endif /* HAVE_IPV6 */
  689. return 0;
  690. }
  691. static const struct message rtproto_str[] = {
  692. {RTPROT_REDIRECT, "redirect"},
  693. {RTPROT_KERNEL, "kernel"},
  694. {RTPROT_BOOT, "boot"},
  695. {RTPROT_STATIC, "static"},
  696. {RTPROT_GATED, "GateD"},
  697. {RTPROT_RA, "router advertisement"},
  698. {RTPROT_MRT, "MRT"},
  699. {RTPROT_ZEBRA, "Zebra"},
  700. #ifdef RTPROT_BIRD
  701. {RTPROT_BIRD, "BIRD"},
  702. #endif /* RTPROT_BIRD */
  703. {0, NULL}
  704. };
  705. /* Routing information change from the kernel. */
  706. static int
  707. netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
  708. {
  709. int len;
  710. struct rtmsg *rtm;
  711. struct rtattr *tb[RTA_MAX + 1];
  712. char anyaddr[16] = { 0 };
  713. int index;
  714. int table;
  715. int metric;
  716. void *dest;
  717. void *gate;
  718. void *src;
  719. rtm = NLMSG_DATA (h);
  720. if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
  721. {
  722. /* If this is not route add/delete message print warning. */
  723. zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
  724. return 0;
  725. }
  726. /* Connected route. */
  727. if (IS_ZEBRA_DEBUG_KERNEL)
  728. zlog_debug ("%s %s %s proto %s",
  729. h->nlmsg_type ==
  730. RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
  731. rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
  732. rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
  733. lookup (rtproto_str, rtm->rtm_protocol));
  734. if (rtm->rtm_type != RTN_UNICAST)
  735. {
  736. return 0;
  737. }
  738. table = rtm->rtm_table;
  739. if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
  740. {
  741. return 0;
  742. }
  743. len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
  744. if (len < 0)
  745. return -1;
  746. memset (tb, 0, sizeof tb);
  747. netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  748. if (rtm->rtm_flags & RTM_F_CLONED)
  749. return 0;
  750. if (rtm->rtm_protocol == RTPROT_REDIRECT)
  751. return 0;
  752. if (rtm->rtm_protocol == RTPROT_KERNEL)
  753. return 0;
  754. if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
  755. return 0;
  756. if (rtm->rtm_src_len != 0)
  757. {
  758. zlog_warn ("netlink_route_change(): no src len");
  759. return 0;
  760. }
  761. index = 0;
  762. metric = 0;
  763. dest = NULL;
  764. gate = NULL;
  765. src = NULL;
  766. if (tb[RTA_OIF])
  767. index = *(int *) RTA_DATA (tb[RTA_OIF]);
  768. if (tb[RTA_DST])
  769. dest = RTA_DATA (tb[RTA_DST]);
  770. else
  771. dest = anyaddr;
  772. if (tb[RTA_GATEWAY])
  773. gate = RTA_DATA (tb[RTA_GATEWAY]);
  774. if (tb[RTA_PREFSRC])
  775. src = RTA_DATA (tb[RTA_PREFSRC]);
  776. if (h->nlmsg_type == RTM_NEWROUTE && tb[RTA_PRIORITY])
  777. metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
  778. if (rtm->rtm_family == AF_INET)
  779. {
  780. struct prefix_ipv4 p;
  781. p.family = AF_INET;
  782. memcpy (&p.prefix, dest, 4);
  783. p.prefixlen = rtm->rtm_dst_len;
  784. if (IS_ZEBRA_DEBUG_KERNEL)
  785. {
  786. if (h->nlmsg_type == RTM_NEWROUTE)
  787. zlog_debug ("RTM_NEWROUTE %s/%d",
  788. inet_ntoa (p.prefix), p.prefixlen);
  789. else
  790. zlog_debug ("RTM_DELROUTE %s/%d",
  791. inet_ntoa (p.prefix), p.prefixlen);
  792. }
  793. if (h->nlmsg_type == RTM_NEWROUTE)
  794. {
  795. if (!tb[RTA_MULTIPATH])
  796. rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table,
  797. metric, 0, SAFI_UNICAST);
  798. else
  799. {
  800. /* This is a multipath route */
  801. struct rib *rib;
  802. struct rtnexthop *rtnh =
  803. (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
  804. len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
  805. rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
  806. rib->type = ZEBRA_ROUTE_KERNEL;
  807. rib->distance = 0;
  808. rib->flags = 0;
  809. rib->metric = metric;
  810. rib->table = table;
  811. rib->nexthop_num = 0;
  812. rib->uptime = time (NULL);
  813. for (;;)
  814. {
  815. if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
  816. break;
  817. rib->nexthop_num++;
  818. index = rtnh->rtnh_ifindex;
  819. gate = 0;
  820. if (rtnh->rtnh_len > sizeof (*rtnh))
  821. {
  822. memset (tb, 0, sizeof (tb));
  823. netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
  824. rtnh->rtnh_len - sizeof (*rtnh));
  825. if (tb[RTA_GATEWAY])
  826. gate = RTA_DATA (tb[RTA_GATEWAY]);
  827. }
  828. if (gate)
  829. {
  830. if (index)
  831. nexthop_ipv4_ifindex_add (rib, gate, src, index);
  832. else
  833. nexthop_ipv4_add (rib, gate, src);
  834. }
  835. else
  836. nexthop_ifindex_add (rib, index);
  837. len -= NLMSG_ALIGN(rtnh->rtnh_len);
  838. rtnh = RTNH_NEXT(rtnh);
  839. }
  840. if (rib->nexthop_num == 0)
  841. XFREE (MTYPE_RIB, rib);
  842. else
  843. rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST);
  844. }
  845. }
  846. else
  847. rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST);
  848. }
  849. #ifdef HAVE_IPV6
  850. if (rtm->rtm_family == AF_INET6)
  851. {
  852. struct prefix_ipv6 p;
  853. char buf[BUFSIZ];
  854. p.family = AF_INET6;
  855. memcpy (&p.prefix, dest, 16);
  856. p.prefixlen = rtm->rtm_dst_len;
  857. if (IS_ZEBRA_DEBUG_KERNEL)
  858. {
  859. if (h->nlmsg_type == RTM_NEWROUTE)
  860. zlog_debug ("RTM_NEWROUTE %s/%d",
  861. inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
  862. p.prefixlen);
  863. else
  864. zlog_debug ("RTM_DELROUTE %s/%d",
  865. inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
  866. p.prefixlen);
  867. }
  868. if (h->nlmsg_type == RTM_NEWROUTE)
  869. rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
  870. else
  871. rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST);
  872. }
  873. #endif /* HAVE_IPV6 */
  874. return 0;
  875. }
  876. static int
  877. netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
  878. {
  879. int len;
  880. struct ifinfomsg *ifi;
  881. struct rtattr *tb[IFLA_MAX + 1];
  882. struct interface *ifp;
  883. char *name;
  884. ifi = NLMSG_DATA (h);
  885. if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
  886. {
  887. /* If this is not link add/delete message so print warning. */
  888. zlog_warn ("netlink_link_change: wrong kernel message %d\n",
  889. h->nlmsg_type);
  890. return 0;
  891. }
  892. len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
  893. if (len < 0)
  894. return -1;
  895. /* Looking up interface name. */
  896. memset (tb, 0, sizeof tb);
  897. netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
  898. #ifdef IFLA_WIRELESS
  899. /* check for wireless messages to ignore */
  900. if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
  901. {
  902. if (IS_ZEBRA_DEBUG_KERNEL)
  903. zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
  904. return 0;
  905. }
  906. #endif /* IFLA_WIRELESS */
  907. if (tb[IFLA_IFNAME] == NULL)
  908. return -1;
  909. name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
  910. /* Add interface. */
  911. if (h->nlmsg_type == RTM_NEWLINK)
  912. {
  913. ifp = if_lookup_by_name (name);
  914. if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  915. {
  916. if (ifp == NULL)
  917. ifp = if_get_by_name (name);
  918. set_ifindex(ifp, ifi->ifi_index);
  919. ifp->flags = ifi->ifi_flags & 0x0000fffff;
  920. ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
  921. ifp->metric = 1;
  922. netlink_interface_update_hw_addr (tb, ifp);
  923. /* If new link is added. */
  924. if_add_update (ifp);
  925. }
  926. else
  927. {
  928. /* Interface status change. */
  929. set_ifindex(ifp, ifi->ifi_index);
  930. ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
  931. ifp->metric = 1;
  932. netlink_interface_update_hw_addr (tb, ifp);
  933. if (if_is_operative (ifp))
  934. {
  935. ifp->flags = ifi->ifi_flags & 0x0000fffff;
  936. if (!if_is_operative (ifp))
  937. if_down (ifp);
  938. else
  939. /* Must notify client daemons of new interface status. */
  940. zebra_interface_up_update (ifp);
  941. }
  942. else
  943. {
  944. ifp->flags = ifi->ifi_flags & 0x0000fffff;
  945. if (if_is_operative (ifp))
  946. if_up (ifp);
  947. }
  948. }
  949. }
  950. else
  951. {
  952. /* RTM_DELLINK. */
  953. ifp = if_lookup_by_name (name);
  954. if (ifp == NULL)
  955. {
  956. zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
  957. name);
  958. return 0;
  959. }
  960. if_delete_update (ifp);
  961. }
  962. return 0;
  963. }
  964. static int
  965. netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
  966. {
  967. /* JF: Ignore messages that aren't from the kernel */
  968. if ( snl->nl_pid != 0 )
  969. {
  970. zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl->nl_pid );
  971. return 0;
  972. }
  973. switch (h->nlmsg_type)
  974. {
  975. case RTM_NEWROUTE:
  976. return netlink_route_change (snl, h);
  977. break;
  978. case RTM_DELROUTE:
  979. return netlink_route_change (snl, h);
  980. break;
  981. case RTM_NEWLINK:
  982. return netlink_link_change (snl, h);
  983. break;
  984. case RTM_DELLINK:
  985. return netlink_link_change (snl, h);
  986. break;
  987. case RTM_NEWADDR:
  988. return netlink_interface_addr (snl, h);
  989. break;
  990. case RTM_DELADDR:
  991. return netlink_interface_addr (snl, h);
  992. break;
  993. default:
  994. zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
  995. break;
  996. }
  997. return 0;
  998. }
  999. /* Interface lookup by netlink socket. */
  1000. int
  1001. interface_lookup_netlink (void)
  1002. {
  1003. int ret;
  1004. /* Get interface information. */
  1005. ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
  1006. if (ret < 0)
  1007. return ret;
  1008. ret = netlink_parse_info (netlink_interface, &netlink_cmd);
  1009. if (ret < 0)
  1010. return ret;
  1011. /* Get IPv4 address of the interfaces. */
  1012. ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
  1013. if (ret < 0)
  1014. return ret;
  1015. ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
  1016. if (ret < 0)
  1017. return ret;
  1018. #ifdef HAVE_IPV6
  1019. /* Get IPv6 address of the interfaces. */
  1020. ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
  1021. if (ret < 0)
  1022. return ret;
  1023. ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
  1024. if (ret < 0)
  1025. return ret;
  1026. #endif /* HAVE_IPV6 */
  1027. return 0;
  1028. }
  1029. /* Routing table read function using netlink interface. Only called
  1030. bootstrap time. */
  1031. int
  1032. netlink_route_read (void)
  1033. {
  1034. int ret;
  1035. /* Get IPv4 routing table. */
  1036. ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
  1037. if (ret < 0)
  1038. return ret;
  1039. ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
  1040. if (ret < 0)
  1041. return ret;
  1042. #ifdef HAVE_IPV6
  1043. /* Get IPv6 routing table. */
  1044. ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
  1045. if (ret < 0)
  1046. return ret;
  1047. ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
  1048. if (ret < 0)
  1049. return ret;
  1050. #endif /* HAVE_IPV6 */
  1051. return 0;
  1052. }
  1053. /* Utility function comes from iproute2.
  1054. Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  1055. int
  1056. addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
  1057. {
  1058. int len;
  1059. struct rtattr *rta;
  1060. len = RTA_LENGTH (alen);
  1061. if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
  1062. return -1;
  1063. rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
  1064. rta->rta_type = type;
  1065. rta->rta_len = len;
  1066. memcpy (RTA_DATA (rta), data, alen);
  1067. n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
  1068. return 0;
  1069. }
  1070. int
  1071. rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
  1072. {
  1073. int len;
  1074. struct rtattr *subrta;
  1075. len = RTA_LENGTH (alen);
  1076. if (RTA_ALIGN (rta->rta_len) + len > maxlen)
  1077. return -1;
  1078. subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
  1079. subrta->rta_type = type;
  1080. subrta->rta_len = len;
  1081. memcpy (RTA_DATA (subrta), data, alen);
  1082. rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
  1083. return 0;
  1084. }
  1085. /* Utility function comes from iproute2.
  1086. Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  1087. int
  1088. addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
  1089. {
  1090. int len;
  1091. struct rtattr *rta;
  1092. len = RTA_LENGTH (4);
  1093. if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
  1094. return -1;
  1095. rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
  1096. rta->rta_type = type;
  1097. rta->rta_len = len;
  1098. memcpy (RTA_DATA (rta), &data, 4);
  1099. n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
  1100. return 0;
  1101. }
  1102. static int
  1103. netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
  1104. {
  1105. zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
  1106. return 0;
  1107. }
  1108. /* sendmsg() to netlink socket then recvmsg(). */
  1109. static int
  1110. netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
  1111. {
  1112. int status;
  1113. struct sockaddr_nl snl;
  1114. struct iovec iov = { (void *) n, n->nlmsg_len };
  1115. struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
  1116. int save_errno;
  1117. memset (&snl, 0, sizeof snl);
  1118. snl.nl_family = AF_NETLINK;
  1119. n->nlmsg_seq = ++nl->seq;
  1120. /* Request an acknowledgement by setting NLM_F_ACK */
  1121. n->nlmsg_flags |= NLM_F_ACK;
  1122. if (IS_ZEBRA_DEBUG_KERNEL)
  1123. zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
  1124. lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
  1125. n->nlmsg_seq);
  1126. /* Send message to netlink interface. */
  1127. if (zserv_privs.change (ZPRIVS_RAISE))
  1128. zlog (NULL, LOG_ERR, "Can't raise privileges");
  1129. status = sendmsg (nl->sock, &msg, 0);
  1130. save_errno = errno;
  1131. if (zserv_privs.change (ZPRIVS_LOWER))
  1132. zlog (NULL, LOG_ERR, "Can't lower privileges");
  1133. if (status < 0)
  1134. {
  1135. zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
  1136. safe_strerror (save_errno));
  1137. return -1;
  1138. }
  1139. /*
  1140. * Get reply from netlink socket.
  1141. * The reply should either be an acknowlegement or an error.
  1142. */
  1143. return netlink_parse_info (netlink_talk_filter, nl);
  1144. }
  1145. /* Routing table change via netlink interface. */
  1146. static int
  1147. netlink_route (int cmd, int family, void *dest, int length, void *gate,
  1148. int index, int zebra_flags, int table)
  1149. {
  1150. int ret;
  1151. int bytelen;
  1152. struct sockaddr_nl snl;
  1153. int discard;
  1154. struct
  1155. {
  1156. struct nlmsghdr n;
  1157. struct rtmsg r;
  1158. char buf[NL_PKT_BUF_SIZE];
  1159. } req;
  1160. memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
  1161. bytelen = (family == AF_INET ? 4 : 16);
  1162. req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
  1163. req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
  1164. req.n.nlmsg_type = cmd;
  1165. req.r.rtm_family = family;
  1166. req.r.rtm_table = table;
  1167. req.r.rtm_dst_len = length;
  1168. req.r.rtm_protocol = RTPROT_ZEBRA;
  1169. req.r.rtm_scope = RT_SCOPE_UNIVERSE;
  1170. if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
  1171. || (zebra_flags & ZEBRA_FLAG_REJECT))
  1172. discard = 1;
  1173. else
  1174. discard = 0;
  1175. if (cmd == RTM_NEWROUTE)
  1176. {
  1177. if (discard)
  1178. {
  1179. if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
  1180. req.r.rtm_type = RTN_BLACKHOLE;
  1181. else if (zebra_flags & ZEBRA_FLAG_REJECT)
  1182. req.r.rtm_type = RTN_UNREACHABLE;
  1183. else
  1184. assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
  1185. }
  1186. else
  1187. req.r.rtm_type = RTN_UNICAST;
  1188. }
  1189. if (dest)
  1190. addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
  1191. if (!discard)
  1192. {
  1193. if (gate)
  1194. addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
  1195. if (index > 0)
  1196. addattr32 (&req.n, sizeof req, RTA_OIF, index);
  1197. }
  1198. /* Destination netlink address. */
  1199. memset (&snl, 0, sizeof snl);
  1200. snl.nl_family = AF_NETLINK;
  1201. /* Talk to netlink socket. */
  1202. ret = netlink_talk (&req.n, &netlink_cmd);
  1203. if (ret < 0)
  1204. return -1;
  1205. return 0;
  1206. }
  1207. /* This function takes a nexthop as argument and adds
  1208. * the appropriate netlink attributes to an existing
  1209. * netlink message.
  1210. *
  1211. * @param routedesc: Human readable description of route type
  1212. * (direct/recursive, single-/multipath)
  1213. * @param bytelen: Length of addresses in bytes.
  1214. * @param nexthop: Nexthop information
  1215. * @param nlmsg: nlmsghdr structure to fill in.
  1216. * @param req_size: The size allocated for the message.
  1217. */
  1218. static void
  1219. _netlink_route_build_singlepath(
  1220. const char *routedesc,
  1221. int bytelen,
  1222. struct nexthop *nexthop,
  1223. struct nlmsghdr *nlmsg,
  1224. struct rtmsg *rtmsg,
  1225. size_t req_size)
  1226. {
  1227. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
  1228. rtmsg->rtm_flags |= RTNH_F_ONLINK;
  1229. if (nexthop->type == NEXTHOP_TYPE_IPV4
  1230. || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  1231. {
  1232. addattr_l (nlmsg, req_size, RTA_GATEWAY,
  1233. &nexthop->gate.ipv4, bytelen);
  1234. if (nexthop->src.ipv4.s_addr)
  1235. addattr_l (nlmsg, req_size, RTA_PREFSRC,
  1236. &nexthop->src.ipv4, bytelen);
  1237. if (IS_ZEBRA_DEBUG_KERNEL)
  1238. zlog_debug("netlink_route_multipath() (%s): "
  1239. "nexthop via %s if %u",
  1240. routedesc,
  1241. inet_ntoa (nexthop->gate.ipv4),
  1242. nexthop->ifindex);
  1243. }
  1244. #ifdef HAVE_IPV6
  1245. if (nexthop->type == NEXTHOP_TYPE_IPV6
  1246. || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1247. || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1248. {
  1249. addattr_l (nlmsg, req_size, RTA_GATEWAY,
  1250. &nexthop->gate.ipv6, bytelen);
  1251. if (IS_ZEBRA_DEBUG_KERNEL)
  1252. zlog_debug("netlink_route_multipath() (%s): "
  1253. "nexthop via %s if %u",
  1254. routedesc,
  1255. inet6_ntoa (nexthop->gate.ipv6),
  1256. nexthop->ifindex);
  1257. }
  1258. #endif /* HAVE_IPV6 */
  1259. if (nexthop->type == NEXTHOP_TYPE_IFINDEX
  1260. || nexthop->type == NEXTHOP_TYPE_IFNAME
  1261. || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  1262. {
  1263. addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
  1264. if (nexthop->src.ipv4.s_addr)
  1265. addattr_l (nlmsg, req_size, RTA_PREFSRC,
  1266. &nexthop->src.ipv4, bytelen);
  1267. if (IS_ZEBRA_DEBUG_KERNEL)
  1268. zlog_debug("netlink_route_multipath() (%s): "
  1269. "nexthop via if %u", routedesc, nexthop->ifindex);
  1270. }
  1271. if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
  1272. || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
  1273. {
  1274. addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
  1275. if (IS_ZEBRA_DEBUG_KERNEL)
  1276. zlog_debug("netlink_route_multipath() (%s): "
  1277. "nexthop via if %u", routedesc, nexthop->ifindex);
  1278. }
  1279. }
  1280. /* This function takes a nexthop as argument and
  1281. * appends to the given rtattr/rtnexthop pair the
  1282. * representation of the nexthop. If the nexthop
  1283. * defines a preferred source, the src parameter
  1284. * will be modified to point to that src, otherwise
  1285. * it will be kept unmodified.
  1286. *
  1287. * @param routedesc: Human readable description of route type
  1288. * (direct/recursive, single-/multipath)
  1289. * @param bytelen: Length of addresses in bytes.
  1290. * @param nexthop: Nexthop information
  1291. * @param rta: rtnetlink attribute structure
  1292. * @param rtnh: pointer to an rtnetlink nexthop structure
  1293. * @param src: pointer pointing to a location where
  1294. * the prefsrc should be stored.
  1295. */
  1296. static void
  1297. _netlink_route_build_multipath(
  1298. const char *routedesc,
  1299. int bytelen,
  1300. struct nexthop *nexthop,
  1301. struct rtattr *rta,
  1302. struct rtnexthop *rtnh,
  1303. union g_addr **src
  1304. )
  1305. {
  1306. rtnh->rtnh_len = sizeof (*rtnh);
  1307. rtnh->rtnh_flags = 0;
  1308. rtnh->rtnh_hops = 0;
  1309. rta->rta_len += rtnh->rtnh_len;
  1310. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
  1311. rtnh->rtnh_flags |= RTNH_F_ONLINK;
  1312. if (nexthop->type == NEXTHOP_TYPE_IPV4
  1313. || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  1314. {
  1315. rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
  1316. &nexthop->gate.ipv4, bytelen);
  1317. rtnh->rtnh_len += sizeof (struct rtattr) + 4;
  1318. if (nexthop->src.ipv4.s_addr)
  1319. *src = &nexthop->src;
  1320. if (IS_ZEBRA_DEBUG_KERNEL)
  1321. zlog_debug("netlink_route_multipath() (%s): "
  1322. "nexthop via %s if %u",
  1323. routedesc,
  1324. inet_ntoa (nexthop->gate.ipv4),
  1325. nexthop->ifindex);
  1326. }
  1327. #ifdef HAVE_IPV6
  1328. if (nexthop->type == NEXTHOP_TYPE_IPV6
  1329. || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1330. || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1331. {
  1332. rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
  1333. &nexthop->gate.ipv6, bytelen);
  1334. if (IS_ZEBRA_DEBUG_KERNEL)
  1335. zlog_debug("netlink_route_multipath() (%s): "
  1336. "nexthop via %s if %u",
  1337. routedesc,
  1338. inet6_ntoa (nexthop->gate.ipv6),
  1339. nexthop->ifindex);
  1340. }
  1341. #endif /* HAVE_IPV6 */
  1342. /* ifindex */
  1343. if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
  1344. || nexthop->type == NEXTHOP_TYPE_IFINDEX
  1345. || nexthop->type == NEXTHOP_TYPE_IFNAME)
  1346. {
  1347. rtnh->rtnh_ifindex = nexthop->ifindex;
  1348. if (nexthop->src.ipv4.s_addr)
  1349. *src = &nexthop->src;
  1350. if (IS_ZEBRA_DEBUG_KERNEL)
  1351. zlog_debug("netlink_route_multipath() (%s): "
  1352. "nexthop via if %u", routedesc, nexthop->ifindex);
  1353. }
  1354. else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1355. || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1356. {
  1357. rtnh->rtnh_ifindex = nexthop->ifindex;
  1358. if (IS_ZEBRA_DEBUG_KERNEL)
  1359. zlog_debug("netlink_route_multipath() (%s): "
  1360. "nexthop via if %u", routedesc, nexthop->ifindex);
  1361. }
  1362. else
  1363. {
  1364. rtnh->rtnh_ifindex = 0;
  1365. }
  1366. }
  1367. /* Log debug information for netlink_route_multipath
  1368. * if debug logging is enabled.
  1369. *
  1370. * @param cmd: Netlink command which is to be processed
  1371. * @param p: Prefix for which the change is due
  1372. * @param nexthop: Nexthop which is currently processed
  1373. * @param routedesc: Semantic annotation for nexthop
  1374. * (recursive, multipath, etc.)
  1375. * @param family: Address family which the change concerns
  1376. */
  1377. static void
  1378. _netlink_route_debug(
  1379. int cmd,
  1380. struct prefix *p,
  1381. struct nexthop *nexthop,
  1382. const char *routedesc,
  1383. int family)
  1384. {
  1385. if (IS_ZEBRA_DEBUG_KERNEL)
  1386. {
  1387. zlog_debug ("netlink_route_multipath() (%s): %s %s/%d type %s",
  1388. routedesc,
  1389. lookup (nlmsg_str, cmd),
  1390. #ifdef HAVE_IPV6
  1391. (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
  1392. inet6_ntoa (p->u.prefix6),
  1393. #else
  1394. inet_ntoa (p->u.prefix4),
  1395. #endif /* HAVE_IPV6 */
  1396. p->prefixlen, nexthop_type_to_str (nexthop->type));
  1397. }
  1398. }
  1399. /* Routing table change via netlink interface. */
  1400. static int
  1401. netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
  1402. int family)
  1403. {
  1404. int bytelen;
  1405. struct sockaddr_nl snl;
  1406. struct nexthop *nexthop = NULL, *tnexthop;
  1407. int recursing;
  1408. int nexthop_num;
  1409. int discard;
  1410. const char *routedesc;
  1411. struct
  1412. {
  1413. struct nlmsghdr n;
  1414. struct rtmsg r;
  1415. char buf[NL_PKT_BUF_SIZE];
  1416. } req;
  1417. memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
  1418. bytelen = (family == AF_INET ? 4 : 16);
  1419. req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
  1420. req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
  1421. req.n.nlmsg_type = cmd;
  1422. req.r.rtm_family = family;
  1423. req.r.rtm_table = rib->table;
  1424. req.r.rtm_dst_len = p->prefixlen;
  1425. req.r.rtm_protocol = RTPROT_ZEBRA;
  1426. req.r.rtm_scope = RT_SCOPE_UNIVERSE;
  1427. if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
  1428. discard = 1;
  1429. else
  1430. discard = 0;
  1431. if (cmd == RTM_NEWROUTE)
  1432. {
  1433. if (discard)
  1434. {
  1435. if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
  1436. req.r.rtm_type = RTN_BLACKHOLE;
  1437. else if (rib->flags & ZEBRA_FLAG_REJECT)
  1438. req.r.rtm_type = RTN_UNREACHABLE;
  1439. else
  1440. assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
  1441. }
  1442. else
  1443. req.r.rtm_type = RTN_UNICAST;
  1444. }
  1445. addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
  1446. /* Metric. */
  1447. addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
  1448. if (discard)
  1449. {
  1450. if (cmd == RTM_NEWROUTE)
  1451. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1452. {
  1453. /* We shouldn't encounter recursive nexthops on discard routes,
  1454. * but it is probably better to handle that case correctly anyway.
  1455. */
  1456. if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1457. continue;
  1458. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1459. }
  1460. goto skip;
  1461. }
  1462. /* Count overall nexthops so we can decide whether to use singlepath
  1463. * or multipath case. */
  1464. nexthop_num = 0;
  1465. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1466. {
  1467. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1468. continue;
  1469. if (cmd == RTM_NEWROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1470. continue;
  1471. if (cmd == RTM_DELROUTE && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
  1472. continue;
  1473. nexthop_num++;
  1474. }
  1475. /* Singlepath case. */
  1476. if (nexthop_num == 1 || MULTIPATH_NUM == 1)
  1477. {
  1478. nexthop_num = 0;
  1479. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1480. {
  1481. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1482. continue;
  1483. if ((cmd == RTM_NEWROUTE
  1484. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1485. || (cmd == RTM_DELROUTE
  1486. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
  1487. {
  1488. routedesc = recursing ? "recursive, 1 hop" : "single hop";
  1489. _netlink_route_debug(cmd, p, nexthop, routedesc, family);
  1490. _netlink_route_build_singlepath(routedesc, bytelen,
  1491. nexthop, &req.n, &req.r,
  1492. sizeof req);
  1493. if (cmd == RTM_NEWROUTE)
  1494. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1495. nexthop_num++;
  1496. break;
  1497. }
  1498. }
  1499. }
  1500. else
  1501. {
  1502. char buf[NL_PKT_BUF_SIZE];
  1503. struct rtattr *rta = (void *) buf;
  1504. struct rtnexthop *rtnh;
  1505. union g_addr *src = NULL;
  1506. rta->rta_type = RTA_MULTIPATH;
  1507. rta->rta_len = RTA_LENGTH (0);
  1508. rtnh = RTA_DATA (rta);
  1509. nexthop_num = 0;
  1510. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1511. {
  1512. if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM)
  1513. break;
  1514. if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1515. continue;
  1516. if ((cmd == RTM_NEWROUTE
  1517. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1518. || (cmd == RTM_DELROUTE
  1519. && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
  1520. {
  1521. routedesc = recursing ? "recursive, multihop" : "multihop";
  1522. nexthop_num++;
  1523. _netlink_route_debug(cmd, p, nexthop,
  1524. routedesc, family);
  1525. _netlink_route_build_multipath(routedesc, bytelen,
  1526. nexthop, rta, rtnh, &src);
  1527. rtnh = RTNH_NEXT (rtnh);
  1528. if (cmd == RTM_NEWROUTE)
  1529. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1530. }
  1531. }
  1532. if (src)
  1533. addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src->ipv4, bytelen);
  1534. if (rta->rta_len > RTA_LENGTH (0))
  1535. addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
  1536. RTA_PAYLOAD (rta));
  1537. }
  1538. /* If there is no useful nexthop then return. */
  1539. if (nexthop_num == 0)
  1540. {
  1541. if (IS_ZEBRA_DEBUG_KERNEL)
  1542. zlog_debug ("netlink_route_multipath(): No useful nexthop.");
  1543. return 0;
  1544. }
  1545. skip:
  1546. /* Destination netlink address. */
  1547. memset (&snl, 0, sizeof snl);
  1548. snl.nl_family = AF_NETLINK;
  1549. /* Talk to netlink socket. */
  1550. return netlink_talk (&req.n, &netlink_cmd);
  1551. }
  1552. int
  1553. kernel_add_ipv4 (struct prefix *p, struct rib *rib)
  1554. {
  1555. return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET);
  1556. }
  1557. int
  1558. kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
  1559. {
  1560. return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET);
  1561. }
  1562. #ifdef HAVE_IPV6
  1563. int
  1564. kernel_add_ipv6 (struct prefix *p, struct rib *rib)
  1565. {
  1566. return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6);
  1567. }
  1568. int
  1569. kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
  1570. {
  1571. return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6);
  1572. }
  1573. /* Delete IPv6 route from the kernel. */
  1574. int
  1575. kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
  1576. unsigned int index, int flags, int table)
  1577. {
  1578. return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix,
  1579. dest->prefixlen, gate, index, flags, table);
  1580. }
  1581. #endif /* HAVE_IPV6 */
  1582. /* Interface address modification. */
  1583. static int
  1584. netlink_address (int cmd, int family, struct interface *ifp,
  1585. struct connected *ifc)
  1586. {
  1587. int bytelen;
  1588. struct prefix *p;
  1589. struct
  1590. {
  1591. struct nlmsghdr n;
  1592. struct ifaddrmsg ifa;
  1593. char buf[NL_PKT_BUF_SIZE];
  1594. } req;
  1595. p = ifc->address;
  1596. memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
  1597. bytelen = (family == AF_INET ? 4 : 16);
  1598. req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
  1599. req.n.nlmsg_flags = NLM_F_REQUEST;
  1600. req.n.nlmsg_type = cmd;
  1601. req.ifa.ifa_family = family;
  1602. req.ifa.ifa_index = ifp->ifindex;
  1603. req.ifa.ifa_prefixlen = p->prefixlen;
  1604. addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
  1605. if (family == AF_INET && cmd == RTM_NEWADDR)
  1606. {
  1607. if (!CONNECTED_PEER(ifc) && ifc->destination)
  1608. {
  1609. p = ifc->destination;
  1610. addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
  1611. bytelen);
  1612. }
  1613. }
  1614. if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
  1615. SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
  1616. if (ifc->label)
  1617. addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
  1618. strlen (ifc->label) + 1);
  1619. return netlink_talk (&req.n, &netlink_cmd);
  1620. }
  1621. int
  1622. kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
  1623. {
  1624. return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
  1625. }
  1626. int
  1627. kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
  1628. {
  1629. return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
  1630. }
  1631. extern struct thread_master *master;
  1632. /* Kernel route reflection. */
  1633. static int
  1634. kernel_read (struct thread *thread)
  1635. {
  1636. netlink_parse_info (netlink_information_fetch, &netlink);
  1637. thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
  1638. return 0;
  1639. }
  1640. /* Filter out messages from self that occur on listener socket,
  1641. caused by our actions on the command socket
  1642. */
  1643. static void netlink_install_filter (int sock, __u32 pid)
  1644. {
  1645. struct sock_filter filter[] = {
  1646. /* 0: ldh [4] */
  1647. BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
  1648. /* 1: jeq 0x18 jt 3 jf 6 */
  1649. BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0),
  1650. /* 2: jeq 0x19 jt 3 jf 6 */
  1651. BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3),
  1652. /* 3: ldw [12] */
  1653. BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
  1654. /* 4: jeq XX jt 5 jf 6 */
  1655. BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
  1656. /* 5: ret 0 (skip) */
  1657. BPF_STMT(BPF_RET|BPF_K, 0),
  1658. /* 6: ret 0xffff (keep) */
  1659. BPF_STMT(BPF_RET|BPF_K, 0xffff),
  1660. };
  1661. struct sock_fprog prog = {
  1662. .len = array_size(filter),
  1663. .filter = filter,
  1664. };
  1665. if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0)
  1666. zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno));
  1667. }
  1668. /* Exported interface function. This function simply calls
  1669. netlink_socket (). */
  1670. void
  1671. kernel_init (void)
  1672. {
  1673. unsigned long groups;
  1674. groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
  1675. #ifdef HAVE_IPV6
  1676. groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
  1677. #endif /* HAVE_IPV6 */
  1678. netlink_socket (&netlink, groups);
  1679. netlink_socket (&netlink_cmd, 0);
  1680. /* Register kernel socket. */
  1681. if (netlink.sock > 0)
  1682. {
  1683. /* Only want non-blocking on the netlink event socket */
  1684. if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0)
  1685. zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name,
  1686. safe_strerror (errno));
  1687. /* Set receive buffer size if it's set from command line */
  1688. if (nl_rcvbufsize)
  1689. netlink_recvbuf (&netlink, nl_rcvbufsize);
  1690. netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
  1691. thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
  1692. }
  1693. }
  1694. /*
  1695. * nl_msg_type_to_str
  1696. */
  1697. const char *
  1698. nl_msg_type_to_str (uint16_t msg_type)
  1699. {
  1700. return lookup (nlmsg_str, msg_type);
  1701. }
  1702. /*
  1703. * nl_rtproto_to_str
  1704. */
  1705. const char *
  1706. nl_rtproto_to_str (u_char rtproto)
  1707. {
  1708. return lookup (rtproto_str, rtproto);
  1709. }