rt_netlink.c 55 KB

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