int inet_route_add(struct rtable_fspec *fs, struct vr_route_req *req) { struct vr_rtable *rtable; struct vrouter *router; unsigned int pmask; router = vrouter_get(req->rtr_req.rtr_rid); if (!router) return -EINVAL; rtable = vr_get_inet_table(router, req->rtr_req.rtr_rt_type); if (!rtable || ((unsigned int)req->rtr_req.rtr_vrf_id > fs->rtb_max_vrfs) || ((unsigned int)(req->rtr_req.rtr_prefix_len) > VR_INET_MAX_PLEN)) return -EINVAL; if (req->rtr_req.rtr_prefix_len) { pmask = ~((1 << (32 - req->rtr_req.rtr_prefix_len)) - 1); req->rtr_req.rtr_prefix &= pmask; } else req->rtr_req.rtr_prefix = 0; return rtable->algo_add(rtable, req); }
int vr_route_get(vr_route_req *req) { struct vr_route_req vr_req; struct vrouter *router; struct vr_rtable *rtable; int ret = 0; vr_req.rtr_req = *req; router = vrouter_get(req->rtr_rid); if (!router) { ret = -ENOENT; goto generate_response; } else { rtable = vr_get_inet_table(router, req->rtr_rt_type); if (!rtable) { ret = -ENOENT; goto generate_response; } ret = rtable->algo_get(vr_req.rtr_req.rtr_vrf_id, &vr_req); } generate_response: vr_message_response(VR_ROUTE_OBJECT_ID, ret ? NULL : &vr_req, ret); return ret; }
static int inet_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router) { int ret; struct vr_rtable *table = NULL; unsigned int i; for (i = 0; i < RT_MAX; i++) { if (!fs->algo_init[i]) continue; if (vr_get_inet_table(router, i)) continue; table = vr_zalloc(sizeof(struct vr_rtable)); if (!table) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, i); ret = fs->algo_init[i](table, fs); if (ret) return vr_module_error(ret, __FUNCTION__, __LINE__, i); vr_put_inet_table(router, i, table); } return 0; }
static void inet_rtb_family_deinit(struct rtable_fspec *fs, struct vrouter *router) { struct vr_rtable *rtable; int i; for (i = 0; i < RT_MAX; i++) { rtable = vr_get_inet_table(router, i); if (rtable) { fs->algo_deinit[i](rtable, fs); vr_free(rtable); } } /* First unicast followed by multicast */ router->vr_inet_rtable = NULL; router->vr_inet_mcast_rtable = NULL; return; }
static void vr_inet_vrf_stats_dump(struct vrouter *router, vr_vrf_stats_req *req) { int ret = 0; struct vr_rtable *rtable; rtable = vr_get_inet_table(router, req->vsr_type); if (!rtable) { ret = -ENOENT; goto generate_error; } ret = rtable->algo_stats_dump(rtable, req); return; generate_error: vr_send_response(ret); return; }
int inet_route_del(struct rtable_fspec *fs, struct vr_route_req *req) { struct vr_rtable *rtable; struct vrouter *router; if ((unsigned int)(req->rtr_req.rtr_prefix_len) > VR_INET_MAX_PLEN || (unsigned int)(req->rtr_req.rtr_vrf_id) >= VR_MAX_VRFS) return -EINVAL; router = vrouter_get(req->rtr_req.rtr_rid); if (!router) return -EINVAL; rtable = vr_get_inet_table(router, req->rtr_req.rtr_rt_type); if (!rtable || req->rtr_req.rtr_vrf_id >= (int)fs->rtb_max_vrfs) return -EINVAL; return rtable->algo_del(rtable, req); }
static void vr_inet_vrf_stats_get(struct vrouter *router, vr_vrf_stats_req *req) { int ret = 0; struct vr_rtable *rtable; vr_vrf_stats_req response; rtable = vr_get_inet_table(router, req->vsr_type); if (!rtable) { ret = -ENOENT; goto generate_error; } if (req->vsr_vrf >= 0 && (unsigned int)req->vsr_vrf >= rtable->algo_max_vrfs) { ret = -EINVAL; goto generate_error; } ret = rtable->algo_stats_get(req, &response); generate_error: vr_message_response(VR_VRF_STATS_OBJECT_ID, ret ? NULL : &response, ret); return; }
int vr_route_dump(vr_route_req *req) { struct vr_route_req vr_req; struct vrouter *router; struct vr_rtable *rtable = NULL; int ret; vr_req.rtr_req = *req; router = vrouter_get(req->rtr_rid); if (!router) { ret = -ENOENT; goto generate_error; } else { if (req->rtr_family == AF_INET) { rtable = vr_get_inet_table(router, req->rtr_rt_type); } else if (req->rtr_family == AF_BRIDGE) { rtable = router->vr_bridge_rtable; } if (!rtable) { ret = -ENOENT; goto generate_error; } ret = rtable->algo_dump(NULL, &vr_req); } return ret; generate_error: vr_send_response(ret); return ret; }
static void inet_rtb_family_deinit(struct rtable_fspec *fs, struct vrouter *router, bool soft_reset) { struct vr_rtable *rtable; int i; for (i = 0; i < RT_MAX; i++) { rtable = vr_get_inet_table(router, i); if (rtable) { fs->algo_deinit[i](rtable, fs, soft_reset); if (i == RT_UCAST) { vr_free(rtable); vr_put_inet_table(router, i, NULL); } if ((i == RT_MCAST) && !soft_reset) { vr_free(rtable); vr_put_inet_table(router, i, NULL); } } } return; }