static int __ni_rtevent_newroute(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, struct nlmsghdr *h) { struct rtmsg *rtm; ni_route_t *rp, *r; ni_route_nexthop_t *nh; ni_netdev_t *dev = NULL; if (!(rtm = ni_rtnl_rtmsg(h, RTM_NEWROUTE))) return -1; /* filter unwanted / unsupported msgs */ if (ni_rtnl_route_filter_msg(rtm)) return 1; rp = ni_route_new(); if (ni_rtnl_route_parse_msg(h, rtm, rp) != 0) { ni_route_free(rp); return -1; } for (nh = &rp->nh; nh; nh = nh->next) { if (!(dev = ni_netdev_by_index(nc, nh->device.index))) continue; if (!(r = ni_route_tables_find_match(dev->routes, rp, ni_route_equal))) continue; rp->owner = r->owner; ni_netconfig_route_del(nc, r, dev); break; } if (ni_netconfig_route_add(nc, rp, dev) < 0) { ni_route_free(rp); return -1; } __ni_netinfo_route_event(nc, NI_EVENT_ROUTE_UPDATE, rp); ni_route_free(rp); return 0; }
int ni_addrconf_lease_routes_data_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node) { const xml_node_t *child; ni_route_t *rp; for (child = node->children; child; child = child->next) { if (ni_string_eq(child->name, "route")) { rp = ni_route_new(); rp->family = lease->family; rp->table = ni_route_guess_table(rp); if (__ni_addrconf_lease_route_from_xml(rp, child) != 0) { ni_route_free(rp); } else if (!ni_route_tables_add_route(&lease->routes, rp)) { ni_route_free(rp); return -1; } } } return 0; }