rt_netlink.c 53 KB

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