nhrp_route.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /* NHRP routing functions
  2. * Copyright (c) 2014-2015 Timo Teräs
  3. *
  4. * This file is free software: you may copy, redistribute and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include "nhrpd.h"
  10. #include "table.h"
  11. #include "memory.h"
  12. #include "stream.h"
  13. #include "log.h"
  14. #include "zclient.h"
  15. static struct zclient *zclient;
  16. static struct route_table *zebra_rib[AFI_MAX];
  17. struct route_info {
  18. union sockunion via;
  19. struct interface *ifp;
  20. struct interface *nhrp_ifp;
  21. };
  22. static void nhrp_zebra_connected(struct zclient *zclient)
  23. {
  24. /* No real VRF support yet -- bind only to the default vrf */
  25. zclient_send_requests (zclient, VRF_DEFAULT);
  26. }
  27. static struct route_node *nhrp_route_update_get(const struct prefix *p, int create)
  28. {
  29. struct route_node *rn;
  30. afi_t afi = family2afi(PREFIX_FAMILY(p));
  31. if (!zebra_rib[afi])
  32. return NULL;
  33. if (create) {
  34. rn = route_node_get(zebra_rib[afi], p);
  35. if (!rn->info) {
  36. rn->info = XCALLOC(MTYPE_NHRP_ROUTE, sizeof(struct route_info));
  37. route_lock_node(rn);
  38. }
  39. return rn;
  40. } else {
  41. return route_node_lookup(zebra_rib[afi], p);
  42. }
  43. }
  44. static void nhrp_route_update_put(struct route_node *rn)
  45. {
  46. struct route_info *ri = rn->info;
  47. if (!ri->ifp && !ri->nhrp_ifp && sockunion_family(&ri->via) == AF_UNSPEC) {
  48. XFREE(MTYPE_NHRP_ROUTE, rn->info);
  49. rn->info = NULL;
  50. route_unlock_node(rn);
  51. }
  52. route_unlock_node(rn);
  53. }
  54. static void nhrp_route_update_zebra(const struct prefix *p, union sockunion *nexthop, struct interface *ifp)
  55. {
  56. struct route_node *rn;
  57. struct route_info *ri;
  58. rn = nhrp_route_update_get(p, (sockunion_family(nexthop) != AF_UNSPEC) || ifp);
  59. if (rn) {
  60. ri = rn->info;
  61. ri->via = *nexthop;
  62. ri->ifp = ifp;
  63. nhrp_route_update_put(rn);
  64. }
  65. }
  66. void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp)
  67. {
  68. struct route_node *rn;
  69. struct route_info *ri;
  70. rn = nhrp_route_update_get(p, ifp != NULL);
  71. if (rn) {
  72. ri = rn->info;
  73. ri->nhrp_ifp = ifp;
  74. nhrp_route_update_put(rn);
  75. }
  76. }
  77. void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix *p, struct interface *ifp, const union sockunion *nexthop, uint32_t mtu)
  78. {
  79. int flags = 0;
  80. if (zclient->sock < 0)
  81. return;
  82. switch (type) {
  83. case NHRP_CACHE_NEGATIVE:
  84. SET_FLAG(flags, ZEBRA_FLAG_REJECT);
  85. break;
  86. case NHRP_CACHE_DYNAMIC:
  87. case NHRP_CACHE_NHS:
  88. case NHRP_CACHE_STATIC:
  89. /* Regular route, so these are announced
  90. * to other routing daemons */
  91. break;
  92. default:
  93. SET_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE);
  94. break;
  95. }
  96. SET_FLAG(flags, ZEBRA_FLAG_INTERNAL);
  97. if (p->family == AF_INET) {
  98. struct in_addr *nexthop_ipv4;
  99. struct zapi_ipv4 api;
  100. memset(&api, 0, sizeof(api));
  101. api.flags = flags;
  102. api.type = ZEBRA_ROUTE_NHRP;
  103. api.safi = SAFI_UNICAST;
  104. SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
  105. if (nexthop) {
  106. nexthop_ipv4 = (struct in_addr *) sockunion_get_addr(nexthop);
  107. api.nexthop_num = 1;
  108. api.nexthop = &nexthop_ipv4;
  109. }
  110. if (ifp) {
  111. SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
  112. api.ifindex_num = 1;
  113. api.ifindex = &ifp->ifindex;
  114. }
  115. if (mtu) {
  116. SET_FLAG(api.message, ZAPI_MESSAGE_MTU);
  117. api.mtu = mtu;
  118. }
  119. if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) {
  120. char buf[2][INET_ADDRSTRLEN];
  121. zlog_debug("Zebra send: IPv4 route %s %s/%d nexthop %s metric %u"
  122. " count %d dev %s",
  123. add ? "add" : "del",
  124. inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
  125. p->prefixlen,
  126. nexthop ? inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])) : "<onlink>",
  127. api.metric, api.nexthop_num, ifp->name);
  128. }
  129. zapi_ipv4_route(
  130. add ? ZEBRA_IPV4_ROUTE_ADD : ZEBRA_IPV4_ROUTE_DELETE,
  131. zclient, (struct prefix_ipv4 *) p, &api);
  132. } else if (p->family == AF_INET6) {
  133. struct in6_addr *nexthop_ipv6;
  134. struct zapi_ipv6 api;
  135. memset(&api, 0, sizeof(api));
  136. api.flags = flags;
  137. api.type = ZEBRA_ROUTE_NHRP;
  138. api.safi = SAFI_UNICAST;
  139. SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
  140. if (nexthop) {
  141. nexthop_ipv6 = (struct in6_addr *) sockunion_get_addr(nexthop);
  142. api.nexthop_num = 1;
  143. api.nexthop = &nexthop_ipv6;
  144. }
  145. if (ifp) {
  146. SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
  147. api.ifindex_num = 1;
  148. api.ifindex = &ifp->ifindex;
  149. }
  150. if (mtu) {
  151. SET_FLAG(api.message, ZAPI_MESSAGE_MTU);
  152. api.mtu = mtu;
  153. }
  154. if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) {
  155. char buf[2][INET6_ADDRSTRLEN];
  156. zlog_debug("Zebra send: IPv6 route %s %s/%d nexthop %s metric %u"
  157. " count %d dev %s",
  158. add ? "add" : "del",
  159. inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
  160. p->prefixlen,
  161. nexthop ? inet_ntop(AF_INET6, api.nexthop[0], buf[1], sizeof(buf[1])) : "<onlink>",
  162. api.metric, api.nexthop_num, ifp->name);
  163. }
  164. zapi_ipv6_route(
  165. add ? ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE,
  166. zclient, (struct prefix_ipv6 *) p, &api);
  167. }
  168. }
  169. int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id)
  170. {
  171. struct stream *s;
  172. struct interface *ifp = NULL;
  173. struct prefix prefix;
  174. union sockunion nexthop_addr;
  175. unsigned char message, nexthop_num, ifindex_num;
  176. unsigned ifindex;
  177. char buf[2][PREFIX_STRLEN];
  178. int i, afaddrlen, added;
  179. s = zclient->ibuf;
  180. memset(&prefix, 0, sizeof(prefix));
  181. sockunion_family(&nexthop_addr) = AF_UNSPEC;
  182. /* Type, flags, message. */
  183. /*type =*/ stream_getc(s);
  184. /*flags =*/ stream_getc(s);
  185. message = stream_getc(s);
  186. /* Prefix */
  187. switch (cmd) {
  188. case ZEBRA_IPV4_ROUTE_ADD:
  189. case ZEBRA_IPV4_ROUTE_DELETE:
  190. prefix.family = AF_INET;
  191. break;
  192. case ZEBRA_IPV6_ROUTE_ADD:
  193. case ZEBRA_IPV6_ROUTE_DELETE:
  194. prefix.family = AF_INET6;
  195. break;
  196. default:
  197. return -1;
  198. }
  199. afaddrlen = family2addrsize(prefix.family);
  200. prefix.prefixlen = stream_getc(s);
  201. stream_get(&prefix.u.val, s, PSIZE(prefix.prefixlen));
  202. /* Nexthop, ifindex, distance, metric. */
  203. if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX)) {
  204. nexthop_num = stream_getc(s);
  205. for (i = 0; i < nexthop_num; i++) {
  206. stream_get(buf[0], s, afaddrlen);
  207. if (i == 0) sockunion_set(&nexthop_addr, prefix.family, (u_char*) buf[0], afaddrlen);
  208. }
  209. ifindex_num = stream_getc(s);
  210. for (i = 0; i < ifindex_num; i++) {
  211. ifindex = stream_getl(s);
  212. if (i == 0 && ifindex != IFINDEX_INTERNAL)
  213. ifp = if_lookup_by_index(ifindex);
  214. }
  215. }
  216. if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
  217. /*distance =*/ stream_getc(s);
  218. if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
  219. /*metric =*/ stream_getl(s);
  220. added = (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD);
  221. debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s",
  222. added ? "add" : "del",
  223. prefix2str(&prefix, buf[0], sizeof buf[0]),
  224. sockunion2str(&nexthop_addr, buf[1], sizeof buf[1]),
  225. ifp ? ifp->name : "(none)");
  226. nhrp_route_update_zebra(&prefix, &nexthop_addr, ifp);
  227. nhrp_shortcut_prefix_change(&prefix, !added);
  228. return 0;
  229. }
  230. int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p, union sockunion *via, struct interface **ifp)
  231. {
  232. struct route_node *rn;
  233. struct route_info *ri;
  234. struct prefix lookup;
  235. afi_t afi = family2afi(sockunion_family(addr));
  236. char buf[PREFIX_STRLEN];
  237. sockunion2hostprefix(addr, &lookup);
  238. rn = route_node_match(zebra_rib[afi], &lookup);
  239. if (!rn) return 0;
  240. ri = rn->info;
  241. if (ri->nhrp_ifp) {
  242. debugf(NHRP_DEBUG_ROUTE, "lookup %s: nhrp_if=%s",
  243. prefix2str(&lookup, buf, sizeof buf),
  244. ri->nhrp_ifp->name);
  245. if (via) sockunion_family(via) = AF_UNSPEC;
  246. if (ifp) *ifp = ri->nhrp_ifp;
  247. } else {
  248. debugf(NHRP_DEBUG_ROUTE, "lookup %s: zebra route dev %s",
  249. prefix2str(&lookup, buf, sizeof buf),
  250. ri->ifp ? ri->ifp->name : "(none)");
  251. if (via) *via = ri->via;
  252. if (ifp) *ifp = ri->ifp;
  253. }
  254. if (p) *p = rn->p;
  255. route_unlock_node(rn);
  256. return 1;
  257. }
  258. enum nhrp_route_type nhrp_route_address(struct interface *in_ifp, union sockunion *addr, struct prefix *p, struct nhrp_peer **peer)
  259. {
  260. struct interface *ifp = in_ifp;
  261. struct nhrp_interface *nifp;
  262. struct nhrp_cache *c;
  263. union sockunion via[4];
  264. uint32_t network_id = 0;
  265. afi_t afi = family2afi(sockunion_family(addr));
  266. int i;
  267. if (ifp) {
  268. nifp = ifp->info;
  269. network_id = nifp->afi[afi].network_id;
  270. c = nhrp_cache_get(ifp, addr, 0);
  271. if (c && c->cur.type == NHRP_CACHE_LOCAL) {
  272. if (p) memset(p, 0, sizeof(*p));
  273. return NHRP_ROUTE_LOCAL;
  274. }
  275. }
  276. for (i = 0; i < 4; i++) {
  277. if (!nhrp_route_get_nexthop(addr, p, &via[i], &ifp))
  278. return NHRP_ROUTE_BLACKHOLE;
  279. if (ifp) {
  280. /* Departing from nbma network? */
  281. nifp = ifp->info;
  282. if (network_id && network_id != nifp->afi[afi].network_id)
  283. return NHRP_ROUTE_OFF_NBMA;
  284. }
  285. if (sockunion_family(&via[i]) == AF_UNSPEC)
  286. break;
  287. /* Resolve via node, but return the prefix of first match */
  288. addr = &via[i];
  289. p = NULL;
  290. }
  291. if (ifp) {
  292. c = nhrp_cache_get(ifp, addr, 0);
  293. if (c && c->cur.type >= NHRP_CACHE_DYNAMIC) {
  294. if (p) memset(p, 0, sizeof(*p));
  295. if (c->cur.type == NHRP_CACHE_LOCAL)
  296. return NHRP_ROUTE_LOCAL;
  297. if (peer) *peer = nhrp_peer_ref(c->cur.peer);
  298. return NHRP_ROUTE_NBMA_NEXTHOP;
  299. }
  300. }
  301. return NHRP_ROUTE_BLACKHOLE;
  302. }
  303. void nhrp_zebra_init(void)
  304. {
  305. zebra_rib[AFI_IP] = route_table_init();
  306. zebra_rib[AFI_IP6] = route_table_init();
  307. zclient = zclient_new(master);
  308. zclient->zebra_connected = nhrp_zebra_connected;
  309. zclient->interface_add = nhrp_interface_add;
  310. zclient->interface_delete = nhrp_interface_delete;
  311. zclient->interface_up = nhrp_interface_up;
  312. zclient->interface_down = nhrp_interface_down;
  313. zclient->interface_address_add = nhrp_interface_address_add;
  314. zclient->interface_address_delete = nhrp_interface_address_delete;
  315. zclient->ipv4_route_add = nhrp_route_read;
  316. zclient->ipv4_route_delete = nhrp_route_read;
  317. zclient->ipv6_route_add = nhrp_route_read;
  318. zclient->ipv6_route_delete = nhrp_route_read;
  319. zclient_init(zclient, ZEBRA_ROUTE_NHRP);
  320. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_KERNEL, VRF_DEFAULT);
  321. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_CONNECT, VRF_DEFAULT);
  322. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_STATIC, VRF_DEFAULT);
  323. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_RIP, VRF_DEFAULT);
  324. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_OSPF, VRF_DEFAULT);
  325. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_ISIS, VRF_DEFAULT);
  326. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_BGP, VRF_DEFAULT);
  327. }
  328. void nhrp_zebra_terminate(void)
  329. {
  330. zclient_stop(zclient);
  331. route_table_finish(zebra_rib[AFI_IP]);
  332. route_table_finish(zebra_rib[AFI_IP6]);
  333. }